From f4f02dd962f01aace001a92b0d5660bc9dad7a96 Mon Sep 17 00:00:00 2001 From: fo Date: Tue, 3 Feb 2026 17:57:13 +0000 Subject: [PATCH 1/5] Add entities search. TODO: Get XML building correctly --- .../panels/edit/modals/SubjectEditor.vue | 9 +++++ .../helpers/ComplexSearchResultsDisplay.vue | 10 +++++ .../edit/modals/helpers/DetailsPanel.vue | 9 ++++- src/lib/utils_network.js | 39 ++++++++++++++++++- src/stores/config.js | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/components/panels/edit/modals/SubjectEditor.vue b/src/components/panels/edit/modals/SubjectEditor.vue index dacd8139..ebb46161 100644 --- a/src/components/panels/edit/modals/SubjectEditor.vue +++ b/src/components/panels/edit/modals/SubjectEditor.vue @@ -96,6 +96,8 @@ + @@ -1535,6 +1537,13 @@ export default { for (let x in this.searchResults.exact) { this.pickLookup[(this.searchResults.names.length - x) * -1 - 2] = this.searchResults.exact[x] } + + console.info("entities: ", this.searchResults.entities) + for (let x in this.searchResults.entities) { + console.info("pickup: ", x, "==", this.searchResults.entities[x]) + this.pickLookup[x] = this.searchResults.entities[x] + + } }, // some context messing here, pass the debounce func a ref to the vue "this" as that to ref in the function callback diff --git a/src/components/panels/edit/modals/helpers/ComplexSearchResultsDisplay.vue b/src/components/panels/edit/modals/helpers/ComplexSearchResultsDisplay.vue index fbb240eb..cbcae5ad 100644 --- a/src/components/panels/edit/modals/helpers/ComplexSearchResultsDisplay.vue +++ b/src/components/panels/edit/modals/helpers/ComplexSearchResultsDisplay.vue @@ -76,6 +76,16 @@ @selectContext="selectContext" @emitLoadContext="loadContext" /> + + diff --git a/src/components/panels/edit/modals/helpers/DetailsPanel.vue b/src/components/panels/edit/modals/helpers/DetailsPanel.vue index f3895a1b..6da6c6a6 100644 --- a/src/components/panels/edit/modals/helpers/DetailsPanel.vue +++ b/src/components/panels/edit/modals/helpers/DetailsPanel.vue @@ -91,8 +91,7 @@ this.labelMap[key] : key }}: @@ -324,6 +323,12 @@ export default { }, methods: { + buildSource: function(source){ + if (source.includes("id.loc.gov")){ + source = source.replace(/(.*)(http.*id.loc.gov.*)$/g, '$1 $2') + } + return source + }, getUsabilityNote: function(data){ let notes = data.notes || [] let needsNote = notes.filter((i) => i.includes("CANNOT BE USED") ? true : false) diff --git a/src/lib/utils_network.js b/src/lib/utils_network.js index 2ff15df1..7c54bda3 100644 --- a/src/lib/utils_network.js +++ b/src/lib/utils_network.js @@ -20,7 +20,7 @@ const utilsNetwork = { lookupLibrary : {}, //Controllers to manage searches - controllers: { + controllers: { // there's got to be a better way "controllerNames": new AbortController(), "controllerNamesGeo": new AbortController(), "controllerNamesSubdivision": new AbortController(), @@ -45,6 +45,7 @@ const utilsNetwork = { "exactName": new AbortController(), "exactSubject": new AbortController(), "lccnSearchController": new AbortController(), + "controllerEntities": new AbortController(), }, subjectSearchActive: false, @@ -512,6 +513,8 @@ const utilsNetwork = { } } + console.info("payload: ", searchPayload) + let results = [] for (let url of urlTemplate) { // kind of hack, change to the public endpoint if we are in dev or public mode @@ -548,6 +551,7 @@ const utilsNetwork = { url = url.replace('searchtype=','searchtype=keyword') } + console.info("url: ", url) let r = await this.fetchSimpleLookup(url, false, searchPayload.signal) @@ -2415,6 +2419,7 @@ const utilsNetwork = { * @return {} - */ subjectSearch: async function(searchVal, complexVal, complexSub, mode){ + console.info("subjectSearch: ", searchVal, "--", mode) // subjectSearch: async function(searchVal, complexVal, mode){ //encode the URLs searchVal = encodeURIComponent(searchVal) @@ -2471,6 +2476,10 @@ const utilsNetwork = { let exactSubject = exactUri.replace('', 'subjects') //children's subjects is supported by known-label lookup? + let subjectEntitiesUrl = useConfigStore().lookupConfig['http://id.loc.gov/authorities/subjects'].modes[0]['ENTITIES'].url.replace('',searchVal).replace('&count=25','&count=50').replace("", "1") + + console.info("URL: ", subjectEntitiesUrl) + if (mode == 'GEO'){ subjectUrlHierarchicalGeographic = subjectUrlHierarchicalGeographic.replace('&count=4','&count=12').replace("", "1") } @@ -2641,6 +2650,14 @@ const utilsNetwork = { signal: this.controllers.controllerHubsKeyword.signal, } + let searchPayloadEntities = { + processor: 'lcAuthorities', + url: [subjectEntitiesUrl], + searchValue: searchVal, + subjectSearch: true, + signal: this.controllers.controllerEntities.signal, + } + let resultsNames =[] @@ -2667,6 +2684,8 @@ const utilsNetwork = { let resultsExactName = [] let resultsExactSubject = [] + let resultsEntities = [] + // this.searchExact(exactPayloadName), // this.searchExact(exactPayloadSubject), // resultsExactName, resultsExactSubject, @@ -2724,8 +2743,15 @@ const utilsNetwork = { this.searchComplex(searchPayloadHubsKeyword) ]); + } else if (mode == "ENTITIES"){ + [resultsEntities] = await Promise.all([ + this.searchComplex(searchPayloadEntities) + ]); } + console.info("entity search: ", searchPayloadEntities) + console.info("complex search: ", searchPayloadSubjectsComplex) + // drop the litearl value from names and complex if (resultsNames.length>0){ resultsNames.pop() @@ -2758,6 +2784,10 @@ const utilsNetwork = { resultsSubjectsSimpleComplex.push(resultsSubjectsSimpleComplex.pop()) } + if (resultsEntities.length>0){ + resultsEntities.push(resultsEntities.pop()) + } + // resultsSubjectsComplex.reverse() @@ -2843,6 +2873,10 @@ const utilsNetwork = { resultsPayloadSubjectsSimpleSubdivision = resultsSubjectsSimpleComplex.concat(resultsPayloadSubjectsSimpleSubdivision) } + + console.info("resultsSubjectsSimple: ", resultsSubjectsSimple) + console.info("entities: ", resultsEntities) + let results = { 'subjectsSimple': pos == 0 ? resultsSubjectsSimple : resultsPayloadSubjectsSimpleSubdivision, 'subjectsComplex': complexHeadings, @@ -2850,7 +2884,8 @@ const utilsNetwork = { 'hierarchicalGeographic': pos == 0 ? [] : resultsHierarchicalGeographic, 'subjectsChildren': pos == 0 ? resultsChildrenSubjects : resultsChildrenSubjectsSubdivisions, 'subjectsChildrenComplex': resultsChildrenSubjectsComplex, - 'exact': exact + 'exact': exact, + 'entities': resultsEntities, } this.subjectSearchActive = false diff --git a/src/stores/config.js b/src/stores/config.js index 17d61b6c..fe76344e 100644 --- a/src/stores/config.js +++ b/src/stores/config.js @@ -551,6 +551,7 @@ export const useConfigStore = defineStore('config', { 'LCSH Auth Subjects':{"url":"http://id.loc.gov/authorities/subjects/suggest2/?q=&memberOf=http://id.loc.gov/authorities/subjects/collection_LCSHAuthorizedHeadings&count=25&offset=&searchtype=left"}, 'LCSH SubDiv Subjects':{"url":"http://id.loc.gov/authorities/subjects/suggest2/?q=&memberOf=http://id.loc.gov/authorities/subjects/collection_Subdivisions&count=25&offset=&searchtype=left"}, 'LCSH GnFrm Subjects':{"url":"http://id.loc.gov/authorities/genreForms/suggest2/?q=&memberOf=http://id.loc.gov/authorities/genreForms/collection_LCGFT_General&count=25&offset=&searchtype=left"}, + 'ENTITIES': {"url":"https://id.loc.gov/entities/subjects/suggest2/?q=&count=25&offset=&searchtype=left"} } ] }, From 9be4c660c3881f8a723b3a09076351a4b4fa71f9 Mon Sep 17 00:00:00 2001 From: fo Date: Tue, 3 Feb 2026 18:40:26 +0000 Subject: [PATCH 2/5] Cleanup. XML was right --- .../panels/edit/modals/SubjectEditor.vue | 2 -- src/lib/utils_network.js | 14 -------------- 2 files changed, 16 deletions(-) diff --git a/src/components/panels/edit/modals/SubjectEditor.vue b/src/components/panels/edit/modals/SubjectEditor.vue index ebb46161..aaf8b3d2 100644 --- a/src/components/panels/edit/modals/SubjectEditor.vue +++ b/src/components/panels/edit/modals/SubjectEditor.vue @@ -1538,9 +1538,7 @@ export default { this.pickLookup[(this.searchResults.names.length - x) * -1 - 2] = this.searchResults.exact[x] } - console.info("entities: ", this.searchResults.entities) for (let x in this.searchResults.entities) { - console.info("pickup: ", x, "==", this.searchResults.entities[x]) this.pickLookup[x] = this.searchResults.entities[x] } diff --git a/src/lib/utils_network.js b/src/lib/utils_network.js index 7c54bda3..bab70077 100644 --- a/src/lib/utils_network.js +++ b/src/lib/utils_network.js @@ -513,8 +513,6 @@ const utilsNetwork = { } } - console.info("payload: ", searchPayload) - let results = [] for (let url of urlTemplate) { // kind of hack, change to the public endpoint if we are in dev or public mode @@ -551,8 +549,6 @@ const utilsNetwork = { url = url.replace('searchtype=','searchtype=keyword') } - console.info("url: ", url) - let r = await this.fetchSimpleLookup(url, false, searchPayload.signal) //Config only allows 25 results, this will add something to the results @@ -2419,7 +2415,6 @@ const utilsNetwork = { * @return {} - */ subjectSearch: async function(searchVal, complexVal, complexSub, mode){ - console.info("subjectSearch: ", searchVal, "--", mode) // subjectSearch: async function(searchVal, complexVal, mode){ //encode the URLs searchVal = encodeURIComponent(searchVal) @@ -2478,8 +2473,6 @@ const utilsNetwork = { let subjectEntitiesUrl = useConfigStore().lookupConfig['http://id.loc.gov/authorities/subjects'].modes[0]['ENTITIES'].url.replace('',searchVal).replace('&count=25','&count=50').replace("", "1") - console.info("URL: ", subjectEntitiesUrl) - if (mode == 'GEO'){ subjectUrlHierarchicalGeographic = subjectUrlHierarchicalGeographic.replace('&count=4','&count=12').replace("", "1") } @@ -2749,9 +2742,6 @@ const utilsNetwork = { ]); } - console.info("entity search: ", searchPayloadEntities) - console.info("complex search: ", searchPayloadSubjectsComplex) - // drop the litearl value from names and complex if (resultsNames.length>0){ resultsNames.pop() @@ -2873,10 +2863,6 @@ const utilsNetwork = { resultsPayloadSubjectsSimpleSubdivision = resultsSubjectsSimpleComplex.concat(resultsPayloadSubjectsSimpleSubdivision) } - - console.info("resultsSubjectsSimple: ", resultsSubjectsSimple) - console.info("entities: ", resultsEntities) - let results = { 'subjectsSimple': pos == 0 ? resultsSubjectsSimple : resultsPayloadSubjectsSimpleSubdivision, 'subjectsComplex': complexHeadings, From 0287f475be4cdd27055264a7d9517712cee99ec2 Mon Sep 17 00:00:00 2001 From: fo Date: Tue, 3 Feb 2026 18:48:52 +0000 Subject: [PATCH 3/5] version++, changelong update --- CHANGELOG.md | 4 ++++ src/stores/config.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06617405..9b191fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. +## [1.4.8] - 2025-02-03 +### Added +- Support for Subject Entities in Subject Builder + ## [1.4.7] - 2025-01-20 ### Changed - ClassWeb search will search `LCSH (w/names)` to do a combined search. diff --git a/src/stores/config.js b/src/stores/config.js index fe76344e..cd44990b 100644 --- a/src/stores/config.js +++ b/src/stores/config.js @@ -7,7 +7,7 @@ export const useConfigStore = defineStore('config', { versionMajor: 1, versionMinor: 4, - versionPatch: 7, + versionPatch: 8, From a931143f52e5b584cf9e0b5c06521d10c6defd3e Mon Sep 17 00:00:00 2001 From: fo Date: Tue, 3 Feb 2026 19:28:59 +0000 Subject: [PATCH 4/5] Limit to staging environment --- src/components/panels/edit/modals/SubjectEditor.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/panels/edit/modals/SubjectEditor.vue b/src/components/panels/edit/modals/SubjectEditor.vue index aaf8b3d2..c8413fa6 100644 --- a/src/components/panels/edit/modals/SubjectEditor.vue +++ b/src/components/panels/edit/modals/SubjectEditor.vue @@ -97,7 +97,7 @@ + :class="['simptip-position-bottom', { 'active': (searchMode === 'ENTITIES') }]" v-if="configStore.returnUrls.env == 'staging'">Entities @@ -879,6 +879,7 @@ export default { computed: { ...mapStores(usePreferenceStore), + ...mapStores(useConfigStore), ...mapState(usePreferenceStore, ['diacriticUseValues', 'diacriticUse', 'diacriticPacks']), ...mapState(useProfileStore, ['returnComponentByPropertyLabel', 'duplicateComponentGetId', 'isEmptyComponent']), From 3edaff285a47f2646e8744fc71628825849ebd92 Mon Sep 17 00:00:00 2001 From: fo Date: Tue, 3 Feb 2026 19:44:28 +0000 Subject: [PATCH 5/5] Update how dashes are handled --- src/components/panels/edit/modals/SubjectEditor.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/panels/edit/modals/SubjectEditor.vue b/src/components/panels/edit/modals/SubjectEditor.vue index c8413fa6..1c9b05bd 100644 --- a/src/components/panels/edit/modals/SubjectEditor.vue +++ b/src/components/panels/edit/modals/SubjectEditor.vue @@ -2231,7 +2231,9 @@ export default { this.searchModeSwitch("GEO") } else if (event.ctrlKey && event.key == "4") { this.searchModeSwitch("HUBS") - } else if (this.searchMode == 'GEO' && event.key == "-") { + } else if (event.ctrlKey && event.key == "5") { + this.searchModeSwitch("ENTITIES") + } else if ((this.searchMode == 'GEO' || this.searchMode == 'ENTITIES') && event.key == "-") { if (this.components.length > 0) { let lastC = this.components[this.components.length - 1]