From 61763a961b4fbd6373d0fd1b05047e1ac26b67ec Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Fri, 17 Jan 2025 15:46:29 +0100 Subject: [PATCH 1/7] - updated code, added new settings; --- src/assets/scss/components/formBuilder.scss | 5 + src/assets/scss/components/misc.scss | 6 +- .../components/BuilderElement/index.js | 28 ++- .../components/ElementSetting/index.js | 8 + .../components/ElementSettingChips/index.js | 43 +++++ .../ElementSettingTableColumns-old/index.js | 159 ------------------ .../BuilderElementSettings/index.js | 16 +- src/pages/BandoFormsEdit/index.js | 6 +- src/tempData.js | 10 +- 9 files changed, 114 insertions(+), 167 deletions(-) create mode 100644 src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingChips/index.js delete mode 100644 src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js diff --git a/src/assets/scss/components/formBuilder.scss b/src/assets/scss/components/formBuilder.scss index b07f322..9382f37 100644 --- a/src/assets/scss/components/formBuilder.scss +++ b/src/assets/scss/components/formBuilder.scss @@ -58,6 +58,11 @@ flex-direction: column; gap: 5px; align-items: flex-start; + + .tagHeader { + display: flex; + gap: 10px; + } } .label { diff --git a/src/assets/scss/components/misc.scss b/src/assets/scss/components/misc.scss index 8f89d4f..9f59541 100644 --- a/src/assets/scss/components/misc.scss +++ b/src/assets/scss/components/misc.scss @@ -31,6 +31,10 @@ } } .p-tag { + &.p-tag-secondary { + background-color: var(--table-border-color); + } + .p-tag-value { color: var(--menuitem-active-color); } @@ -147,7 +151,7 @@ max-width: 100%; } -.p-dropdown { +.p-dropdown, .p-chips, .p-chips-multiple-container { width: 100%; } diff --git a/src/pages/BandoFormsEdit/components/BuilderElement/index.js b/src/pages/BandoFormsEdit/components/BuilderElement/index.js index 8a7b86e..9f5e0d0 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElement/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElement/index.js @@ -1,7 +1,8 @@ -import React, { useRef } from 'react' +import React, { useEffect, useRef, useState } from 'react' import { useDrag, useDrop } from 'react-dnd' import { ItemTypes } from '../ItemTypes'; import { __ } from '@wordpress/i18n'; +import { head, isEmpty } from 'ramda'; // store import { storeSet, useStore } from '../../../../store'; @@ -14,6 +15,10 @@ import BuilderElementProperLabel from '../BuilderElementProperLabel'; const BuilderElement = ({ id, name, label, index, bandoStatus }) => { const draggingElementId = useStore().main.draggingElementId(); const ref = useRef(null); + const elements = useStore().main.formElements(); + const element = head(elements.filter(o => o.id === id)); + const [isVariable, setIsVariable] = useState('secondary'); + const [isFormula, setIsFormula] = useState('secondary'); const [{ handlerId }, drop] = useDrop({ accept: ItemTypes.FIELD, @@ -97,6 +102,19 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => { const opacity = isDragging ? 0 : 1; drag(drop(ref)); + useEffect(() => { + const variable = head(element.settings.filter(o => o.name === 'variable')); + const formula = head(element.settings.filter(o => o.name === 'formula')); + + if (variable && !isEmpty(variable.value)) { + setIsVariable('warning'); + } + + if (formula && !isEmpty(formula.value)) { + setIsFormula('warning'); + } + }, [elements]); + return ( draggingElementId === id ?
@@ -104,7 +122,13 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => {
:
- +
+ + {name === 'numberinput' + ? : null} + {name === 'numberinput' + ? : null} +
diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js index 67c1bf0..8a5d0c8 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js @@ -11,6 +11,7 @@ import { Editor } from 'primereact/editor'; import { mimeTypes } from '../../../../../../configData'; import ElementSettingTableColumns from '../ElementSettingTableColumns'; import { InputSwitch } from 'primereact/inputswitch'; +import ElementSettingChips from '../ElementSettingChips'; const ElementSetting = ({ setting, changeFn, updateDataFn, bandoStatus }) => { @@ -24,6 +25,8 @@ const ElementSetting = ({ setting, changeFn, updateDataFn, bandoStatus }) => { mime: __('Tipo di file', 'gepafin'), text: __('Testo formattato', 'gepafin'), table_columns: '', + variable: __('Variable (only letters and "_")', 'gepafin'), + formula: __('Auto calculation formula', 'gepafin') } const renderHeader = () => { @@ -85,6 +88,11 @@ const ElementSetting = ({ setting, changeFn, updateDataFn, bandoStatus }) => { return changeFn(e.value, setting.name)}/> + } else if (['variable'].includes(setting.name)) { + return changeFn(value, setting.name)} + value={setting.value}/> } else { return { + const [lastTyped, setLastTyped] = useState([]) + + const isValidValue = (newVal) => { + const validationRegex = /^[a-zA-Z_]+$/; + return validationRegex.test(newVal); + }; + + const handleAdd = (e) => { + const newValue = e.value[e.value.length - 1]; + + if (restrictedValues.includes(newValue)) { + changeFn([]); + return; + } + + if (!isValidValue(newValue)) { + changeFn(lastTyped); + return; + } + + setLastTyped(e.value) + changeFn(e.value); + }; + + return ( +
+ +
+ ); +} + +export default ElementSettingChips; \ No newline at end of file diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js deleted file mode 100644 index ee5d9aa..0000000 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js +++ /dev/null @@ -1,159 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { __ } from '@wordpress/i18n'; -import { wrap } from 'object-path-immutable'; -import { pathOr } from 'ramda'; - -// components -import { InputText } from 'primereact/inputtext'; -import { Button } from 'primereact/button'; -import { InputSwitch } from 'primereact/inputswitch'; - -// tools -import uniqid from '../../../../../../helpers/uniqid'; - -const ElementSettingTableColumns = ({ - value, - name, - setDataFn, - bandoStatus - }) => { - const [stateFieldData, setStateFieldData] = useState([]); - const [rowsData, setRowsData] = useState([]); - - const removeItem = (index) => { - const newData = stateFieldData.toSpliced(index, 1); - setStateFieldData(newData); - } - - const addNewItem = () => { - setStateFieldData([...stateFieldData, { name: uniqid('o'), label: '', predefined: false }]); - } - - const addNewRow = () => { - const obj = stateFieldData - .filter(o => o.predefined) - .reduce((acc, cur) => { - acc[cur.name] = '' - return acc; - }, {}); - setRowsData([...rowsData, obj]); - } - - const removeRow = (index) => { - const newRowsData = wrap(rowsData).del([index]).value(); - setRowsData(newRowsData); - } - - const onInputChange = (e, index) => { - const { value } = e.target; - const newData = stateFieldData.map((o, i) => { - if (i === index) { - o.label = value; - } - return o; - }) - setStateFieldData(newData); - } - - const onSubInputChange = (e, name, index) => { - const { value } = e.target; - const newRowsData = wrap(rowsData).set([index, name], value).value(); - setRowsData(newRowsData); - } - - const setChecked = (value, index) => { - let name = ''; - const newData = stateFieldData.map((o, i) => { - if (i === index) { - o.predefined = value; - name = o.name; - } - return o; - }); - - let newRowsData = []; - - if (value === false) { - newRowsData = rowsData.map(o => wrap(o).set([name], '').value()); - } else { - newRowsData = rowsData.map(o => wrap(o).set([name], '').value()); - } - - setRowsData(newRowsData); - setStateFieldData(newData); - } - - const properField = (item, i) => { - return <> - onInputChange(e, i)}/> -
- {__('Predefinito?', 'gepafin')} - setChecked(e.value, i)}/> -
- - } - - const properSubField = (item, i, name) => { - return onSubInputChange(e, name, i)}/> - } - - useEffect(() => { - const stateFieldData = pathOr([], ['stateFieldData'], value); - setStateFieldData(stateFieldData); - const rowsData = pathOr([], ['rowsData'], value); - setRowsData(rowsData); - }, []); - - useEffect(() => { - setDataFn(name, { - stateFieldData, - rowsData - }); - }, [stateFieldData, rowsData]); - - stateFieldData.filter(o => o.predefined) - - return ( - <> -
- {stateFieldData.map((o, i) =>
-
- {properField(o, i)} -
-
)} -
- {stateFieldData - .filter(o => o.predefined) - .map((o, i) =>
-
- -
- {rowsData.map((c, k) => { - return
-
- {properSubField(c, k, o.name)} -
-
- })} -
-
-
)} - - ) -} - -export default ElementSettingTableColumns; \ No newline at end of file diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js index 3e4f66a..0c1eed9 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js @@ -160,7 +160,9 @@ const BuilderElementSettings = ({ closeSettingsFn, bandoStatus }) => { {settings - ? settings.map((o) => !['variable', 'formula'].includes(o.name)) + .map((o) => { placeholder={__('Scegli', 'gepafin')}/>
+ + {settings + ? settings + .filter(o => ['variable', 'formula'].includes(o.name)) + .map((o) => ) + : null} +
: { const [forms, setForms] = useState([]); const [formOptions, setFormOptions] = useState([]); const [chosenMainFieldOptions, setChosenMainFieldOptions] = useState([]); - //const [chosenMainField, setChosenMainField] = useState(''); const [mainFieldSuboptions, setMainFieldSubOptions] = useState([]); const [bandoStatus, setBandoStatus] = useState(''); const [isFlowAllowed, setIsFlowAllowed] = useState(true); @@ -162,18 +161,18 @@ const BandoFlowEdit = () => { const shoudDisableSaving = useCallback(() => { const nonEmptyFlowItems = flowStructure.flowData.filter(o => isEmpty(o.chosenField)).filter(o => !isEmpty(o.chosenValue)); - /*if (flowForms.length > 2) { - console.log('disable BTN:', nonEmptyFlowItems.length !== flowForms.length - 2, isEmpty(flowEdges), 'PUBLISH' === bandoStatus, - isEmpty(initialForm), isEmpty(finalForm)); + /*if (forms.length > 2) { + console.log('disable BTN:', nonEmptyFlowItems.length !== forms.length - 2, isEmpty(flowStructure.flowEdges), 'PUBLISH' === bandoStatus, + isEmpty(flowStructure.initialForm), isEmpty(flowStructure.finalForm)); } else { - console.log('disable BTN:', nonEmptyFlowItems.length !== 1, isEmpty(flowEdges), 'PUBLISH' === bandoStatus, - isEmpty(initialForm), isEmpty(finalForm)); + console.log('disable BTN (2 forms):', isEmpty(flowStructure.flowEdges), 'PUBLISH' === bandoStatus, + isEmpty(flowStructure.initialForm), isEmpty(flowStructure.finalForm)); }*/ return forms.length > 2 ? nonEmptyFlowItems.length !== forms.length - 2 || isEmpty(flowStructure.flowEdges) || 'PUBLISH' === bandoStatus || isEmpty(flowStructure.initialForm) || isEmpty(flowStructure.finalForm) - : nonEmptyFlowItems.length !== 1 || isEmpty(flowStructure.flowEdges) || 'PUBLISH' === bandoStatus + : isEmpty(flowStructure.flowEdges) || 'PUBLISH' === bandoStatus || isEmpty(flowStructure.initialForm) || isEmpty(flowStructure.finalForm); }, [flowStructure, forms]); diff --git a/src/pages/BandoFormsEdit/components/BuilderElement/index.js b/src/pages/BandoFormsEdit/components/BuilderElement/index.js index 9f5e0d0..71c0324 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElement/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElement/index.js @@ -124,7 +124,7 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => {
- {name === 'numberinput' + {['numberinput', 'criteria_table'].includes(name) ? : null} {name === 'numberinput' ? : null} diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js index 8a5d0c8..cb50706 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSetting/index.js @@ -2,19 +2,23 @@ import React from 'react'; import { __ } from '@wordpress/i18n'; import { is } from 'ramda'; +// tools +import renderHtmlContent from '../../../../../../helpers/renderHtmlContent'; + // components import ElementSettingRepeater from '../ElementSettingRepeater'; import { InputText } from 'primereact/inputtext'; import { MultiSelect } from 'primereact/multiselect'; import { Editor } from 'primereact/editor'; - -import { mimeTypes } from '../../../../../../configData'; import ElementSettingTableColumns from '../ElementSettingTableColumns'; import { InputSwitch } from 'primereact/inputswitch'; import ElementSettingChips from '../ElementSettingChips'; +import ElementSettingCriteriaTableColumns from '../ElementSettingCriteriaTableColumns'; + +import { mimeTypes } from '../../../../../../configData'; + const ElementSetting = ({ setting, changeFn, updateDataFn, bandoStatus }) => { - const settingLabels = { label: __('Label', 'gepafin'), placeholder: __('Segnaposto', 'gepafin'), @@ -25,10 +29,15 @@ const ElementSetting = ({ setting, changeFn, updateDataFn, bandoStatus }) => { mime: __('Tipo di file', 'gepafin'), text: __('Testo formattato', 'gepafin'), table_columns: '', + criteria_table_columns: '', variable: __('Variable (only letters and "_")', 'gepafin'), formula: __('Auto calculation formula', 'gepafin') } + const settingDescription = { + formula: __('Create formula using previously declared variables. Use these math operators: +, -, *, /. Example of formula: {entrate}+{assicurazione}.', 'gepafin') + } + const renderHeader = () => { return ( @@ -84,6 +93,12 @@ const ElementSetting = ({ setting, changeFn, updateDataFn, bandoStatus }) => { name={setting.name} bandoStatus={bandoStatus} setDataFn={updateDataFn}/> + } else if (setting.name === 'criteria_table_columns') { + return } else if (['isRequestedAmount', 'isDelegation'].includes(setting.name)) { return { return
{getProperField(setting)} + {settingDescription[setting.name] + ?
+

{renderHtmlContent(settingDescription[setting.name])}

+
: null}
} diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingChips/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingChips/index.js index 9b44a7e..846dcc5 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingChips/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingChips/index.js @@ -2,8 +2,9 @@ import React, { useState } from 'react'; // components import { Chips } from 'primereact/chips'; +import { isEmpty } from 'ramda'; -const ElementSettingChips = ({ restrictedValues = [], changeFn, value }) => { +const ElementSettingChips = ({ restrictedValues = [], changeFn, value = [] }) => { const [lastTyped, setLastTyped] = useState([]) const isValidValue = (newVal) => { @@ -12,7 +13,7 @@ const ElementSettingChips = ({ restrictedValues = [], changeFn, value }) => { }; const handleAdd = (e) => { - const newValue = e.value[e.value.length - 1]; + const newValue = isEmpty(e.value) ? '' : e.value[e.value.length - 1]; if (restrictedValues.includes(newValue)) { changeFn([]); diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingCriteriaTableColumns/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingCriteriaTableColumns/index.js new file mode 100644 index 0000000..0053d76 --- /dev/null +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingCriteriaTableColumns/index.js @@ -0,0 +1,326 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { __, sprintf } from '@wordpress/i18n'; +import { wrap } from 'object-path-immutable'; +import { isEmpty, pathOr } from 'ramda'; + +// components +import { InputText } from 'primereact/inputtext'; +import { Button } from 'primereact/button'; +import { InputSwitch } from 'primereact/inputswitch'; + +// tools +import uniqid from '../../../../../../helpers/uniqid'; +import { Dropdown } from 'primereact/dropdown'; +import { Accordion, AccordionTab } from 'primereact/accordion'; + +const ElementSettingCriteriaTableColumns = ({ + value, + name, + setDataFn, + bandoStatus + }) => { + const [stateFieldData, setStateFieldData] = useState([]); + const [rowsData, setRowsData] = useState([]); + + const removeItem = (index) => { + let newData = stateFieldData + .toSpliced(index, 1) + newData = newData.map((o, i) => { + return i === newData.length - 1 + ? {...o, fieldtype: 'numeric', predefined: false, enableFormula: true} + : {...o, fieldtype: 'text', predefined: true, enableFormula: false} + }); + setStateFieldData(newData); + } + + const addNewItem = () => { + setStateFieldData([ + ...stateFieldData.map(o => ({...o, fieldtype: 'text', predefined: true, enableFormula: false})), + { name: uniqid('o'), label: '', fieldtype: 'numeric', predefined: false, enableFormula: true } + ]); + } + + const addNewRow = () => { + const obj = stateFieldData + .filter(o => o.predefined) + .reduce((acc, cur) => { + acc[cur.name] = '' + return acc; + }, {}); + setRowsData([...rowsData, obj]); + } + + const removeRow = (index) => { + const newRowsData = wrap(rowsData).del([index]).value(); + setRowsData(newRowsData); + } + + const onInputChange = (e, index) => { + const { value } = e.target; + const newData = stateFieldData.map((o, i) => { + if (i === index) { + o.label = value; + } + return o; + }) + setStateFieldData(newData); + } + + const onLastRowInputChange = (e, index) => { + const { value } = e.target; + const newData = stateFieldData.map((o, i) => { + if (i === index) { + o.lastRowText = value; + } + return o; + }) + setStateFieldData(newData); + } + + const onTypeChange = (value, index) => { + const newData = stateFieldData.map((o, i) => { + if (i === index) { + o.fieldtype = value; + } + return o; + }) + setStateFieldData(newData); + } + + const onLastRowFormulaChange = (value, index) => { + const newData = stateFieldData.map((o, i) => { + if (i === index) { + o.lastRowFormula = value; + } + return o; + }) + setStateFieldData(newData); + } + + const onSubInputChange = (e, name, index) => { + const { value } = e.target; + const newRowsData = wrap(rowsData).set([index, name], value).value(); + setRowsData(newRowsData); + } + + const setChecked = (value, index) => { + let name = ''; + const newData = stateFieldData.map((o, i) => { + if (i === index) { + o.predefined = value; + name = o.name; + } + return o; + }); + + let newRowsData = []; + + if (value === false) { + newRowsData = rowsData.map(o => wrap(o).set([name], '').value()); + } else { + newRowsData = rowsData.map(o => wrap(o).set([name], '').value()); + } + + setRowsData(newRowsData); + setStateFieldData(newData); + } + + const setColFormulaChecked = (index) => { + const newData = stateFieldData.map((o, i) => { + if (i === index) { + const newVal = o.enableFormula !== true; + o.enableFormula = newVal; + if (newVal) { + o.lastRowFormula = 'sum'; + o.fieldtype = 'numeric'; + delete o.lastRowText; + } else { + delete o.lastRowFormula; + delete o.fieldtype; + o.lastRowText = ''; + } + } + return o; + }); + setStateFieldData(newData); + } + + const handleClearLastRowData = useCallback(() => { + const newData = stateFieldData.map((o) => { + delete o.lastRowFormula; + o.lastRowText = ''; + delete o.enableFormula; + + return o; + }); + + setStateFieldData(newData); + }, [stateFieldData]); + + const properFields = (item, i) => { + return <> +
+ onInputChange(e, i)}/> +
+
+ onTypeChange(e.value, i)} + options={[ + { value: 'text', label: __('Testo', 'gepafin') }, + { value: 'numeric', label: __('Numerico', 'gepafin') } + ]}/> +
+
+ +
+
+ setChecked(e.value, i)}/> +
+
+
+ + } + + const properSubField = (item, i, name) => { + return <> +
+ onSubInputChange(e, name, i)}/> +
+
+
+ + } + + const properFieldsLastRow = useCallback((item, i) => { + return <> +
+ {sprintf(__('Colonna %d'), i + 1)} +
+ {item.enableFormula + ?
+ onLastRowFormulaChange(e.value, i)} + options={[ + { value: 'sum', label: __('Somma automatica', 'gepafin') } + ]}/> +
+ :
+ onLastRowInputChange(e, i)}/> +
} + + }, [stateFieldData]); + + const lastRow =
+
+
+ {__('Definisci ultima righa', 'gepafin')} +
+
+ {stateFieldData.map((o, i) =>
+ {properFieldsLastRow(o, i)} +
)} +
; + + useEffect(() => { + const stateFieldData = pathOr([], ['stateFieldData'], value); + setStateFieldData(stateFieldData); + const rowsData = pathOr([], ['rowsData'], value); + setRowsData(rowsData); + }, []); + + useEffect(() => { + setDataFn(name, { + stateFieldData, + rowsData + }); + }, [stateFieldData, rowsData]); + + return ( + <> +
+ {stateFieldData.length > 0 + ?
+
{__('Colonne', 'gepafin')}
+
{__('Tipo', 'gepafin')}
+
{__('Calcola', 'gepafin')}
+
{__('Predefinito?', 'gepafin')}
+
+
: null} + {stateFieldData.map((o, i) =>
+ {properFields(o, i)} +
)} +
+ {stateFieldData + .filter(o => o.predefined).length > 0 + ?
+ + {stateFieldData + //.filter(o => o.predefined) + .map((o, i) => + o.predefined + ? +
+ {rowsData.map((c, k) => { + return
+ {properSubField(c, k, o.name)} +
+ })} +
+
: null)} +
+
+ : null} + {lastRow} + + ) +} + +export default ElementSettingCriteriaTableColumns; \ No newline at end of file diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns/index.js index 1806e6d..30eb834 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns/index.js @@ -158,7 +158,7 @@ const ElementSettingTableColumns = ({
onTypeChange(e.value, i)} options={[ @@ -168,6 +168,7 @@ const ElementSettingTableColumns = ({
@@ -212,6 +214,7 @@ const ElementSettingTableColumns = ({ {item.enableFormula ?
onLastRowFormulaChange(e.value, i)} options={[ @@ -232,6 +235,7 @@ const ElementSettingTableColumns = ({ {__('Definisci ultima righa', 'gepafin')}
{stateFieldData .filter(o => o.predefined).length > 0 diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js index 0c1eed9..e95efd6 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js @@ -110,22 +110,6 @@ const BuilderElementSettings = ({ closeSettingsFn, bandoStatus }) => { return dynamicDataOptions[type] ?? []; } - /*const searchDynamicTags = (event) => { - const type = activeElementData.name; - const available = dynamicDataOptions[type]; - let filtered; - - if (!event.query.trim().length) { - filtered = [...available]; - } else { - filtered = available.filter((tag) => { - return tag.label.toLowerCase().startsWith(event.query.toLowerCase()); - }); - } - - setFilteredDynamicDataOptions(filtered); - }*/ - useEffect(() => { const chosen = head(elements.filter(o => o.id === activeElement)); const elementItems = storeGet.main.elementItems(); @@ -163,11 +147,11 @@ const BuilderElementSettings = ({ closeSettingsFn, bandoStatus }) => { ? settings .filter(o => !['variable', 'formula'].includes(o.name)) .map((o) => ) + key={o.name} + setting={o} + bandoStatus={bandoStatus} + changeFn={onChange} + updateDataFn={onUpdateOptions}/>) : null} {!isNil(dynamicDataOptions[activeElementData.name]) ?
@@ -250,18 +234,21 @@ const BuilderElementSettings = ({ closeSettingsFn, bandoStatus }) => { placeholder={__('Scegli', 'gepafin')}/>
- - {settings - ? settings - .filter(o => ['variable', 'formula'].includes(o.name)) - .map((o) => ) - : null} - + {settings + && settings + .filter(o => ['variable', 'formula'].includes(o.name)).length > 0 + ? + {settings + ? settings + .filter(o => ['variable', 'formula'].includes(o.name)) + .map((o) => ) + : null} + : null} } - )} + {o.href + ? + {is(String, o.icon) + ? + : o.icon} + {o.label} + + : (o.clickFn ? + + :
+ {o.label} +
)} + )} } diff --git a/src/pages/BandiPreInstructor/components/AllBandiTable/index.js b/src/pages/BandiPreInstructor/components/AllBandiTable/index.js new file mode 100644 index 0000000..a5dbe61 --- /dev/null +++ b/src/pages/BandiPreInstructor/components/AllBandiTable/index.js @@ -0,0 +1,149 @@ +import React, { useState, useEffect} from 'react'; +import { __ } from '@wordpress/i18n'; +import { is, uniq } from 'ramda'; + +// tools +import getBandoSeverity from '../../../../helpers/getBandoSeverity'; +import getBandoLabel from '../../../../helpers/getBandoLabel'; +import getDateFromISOstring from '../../../../helpers/getDateFromISOstring'; + +// api +import BandoService from '../../../../service/bando-service'; + +// components +import { FilterMatchMode, FilterOperator } from 'primereact/api'; +import { DataTable } from 'primereact/datatable'; +import { Column } from 'primereact/column'; +import { Dropdown } from 'primereact/dropdown'; +import { Button } from 'primereact/button'; +import { Calendar } from 'primereact/calendar'; +import { Tag } from 'primereact/tag'; +import ProperBandoLabel from '../../../../components/ProperBandoLabel'; +import { Link } from 'react-router-dom'; +import translationStrings from '../../../../translationStringsForComponents'; + + +const AllBandiTable = () => { + const [items, setItems] = useState(null); + const [filters, setFilters] = useState(null); + const [localAsyncRequest, setLocalAsyncRequest] = useState(false); + const [statuses, setStatuses] = useState([]); + + useEffect(() => { + setLocalAsyncRequest(true); + BandoService.getBandi(getCallback, errGetCallbacks); + }, []); + + const getCallback = (data) => { + if (data.status === 'SUCCESS') { + setItems(getFormattedBandiData(data.data)); + setStatuses(uniq(data.data.map(o => o.status))) + initFilters(); + } + setLocalAsyncRequest(false); + } + + const errGetCallbacks = (data) => { + setLocalAsyncRequest(false); + } + + const getFormattedBandiData = (data) => { + return data.map((d) => { + d.dates = d.dates.map(v => is(String, v) ? new Date(v) : (v ? v : '')); + return d; + }); + }; + + const clearFilter = () => { + initFilters(); + }; + + const initFilters = () => { + setFilters({ + global: { value: null, matchMode: FilterMatchMode.CONTAINS }, + name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, + start_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] }, + end_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] }, + status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, + }); + }; + + const renderHeader = () => { + return ( +
+
+ ); + }; + + /*const nameBodyTemplate = (rowData) => { + return {rowData.name} + }*/ + + const dateStartBodyTemplate = (rowData) => { + return getDateFromISOstring(rowData.dates[0]); + }; + + const dateEndBodyTemplate = (rowData) => { + return getDateFromISOstring(rowData.dates[1]); + }; + + const dateFilterTemplate = (options) => { + return options.filterCallback(e.value, options.index)} dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />; + }; + + const statusBodyTemplate = (rowData) => { + return ; + }; + + const statusFilterTemplate = (options) => { + return options.filterCallback(e.value, options.index)} + itemTemplate={statusItemTemplate} + placeholder={translationStrings.selectOneLabel} + className="p-column-filter" + showClear />; + }; + + const statusItemTemplate = (option) => { + return ; + }; + + const actionsBodyTemplate = (rowData) => { + return + + + + + + + + + + + + + ); + }; + + const header = renderHeader(); + + const updateEvaluationValue = (value, path, maxValue) => { + let finalValue = value; + + if (maxValue) { + finalValue = value > maxValue ? maxValue : value; + } + + const newData = wrap(formData).set(path.split('.'), finalValue).value(); + + setFormData(newData); + } + + const doCreate = () => { + storeSet.main.setAsyncRequest(); + + AmendmentsService.createSoccorso(formData, createCallback, errCreateCallback, [ + ['applicationEvaluationId', evaluationId] + ]); + } + + const createCallback = (data) => { + if (data.status === 'SUCCESS') { + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: data.message + }); + } + setTimeout(() => { + navigate(`/mie-domande/${id}/soccorso/${data.data.id}`); + }, 1000) + } + storeSet.main.unsetAsyncRequest(); + } + + const errCreateCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + storeSet.main.unsetAsyncRequest(); + } + + const initCreationProcess = () => { + setIsVisibleConfirmDialog(true); + } + + const headerConfirmDialog = () => { + return {__('Richiesta di conferma', 'gepafin')}; + } + + const hideConfirmDialog = () => { + setIsVisibleConfirmDialog(false); + } + + const footerConfirmDialog = () => { + return
+
+ } + + const doConfirm = () => { + setIsVisibleConfirmDialog(false); + doCreate(); + } + + return ( +
+
+

{__('Richiesta Integrazione Documentale', 'gepafin')}

+
+ +
+ + + +
+
+ +
+ + {!isAsyncRequest && !isEmpty(data) + ?
+
+

+ {__('ID domanda', 'gepafin')} + {data.applicationId} +

+

+ {__('Bando', 'gepafin')} + {data.callName} +

+

+ {__('Referente Aziendale', 'gepafin')} + {data.beneficiaryName} +

+
+ +
+
+
+

{__('Pec/Email', 'gepafin')}

+
+ updateEvaluationValue( + e.htmlValue, + 'note' + )} + style={{ height: 80 * 3, width: '100%' }} + /> +
+ +

{__('Tempo per la Risposta (giorni)', 'gepafin')}

+
+ updateEvaluationValue( + e.value, + 'responseDays', + 9999 + )}/> +
+ +

