@oneblink/apps-react 2.9.0-beta.7 → 2.9.0-beta.9
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/dist/components/QuillHTML.d.ts +4 -0
- package/dist/components/QuillHTML.js +8 -0
- package/dist/components/QuillHTML.js.map +1 -0
- package/dist/components/renderer/FormElementLabelContainer.d.ts +6 -0
- package/dist/components/renderer/FormElementLabelContainer.js +14 -5
- package/dist/components/renderer/FormElementLabelContainer.js.map +1 -1
- package/dist/form-elements/FormElementCalculation.js +2 -1
- package/dist/form-elements/FormElementCalculation.js.map +1 -1
- package/dist/form-elements/FormElementHTML.js +2 -3
- package/dist/form-elements/FormElementHTML.js.map +1 -1
- package/dist/form-elements/FormElementSection.js +5 -7
- package/dist/form-elements/FormElementSection.js.map +1 -1
- package/dist/hooks/useHint.d.ts +1 -1
- package/dist/hooks/useHint.js +0 -2
- package/dist/hooks/useHint.js.map +1 -1
- package/package.json +1 -1
@@ -0,0 +1,8 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import clsx from 'clsx';
|
3
|
+
export default function QuillHTML({ html, ...props }) {
|
4
|
+
return (React.createElement("div", { ...props, className: clsx(props.className, 'ql-editor'), dangerouslySetInnerHTML: {
|
5
|
+
__html: html,
|
6
|
+
} }));
|
7
|
+
}
|
8
|
+
//# sourceMappingURL=QuillHTML.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"QuillHTML.js","sourceRoot":"","sources":["../../src/components/QuillHTML.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,IAAI,EACJ,GAAG,KAAK,EAGT;IACC,OAAO,CACL,gCACM,KAAK,EACT,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAC7C,uBAAuB,EAAE;YACvB,MAAM,EAAE,IAAI;SACb,GACD,CACH,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\n\nexport default function QuillHTML({\n html,\n ...props\n}: React.ComponentProps<'div'> & {\n html: string\n}) {\n return (\n <div\n {...props}\n className={clsx(props.className, 'ql-editor')}\n dangerouslySetInnerHTML={{\n __html: html,\n }}\n />\n )\n}\n"]}
|
@@ -8,5 +8,11 @@ declare function FormElementLabelContainer({ className, element, id, required, c
|
|
8
8
|
children: React.ReactNode;
|
9
9
|
leading?: React.ReactNode;
|
10
10
|
}): JSX.Element;
|
11
|
+
export declare function HintTooltip({ hint }: {
|
12
|
+
hint: string;
|
13
|
+
}): JSX.Element;
|
14
|
+
export declare function HintBelowLabel({ hint }: {
|
15
|
+
hint: string;
|
16
|
+
}): JSX.Element;
|
11
17
|
declare const _default: React.MemoExoticComponent<typeof FormElementLabelContainer>;
|
12
18
|
export default _default;
|
@@ -2,19 +2,28 @@ import * as React from 'react';
|
|
2
2
|
import { Tooltip } from '@mui/material';
|
3
3
|
import clsx from 'clsx';
|
4
4
|
import useHint from '../../hooks/useHint';
|
5
|
+
import QuillHTML from '../QuillHTML';
|
5
6
|
function FormElementLabelContainer({ className, element, id, required, children, leading, }) {
|
6
|
-
const hint = useHint(element.hint);
|
7
7
|
return (React.createElement("div", { className: clsx('ob-form__element', className) },
|
8
8
|
React.createElement("div", { className: "label ob-label__container" },
|
9
9
|
leading,
|
10
10
|
React.createElement("label", { className: clsx('ob-label', {
|
11
11
|
'ob-label__required is-required': required,
|
12
12
|
}), htmlFor: id }, element.label),
|
13
|
-
|
14
|
-
React.createElement(
|
15
|
-
hint && element.hintPosition === 'BELOW_LABEL' && (React.createElement("div", { className: "ob-hint-text__container" },
|
16
|
-
React.createElement(
|
13
|
+
element.hint &&
|
14
|
+
(element.hintPosition === 'TOOLTIP' || !element.hintPosition) && (React.createElement(HintTooltip, { hint: element.hint }))),
|
15
|
+
element.hint && element.hintPosition === 'BELOW_LABEL' && (React.createElement("div", { className: "ob-hint-text__container" },
|
16
|
+
React.createElement(HintBelowLabel, { hint: element.hint }))),
|
17
17
|
children));
|
18
18
|
}
|
19
|
+
export function HintTooltip({ hint }) {
|
20
|
+
const html = useHint(hint);
|
21
|
+
return (React.createElement(Tooltip, { title: React.createElement(QuillHTML, { html: html, className: "ob-hint-tooltip" }), arrow: true, enterTouchDelay: 0, leaveTouchDelay: 10000 },
|
22
|
+
React.createElement("i", { className: "material-icons has-text-grey-light ob-label__hint" }, "info")));
|
23
|
+
}
|
24
|
+
export function HintBelowLabel({ hint }) {
|
25
|
+
const html = useHint(hint);
|
26
|
+
return React.createElement(QuillHTML, { html: html, className: "ob-hint-text" });
|
27
|
+
}
|
19
28
|
export default React.memo(FormElementLabelContainer);
|
20
29
|
//# sourceMappingURL=FormElementLabelContainer.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementLabelContainer.js","sourceRoot":"","sources":["../../../src/components/renderer/FormElementLabelContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,OAAO,MAAM,qBAAqB,CAAA;
|
1
|
+
{"version":3,"file":"FormElementLabelContainer.js","sourceRoot":"","sources":["../../../src/components/renderer/FormElementLabelContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,OAAO,MAAM,qBAAqB,CAAA;AACzC,OAAO,SAAS,MAAM,cAAc,CAAA;AAEpC,SAAS,yBAAyB,CAAC,EACjC,SAAS,EACT,OAAO,EACP,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,OAAO,GAQR;IACC,OAAO,CACL,6BAAK,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC;QACjD,6BAAK,SAAS,EAAC,2BAA2B;YACvC,OAAO;YACR,+BACE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE;oBAC1B,gCAAgC,EAAE,QAAQ;iBAC3C,CAAC,EACF,OAAO,EAAE,EAAE,IAEV,OAAO,CAAC,KAAK,CACR;YACP,OAAO,CAAC,IAAI;gBACX,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAC/D,oBAAC,WAAW,IAAC,IAAI,EAAE,OAAO,CAAC,IAAI,GAAI,CACpC,CACC;QACL,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY,KAAK,aAAa,IAAI,CACzD,6BAAK,SAAS,EAAC,yBAAyB;YACtC,oBAAC,cAAc,IAAC,IAAI,EAAE,OAAO,CAAC,IAAI,GAAI,CAClC,CACP;QACA,QAAQ,CACL,CACP,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,EAAoB;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1B,OAAO,CACL,oBAAC,OAAO,IACN,KAAK,EAAE,oBAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAC,iBAAiB,GAAG,EAC5D,KAAK,QACL,eAAe,EAAE,CAAC,EAClB,eAAe,EAAE,KAAK;QAEtB,2BAAG,SAAS,EAAC,mDAAmD,WAAS,CACjE,CACX,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAE,IAAI,EAAoB;IACvD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1B,OAAO,oBAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAC,cAAc,GAAG,CAAA;AAC3D,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { Tooltip } from '@mui/material'\nimport clsx from 'clsx'\nimport { FormTypes } from '@oneblink/types'\nimport useHint from '../../hooks/useHint'\nimport QuillHTML from '../QuillHTML'\n\nfunction FormElementLabelContainer({\n className,\n element,\n id,\n required,\n children,\n leading,\n}: {\n className: string\n element: FormTypes.FormElementBase\n id: string\n required: boolean\n children: React.ReactNode\n leading?: React.ReactNode\n}) {\n return (\n <div className={clsx('ob-form__element', className)}>\n <div className=\"label ob-label__container\">\n {leading}\n <label\n className={clsx('ob-label', {\n 'ob-label__required is-required': required,\n })}\n htmlFor={id}\n >\n {element.label}\n </label>\n {element.hint &&\n (element.hintPosition === 'TOOLTIP' || !element.hintPosition) && (\n <HintTooltip hint={element.hint} />\n )}\n </div>\n {element.hint && element.hintPosition === 'BELOW_LABEL' && (\n <div className=\"ob-hint-text__container\">\n <HintBelowLabel hint={element.hint} />\n </div>\n )}\n {children}\n </div>\n )\n}\n\nexport function HintTooltip({ hint }: { hint: string }) {\n const html = useHint(hint)\n\n return (\n <Tooltip\n title={<QuillHTML html={html} className=\"ob-hint-tooltip\" />}\n arrow\n enterTouchDelay={0}\n leaveTouchDelay={10000}\n >\n <i className=\"material-icons has-text-grey-light ob-label__hint\">info</i>\n </Tooltip>\n )\n}\n\nexport function HintBelowLabel({ hint }: { hint: string }) {\n const html = useHint(hint)\n\n return <QuillHTML html={html} className=\"ob-hint-text\" />\n}\n\nexport default React.memo(FormElementLabelContainer)\n"]}
|
@@ -6,6 +6,7 @@ import useFormSubmissionModel from '../hooks/useFormSubmissionModelContext';
|
|
6
6
|
import { Sentry } from '@oneblink/apps';
|
7
7
|
import { localisationService } from '@oneblink/apps';
|
8
8
|
import { formElementsService } from '@oneblink/sdk-core';
|
9
|
+
import QuillHTML from '../components/QuillHTML';
|
9
10
|
const isUnenteredValue = (value) => {
|
10
11
|
return !value && value !== 0;
|
11
12
|
};
|
@@ -165,7 +166,7 @@ function FormElementCalculation({ element, onChange, value }) {
|
|
165
166
|
}, [calculation, element, formSubmissionModel, onChange, value]);
|
166
167
|
return (React.createElement("div", { className: "cypress-calculation-element" },
|
167
168
|
React.createElement("div", { className: "ob-form__element ob-calculation" },
|
168
|
-
React.createElement(
|
169
|
+
React.createElement(QuillHTML, { html: htmlValue, className: "cypress-calculation-result ob-calculation__content" }),
|
169
170
|
hasError && (React.createElement("div", { className: "notification cypress-calculation-is-invalid", role: "alert" },
|
170
171
|
React.createElement("div", { className: "columns is-vcentered" },
|
171
172
|
React.createElement("div", { className: "column is-narrow" },
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementCalculation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementCalculation.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport ExpressionParser from 'morph-expressions'\nimport escapeString from 'escape-string-regexp'\nimport sanitizeHtmlStandard from '../services/sanitize-html'\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport { FormTypes } from '@oneblink/types'\nimport { Sentry } from '@oneblink/apps'\nimport { localisationService } from '@oneblink/apps'\nimport {\n FormElementValueChangeHandler,\n FormSubmissionModel,\n} from '../types/form'\nimport { formElementsService } from '@oneblink/sdk-core'\ntype Props = {\n element: FormTypes.CalculationElement\n onChange: FormElementValueChangeHandler<number>\n value: unknown | undefined\n}\n\nconst isUnenteredValue = (value: unknown | undefined) => {\n return !value && value !== 0\n}\n\nconst isObjectWithValue = (obj: unknown): obj is { value: unknown } => {\n return typeof obj === 'object' && obj !== null && 'value' in obj\n}\n\nfunction FormElementCalculation({ element, onChange, value }: Props) {\n const { formSubmissionModel } = useFormSubmissionModel()\n\n const htmlValue = React.useMemo(() => {\n let htmlTemplate\n\n if (!isNaN(value as number)) {\n htmlTemplate = element.defaultValue\n } else {\n console.log(\n '[Calculation] Was not a number... setting pre-calculation display',\n )\n htmlTemplate = element.preCalculationDisplay\n }\n\n const numberValue = typeof value === 'number' ? value : 0\n return sanitizeHtmlStandard(\n (htmlTemplate || '').replace(\n /{result}/gi,\n element.displayAsCurrency\n ? localisationService.formatCurrency(numberValue)\n : localisationService.formatNumber(numberValue),\n ),\n )\n }, [element, value])\n\n const registerProperty = React.useCallback(\n (\n exprParser,\n {\n replacement,\n nestedElementNames,\n }: {\n replacement: string\n nestedElementNames: string[]\n },\n ) => {\n exprParser.registerProperty(\n replacement,\n (submission: FormSubmissionModel) => {\n const defaultAccumulator = submission[nestedElementNames[0]]\n\n return nestedElementNames.reduce(\n (\n elementValue: unknown | undefined,\n elementName: string,\n index: number,\n ) => {\n // Numbers can just be returned as is\n if (typeof elementValue === 'number') {\n return elementValue\n }\n\n // attempt to get a number from the element value as a string.\n // NaN is accounted for is the calculation\n // so we can return that from here\n if (typeof elementValue === 'string') {\n return parseFloat(elementValue)\n }\n\n if (Array.isArray(elementValue)) {\n // If there are no entries, we can return null\n // to prevent the calculation from running.\n if (!elementValue.length) {\n return NaN\n }\n\n // An array could be an element that allows multiple\n // values e.g. checkboxes. If thats that case, we just\n // add them all together and move on\n const elementValues = elementValue.map((entry) =>\n parseFloat(entry),\n )\n if (elementValues.every((entry) => !Number.isNaN(entry))) {\n return elementValues.reduce(\n (number, entry) => number + entry,\n 0,\n )\n }\n\n // Other wise attempt to process it as a repeatable set\n // If we found another repeatable set to process,\n // pass it to the next element name to\n // iterate over the entries\n\n // If we are processing the entries in a repeatable set,\n // we can sum the numbers elements in the entries\n const nextElementName = nestedElementNames[index + 1]\n\n let isNestedRepeatableSet = false\n const nestedElementValues = elementValue.reduce(\n (nestedElementValues, entry) => {\n if (entry) {\n const nextElementValue = entry[nextElementName]\n if (Array.isArray(nextElementValue)) {\n if (nextElementValue.length) {\n nestedElementValues.push(...nextElementValue)\n isNestedRepeatableSet = true\n }\n } else {\n nestedElementValues.push(nextElementValue)\n }\n }\n return nestedElementValues\n },\n [],\n )\n\n // If the nested element values are all arrays, we can pass them on to the next iteration\n if (isNestedRepeatableSet) {\n return nestedElementValues\n }\n\n return nestedElementValues.reduce(\n (total: number, nestedElementValue: unknown | undefined) => {\n if (Number.isNaN(total)) {\n return NaN\n }\n const value = parseFloat(nestedElementValue as string)\n if (Number.isNaN(value)) {\n return NaN\n }\n return total + value\n },\n 0,\n )\n }\n\n // \"compliance\" form element has an object value with a \"value\" property.\n if (\n isObjectWithValue(elementValue) &&\n typeof elementValue.value === 'string'\n ) {\n return parseFloat(elementValue.value)\n }\n\n // We did not find a number value from the known elements,\n // we will assume we are at the end of the line.\n return NaN\n },\n defaultAccumulator,\n )\n },\n )\n },\n [],\n )\n\n const { calculation, hasError } = React.useMemo(() => {\n const exprParser = new ExpressionParser()\n exprParser.registerFunction('ROUND', (value: number, precision: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return parseFloat(value.toFixed(precision))\n }\n return null\n })\n exprParser.registerFunction(\n 'ISNULL',\n (value: unknown | undefined, defaultValue: number) => {\n if (isUnenteredValue(value)) {\n return defaultValue || 0\n }\n return value\n },\n )\n\n try {\n if (!element.calculation) throw new Error('Element has no calculation.')\n const elementNames: string[] = []\n formElementsService.matchElementsTagRegex(\n element.calculation,\n ({ elementName }) => {\n elementNames.push(elementName)\n },\n )\n\n const code = elementNames.reduce((code, elementName, index) => {\n const regex = new RegExp(escapeString(`{ELEMENT:${elementName}}`), 'g')\n const replacement = `a${index}`\n registerProperty(exprParser, {\n replacement,\n nestedElementNames: elementName.split('|'),\n })\n return code.replace(regex, replacement)\n }, element.calculation || '')\n\n return {\n calculation: exprParser.parse(code.trim()),\n hasError: false,\n }\n } catch (e) {\n console.warn(\n 'Error while setting up parsing for calculation element',\n element,\n e,\n )\n Sentry.captureException(e)\n return {\n calculation: null,\n hasError: true,\n }\n }\n }, [element, registerProperty])\n\n // MODEL LISTENER\n React.useEffect(() => {\n if (!calculation) return\n const newValue = calculation.eval(formSubmissionModel)\n if (value === newValue || (value === undefined && isNaN(newValue))) {\n return\n }\n if (!isNaN(newValue)) {\n onChange(element, newValue)\n } else {\n onChange(element, undefined)\n }\n }, [calculation, element, formSubmissionModel, onChange, value])\n\n return (\n <div className=\"cypress-calculation-element\">\n <div className=\"ob-form__element ob-calculation\">\n <div\n className=\"cypress-calculation-result ob-calculation__content ql-editor\"\n dangerouslySetInnerHTML={{ __html: htmlValue }}\n ></div>\n {hasError && (\n <div\n className=\"notification cypress-calculation-is-invalid\"\n role=\"alert\"\n >\n <div className=\"columns is-vcentered\">\n <div className=\"column is-narrow\">\n <i className=\"material-icons has-text-warning\">error</i>\n </div>\n <div className=\"column\">\n <p>There is an error in the calculation for this element.</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementCalculation)\n"]}
|
1
|
+
{"version":3,"file":"FormElementCalculation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementCalculation.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport ExpressionParser from 'morph-expressions'\nimport escapeString from 'escape-string-regexp'\nimport sanitizeHtmlStandard from '../services/sanitize-html'\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport { FormTypes } from '@oneblink/types'\nimport { Sentry } from '@oneblink/apps'\nimport { localisationService } from '@oneblink/apps'\nimport {\n FormElementValueChangeHandler,\n FormSubmissionModel,\n} from '../types/form'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport QuillHTML from '../components/QuillHTML'\ntype Props = {\n element: FormTypes.CalculationElement\n onChange: FormElementValueChangeHandler<number>\n value: unknown | undefined\n}\n\nconst isUnenteredValue = (value: unknown | undefined) => {\n return !value && value !== 0\n}\n\nconst isObjectWithValue = (obj: unknown): obj is { value: unknown } => {\n return typeof obj === 'object' && obj !== null && 'value' in obj\n}\n\nfunction FormElementCalculation({ element, onChange, value }: Props) {\n const { formSubmissionModel } = useFormSubmissionModel()\n\n const htmlValue = React.useMemo(() => {\n let htmlTemplate\n\n if (!isNaN(value as number)) {\n htmlTemplate = element.defaultValue\n } else {\n console.log(\n '[Calculation] Was not a number... setting pre-calculation display',\n )\n htmlTemplate = element.preCalculationDisplay\n }\n\n const numberValue = typeof value === 'number' ? value : 0\n return sanitizeHtmlStandard(\n (htmlTemplate || '').replace(\n /{result}/gi,\n element.displayAsCurrency\n ? localisationService.formatCurrency(numberValue)\n : localisationService.formatNumber(numberValue),\n ),\n )\n }, [element, value])\n\n const registerProperty = React.useCallback(\n (\n exprParser,\n {\n replacement,\n nestedElementNames,\n }: {\n replacement: string\n nestedElementNames: string[]\n },\n ) => {\n exprParser.registerProperty(\n replacement,\n (submission: FormSubmissionModel) => {\n const defaultAccumulator = submission[nestedElementNames[0]]\n\n return nestedElementNames.reduce(\n (\n elementValue: unknown | undefined,\n elementName: string,\n index: number,\n ) => {\n // Numbers can just be returned as is\n if (typeof elementValue === 'number') {\n return elementValue\n }\n\n // attempt to get a number from the element value as a string.\n // NaN is accounted for is the calculation\n // so we can return that from here\n if (typeof elementValue === 'string') {\n return parseFloat(elementValue)\n }\n\n if (Array.isArray(elementValue)) {\n // If there are no entries, we can return null\n // to prevent the calculation from running.\n if (!elementValue.length) {\n return NaN\n }\n\n // An array could be an element that allows multiple\n // values e.g. checkboxes. If thats that case, we just\n // add them all together and move on\n const elementValues = elementValue.map((entry) =>\n parseFloat(entry),\n )\n if (elementValues.every((entry) => !Number.isNaN(entry))) {\n return elementValues.reduce(\n (number, entry) => number + entry,\n 0,\n )\n }\n\n // Other wise attempt to process it as a repeatable set\n // If we found another repeatable set to process,\n // pass it to the next element name to\n // iterate over the entries\n\n // If we are processing the entries in a repeatable set,\n // we can sum the numbers elements in the entries\n const nextElementName = nestedElementNames[index + 1]\n\n let isNestedRepeatableSet = false\n const nestedElementValues = elementValue.reduce(\n (nestedElementValues, entry) => {\n if (entry) {\n const nextElementValue = entry[nextElementName]\n if (Array.isArray(nextElementValue)) {\n if (nextElementValue.length) {\n nestedElementValues.push(...nextElementValue)\n isNestedRepeatableSet = true\n }\n } else {\n nestedElementValues.push(nextElementValue)\n }\n }\n return nestedElementValues\n },\n [],\n )\n\n // If the nested element values are all arrays, we can pass them on to the next iteration\n if (isNestedRepeatableSet) {\n return nestedElementValues\n }\n\n return nestedElementValues.reduce(\n (total: number, nestedElementValue: unknown | undefined) => {\n if (Number.isNaN(total)) {\n return NaN\n }\n const value = parseFloat(nestedElementValue as string)\n if (Number.isNaN(value)) {\n return NaN\n }\n return total + value\n },\n 0,\n )\n }\n\n // \"compliance\" form element has an object value with a \"value\" property.\n if (\n isObjectWithValue(elementValue) &&\n typeof elementValue.value === 'string'\n ) {\n return parseFloat(elementValue.value)\n }\n\n // We did not find a number value from the known elements,\n // we will assume we are at the end of the line.\n return NaN\n },\n defaultAccumulator,\n )\n },\n )\n },\n [],\n )\n\n const { calculation, hasError } = React.useMemo(() => {\n const exprParser = new ExpressionParser()\n exprParser.registerFunction('ROUND', (value: number, precision: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return parseFloat(value.toFixed(precision))\n }\n return null\n })\n exprParser.registerFunction(\n 'ISNULL',\n (value: unknown | undefined, defaultValue: number) => {\n if (isUnenteredValue(value)) {\n return defaultValue || 0\n }\n return value\n },\n )\n\n try {\n if (!element.calculation) throw new Error('Element has no calculation.')\n const elementNames: string[] = []\n formElementsService.matchElementsTagRegex(\n element.calculation,\n ({ elementName }) => {\n elementNames.push(elementName)\n },\n )\n\n const code = elementNames.reduce((code, elementName, index) => {\n const regex = new RegExp(escapeString(`{ELEMENT:${elementName}}`), 'g')\n const replacement = `a${index}`\n registerProperty(exprParser, {\n replacement,\n nestedElementNames: elementName.split('|'),\n })\n return code.replace(regex, replacement)\n }, element.calculation || '')\n\n return {\n calculation: exprParser.parse(code.trim()),\n hasError: false,\n }\n } catch (e) {\n console.warn(\n 'Error while setting up parsing for calculation element',\n element,\n e,\n )\n Sentry.captureException(e)\n return {\n calculation: null,\n hasError: true,\n }\n }\n }, [element, registerProperty])\n\n // MODEL LISTENER\n React.useEffect(() => {\n if (!calculation) return\n const newValue = calculation.eval(formSubmissionModel)\n if (value === newValue || (value === undefined && isNaN(newValue))) {\n return\n }\n if (!isNaN(newValue)) {\n onChange(element, newValue)\n } else {\n onChange(element, undefined)\n }\n }, [calculation, element, formSubmissionModel, onChange, value])\n\n return (\n <div className=\"cypress-calculation-element\">\n <div className=\"ob-form__element ob-calculation\">\n <QuillHTML\n html={htmlValue}\n className=\"cypress-calculation-result ob-calculation__content\"\n />\n {hasError && (\n <div\n className=\"notification cypress-calculation-is-invalid\"\n role=\"alert\"\n >\n <div className=\"columns is-vcentered\">\n <div className=\"column is-narrow\">\n <i className=\"material-icons has-text-warning\">error</i>\n </div>\n <div className=\"column\">\n <p>There is an error in the calculation for this element.</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementCalculation)\n"]}
|
@@ -4,6 +4,7 @@ import { RepeatableSetIndexContext } from './FormElementRepeatableSet';
|
|
4
4
|
import useFormSubmissionModel from '../hooks/useFormSubmissionModelContext';
|
5
5
|
import { submissionService } from '@oneblink/sdk-core';
|
6
6
|
import { localisationService } from '@oneblink/apps';
|
7
|
+
import QuillHTML from '../components/QuillHTML';
|
7
8
|
function FormElementHTML({ element }) {
|
8
9
|
const { formSubmissionModel, elements } = useFormSubmissionModel();
|
9
10
|
const index = React.useContext(RepeatableSetIndexContext);
|
@@ -22,9 +23,7 @@ function FormElementHTML({ element }) {
|
|
22
23
|
}, [element.defaultValue, elements, formSubmissionModel, index]);
|
23
24
|
return (React.createElement("div", { className: "cypress-html-element" },
|
24
25
|
React.createElement("div", { className: "ob-form__element ob-information cypress-html-element" },
|
25
|
-
React.createElement(
|
26
|
-
__html: html,
|
27
|
-
} }))));
|
26
|
+
React.createElement(QuillHTML, { html: html, className: "cypress-html-element-content ob-information__content" }))));
|
28
27
|
}
|
29
28
|
export default React.memo(FormElementHTML);
|
30
29
|
//# sourceMappingURL=FormElementHTML.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementHTML.js","sourceRoot":"","sources":["../../src/form-elements/FormElementHTML.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,YAAY,MAAM,2BAA2B,CAAA;AAEpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,sBAAsB,MAAM,wCAAwC,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;
|
1
|
+
{"version":3,"file":"FormElementHTML.js","sourceRoot":"","sources":["../../src/form-elements/FormElementHTML.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,YAAY,MAAM,2BAA2B,CAAA;AAEpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,sBAAsB,MAAM,wCAAwC,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,SAAS,MAAM,yBAAyB,CAAA;AAM/C,SAAS,eAAe,CAAC,EAAE,OAAO,EAAS;IACzC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,GAAG,sBAAsB,EAAE,CAAA;IAClE,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAA;IACzD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC9B,IAAI,IAAI,GAAG,OAAO,CAAC,YAAY,CAAA;QAC/B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;QAEtD,IAAI,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,IAAI,EAAE;YAClD,UAAU,EAAE,mBAAmB;YAC/B,YAAY,EAAE,QAAQ;YACtB,cAAc,EAAE,mBAAmB,CAAC,cAAc;YAClD,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9D,YAAY,EAAE,mBAAmB,CAAC,YAAY;YAC9C,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;SAC/D,CAAC,CAAA;QAEF,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,EAAE,mBAAmB,EAAE,KAAK,CAAC,CAAC,CAAA;IAEhE,OAAO,CACL,6BAAK,SAAS,EAAC,sBAAsB;QACnC,6BAAK,SAAS,EAAC,sDAAsD;YACnE,oBAAC,SAAS,IACR,IAAI,EAAE,IAAI,EACV,SAAS,EAAC,sDAAsD,GAChE,CACE,CACF,CACP,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport sanitizeHtml from '../services/sanitize-html'\nimport { FormTypes } from '@oneblink/types'\nimport { RepeatableSetIndexContext } from './FormElementRepeatableSet'\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport { submissionService } from '@oneblink/sdk-core'\nimport { localisationService } from '@oneblink/apps'\nimport QuillHTML from '../components/QuillHTML'\n\ntype Props = {\n element: FormTypes.HtmlElement\n}\n\nfunction FormElementHTML({ element }: Props) {\n const { formSubmissionModel, elements } = useFormSubmissionModel()\n const index = React.useContext(RepeatableSetIndexContext)\n const html = React.useMemo(() => {\n let html = element.defaultValue\n html = html.replace('{INDEX}', (index + 1).toString())\n\n html = submissionService.replaceElementValues(html, {\n submission: formSubmissionModel,\n formElements: elements,\n formatCurrency: localisationService.formatCurrency,\n formatDate: (v) => localisationService.formatDate(new Date(v)),\n formatNumber: localisationService.formatNumber,\n formatTime: (v) => localisationService.formatTime(new Date(v)),\n })\n\n return sanitizeHtml(html)\n }, [element.defaultValue, elements, formSubmissionModel, index])\n\n return (\n <div className=\"cypress-html-element\">\n <div className=\"ob-form__element ob-information cypress-html-element\">\n <QuillHTML\n html={html}\n className=\"cypress-html-element-content ob-information__content\"\n />\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementHTML)\n"]}
|
@@ -4,11 +4,10 @@ import { Collapse, Tooltip } from '@mui/material';
|
|
4
4
|
import useBooleanState from '../hooks/useBooleanState';
|
5
5
|
import OneBlinkFormElements from '../components/renderer/OneBlinkFormElements';
|
6
6
|
import { checkSectionValidity } from '../services/form-validation';
|
7
|
-
import
|
7
|
+
import { HintBelowLabel, HintTooltip, } from '../components/renderer/FormElementLabelContainer';
|
8
8
|
function FormElementSection({ element, onLookup, displayValidationMessages, ...props }) {
|
9
9
|
const [isCollapsed, , , toggle] = useBooleanState(element.isCollapsed);
|
10
10
|
const [isDisplayingError, setIsDisplayingError] = React.useState(isCollapsed);
|
11
|
-
const hint = useHint(element.hint);
|
12
11
|
React.useEffect(() => {
|
13
12
|
if (isCollapsed && !isDisplayingError) {
|
14
13
|
setIsDisplayingError(true);
|
@@ -54,17 +53,16 @@ function FormElementSection({ element, onLookup, displayValidationMessages, ...p
|
|
54
53
|
React.createElement("div", { className: "ob-section__header cypress-section-header", onClick: toggle },
|
55
54
|
React.createElement("h3", { className: "ob-section__header-text title is-3" },
|
56
55
|
element.label,
|
57
|
-
hint &&
|
58
|
-
(element.hintPosition === 'TOOLTIP' || !element.hintPosition) && (React.createElement(
|
59
|
-
React.createElement("i", { className: "material-icons has-text-grey-light ob-label__hint" }, "info")))),
|
56
|
+
element.hint &&
|
57
|
+
(element.hintPosition === 'TOOLTIP' || !element.hintPosition) && (React.createElement(HintTooltip, { hint: element.hint }))),
|
60
58
|
React.createElement("div", { className: "ob-section__header-icon-container" },
|
61
59
|
isInvalid && (React.createElement(Tooltip, { title: "Section has errors" },
|
62
60
|
React.createElement("i", { className: "material-icons has-text-danger cypress-section-invalid-icon section-invalid-icon fade-in" }, "warning"))),
|
63
61
|
React.createElement("i", { className: clsx('ob-section__header-icon material-icons', {
|
64
62
|
'is-rotated': !isCollapsed,
|
65
63
|
}) }, "expand_more")),
|
66
|
-
hint && element.hintPosition === 'BELOW_LABEL' && (React.createElement("div", { className: "ob-section__hint-text-container" },
|
67
|
-
React.createElement(
|
64
|
+
element.hint && element.hintPosition === 'BELOW_LABEL' && (React.createElement("div", { className: "ob-section__hint-text-container" },
|
65
|
+
React.createElement(HintBelowLabel, { hint: element.hint })))),
|
68
66
|
React.createElement("hr", { className: "ob-section__divider" }),
|
69
67
|
React.createElement(Collapse, { in: !isCollapsed, classes: {
|
70
68
|
root: 'ob-section__content',
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementSection.js","sourceRoot":"","sources":["../../src/form-elements/FormElementSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,eAAe,MAAM,0BAA0B,CAAA;AACtD,OAAO,oBAEN,MAAM,6CAA6C,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAElE,OAAO,
|
1
|
+
{"version":3,"file":"FormElementSection.js","sourceRoot":"","sources":["../../src/form-elements/FormElementSection.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport { Collapse, Tooltip } from '@mui/material'\nimport { FormTypes } from '@oneblink/types'\nimport useBooleanState from '../hooks/useBooleanState'\nimport OneBlinkFormElements, {\n Props,\n} from '../components/renderer/OneBlinkFormElements'\nimport { checkSectionValidity } from '../services/form-validation'\nimport { FormElementLookupHandler } from '../types/form'\nimport {\n HintBelowLabel,\n HintTooltip,\n} from '../components/renderer/FormElementLabelContainer'\n\nfunction FormElementSection<T extends FormTypes._NestedElementsElement>({\n element,\n onLookup,\n displayValidationMessages,\n ...props\n}: Omit<Props<T>, 'elements'> & {\n element: FormTypes.SectionElement\n}) {\n const [isCollapsed, , , toggle] = useBooleanState(element.isCollapsed)\n const [isDisplayingError, setIsDisplayingError] = React.useState(isCollapsed)\n\n React.useEffect(() => {\n if (isCollapsed && !isDisplayingError) {\n setIsDisplayingError(true)\n }\n }, [isCollapsed, isDisplayingError])\n\n const displayValidationMessage =\n displayValidationMessages || isDisplayingError\n\n const isInvalid = React.useMemo(() => {\n return (\n displayValidationMessage &&\n checkSectionValidity(element, props.formElementsValidation)\n )\n }, [displayValidationMessage, element, props.formElementsValidation])\n\n const isValid = React.useMemo(() => {\n return !checkSectionValidity(element, props.formElementsValidation)\n }, [element, props.formElementsValidation])\n\n const handleLookup = React.useCallback<FormElementLookupHandler>(\n (mergeLookupResults) => {\n onLookup((currentFormSubmission) => {\n let model = currentFormSubmission.submission\n const elements = currentFormSubmission.elements.map((formElement) => {\n if (formElement.type === 'section' && formElement.id === element.id) {\n const { elements, submission } = mergeLookupResults({\n elements: formElement.elements,\n submission: currentFormSubmission.submission,\n lastElementUpdated: currentFormSubmission.lastElementUpdated,\n })\n model = submission\n return {\n ...formElement,\n elements,\n }\n }\n return formElement\n })\n\n return {\n elements,\n submission: model,\n lastElemenetUpdated: currentFormSubmission.lastElementUpdated,\n }\n })\n },\n [element.id, onLookup],\n )\n\n return (\n <div\n className={clsx('ob-section', {\n 'ob-section__invalid': isInvalid,\n 'ob-section__valid': isValid,\n })}\n >\n <div\n className=\"ob-section__header cypress-section-header\"\n onClick={toggle}\n >\n <h3 className=\"ob-section__header-text title is-3\">\n {element.label}\n {element.hint &&\n (element.hintPosition === 'TOOLTIP' || !element.hintPosition) && (\n <HintTooltip hint={element.hint} />\n )}\n </h3>\n <div className=\"ob-section__header-icon-container\">\n {isInvalid && (\n <Tooltip title=\"Section has errors\">\n <i className=\"material-icons has-text-danger cypress-section-invalid-icon section-invalid-icon fade-in\">\n warning\n </i>\n </Tooltip>\n )}\n <i\n className={clsx('ob-section__header-icon material-icons', {\n 'is-rotated': !isCollapsed,\n })}\n >\n expand_more\n </i>\n </div>\n {element.hint && element.hintPosition === 'BELOW_LABEL' && (\n <div className=\"ob-section__hint-text-container\">\n <HintBelowLabel hint={element.hint} />\n </div>\n )}\n </div>\n <hr className=\"ob-section__divider\" />\n <Collapse\n in={!isCollapsed}\n classes={{\n root: 'ob-section__content',\n entered: 'ob-section__expanded',\n hidden: 'ob-section__collapsed',\n }}\n >\n <OneBlinkFormElements\n {...props}\n displayValidationMessages={displayValidationMessage}\n onLookup={handleLookup}\n elements={element.elements}\n />\n </Collapse>\n </div>\n )\n}\n\nexport default React.memo(FormElementSection)\n"]}
|
package/dist/hooks/useHint.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
declare const useHint: (elementHint: string
|
1
|
+
declare const useHint: (elementHint: string) => string;
|
2
2
|
export default useHint;
|
package/dist/hooks/useHint.js
CHANGED
@@ -8,8 +8,6 @@ const useHint = (elementHint) => {
|
|
8
8
|
const { formSubmissionModel, elements } = useFormSubmissionModel();
|
9
9
|
const index = React.useContext(RepeatableSetIndexContext);
|
10
10
|
return React.useMemo(() => {
|
11
|
-
if (!elementHint)
|
12
|
-
return;
|
13
11
|
let html = elementHint;
|
14
12
|
html = html.replace('{INDEX}', (index + 1).toString());
|
15
13
|
html = submissionService.replaceElementValues(html, {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useHint.js","sourceRoot":"","sources":["../../src/hooks/useHint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,YAAY,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA;AACrF,OAAO,sBAAsB,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD,MAAM,OAAO,GAAG,CAAC,
|
1
|
+
{"version":3,"file":"useHint.js","sourceRoot":"","sources":["../../src/hooks/useHint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,YAAY,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA;AACrF,OAAO,sBAAsB,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD,MAAM,OAAO,GAAG,CAAC,WAAmB,EAAE,EAAE;IACtC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,GAAG,sBAAsB,EAAE,CAAA;IAClE,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAA;IACzD,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACxB,IAAI,IAAI,GAAG,WAAW,CAAA;QACtB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;QAEtD,IAAI,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,IAAI,EAAE;YAClD,UAAU,EAAE,mBAAmB;YAC/B,YAAY,EAAE,QAAQ;YACtB,cAAc,EAAE,mBAAmB,CAAC,cAAc;YAClD,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9D,YAAY,EAAE,mBAAmB,CAAC,YAAY;YAC9C,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;SAC/D,CAAC,CAAA;QAEF,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,mBAAmB,EAAE,KAAK,CAAC,CAAC,CAAA;AACzD,CAAC,CAAA;AAED,eAAe,OAAO,CAAA","sourcesContent":["import * as React from 'react'\nimport sanitizeHtml from '../services/sanitize-html'\nimport { RepeatableSetIndexContext } from '../form-elements/FormElementRepeatableSet'\nimport useFormSubmissionModel from './useFormSubmissionModelContext'\nimport { submissionService } from '@oneblink/sdk-core'\nimport { localisationService } from '@oneblink/apps'\n\nconst useHint = (elementHint: string) => {\n const { formSubmissionModel, elements } = useFormSubmissionModel()\n const index = React.useContext(RepeatableSetIndexContext)\n return React.useMemo(() => {\n let html = elementHint\n html = html.replace('{INDEX}', (index + 1).toString())\n\n html = submissionService.replaceElementValues(html, {\n submission: formSubmissionModel,\n formElements: elements,\n formatCurrency: localisationService.formatCurrency,\n formatDate: (v) => localisationService.formatDate(new Date(v)),\n formatNumber: localisationService.formatNumber,\n formatTime: (v) => localisationService.formatTime(new Date(v)),\n })\n\n return sanitizeHtml(html)\n }, [elementHint, elements, formSubmissionModel, index])\n}\n\nexport default useHint\n"]}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@oneblink/apps-react",
|
3
3
|
"description": "Helper functions for OneBlink apps in ReactJS.",
|
4
|
-
"version": "2.9.0-beta.
|
4
|
+
"version": "2.9.0-beta.9",
|
5
5
|
"author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
|
6
6
|
"bugs": {
|
7
7
|
"url": "https://github.com/oneblink/apps-react/issues"
|