Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
components.form.utils.task-utils.tsx Maven / Gradle / Ivy
import { Crumb } from 'components/breadcrumbs/Crumb';
import {
basedOnEntries, getProcessName, getTaskSimpleName
} from 'components/form/utils/form-utils';
import { FormInfo } from 'contexts/FormInfoContext';
import { T } from 'helpers/translator';
import { Field } from 'types/graphql';
import Types from 'types/types';
import { useTheme } from '@mui/material/styles';
export function setStepIconTabIndices(delay: number = 0) {
const updateIndices = () => {
//selector for checkboxes: 'input:not([type="hidden"]):not([type="checkbox"][name="multiple"]),button[type="submit"]'
document
.querySelectorAll('.step button.MuiButtonBase-root.MuiIconButton-root,.ps__thumb-x')
.forEach( (item, index) => {
item.setAttribute("tabindex", "-1")
});
}
setTimeout(updateIndices, delay)
}
export function getTaskCrumbs(translator: T, formInfo: FormInfo): Crumb[] {
return [
{
key: "default:start",
label: translator.toMenuLabel('start')!,
link: "/gears/processes/start",
},
{
key: formInfo.processDefinition.key,
label: getProcessName(translator, formInfo)!,
},
{
key: formInfo.taskId || (formInfo.processDefinition.key + "-start"),
label: getTaskSimpleName(translator, formInfo)!
}
]
}
export type BreakPointType = "free" | "normal"
function determineBreakpointType(width: number): BreakPointType {
const theme = useTheme()
const points = theme.breakpoints.values
switch (true) {
case points.xs > width: return "normal"
case points.sm > width: return "normal"
case points.md > width + 200: return "free"
case points.lg > width + 200: return "free"
case points.xl > width + 200: return "free"
default: return "free"
}
}
function determineFieldBreakpoint(formInfo: FormInfo, field: Field): BreakPointType {
const type = field.type
if (type == "MULTIPLE")
return "free"
else
return "normal"
}
type StepPlanField = {
field: Field
type: BreakPointType
}
type StepPlanItemGroups = StepPlanField[][]
type StepPlanItem = {
basedOn: boolean
fields: Field[]
header: boolean
submit: boolean
type: BreakPointType
}
export type StepPlan = StepPlanItem[]
/* this function returns a partitioning of fields, identified by a partition type.
The goal is te separate a multiple input from others types of inputs.
[field1, field2, ...] => [{type: ..., [field1, field2]}, {type: ..., [fieldn]}, ...]
*/
export const createStepCardPlan = (formInfo: FormInfo) => {
const combine = (previousField: StepPlanField, currentField: StepPlanField) => previousField.type === currentField.type
const createPlan = (fields: Field[]): StepPlanItemGroups => fields
// identify the type of each field
.map((field: Field): StepPlanField => ({ type: determineFieldBreakpoint(formInfo, field), field }))
// combine adjacent fields of the same type
.reduce(
function(prev: StepPlanItemGroups, curr: StepPlanField) {
if (prev.length && combine(prev[prev.length - 1][0], curr)) {
prev[prev.length - 1].push(curr);
} else {
prev.push([curr]);
}
return prev;
}, []
);
const normalize = (result: StepPlanItemGroups): StepPlan => result
.map(group => { return {
type : group[0].type,
fields: group.map(item => item.field),
header : false,
submit : false,
basedOn : false,
} } )
const addHeader = (result: StepPlan): StepPlan => {
// add header to a partition
if (result.length > 0 && result[0].type === "normal") {
// inject header into first partition if it is small
result[0].header = true
return result
} else {
// add seperate small partition to contain only the header
return [{ type: "normal", fields: [], header: true, basedOn: false, submit: false }, ...result ]
}
}
const addBasedOn = (result: StepPlan): StepPlan => {
// add header to a partition
const basedOn = formInfo.form.values.__basedOn
if (!basedOn)
return result
const basedOnWidth = determineBasedOnWidth(basedOn)
const basedOnBreakpoint = determineBreakpointType(basedOnWidth)
if (result.length && result[0].type === basedOnBreakpoint) {
// inject header into first partition if it is small
result[0].basedOn = true
return result
} else {
// add seperate small partition to contain only the header
return [{ type: basedOnBreakpoint, fields: [], header: false, basedOn: true, submit: false }, ...result ]
}
}
const addSubmit = (result: StepPlan): StepPlan => {
// add header to a partition
if (result.length && result[result.length -1].type === "normal") {
result[result.length -1].submit = true
return result
} else {
return [...result, { type: "normal", fields: [], header: false, basedOn: false, submit: true } ]
}
}
const fields: Field[] = Array.isArray(formInfo?.form?.fields) ? formInfo.form.fields : []
const plan = addSubmit(addHeader(addBasedOn(normalize(createPlan(fields)))))
// verify plan
if (plan.length) {
if (!plan[0].header)
console.error("A step plan does not include the header in the first partition: %o", plan)
if (fields.length && !plan[plan.length -1].submit)
console.error("A step plan does not a submit in the last partition: %o", plan)
}
return plan
}
export const determineBasedOnWidth = (basedOn: any, asRow: boolean = false): number => {
const basedOnColumns = determineBasedOnColumns(basedOn, asRow)
const width = 150
return width * basedOnColumns
}
export const determineBasedOnColumns = (basedOn: any, asRow?: boolean) => {
function computeColumns(basedOn: any, asRow?: boolean): number {
if (basedOn?.__kind === 'entity')
return 1
else if (basedOn?.__kind === 'tuple' || (Types.isObject(basedOn) && basedOnEntries(basedOn).length != 0)) {
const entries = basedOnEntries(basedOn)
if (asRow) {
const entrySizes = entries.map ( ([key, value]) => computeColumns(value))
return entrySizes.reduce((partialSum, a) => partialSum + a, 0)
} else {
const entrySizes = entries.map ( ([key, value]) => 1 + computeColumns(value))
return Math.max(...[...entrySizes,2])
}
} else if (Array.isArray(basedOn)) {
if (Array.isArray(basedOn[0])) {
// list : max the rows, sum the columns
const rowWidths = basedOn
.map(row => row
.map(computeColumns)
.reduce((partialSum: number, a: number): number => partialSum + a, 0)
)
return Math.max(...rowWidths)
} else if (Types.isObject(basedOn[0])) {
return Math.max(...(basedOn.map(row => computeColumns(row, true))))
}
else
return basedOn.map(row => computeColumns(row)).reduce((partialSum, a) => partialSum + a, 0)
}
else if (basedOn?.__kind === 'entity')
return 1
else
return 1
}
return basedOn == null || basedOn == undefined ? 0 : computeColumns(basedOn, asRow)
}