@cccsaurora/howler-ui 2.17.0-dev.548 → 2.17.0-dev.551

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.
@@ -6,7 +6,11 @@ export interface HowlerHelper {
6
6
  en: string;
7
7
  fr: string;
8
8
  };
9
+ async?: boolean;
9
10
  callback?: Handlebars.HelperDelegate;
10
11
  componentCallback?: (...args: any[]) => ReactElement | Promise<ReactElement>;
11
12
  }
12
- export declare const useHelpers: () => HowlerHelper[];
13
+ export declare const useHelpers: (opts?: {
14
+ async: boolean;
15
+ components: boolean;
16
+ }) => HowlerHelper[];
@@ -13,7 +13,7 @@ import { usePluginStore } from 'react-pluggable';
13
13
  import ActionButton from '../ActionButton';
14
14
  import JSONViewer from '../json/JSONViewer';
15
15
  const FETCH_RESULTS = {};
16
- export const useHelpers = () => {
16
+ export const useHelpers = (opts = { async: true, components: true }) => {
17
17
  const pluginStore = usePluginStore();
18
18
  const allHelpers = useMemo(() => [
19
19
  {
@@ -86,6 +86,7 @@ export const useHelpers = () => {
86
86
  en: 'Fetches the url provided and returns the given (flattened) key from the returned JSON object. Note that the result must be JSON!',
87
87
  fr: "Récupère l'URL fournie et retourne la clé donnée (aplatie) de l'objet JSON retourné. Notez que le résultat doit être du JSON !"
88
88
  },
89
+ async: true,
89
90
  callback: async (url, key) => {
90
91
  try {
91
92
  if (!FETCH_RESULTS[url]) {
@@ -164,7 +165,7 @@ export const useHelpers = () => {
164
165
  en: 'Returns the given (flattened) key from the provided object.',
165
166
  fr: "Retourne la clé donnée (aplatie) de l'objet fourni."
166
167
  },
167
- callback: async (data, key) => {
168
+ callback: (data, key) => {
168
169
  try {
169
170
  return get(data, key);
170
171
  }
@@ -213,7 +214,17 @@ export const useHelpers = () => {
213
214
  return _jsx(ActionButton, { actionId: actionId, hitId: hitId, ...(context.hash ?? {}) });
214
215
  }
215
216
  },
217
+ {
218
+ keyword: 'replace',
219
+ documentation: {
220
+ en: '',
221
+ fr: ''
222
+ },
223
+ callback: (str, searchValue, replaceValue) => {
224
+ return str.replace(searchValue ?? '', replaceValue ?? '');
225
+ }
226
+ },
216
227
  ...howlerPluginStore.plugins.flatMap(plugin => pluginStore.executeFunction(`${plugin}.helpers`))
217
- ], [pluginStore]);
228
+ ].filter((entry) => (opts.async || !entry.async) && (opts.components || !entry.componentCallback)), [opts.async, opts.components, pluginStore]);
218
229
  return allHelpers;
219
230
  };
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ErrorOutline } from '@mui/icons-material';
3
3
  import { Tooltip } from '@mui/material';
4
+ import { useHelpers } from '@cccsaurora/howler-ui/components/elements/display/handlebars/helpers';
4
5
  import HowlerCard from '@cccsaurora/howler-ui/components/elements/display/HowlerCard';
5
6
  import Handlebars from 'handlebars';
6
7
  import { isEmpty } from 'lodash-es';
@@ -11,7 +12,9 @@ import { flattenDeep } from '@cccsaurora/howler-ui/utils/utils';
11
12
  import RelatedLink from './RelatedLink';
12
13
  const PivotLink = ({ pivot, hit, compact = false }) => {
13
14
  const { i18n } = useTranslation();
15
+ const helpers = useHelpers({ async: false, components: false });
14
16
  const pluginStore = usePluginStore();
17
+ const handlebars = useMemo(() => Handlebars.create(), []);
15
18
  const flatHit = useMemo(() => flattenDeep(hit ?? {}), [hit]);
16
19
  const href = useMemo(() => {
17
20
  if (!pivot || pivot.format !== 'link' || !flatHit || isEmpty(flatHit)) {
@@ -30,10 +33,25 @@ const PivotLink = ({ pivot, hit, compact = false }) => {
30
33
  }
31
34
  return result;
32
35
  }));
33
- return Handlebars.compile(pivot.value)(templateObject);
34
- }, [flatHit, pivot]);
36
+ helpers.forEach(helper => {
37
+ if (handlebars.helpers[helper.keyword]) {
38
+ return;
39
+ }
40
+ handlebars.registerHelper(helper.keyword, (...args) => {
41
+ // eslint-disable-next-line no-console
42
+ console.debug(`Running helper ${helper.keyword}`);
43
+ return helper.callback(...args);
44
+ });
45
+ });
46
+ try {
47
+ return handlebars.compile(pivot.value)(templateObject);
48
+ }
49
+ catch (e) {
50
+ return pivot.value;
51
+ }
52
+ }, [flatHit, pivot, handlebars, helpers]);
35
53
  if (href) {
36
- return _jsx(RelatedLink, { title: pivot.label[i18n.language], href: href, compact: compact, icon: pivot.icon });
54
+ return (_jsx(RelatedLink, { title: pivot.label[i18n.language], href: href, compact: compact, icon: pivot.icon, target: "_blank" }));
37
55
  }
