From 43569c62bf73785bba6b23d48061f15a9af66765 Mon Sep 17 00:00:00 2001 From: StiftungAusNachlass Date: Tue, 10 Dec 2024 22:15:43 +0100 Subject: [PATCH] major improvements, see releasenotes v.1.1.0 --- l10n/customDataTypeFinto.csv | 9 + manifest.master.yml | 41 +++- manifest.yml | 89 ------- src/updater/FINTOUpdater.js | 229 ++++++++++++------ src/webfrontend/CustomDataTypeFINTO.coffee | 209 +++++++++++----- .../CustomDataTypeFINTOTreeview.coffee | 4 + src/webfrontend/FINTOUtilities.coffee | 86 +++++-- 7 files changed, 397 insertions(+), 270 deletions(-) mode change 100644 => 100755 l10n/customDataTypeFinto.csv delete mode 100755 manifest.yml diff --git a/l10n/customDataTypeFinto.csv b/l10n/customDataTypeFinto.csv old mode 100644 new mode 100755 index 899e553..66bd0ec --- a/l10n/customDataTypeFinto.csv +++ b/l10n/customDataTypeFinto.csv @@ -58,3 +58,12 @@ custom.data.type.commons.controls.search.label,Suchen,Search,Hae,Sök custom.data.type.commons.controls.detailinfo.label,Detailinfo, Details,Tiedot,Detaljer custom.data.type.commons.controls.calluri.label,Uri aufrufen,Call URI,Verkkolinkki,Öppna URI custom.data.type.commons.controls.delete.label,Löschen,Delete,Poista,Radera +server.config.parameter.system.mapbox.mapbox_api_key.label,Mapbox-Token,Mapbox-Token,Mapbox-Token,Mapbox-Token +server.config.parameter.system.mapbox.mapbox_style.label,Mapbox-Style,Mapbox-Style,Mapbox-Style,Mapbox-Style +server.config.name.system.mapbox,Mapbox-Konfiguration,Mapbox-Configuration,Mapbox-Configuration,Mapbox-Configuration +custom.data.type.finto.config.parameter.mask.display_multiple_languages_in_searchhits.value.label,Zeige mehrere Sprachen in Suchergebnisauswahl an(ISO 639-1 & komma-separatiert),Show multiple languages ​​in search result selection (ISO 639-1 & comma-separated),Näytä useita kieliä hakutulosten valinnassa (ISO 639-1 ja pilkuilla eroteltu),Visa flera språk i val av sökresultat (ISO 639-1 & kommaseparerad) +custom.data.type.finto.config.parameter.mask.editor_display.value.label,Editor-Ansicht,Editor-Display,Editor-Display,Editor-Display +custom.data.type.finto.config.option.mask.editor_display.value.default,Standard,Default,Default,Default +custom.data.type.finto.config.option.mask.editor_display.value.condensed,1 Zeile,One-liner,One-liner,One-liner +custom.data.type.finto.config.parameter.mask.use_dropdown_info_popup.value.label,Infopopup?,Infopopup?,Infopopup?,Infopopup? +custom.data.type.finto.config.parameter.mask.use_dropdown_info_popup.value.checkbox,Auch für Dropdown anzeigen,Show for dropdown too,Show for dropdown too,Show for dropdown too \ No newline at end of file diff --git a/manifest.master.yml b/manifest.master.yml index 2fa9971..467895b 100755 --- a/manifest.master.yml +++ b/manifest.master.yml @@ -1,7 +1,7 @@ plugin: name: custom-data-type-finto - version: 1.0 - url: https://github.com/programmfabrik/fylr-custom-data-type-finto + version: 1.1 + url: https://github.com/programmfabrik/fylr-plugin-custom-data-type-finto displayname: de-DE: FINTO-Verknüpfung en-US: FINTO-Referencing @@ -28,6 +28,8 @@ custom_types: type: text conceptAncestors: type: text + conceptGeoJSON: + type: geo_json conceptSource: type: text facetTerm: @@ -52,11 +54,26 @@ custom_types: value: type: select options: ["popover", "popover_treeview", "dropdown"] + - name: editor_display + parameters: + value: + type: select + options: ["default", "condensed"] + - name: use_dropdown_info_popup + parameters: + value: + type: bool - name: allow_label_choice parameters: value: type: bool + - name: display_multiple_languages_in_searchhits + parameters: + value: + type: text update: + plugin_user: + reference: system:root exec: service: "node" commands: @@ -70,20 +87,22 @@ custom_types: value: "%_exec.pluginDir%/updater/FintoUpdater.js" - type: "value" value: "%info.json%" - timeout: 60 - batch_size: 1 + timeout: 120 + batch_size: 10 expires_days: 1 - interval_base_config: update_interval_finto.days base_config: + - name: mapbox + group: mapbox + parameters: + mapbox_api_key: + type: text + mapbox_style: + type: text + default: "satellite-streets-v12" - name: update_interval_finto group: update_custom_data_type parameters: - days: - type: int - min: 0 - default: 0 - position: 0 default_language: type: text default: 'fi' - position: 1 + position: 1 \ No newline at end of file diff --git a/manifest.yml b/manifest.yml deleted file mode 100755 index b40e176..0000000 --- a/manifest.yml +++ /dev/null @@ -1,89 +0,0 @@ -plugin: - name: custom-data-type-finto - version: 1.0 - url: https://github.com/programmfabrik/fylr-custom-data-type-finto - displayname: - de-DE: FINTO-Verknüpfung - en-US: FINTO-Referencing - fi-FI: FINTO-Pikakuvake - sv-SE: FINTO-Genväg - info: - de-DE: Stellt Verknüpfungen zu dem finnischen Thesaurus- und Ontology-Service FINTO her - en-US: Links to the Finnish thesaurus and ontology service FINTO - fi-FI: Linkkejä suomalaiseen asiasanasto- ja ontologiapalveluun FINTO - sv-SE: Länkar till den finska tesaurus- och ontologitjänsten FINTO - l10n: l10n/customDataTypeFinto.csv - webfrontend: - url: customDataTypeFinto.js - css: customDataTypeFinto.css - -base_url_prefix: "webfrontend" - -custom_types: - finto: - mapping: - conceptName: - type: text - conceptURI: - type: text - conceptAncestors: - type: text - conceptSource: - type: text - facetTerm: - type: text_l10n - config: - schema: - - name: vocabulary_notation - parameters: - value: - type: text - - name: vocabulary_parent - parameters: - value: - type: text - - name: lang - parameters: - value: - type: text - mask: - - name: editor_style - parameters: - value: - type: select - options: ["popover", "popover_treeview", "dropdown"] - - name: allow_label_choice - parameters: - value: - type: bool - update: - exec: - service: "node" - commands: - - prog: "node" - stdin: - type: body - stdout: - type: body - args: - - type: "value" - value: "%_exec.pluginDir%/updater/customDataTypeFintoUpdater.js" - - type: "value" - value: "%info.json%" - timeout: 60 - batch_size: 1 - expires_days: 1 - interval_base_config: update_interval_finto.days -base_config: - - name: update_interval_finto - group: update_custom_data_type - parameters: - days: - type: int - min: 0 - default: 0 - position: 0 - default_language: - type: text - default: 'fi' - position: 1 diff --git a/src/updater/FINTOUpdater.js b/src/updater/FINTOUpdater.js index 3b4c9c6..72303f9 100755 --- a/src/updater/FINTOUpdater.js +++ b/src/updater/FINTOUpdater.js @@ -6,7 +6,15 @@ const fetch = (...args) => import('node-fetch').then(({ let databaseLanguages = []; let frontendLanguages = []; +let defaultLanguage = 'fi'; +let info = {} + +let access_token = ''; + +if (process.argv.length >= 3) { + info = JSON.parse(process.argv[2]) +} function hasChanges(objectOne, objectTwo) { var len; @@ -20,6 +28,28 @@ function hasChanges(objectOne, objectTwo) { return false; } +function getConfigFromAPI() { + return new Promise((resolve, reject) => { + var url = 'http://fylr.localhost:8081/api/v1/config?access_token=' + access_token + fetch(url, { + headers: { + 'Accept': 'application/json' + }, + }) + .then(response => { + if (response.ok) { + resolve(response.json()); + } else { + console.error("FINTO-Updater: Fehler bei der Anfrage an /config "); + } + }) + .catch(error => { + console.error(error); + console.error("FINTO-Updater: Fehler bei der Anfrage an /config"); + }); + }); +} + main = (payload) => { switch (payload.action) { case "start_update": @@ -39,7 +69,9 @@ main = (payload) => { // collect URIs let URIList = []; for (var i = 0; i < payload.objects.length; i++) { - URIList.push(payload.objects[i].data.conceptURI); + if(payload.objects[i].data.conceptURI && payload.objects[i].data.conceptSource) { + URIList.push(payload.objects[i].data.conceptURI + '@@@' + payload.objects[i].data.conceptSource); + } } // unique urilist URIList = [...new Set(URIList)] @@ -47,9 +79,12 @@ main = (payload) => { let requestUrls = []; let requests = []; - URIList.forEach((uri) => { + URIList.forEach((info) => { + let parts = info.split('@@@'); + const uri = parts[0]; + const vocNotation = parts[1]; let dataRequestUrl = 'https://api.finto.fi/rest/v1/data?uri=' + encodeURIComponent(uri) + '&format=application%2Fjson'; - let hierarchieRequestUrl = 'https://api.finto.fi/rest/v1/' + FINTOUtilities.getVocNotationFromURI(uri) + '/hierarchy?uri=' + encodeURIComponent(uri) + '&lang=fi&format=application%2Fjson'; + let hierarchieRequestUrl = 'https://api.finto.fi/rest/v1/' + vocNotation + '/hierarchy?uri=' + encodeURIComponent(uri) + '&lang=fi&format=application%2Fjson'; let dataRequest = fetch(dataRequestUrl); let hierarchieRequest = fetch(hierarchieRequestUrl); requests.push({ @@ -132,18 +167,28 @@ main = (payload) => { } }); if (resultJSON) { - // get desired language for preflabel. This is frontendlanguage from original data... - let desiredLanguage = originalCdata.frontendLanguage; + // get desired language for conceptName. This is frontendlanguage from original data or fallback + let frontendLanguage = defaultLanguage; + if (originalCdata.frontendLanguage) { + if (originalCdata.frontendLanguage.length == 2) { + frontendLanguage = originalCdata.frontendLanguage; + } + } // save conceptName - newCdata.conceptName = FINTOUtilities.getPrefLabelFromDataResult(resultJSON, desiredLanguage, frontendLanguages); + newCdata.conceptName = FINTOUtilities.getPrefLabelFromDataResult(resultJSON, databaseLanguages, frontendLanguage) // save conceptURI newCdata.conceptURI = uri; // save conceptSource - newCdata.conceptSource = FINTOUtilities.getVocNotationFromURI(uri); + newCdata.conceptSource = originalCdata.conceptSource; // save _fulltext newCdata._fulltext = FINTOUtilities.getFullTextFromJSONObject(resultJSON, databaseLanguages); // save _standard newCdata._standard = FINTOUtilities.getStandardFromJSONObject(resultJSON, databaseLanguages); + // save geo (alsonin _standard) + geoJSON = FINTOUtilities.getGeoJSONFromFINTOJSON(resultJSON); + if(geoJSON) { + newCdata.conceptGeoJSON = geoJSON; + } // save facet newCdata.facetTerm = FINTOUtilities.getFacetTermFromJSONObject(resultJSON, databaseLanguages); // save frontend language (same as given) @@ -153,44 +198,53 @@ main = (payload) => { /////////////////////////////////////////////////////// // ancestors + newCdata.conceptAncestors = []; + if(originalCdata.conceptAncestors) { + newCdata.conceptAncestors = originalCdata.conceptAncestors; + } if (matchingRecordHierarchy.requestType == 'broader') { - let hierarchyJSON = matchingRecordHierarchy.data.broaderTransitive - // save ancestors if treeview, add ancestors - newCdata.conceptAncestors = []; - for (let i = 1; i < Object.keys(hierarchyJSON).length; i++) { - for (let [hierarchyKey, hierarchyValue] of Object.entries(hierarchyJSON)) { - if (hierarchyKey !== uri) { - // check if hierarchy-entry contains the actual record in narrowers - // or if the narrower of the hierarchy-entry contains one of the already set ancestors - let isnarrower = false; - if (hierarchyValue.narrower) { - if (!Array.isArray(hierarchyValue.narrower)) { - hierarchyValue.narrower = [hierarchyValue.narrower]; - } - for (let narrower of hierarchyValue.narrower) { - if (narrower.uri === uri) { - if (!newCdata.conceptAncestors.includes(hierarchyValue.uri)) { - newCdata.conceptAncestors.push(hierarchyValue.uri); + if(matchingRecordHierarchy.data != null) { + if(matchingRecordHierarchy.data.broaderTransitive) { + newCdata.conceptAncestors = []; + let hierarchyJSON = matchingRecordHierarchy.data.broaderTransitive + // save ancestors if treeview, add ancestors + + for (let i = 1; i < Object.keys(hierarchyJSON).length; i++) { + for (let [hierarchyKey, hierarchyValue] of Object.entries(hierarchyJSON)) { + if (hierarchyKey !== uri) { + // check if hierarchy-entry contains the actual record in narrowers + // or if the narrower of the hierarchy-entry contains one of the already set ancestors + let isnarrower = false; + if (hierarchyValue.narrower) { + if (!Array.isArray(hierarchyValue.narrower)) { + hierarchyValue.narrower = [hierarchyValue.narrower]; } - } else if (newCdata.conceptAncestors.includes(narrower.uri)) { - if (!newCdata.conceptAncestors.includes(hierarchyValue.uri)) { - newCdata.conceptAncestors.push(hierarchyValue.uri); + for (let narrower of hierarchyValue.narrower) { + if (narrower.uri === uri) { + if (!newCdata.conceptAncestors.includes(hierarchyValue.uri)) { + newCdata.conceptAncestors.push(hierarchyValue.uri); + } + } else if (newCdata.conceptAncestors.includes(narrower.uri)) { + if (!newCdata.conceptAncestors.includes(hierarchyValue.uri)) { + newCdata.conceptAncestors.push(hierarchyValue.uri); + } + } } } } } } } + // add own uri to ancestor-uris + newCdata.conceptAncestors.push(uri); + // merge ancestors to string + newCdata.conceptAncestors = newCdata.conceptAncestors.join(' '); } - // add own uri to ancestor-uris - newCdata.conceptAncestors.push(uri); - // merge ancestors to string - newCdata.conceptAncestors = newCdata.conceptAncestors.join(' '); - - if (hasChanges(payload.objects[index].data, newCdata)) { - payload.objects[index].data = newCdata; - } else {} } + if (hasChanges(payload.objects[index].data, newCdata)) { + payload.objects[index].data = newCdata; + } else {} + } else { console.error('No matching record found'); } @@ -242,56 +296,73 @@ outputErr = (err2) => { process.stdin.setEncoding('utf8'); - //////////////////////////////////////////////////////////////////////////// - // get config and read the languages - //////////////////////////////////////////////////////////////////////////// + access_token = info && info.plugin_user_access_token; + + if(access_token) { - let config = JSON.parse(process.argv[2]); + //////////////////////////////////////////////////////////////////////////// + // get config and read the languages + //////////////////////////////////////////////////////////////////////////// - databaseLanguages = config.config.system.config.languages.database; - databaseLanguages = databaseLanguages.map((value, key, array) => { - return value.value; - }); + getConfigFromAPI().then(config => { + databaseLanguages = config.system.config.languages.database; + databaseLanguages = databaseLanguages.map((value, key, array) => { + return value.value; + }); - frontendLanguages = config.config.system.config.languages.frontend; + frontendLanguages = config.system.config.languages.frontend; - //////////////////////////////////////////////////////////////////////////// - // availabilityCheck for finto-api - //////////////////////////////////////////////////////////////////////////// - https.get('https://api.finto.fi/rest/v1/vocabularies?lang=fi', res => { - let testData = []; - res.on('data', chunk => { - testData.push(chunk); - }); - res.on('end', () => { - const vocabs = JSON.parse(Buffer.concat(testData).toString()); - if (vocabs.vocabularies) { - //////////////////////////////////////////////////////////////////////////// - // test successfull --> continue with custom-data-type-update - //////////////////////////////////////////////////////////////////////////// - process.stdin.on('readable', () => { - let chunk; - while ((chunk = process.stdin.read()) !== null) { - data = data + chunk + const testDefaultLanguageConfig = config.plugin['custom-data-type-finto'].config.update_interval_finto.default_language; + if (testDefaultLanguageConfig) { + if (testDefaultLanguageConfig.length == 2) { + defaultLanguage = testDefaultLanguageConfig; } + } + + //////////////////////////////////////////////////////////////////////////// + // availabilityCheck for finto-api + //////////////////////////////////////////////////////////////////////////// + https.get('https://api.finto.fi/rest/v1/vocabularies?lang=fi', res => { + let testData = []; + res.on('data', chunk => { + testData.push(chunk); }); - process.stdin.on('end', () => { - /////////////////////////////////////// - // continue with update-routine - /////////////////////////////////////// - try { - let payload = JSON.parse(data) - main(payload) - } catch (error) { - console.error("caught error", error) - outputErr(error) + res.on('end', () => { + const vocabs = JSON.parse(Buffer.concat(testData).toString()); + if (vocabs.vocabularies) { + //////////////////////////////////////////////////////////////////////////// + // test successfull --> continue with custom-data-type-update + //////////////////////////////////////////////////////////////////////////// + process.stdin.on('readable', () => { + let chunk; + while ((chunk = process.stdin.read()) !== null) { + data = data + chunk + } + }); + process.stdin.on('end', () => { + /////////////////////////////////////// + // continue with update-routine + /////////////////////////////////////// + try { + let payload = JSON.parse(data) + main(payload) + } catch (error) { + console.error("caught error", error) + outputErr(error) + } + }); + } else { + console.error('Error while interpreting data from api.finto.fi: ', err.message); } }); - } else { - console.error('Error while interpreting data from api.finto.fi: ', err.message); - } - }); - }).on('error', err => { - console.error('Error while receiving data from api.finto.fi: ', err.message); - }); + }).on('error', err => { + console.error('Error while receiving data from api.finto.fi: ', err.message); + }); + }).catch(error => { + console.error('Es gab einen Fehler beim Laden der Konfiguration:', error); + }); + } + else { + console.error("kein Accesstoken gefunden"); + } })(); \ No newline at end of file diff --git a/src/webfrontend/CustomDataTypeFINTO.coffee b/src/webfrontend/CustomDataTypeFINTO.coffee index 433731a..2e6010a 100755 --- a/src/webfrontend/CustomDataTypeFINTO.coffee +++ b/src/webfrontend/CustomDataTypeFINTO.coffee @@ -4,9 +4,7 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons # configure used facet getFacet: (opts) -> opts.field = @ - new CustomDataTypeCommonFacet(opts) - # TODO - # new CustomDataTypeFINTOFacet(opts) + new CustomDataTypeFINTOFacet(opts) ####################################################################### # return name of plugin @@ -59,8 +57,21 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons desiredLanguage = desiredLanguage.split('-') language = desiredLanguage[0] + if language == '*' + language = '' + return language + + ####################################################################### + # get active frontend language + getActiveFrontendLanguage: () -> + frontendLanguage = ez5.loca.getLanguage() + frontendLanguage = frontendLanguage.split('-') + frontendLanguage = frontendLanguage[0] + + return frontendLanguage + ####################################################################### # returns the databaseLanguages getDatabaseLanguages: () -> @@ -421,23 +432,46 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons # a list of the unique text suggestions for treeview-suggest unique_text_suggestions = [] unique_text_items = [] + + uriOrderedRecords = [] for recordKey, record of data + if ! uriOrderedRecords[record.uri] + uriOrderedRecords[record.uri] = [] + uriOrderedRecords[record.uri].push record + + for recordsURI, records of uriOrderedRecords vocab = 'default' if showHeadlines - vocab = record.vocab + vocab = records[0].vocab if ! Array.isArray tmp_items[vocab] tmp_items[vocab] = [] - do(record) -> + do(records) -> + # check and get if record exists in frontendlanguage in results + prefLabel = records[0].prefLabel; + for recordKey, record of records + if record.lang == that.getActiveFrontendLanguage() + prefLabel = record.prefLabel + continue + # if labels are wanted it multiple languages (test with "joe") + langLabels = [] + if that.getCustomMaskSettings()?.display_multiple_languages_in_searchhits?.value + langEntries = that.getCustomMaskSettings().display_multiple_languages_in_searchhits.value.split(',') + for recordKey, record of records + if langEntries.includes record.lang + langLabels.push record.prefLabel + langLabels = Array.from new Set langLabels + if langLabels.length > 0 + prefLabel = langLabels.join(' / ') # new item item = - text: record.prefLabel - value: record.uri + '@' + record.vocab + text: prefLabel + value: records[0].uri + '@' + records[0].vocab tooltip: markdown: true placement: "ne" content: (tooltip) -> # show infopopup - encodedURI = encodeURIComponent(record.uri) + encodedURI = encodeURIComponent(records[0].uri) that.__getAdditionalTooltipInfo(encodedURI, tooltip, extendedInfo_xhr) new CUI.Label(icon: "spinner", text: $$('custom.data.type.finto.modal.form.popup.loadingstring')) tmp_items[vocab].push item @@ -496,18 +530,13 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons ] that.popover.setContent(newLoaderPanel) - # if treeview in popup also get the ancestors - ancestors = ''; - #if that.renderPopupAsTreeview() && ! that.popover - if that.renderPopupAsTreeview() - ancestors = ',ancestors' - # get full record to get correct preflabel in desired language # load the record itself and also the hierarchie of the record allDataAPIPath = location.protocol + '//api.finto.fi/rest/v1/data?uri=' + encodeURIComponent(searchUri) + '&format=application%2Fjson' # XHR for basic information dataEntry_xhr = new (CUI.XHR)(url: allDataAPIPath) dataEntry_xhr.start().done((resultJSON, status, statusText) -> + # xhr for hierarchy-informations to fill "conceptAncestors" allHierarchyAPIPath = location.protocol + '//api.finto.fi/rest/v1/' + recordsOriginalVocab + '/hierarchy?uri=' + encodeURIComponent(searchUri) + '&lang=' + that.getLanguageParameterForRequests() + '&format=application%2Fjson' @@ -521,11 +550,11 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons resultJSON = json databaseLanguages = that.getDatabaseLanguages() - frontendLanguages = that.getFrontendLanguages() + frontendLanguage = that.getActiveFrontendLanguage() desiredLanguage = that.getLanguageParameterForRequests() # save conceptName - cdata.conceptName = FINTOUtilities.getPrefLabelFromDataResult(resultJSON, desiredLanguage, frontendLanguages) + cdata.conceptName = FINTOUtilities.getPrefLabelFromDataResult(resultJSON, databaseLanguages, frontendLanguage) # save conceptURI cdata.conceptURI = resultJSON.uri # save conceptSource @@ -536,8 +565,13 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons cdata._standard = FINTOUtilities.getStandardFromJSONObject(resultJSON, databaseLanguages) # save facet cdata.facetTerm = FINTOUtilities.getFacetTermFromJSONObject(resultJSON, databaseLanguages) + # save geo (also in _standard) + geoJSON = FINTOUtilities.getGeoJSONFromFINTOJSON(resultJSON) + if geoJSON + cdata.conceptGeoJSON = geoJSON + # save frontendlanguage - cdata.frontendLanguage = that.getLanguageParameterForRequests() + cdata.frontendLanguage = that.getActiveFrontendLanguage() # save ancestors if treeview, add ancestors cdata.conceptAncestors = [] @@ -570,17 +604,6 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons else anchor = input that.__chooseLabelManually(cdata, layout, resultJSON, anchor, opts) - # user is not allowed to choose-label manually --> choose prefLabel in default language - else - foundMatchingLabel = false - if resultJSON.prefLabel.length > 0 - for prefLabelKey, prefLabelValue of resultJSON.prefLabel - if prefLabelValue.lang == that.getLanguageParameterForRequests() - cdata.conceptName = prefLabelValue.value - foundMatchingLabel = true - - if ! foundMatchingLabel - cdata.conceptName = resultJSON.prefLabel[Object.keys(resultJSON.prefLabel)[0]].value # update the layout in form that.__updateResult(cdata, layout, opts) # close popover @@ -591,6 +614,24 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons # is this from exact search and user has to choose exact-search-mode?! if that._finto_opts?.callFromExpertSearch == true CustomDataTypeFINTO.prototype.__chooseExpertHierarchicalSearchMode(that._cdata, that._editor_layout, resultJSON, that._editor_layout, that._finto_opts) + + if opts?.data + opts.data[that.name(opts)] = CUI.util.copyObject(cdata) + + CUI.Events.trigger + node: layout + type: "editor-changed" + CUI.Events.trigger + node: layout + type: "data-changed" + + # update the layout in form + that.__updateResult(cdata, layout, opts) + # close popover + if that.popover + that.popover.hide() + @ + ) ) @@ -653,6 +694,17 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons __renderEditorInputInline: (data, cdata, opts = {}) -> that = @ + extendedInfo_xhr = { "xhr" : undefined } + + # if multible vocabularys are given, show only the first one in dropdown + voc = 'yso' + vocTest = @getVocabularyNameFromDatamodel(opts) + vocTest = vocTest.split('|') + if(vocTest.length > 1) + voc = vocTest[0] + else + voc = @getVocabularyNameFromDatamodel(opts) + fields = [] select = { type: CUI.Select @@ -663,14 +715,6 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons dfr = new CUI.Deferred() values = [] - # if multible vocabularys are given, show only the first one in dropdown - vocTest = @getVocabularyNameFromDatamodel(opts) - vocTest = vocTest.split('|') - if(vocTest.length > 1) - voc = vocTest[0] - else - voc = @getVocabularyNameFromDatamodel(opts) - # parent-parameter? parentParameter = '123' if that.getCustomSchemaSettings()?.vocabulary_parent?.value @@ -690,15 +734,26 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons data = data.narrowerTransitive for key, suggestion of data - label = suggestion.prefLabel - if ! label - label = $$('custom.data.type.finto.modal.form.dropdown.nolabelinlanguagefound') - if suggestion.uri != parentParameter - item = ( - text: label - value: suggestion.uri - ) - select_items.push item + do(key) -> + label = suggestion.prefLabel + if ! label + label = $$('custom.data.type.finto.modal.form.dropdown.nolabelinlanguagefound') + if suggestion.uri != parentParameter + item = ( + text: label + value: suggestion.uri + ) + # only show tooltip, if configures in datamodel + if that.getCustomMaskSettings()?.use_dropdown_info_popup?.value + item.tooltip = + markdown: true + placement: 'nw' + content: (tooltip) -> + # get jskos-details-data + that.__getAdditionalTooltipInfo(data[key].uri, tooltip, extendedInfo_xhr) + # loader, until details are xhred + new CUI.Label(icon: "spinner", text: $$('custom.data.type.finto.modal.form.popup.loadingstring')) + select_items.push item # if cdata is already set, choose correspondending option from select if cdata?.conceptURI != '' @@ -748,11 +803,15 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons # save conceptURI cdata.conceptURI = resultJSON.uri # save conceptSource - cdata.conceptSource = FINTOUtilities.getVocNotationFromURI(resultJSON.uri) + cdata.conceptSource = voc # save _fulltext cdata._fulltext = FINTOUtilities.getFullTextFromJSONObject(resultJSON, databaseLanguages) # save _standard cdata._standard = FINTOUtilities.getStandardFromJSONObject(resultJSON, databaseLanguages) + # save geo (also in _standard) + geoJSON = FINTOUtilities.getGeoJSONFromFINTOJSON(resultJSON) + if geoJSON + cdata.conceptGeoJSON = geoJSON # save facet cdata.facetTerm = FINTOUtilities.getFacetTermFromJSONObject(resultJSON, databaseLanguages) # save frontendlanguage @@ -789,7 +848,7 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons extendedInfo_xhr.xhr = new (CUI.XHR)(url: location.protocol + '//api.finto.fi/rest/v1/data?uri=' + uri + '&format=application%2Fjson') extendedInfo_xhr.xhr.start() .done((data, status, statusText) -> - htmlContent = FINTOUtilities.getJSONPreview(data, decodeURIComponent(uri), that.getLanguageParameterForRequests(), that.getFrontendLanguages()) + htmlContent = FINTOUtilities.getJSONPreview(that, data, decodeURIComponent(uri), that.getLanguageParameterForRequests(), that.getDatabaseLanguages(), that.getFrontendLanguages()) tooltip.DOM.innerHTML = htmlContent tooltip.autoSize() ) @@ -808,11 +867,13 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons # get vocparameter from dropdown, if available... popoverVocabularySelectTest = cdata_form.getFieldsByName("finto_PopoverVocabularySelect")[0] if popoverVocabularySelectTest?.getValue() - vocParameter = popoverVocabularySelectTest?.getValue() + vocParameter = popoverVocabularySelectTest.getValue() else - # else get first voc from given voclist (1-n) + # else get first voc from given voclist vocParameter = that.getActiveVocabularyName(cdata) - vocParameter = vocParameter.split('|') + vocParameter = vocParameter.replace /,/g, " " + vocParameter = vocParameter.replace /\|/g, " " + vocParameter = vocParameter.split(' ') vocParameter = vocParameter[0] treeview = new FINTO_ListViewTree(popover, layout, cdata, cdata_form, that, opts, vocParameter) @@ -828,6 +889,8 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons center: content: [ treeview.treeview + , + cdata_form ] @popover.setContent(treeviewPane) @@ -866,6 +929,7 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons searchbar = cdata_form.getFieldsByName("searchbarInput")[0] if searchbar searchbar.reset() + searchbar.setValue('') # init xhr-object to abort running xhrs searchsuggest_xhr = { "xhr" : undefined } @@ -879,14 +943,16 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons if elem.opts.name == 'finto_PopoverVocabularySelect' && that.renderPopupAsTreeview() @buildAndSetTreeviewLayout(@popover, layout, cdata, cdata_form, that, false, opts) that.__setEditorFieldStatus(cdata, layout) - if elem.opts.name == 'searchbarInput' || elem.opts.name == 'finto_PopoverVocabularySelect' || elem.opts.name == 'finto_countSuggestions' + if (elem.opts.name == 'searchbarInput' || elem.opts.name == 'finto_PopoverVocabularySelect' || elem.opts.name == 'finto_countSuggestions') && ! that.renderPopupAsTreeview() that.__updateSuggestionsMenu(cdata, cdata_form, data.searchbarInput, elem, suggest_Menu, searchsuggest_xhr, layout, opts) .start() # init suggestmenu - suggest_Menu = new CUI.Menu - element : cdata_form.getFieldsByName("searchbarInput")[0] - use_element_width_as_min_width: true + suggest_Menu = cdata_form.getFieldsByName("searchbarInput")[0] + if suggest_Menu + suggest_Menu= new CUI.Menu + element : cdata_form.getFieldsByName("searchbarInput")[0] + use_element_width_as_min_width: true # treeview? if that.renderPopupAsTreeview() @@ -928,7 +994,7 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons # start new request and download all vocabulary-informations searchsuggest_xhr = new (CUI.XHR)(url: location.protocol + '//api.finto.fi/rest/v1/vocabularies?lang=' + that.getLanguageParameterForRequests()) searchsuggest_xhr.start().done((data, status, statusText) -> - # read options for select + # enter the vocs to select in same order as in given in datamodell, because result from api is more or less random select_items = [] # allow to choose all vocs only, if not treeview if ! that.renderPopupAsTreeview() @@ -937,14 +1003,15 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons value: that.getVocabularyNameFromDatamodel() ) select_items.push item - for entry, key in data.vocabularies - # add vocs to select - if splittedVocs.includes(entry.id) - item = ( - text: entry.title - value: entry.id - ) - select_items.push item + for splittedVoc, splittedVocKey in splittedVocs + for entry, key in data.vocabularies + # add vocs to select + if splittedVoc == entry.id + item = ( + text: entry.title + value: entry.id + ) + select_items.push item thisSelect.enable() dfr.resolve(select_items) @@ -981,7 +1048,9 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons ] } - fields.push maxhits + # not in popover-mode + if ! that.renderPopupAsTreeview() + fields.push maxhits # searchfield (autocomplete) option = { @@ -993,7 +1062,9 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons placeholder: $$("custom.data.type.finto.modal.form.text.searchbar.placeholder") name: "searchbarInput" } - fields.push option + # not in popover-mode + if ! that.renderPopupAsTreeview() + fields.push option fields @@ -1012,6 +1083,12 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons extendedInfo_xhr = { "xhr" : undefined } + # show label of button in active frontendlanguage, if possible, else fallback to conceptName + label = cdata.conceptName + if cdata?._standard?.l10ntext + if cdata._standard?.l10ntext[ez5.loca.getLanguage()] + label = cdata._standard?.l10ntext[ez5.loca.getLanguage()] + # output Button with Name of picked finto-Entry and URI encodedURI = encodeURIComponent(cdata.conceptURI) new CUI.HorizontalLayout @@ -1020,7 +1097,7 @@ class CustomDataTypeFINTO extends CustomDataTypeWithCommons content: new CUI.Label centered: false - text: cdata.conceptName + text: label center: content: new CUI.ButtonHref diff --git a/src/webfrontend/CustomDataTypeFINTOTreeview.coffee b/src/webfrontend/CustomDataTypeFINTOTreeview.coffee index 0dff151..7470579 100755 --- a/src/webfrontend/CustomDataTypeFINTOTreeview.coffee +++ b/src/webfrontend/CustomDataTypeFINTOTreeview.coffee @@ -255,6 +255,10 @@ class FINTO_ListViewTreeNode extends CUI.ListViewTreeNode that._cdata._fulltext = FINTOUtilities.getFullTextFromJSONObject(resultJSON, databaseLanguages) # save _standard that._cdata._standard = FINTOUtilities.getStandardFromJSONObject(resultJSON, databaseLanguages) + # save geo (also in _standard) + geoJSON = FINTOUtilities.getGeoJSONFromFINTOJSON(resultJSON) + if geoJSON + that._cdata.conceptGeoJSON = geoJSON # save facet that._cdata.facetTerm = FINTOUtilities.getFacetTermFromJSONObject(resultJSON, databaseLanguages) # save frontendlanguage diff --git a/src/webfrontend/FINTOUtilities.coffee b/src/webfrontend/FINTOUtilities.coffee index 930fbf8..1098adc 100755 --- a/src/webfrontend/FINTOUtilities.coffee +++ b/src/webfrontend/FINTOUtilities.coffee @@ -47,6 +47,21 @@ class FINTOUtilities else return false + ######################################################################## + # extract geoinformation and make geojson + @getGeoJSONFromFINTOJSON: (object) -> + + geoJSON = false + coordsFound = false + + # lat + lng? + if object? and object['http://www.w3.org/2003/01/geo/wgs84_pos#lat']? and object['http://www.w3.org/2003/01/geo/wgs84_pos#long']? + geoJSON = + type: "Point" + coordinates: [object['http://www.w3.org/2003/01/geo/wgs84_pos#long']*1, object['http://www.w3.org/2003/01/geo/wgs84_pos#lat']*1] + coordsFound = true + + return geoJSON ######################################################################## # generates the fulltext for a given graph-record @@ -160,6 +175,12 @@ class FINTOUtilities # if l10n-object is not empty _standard.l10ntext = l10nObject + + # add geojson, if given + geoJSON = @getGeoJSONFromFINTOJSON json + if geoJSON + _standard.geo = geoJSON + return _standard @@ -214,7 +235,7 @@ class FINTOUtilities ############################################################################# # generates a html-preview for a given json-record ############################################################################# - @getJSONPreview = (data, uri, desiredLanguage, frontendLanguages) -> + @getJSONPreview = (context, data, uri, desiredLanguage, databaseLanguages, frontendLanguages) -> that = @ html = '' @@ -225,7 +246,7 @@ class FINTOUtilities if record.uri == uri prefLabel = $$('custom.data.type.finto.modal.form.popup.jsonpreview.nopreflabel') if record?.prefLabel - prefLabel = that.getPrefLabelFromDataResult(record, desiredLanguage, frontendLanguages) + prefLabel = that.getPrefLabelFromDataResult(record, desiredLanguage, databaseLanguages, frontendLanguages) html += '
 ' + record.uri + '