{__('Notifica', 'gepafin')}

+
+
+ updateEvaluationValue( + e.value, + 'isSendEmail' + )}/> + +
+
+ updateEvaluationValue( + e.value, + 'isSendNotification' + )}/> + +
+
+
+ {formData.formFields + ?
+

{__('Documenti da Integrare', 'gepafin')}

+
+
+ {formData.formFields.map((o, i) =>
+ updateEvaluationValue( + e.checked, + `formFields.${i}.selected` + )} + checked={o.selected}> + +
)} +
+
+
+ : null} +
+
+ +
+ + {__('Attenzione', 'gepafin')} + {__("L'invio della richiesta di integrazione sospenderà il termine di valutazione della domanda.", 'gepafin')} +
+ +
+ {__('Azioni', 'gepafin')} +
+ +
+
+
+
+ + +
+

{__('Soccorso istruttorio autorizzato dal direttore e autorizzazione caricata su portale a seguito del quale parte l\'email?', 'gepafin')}

+
+
+ +
+ : <> + + + + + + + + + } +
+ ) + +} + +export default SoccorsoAddInstructorManager; diff --git a/src/pages/SoccorsoEditInstructorManager/index.js b/src/pages/SoccorsoEditInstructorManager/index.js new file mode 100644 index 0000000..6726001 --- /dev/null +++ b/src/pages/SoccorsoEditInstructorManager/index.js @@ -0,0 +1,587 @@ +import React, { useState, useEffect, useRef, useMemo } from 'react'; +import { __ } from '@wordpress/i18n'; +import { useNavigate, useParams } from 'react-router-dom'; +import { is, isEmpty } from 'ramda'; +import { wrap } from 'object-path-immutable'; +import { klona } from 'klona'; +import { useForm } from 'react-hook-form'; + +// store +import { storeSet, useStore } from '../../store'; + +// api +import AmendmentsService from '../../service/amendments-service'; + +// tools +import set404FromErrorResponse from '../../helpers/set404FromErrorResponse'; +import getBandoLabel from '../../helpers/getBandoLabel'; +import getDateFromISOstring from '../../helpers/getDateFromISOstring'; +import getEmailTemplateForSoccorso from '../../helpers/getStrippedHtmlBodyTags'; + +// components +import { Button } from 'primereact/button'; +import BlockingOverlay from '../../components/BlockingOverlay'; +import { Toast } from 'primereact/toast'; +import { classNames } from 'primereact/utils'; +import { Dialog } from 'primereact/dialog'; +import FormField from '../../components/FormField'; +import { Editor } from 'primereact/editor'; +import { InputNumber } from 'primereact/inputnumber'; +import SoccorsoComunications from '../SoccorsoEditPreInstructor/components/SoccorsoComunications'; + + +const SoccorsoEditInstructorManager = () => { + const isAsyncRequest = useStore().main.isAsyncRequest(); + const { id, amendmentId } = useParams(); + const navigate = useNavigate(); + const [data, setData] = useState({}); + const [isVisibleCloseAmendDialog, setIsVisibleCloseAmendDialog] = useState(false); + const [isVisibleExtendTimeDialog, setIsVisibleExtendTimeDialog] = useState(false); + const [extendedTime, setExtendedTime] = useState(3); + const [isLoadingExtendingTime, setIsLoadingExtendingTime] = useState(false); + const [isLoadingReminding, setIsLoadingReminding] = useState(false); + const [internalNote, setInternalNote] = useState(''); + const toast = useRef(null); + const [formInitialData, setFormInitialData] = useState({}); + const { + control, + handleSubmit, + formState: { errors }, + setValue, + register, + trigger, + getValues + } = useForm({ + defaultValues: useMemo(() => { + return formInitialData; + }, [formInitialData]), mode: 'onChange' + }); + + const goToEvaluationPage = () => { + navigate(`/mie-domande/${id}`); + } + + const getCallback = (data) => { + if (data.status === 'SUCCESS') { + setData(getFormattedData(data.data)); + let formDataInitial = data.data.applicationFormFields.reduce((acc, cur) => { + if (cur.fieldValue) { + acc[cur.fieldId] = cur.fieldValue; + } + return acc; + }, {}); + formDataInitial = { + ...formDataInitial, + amendmentDocuments: data.data.amendmentDocuments + } + setFormInitialData(formDataInitial); + } + storeSet.main.unsetAsyncRequest(); + } + + const errGetCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + storeSet.main.unsetAsyncRequest(); + } + + const getFormattedData = (data) => { + data.startDate = is(String, data.startDate) ? new Date(data.startDate) : (data.startDate ? data.startDate : ''); + data.expirationDate = is(String, data.expirationDate) ? new Date(data.expirationDate) : (data.expirationDate ? data.expirationDate : ''); + return data; + }; + + const renderHeader = () => { + return ( + + + + + + + + + + + + + + ); + }; + + const header = renderHeader(); + + const updateNewAmendmentData = (value, path) => { + const newData = wrap(data).set(path, value).value(); + setData(newData); + } + + const onSubmit = () => { + }; + + const doUpdateAmendment = (doClose = false) => { + trigger(); + let formValues = klona(getValues()); + const newFormValues = Object.keys(formValues) + .filter(v => v !== 'amendmentDocuments') + .reduce((acc, cur) => { + let fieldVal = formValues[cur]; + + fieldVal = isEmpty(fieldVal) ? null : fieldVal; + fieldVal = is(Array, fieldVal) ? fieldVal.map(o => o.id).join(',') : null; + + acc.push({ + 'fieldId': cur, + 'fieldValue': fieldVal + }); + return acc; + }, []); + const newAmendDocs = formValues.amendmentDocuments + ? formValues.amendmentDocuments.map(o => o.id).join(',') + : ''; + + const submitData = { + applicationFormFields: newFormValues, + amendmentDocuments: newAmendDocs, + amendmentNotes: data.amendmentNotes + } + + storeSet.main.setAsyncRequest(); + AmendmentsService.updateSoccorso( + amendmentId, + submitData, + (resp) => updateAmendmentCallback(resp, doClose), + errUpdateAmendmentCallback + ); + } + + const updateAmendmentCallback = (data, doClose = false) => { + if (data.status === 'SUCCESS') { + setData(getFormattedData(data.data)); + + if (doClose) { + const submitData = { + internalNote + } + storeSet.main.setAsyncRequest(); + AmendmentsService.closeSoccorso(amendmentId, submitData, closeAmendmentCallback, errCloseAmendmentCallback); + } else { + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: data.message + }); + } + let formDataInitial = data.data.applicationFormFields.reduce((acc, cur) => { + if (cur.fieldValue) { + acc[cur.fieldId] = cur.fieldValue; + } + return acc; + }, formInitialData); + formDataInitial = { + ...formDataInitial, + amendmentDocuments: data.data.amendmentDocuments + } + setFormInitialData(formDataInitial); + } + } + storeSet.main.unsetAsyncRequest(); + } + + const errUpdateAmendmentCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + storeSet.main.unsetAsyncRequest(); + } + + const openCloseAmendmentDialog = () => { + setIsVisibleCloseAmendDialog(true); + } + + const headerCloseAmendDialog = () => { + return {__('Chiudi Soccorso Istruttorio', 'gepafin')} + } + + const hideCloseAmendDialog = () => { + setIsVisibleCloseAmendDialog(false); + } + + const footerCloseAmendDialog = () => { + return
+
+ } + + const doCloseAmendment = () => { + doUpdateAmendment(true); + } + + const closeAmendmentCallback = (data) => { + if (data.status === 'SUCCESS') { + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: data.message + }); + } + if (data.data.status) { + updateNewAmendmentData(data.data.status, ['status']); + setIsVisibleCloseAmendDialog(false); + } + } + storeSet.main.unsetAsyncRequest(); + } + + const errCloseAmendmentCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + storeSet.main.unsetAsyncRequest(); + } + + const headerExtendRespDialog = () => { + return {__('Estendi scadenza', 'gepafin')} + } + + const hideExtendRespDialog = () => { + setIsVisibleExtendTimeDialog(false); + } + + const footerExtendRespDialog = () => { + return
+
+ } + + const openExtendResponseTimeDialog = () => { + setIsVisibleExtendTimeDialog(true); + setExtendedTime(3); + } + + const doExtendTimeResponse = () => { + setIsLoadingExtendingTime(true); + AmendmentsService.extendSoccorso(amendmentId, extendedTime, extendCallback, errExtendCallback); + } + + const extendCallback = (data) => { + if (data.status === 'SUCCESS') { + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: data.message + }); + } + setIsVisibleExtendTimeDialog(false); + } + setIsLoadingExtendingTime(false); + } + + const errExtendCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + setIsLoadingExtendingTime(false); + } + + const sendReminder = () => { + setIsLoadingReminding(true); + AmendmentsService.sendReminderForSoccorso(amendmentId, reminderCallback, errReminderCallback) + } + + const reminderCallback = (data) => { + if (data.status === 'SUCCESS') { + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: data.message + }); + } + } + setIsLoadingReminding(false); + } + + const errReminderCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + setIsLoadingReminding(false); + } + + useEffect(() => { + if (formInitialData) { + Object.keys(formInitialData).map(k => setValue(k, formInitialData[k])); + trigger(); + } + }, [formInitialData]); + + useEffect(() => { + const parsedSoccorsoId = parseInt(amendmentId); + const soccorsoEntityId = !isNaN(parsedSoccorsoId) ? parsedSoccorsoId : 0; + + AmendmentsService.getSoccorsoById(getCallback, errGetCallback, [['id', soccorsoEntityId]]); + }, [amendmentId]); + + return ( +
+
+

{__('Soccorso Istruttorio - Dettagli', 'gepafin')}

+
+ +
+ + + +
+
+ +
+ +
+
+

+ {__('ID domanda', 'gepafin')} + {data.applicationId} +

+

+ {__('Bando', 'gepafin')} + {data.callName} +

+

+ {__('Referente Aziendale', 'gepafin')} + {data.beneficiaryName} +

+

+ {__('Inizio', 'gepafin')} + {getDateFromISOstring(data.startDate)} +

+

+ {__('Scadenza', 'gepafin')} + {getDateFromISOstring(data.expirationDate)} +

+

+ {__('Stato', 'gepafin')} + {getBandoLabel(data.status)} +

+
+ +
+

{__('Dettagli richiesta', 'gepafin')}

+

{__('Note e spiegazioni', 'gepafin')}

+
{getEmailTemplateForSoccorso(data.emailTemplate, data.note)}
+
+
+

{__('Documenti richiesti', 'gepafin')}

+
    + {data.formFields + ? data.formFields.map((o, i) =>
  1. + {o.label} +
  2. ) : null} +
+
+ +
+

{__('Comunicazioni', 'gepafin')}

+ +
+ + {data.formFields && !isEmpty(data.formFields) + ?
+

{__('Documenti Ricevuti', 'gepafin')}

+ +
+ {data.formFields.map((o, i) => { + return + })} + +
: null} + +
+

{__('Documenti aggiuntivi', 'gepafin')}

+
+

{__('Notes', 'gepafin')}

+
+ + updateNewAmendmentData( + e.htmlValue, + 'amendmentNotes' + )} + style={{ height: 80 * 3, width: '100%' }} + /> +
+ +
+
+ +
+ +
+ {__('Azioni', 'gepafin')} +
+ +
+
+
+
+ +
+ + +
+ + setExtendedTime(e.value)}/> +
+
+ + +
+ +
+ + setInternalNote(e.htmlValue)} + style={{ height: 80 * 3, width: '100%' }} + /> +
+
+
+
+ ) + +} + +export default SoccorsoEditInstructorManager; diff --git a/src/pages/SoccorsoIstruttorioPreInstructor/index.js b/src/pages/SoccorsoIstruttorioPreInstructor/index.js index 6a92b97..4adb445 100644 --- a/src/pages/SoccorsoIstruttorioPreInstructor/index.js +++ b/src/pages/SoccorsoIstruttorioPreInstructor/index.js @@ -34,12 +34,6 @@ const SoccorsoIstruttorioPreInstructor = () => {
-
- -
- -
-

{__('Riepilogo', 'gepafin')}

@@ -88,6 +82,12 @@ const SoccorsoIstruttorioPreInstructor = () => {
+ +
+ +
+ +
) } diff --git a/src/routes.js b/src/routes.js index c8c0302..e72c0c2 100644 --- a/src/routes.js +++ b/src/routes.js @@ -41,6 +41,13 @@ import DomandeInstructorManager from './pages/DomandeInstructorManager'; import DomandaEditInstructorManager from './pages/DomandaEditInstructorManager'; import UserActivity from './pages/UserActivity'; import DomandeArchive from './pages/DomandeArchive'; +import BandiPreInstructor from './pages/BandiPreInstructor'; +import BandoViewPreInstructor from './pages/BandoViewPreInstructor'; +import DomandeArchivePreInstructor from './pages/DomandeArchivePreInstructor'; +import DashboardInstructorManager from './pages/DashboardInstructorManager'; +import DomandeMieInstructorManager from './pages/DomandeMieInstructorManager'; +import SoccorsoAddInstructorManager from './pages/SoccorsoAddInstructorManager'; +import SoccorsoEditInstructorManager from './pages/SoccorsoEditInstructorManager'; const routes = ({ role, chosenCompanyId }) => { @@ -51,19 +58,19 @@ const routes = ({ role, chosenCompanyId }) => { {'ROLE_SUPER_ADMIN' === role ? : null} {'ROLE_BENEFICIARY' === role ? : null} {'ROLE_PRE_INSTRUCTOR' === role ? : null} - {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} }/> {'ROLE_SUPER_ADMIN' === role ? : null} {'ROLE_BENEFICIARY' === role ? : null} - {'ROLE_PRE_INSTRUCTOR' === role ? : null} - {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} }/> {'ROLE_SUPER_ADMIN' === role ? : null} {'ROLE_BENEFICIARY' === role ? : null} - {'ROLE_PRE_INSTRUCTOR' === role ? : null} - {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} }/> {'ROLE_SUPER_ADMIN' === role ? : null} @@ -117,7 +124,7 @@ const routes = ({ role, chosenCompanyId }) => { {'ROLE_SUPER_ADMIN' === role ? : null} {'ROLE_BENEFICIARY' === role ? : null} {'ROLE_PRE_INSTRUCTOR' === role ? : null} - {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} }/> {'ROLE_SUPER_ADMIN' === role ? : null} @@ -128,7 +135,7 @@ const routes = ({ role, chosenCompanyId }) => { {'ROLE_SUPER_ADMIN' === role ? : null} {'ROLE_BENEFICIARY' === role ? : null} - {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} }/> @@ -141,7 +148,7 @@ const routes = ({ role, chosenCompanyId }) => { {'ROLE_SUPER_ADMIN' === role ? : null} {'ROLE_BENEFICIARY' === role ? : null} {'ROLE_PRE_INSTRUCTOR' === role ? : null} - {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} }/> {'ROLE_SUPER_ADMIN' === role ? : null} @@ -155,6 +162,36 @@ const routes = ({ role, chosenCompanyId }) => { {'ROLE_PRE_INSTRUCTOR' === role ? : null} {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} }/> + + {'ROLE_SUPER_ADMIN' === role ? : null} + {'ROLE_BENEFICIARY' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + }/> + + {'ROLE_SUPER_ADMIN' === role ? : null} + {'ROLE_BENEFICIARY' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + }/> + + {'ROLE_SUPER_ADMIN' === role ? : null} + {'ROLE_BENEFICIARY' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + }/> + + {'ROLE_SUPER_ADMIN' === role ? : null} + {'ROLE_BENEFICIARY' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + }/> + + {'ROLE_SUPER_ADMIN' === role ? : null} + {'ROLE_BENEFICIARY' === role ? : null} + {'ROLE_PRE_INSTRUCTOR' === role ? : null} + {'ROLE_INSTRUCTOR_MANAGER' === role ? : null} + }/> {'ROLE_SUPER_ADMIN' === role ? : null} {'ROLE_BENEFICIARY' === role ? : null}