@opengeoweb/knmi-components 14.5.1 → 15.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -1,12 +1,20 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { Grid, Box, FormControlLabel, Radio, MenuItem, Checkbox, Button } from '@mui/material';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { LinearProgress, Box, Grid, FormControlLabel, Radio, MenuItem, Checkbox, Button } from '@mui/material';
3
3
  import { useFormContext } from 'react-hook-form';
4
4
  import { FORM_FIELDS_NAMESPACE, ReactHookFormTextField, ReactHookFormNumberField, isLatitude, isLongitude, isValidMin, isValidMax, ReactHookFormDateTime, isXHoursBefore, isXHoursAfter, ReactHookFormRadioGroup, ReactHookFormSelect, ReactHookFormFormControl, ReactHookFormProvider, defaultFormOptions } from '@opengeoweb/form-fields';
5
- import { SHARED_NAMESPACE, dateUtils, usePreventBrowserClose } from '@opengeoweb/shared';
5
+ import { sessionStorageProvider, SHARED_NAMESPACE, dateUtils, usePreventBrowserClose, AlertBanner, ErrorBoundary } from '@opengeoweb/shared';
6
+ import { useMutation } from '@tanstack/react-query';
7
+ import { useDispatch } from 'react-redux';
8
+ import { useAuthenticationContext } from '@opengeoweb/authentication';
9
+ import { snackbarActions, snackbarTypes } from '@opengeoweb/snackbar';
10
+ import { getHeaders, handleResponse } from '@opengeoweb/api';
6
11
  import 'i18next';
7
12
  import { useTranslation } from 'react-i18next';
8
13
 