' @@ -306,27 +327,47 @@ class FINTOUtilities if note html += '

' + $$('custom.data.type.finto.modal.form.popup.jsonpreview.note') + '

' + note - html = '
' + html + '
' - return html - - - ############################################################################ - # get vocabulary-notation from finto-uri - ############################################################################ - - @getVocNotationFromURI: (uri) -> - uri = decodeURIComponent(uri) - uri = uri.replace('http://www.yso.fi/onto/', '') - uriParts = uri.split('/') - notation = uriParts[0] + # map (if mapbox-token is given) + baseConfig = ez5.session.getBaseConfig("plugin", "custom-data-type-finto") + if baseConfig?.mapbox?.mapbox_api_key + geoJSON = that.getGeoJSONFromFINTOJSON(record) + if geoJSON + mapbox_api_key = baseConfig.mapbox.mapbox_api_key + wrappedGeoJSON = JSON.parse('{"geometry":' + JSON.stringify(geoJSON) + '}') + + # generates static mapbox-map via geojson + jsonStr = '{"type": "FeatureCollection","features": [{"geometry":{}}]}' + fullgeoJSON = JSON.parse(jsonStr) + + fullgeoJSON.features[0].geometry = geoJSON + + bounds = geojsonExtent(fullgeoJSON) + if bounds + size = [ + 500 + 300 + ] + vp = geoViewport.viewport(bounds, size) + encodedGeoJSON = wrappedGeoJSON + encodedGeoJSON.properties = {} + encodedGeoJSON.type = "Feature" + encodedGeoJSON.properties['stroke-width'] = 4 + encodedGeoJSON.properties['stroke'] = '#C20000' + encodedGeoJSON = JSON.stringify(encodedGeoJSON) + encodedGeoJSON = encodeURIComponent(encodedGeoJSON) + if vp.zoom > 16 + vp.zoom = 12; + imageSrc = 'https://api.mapbox.com/styles/v1/mapbox/' + baseConfig.mapbox.mapbox_style + '/static/geojson(' + encodedGeoJSON + ')/' + vp.center.join(',') + ',' + vp.zoom + '/' + size.join('x') + '@2x?access_token=' + mapbox_api_key + html += '
' - notation + html = '
' + html + '
' + return html ############################################################################# # get prefLabel from json (preferred in active Frontend-Language) ############################################################################# - @getPrefLabelFromDataResult = (json, desiredLanguage, frontendLanguages) -> + @getPrefLabelFromDataResult = (json, databaseLanguages, activeFrontendLanguage) -> if typeof $$ != "undefined" prefLabelFallback = $$("custom.data.type.finto.modal.form.popup.treeview.nopreflabel") else @@ -337,11 +378,6 @@ class FINTOUtilities prefLabel = prefLabelFallback; - for key, value of frontendLanguages - tmp = value.split('-') - tmp = tmp[0] - frontendLanguages[key] = tmp - # if only 1 preflabel, than as object if ! Array.isArray json.prefLabel if json.prefLabel.value @@ -349,12 +385,12 @@ class FINTOUtilities # try to find label in given frontend-language for key, value of json.prefLabel - if value.lang == desiredLanguage + if value.lang == activeFrontendLanguage return value.value - # if no preflabel in active frontendlanguage, choose a random label from configured frontendlanguages + # if no preflabel in active frontendlanguage, choose a random label for key, value of json.prefLabel - if frontendLanguages.includes value.lang + if databaseLanguages.includes value.lang return value.value # else a random language