import filterMapping from "@/data/FiltersLabelMapping.json"; import Client from "@/lib/GraphClient/GraphClient.js"; import recordsQuery from "@/lib/GraphClient/queries/getRecords.json"; let client = new Client(); export const mutations = { setCollectionIdsParam(state, collectionIDs) { state.collectionIDs = collectionIDs; state.params["ids"] = collectionIDs; }, setRecords(state, data) { state.records = data["records"]; state.facets = buildFacets(data["aggregations"]); state.totalPages = data["totalPages"]; state.perPage = data["perPage"]; state.currentPage = data["currentPage"]; state.hits = data["totalCount"]; }, resetRecords(state) { recordsQuery.queryParam = null; state.records = []; }, resetPages(state) { state.hits = null; state.perPage = null; state.currentPage = 1; state.totalPages = null; }, setLoadingStatus(state, status) { state.loading = status; }, cleanRecordsStore(state) { state.params = { ids: [] }; state.collectionIDs = []; state.records = []; state.facets = []; state.hits = null; state.loading = false; state.totalPages = null; state.perPage = null; state.currentPage = 1; }, }; export const actions = { async initializeCollectionRecords(state, collectionIDs) { this.commit("records/setCollectionIdsParam", collectionIDs); this.commit("records/setLoadingStatus", true); this.commit("records/resetRecords"); this.commit("records/resetPages"); recordsQuery.queryParam = state.state.params; let data; try { data = await client.executeQuery(recordsQuery); this.commit("records/setRecords", data["searchFairsharingRecords"]); this.commit("records/setLoadingStatus", false); } catch { // Loading complete, but no data returned... this.commit("records/setRecords", { records: [] }); } }, async fetchCollectionRecords(state, options) { let params = options.params; let token = options.token; this.commit("records/setLoadingStatus", true); this.commit("records/resetRecords"); this.commit("records/resetPages"); //initialize params state state.state.params = { ids: [...state.state.params.ids] }; Object.keys(params).forEach((key) => { state.state.params[key] = params[key]; }); recordsQuery.queryParam = state.state.params; let data; try { if (token) { client.setHeader(token); } data = await client.executeQuery(recordsQuery); this.commit("records/setRecords", data["searchFairsharingRecords"]); this.commit("records/setLoadingStatus", false); } catch { // Loading complete, but no data returned... this.commit("records/setRecords", { records: [] }); } }, async fetchRecords(state, options) { let params = options.params; let token = options.token; this.commit("records/setLoadingStatus", true); this.commit("records/resetRecords"); this.commit("records/resetPages"); // params['q'] needs to be sanitised here. if (Object.keys(params).length > 0) { if ("q" in params) { // TODO: Is it worth preserving foreign characters as discussed here? // https://stackoverflow.com/questions/22192458/how-to-remove-non-alphanumeric-characters-and-space-but-keep-foreign-language-i const cleaned = params["q"].replace(/[^0-9a-z\s]/gi, ""); const newParams = { ...params, q: cleaned }; recordsQuery.queryParam = newParams; } else { recordsQuery.queryParam = params; } } let data; try { if (token) { client.setHeader(token); } data = await client.executeQuery(recordsQuery); // See: https://github.com/FAIRsharing/FAIRsharing-API/issues/532 if (data["error"] === "invalid query") { this.commit("records/setRecords", { aggregations: { is_invalid: { meta: {}, doc_count: 1, doc_count_error_upper_bound: 1, sum_other_doc_count: 1, buckets: [{ key: 1, key_as_string: "true", doc_count: 1 }], }, }, records: [], }); } else { this.commit("records/setRecords", data["searchFairsharingRecords"]); } this.commit("records/setLoadingStatus", false); } catch { // Loading complete, but no data returned... /* istanbul ignore next */ this.commit("records/setRecords", { records: [] }); } }, resetRecords() { this.commit("records/resetRecords"); }, }; export const getters = { getFilter: (state) => (facetName) => { if (state.facets.length > 0) { let currentFacet = JSON.parse( JSON.stringify( state.facets.find((facet) => facet.filterName === facetName) ) ); currentFacet["values"] = currentFacet["buckets"]; return currentFacet; } return []; }, getRecordsLength: (state) => { return state.records.length; }, getCollectionIdsParams: (state) => { return state.collectionIDs; }, }; /** * The records store handles the requests related to records (searchFairsharingRecords and fairsharingRecord). * @type {Object} */ let recordsStore = { namespaced: true, state: { params: { ids: [] }, collectionIDs: [], records: [], facets: [], hits: null, loading: false, totalPages: null, perPage: null, currentPage: 1, }, mutations: mutations, actions: actions, getters: getters, }; export default recordsStore; /** * Given an object containing the raw facets coming from the client and a mapping object , build the ready to use facets * for usage by the Vue components. * @param {Object} rawFacets - the aggregation object coming from the API response as data['aggregations'] * @returns {Array} output - the array of ready to use facets containing a name, a label and values */ export const buildFacets = function (rawFacets) { let output = []; const mapper = filterMapping["autocomplete"]; Object.keys(rawFacets).forEach(function (facetName) { if (Object.prototype.hasOwnProperty.call(mapper, facetName)) { let localFacet = mapper[facetName]; rawFacets[facetName]["buckets"].forEach(function (bucket) { if (Object.prototype.hasOwnProperty.call(bucket, "key_as_string")) { bucket["key"] = bucket["key_as_string"]; } }); localFacet["buckets"] = rawFacets[facetName]["buckets"]; output.push(localFacet); } }); return output; };