Skip to content
Snippets Groups Projects
Commit 4becca9d authored by esikkala's avatar esikkala
Browse files

Add reducer and actions for ClientFS

parent 4d5e152a
No related branches found
No related tags found
No related merge requests found
......@@ -26,7 +26,9 @@ export const UPDATE_FACET_VALUES = 'UPDATE_FACET_VALUES'
export const UPDATE_FACET_VALUES_CONSTRAIN_SELF = 'UPDATE_FACET_VALUES_CONSTRAIN_SELF'
export const UPDATE_FACET_OPTION = 'UPDATE_FACET_OPTION'
export const UPDATE_CLIENT_SIDE_FILTER = 'UPDATE_CLIENT_SIDE_FILTER'
export const UPDATE_MAP_BOUNDS = 'UPDATE_MAP_BOUNDS'
export const FETCH_GEOJSON_LAYERS = 'FETCH_GEOJSON_LAYERS'
export const FETCH_GEOJSON_LAYERS_BACKEND = 'FETCH_GEOJSON_LAYERS_BACKEND'
export const UPDATE_GEOJSON_LAYERS = 'UPDATE_GEOJSON_LAYERS'
export const OPEN_MARKER_POPUP = 'OPEN_MARKER_POPUP'
export const SHOW_ERROR = 'SHOW_ERROR'
......@@ -36,6 +38,14 @@ export const LOAD_LOCALES = 'LOAD_LOCALES'
export const LOAD_LOCALES_FAILED = 'LOAD_LOCALES_FAILED'
export const UPDATE_LOCALE = 'UPDATE_LOCALE'
export const ANIMATE_MAP = 'ANIMATE_MAP'
export const CLIENT_FS_UPDATE_QUERY = 'CLIENT_FS_UPDATE_QUERY'
export const CLIENT_FS_TOGGLE_DATASET = 'CLIENT_FS_TOGGLE_DATASET'
export const CLIENT_FS_FETCH_RESULTS = 'CLIENT_FS_FETCH_RESULTS'
export const CLIENT_FS_FETCH_RESULTS_FAILED = 'CLIENT_FS_FETCH_RESULTS_FAILED'
export const CLIENT_FS_UPDATE_RESULTS = 'CLIENT_FS_UPDATE_RESULTS'
export const CLIENT_FS_CLEAR_RESULTS = 'CLIENT_FS_CLEAR_RESULTS'
export const CLIENT_FS_UPDATE_FACET = 'CLIENT_FS_UPDATE_FACET'
export const CLIENT_FS_SORT_RESULTS = 'CLIENT_FS_SORT_RESULTS'
export const fetchPaginatedResults = (resultClass, facetClass, sortBy) => ({
type: FETCH_PAGINATED_RESULTS,
......@@ -251,12 +261,57 @@ export const animateMap = value => ({
type: ANIMATE_MAP,
value
})
export const updateMapBounds = bounds => ({
type: UPDATE_MAP_BOUNDS,
bounds
})
export const fetchGeoJSONLayers = ({ layerIDs, bounds }) => ({
type: FETCH_GEOJSON_LAYERS,
layerIDs,
bounds
})
export const fetchGeoJSONLayersBackend = ({ layerIDs, bounds }) => ({
type: FETCH_GEOJSON_LAYERS_BACKEND,
layerIDs,
bounds
})
export const updateGeoJSONLayers = ({ payload }) => ({
type: UPDATE_GEOJSON_LAYERS,
payload
})
export const clientFSUpdateQuery = query => ({
type: CLIENT_FS_UPDATE_QUERY,
query
})
export const clientFSToggleDataset = dataset => ({
type: CLIENT_FS_TOGGLE_DATASET,
dataset
})
export const clientFSFetchResults = ({ jenaIndex, query }) => ({
type: CLIENT_FS_FETCH_RESULTS,
jenaIndex,
query
})
export const clientFSFetchResultsFailed = error => ({
type: CLIENT_FS_FETCH_RESULTS_FAILED,
error
})
export const clientFSUpdateResults = ({ results, jenaIndex }) => ({
type: CLIENT_FS_UPDATE_RESULTS,
results,
jenaIndex
})
export const clientFSClearResults = () => ({
type: CLIENT_FS_CLEAR_RESULTS
})
export const clientFSUpdateFacet = ({ facetID, value, latestValues }) => ({
type: CLIENT_FS_UPDATE_FACET,
facetID,
value,
latestValues
})
export const clientFSSortResults = options => ({
type: CLIENT_FS_SORT_RESULTS,
options
})
......@@ -14,7 +14,7 @@ import intl from 'react-intl-universal'
import localeEN from '../translations/sampo/localeEN'
import localeFI from '../translations/sampo/localeFI'
import localeSV from '../translations/sampo/localeSV'
import { stateToUrl, handleAxiosError } from '../helpers/helpers'
import { stateToUrl, handleAxiosError, pickSelectedDatasets, boundsToValues } from '../helpers/helpers'
import querystring from 'querystring'
import {
FETCH_RESULT_COUNT,
......@@ -32,16 +32,21 @@ import {
FETCH_SIMILAR_DOCUMENTS_BY_ID_FAILED,
FETCH_FACET_FAILED,
FETCH_GEOJSON_LAYERS,
FETCH_GEOJSON_LAYERS_BACKEND,
CLIENT_FS_FETCH_RESULTS,
CLIENT_FS_FETCH_RESULTS_FAILED,
LOAD_LOCALES,
updateResultCount,
updatePaginatedResults,
updateResults,
clientFSUpdateResults,
updateInstance,
updateInstanceRelatedData,
updateFacetValues,
updateFacetValuesConstrainSelf,
updateLocale,
updateGeoJSONLayers
updateGeoJSONLayers,
SHOW_ERROR
} from '../actions'
import {
rootUrl,
......@@ -133,6 +138,37 @@ const fetchResultsEpic = (action$, state$) => action$.pipe(
})
)
const clientFSFetchResultsEpic = (action$, state$) => action$.pipe(
ofType(CLIENT_FS_FETCH_RESULTS),
withLatestFrom(state$),
debounceTime(500),
switchMap(([action, state]) => {
const { jenaIndex } = action
const selectedDatasets = pickSelectedDatasets(state.clientSideFacetedSearch.datasets)
const dsParams = selectedDatasets.map(ds => `dataset=${ds}`).join('&')
let requestUrl
if (action.jenaIndex === 'text') {
requestUrl = `${apiUrl}federatedSearch?q=${action.query}&${dsParams}`
} else if (action.jenaIndex === 'spatial') {
const { latMin, longMin, latMax, longMax } = state.leafletMap
requestUrl = `${apiUrl}federatedSearch?latMin=${latMin}&longMin=${longMin}&latMax=${latMax}&longMax=${longMax}&${dsParams}`
}
return ajax.getJSON(requestUrl).pipe(
map(response => clientFSUpdateResults({
results: response,
jenaIndex
})),
catchError(error => of({
type: CLIENT_FS_FETCH_RESULTS_FAILED,
error: error,
message: {
text: backendErrorText,
title: 'Error'
}
}))
)
})
)
const fetchResultCountEpic = (action$, state$) => action$.pipe(
ofType(FETCH_RESULT_COUNT),
withLatestFrom(state$),
......@@ -335,7 +371,37 @@ const fetchSimilarDocumentsEpic = (action$, state$) => action$.pipe(
})
)
const fetchGeoJSONLayers = action$ => action$.pipe(
const fetchGeoJSONLayersBackendEpic = (action$, state$) => action$.pipe(
ofType(FETCH_GEOJSON_LAYERS_BACKEND),
withLatestFrom(state$),
mergeMap(([action]) => {
const { layerIDs, bounds } = action
const { latMin, longMin, latMax, longMax } = boundsToValues(bounds)
const params = {
layerID: layerIDs,
latMin,
longMin,
latMax,
longMax
}
const requestUrl = `${apiUrl}wfs?${querystring.stringify(params)}`
return ajax.getJSON(requestUrl).pipe(
map(res => updateGeoJSONLayers({
payload: res
})),
catchError(error => of({
type: SHOW_ERROR,
error: error,
message: {
text: backendErrorText,
title: 'Error'
}
}))
)
})
)
const fetchGeoJSONLayersEpic = action$ => action$.pipe(
ofType(FETCH_GEOJSON_LAYERS),
mergeMap(async action => {
const { layerIDs, bounds } = action
......@@ -346,16 +412,19 @@ const fetchGeoJSONLayers = action$ => action$.pipe(
const fetchGeoJSONLayer = async (layerID, bounds) => {
const baseUrl = 'http://kartta.nba.fi/arcgis/services/WFS/MV_Kulttuuriymparisto/MapServer/WFSServer'
const boundsStr =
`${bounds._southWest.lng},${bounds._southWest.lat},${bounds._northEast.lng},${bounds._northEast.lat}`
// const baseUrl = 'http://avaa.tdata.fi/geoserver/kotus/ows'
// const baseUrl = 'http://avaa.tdata.fi/geoserver/paituli/wfs'
// const boundsStr =
// `${bounds._southWest.lng},${bounds._southWest.lat},${bounds._northEast.lng},${bounds._northEast.lat}`
const mapServerParams = {
request: 'GetFeature',
service: 'WFS',
version: '2.0.0',
typeName: layerID,
srsName: 'EPSG:4326',
outputFormat: 'geojson',
bbox: boundsStr
// outputFormat: 'geojson'
outputFormat: 'application/json'
// bbox: boundsStr
}
const url = `${baseUrl}?${querystring.stringify(mapServerParams)}`
try {
......@@ -372,6 +441,7 @@ const fetchGeoJSONLayer = async (layerID, bounds) => {
const rootEpic = combineEpics(
fetchPaginatedResultsEpic,
fetchResultsEpic,
clientFSFetchResultsEpic,
fetchResultCountEpic,
fetchResultsClientSideEpic,
fetchByURIEpic,
......@@ -379,7 +449,8 @@ const rootEpic = combineEpics(
fetchFacetConstrainSelfEpic,
loadLocalesEpic,
fetchSimilarDocumentsEpic,
fetchGeoJSONLayers
fetchGeoJSONLayersEpic,
fetchGeoJSONLayersBackendEpic
)
export default rootEpic
......@@ -68,7 +68,7 @@ export const urlToState = ({ initialState, queryString }) => {
return params
}
const boundsToValues = bounds => {
export const boundsToValues = bounds => {
const latMin = bounds._southWest.lat
const longMin = bounds._southWest.lng
const latMax = bounds._northEast.lat
......@@ -99,3 +99,13 @@ export const handleAxiosError = error => {
}
console.log(error.config)
}
export const pickSelectedDatasets = datasets => {
const selected = []
Object.keys(datasets).map(key => {
if (datasets[key].selected) {
selected.push(key)
}
})
return selected
}
import {
FETCH_RESULTS_CLIENT_SIDE,
UPDATE_RESULTS,
CLEAR_RESULTS,
UPDATE_CLIENT_SIDE_FILTER,
SORT_RESULTS
} from '../actions'
export const INITIAL_STATE = {
query: '',
results: [],
latestFilter: {
id: ''
},
latestFilterValues: [],
resultsFilter: {
prefLabel: new Set(),
type: new Set()
},
sortBy: 'prefLabel',
sortDirection: 'asc',
// groupBy: 'broaderTypeLabel',
// groupByLabel: 'Paikanlaji',
textResultsFetching: false,
spatialResultsFetching: false
}
const clientSideFacetedSearch = (state = INITIAL_STATE, action) => {
if (action.resultClass === 'all') {
switch (action.type) {
case FETCH_RESULTS_CLIENT_SIDE:
return {
...state,
[`${action.jenaIndex}ResultsFetching`]: true
}
case UPDATE_RESULTS:
return {
...state,
query: action.query,
results: action.data,
[`${action.jenaIndex}ResultsFetching`]: false
}
case CLEAR_RESULTS:
return {
...state,
results: null,
fetchingResults: false,
query: '',
resultsFilter: {
prefLabel: new Set(),
type: new Set()
}
}
case UPDATE_CLIENT_SIDE_FILTER:
return updateResultsFilter(state, action)
case SORT_RESULTS:
return {
...state,
sortBy: action.options.sortBy,
sortDirection: action.options.sortDirection
}
default:
return state
}
} else return state
}
const updateResultsFilter = (state, action) => {
const { property, value, latestValues } = action.filterObj
const nSet = state.resultsFilter[property]
if (nSet.has(value)) {
nSet.delete(value)
} else {
nSet.add(value)
}
const newFilter = {
...state.resultsFilter,
[property]: nSet
}
return {
...state,
resultsFilter: newFilter,
latestFilter: {
id: property
},
latestFilterValues: latestValues
}
}
export default clientSideFacetedSearch
import { combineReducers } from 'redux'
import { reducer as toastrReducer } from 'react-redux-toastr'
// general reducers:
import error from './error'
import options from './options'
import animation from './animation'
import leafletMapLayers from './leafletMapLayers'
import clientSideFacetedSearch from './clientSideFacetedSearch'
// portal spefic reducers:
import clientSideFacetedSearch from './sampo/clientSideFacetedSearch'
import perspective1 from './sampo/perspective1'
import perspective2 from './sampo/perspective2'
import perspective3 from './sampo/perspective3'
......
import {
CLIENT_FS_UPDATE_QUERY,
CLIENT_FS_TOGGLE_DATASET,
CLIENT_FS_FETCH_RESULTS,
CLIENT_FS_FETCH_RESULTS_FAILED,
CLIENT_FS_UPDATE_RESULTS,
CLIENT_FS_CLEAR_RESULTS,
CLIENT_FS_UPDATE_FACET,
CLIENT_FS_SORT_RESULTS
} from '../../actions'
export const INITIAL_STATE = {
query: '',
datasets: {
kotus: { selected: true },
pnr: { selected: true },
warsa_karelian_places: { selected: false },
tgn: { selected: false }
},
results: null,
facets: {
datasetSelector: {
facetID: 'datasetSelector',
filterType: 'datasetSelector'
},
prefLabel: {
facetID: 'prefLabel',
filterType: 'clientFSLiteral',
selectionsSet: new Set(),
isFetching: false,
searchField: true,
containerClass: 'ten',
type: 'hierarchical'
},
broaderTypeLabel: {
facetID: 'broaderTypeLabel',
filterType: 'clientFSLiteral',
selectionsSet: new Set(),
isFetching: false,
searchField: true,
containerClass: 'ten',
type: 'hierarchical'
},
broaderAreaLabel: {
facetID: 'broaderAreaLabel',
filterType: 'clientFSLiteral',
selectionsSet: new Set(),
isFetching: false,
searchField: true,
containerClass: 'ten',
type: 'hierarchical'
},
modifier: {
facetID: 'modifier',
filterType: 'clientFSLiteral',
selectionsSet: new Set(),
isFetching: false,
searchField: true,
containerClass: 'ten',
type: 'hierarchical'
},
basicElement: {
facetID: 'basicElement',
filterType: 'clientFSLiteral',
selectionsSet: new Set(),
isFetching: false,
searchField: true,
containerClass: 'ten',
type: 'hierarchical'
},
collectionYear: {
facetID: 'collectionYear',
filterType: 'clientFSLiteral',
selectionsSet: new Set(),
isFetching: false,
searchField: true,
containerClass: 'ten',
type: 'hierarchical'
},
source: {
facetID: 'source',
filterType: 'clientFSLiteral',
selectionsSet: new Set(),
isFetching: false,
searchField: false,
containerClass: 'three',
type: 'hierarchical'
}
},
lastlyUpdatedFacet: null,
facetUpdateID: 0,
sortBy: 'broaderAreaLabel',
sortDirection: 'asc',
groupBy: 'broaderTypeLabel',
groupByLabel: 'Paikanlaji',
textResultsFetching: false,
spatialResultsFetching: false
}
const clientSideFacetedSearch = (state = INITIAL_STATE, action) => {
switch (action.type) {
case CLIENT_FS_UPDATE_QUERY:
return { ...state, query: action.query || '' }
case CLIENT_FS_TOGGLE_DATASET:
return {
...state,
suggestions: [],
results: null,
datasets: {
...state.datasets,
[action.dataset]: {
...state.datasets[action.dataset],
selected: !state.datasets[action.dataset].selected
}
}
}
case CLIENT_FS_FETCH_RESULTS:
return {
...state,
[`${action.jenaIndex}ResultsFetching`]: true
}
case CLIENT_FS_FETCH_RESULTS_FAILED:
return {
...state,
textResultsFetching: false,
spatialResultsFetching: false
}
case CLIENT_FS_CLEAR_RESULTS:
return {
...state,
results: null,
fetchingResults: false,
query: INITIAL_STATE.query,
facets: INITIAL_STATE.facets
}
case CLIENT_FS_UPDATE_RESULTS:
return {
...state,
results: action.results,
[`${action.jenaIndex}ResultsFetching`]: false
}
case CLIENT_FS_UPDATE_FACET:
return clientFSUpdateFacet(state, action)
case CLIENT_FS_SORT_RESULTS:
return {
...state,
sortBy: action.options.sortBy,
sortDirection: action.options.sortDirection
}
default:
return state
}
}
const clientFSUpdateFacet = (state, action) => {
const { facetID, value, latestValues } = action
const newSelectionsSet = state.facets[facetID].selectionsSet
if (newSelectionsSet.has(value)) {
newSelectionsSet.delete(value)
} else {
newSelectionsSet.add(value)
}
const updatedFacets = {
...state.facets,
[facetID]: {
...state.facets[facetID],
selectionsSet: newSelectionsSet
}
}
return {
...state,
facetUpdateID: ++state.facetUpdateID,
facets: updatedFacets,
lastlyUpdatedFacet: {
facetID: facetID,
values: latestValues
}
}
}
export default clientSideFacetedSearch
......@@ -62,7 +62,7 @@ export default {
leafletMap: {
basemaps: {
mapbox: {
'light-v10': 'MapBox Light'
'light-v10': 'Mapbox Light'
},
googleRoadmap: 'Google Maps',
topographicalMapNLS: 'Topographical map (National Land Survey of Finland)',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment