Skip to content

Commit

Permalink
Merge pull request #1139 from libris/feature/bulkchange-delete-create
Browse files Browse the repository at this point in the history
Add functionality for deleting and creating records in bulk
  • Loading branch information
lrosenstrom authored Oct 31, 2024
2 parents 10e725f + e4ae76e commit 78bf6e2
Show file tree
Hide file tree
Showing 7 changed files with 347 additions and 68 deletions.
32 changes: 20 additions & 12 deletions cataloging/src/components/care/bulk-changes-header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {mapGetters} from "vuex";
import {
STATUS_KEY,
} from "@/utils/bulk.js";
import TypeIcon from "../shared/type-icon.vue";
export default {
name: 'bulk-changes-header.vue',
components: {IdPill, FormBuilder},
components: {TypeIcon, IdPill, FormBuilder},
data() {
return {
editing: false,
Expand All @@ -21,6 +22,7 @@ export default {
documentId: '',
isNew: false,
isDraft: false,
specType: ''
},
computed: {
...mapGetters([
Expand All @@ -36,6 +38,9 @@ export default {
status() {
return StringUtil.getLabelByLang(this.currentBulkChange[STATUS_KEY], this.user.settings.language, this.resources);
},
typeLabel() {
return StringUtil.getLabelByLang(this.specType, this.user.settings.language, this.resources);
},
},
methods: {
translatePhrase,
Expand All @@ -58,7 +63,6 @@ export default {
</script>
<template>
<div class="BulkChanges">
<h1>
<input class="BulkChanges-inputField"
ref="heading"
v-if="editing"
Expand All @@ -75,19 +79,15 @@ export default {
>
{{this.name}}
</span>
<span class="badge badge-accent2">{{ this.status }}</span>
<!-- <span class="BulkChanges-noItems badge badge-accent-2"-->
<!-- v-if="this.noAffected"> {{this.noAffectedLabel}}-->
<!-- </span>-->
</h1>
<span class="badge badge-accent2">{{ this.status }}</span>
<span class="BulkChanges-type" v-tooltip.right="typeLabel">
<type-icon :type="specType"/>
</span>
<span class="BulkChanges-id">
<id-pill
v-if="!isNew"
:uri="documentId"
/>
<!-- <span class="badge badge-accent"-->
<!-- v-if="isNew"-->
<!-- >Ny</span>-->
</span>
</div>
</template>
Expand All @@ -101,6 +101,7 @@ export default {
font-size: 3rem;
padding-bottom: 10px;
padding-right: 1rem;
font-weight: 600;
&.cursor-pointer {
cursor: pointer;
}
Expand All @@ -115,8 +116,15 @@ export default {
margin-left: auto;
text-align:right;
}
&-noItems {
margin-left: 5px;
&-typeHeader {
display: flex;
width: 100%;
flex-wrap: wrap;
}
&-type{
margin-left: 3px;
display: flex;
font-size: 12px;
}
}
</style>
115 changes: 73 additions & 42 deletions cataloging/src/components/care/bulk-changes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import {
SHOULD_UPDATE_TIMESTAMP_KEY,
STATUS_KEY,
Status,
TARGET_FORM_KEY, VALUE_FROM_KEY,
TARGET_FORM_KEY,
VALUE_FROM_KEY,
Type
} from "@/utils/bulk.js";
export default {
Expand All @@ -50,7 +52,7 @@ export default {
showOverview: true,
inlinedIds: [],
activeStep: '',
steps: [
allSteps: [
'form',
'targetForm',
'preview',
Expand Down Expand Up @@ -105,9 +107,15 @@ export default {
return this.isActive('targetForm') ? this.inspector.data.mainEntity : this.currentSpec[TARGET_FORM_KEY];
},
formTitle() {
if (this.specType === Type.Delete) {
return `${this.steps.indexOf('form') + 1}. ${translatePhrase('Remove records')}`
}
return `${this.steps.indexOf('form') + 1}. ${translatePhrase('Selection')}`
},
changesTitle() {
if (this.specType === Type.Create) {
return `${this.steps.indexOf('targetForm') + 1}. ${translatePhrase('Create records')}`
}
return `${this.steps.indexOf('targetForm') + 1}. ${translatePhrase('Changes')}`
},
previewTitle() {
Expand Down Expand Up @@ -151,6 +159,15 @@ export default {
shouldExportAffected() {
return this.isLoud;
},
steps() {
if (!this.hasTargetForm) {
return this.allSteps.filter(step => step !== 'targetForm');
} else if(!this.hasMatchForm) {
return this.allSteps.filter(step => step !== 'form')
} else {
return this.allSteps;
}
},
hasUnsavedChanges() {
if (this.lastFetchedSpec && this.isDraft) {
const matchFormEqual = isEqual(this.formObj, this.lastFetchedSpec[MATCH_FORM_KEY]);
Expand All @@ -159,6 +176,15 @@ export default {
}
return false;
},
hasTargetForm() {
return this.specType !== Type.Delete;
},
hasMatchForm() {
return this.specType !== Type.Create;
},
specType() {
return this.currentSpec['@type'];
}
},
methods: {
translatePhrase,
Expand All @@ -171,7 +197,6 @@ export default {
const record = initData['@graph'][0];
const mainEntity = initData['@graph'][1];
this.currentBulkChange = mainEntity;
this.currentBulkChange.label = '<namn>-' + this.getDateString();
this.currentSpec = this.currentBulkChange[CHANGE_SPEC_KEY];
Expand All @@ -196,8 +221,7 @@ export default {
// FIXME: remove emptyTemplate
const initial = emptyTemplate.mainEntity[CHANGE_SPEC_KEY][MATCH_FORM_KEY];
this.setInspectorData(initial);
this.currentSpec[MATCH_FORM_KEY] = initial;
this.currentSpec[TARGET_FORM_KEY] = initial; //FIXME: to avoid undefined on init
this.currentSpec = emptyTemplate.mainEntity[CHANGE_SPEC_KEY]; //FIXME: to avoid undefined on init
this.fetchRecord(this.documentId);
},
fetchRecord(fnurgel) {
Expand Down Expand Up @@ -365,27 +389,25 @@ export default {
// const agents = (this.changeSets || []).map((c) => c.agent).filter((a) => a);
// DataUtil.fetchMissingLinkedToQuoted(agents, this.$store);
if (typeof result.changeSets === 'undefined') {
this.resetPreviewData();
return;
}
// Form preview
const formChangeset = result.changeSets[1];
if (typeof result.changeSets !== 'undefined') {
const formChangeset = result.changeSets[1];
const [formDisplayData, formDisplayPaths] = HistoryUtil.buildDisplayData(
this.currentSpec[MATCH_FORM_KEY],
this.currentSpec[TARGET_FORM_KEY],
formChangeset.addedPaths,
formChangeset.removedPaths,
(s) => StringUtil.getLabelByLang(s, this.user.settings.language, this.resources),
);
this.formPreviewData= formDisplayData;
this.formPreviewDiff.removed = formDisplayPaths.removed.map(path => `mainEntity.${path}`);
this.formPreviewDiff.added = formDisplayPaths.added.map(path => `mainEntity.${path}`);
this.formPreviewDiff.modified = formDisplayPaths.modified.map(path => `mainEntity.${path}`);
const [formDisplayData, formDisplayPaths] = HistoryUtil.buildDisplayData(
this.currentSpec[MATCH_FORM_KEY],
this.currentSpec[TARGET_FORM_KEY],
formChangeset.addedPaths,
formChangeset.removedPaths,
(s) => StringUtil.getLabelByLang(s, this.user.settings.language, this.resources),
);
this.formPreviewData = formDisplayData;
this.formPreviewDiff.removed = formDisplayPaths.removed.map(path => `mainEntity.${path}`);
this.formPreviewDiff.added = formDisplayPaths.added.map(path => `mainEntity.${path}`);
this.formPreviewDiff.modified = formDisplayPaths.modified.map(path => `mainEntity.${path}`);
}
this.totalItems = result.totalItems;
if (this.totalItems === 0 || typeof result.changeSets === 'undefined') {
if (this.totalItems === 0) {
this.resetPreviewData();
return;
} else {
Expand All @@ -396,22 +418,29 @@ export default {
this.previousPreviewLink = result.prev;
this.itemOffset = result.itemOffset;
let before = result.items[0].changeSets[0].version;
let after = result.items[0].changeSets[1].version;
const changeset = result.items[0].changeSets[1];
if (this.specType === Type.Update) {
let before = result.items[0].changeSets[0].version;
let after = result.items[0].changeSets[1].version;
const changeset = result.items[0].changeSets[1];
const [displayData, displayPaths] = HistoryUtil.buildDisplayData(
before,
after,
changeset.addedPaths.map(el => el.slice(2)), //temporary hack to remove [@graph, 1, ...
changeset.removedPaths.map(el => el.slice(2)),
(s) => StringUtil.getLabelByLang(s, this.user.settings.language, this.resources),
);
const [displayData, displayPaths] = HistoryUtil.buildDisplayData(
before,
after,
changeset.addedPaths.map(el => el.slice(2)), //temporary hack to remove [@graph, 1, ...
changeset.removedPaths.map(el => el.slice(2)),
(s) => StringUtil.getLabelByLang(s, this.user.settings.language, this.resources),
);
this.fullPreviewData= displayData;
this.fullPreviewDiff.removed = displayPaths.removed.map(path => `mainEntity.${path}`);
this.fullPreviewDiff.added = displayPaths.added.map(path => `mainEntity.${path}`);
this.fullPreviewDiff.modified = displayPaths.modified.map(path => `mainEntity.${path}`);
this.fullPreviewData = displayData;
this.fullPreviewDiff.removed = displayPaths.removed.map(path => `mainEntity.${path}`);
this.fullPreviewDiff.added = displayPaths.added.map(path => `mainEntity.${path}`);
this.fullPreviewDiff.modified = displayPaths.modified.map(path => `mainEntity.${path}`);
} else if (this.specType === Type.Delete) {
this.fullPreviewDiff.removed = [];
this.fullPreviewDiff.added = [];
this.fullPreviewDiff.modifed = [];
this.fullPreviewData = result.items[0].changeSets[0].version;
}
DataUtil.fetchMissingLinkedToQuoted(this.fullPreviewData, this.$store);
this.loadingPreview.next = false;
this.loadingPreview.previous = false;
Expand Down Expand Up @@ -671,8 +700,9 @@ export default {
:documentId="documentId"
:is-new="isNew"
:is-draft="isDraft"
:spec-type="specType"
/>
<div ref="matchForm">
<div ref="matchForm" v-if="hasMatchForm">
<form-builder
:title="formTitle"
tabindex="0"
Expand All @@ -684,7 +714,7 @@ export default {
@removeIdList="removeIdList"
/>
</div>
<div ref="targetForm">
<div ref="targetForm" v-if="hasTargetForm">
<target-form-builder
:title="changesTitle"
tabindex="0"
Expand All @@ -710,6 +740,7 @@ export default {
:total-items="totalItems"
:finished="isFinished"
:has-unsaved="hasUnsavedChanges"
:spec-type="specType"
@onActive="focusPreview"
/>
</div>
Expand Down Expand Up @@ -740,10 +771,10 @@ export default {
</div>
</div>
<div>
<!-- SPECIFICATION-->
<!-- <pre>{{ this.currentBulkChange }}</pre>-->
<!-- ENTITY FORM-->
<!-- <pre>{{ this.dataObj }}</pre>-->
SPECIFICATION
<pre>{{ this.currentBulkChange }}</pre>
ENTITY FORM
<pre>{{ this.dataObj }}</pre>

<!-- RECORD-->
<!-- <pre>{{ this.record }}</pre>-->
Expand Down
29 changes: 24 additions & 5 deletions cataloging/src/components/care/preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { mapGetters } from 'vuex';
import {isEmpty} from 'lodash-es';
import ItemEntity from "@/components/inspector/item-entity.vue";
import EntitySummary from "@/components/shared/entity-summary.vue";
import {asFnurgelLink, translatePhrase} from "@/utils/filters.js";
import {offset} from "@floating-ui/dom";
import {translatePhrase} from "@/utils/filters.js";
import * as StringUtil from "../../../../lxljs/string.js";
import { Status } from "@/utils/bulk.js";
import { Status, Type } from "@/utils/bulk.js";
export default {
name: 'preview',
Expand Down Expand Up @@ -51,6 +50,10 @@ export default {
type: Boolean,
default: false,
},
specType: {
type: String,
default: '',
}
},
computed: {
...mapGetters([
Expand All @@ -68,7 +71,7 @@ export default {
return !isEmpty(this.previewData) && !isEmpty(this.previewDiff);
},
showPreview() {
return this.hasPreviewData && !this.hasUnsaved;
return this.hasPreviewData;
},
noHitsLabel() {
if (this.hasUnsaved) {
Expand All @@ -79,8 +82,17 @@ export default {
return translatePhrase('No matching records');
}
},
deleteSpecLabel() {
return translatePhrase('Delete record');
},
completedLabel() {
return StringUtil.getLabelByLang(Status.Completed, this.user.settings.language, this.resources)
},
isDeleteSpec() {
return this.specType === Type.Delete;
},
isUpdateSpec() {
return this.specType === Type.Update;
}
},
emits: ['onInactive', 'onActive'],
Expand Down Expand Up @@ -126,14 +138,21 @@ export default {
:should-link="false"
:exclude-components="['details']"/>
</div>
<entity-form
<entity-form v-if="isUpdateSpec"
:editing-object="'mainEntity'"
:key="formTab.id"
:is-active="true"
:diff="previewDiff"
:form-data="previewData"
:locked="true"
/>
<entity-form v-if="isDeleteSpec"
:editing-object="'mainEntity'"
:key="formTab.id"
:is-active="true"
:form-data="previewData"
:locked="true"
/>
</div>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions cataloging/src/components/shared/type-icon.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script>
import { mapGetters } from 'vuex';
import { Type } from '@/utils/bulk.js';
export default {
name: 'type-icon',
props: {
Expand Down Expand Up @@ -37,7 +37,9 @@ export default {
ManuscriptNotatedMusic: 'music',
InquiryAction: 'question',
ChangeNotice: 'exclamation',
ChangeObservation: 'exchange',
[Type.Update]: 'edit',
[Type.Delete]: 'trash-o',
[Type.Create]: 'plus',
// Place: 'map-marker',
},
forcedUnspecified: [
Expand Down
Loading

0 comments on commit 78bf6e2

Please sign in to comment.