38
56
  // Hide a relatively useless console error, we'll show a UI component instead
39
57
  // eslint-disable-next-line no-console
@@ -4,5 +4,6 @@ declare const RelatedLink: React.FC<PropsWithChildren<{
4
4
  title?: string;
5
5
  href?: string;
6
6
  compact?: boolean;
7
+ target?: string;
7
8
  }>>;
8
9
  export default RelatedLink;
@@ -4,8 +4,8 @@ import HowlerCard from '@cccsaurora/howler-ui/components/elements/display/Howler
4
4
  import React, {} from 'react';
5
5
  import { Link } from 'react-router-dom';
6
6
  import RelatedIcon from './RelatedIcon';
7
- const RelatedLink = ({ icon, title, href, compact = false, children }) => {
8
- return (_jsx(HowlerCard, { variant: compact ? 'outlined' : 'elevation', onClick: () => window.open(href), sx: [
7
+ const RelatedLink = ({ icon, title, href, target, compact = false, children }) => {
8
+ return (_jsx(HowlerCard, { variant: compact ? 'outlined' : 'elevation', onClick: () => window.open(href, target), sx: [
9
9
  theme => ({
10
10
  cursor: 'pointer',
11
11
  backgroundColor: 'transparent',
@@ -17,6 +17,6 @@ const RelatedLink = ({ icon, title, href, compact = false, children }) => {
17
17
  '& a': { textDecoration: 'none', color: 'text.primary' }
18
18
  }),
19
19
  !compact && { border: 'thin solid', borderColor: 'transparent' }
20
- ], children: _jsxs(Stack, { direction: "row", p: compact ? 0.5 : 1, spacing: 1, alignItems: "center", children: [children || _jsx(RelatedIcon, { icon: icon, title: title, href: href, compact: compact }), _jsx(Typography, { component: Link, to: href, onClick: e => e.stopPropagation(), children: title ?? href })] }) }, href));
20
+ ], children: _jsxs(Stack, { direction: "row", p: compact ? 0.5 : 1, spacing: 1, alignItems: "center", children: [children || _jsx(RelatedIcon, { icon: icon, title: title, href: href, compact: compact }), _jsx(Typography, { component: Link, to: href, target: target, onClick: e => e.stopPropagation(), children: title ?? href })] }) }, href));
21
21
  };
22
22
  export default RelatedLink;
@@ -18,7 +18,7 @@ const CustomSpan = () => {
18
18
  const endDate = useContextSelector(ParameterContext, ctx => (ctx.endDate ? dayjs(ctx.endDate) : defaultEndDate));
19
19
  useEffect(() => {
20
20
  if (span?.endsWith('custom')) {
21
- setCustomSpan(startDate.format('YYYY-MM-DD HH:mm'), endDate.format('YYYY-MM-DD HH:mm'));
21
+ setCustomSpan(startDate.toISOString(), endDate.toISOString());
22
22
  }
23
23
  }, [endDate, setCustomSpan, span, startDate]);
24
24
  return span?.endsWith('custom') ? (_jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, children: _jsxs(Stack, { direction: "row", spacing: 1, useFlexGap: true, flexWrap: "wrap", children: [_jsx(DateTimePicker, { sx: { minWidth: '175px', flexGrow: 1, marginTop: 1 }, slotProps: { textField: { size: 'small' } }, label: t('date.select.start'), value: startDate ? dayjs(startDate) : dayjs().subtract(1, 'days'), maxDate: endDate, onChange: (newStartDate) => setCustomSpan(newStartDate.toISOString(), endDate.toISOString()), ampm: false, disableFuture: true }), _jsx(DateTimePicker, { sx: { minWidth: '175px', flexGrow: 1, marginTop: 1 }, slotProps: { textField: { size: 'small' } }, label: t('date.select.end'), value: endDate, minDate: startDate, onChange: (newEndDate) => setCustomSpan(startDate.toISOString(), newEndDate.toISOString()), ampm: false, disableFuture: true })] }) })) : null;
package/package.json CHANGED
@@ -101,7 +101,7 @@
101
101
  "internal-slot": "1.0.7"
102
102
  },
103
103
  "type": "module",
104
- "version": "2.17.0-dev.548",
104
+ "version": "2.17.0-dev.551",
105
105
  "exports": {
106
106
  "./i18n": "./i18n.js",
107
107
  "./index.css": "./index.css",