9
14
  var en = {
15
+ "error-auth-login": "This feature is protected by authentication. Please log in to proceed",
16
+ "error-publish": "Something went wrong while publishing. Please try again.",
17
+ "message-publish-success": "Product was published successfully",
10
18
  "clear-form": "Clear",
11
19
  "publish-form": "Publish",
12
20
  "reference-name": "Reference name",
@@ -31,6 +39,9 @@ var fi = {
31
39
  var no = {
32
40
  };
33
41
  var nl = {
42
+ "error-auth-login": "Deze functie wordt beschermd door authenticatie. Log in om verder te gaan",
43
+ "error-publish": "Er is iets mis gegaan met publiceren. Probeer het opnieuw.",
44
+ "message-publish-success": "Product is succesvol gepubliceerd",
34
45
  "clear-form": "Wissen",
35
46
  "publish-form": "Publiceren",
36
47
  "reference-name": "Referentie naam",
@@ -57,6 +68,31 @@ var knmicomponentTranslations = {
57
68
  nl: nl
58
69
  };
59
70
 
71
+ /* *
72
+ * Licensed under the Apache License, Version 2.0 (the "License");
73
+ * you may not use this file except in compliance with the License.
74
+ * You may obtain a copy of the License at
75
+ *
76
+ * http://www.apache.org/licenses/LICENSE-2.0
77
+ *
78
+ * Unless required by applicable law or agreed to in writing, software
79
+ * distributed under the License is distributed on an "AS IS" BASIS,
80
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81
+ * See the License for the specific language governing permissions and
82
+ * limitations under the License.
83
+ *
84
+ * Copyright 2026 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
85
+ * Copyright 2026 - Finnish Meteorological Institute (FMI)
86
+ * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
87
+ * */
88
+ const config = sessionStorageProvider.getConfig();
89
+ const publisherBaseUrl = config.GW_KNMI_PUBLISHER_BASE_URL || '';
90
+ const publishProduct = async (auth, data) => fetch(`${publisherBaseUrl}/publish`, {
91
+ headers: getHeaders(auth),
92
+ method: 'POST',
93
+ body: JSON.stringify(data)
94
+ }).then(handleResponse);
95
+
60
96
  /* *
61
97
  * Licensed under the Apache License, Version 2.0 (the "License");
62
98
  * you may not use this file except in compliance with the License.
@@ -78,6 +114,52 @@ const KNMICOMPONENTS_NAMESPACE = 'KNMIComponents';
78
114
  const ns = [KNMICOMPONENTS_NAMESPACE, SHARED_NAMESPACE, FORM_FIELDS_NAMESPACE];
79
115
  const useKNMIComponentsTranslation = () => useTranslation(ns);
80
116
 
117
+ /* *
118
+ * Licensed under the Apache License, Version 2.0 (the "License");
119
+ * you may not use this file except in compliance with the License.
120
+ * You may obtain a copy of the License at
121
+ *
122
+ * http://www.apache.org/licenses/LICENSE-2.0
123
+ *
124
+ * Unless required by applicable law or agreed to in writing, software
125
+ * distributed under the License is distributed on an "AS IS" BASIS,
126
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127
+ * See the License for the specific language governing permissions and
128
+ * limitations under the License.
129
+ *
130
+ * Copyright 2026 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
131
+ * Copyright 2026 - Finnish Meteorological Institute (FMI)
132
+ * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
133
+ * */
134
+ const usePublishProduct = () => {
135
+ const {
136
+ auth
137
+ } = useAuthenticationContext();
138
+ const {
139
+ t
140
+ } = useKNMIComponentsTranslation();
141
+ const dispatch = useDispatch();
142
+ return useMutation({
143
+ mutationFn: async ({
144
+ data
145
+ }) => {
146
+ if (!auth) {
147
+ throw new Error('Authentication context not found');
148
+ }
149
+ return publishProduct(auth, data);
150
+ },
151
+ onSuccess: async (_data, {
152
+ clearForm
153
+ }) => {
154
+ dispatch(snackbarActions.openSnackbar({
155
+ type: snackbarTypes.SnackbarMessageType.TRANSLATABLE_MESSAGE,
156
+ key: t('message-publish-success')
157
+ }));
158
+ clearForm();
159
+ }
160
+ });
161
+ };
162
+
81
163
  const formStyles = {
82
164
  padding: '32px 16px',
83
165
  '.MuiSelect-select.MuiInputBase-input.MuiFilledInput-input': {
@@ -128,9 +210,7 @@ const generateDefaultValues = () => {
128
210
  spatialUncertainty: false
129
211
  };
130
212
  };
131
- const Form = ({
132
- onPublish
133
- }) => {
213
+ const Form = () => {
134
214
  const {
135
215
  t
136
216
  } = useKNMIComponentsTranslation();
@@ -147,25 +227,45 @@ const Form = ({
147
227
  } = formState;
148
228
  const isDirty = Object.keys(dirtyFields).length > 0;
149
229
  usePreventBrowserClose(isDirty);
230
+ const {
231
+ mutate: publishProduct,
232
+ error: publishError,
233
+ isPending: isPublishing
234
+ } = usePublishProduct();
150
235
  const handleSendForm = () => {
151
236
  void handleSubmit(data => {
152
- onPublish(data);
153
- // eslint-disable-next-line no-console
154
- console.log(data);
155
- handleClearForm();
237
+ publishProduct({
238
+ data: data,
239
+ clearForm: handleClearForm
240
+ });
156
241
  })();
157
242
  };
158
243
  const handleClearForm = () => {
159
244
  reset(generateDefaultValues());
160
245
  };
161
246
  const spatialUncertainty = watch('spatialUncertainty');
162
- return jsx("form", {
247
+ return jsxs("form", {
163
248
  "data-testid": "trajks-form",
164
249
  style: {
165
250
  height: '100%',
166
251
  overflowY: 'auto'
167
252
  },
168
- children: jsxs(Grid, {
253
+ children: [isPublishing ? jsx(LinearProgress, {
254
+ color: "secondary",
255
+ sx: {
256
+ position: 'absolute',
257
+ width: '100%'
258
+ }
259
+ }) : null, publishError ? jsx(Box, {
260
+ sx: {
261
+ width: '100%'
262
+ },
263
+ children: jsx(AlertBanner, {
264
+ info: publishError.message,
265
+ shouldClose: true,
266
+ title: t('error-publish')
267
+ })
268
+ }) : null, jsxs(Grid, {
169
269
  container: true,
170
270
  spacing: 3,
171
271
  sx: formStyles,
@@ -352,7 +452,7 @@ const Form = ({
352
452
  })
353
453
  }), jsx(Grid, {
354
454
  children: jsx(Button, {
355
- disabled: !isValid,
455
+ disabled: !isValid || isPublishing,
356
456
  onClick: handleSendForm,
357
457
  size: "small",
358
458
  sx: {
@@ -364,7 +464,7 @@ const Form = ({
364
464
  })
365
465
  })]
366
466
  })]
367
- })
467
+ })]
368
468
  });
369
469
  };
370
470
  const TrajksForm = props => {
@@ -379,29 +479,34 @@ const TrajksForm = props => {
379
479
  });
380
480
  };
381
481
 
382
- const TRAJKS_COMPONENT_TYPE = 'TrajksModule';
383
- const trajksViewPreset = {
384
- id: 'TrajksForm',
385
- title: 'Trajks form',
386
- scope: 'system',
387
- abstract: '',
388
- keywords: 'TrajksForm',
389
- initialProps: {},
390
- componentType: TRAJKS_COMPONENT_TYPE
482
+ const TrajksFormWrapper = () => {
483
+ const {
484
+ t
485
+ } = useKNMIComponentsTranslation();
486
+ const {
487
+ isLoggedIn
488
+ } = useAuthenticationContext();
489
+ if (!isLoggedIn) {
490
+ return jsx(AlertBanner, {
491
+ title: t('error-auth-login')
492
+ });
493
+ }
494
+ return jsx(ErrorBoundary, {
495
+ children: jsx(TrajksForm, {})
496
+ });
391
497
  };
498
+
499
+ const TRAJKS_COMPONENT_TYPE = 'TrajksModule';
392
500
  const componentsLookUp = payload => {
393
501
  const {
394
502
  componentType
395
503
  } = payload;
396
504
  switch (componentType) {
397
- case trajksViewPreset.componentType:
398
- // TODO: update this component after backend is ready
399
- return jsx(TrajksForm, {
400
- onPublish: () => {}
401
- });
505
+ case TRAJKS_COMPONENT_TYPE:
506
+ return jsx(TrajksFormWrapper, {});
402
507
  default:
403
508
  return null;
404
509
  }
405
510
  };
406
511
 
407
- export { Form, KNMICOMPONENTS_NAMESPACE, TrajksForm, componentsLookUp, generateDefaultValues, knmicomponentTranslations as knmiComponentTranslations, trajksViewPreset };
512
+ export { Form, KNMICOMPONENTS_NAMESPACE, TrajksForm, componentsLookUp, generateDefaultValues, knmicomponentTranslations as knmiComponentTranslations };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/knmi-components",
3
- "version": "14.5.1",
3
+ "version": "15.0.0",
4
4
  "description": "GeoWeb knmi-components library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,13 +8,18 @@
8
8
  "url": "git@gitlab.com:opengeoweb/opengeoweb.git"
9
9
  },
10
10
  "dependencies": {
11
- "@opengeoweb/form-fields": "14.5.1",
11
+ "@opengeoweb/form-fields": "15.0.0",
12
12
  "react-hook-form": "^7.61.1",
13
13
  "@mui/material": "^7.2.0",
14
- "@opengeoweb/shared": "14.5.1",
15
- "@opengeoweb/theme": "14.5.1",
14
+ "@opengeoweb/shared": "15.0.0",
15
+ "@opengeoweb/theme": "15.0.0",
16
16
  "i18next": "^25.3.2",
17
- "react-i18next": "^15.1.1"
17
+ "react-i18next": "^15.1.1",
18
+ "@opengeoweb/api": "15.0.0",
19
+ "@opengeoweb/authentication": "15.0.0",
20
+ "@tanstack/react-query": "^5.85.5",
21
+ "react-redux": "^9.2.0",
22
+ "@opengeoweb/snackbar": "15.0.0"
18
23
  },
19
24
  "devDependencies": {
20
25
  "eslint-plugin-storybook": "9.0.17"
@@ -0,0 +1,3 @@
1
+ import type { Credentials } from '@opengeoweb/authentication';
2
+ import type { TrajksFormValues } from '../components/Trajks';
3
+ export declare const publishProduct: (auth: Credentials, data: TrajksFormValues) => Promise<Headers | null>;
@@ -0,0 +1 @@
1
+ export declare const requestHandlers: import("msw").HttpHandler[];
@@ -0,0 +1,9 @@
1
+ import type { UseMutationResult } from '@tanstack/react-query';
2
+ import type { TrajksFormValues } from '../components/Trajks';
3
+ type MutationReturnType<T> = UseMutationResult<Headers | null, Error, T>;
4
+ interface PublishProductProps {
5
+ data: TrajksFormValues;
6
+ clearForm: () => void;
7
+ }
8
+ export declare const usePublishProduct: () => MutationReturnType<PublishProductProps>;
9
+ export {};
@@ -1,13 +1,4 @@
1
1
  declare const TRAJKS_COMPONENT_TYPE: "TrajksModule";
2
- export declare const trajksViewPreset: {
3
- id: string;
4
- title: string;
5
- scope: string;
6
- abstract: string;
7
- keywords: string;
8
- initialProps: {};
9
- componentType: "TrajksModule";
10
- };
11
2
  export type TrajksComponentType = typeof TRAJKS_COMPONENT_TYPE;
12
3
  export interface ComponentsLookUpPayload {
13
4
  componentType: TrajksComponentType;
@@ -1,4 +1,4 @@
1
- interface TrajksFormValues {
1
+ export interface TrajksFormValues {
2
2
  referenceName: string;
3
3
  lat: number | string;
4
4
  lon: number | string;
@@ -10,9 +10,5 @@ interface TrajksFormValues {
10
10
  spatialUncertainty: boolean;
11
11
  }
12
12
  export declare const generateDefaultValues: () => TrajksFormValues;
13
- interface FormType {
14
- onPublish: (data: TrajksFormValues) => void;
15
- }
16
- export declare const Form: ({ onPublish }: FormType) => React.JSX.Element;
17
- export declare const TrajksForm: React.FC<FormType>;
18
- export {};
13
+ export declare const Form: () => React.JSX.Element;
14
+ export declare const TrajksForm: React.FC;
@@ -0,0 +1 @@
1
+ export declare const TrajksFormWrapper: React.FC;
@@ -0,0 +1,9 @@
1
+ import type { StoryObj } from '@storybook/react-webpack5';
2
+ import { TrajksFormWrapper } from './TrajksFormWrapper';
3
+ type Story = StoryObj<typeof TrajksFormWrapper>;
4
+ declare const _default: {
5
+ title: string;
6
+ };
7
+ export default _default;
8
+ export declare const Demo: Story;
9
+ export declare const DemoError: Story;
@@ -1,9 +1,5 @@
1
1
  import type { Theme } from '@mui/material';
2
2
  import type { UseFormProps } from 'react-hook-form';
3
- export declare const KNMIComponentsThemeWrapper: React.FC<{
4
- children: React.ReactNode;
5
- theme?: Theme;
6
- }>;
7
3
  interface KNMIComponentsThemeFormProviderProps {
8
4
  children: React.ReactNode;
9
5
  options?: UseFormProps;