Skip to content

Commit 941c2ff

Browse files
committed
feat: add hook to read the application context
1 parent bfc0609 commit 941c2ff

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

Diff for: src/hooks/useReadAppContext.ts

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
import {
2+
ConfigProvider
3+
} from 'antd';
4+
5+
import Color from 'color';
6+
7+
import OlFormatGeoJSON from 'ol/format/GeoJSON';
8+
import OlLayerVector from 'ol/layer/Vector';
9+
import OlMap from 'ol/Map';
10+
11+
import Logger from '@terrestris/base-util/dist/Logger';
12+
13+
import useMap from '@terrestris/react-geo/dist/Hook/useMap';
14+
import {
15+
DigitizeUtil
16+
} from '@terrestris/react-geo/dist/Util/DigitizeUtil';
17+
18+
import Application from '@terrestris/shogun-util/dist/model/Application';
19+
import SHOGunApplicationUtil from '@terrestris/shogun-util/dist/parser/SHOGunApplicationUtil';
20+
import SHOGunAPIClient from '@terrestris/shogun-util/dist/service/SHOGunAPIClient';
21+
22+
import {
23+
setDescription
24+
} from '../store/description';
25+
import {
26+
setId
27+
} from '../store/id';
28+
import {
29+
setLogoPath
30+
} from '../store/logoPath';
31+
import {
32+
setStateOnly
33+
} from '../store/stateOnly';
34+
import {
35+
setTitle
36+
} from '../store/title';
37+
import {
38+
ClientTools,
39+
setToolConfig
40+
} from '../store/toolConfig';
41+
42+
import {
43+
parseStyle
44+
} from '../utils/parseStyle';
45+
46+
import useAppDispatch from './useAppDispatch';
47+
import useSHOGunAPIClient from './useSHOGunAPIClient';
48+
49+
export type ReadOpts = {
50+
map: OlMap;
51+
client: SHOGunAPIClient;
52+
};
53+
54+
export const useReadAppContext = () => {
55+
const dispatch = useAppDispatch();
56+
57+
const map = useMap();
58+
59+
const client = useSHOGunAPIClient();
60+
61+
if (!map || !client) {
62+
return;
63+
}
64+
65+
const restoreMap = async (application: Application) => {
66+
const parser = new SHOGunApplicationUtil({
67+
client
68+
});
69+
70+
try {
71+
const view = await parser.parseMapView(application);
72+
73+
if (view) {
74+
view.setConstrainResolution(true);
75+
if (application.clientConfig?.mapView.extent) {
76+
view.set('extent', application.clientConfig.mapView.extent);
77+
}
78+
79+
map?.setView(view);
80+
}
81+
} catch (error) {
82+
Logger.warn('Error while restoring the map view: ', error);
83+
}
84+
85+
try {
86+
const layers = await parser.parseLayerTree(application);
87+
88+
// TODO Is this asssumption correct?
89+
if (layers && layers.getLayersArray().length > 0) {
90+
map.getLayers().getArray()
91+
.filter(l => !(l instanceof OlLayerVector))
92+
.forEach(l => map.removeLayer(l));
93+
94+
layers.getLayers().getArray()
95+
.forEach(l => {
96+
const appSettings = application.layerConfig
97+
?.find(layerConfig => layerConfig.layerId === l.get('shogunId'));
98+
l.set('appSettings', appSettings);
99+
map.addLayer(l);
100+
});
101+
102+
const highestZIndex = map.getAllLayers().reduce((previous, current) => {
103+
const currentZIndex = current.getZIndex();
104+
if (currentZIndex > previous) {
105+
return currentZIndex;
106+
}
107+
108+
return previous;
109+
}, 0);
110+
111+
// TODO Loading indicator isn't working anymore
112+
map.getAllLayers()
113+
.forEach((l, idx) => {
114+
if (l instanceof OlLayerVector) {
115+
l.setZIndex(highestZIndex + (idx + 1));
116+
}
117+
});
118+
}
119+
} catch (error) {
120+
Logger.warn('Error while restoring the map layers: ', error);
121+
}
122+
};
123+
124+
const restoreTheme = (application: Application) => {
125+
ConfigProvider.config({
126+
theme: {
127+
primaryColor: Color(application.clientConfig?.theme?.primaryColor).isLight() ?
128+
Color(application.clientConfig?.theme?.primaryColor).darken(0.5).hexa() :
129+
application.clientConfig?.theme?.primaryColor
130+
}
131+
});
132+
133+
const appElement = document.querySelector('.App') as HTMLElement;
134+
135+
if (appElement) {
136+
if (application.clientConfig?.theme?.primaryColor) {
137+
appElement.style.setProperty('--primaryColor', application.clientConfig?.theme?.primaryColor);
138+
}
139+
140+
if (application.clientConfig?.theme?.secondaryColor) {
141+
appElement.style.setProperty('--secondaryColor', application.clientConfig?.theme?.secondaryColor);
142+
}
143+
144+
if (application.clientConfig?.theme?.complementaryColor) {
145+
appElement.style.setProperty('--complementaryColor', application.clientConfig?.theme?.complementaryColor);
146+
}
147+
}
148+
149+
if (application.clientConfig?.theme?.logoPath) {
150+
dispatch(setLogoPath(application.clientConfig?.theme?.logoPath));
151+
}
152+
};
153+
154+
const restoreName = (application: Application) => {
155+
if (application.name) {
156+
dispatch(setTitle(application.name));
157+
}
158+
};
159+
160+
const restoreDescription = (application: Application) => {
161+
if (application.clientConfig?.description) {
162+
dispatch(setDescription(application.clientConfig?.description));
163+
}
164+
};
165+
166+
const restoreToolConfig = async (application: Application) => {
167+
if (application.toolConfig) {
168+
dispatch(setToolConfig(application.toolConfig));
169+
}
170+
171+
const drawToolConfig = application.toolConfig?.find(tool => tool.name === ClientTools.DRAW_TOOLS);
172+
if (drawToolConfig && drawToolConfig.config.visible) {
173+
const drawVectorLayer = DigitizeUtil.getDigitizeLayer(map);
174+
175+
if (drawVectorLayer) {
176+
drawVectorLayer.getSource()?.clear();
177+
178+
if (drawToolConfig.config.features) {
179+
try {
180+
const feats = new OlFormatGeoJSON().readFeatures(drawToolConfig.config.features, {
181+
dataProjection: 'EPSG:4326',
182+
featureProjection: map.getView().getProjection()
183+
});
184+
drawVectorLayer.getSource()?.addFeatures(feats);
185+
} catch (error) {
186+
Logger.warn('Error while restoring the draw features: ', error);
187+
}
188+
}
189+
190+
if (drawToolConfig.config.style) {
191+
try {
192+
const styleFunction = await parseStyle(drawToolConfig.config.style);
193+
drawVectorLayer.setStyle(styleFunction);
194+
} catch (error) {
195+
Logger.warn('Error while restoring the draw style: ', error);
196+
}
197+
}
198+
}
199+
}
200+
};
201+
202+
const restoreId = (application: Application) => {
203+
if (application.id) {
204+
dispatch(setId(application.id));
205+
}
206+
};
207+
208+
const clearUrl = () => {
209+
const url = new URL(window.location.href);
210+
const params = url.searchParams;
211+
212+
params.delete('applicationId');
213+
214+
window.history.replaceState(null, '', url);
215+
};
216+
217+
const readAppContext = async (application: Application) => {
218+
// TODO Do we need to become smarter in here?
219+
clearUrl();
220+
221+
dispatch(setStateOnly(true));
222+
223+
await restoreMap(application);
224+
225+
restoreTheme(application);
226+
227+
restoreId(application);
228+
229+
restoreName(application);
230+
231+
restoreDescription(application);
232+
233+
await restoreToolConfig(application);
234+
};
235+
236+
return readAppContext;
237+
};
238+
239+
export default useReadAppContext;

0 commit comments

Comments
 (0)