From db08865c22fc2eede016c42691c04ba6b49520fa Mon Sep 17 00:00:00 2001 From: f-osorio Date: Tue, 7 Jan 2025 15:08:33 -0500 Subject: [PATCH 01/91] Fix issue with literals in subjects The subject builder was encountering an error when there was a literal because the `uri` was `null` and `.includes()` hit an error --- src/components/panels/edit/modals/SubjectEditor.vue | 9 ++++++--- src/stores/config.js | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/panels/edit/modals/SubjectEditor.vue b/src/components/panels/edit/modals/SubjectEditor.vue index aded7ba4..eb65fd07 100644 --- a/src/components/panels/edit/modals/SubjectEditor.vue +++ b/src/components/panels/edit/modals/SubjectEditor.vue @@ -2486,11 +2486,14 @@ methods: { for (let component in frozenComponents){ // if (this.components[component].complex && !['madsrdf:Geographic', 'madsrdf:HierarchicalGeographic'].includes(this.components[component].type)){ const target = frozenComponents[component] - - if (!(['madsrdf:Geographic', 'madsrdf:HierarchicalGeographic'].includes(target.type) || target.uri.includes("childrensSubjects/sj")) && target.complex){ + if (!(['madsrdf:Geographic', 'madsrdf:HierarchicalGeographic'].includes(target.type) || (target.uri && target.uri.includes("childrensSubjects/sj"))) && target.complex){ let uri = target.uri let data = false //await this.parseComplexSubject(uri) //This can take a while, and is only need for the URI, but lots of things don't have URIs - data = await this.parseComplexSubject(uri) + if (uri){ + data = await this.parseComplexSubject(uri) + } else { + data = target + } let subs subs = target.marcKey.slice(5) diff --git a/src/stores/config.js b/src/stores/config.js index dd6416de..9466ce80 100644 --- a/src/stores/config.js +++ b/src/stores/config.js @@ -7,7 +7,7 @@ export const useConfigStore = defineStore('config', { versionMajor: 0, versionMinor: 17, - versionPatch: 14, + versionPatch: 15, regionUrls: { From 3b77e58b4475d74d066c4dafd9d31e4b45efc859 Mon Sep 17 00:00:00 2001 From: f-osorio Date: Wed, 8 Jan 2025 08:56:30 -0500 Subject: [PATCH 02/91] Add ability to add an item --- src/components/panels/nav/Nav.vue | 4 ++ src/stores/profile.js | 78 ++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/components/panels/nav/Nav.vue b/src/components/panels/nav/Nav.vue index 0de6de0a..5e4b92ba 100644 --- a/src/components/panels/nav/Nav.vue +++ b/src/components/panels/nav/Nav.vue @@ -141,6 +141,10 @@ { text: 'Add Secondary Instance', click: () => { this.profileStore.createInstance(true) } + }, + { + text: 'Add Item', + click: () => { this.profileStore.createItem() } } ) } diff --git a/src/stores/profile.js b/src/stores/profile.js index d5ce9a03..3fea2287 100644 --- a/src/stores/profile.js +++ b/src/stores/profile.js @@ -3968,7 +3968,7 @@ export const useProfileStore = defineStore('profile', { /** * Build a new instance * - * @param lccn {string} the lccn for the new instance. If there isn't one, this is a secondary instance + * @param secondary {bool} whether this should an instance or a secondary instance * @return {void} */ createInstance: function(secondary=false){ @@ -4033,7 +4033,7 @@ export const useProfileStore = defineStore('profile', { this.activeProfile.rt[newRtId].URI = utilsProfile.suggestURI(this.activeProfile,'bf:Instance',workUri) this.activeProfile.rt[newRtId].instanceOf = workUri - if (secondary){ + if (secondary && secondary != "item"){ this.activeProfile.rt[newRtId]['@type'] = 'http://id.loc.gov/ontologies/bflc/SecondaryInstance' } @@ -4046,6 +4046,80 @@ export const useProfileStore = defineStore('profile', { }, + /** + * Create a new item for the record + * + * @return {void} + */ + createItem: async function(secondary=false){ + + // find the RT for the instance of this profile orginally + // get the work rt + + let itemName + let itemRt + let workUri + let instanceUri + + console.info("active: ", this.activeProfile) + + for (let rtId in this.activeProfile.rt){ + if (rtId.includes(":Work")){ + workUri = this.activeProfile.rt[rtId].URI + // now find the corosponding item id + for (let allRt in this.profiles){ + if (this.profiles[allRt].rtOrder.indexOf(rtId)>-1){ + if (this.profiles[allRt].rtOrder.filter(i => i.includes(":Item"))[0]){ + itemName = this.profiles[allRt].rtOrder.filter(i => i.includes(":Item"))[0] + itemRt = JSON.parse(JSON.stringify(this.profiles[allRt].rt[itemName])) + } + } + } + } + if (rtId.includes(":Instance")){ + instanceUri = this.activeProfile.rt[rtId].URI + } + } + + let itemCount = 0; + + // gather info to add it + let items = Object.keys(this.activeProfile.rt).filter(i => i.includes(":Item")) + if (items.length>1){ + itemCount = items.length -1 + } + + + itemCount++ + // console.log('itemCount',itemCount) + let newRtId = itemName +'_'+itemCount + itemRt.isNew = true + this.activeProfile.rt[newRtId] = itemRt + this.activeProfile.rtOrder.push(newRtId) + + // give it all new guids + for (let pt in this.activeProfile.rt[newRtId].pt){ + this.activeProfile.rt[newRtId].pt[pt]['@guid'] = short.generate() + // update the parentId + this.activeProfile.rt[newRtId].pt[pt].parentId = this.activeProfile.rt[newRtId].pt[pt].parentId.replace(itemName, newRtId) + this.activeProfile.rt[newRtId].pt[pt].parent = this.activeProfile.rt[newRtId].pt[pt].parent.replace(itemName, newRtId) + } + + + + // setup the new instance's properies + // profile.rt[newRdId].URI = 'http://id.loc.gov/resources/instances/'+ translator.toUUID(translator.new()) + + this.activeProfile.rt[newRtId].URI = utilsProfile.suggestURI(this.activeProfile,'bf:Item', instanceUri) + this.activeProfile.rt[newRtId].itemOf = instanceUri + + //Add to rtLookup, with a copy of an instance as the value + this.rtLookup[newRtId] = this.rtLookup[itemName] + + this.dataChanged() + + }, + /** * * From 2499eab98f81292048a82c885b72345e435c0366 Mon Sep 17 00:00:00 2001 From: f-osorio Date: Wed, 8 Jan 2025 10:08:32 -0500 Subject: [PATCH 03/91] User needs to select an instance when > 1 --- src/App.vue | 2 +- .../panels/nav/ItemInstanceSelectionModal.vue | 183 ++++++++++++++++++ src/components/panels/nav/Nav.vue | 47 ++++- src/stores/profile.js | 28 +-- 4 files changed, 242 insertions(+), 18 deletions(-) create mode 100644 src/components/panels/nav/ItemInstanceSelectionModal.vue diff --git a/src/App.vue b/src/App.vue index 9d21e832..87860a77 100644 --- a/src/App.vue +++ b/src/App.vue @@ -60,7 +60,7 @@ export default { // gives access to this.counterStore and this.userStore ...mapStores(useConfigStore, useProfileStore, usePreferenceStore), // // gives read access to this.count and this.double - ...mapState(useProfileStore, ['profilesLoaded', 'showValidateModal','profilesLoaded', 'showPostModal']), + ...mapState(useProfileStore, ['profilesLoaded', 'showValidateModal','profilesLoaded', 'showPostModal', 'showItemInstanceSelection']), ...mapWritableState(useProfileStore, ['showShelfListingModal','showHubStubCreateModal', 'showAutoDeweyModal']), ...mapState(usePreferenceStore, ['showPrefModal','catCode']), diff --git a/src/components/panels/nav/ItemInstanceSelectionModal.vue b/src/components/panels/nav/ItemInstanceSelectionModal.vue new file mode 100644 index 00000000..77c4fc53 --- /dev/null +++ b/src/components/panels/nav/ItemInstanceSelectionModal.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/src/components/panels/nav/Nav.vue b/src/components/panels/nav/Nav.vue index 5e4b92ba..9ea5c632 100644 --- a/src/components/panels/nav/Nav.vue +++ b/src/components/panels/nav/Nav.vue @@ -17,6 +17,10 @@ + + @@ -33,13 +37,15 @@ import PostModal from "@/components/panels/nav/PostModal.vue"; import ValidateModal from "@/components/panels/nav/ValidateModal.vue"; import RecoveryModal from "@/components/panels/nav/RecoveryModal.vue"; + import ItemInstanceSelectionModal from "@/components/panels/nav/ItemInstanceSelectionModal.vue"; export default { - components: { VueFileToolbarMenu, PostModal, ValidateModal,RecoveryModal }, + components: { VueFileToolbarMenu, PostModal, ValidateModal,RecoveryModal,ItemInstanceSelectionModal }, data() { return { allSelected: false, + instances: [], } }, props:{ @@ -57,7 +63,7 @@ ...mapState(usePreferenceStore, ['styleDefault', 'showPrefModal', 'panelDisplay']), ...mapState(useConfigStore, ['layouts']), ...mapWritableState(usePreferenceStore, ['showLoginModal','showScriptshifterConfigModal','showDiacriticConfigModal','showTextMacroModal','layoutActiveFilter','layoutActive','showFieldColorsModal']), - ...mapWritableState(useProfileStore, ['showPostModal', 'showShelfListingModal', 'activeShelfListData','showValidateModal', 'showRecoveryModal', 'showAutoDeweyModal']), + ...mapWritableState(useProfileStore, ['showPostModal', 'showShelfListingModal', 'activeShelfListData','showValidateModal', 'showRecoveryModal', 'showAutoDeweyModal', 'showItemInstanceSelection']), ...mapWritableState(useConfigStore, ['showNonLatinBulkModal','showNonLatinAgentModal']), @@ -144,7 +150,7 @@ }, { text: 'Add Item', - click: () => { this.profileStore.createItem() } + click: () => { this.addItem() } } ) } @@ -527,6 +533,41 @@ document.body.removeChild(temp) }, + addItem: function(){ + let instanceCount = 0 + let instance = null + for (let p in this.activeProfile.rt){ + if (p.includes(":Instance")){ + this.instances.push(p) + instanceCount++ + } + } + if (instanceCount == 0){ + alert("There are no instances in the record. You need to crete one before you can add an item.") + return + } + if (instanceCount>1){ + console.info("open instance selection modal") + // show a modal to select which instance the item belongs too + this.showItemInstanceSelection = true + } else { + this.profileStore.createItem(this.targetInstance) + } + }, + + setInstance: function(data){ + console.info("setting instance") + this.targetInstance = this.instances[data] + this.showItemInstanceSelection = false + this.instances = [] + this.profileStore.createItem(this.targetInstance) + }, + + hideInstanceSelectionModal: function(){ + this.instances = [] + this.showItemInstanceSelection = false; + } + }, created() {} diff --git a/src/stores/profile.js b/src/stores/profile.js index 3fea2287..96e69805 100644 --- a/src/stores/profile.js +++ b/src/stores/profile.js @@ -85,6 +85,7 @@ export const useProfileStore = defineStore('profile', { showRecoveryModal: false, showValidateModal: false, showHubStubCreateModal: false, + showItemInstanceSelection: false, activeHubStubData:{ }, activeHubStubComponent:{ @@ -4048,10 +4049,11 @@ export const useProfileStore = defineStore('profile', { /** * Create a new item for the record + * @param instance {string} position of the rt for the instance that the item belongs to, when there is more than 1 instance * * @return {void} */ - createItem: async function(secondary=false){ + createItem: async function(instance){ // find the RT for the instance of this profile orginally // get the work rt @@ -4061,22 +4063,22 @@ export const useProfileStore = defineStore('profile', { let workUri let instanceUri - console.info("active: ", this.activeProfile) - for (let rtId in this.activeProfile.rt){ if (rtId.includes(":Work")){ - workUri = this.activeProfile.rt[rtId].URI - // now find the corosponding item id - for (let allRt in this.profiles){ - if (this.profiles[allRt].rtOrder.indexOf(rtId)>-1){ - if (this.profiles[allRt].rtOrder.filter(i => i.includes(":Item"))[0]){ - itemName = this.profiles[allRt].rtOrder.filter(i => i.includes(":Item"))[0] - itemRt = JSON.parse(JSON.stringify(this.profiles[allRt].rt[itemName])) - } + workUri = this.activeProfile.rt[rtId].URI + // now find the corosponding item id + for (let allRt in this.profiles){ + if (this.profiles[allRt].rtOrder.indexOf(rtId)>-1){ + if (this.profiles[allRt].rtOrder.filter(i => i.includes(":Item"))[0]){ + itemName = this.profiles[allRt].rtOrder.filter(i => i.includes(":Item"))[0] + itemRt = JSON.parse(JSON.stringify(this.profiles[allRt].rt[itemName])) } } + } } - if (rtId.includes(":Instance")){ + if (instance && rtId == instance){ + instanceUri = this.activeProfile.rt[rtId].URI + }else if (rtId.includes(":Instance")){ instanceUri = this.activeProfile.rt[rtId].URI } } @@ -4105,8 +4107,6 @@ export const useProfileStore = defineStore('profile', { this.activeProfile.rt[newRtId].pt[pt].parent = this.activeProfile.rt[newRtId].pt[pt].parent.replace(itemName, newRtId) } - - // setup the new instance's properies // profile.rt[newRdId].URI = 'http://id.loc.gov/resources/instances/'+ translator.toUUID(translator.new()) From 4cbb6200c15c89ca0e42d080852d515edf316b49 Mon Sep 17 00:00:00 2001 From: f-osorio Date: Wed, 8 Jan 2025 11:06:12 -0500 Subject: [PATCH 04/91] Fix only being able to have 1 item --- src/stores/profile.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/stores/profile.js b/src/stores/profile.js index 96e69805..e2e2796c 100644 --- a/src/stores/profile.js +++ b/src/stores/profile.js @@ -4083,22 +4083,28 @@ export const useProfileStore = defineStore('profile', { } } + console.info("itemName: ", itemName) + console.info("itemRt: ", itemRt) + let itemCount = 0; // gather info to add it let items = Object.keys(this.activeProfile.rt).filter(i => i.includes(":Item")) - if (items.length>1){ - itemCount = items.length -1 + console.info("items: ", items) + if (items.length >= 1){ + itemCount = items.length } - itemCount++ + // console.log('itemCount',itemCount) let newRtId = itemName +'_'+itemCount itemRt.isNew = true this.activeProfile.rt[newRtId] = itemRt this.activeProfile.rtOrder.push(newRtId) + console.info("newRtId: ", newRtId) + // give it all new guids for (let pt in this.activeProfile.rt[newRtId].pt){ this.activeProfile.rt[newRtId].pt[pt]['@guid'] = short.generate() From f7824c08a779c238ba70391dcf618e05c9393c88 Mon Sep 17 00:00:00 2001 From: f-osorio Date: Wed, 8 Jan 2025 13:12:16 -0500 Subject: [PATCH 05/91] Add icon for item in propertyPanel --- src/components/panels/sidebar_property/Properties.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/panels/sidebar_property/Properties.vue b/src/components/panels/sidebar_property/Properties.vue index 6942d8cd..d1d58fd5 100644 --- a/src/components/panels/sidebar_property/Properties.vue +++ b/src/components/panels/sidebar_property/Properties.vue @@ -148,8 +148,8 @@ - - + + From 6b27d2f240f5a24b431228352a7321a77159fb5b Mon Sep 17 00:00:00 2001 From: f-osorio Date: Wed, 8 Jan 2025 13:28:12 -0500 Subject: [PATCH 06/91] Update display of Item fields --- src/components/panels/edit/EditPanel.vue | 34 +++++++++++++------ .../panels/sidebar_property/Properties.vue | 2 +- src/stores/preference.js | 8 +++++ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/components/panels/edit/EditPanel.vue b/src/components/panels/edit/EditPanel.vue index 81e9a572..faf825fe 100644 --- a/src/components/panels/edit/EditPanel.vue +++ b/src/components/panels/edit/EditPanel.vue @@ -11,12 +11,10 @@ -
- + :class="{'edit-panel-work': (profileName.split(':').slice(-1)[0] == 'Work'), 'edit-panel-instance': (profileName.split(':').slice(-1)[0] == 'Instance'), 'edit-panel-item': (profileName.split(':').slice(-1)[0].includes('Item')), 'edit-panel-instance-secondary': (profileName.split(':').slice(-1)[0].indexOf('_') > -1 && !profileName.split(':').slice(-1)[0].includes('Item')), 'edit-panel-scroll-x-parent': preferenceStore.returnValue('--b-edit-main-splitpane-edit-scroll-x')}">