dinocollab-core 2.2.13 → 2.2.15
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/data-surface/index.js +1 -1
- package/dist/form/index.js +1 -1
- package/dist/src/components/image-with-fallback.js +1 -1
- package/dist/src/components/image-with-fallback.js.map +1 -1
- package/dist/src/data-surface/button-switch.js +1 -1
- package/dist/src/data-surface/button-switch.js.map +1 -1
- package/dist/src/data-surface/helpers.js +1 -1
- package/dist/src/data-surface/helpers.js.map +1 -1
- package/dist/src/data-surface/ui.units.js +1 -1
- package/dist/src/data-surface/ui.units.js.map +1 -1
- package/dist/src/filter-bar/components/chip-viewer.js +1 -1
- package/dist/src/filter-bar/components/chip-viewer.js.map +1 -1
- package/dist/src/filter-bar/components/filter-input.mobile.js +1 -1
- package/dist/src/filter-bar/components/filter-input.mobile.js.map +1 -1
- package/dist/src/filter-bar/components/filter-summary.js +1 -1
- package/dist/src/filter-bar/components/filter-summary.js.map +1 -1
- package/dist/src/filter-bar/components/popper-custom.js +1 -1
- package/dist/src/filter-bar/components/popper-custom.js.map +1 -1
- package/dist/src/filter-bar/components/ui.units.js +1 -1
- package/dist/src/filter-bar/components/ui.units.js.map +1 -1
- package/dist/src/filter-bar/convert-to-graphql.js +1 -1
- package/dist/src/filter-bar/convert-to-graphql.js.map +1 -1
- package/dist/src/filter-bar/index.create.js +1 -1
- package/dist/src/filter-bar/index.create.js.map +1 -1
- package/dist/src/filter-bar/index.dino.js +1 -1
- package/dist/src/filter-bar/index.dino.js.map +1 -1
- package/dist/src/filter-bar/menu/create-form-field-datetime.js +2 -0
- package/dist/src/filter-bar/menu/create-form-field-datetime.js.map +1 -0
- package/dist/src/filter-bar/menu/create-form-field-select-multiple.js +1 -1
- package/dist/src/filter-bar/menu/create-form-field-select-multiple.js.map +1 -1
- package/dist/src/filter-bar/menu/create-form-field-select.js +1 -1
- package/dist/src/filter-bar/menu/create-form-field-select.js.map +1 -1
- package/dist/src/filter-bar/menu/create-form-field-string.js +1 -1
- package/dist/src/filter-bar/menu/create-form-field-string.js.map +1 -1
- package/dist/src/filter-bar/menu/create.js +1 -1
- package/dist/src/filter-bar/menu/create.js.map +1 -1
- package/dist/src/filter-bar/types.js.map +1 -1
- package/dist/src/form/create.date-expired.js +1 -1
- package/dist/src/form/create.date-expired.js.map +1 -1
- package/dist/src/form/create.form-base.js +1 -1
- package/dist/src/form/create.form-base.js.map +1 -1
- package/dist/src/form/create.form-grid-layout.js +1 -1
- package/dist/src/form/create.form-grid-layout.js.map +1 -1
- package/dist/src/form/create.form-grid-layout.units.js +1 -1
- package/dist/src/form/create.form-grid-layout.units.js.map +1 -1
- package/dist/src/form/create.select-simple.js +1 -1
- package/dist/src/form/create.select-simple.js.map +1 -1
- package/dist/src/form/create.select-with-api.js +1 -1
- package/dist/src/form/create.select-with-api.js.map +1 -1
- package/dist/src/form/dino-form.js.map +1 -1
- package/dist/src/table/create.table.js +1 -1
- package/dist/src/table/create.table.js.map +1 -1
- package/dist/src/table/helpers.js +1 -1
- package/dist/src/table/helpers.js.map +1 -1
- package/dist/src/table/styled.js +2 -0
- package/dist/src/table/styled.js.map +1 -0
- package/dist/src/table/toolbar-pannel.js +1 -1
- package/dist/src/table/toolbar-pannel.js.map +1 -1
- package/dist/src/utils/helpers.js +1 -1
- package/dist/src/utils/helpers.js.map +1 -1
- package/dist/table/index.js +1 -1
- package/dist/types/components/image-with-fallback.d.ts +7 -2
- package/dist/types/data-surface/button-switch.d.ts +1 -0
- package/dist/types/data-surface/helpers.d.ts +5 -3
- package/dist/types/data-surface/ui.units.d.ts +4 -2
- package/dist/types/data-view/dino.d.ts +1 -1
- package/dist/types/data-view/query-param-url.d.ts +1 -1
- package/dist/types/filter-bar/components/filter-summary.types.d.ts +2 -1
- package/dist/types/filter-bar/components/hint-icon.types.d.ts +1 -1
- package/dist/types/filter-bar/components/popper-custom.d.ts +1 -0
- package/dist/types/filter-bar/components/ui.units.d.ts +8 -1
- package/dist/types/filter-bar/index.d.ts +2 -0
- package/dist/types/filter-bar/index.dino.d.ts +2 -0
- package/dist/types/filter-bar/menu/create-form-field-datetime.d.ts +53 -0
- package/dist/types/filter-bar/menu/create-form-field-select-multiple.d.ts +17 -0
- package/dist/types/filter-bar/menu/create-form-field-select.d.ts +17 -0
- package/dist/types/filter-bar/menu/create-form-field-string.d.ts +16 -0
- package/dist/types/filter-bar/menu/create.d.ts +17 -0
- package/dist/types/filter-bar/menu/types.d.ts +6 -1
- package/dist/types/filter-bar/types.d.ts +3 -0
- package/dist/types/form/create.date-expired.d.ts +10 -5
- package/dist/types/form/create.form-base.d.ts +1 -0
- package/dist/types/form/create.form-grid-layout.d.ts +6 -4
- package/dist/types/form/create.form-grid-layout.units.d.ts +12 -6
- package/dist/types/form/create.select-simple.d.ts +13 -3
- package/dist/types/form/create.select-with-api.d.ts +56 -4
- package/dist/types/form/dino-form.d.ts +4 -3
- package/dist/types/form/index.d.ts +2 -1
- package/dist/types/table/helpers.d.ts +0 -3
- package/dist/types/table/index.d.ts +1 -1
- package/dist/types/table/styled.d.ts +8 -0
- package/dist/types/table/toolbar-pannel.d.ts +5 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-form-field-select-multiple.js","sources":["../../../../src/filter-bar/menu/create-form-field-select-multiple.tsx"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { useMemo, useState } from 'react'\r\nimport { Box, Button, Checkbox, FormControlLabel, FormGroup, formGroupClasses, styled } from '@mui/material'\r\nimport { createChipViewers, TChipViewerGroup } from '../components/chip-viewer'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\n// types\r\nimport type { FC } from 'react'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { IFieldSelectOption } from './create-form-field-select'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\nimport { getErrorMessage } from '../../form'\r\n\r\nexport interface IFormFieldSelectMultipleProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\nexport interface IFormFieldSelectMultipleParam<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** List of options for the select field */\r\n options: IFieldSelectOption[]\r\n}\r\n\r\nfunction createFormFieldSelectMultiple<T>(params?: IFormFieldSelectMultipleParam<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n const { options = [] } = params || {}\r\n\r\n const FormFieldSelectMultiple: FC<IFormFieldSelectMultipleProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const { value = { values: [], logic: 'or' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n // Track checked values as controlled state to avoid the uncontrolled→controlled MUI warning\r\n const initialChecked = useMemo<TFieldValid[]>(() => {\r\n const values = Array.isArray(value.values) ? value.values : [value.values]\r\n return options.filter((opt) => values.includes(opt.value)).map((opt) => opt.value)\r\n }, [])\r\n const [checkedValues, setCheckedValues] = useState<TFieldValid[]>(initialChecked)\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n\r\n const handleCheckboxChange = (optionValue: TFieldValid, checked: boolean) => {\r\n setCheckedValues((prev) => (checked ? [...prev, optionValue] : prev.filter((v) => v !== optionValue)))\r\n }\r\n\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n const obj = { [mergedConfig.field]: checkedValues } as Partial<TFieldModelValid<T>>\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const newValue: TFieldValue = { values: checkedValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n }\r\n }\r\n\r\n const errorResult = getErrorMessage(errorData, mergedConfig.field)\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return { field: mergedConfig.field, items: items.map((v) => ({ value: v })) }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <FormGroup className={errorResult.error ? 'error' : ''}>\r\n {options.map((x, i) => {\r\n const isChecked = checkedValues.includes(x.value as TFieldValid)\r\n return (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n label={x.label ?? x.value}\r\n control={\r\n <Checkbox\r\n name={mergedConfig.field.toString()}\r\n checked={isChecked}\r\n onChange={(e) => handleCheckboxChange(x.value as TFieldValid, e.target.checked)}\r\n />\r\n }\r\n />\r\n )\r\n })}\r\n </FormGroup>\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelectMultiple\r\n}\r\n\r\nexport default createFormFieldSelectMultiple\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n },\r\n [`.${formGroupClasses.root}`]: {}\r\n})\r\n"],"names":["createFormFieldSelectMultiple","params","ChipViewers","createChipViewers","_ref$options","options","props","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","initialChecked","Array","isArray","filter","opt","includes","map","_useState3","_useState4","checkedValues","setCheckedValues","_useState5","_useState6","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","v","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","obj","_defineProperty","validator","run","keys","length","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","FormGroup","error","x","i","_x$label","isChecked","FormControlLabel","control","Checkbox","name","checked","e","optionValue","target","prev","_toConsumableArray","PopperFooter","Button","color","variant","disabled","_props$onRemoveField","onRemoveField","call","Box","flex","type","styled","position","content","display","inset","backgroundColor","zIndex","opacity","transition","visibility","pointerEvents","formGroupClasses","root"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create-form-field-select-multiple.js","sources":["../../../../src/filter-bar/menu/create-form-field-select-multiple.tsx"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { useMemo, useState } from 'react'\r\nimport { Box, Button, Checkbox, FormControlLabel, FormGroup, formGroupClasses, styled } from '@mui/material'\r\nimport { getErrorMessage } from '../../form'\r\nimport { createChipViewers, TChipViewerGroup } from '../components/chip-viewer'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\n// types\r\nimport type { FC } from 'react'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { IFieldSelectOption } from './create-form-field-select'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\n\r\n/** Props for the `FormFieldSelectMultiple` component returned by `createFormFieldSelectMultiple`. Extends the base filter-menu form props. */\r\nexport interface IFormFieldSelectMultipleProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\n/** Parameters passed to `createFormFieldSelectMultiple` to configure the generated component. */\r\nexport interface IFormFieldSelectMultipleParam<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** List of options for the select field */\r\n options: IFieldSelectOption[]\r\n}\r\n\r\n/**\r\n * Factory function that creates a `FormFieldSelectMultiple` filter-menu component.\r\n *\r\n * The generated component renders a checkbox list of options inside a\r\n * popper/menu panel, allowing the user to select **multiple values** at once.\r\n * It supports:\r\n * - Controlled checkbox state to prevent uncontrolled→controlled React warnings\r\n * - OR / AND logic toggle when more than one value is applied\r\n * - Chip viewers showing the currently applied values\r\n * - Built-in validation via an optional `validator` prop\r\n * - A loading overlay that disables interaction while `isLoading` is true\r\n *\r\n * @param params - Static configuration (option list, optional field config override)\r\n * @returns A React FC ready to be used as a multi-select filter-menu field component\r\n */\r\nfunction createFormFieldSelectMultiple<T>(params?: IFormFieldSelectMultipleParam<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n const { options = [] } = params || {}\r\n\r\n const FormFieldSelectMultiple: FC<IFormFieldSelectMultipleProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const { value = { values: [], logic: mergedConfig?.defaultLogic ?? 'or' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n // Track checked values as controlled state to avoid the uncontrolled→controlled MUI warning\r\n const initialChecked = useMemo<TFieldValid[]>(() => {\r\n const values = Array.isArray(value.values) ? value.values : [value.values]\r\n return options.filter((opt) => values.includes(opt.value)).map((opt) => opt.value)\r\n }, [])\r\n const [checkedValues, setCheckedValues] = useState<TFieldValid[]>(initialChecked)\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n\r\n const handleCheckboxChange = (optionValue: TFieldValid, checked: boolean) => {\r\n setCheckedValues((prev) => (checked ? [...prev, optionValue] : prev.filter((v) => v !== optionValue)))\r\n }\r\n\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n const obj = { [mergedConfig.field]: checkedValues } as Partial<TFieldModelValid<T>>\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const newValue: TFieldValue = { values: checkedValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n }\r\n }\r\n\r\n const errorResult = getErrorMessage(errorData, mergedConfig.field)\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return {\r\n field: mergedConfig.field,\r\n items: items.map((v) => {\r\n return { value: v, label: options.find((o) => o.value === v)?.label }\r\n })\r\n }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <FormGroup className={errorResult.error ? 'error' : ''}>\r\n {options.map((x, i) => {\r\n const isChecked = checkedValues.includes(x.value as TFieldValid)\r\n const disabled = filterViewerValue.items.length > 0 && filterViewerValue.items.some((item) => item.value === x.value)\r\n return (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n disabled={disabled}\r\n label={x.label ?? x.value}\r\n control={\r\n <Checkbox\r\n name={mergedConfig.field.toString()}\r\n checked={isChecked}\r\n onChange={(e) => handleCheckboxChange(x.value as TFieldValid, e.target.checked)}\r\n />\r\n }\r\n />\r\n )\r\n })}\r\n </FormGroup>\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelectMultiple\r\n}\r\n\r\nexport default createFormFieldSelectMultiple\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n },\r\n [`.${formGroupClasses.root}`]: {}\r\n})\r\n"],"names":["createFormFieldSelectMultiple","params","ChipViewers","createChipViewers","_ref$options","options","props","_mergedConfig$default","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","initialChecked","Array","isArray","filter","opt","includes","map","_useState3","_useState4","checkedValues","setCheckedValues","_useState5","_useState6","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","v","_options$find","find","o","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","obj","_defineProperty","validator","run","keys","length","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","FormGroup","error","x","i","_x$label","isChecked","disabled","some","item","FormControlLabel","control","Checkbox","name","checked","e","optionValue","target","prev","_toConsumableArray","PopperFooter","Button","color","variant","_props$onRemoveField","onRemoveField","call","Box","flex","type","styled","position","content","display","inset","backgroundColor","zIndex","opacity","transition","visibility","pointerEvents","formGroupClasses","root"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{defineProperty as e,slicedToArray as
|
|
1
|
+
import{defineProperty as e,slicedToArray as l}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useMemo as r,useState as n}from"react";import{styled as a,radioGroupClasses as t,RadioGroup as s,FormControlLabel as u,Typography as c,Radio as v,Button as d,Box as m}from"@mui/material";import{getErrorMessage as f,convertFormDataToJson as p}from"../../form/helpers.js";import{createChipViewers as b}from"../components/chip-viewer.js";import{ButtonBack as g,ChipDark as h,FilterLogicToggle as y}from"../components/ui.units.js";import{PopperContent as x,PopperBody as C,PopperFooter as j}from"../components/popper-custom.js";function z(e){var a=b(),t=e.options;return function(b){var z,A,F=r(function(){return Object.assign({},b.currentConfig,null==e?void 0:e.config)},[null==e?void 0:e.config,b.currentConfig]),L=b.value,S=void 0===L?{values:[],logic:null!==(z=null==F?void 0:F.defaultLogic)&&void 0!==z?z:"or"}:L,M=n(S.logic),R=l(M,2),T=R[0],w=R[1],B=null!==(A=null==F?void 0:F.label)&&void 0!==A?A:F.field.toString(),V=n({}),D=l(V,2),I=D[0],N=D[1],O=function(e){b.onSubmit(F.field,e,F)},P=f(I,F.field),_=r(function(){var e=Array.isArray(S.values)?S.values:[S.values];return{field:F.field,items:e.map(function(e){var l;return{value:e,label:null===(l=t.find(function(l){return l.value===e}))||void 0===l?void 0:l.label}})}},[F.field,S]),E=[];return b.isLoading&&E.push("disabled"),o(k,{className:E.join(" "),noValidate:!0,onSubmit:function(e){var l;e.preventDefault();var o=new FormData(e.currentTarget),i=p(o),r=null===(l=b.validator)||void 0===l?void 0:l.run(i);if(N(r||{}),!r||0===Object.keys(r).length){var n=F.field,a=Array.isArray(i[n])?i[n]:[i[n]];O({values:a,logic:T})}},children:i(x,{title:"Filter by ".concat(B),onClose:b.onClose,slots:{beforeTitle:o(g,{size:"small",onClick:b.onBack}),afterTitle:F.singleValue?o(h,{sx:{ml:1.5},size:"small",label:"Last value only"}):!S.values||S.values.length<2?null:o(y,{sx:{ml:1},value:T,onChange:function(e,l){return function(e){w(e);var l={values:S.values,logic:e};O(l)}(l)}})},children:[i(C,{children:[o(a,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:_,onRemove:b.onRemove}),o(s,{sx:{mx:-1},name:F.field.toString(),className:P.error?"error":"",children:t.map(function(e,l){var i,r=_.items.length>0&&_.items.some(function(l){return l.value===e.value});return o(u,{disabled:r,value:e.value,control:o(v,{size:"small"}),label:o(c,{variant:"body2",children:null!==(i=e.label)&&void 0!==i?i:e.value})},e.value.toString()+l)})}),P.error&&o(c,{variant:"caption",color:"error",sx:{mt:.5},children:P.message})]}),i(j,{children:[o(d,{size:"small",color:"error",variant:"text",disabled:!S.values||0===S.values.length,onClick:function(){var e;null===(e=b.onRemoveField)||void 0===e||e.call(b,F.field)},children:"Clear All"}),o(m,{sx:{flex:1}}),o(d,{size:"small",color:"inherit",variant:"text",onClick:b.onClose,children:"Cancel"}),o(d,{size:"small",type:"submit",color:"primary",variant:"contained",children:"Apply"})]})]})})}}var k=a("form")(e({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.2)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}},".".concat(t.root),{"&.error .MuiRadio-root":{color:"#d32f2f"},".MuiFormControlLabel-root":{margin:0},".MuiFormControlLabel-root:hover":{backgroundColor:"rgba(25, 118, 210, 0.04)"}}));export{z as default};
|
|
2
2
|
//# sourceMappingURL=create-form-field-select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-form-field-select.js","sources":["../../../../src/filter-bar/menu/create-form-field-select.tsx"],"sourcesContent":["import { createRef, FC, useMemo, useState } from 'react'\r\nimport { Box, Button, FormControlLabel, Radio, RadioGroup, radioGroupClasses, styled, Typography } from '@mui/material'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\nimport { convertFormDataToJson, getErrorMessage } from '../../form/helpers'\r\nimport { createChipViewers, TChipViewerGroup } from '../components/chip-viewer'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\n\r\nexport interface IFormFieldSelectProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\nexport interface IFieldSelectOption {\r\n value: TFieldValid\r\n label?: string\r\n}\r\n\r\nexport interface IFormFieldSelectParams<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** List of options for the select field */\r\n options: IFieldSelectOption[]\r\n}\r\n\r\nfunction createFormFieldSelect<T>(params: IFormFieldSelectParams<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n const { options } = params\r\n\r\n const FormFieldSelect: FC<IFormFieldSelectProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const { value = { values: [], logic: 'or' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n const formData = new FormData(event.currentTarget)\r\n const obj = convertFormDataToJson<TFieldModelValid<T>>(formData)\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const { field } = mergedConfig\r\n const newValues = (Array.isArray(obj[field]) ? obj[field] : [obj[field]]) as TFieldValid[]\r\n const newValue: TFieldValue = { values: newValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n }\r\n }\r\n\r\n const errorResult = getErrorMessage(errorData, mergedConfig.field)\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return { field: mergedConfig.field, items: items.map((v) => ({ value: v })) }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <RadioGroup sx={{ mx: -1 }} name={mergedConfig.field.toString()} className={errorResult.error ? 'error' : ''}>\r\n {options.map((x, i) => (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n control={<Radio size='small' />}\r\n label={<Typography variant='body2'>{x.label ?? x.value}</Typography>}\r\n />\r\n ))}\r\n </RadioGroup>\r\n {errorResult.error && (\r\n <Typography variant='caption' color='error' sx={{ mt: 0.5 }}>\r\n {errorResult.message}\r\n </Typography>\r\n )}\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelect\r\n}\r\n\r\nexport default createFormFieldSelect\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n },\r\n [`.${radioGroupClasses.root}`]: {\r\n '&.error .MuiRadio-root': { color: '#d32f2f' },\r\n '.MuiFormControlLabel-root': { margin: 0 },\r\n '.MuiFormControlLabel-root:hover': { backgroundColor: 'rgba(25, 118, 210, 0.04)' }\r\n }\r\n})\r\n"],"names":["createFormFieldSelect","params","ChipViewers","createChipViewers","options","props","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","_useState3","_useState4","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","formData","FormData","currentTarget","obj","convertFormDataToJson","validator","run","keys","length","newValues","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","RadioGroup","mx","name","error","x","i","_x$label","FormControlLabel","control","Radio","Typography","variant","color","mt","message","PopperFooter","Button","disabled","_props$onRemoveField","onRemoveField","call","Box","flex","type","styled","_defineProperty","position","content","display","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents","radioGroupClasses","root","margin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create-form-field-select.js","sources":["../../../../src/filter-bar/menu/create-form-field-select.tsx"],"sourcesContent":["import { FC, useMemo, useState } from 'react'\r\nimport { Box, Button, FormControlLabel, Radio, RadioGroup, radioGroupClasses, styled, Typography } from '@mui/material'\r\nimport { convertFormDataToJson, getErrorMessage } from '../../form/helpers'\r\nimport { createChipViewers, TChipViewerGroup } from '../components/chip-viewer'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\n\r\n/** Props for the `FormFieldSelect` component returned by `createFormFieldSelect`. Extends the base filter-menu form props. */\r\nexport interface IFormFieldSelectProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\n/** A single option item rendered as a radio button inside the select filter menu. */\r\nexport interface IFieldSelectOption {\r\n value: TFieldValid\r\n label?: string\r\n}\r\n\r\n/** Parameters passed to `createFormFieldSelect` to configure the generated component. */\r\nexport interface IFormFieldSelectParams<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** List of options for the select field */\r\n options: IFieldSelectOption[]\r\n}\r\n\r\n/**\r\n * Factory function that creates a `FormFieldSelect` filter-menu component.\r\n *\r\n * The generated component renders a radio-button list of options inside a\r\n * popper/menu panel. It supports:\r\n * - Single or multi-value selection (controlled by `config.singleValue`)\r\n * - OR / AND logic toggle when more than one value is selected\r\n * - Chip viewers showing the currently applied values\r\n * - Built-in validation via an optional `validator` prop\r\n * - A loading overlay that disables interaction while `isLoading` is true\r\n *\r\n * @param params - Static configuration (option list, optional field config override)\r\n * @returns A React FC ready to be used as a filter-menu field component\r\n */\r\nfunction createFormFieldSelect<T>(params: IFormFieldSelectParams<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n const { options } = params\r\n\r\n const FormFieldSelect: FC<IFormFieldSelectProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const { value = { values: [], logic: mergedConfig?.defaultLogic ?? 'or' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n const formData = new FormData(event.currentTarget)\r\n const obj = convertFormDataToJson<TFieldModelValid<T>>(formData)\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const { field } = mergedConfig\r\n const newValues = (Array.isArray(obj[field]) ? obj[field] : [obj[field]]) as TFieldValid[]\r\n const newValue: TFieldValue = { values: newValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n }\r\n }\r\n\r\n const errorResult = getErrorMessage(errorData, mergedConfig.field)\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return {\r\n field: mergedConfig.field,\r\n items: items.map((v) => ({ value: v, label: options.find((o) => o.value === v)?.label }))\r\n }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <RadioGroup sx={{ mx: -1 }} name={mergedConfig.field.toString()} className={errorResult.error ? 'error' : ''}>\r\n {options.map((x, i) => {\r\n const disabled = filterViewerValue.items.length > 0 && filterViewerValue.items.some((item) => item.value === x.value)\r\n return (\r\n <FormControlLabel\r\n disabled={disabled}\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n control={<Radio size='small' />}\r\n label={<Typography variant='body2'>{x.label ?? x.value}</Typography>}\r\n />\r\n )\r\n })}\r\n </RadioGroup>\r\n {errorResult.error && (\r\n <Typography variant='caption' color='error' sx={{ mt: 0.5 }}>\r\n {errorResult.message}\r\n </Typography>\r\n )}\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelect\r\n}\r\n\r\nexport default createFormFieldSelect\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n },\r\n [`.${radioGroupClasses.root}`]: {\r\n '&.error .MuiRadio-root': { color: '#d32f2f' },\r\n '.MuiFormControlLabel-root': { margin: 0 },\r\n '.MuiFormControlLabel-root:hover': { backgroundColor: 'rgba(25, 118, 210, 0.04)' }\r\n }\r\n})\r\n"],"names":["createFormFieldSelect","params","ChipViewers","createChipViewers","options","props","_mergedConfig$default","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","_useState3","_useState4","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","_options$find","find","o","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","formData","FormData","currentTarget","obj","convertFormDataToJson","validator","run","keys","length","newValues","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","RadioGroup","mx","name","error","x","i","_x$label","disabled","some","item","FormControlLabel","control","Radio","Typography","variant","color","mt","message","PopperFooter","Button","_props$onRemoveField","onRemoveField","call","Box","flex","type","styled","_defineProperty","position","content","display","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents","radioGroupClasses","root","margin"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{slicedToArray as e}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as l,jsxs as i}from"react/jsx-runtime";import{useMemo as
|
|
1
|
+
import{slicedToArray as e}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as l,jsxs as i}from"react/jsx-runtime";import{useMemo as o,useState as r,createRef as n}from"react";import{styled as t,TextField as a,Button as s,Box as u}from"@mui/material";import{createChipViewers as c}from"../components/chip-viewer.js";import{getErrorMessage as m,convertFormDataToJson as v}from"../../form/helpers.js";import{ButtonBack as d,ChipDark as f,FilterLogicToggle as p}from"../components/ui.units.js";import{PopperContent as b,PopperBody as g,PopperFooter as h}from"../components/popper-custom.js";function y(t){var y=c();return function(c){var C,j,z=o(function(){return Object.assign({},c.currentConfig,null==t?void 0:t.config)},[null==t?void 0:t.config,c.currentConfig]),A=n(),k=c.value,T=void 0===k?{values:[],logic:null!==(C=null==z?void 0:z.defaultLogic)&&void 0!==C?C:"or"}:k,B=r(T.logic),F=e(B,2),R=F[0],S=F[1],w=null!==(j=null==z?void 0:z.label)&&void 0!==j?j:z.field.toString(),I=r({}),L=e(I,2),V=L[0],D=L[1],E=function(e){c.onSubmit(z.field,e,z)},H=m(V,z.field),M=o(function(){var e=Array.isArray(T.values)?T.values:[T.values];return{field:z.field,items:e.map(function(e){return{value:e}})}},[z.field,T]),O=[];return c.isLoading&&O.push("disabled"),l(x,{className:O.join(" "),noValidate:!0,onSubmit:function(e){var l;e.preventDefault(),e.stopPropagation();var i=new FormData(e.currentTarget),o=v(i),r=null===(l=c.validator)||void 0===l?void 0:l.run(o);if(D(r||{}),!r||0===Object.keys(r).length){var n=z.field,t=Array.isArray(o[n])?o[n]:[o[n]];E({values:t,logic:R}),A.current&&(A.current.blur(),A.current.value="")}},children:i(b,{title:"Filter by ".concat(w),onClose:c.onClose,slots:{beforeTitle:l(d,{size:"small",onClick:c.onBack}),afterTitle:z.singleValue?l(f,{sx:{ml:1.5},size:"small",label:"Last value only"}):!T.values||T.values.length<2?null:l(p,{sx:{ml:1},value:R,onChange:function(e,l){return function(e){S(e);var l={values:T.values,logic:e};E(l)}(l)}})},children:[i(g,{children:[l(y,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:M,onRemove:c.onRemove}),l(a,{inputRef:A,autoFocus:!0,name:z.field.toString(),size:"small",fullWidth:!0,placeholder:"Enter value",error:H.error,helperText:H.message,sx:{".MuiInputBase-root":{minHeight:"42px"}}})]}),i(h,{children:[l(s,{size:"small",color:"error",variant:"text",disabled:!T.values||0===T.values.length,onClick:function(){var e;null===(e=c.onRemoveField)||void 0===e||e.call(c,z.field)},children:"Clear All"}),l(u,{sx:{flex:1}}),l(s,{size:"small",color:"inherit",variant:"text",onClick:c.onClose,children:"Cancel"}),l(s,{size:"small",type:"submit",color:"primary",variant:"contained",children:"Apply"})]})]})})}}var x=t("form")({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.2)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}});export{y as default};
|
|
2
2
|
//# sourceMappingURL=create-form-field-string.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-form-field-string.js","sources":["../../../../src/filter-bar/menu/create-form-field-string.tsx"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { createRef, useMemo, useState } from 'react'\r\nimport { Box, Button, styled, TextField } from '@mui/material'\r\nimport { createChipViewers } from '../components/chip-viewer'\r\nimport { convertFormDataToJson, getErrorMessage } from '../../form/helpers'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\n// types\r\nimport type { FC } from 'react'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { TChipViewerGroup } from '../components/chip-viewer'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\n\r\nexport interface IFormFieldStringProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\nexport interface IFormFieldStringParam<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n}\r\n\r\nfunction createFormFieldString<T>(params?: IFormFieldStringParam<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n\r\n const FormFieldString: FC<IFormFieldStringProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const refInput = createRef<HTMLInputElement>()\r\n const { value = { values: [], logic: 'or' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault() // Prevent default form submission behavior\r\n event.stopPropagation() // Stop the event from bubbling up to parent elements (like Popper) which might cause it to close prematurely\r\n const formData = new FormData(event.currentTarget)\r\n const obj = convertFormDataToJson<TFieldModelValid<T>>(formData)\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const { field } = mergedConfig\r\n const newValues = (Array.isArray(obj[field]) ? obj[field] : [obj[field]]) as TFieldValid[]\r\n const newValue: TFieldValue = { values: newValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n\r\n if (refInput.current) {\r\n refInput.current.blur()\r\n refInput.current.value = ''\r\n }\r\n }\r\n }\r\n\r\n const error = getErrorMessage(errorData, mergedConfig.field)\r\n\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return { field: mergedConfig.field, items: items.map((v) => ({ value: v })) }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <TextField\r\n inputRef={refInput}\r\n autoFocus\r\n name={mergedConfig.field.toString()}\r\n size='small'\r\n fullWidth\r\n placeholder='Enter value'\r\n error={error.error}\r\n helperText={error.message}\r\n sx={{ '.MuiInputBase-root': { minHeight: '42px' } }}\r\n />\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldString\r\n}\r\n\r\nexport default createFormFieldString\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n }\r\n})\r\n"],"names":["createFormFieldString","params","ChipViewers","createChipViewers","props","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","refInput","createRef","_props$value","value","values","logic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","_useState3","_useState4","errorData","setErrorData","handleSubmit","newValue","onSubmit","error","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","stopPropagation","formData","FormData","currentTarget","obj","convertFormDataToJson","validator","run","keys","length","newValues","current","blur","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","TextField","inputRef","autoFocus","name","fullWidth","placeholder","helperText","message","minHeight","PopperFooter","Button","color","variant","disabled","_props$onRemoveField","onRemoveField","call","Box","flex","type","styled","position","content","display","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create-form-field-string.js","sources":["../../../../src/filter-bar/menu/create-form-field-string.tsx"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { createRef, useMemo, useState } from 'react'\r\nimport { Box, Button, styled, TextField } from '@mui/material'\r\nimport { createChipViewers } from '../components/chip-viewer'\r\nimport { convertFormDataToJson, getErrorMessage } from '../../form/helpers'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\n// types\r\nimport type { FC } from 'react'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { TChipViewerGroup } from '../components/chip-viewer'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\n\r\n/** Props for the `FormFieldString` component returned by `createFormFieldString`. Extends the base filter-menu form props. */\r\nexport interface IFormFieldStringProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\n/** Parameters passed to `createFormFieldString` to configure the generated component. */\r\nexport interface IFormFieldStringParam<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n}\r\n\r\n/**\r\n * Factory function that creates a `FormFieldString` filter-menu component.\r\n *\r\n * The generated component renders a free-text input inside a popper/menu panel,\r\n * letting the user type arbitrary string values as filter criteria. It supports:\r\n * - OR / AND logic toggle when more than one value is applied\r\n * - Chip viewers showing the currently applied values\r\n * - Auto-focus and input reset after each successful submission\r\n * - Built-in validation via an optional `validator` prop\r\n * - A loading overlay that disables interaction while `isLoading` is true\r\n *\r\n * @param params - Static configuration (optional field config override)\r\n * @returns A React FC ready to be used as a free-text filter-menu field component\r\n */\r\nfunction createFormFieldString<T>(params?: IFormFieldStringParam<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n\r\n const FormFieldString: FC<IFormFieldStringProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const refInput = createRef<HTMLInputElement>()\r\n const { value = { values: [], logic: mergedConfig?.defaultLogic ?? 'or' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault() // Prevent default form submission behavior\r\n event.stopPropagation() // Stop the event from bubbling up to parent elements (like Popper) which might cause it to close prematurely\r\n const formData = new FormData(event.currentTarget)\r\n const obj = convertFormDataToJson<TFieldModelValid<T>>(formData)\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const { field } = mergedConfig\r\n const newValues = (Array.isArray(obj[field]) ? obj[field] : [obj[field]]) as TFieldValid[]\r\n const newValue: TFieldValue = { values: newValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n\r\n if (refInput.current) {\r\n refInput.current.blur()\r\n refInput.current.value = ''\r\n }\r\n }\r\n }\r\n\r\n const error = getErrorMessage(errorData, mergedConfig.field)\r\n\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return { field: mergedConfig.field, items: items.map((v) => ({ value: v })) }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <TextField\r\n inputRef={refInput}\r\n autoFocus\r\n name={mergedConfig.field.toString()}\r\n size='small'\r\n fullWidth\r\n placeholder='Enter value'\r\n error={error.error}\r\n helperText={error.message}\r\n sx={{ '.MuiInputBase-root': { minHeight: '42px' } }}\r\n />\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldString\r\n}\r\n\r\nexport default createFormFieldString\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n }\r\n})\r\n"],"names":["createFormFieldString","params","ChipViewers","createChipViewers","props","_mergedConfig$default","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","refInput","createRef","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","_useState3","_useState4","errorData","setErrorData","handleSubmit","newValue","onSubmit","error","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","stopPropagation","formData","FormData","currentTarget","obj","convertFormDataToJson","validator","run","keys","length","newValues","current","blur","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","TextField","inputRef","autoFocus","name","fullWidth","placeholder","helperText","message","minHeight","PopperFooter","Button","color","variant","disabled","_props$onRemoveField","onRemoveField","call","Box","flex","type","styled","position","content","display","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{defineProperty as e,objectWithoutProperties as n,objectSpread2 as r,slicedToArray as
|
|
1
|
+
import{defineProperty as e,objectWithoutProperties as n,objectSpread2 as r,slicedToArray as o,asyncToGenerator as t,regenerator as i}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as l,jsxs as a}from"react/jsx-runtime";import{useState as u,useContext as c,useMemo as s,createRef as d}from"react";import{styled as m,Box as f,MenuList as p,Tooltip as v,IconButton as h,Badge as b,MenuItem as g,Typography as y,Button as j}from"@mui/material";import F from"@mui/icons-material/FilterList";import C from"@mui/material/ClickAwayListener";import{KeySpecial as k}from"../types.js";import{useFilterActions as I}from"../hooks.js";import{FilterBarContext as x}from"../index.context.js";import{FilterMenuNoField as S}from"../components/ui.units.js";import{mapSpecialLabel as w,mapSpecialTexts as P}from"../helpers.js";import{SingleRuleValidate as R,FormValidator as q}from"../../form/validator.js";import{PopperCustom as T,PopperContent as A,PopperFooter as B}from"../components/popper-custom.js";import O from"./create-form-field-string.js";var M=["fields","validation","enableQuickSearch"];function D(m){var f=L,p=function(e){var o=e.fields,t=e.validation,i=e.enableQuickSearch,l=void 0===i||i,a=n(e,M),u=k.quickSearch,c=r({},o);if(l){var s=c[u],d=null!=s&&s.label?s.label:w[u],m=Object.assign({},c[u],{field:u,label:d,singleValue:!0});c[u]=m}else delete c[u];var f=Object.keys(c),p=f.reduce(function(e,n){var o=c[n];return o?(e[n]=r(r({},o),{},{field:n}),e):e},{}),v=r({},t);return f.forEach(function(e){var n,r,o,t=v[e],i=null!==(n=null!==(r=null==t?void 0:t.label)&&void 0!==r?r:null===(o=c[e])||void 0===o?void 0:o.label)&&void 0!==n?n:e.toString();t?t.Rules.some(function(e){return e.rule===R.Required})||(t.label=i,t.Rules.push({rule:R.Required})):v[e]={Rules:[{rule:R.Required}],label:i}}),r(r({},a),{},{fields:p,validation:v,enableQuickSearch:l})}(m),D=function(n){return Object.keys(n.fields).reduce(function(r,o){var t,i=o,l=null===(t=n.validation)||void 0===t?void 0:t[i];return l&&(r[i]=new q(e({},i,l))),r},{})}(p),V=function(e){var n=e.fields;return Object.keys(n).reduce(function(e,r){var o,t=r,i=n[t];return i&&(e[t]=null!==(o=i.FormComponent)&&void 0!==o?o:O()),e},{})}(p),z=m.quickSearchHint;return function(e){var n=d(),w=u(null),R=o(w,2),q=R[0],O=R[1],M=Boolean(q),L=c(x),E=I(L),H=u(null),_=o(H,2),G=_[0],W=_[1],J=s(function(){var n=m.popperProps,r=m.rootProps;return Object.assign({},{popperProps:n,rootProps:r},e.slots)},[m,e.slots]),K=function(){O(null),setTimeout(function(){W(null)},300)},U=function(){E.clearAllFilters(),K()},X=function(){var e=t(i().m(function e(n,r,o){return i().w(function(e){for(;;)switch(e.n){case 0:if(r){e.n=1;break}return e.a(2);case 1:null!=o&&o.singleValue?E.replaceFilter(n,r,{logic:r.logic}):E.upsertManyFilter(n,r,{logic:r.logic});case 2:return e.a(2)}},e)}));return function(n,r,o){return e.apply(this,arguments)}}(),Y=s(function(){var e=Object.values(p.fields);return Array.from(e)},[p.fields]),Z=E.getTotalCount(),$="".concat(Z," Filter").concat(1!==Z?"s":"");return l(C,{onClickAway:K,children:a(N,r(r({className:f.root},J.rootProps),{},{children:[l(v,{title:$,arrow:!0,placement:"top",children:l(h,{size:"small",ref:n,onClick:function(){W(null),O(n.current)},children:l(b,{badgeContent:Z,color:"primary",invisible:0===Z,children:l(F,{fontSize:"small"})})})}),l(T,r(r({open:M,anchorEl:q,placement:"bottom",transition:!0,disablePortal:!0},J.popperProps),{},{children:function(){if(0===Y.length)return l(S,{onClose:K});var e=G?p.fields[G]:void 0;if(G&&e){var n,o=V[G];if(!o)return null;var t=r({},e);null!=t&&t.FormComponent&&delete t.FormComponent;var i=null===(n=L.filterState.storeFilter)||void 0===n?void 0:n[G];return l(o,{currentConfig:t,value:i,isLoading:L.isLoading,onRemove:E.removeFilterByFieldValue,validator:D[G],onSubmit:X,onClose:K,onRemoveField:function(e){return E.removeFilter(e)},onBack:function(){return W(null)}})}return a(A,{title:"Filter by",onClose:K,children:[l(Q,{className:f.menu,children:Y.map(function(e){var n,r,o=e.field.toString();if(!o)return null;var t=E.getFieldInfo(e.field),i=null!==(n=null==t?void 0:t.values.join(", "))&&void 0!==n?n:"",u=t?t.values.length:0,c=u>0?" (".concat(u,")"):"",s=null!==(r=e.label)&&void 0!==r?r:o.toString(),d=u>0?"Filter by ".concat(s,": ").concat(i):void 0;if(e.field===k.quickSearch){var m=P.qsTooltip;d="function"==typeof z?z(m):null!=z?z:m}else if(e.tooltip){var p,h="function"==typeof e.tooltip?e.tooltip(null==t?void 0:t.values):e.tooltip;d=(null!==(p=null==t?void 0:t.values.length)&&void 0!==p?p:0)>0?h:void 0}return l(g,{className:f.menuItem,sx:{justifyContent:"space-between"},onClick:function(){return n=e.field,void W(n);var n},children:l(v,{title:d,placement:"right",arrow:!0,children:a("div",{className:f.menuItemInner,children:[l(y,{variant:"body2",children:s}),l(y,{variant:"caption",sx:{ml:1,color:"text.secondary"},children:c})]})})},o)})}),l(B,{children:l(j,{color:"error",disabled:0===Z,onClick:U,children:"Clear All"})})]})}()}))]}))})}}var L={root:"DinoFilterMenu-root",menu:"DinoFilterMenu-menu",menuItem:"DinoFilterMenu-menuItem",menuItemInner:"DinoFilterMenu-menuItemInner"},N=m(f)(e({},"&.".concat(L.root),{display:"inline-flex",justifyContent:"center",alignItems:"center",flex:"0 0 auto"})),Q=m(p)(e(e({},".".concat(L.menuItem),{paddingTop:0,paddingBottom:0}),".".concat(L.menuItemInner),{display:"flex",justifyContent:"space-between",alignItems:"center",width:"100%",gap:"4px",paddingTop:"6px",paddingBottom:"6px"}));export{D as createFilterMenu,L as filterMenuClasses};
|
|
2
2
|
//# sourceMappingURL=create.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sources":["../../../../src/filter-bar/menu/create.tsx"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { createRef, useContext, useMemo, useState } from 'react'\r\nimport { Badge, Box, Button, IconButton, MenuItem, MenuList, styled, Tooltip, Typography } from '@mui/material'\r\nimport FilterListIcon from '@mui/icons-material/FilterList'\r\nimport ClickAwayListener from '@mui/material/ClickAwayListener'\r\nimport { KeySpecial } from '../types'\r\nimport { useFilterActions } from '../hooks'\r\nimport { FilterBarContext } from '../index.context'\r\nimport { mapSpecialLabel, mapSpecialTexts } from '../helpers'\r\nimport { FormValidator, SingleRuleValidate } from '../../form/validator'\r\nimport { PopperContent, PopperCustom, PopperFooter } from '../components/popper-custom'\r\nimport { FilterMenuNoField } from '../components/ui.units'\r\nimport createFormFieldString from './create-form-field-string'\r\n// types\r\nimport type { FC } from 'react'\r\nimport type { IFilterBarContext } from '../index.context'\r\nimport type { TFieldModelValid, TFieldType, TFieldValue } from '../types'\r\nimport type { IConfigValue, IFormValidatorConfig } from '../../form/validator'\r\nimport type { IFilterMenuConfigInternal, TFieldMenuConfigsInternal } from './types'\r\nimport type { IFilterMenuProps, IFilterMenuSlots, TFieldMenuConfigs } from './types'\r\nimport type { IFieldMenuConfig, IFilterMenuConfig, IFilterMenuFormProps } from './types'\r\n\r\nfunction generateValidatorMap<T>(config: IFilterMenuConfig<T>) {\r\n const keys = Object.keys(config.fields) as TFieldType<T>[]\r\n const validateMaps = keys.reduce(\r\n (acc, key) => {\r\n const fieldKey = key as TFieldType<T>\r\n const fieldConfig = config.validation?.[fieldKey]\r\n if (fieldConfig) {\r\n acc[fieldKey] = new FormValidator({ [fieldKey]: fieldConfig } as IFormValidatorConfig<Partial<TFieldModelValid<T>>>)\r\n }\r\n return acc\r\n },\r\n {} as Record<TFieldType<T>, FormValidator<Partial<TFieldModelValid<T>>>>\r\n )\r\n return validateMaps\r\n}\r\n\r\nfunction generateFormInputMap<T>(config: IFilterMenuConfig<T>) {\r\n const { fields } = config\r\n const keys = Object.keys(fields) as TFieldType<T>[]\r\n const formInputMaps = keys.reduce(\r\n (acc, key) => {\r\n const fieldKey = key as TFieldType<T>\r\n const fieldConfig = fields[fieldKey] as IFieldMenuConfig<T>\r\n if (fieldConfig) {\r\n acc[fieldKey] = fieldConfig.FormComponent ?? createFormFieldString()\r\n }\r\n return acc\r\n },\r\n {} as Record<TFieldType<T>, React.ComponentType<IFilterMenuFormProps<T>>>\r\n )\r\n return formInputMaps\r\n}\r\n\r\nfunction generateConfigs<T>(config: IFilterMenuConfig<T>): IFilterMenuConfigInternal<T> {\r\n const { fields, validation, enableQuickSearch = true, ...rest } = config\r\n const qsKey = KeySpecial.quickSearch\r\n\r\n // Merge quick search field if enabled\r\n const mergedFields: TFieldMenuConfigs<T> = { ...fields }\r\n if (enableQuickSearch) {\r\n const item = mergedFields[qsKey]\r\n const label = item?.label ? item.label : mapSpecialLabel[qsKey]\r\n const temp = Object.assign({}, mergedFields[qsKey], { field: qsKey, label, singleValue: true })\r\n mergedFields[qsKey] = temp\r\n } else {\r\n delete mergedFields[qsKey]\r\n }\r\n\r\n const keys = Object.keys(mergedFields) as TFieldType<T>[]\r\n const finalFields = keys.reduce<TFieldMenuConfigsInternal<T>>((acc, key) => {\r\n const fieldConfig = mergedFields[key]\r\n if (!fieldConfig) return acc\r\n acc[key] = { ...fieldConfig, field: key }\r\n return acc\r\n }, {} as TFieldMenuConfigsInternal<T>)\r\n\r\n // Merge validation config with default required rule\r\n const mergedValidation: IFormValidatorConfig<Partial<TFieldModelValid<T>>> = { ...validation }\r\n keys.forEach((key) => {\r\n const item: IConfigValue<Partial<TFieldModelValid<T>>> | undefined = mergedValidation[key]\r\n const label = item?.label ?? mergedFields[key]?.label ?? key.toString()\r\n if (!item) {\r\n mergedValidation[key] = { Rules: [{ rule: SingleRuleValidate.Required }], label }\r\n } else if (!item.Rules.some((r) => r.rule === SingleRuleValidate.Required)) {\r\n item.label = label\r\n item.Rules.push({ rule: SingleRuleValidate.Required })\r\n }\r\n })\r\n\r\n return { ...rest, fields: finalFields, validation: mergedValidation, enableQuickSearch }\r\n}\r\n\r\nexport function createFilterMenu<T>(config: IFilterMenuConfig<T>) {\r\n const classes = filterMenuClasses\r\n const mergedConfigs = generateConfigs(config)\r\n const validateMaps = generateValidatorMap(mergedConfigs)\r\n const formInputMaps = generateFormInputMap(mergedConfigs)\r\n const quickSearchHint = config.quickSearchHint\r\n\r\n // Component\r\n const FilterMenu: FC<IFilterMenuProps<T>> = (props) => {\r\n const refButton = createRef<HTMLButtonElement>()\r\n\r\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)\r\n const isOpen = Boolean(anchorEl)\r\n\r\n const context = useContext(FilterBarContext) as IFilterBarContext<T>\r\n const filterActions = useFilterActions<T>(context)\r\n\r\n const [fieldSelected, setFieldSelected] = useState<TFieldType<T> | null>(null)\r\n\r\n const mergedSlots = useMemo<IFilterMenuSlots>(() => {\r\n const { popperProps, rootProps } = config\r\n return Object.assign({}, { popperProps, rootProps }, props.slots)\r\n }, [config, props.slots])\r\n\r\n const handleClose = () => {\r\n setAnchorEl(null)\r\n setTimeout(() => {\r\n setFieldSelected(null)\r\n }, 300)\r\n }\r\n\r\n const handleOpen = () => {\r\n setFieldSelected(null)\r\n setAnchorEl(refButton.current)\r\n }\r\n\r\n const handleMenuItemClick = (field: TFieldType<T>) => {\r\n setFieldSelected(field)\r\n }\r\n\r\n const handleClearAll = () => {\r\n filterActions.clearAllFilters()\r\n handleClose()\r\n }\r\n\r\n const handleSubmit = async (key: TFieldType<T>, value?: TFieldValue, config?: IFieldMenuConfig<T>) => {\r\n if (!value) return\r\n if (config?.singleValue) {\r\n filterActions.replaceFilter(key, value, { logic: value.logic })\r\n } else {\r\n filterActions.upsertManyFilter(key, value, { logic: value.logic })\r\n }\r\n }\r\n\r\n const data = useMemo(() => {\r\n const keys = Object.values(mergedConfigs.fields)\r\n return Array.from(keys) as IFieldMenuConfig<T>[]\r\n }, [mergedConfigs.fields])\r\n\r\n const renderContent = () => {\r\n if (data.length === 0) {\r\n return <FilterMenuNoField onClose={handleClose} />\r\n }\r\n const currentConfig = fieldSelected ? mergedConfigs.fields[fieldSelected] : undefined\r\n\r\n if (fieldSelected && currentConfig) {\r\n const FormComponent = formInputMaps[fieldSelected] as React.ComponentType<IFilterMenuFormProps<T>>\r\n if (!FormComponent) return null\r\n\r\n const config: IFieldMenuConfig<T> = { ...currentConfig }\r\n // Remove FormComponent from config before passing to form, as it's not needed there and can cause unnecessary re-renders\r\n if (config?.FormComponent) delete config.FormComponent\r\n\r\n const value = context.filterState.storeFilter?.[fieldSelected]\r\n return (\r\n <FormComponent\r\n currentConfig={config}\r\n value={value}\r\n isLoading={context.isLoading}\r\n onRemove={filterActions.removeFilterByFieldValue}\r\n validator={validateMaps[fieldSelected]}\r\n onSubmit={handleSubmit}\r\n onClose={handleClose}\r\n onRemoveField={(f) => filterActions.removeFilter(f)}\r\n onBack={() => setFieldSelected(null)}\r\n />\r\n )\r\n }\r\n\r\n return (\r\n <PopperContent title='Filter by' onClose={handleClose}>\r\n <MenuListCustom className={classes.menu}>\r\n {data.map((item) => {\r\n const key = item.field.toString()\r\n if (!key) return null\r\n const info = filterActions.getFieldInfo(item.field)\r\n const note = info?.values.join(', ') ?? ''\r\n const fieldCount = info ? info.values.length : 0\r\n const suffix = fieldCount > 0 ? ` (${fieldCount})` : ''\r\n const label = item.label ?? key.toString()\r\n let tooltipTitle = fieldCount > 0 ? `Filter by ${label}: ${note}` : undefined\r\n if (item.field === KeySpecial.quickSearch) {\r\n const txt = mapSpecialTexts.qsTooltip\r\n tooltipTitle = typeof quickSearchHint === 'function' ? quickSearchHint(txt) : (quickSearchHint ?? txt)\r\n }\r\n return (\r\n <MenuItem\r\n key={key}\r\n className={classes.menuItem}\r\n sx={{ justifyContent: 'space-between' }}\r\n onClick={() => handleMenuItemClick(item.field)}\r\n >\r\n <Tooltip title={tooltipTitle} placement='right' arrow>\r\n <div className={classes.menuItemInner}>\r\n <Typography variant='body2'>{label}</Typography>\r\n <Typography variant='caption' sx={{ ml: 1, color: 'text.secondary' }}>\r\n {suffix}\r\n </Typography>\r\n </div>\r\n </Tooltip>\r\n </MenuItem>\r\n )\r\n })}\r\n </MenuListCustom>\r\n <PopperFooter>\r\n <Button color='error' disabled={filterCount === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n )\r\n }\r\n\r\n const filterCount = filterActions.getTotalCount()\r\n const iconTitle = `${filterCount} Filter${filterCount !== 1 ? 's' : ''}`\r\n return (\r\n <ClickAwayListener onClickAway={handleClose}>\r\n <FilterInputStyled className={classes.root} {...mergedSlots.rootProps}>\r\n <Tooltip title={iconTitle} arrow placement='top'>\r\n <IconButton size='small' ref={refButton} onClick={handleOpen}>\r\n <Badge badgeContent={filterCount} color='primary' invisible={filterCount === 0}>\r\n <FilterListIcon fontSize='small' />\r\n </Badge>\r\n </IconButton>\r\n </Tooltip>\r\n <PopperCustom open={isOpen} anchorEl={anchorEl} placement='bottom' transition disablePortal {...mergedSlots.popperProps}>\r\n {renderContent()}\r\n </PopperCustom>\r\n </FilterInputStyled>\r\n </ClickAwayListener>\r\n )\r\n }\r\n return FilterMenu\r\n}\r\n\r\n// styles\r\nexport const filterMenuClasses = {\r\n root: 'DinoFilterMenu-root',\r\n input: 'DinoFilterMenu-input',\r\n beforeInput: 'DinoFilterMenu-beforeInput',\r\n menu: 'DinoFilterMenu-menu',\r\n menuItem: 'DinoFilterMenu-menuItem',\r\n menuItemInner: 'DinoFilterMenu-menuItemInner'\r\n}\r\n\r\nconst FilterInputStyled = styled(Box)({\r\n [`&.${filterMenuClasses.root}`]: {\r\n display: 'inline-flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n flex: '0 0 auto'\r\n }\r\n})\r\n\r\nconst MenuListCustom = styled(MenuList)({\r\n [`.${filterMenuClasses.menuItem}`]: {\r\n paddingTop: 0,\r\n paddingBottom: 0\r\n },\r\n [`.${filterMenuClasses.menuItemInner}`]: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n width: '100%',\r\n gap: '4px',\r\n paddingTop: '6px',\r\n paddingBottom: '6px'\r\n }\r\n})\r\n"],"names":["createFilterMenu","config","classes","filterMenuClasses","mergedConfigs","fields","validation","_config$enableQuickSe","enableQuickSearch","rest","_objectWithoutProperties","_excluded","qsKey","KeySpecial","quickSearch","mergedFields","_objectSpread","item","label","mapSpecialLabel","temp","Object","assign","field","singleValue","keys","finalFields","reduce","acc","key","fieldConfig","mergedValidation","forEach","_ref","_item$label","_mergedFields$key","toString","Rules","some","r","rule","SingleRuleValidate","Required","push","generateConfigs","validateMaps","_config$validation","fieldKey","FormValidator","_defineProperty","generateValidatorMap","formInputMaps","_fieldConfig$FormComp","FormComponent","createFormFieldString","generateFormInputMap","quickSearchHint","props","refButton","createRef","_useState","useState","_useState2","_slicedToArray","anchorEl","setAnchorEl","isOpen","Boolean","context","useContext","FilterBarContext","filterActions","useFilterActions","_useState3","_useState4","fieldSelected","setFieldSelected","mergedSlots","useMemo","popperProps","rootProps","slots","handleClose","setTimeout","handleClearAll","clearAllFilters","handleSubmit","_ref2","_asyncToGenerator","_regenerator","m","_callee","value","w","_context","n","a","replaceFilter","logic","upsertManyFilter","_x","_x2","_x3","apply","this","arguments","data","values","Array","from","filterCount","getTotalCount","iconTitle","concat","_jsx","ClickAwayListener","onClickAway","children","_jsxs","FilterInputStyled","className","root","Tooltip","title","arrow","placement","IconButton","size","ref","onClick","current","Badge","badgeContent","color","invisible","FilterListIcon","fontSize","PopperCustom","open","transition","disablePortal","length","FilterMenuNoField","onClose","currentConfig","undefined","_context$filterState$","filterState","storeFilter","isLoading","onRemove","removeFilterByFieldValue","validator","onSubmit","onRemoveField","f","removeFilter","onBack","PopperContent","MenuListCustom","menu","map","_info$values$join","_item$label2","info","getFieldInfo","note","join","fieldCount","suffix","tooltipTitle","txt","mapSpecialTexts","qsTooltip","MenuItem","menuItem","sx","justifyContent","menuItemInner","Typography","variant","ml","PopperFooter","Button","disabled","renderContent","styled","Box","display","alignItems","flex","MenuList","paddingTop","paddingBottom","width","gap"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create.js","sources":["../../../../src/filter-bar/menu/create.tsx"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { createRef, useContext, useMemo, useState } from 'react'\r\nimport { Badge, Box, Button, IconButton, MenuItem, MenuList, styled, Tooltip, Typography } from '@mui/material'\r\nimport FilterListIcon from '@mui/icons-material/FilterList'\r\nimport ClickAwayListener from '@mui/material/ClickAwayListener'\r\nimport { KeySpecial } from '../types'\r\nimport { useFilterActions } from '../hooks'\r\nimport { FilterBarContext } from '../index.context'\r\nimport { FilterMenuNoField } from '../components/ui.units'\r\nimport { mapSpecialLabel, mapSpecialTexts } from '../helpers'\r\nimport { FormValidator, SingleRuleValidate } from '../../form/validator'\r\nimport { PopperContent, PopperCustom, PopperFooter } from '../components/popper-custom'\r\nimport createFormFieldString from './create-form-field-string'\r\n// types\r\nimport type { FC } from 'react'\r\nimport type { IFilterBarContext } from '../index.context'\r\nimport type { TFieldModelValid, TFieldType, TFieldValue } from '../types'\r\nimport type { IConfigValue, IFormValidatorConfig } from '../../form/validator'\r\nimport type { IFilterMenuConfigInternal, TFieldMenuConfigsInternal } from './types'\r\nimport type { IFilterMenuProps, IFilterMenuSlots, TFieldMenuConfigs } from './types'\r\nimport type { IFieldMenuConfig, IFilterMenuConfig, IFilterMenuFormProps } from './types'\r\n\r\n// #region utils\r\n/**\r\n * Builds a map of `FormValidator` instances keyed by field name.\r\n * Each validator is constructed from the validation rules defined in `config.validation`.\r\n * Fields with no validation config are skipped.\r\n *\r\n * @internal\r\n */\r\nfunction generateValidatorMap<T>(config: IFilterMenuConfig<T>) {\r\n const keys = Object.keys(config.fields) as TFieldType<T>[]\r\n const validateMaps = keys.reduce(\r\n (acc, key) => {\r\n const fieldKey = key as TFieldType<T>\r\n const fieldConfig = config.validation?.[fieldKey]\r\n if (fieldConfig) {\r\n acc[fieldKey] = new FormValidator({ [fieldKey]: fieldConfig } as IFormValidatorConfig<Partial<TFieldModelValid<T>>>)\r\n }\r\n return acc\r\n },\r\n {} as Record<TFieldType<T>, FormValidator<Partial<TFieldModelValid<T>>>>\r\n )\r\n return validateMaps\r\n}\r\n\r\n/**\r\n * Builds a map of form input components keyed by field name.\r\n * If a field defines a custom `FormComponent`, that is used; otherwise falls back to\r\n * the default `createFormFieldString()` free-text component.\r\n *\r\n * @internal\r\n */\r\nfunction generateFormInputMap<T>(config: IFilterMenuConfig<T>) {\r\n const { fields } = config\r\n const keys = Object.keys(fields) as TFieldType<T>[]\r\n const formInputMaps = keys.reduce(\r\n (acc, key) => {\r\n const fieldKey = key as TFieldType<T>\r\n const fieldConfig = fields[fieldKey] as IFieldMenuConfig<T>\r\n if (fieldConfig) {\r\n acc[fieldKey] = fieldConfig.FormComponent ?? createFormFieldString()\r\n }\r\n return acc\r\n },\r\n {} as Record<TFieldType<T>, React.ComponentType<IFilterMenuFormProps<T>>>\r\n )\r\n return formInputMaps\r\n}\r\n\r\n/**\r\n * Normalises a raw `IFilterMenuConfig` into the internal format used by the menu:\r\n * - Injects the quick-search pseudo-field when `enableQuickSearch` is `true` (default)\r\n * - Stamps each field entry with its own `field` key\r\n * - Ensures every field has at least a `Required` validation rule\r\n *\r\n * @internal\r\n */\r\nfunction generateConfigs<T>(config: IFilterMenuConfig<T>): IFilterMenuConfigInternal<T> {\r\n const { fields, validation, enableQuickSearch = true, ...rest } = config\r\n const qsKey = KeySpecial.quickSearch\r\n\r\n // Merge quick search field if enabled\r\n const mergedFields: TFieldMenuConfigs<T> = { ...fields }\r\n if (enableQuickSearch) {\r\n const item = mergedFields[qsKey]\r\n const label = item?.label ? item.label : mapSpecialLabel[qsKey]\r\n const temp = Object.assign({}, mergedFields[qsKey], { field: qsKey, label, singleValue: true })\r\n mergedFields[qsKey] = temp\r\n } else {\r\n delete mergedFields[qsKey]\r\n }\r\n\r\n const keys = Object.keys(mergedFields) as TFieldType<T>[]\r\n const finalFields = keys.reduce<TFieldMenuConfigsInternal<T>>((acc, key) => {\r\n const fieldConfig = mergedFields[key]\r\n if (!fieldConfig) return acc\r\n acc[key] = { ...fieldConfig, field: key }\r\n return acc\r\n }, {} as TFieldMenuConfigsInternal<T>)\r\n\r\n // Merge validation config with default required rule\r\n const mergedValidation: IFormValidatorConfig<Partial<TFieldModelValid<T>>> = { ...validation }\r\n keys.forEach((key) => {\r\n const item: IConfigValue<Partial<TFieldModelValid<T>>> | undefined = mergedValidation[key]\r\n const label = item?.label ?? mergedFields[key]?.label ?? key.toString()\r\n if (!item) {\r\n mergedValidation[key] = { Rules: [{ rule: SingleRuleValidate.Required }], label }\r\n } else if (!item.Rules.some((r) => r.rule === SingleRuleValidate.Required)) {\r\n item.label = label\r\n item.Rules.push({ rule: SingleRuleValidate.Required })\r\n }\r\n })\r\n\r\n return { ...rest, fields: finalFields, validation: mergedValidation, enableQuickSearch }\r\n}\r\n// #endregion\r\n\r\n// #region main\r\n/**\r\n * Factory function that creates a `FilterMenu` component from a static field configuration.\r\n *\r\n * The generated component renders a badge icon button that opens a popper panel with:\r\n * - A **field list** view — lists all configured filter fields with applied-value counts\r\n * - A **field form** view — renders the appropriate input component for the selected field\r\n * - A **quick-search** field (opt-out via `enableQuickSearch: false`)\r\n * - OR / AND logic toggle support per field\r\n * - \"Clear All\" action to reset all active filters at once\r\n *\r\n * All state (open/close, selected field) is local; filter values are read/written through\r\n * `FilterBarContext` via `useFilterActions`.\r\n *\r\n * @param config - Static filter-menu configuration (fields, validation, slots, etc.)\r\n * @returns A React FC ready to be dropped anywhere inside a `FilterBarProvider`\r\n */\r\nexport function createFilterMenu<T>(config: IFilterMenuConfig<T>) {\r\n const classes = filterMenuClasses\r\n const mergedConfigs = generateConfigs(config)\r\n const validateMaps = generateValidatorMap(mergedConfigs)\r\n const formInputMaps = generateFormInputMap(mergedConfigs)\r\n const quickSearchHint = config.quickSearchHint\r\n\r\n // Component\r\n const FilterMenu: FC<IFilterMenuProps<T>> = (props) => {\r\n const refButton = createRef<HTMLButtonElement>()\r\n\r\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)\r\n const isOpen = Boolean(anchorEl)\r\n\r\n const context = useContext(FilterBarContext) as IFilterBarContext<T>\r\n const filterActions = useFilterActions<T>(context)\r\n\r\n const [fieldSelected, setFieldSelected] = useState<TFieldType<T> | null>(null)\r\n\r\n const mergedSlots = useMemo<IFilterMenuSlots>(() => {\r\n const { popperProps, rootProps } = config\r\n return Object.assign({}, { popperProps, rootProps }, props.slots)\r\n }, [config, props.slots])\r\n\r\n const handleClose = () => {\r\n setAnchorEl(null)\r\n setTimeout(() => {\r\n setFieldSelected(null)\r\n }, 300)\r\n }\r\n\r\n const handleOpen = () => {\r\n setFieldSelected(null)\r\n setAnchorEl(refButton.current)\r\n }\r\n\r\n const handleMenuItemClick = (field: TFieldType<T>) => {\r\n setFieldSelected(field)\r\n }\r\n\r\n const handleClearAll = () => {\r\n filterActions.clearAllFilters()\r\n handleClose()\r\n }\r\n\r\n const handleSubmit = async (key: TFieldType<T>, value?: TFieldValue, config?: IFieldMenuConfig<T>) => {\r\n if (!value) return\r\n if (config?.singleValue) {\r\n filterActions.replaceFilter(key, value, { logic: value.logic })\r\n } else {\r\n filterActions.upsertManyFilter(key, value, { logic: value.logic })\r\n }\r\n }\r\n\r\n const data = useMemo(() => {\r\n const keys = Object.values(mergedConfigs.fields)\r\n return Array.from(keys) as IFieldMenuConfig<T>[]\r\n }, [mergedConfigs.fields])\r\n\r\n const renderContent = () => {\r\n if (data.length === 0) {\r\n return <FilterMenuNoField onClose={handleClose} />\r\n }\r\n const currentConfig = fieldSelected ? mergedConfigs.fields[fieldSelected] : undefined\r\n\r\n if (fieldSelected && currentConfig) {\r\n const FormComponent = formInputMaps[fieldSelected] as React.ComponentType<IFilterMenuFormProps<T>>\r\n if (!FormComponent) return null\r\n\r\n const config: IFieldMenuConfig<T> = { ...currentConfig }\r\n // Remove FormComponent from config before passing to form, as it's not needed there and can cause unnecessary re-renders\r\n if (config?.FormComponent) delete config.FormComponent\r\n\r\n const value = context.filterState.storeFilter?.[fieldSelected]\r\n return (\r\n <FormComponent\r\n currentConfig={config}\r\n value={value}\r\n isLoading={context.isLoading}\r\n onRemove={filterActions.removeFilterByFieldValue}\r\n validator={validateMaps[fieldSelected]}\r\n onSubmit={handleSubmit}\r\n onClose={handleClose}\r\n onRemoveField={(f) => filterActions.removeFilter(f)}\r\n onBack={() => setFieldSelected(null)}\r\n />\r\n )\r\n }\r\n\r\n return (\r\n <PopperContent title='Filter by' onClose={handleClose}>\r\n <MenuListCustom className={classes.menu}>\r\n {data.map((item) => {\r\n const key = item.field.toString()\r\n if (!key) return null\r\n const info = filterActions.getFieldInfo(item.field)\r\n const note = info?.values.join(', ') ?? ''\r\n const fieldCount = info ? info.values.length : 0\r\n const suffix = fieldCount > 0 ? ` (${fieldCount})` : ''\r\n const label = item.label ?? key.toString()\r\n let tooltipTitle = fieldCount > 0 ? `Filter by ${label}: ${note}` : undefined\r\n if (item.field === KeySpecial.quickSearch) {\r\n const txt = mapSpecialTexts.qsTooltip\r\n tooltipTitle = typeof quickSearchHint === 'function' ? quickSearchHint(txt) : (quickSearchHint ?? txt)\r\n } else if (item.tooltip) {\r\n const tooltip = typeof item.tooltip === 'function' ? item.tooltip(info?.values) : item.tooltip\r\n tooltipTitle = (info?.values.length ?? 0) > 0 ? tooltip : undefined\r\n }\r\n return (\r\n <MenuItem\r\n key={key}\r\n className={classes.menuItem}\r\n sx={{ justifyContent: 'space-between' }}\r\n onClick={() => handleMenuItemClick(item.field)}\r\n >\r\n <Tooltip title={tooltipTitle} placement='right' arrow>\r\n <div className={classes.menuItemInner}>\r\n <Typography variant='body2'>{label}</Typography>\r\n <Typography variant='caption' sx={{ ml: 1, color: 'text.secondary' }}>\r\n {suffix}\r\n </Typography>\r\n </div>\r\n </Tooltip>\r\n </MenuItem>\r\n )\r\n })}\r\n </MenuListCustom>\r\n <PopperFooter>\r\n <Button color='error' disabled={filterCount === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n )\r\n }\r\n\r\n const filterCount = filterActions.getTotalCount()\r\n const iconTitle = `${filterCount} Filter${filterCount !== 1 ? 's' : ''}`\r\n return (\r\n <ClickAwayListener onClickAway={handleClose}>\r\n <FilterInputStyled className={classes.root} {...mergedSlots.rootProps}>\r\n <Tooltip title={iconTitle} arrow placement='top'>\r\n <IconButton size='small' ref={refButton} onClick={handleOpen}>\r\n <Badge badgeContent={filterCount} color='primary' invisible={filterCount === 0}>\r\n <FilterListIcon fontSize='small' />\r\n </Badge>\r\n </IconButton>\r\n </Tooltip>\r\n <PopperCustom open={isOpen} anchorEl={anchorEl} placement='bottom' transition disablePortal {...mergedSlots.popperProps}>\r\n {renderContent()}\r\n </PopperCustom>\r\n </FilterInputStyled>\r\n </ClickAwayListener>\r\n )\r\n }\r\n return FilterMenu\r\n}\r\n// #endregion\r\n\r\n// #region styles\r\n/** CSS class names used by the `FilterMenu` component for external style overrides. */\r\nexport const filterMenuClasses = {\r\n root: 'DinoFilterMenu-root',\r\n input: 'DinoFilterMenu-input',\r\n beforeInput: 'DinoFilterMenu-beforeInput',\r\n menu: 'DinoFilterMenu-menu',\r\n menuItem: 'DinoFilterMenu-menuItem',\r\n menuItemInner: 'DinoFilterMenu-menuItemInner'\r\n}\r\n\r\nconst FilterInputStyled = styled(Box)({\r\n [`&.${filterMenuClasses.root}`]: {\r\n display: 'inline-flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n flex: '0 0 auto'\r\n }\r\n})\r\n\r\nconst MenuListCustom = styled(MenuList)({\r\n [`.${filterMenuClasses.menuItem}`]: { paddingTop: 0, paddingBottom: 0 },\r\n [`.${filterMenuClasses.menuItemInner}`]: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n width: '100%',\r\n gap: '4px',\r\n paddingTop: '6px',\r\n paddingBottom: '6px'\r\n }\r\n})\r\n// #endregion\r\n"],"names":["createFilterMenu","config","classes","filterMenuClasses","mergedConfigs","fields","validation","_config$enableQuickSe","enableQuickSearch","rest","_objectWithoutProperties","_excluded","qsKey","KeySpecial","quickSearch","mergedFields","_objectSpread","item","label","mapSpecialLabel","temp","Object","assign","field","singleValue","keys","finalFields","reduce","acc","key","fieldConfig","mergedValidation","forEach","_ref","_item$label","_mergedFields$key","toString","Rules","some","r","rule","SingleRuleValidate","Required","push","generateConfigs","validateMaps","_config$validation","fieldKey","FormValidator","_defineProperty","generateValidatorMap","formInputMaps","_fieldConfig$FormComp","FormComponent","createFormFieldString","generateFormInputMap","quickSearchHint","props","refButton","createRef","_useState","useState","_useState2","_slicedToArray","anchorEl","setAnchorEl","isOpen","Boolean","context","useContext","FilterBarContext","filterActions","useFilterActions","_useState3","_useState4","fieldSelected","setFieldSelected","mergedSlots","useMemo","popperProps","rootProps","slots","handleClose","setTimeout","handleClearAll","clearAllFilters","handleSubmit","_ref2","_asyncToGenerator","_regenerator","m","_callee","value","w","_context","n","a","replaceFilter","logic","upsertManyFilter","_x","_x2","_x3","apply","this","arguments","data","values","Array","from","filterCount","getTotalCount","iconTitle","concat","_jsx","ClickAwayListener","onClickAway","children","_jsxs","FilterInputStyled","className","root","Tooltip","title","arrow","placement","IconButton","size","ref","onClick","current","Badge","badgeContent","color","invisible","FilterListIcon","fontSize","PopperCustom","open","transition","disablePortal","length","FilterMenuNoField","onClose","currentConfig","undefined","_context$filterState$","filterState","storeFilter","isLoading","onRemove","removeFilterByFieldValue","validator","onSubmit","onRemoveField","f","removeFilter","onBack","PopperContent","MenuListCustom","menu","map","_info$values$join","_item$label2","info","getFieldInfo","note","join","fieldCount","suffix","tooltipTitle","txt","mapSpecialTexts","qsTooltip","tooltip","_info$values$length","MenuItem","menuItem","sx","justifyContent","menuItemInner","Typography","variant","ml","PopperFooter","Button","disabled","renderContent","styled","Box","display","alignItems","flex","MenuList","paddingTop","paddingBottom","width","gap"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/filter-bar/types.ts"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n/**\r\n * @en\r\n * - Allowed primitive values for filter fields.\r\n * - Runtime types: string, number, boolean.\r\n * - Use ISO date strings or a discriminated union if date/serialization handling is needed.\r\n * @vi\r\n * - Gia tri nguyen thuy hop le cho cac field filter.\r\n * - Kieu runtime: string, number, boolean.\r\n * - Neu can xu ly Date qua mang/serialize thi dung chuoi ISO hoac discriminated union.\r\n */\r\nexport type TFieldValid = string | number | boolean\r\n/**\r\n * @en\r\n * - Special UI-only filter keys (e.g. quickSearch).\r\n * - Kept as const so `TypeScript` preserves literal types.\r\n * @vi\r\n * - Khoa filter dac biet cho UI (vi dụ: quickSearch).\r\n * - Giu const de `TypeScript` giu literal types.\r\n */\r\nexport const KeySpecial = {\r\n quickSearch: 'quickSearch',\r\n sortShuffle: 'sortShuffle'\r\n} as const\r\nexport type KeySpecial = keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Union of model field keys and special filter keys used by the filter system.\r\n * - Purpose: allow filters to reference either a model property or a special UI key.\r\n * @vi\r\n * - Tap hop cac khoa cua model va cac khoa filter dac biet cho he thong filter.\r\n * - Muc dich: cho phep filter tham chieu truong model hoac key UI dac biet.\r\n */\r\nexport type TFieldType<T> = keyof T | keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Merge external model with special filter keys so filters can reference both.\r\n * - Purpose: extend a model type with UI special keys (e.g. quickSearch) for safe typing.\r\n * @vi\r\n * - Gop model ngoai voi cac key filter dac biet de filter co the tham chieu ca hai.\r\n * - Muc dich: mo rong kieu model de chua cac key UI (vd quickSearch) de type an toan.\r\n */\r\nexport type TFieldModelValid<T> = T & Record<keyof typeof KeySpecial, any>\r\n\r\n/**\r\n * @en Sorting direction for fields.\r\n * @vi Huong sap xep cho cac truong.\r\n */\r\nexport type TDirection = 'asc' | 'desc'\r\n/**\r\n * @en Interface for defining sorting behavior on a field.\r\n * @vi Giao dien de dinh nghia cach sap xep tren mot truong.\r\n */\r\nexport type TFieldSort<T> = {\r\n field: TFieldType<T>\r\n /** Sorting direction. Optional. Default is 'desc'. */\r\n direction?: TDirection\r\n}\r\n/**\r\n * @en Definition of core types for the filter bar system, including filter values, field types, and overall filter state structure.\r\n * @vi Dinh nghia cac kieu co ban cho he thong filter bar, bao gom gia tri filter, kieu field va cau truc tong the cua filter state.\r\n */\r\nexport type TLogic = 'and' | 'or'\r\n/**\r\n * @en\r\n * - Structure for storing filter values and their logical relationship (AND/OR) for each field.\r\n * @vi\r\n * - Cau truc de luu tru cac gia tri filter va moi quan he logic (AND/OR) cho moi field.\r\n */\r\nexport type TFieldValue = {\r\n /** Logical operator for combining values within this field. Default is 'and'. */\r\n logic?: TLogic\r\n values: TFieldValid[]\r\n}\r\n/**\r\n * @en\r\n * - Type for storing active filters in the filter state, mapping field keys to their filter values.\r\n * @vi\r\n * - Kieu de luu tru cac filter dang hoat dong trong filter state, map cac khoa field voi gia tri filter cua chung.\r\n */\r\nexport type TFieldStore<T> = Partial<Record<TFieldType<T>, TFieldValue>>\r\n/**\r\n * @en\r\n * - Overall filter state structure, including the logical operator for combining filters and optional storage for active filters and sorting.\r\n * @vi\r\n * - Cau truc tong the cho filter state, bao gom toan tu logic de ket hop cac filter va luu tru tuy chon cho cac filter dang hoat dong va sap xep.\r\n */\r\nexport type TFilterState<T> = {\r\n /** Logical operator for combining filters. Default is 'and'. */\r\n filterLogic?: TLogic\r\n storeFilter?: TFieldStore<T>\r\n storeSort?: TFieldSort<T>\r\n}\r\n"],"names":["KeySpecial","quickSearch","sortShuffle"],"mappings":"AAqBO,IAAMA,EAAa,CACxBC,YAAa,cACbC,YAAa"}
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../src/filter-bar/types.ts"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n/**\r\n * @en\r\n * - Allowed primitive values for filter fields.\r\n * - Runtime types: string, number, boolean.\r\n * - Use ISO date strings or a discriminated union if date/serialization handling is needed.\r\n * @vi\r\n * - Gia tri nguyen thuy hop le cho cac field filter.\r\n * - Kieu runtime: string, number, boolean.\r\n * - Neu can xu ly Date qua mang/serialize thi dung chuoi ISO hoac discriminated union.\r\n */\r\nexport type TFieldValid = string | number | boolean\r\n/**\r\n * @en\r\n * - Special UI-only filter keys (e.g. quickSearch).\r\n * - Kept as const so `TypeScript` preserves literal types.\r\n * @vi\r\n * - Khoa filter dac biet cho UI (vi dụ: quickSearch).\r\n * - Giu const de `TypeScript` giu literal types.\r\n */\r\nexport const KeySpecial = {\r\n quickSearch: 'quickSearch',\r\n sortShuffle: 'sortShuffle'\r\n} as const\r\nexport type KeySpecial = keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Union of model field keys and special filter keys used by the filter system.\r\n * - Purpose: allow filters to reference either a model property or a special UI key.\r\n * @vi\r\n * - Tap hop cac khoa cua model va cac khoa filter dac biet cho he thong filter.\r\n * - Muc dich: cho phep filter tham chieu truong model hoac key UI dac biet.\r\n */\r\nexport type TFieldType<T> = keyof T | keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Merge external model with special filter keys so filters can reference both.\r\n * - Purpose: extend a model type with UI special keys (e.g. quickSearch) for safe typing.\r\n * @vi\r\n * - Gop model ngoai voi cac key filter dac biet de filter co the tham chieu ca hai.\r\n * - Muc dich: mo rong kieu model de chua cac key UI (vd quickSearch) de type an toan.\r\n */\r\nexport type TFieldModelValid<T> = T & Record<keyof typeof KeySpecial, any>\r\n\r\n/**\r\n * @en Sorting direction for fields.\r\n * @vi Huong sap xep cho cac truong.\r\n */\r\nexport type TDirection = 'asc' | 'desc'\r\n/**\r\n * @en Interface for defining sorting behavior on a field.\r\n * @vi Giao dien de dinh nghia cach sap xep tren mot truong.\r\n */\r\nexport type TFieldSort<T> = {\r\n field: TFieldType<T>\r\n /** Sorting direction. Optional. Default is 'desc'. */\r\n direction?: TDirection\r\n}\r\n/**\r\n * @en Definition of core types for the filter bar system, including filter values, field types, and overall filter state structure.\r\n * @vi Dinh nghia cac kieu co ban cho he thong filter bar, bao gom gia tri filter, kieu field va cau truc tong the cua filter state.\r\n */\r\nexport type TLogic = 'and' | 'or'\r\n\r\nexport type TDateLogic = 'before' | 'after' | 'on' | 'range'\r\n/**\r\n * @en\r\n * - Structure for storing filter values and their logical relationship (AND/OR) for each field.\r\n * @vi\r\n * - Cau truc de luu tru cac gia tri filter va moi quan he logic (AND/OR) cho moi field.\r\n */\r\nexport type TFieldValue = {\r\n /** Logical operator for combining values within this field. Default is 'and'. */\r\n logic?: TLogic\r\n /** Logical operator for date-specific filtering. Optional. */\r\n dateLogic?: TDateLogic\r\n values: TFieldValid[]\r\n}\r\n/**\r\n * @en\r\n * - Type for storing active filters in the filter state, mapping field keys to their filter values.\r\n * @vi\r\n * - Kieu de luu tru cac filter dang hoat dong trong filter state, map cac khoa field voi gia tri filter cua chung.\r\n */\r\nexport type TFieldStore<T> = Partial<Record<TFieldType<T>, TFieldValue>>\r\n/**\r\n * @en\r\n * - Overall filter state structure, including the logical operator for combining filters and optional storage for active filters and sorting.\r\n * @vi\r\n * - Cau truc tong the cho filter state, bao gom toan tu logic de ket hop cac filter va luu tru tuy chon cho cac filter dang hoat dong va sap xep.\r\n */\r\nexport type TFilterState<T> = {\r\n /** Logical operator for combining filters. Default is 'and'. */\r\n filterLogic?: TLogic\r\n storeFilter?: TFieldStore<T>\r\n storeSort?: TFieldSort<T>\r\n}\r\n"],"names":["KeySpecial","quickSearch","sortShuffle"],"mappings":"AAqBO,IAAMA,EAAa,CACxBC,YAAa,cACbC,YAAa"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{defineProperty as e,inherits as t,createClass as
|
|
1
|
+
import{defineProperty as e,inherits as t,createClass as r,objectSpread2 as a,classCallCheck as i,callSuper as s}from"../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as n,jsxs as o}from"react/jsx-runtime";import{Component as l}from"react";import{LocalizationProvider as u}from"@mui/x-date-pickers";import{AdapterDayjs as d}from"@mui/x-date-pickers/AdapterDayjs";import{styled as c,Box as p,colors as h,TextField as f,Typography as m,Switch as g}from"@mui/material";import{getErrorMessage as v}from"./helpers.js";import{mergeObjects as C,tryParseIntRequired as y}from"../utils/helpers.js";import"../utils/dayjs-config.js";import"../utils/query-param.js";import D from"dayjs";var b="DateExpired-root",x="DateExpired-control",k="DateExpired-label",w="DateExpired-expired",O="DateExpired-labelSwitch",N="DateExpired-input",j="DateExpired-switch";function E(c){var p=function(){function p(t){var r,l;return i(this,p),l=s(this,p,[t]),e(l,"defaultNumberOfDays",30),e(l,"mapTextFieldProps",function(){var e=l.props,t=e.messageErrors,r=e.name,i=e.onBlur,s=e.slots,u=l.props.disabled||!l.state.switchChecked,d=a({fullWidth:!0,className:N,label:o("span",{className:k,children:["Expiry date",l.state.switchChecked&&n("b",{children:l.getOffsetDate(l.state.numberOfDays)})]}),variant:"outlined",type:"number",disabled:u,value:l.state.switchChecked?l.state.numberOfDays:0,onChange:l.handleChange},null==s?void 0:s.textFieldProps);if(r){d.onBlur=function(){return i&&i(r)};var c,p=v(t,r);if(p.error)d.error=Boolean(p.error),d.helperText=null!==(c=p.message)&&void 0!==c?c:""}return C({},d,l.mergeConfig.textFieldProps)}),e(l,"handleChange",function(e){var t=""!=e.target.value?parseInt(e.target.value):0;l.setState({numberOfDays:t},function(){var e=v(l.props.messageErrors,l.props.name);t>0&&e.error&&l.mergeConfig.handleBlur()})}),e(l,"handleSwitchChange",function(e){l.setState({switchChecked:e},function(){var e=l.props,t=e.name,r=e.onBlur;t&&r&&r(t)})}),e(l,"getRootClasses",function(){var e=[b];return l.state.numberOfDays<1&&e.push(w),e.join(" ")}),e(l,"getNumberOfDays",function(){var e=l.mergeConfig.defaultValue;return"number"===l.mergeConfig.inputType||void 0!==e&&!isNaN(Number(e))?y(e,l.defaultNumberOfDays):l.getDaysUntilDate(e,l.defaultNumberOfDays)}),e(l,"getOffsetDate",function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"MMMM D, YYYY";return D().add(e,"day").format(t)}),e(l,"getDaysUntilDate",function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;try{if(!e)return t;if(!("number"==typeof e?D().add(e,"day"):D(e)).isValid())return t;var r=D(e),a=D(),i=r.diff(a,"day",!0);return Math.round(i)}catch(e){return t}}),l.mergeConfigCached=null!==(r=l.updateMergeConfig(t.slots))&&void 0!==r?r:{},l.state={numberOfDays:l.getNumberOfDays(),switchChecked:l.mergeConfig.switchChecked},l.id=(new Date).getTime().toString(),l}return t(p,l),r(p,[{key:"mergeConfig",get:function(){return this.mergeConfigCached}},{key:"defaultValueInput",get:function(){return this.state.switchChecked?"number"===this.mergeConfig.inputType?this.state.numberOfDays:this.getOffsetDate(this.state.numberOfDays,"YYYY-MM-DDTHH:mm:ss.sssZ"):""}},{key:"componentDidUpdate",value:function(e){e.slots===this.props.slots&&e.data===this.props.data||(this.mergeConfigCached=this.updateMergeConfig(this.props.slots))}},{key:"render",value:function(){var e,t=this,r=this.props.slots;return n(u,{dateAdapter:d,children:o(M,a(a({className:this.getRootClasses()},null==r?void 0:r.rootProps),{},{children:[n("input",{type:"text",hidden:!0,name:null===(e=this.props.name)||void 0===e?void 0:e.toString(),defaultValue:this.defaultValueInput},this.defaultValueInput),n(f,a({},this.mapTextFieldProps())),o("div",{className:x,children:[n(m,a(a({variant:"caption",className:O},{component:"label",htmlFor:this.id}),{},{sx:{color:this.state.switchChecked?"success.main":"#767676"},children:this.state.switchChecked?"Use Expiration Date":"No Expiration"})),n(g,a({id:this.id,size:"small",color:"success",checked:this.state.switchChecked,onChange:function(e,r){return t.handleSwitchChange(r)}},this.mergeConfig.switchProps))]})]}))})}},{key:"updateMergeConfig",value:function(e){var t,r,i,s=C(c,this.props,e),n=this.props,o=n.data,l=n.name,u=n.onBlur,d=n.defaultValue,p=n.switchChecked,h=n.switchCheckedGetter,f=null!==(t=null!=d?d:o&&l?null===(r=o[l])||void 0===r?void 0:r.toString():void 0)&&void 0!==t?t:null==c||null===(i=c.defaultValue)||void 0===i?void 0:i.toString(),m=null!=p?p:null==c?void 0:c.switchChecked,g=!(!o&&void 0===f&&void 0===m)&&(!!f||!!m);return h&&(g=h(f,o)),a(a({},s),{},{switchChecked:g,defaultValue:f,handleBlur:function(){l&&u&&u(l)}})}}])}();return p}var M=c(p)(e(e(e(e(e(e({display:"flex",alignItems:"center",gap:"10px",position:"relative"},".".concat(j),{margin:0,flex:"0 0 auto"}),".".concat(k),{b:{color:h.blue[600],marginLeft:"8px"}}),".".concat(O),{fontWeight:600,cursor:"pointer"}),".".concat(x),{position:"absolute",top:0,right:0,height:"100%",display:"flex",alignItems:"center"}),".".concat(N),{".MuiInputBase-input":{paddingRight:"160px"}}),"&.".concat(w),e({},".".concat(k),{b:{color:h.red[600]}})));export{E as default};
|
|
2
2
|
//# sourceMappingURL=create.date-expired.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.date-expired.js","sources":["../../../src/form/create.date-expired.tsx"],"sourcesContent":["import React, { Component } from 'react'\r\nimport { LocalizationProvider } from '@mui/x-date-pickers'\r\nimport { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'\r\nimport { Switch, Typography, TextField, styled, Box, TextFieldProps, SwitchProps, colors } from '@mui/material'\r\nimport { IFormInputBase } from './types'\r\nimport { getErrorMessage } from './helpers'\r\nimport { dayjsCustom, mergeObjects, tryParseIntRequired } from '../utils'\r\n\r\nconst defaultFormatString = 'MMMM D, YYYY'\r\n\r\nconst dateExpiredClasses = {\r\n root: 'DateExpired-root',\r\n control: 'DateExpired-control',\r\n label: 'DateExpired-label',\r\n expired: 'DateExpired-expired',\r\n labelSwitch: 'DateExpired-labelSwitch',\r\n input: 'DateExpired-input',\r\n switch: 'DateExpired-switch'\r\n}\r\n\r\ninterface ISlots<T> {\r\n /** @default string */\r\n type?: 'number' | 'string'\r\n textFieldProps?: Partial<TextFieldProps>\r\n switchProps?: SwitchProps\r\n switchChecked?: boolean\r\n switchCheckedGetter?: (value: any, model?: Partial<T>) => boolean\r\n}\r\n\r\ninterface MergeConfig<T> extends ISlots<T> {\r\n switchChecked: boolean\r\n defaulValue?: string\r\n handleBlur: () => void\r\n}\r\n\r\ninterface IProps<T> extends IFormInputBase<T> {\r\n slots?: ISlots<T>\r\n}\r\n\r\ninterface IState {\r\n numberOfDays: number\r\n switchChecked: boolean\r\n}\r\n\r\nfunction CreateDateExpired<T>(params?: ISlots<T>): React.ComponentType<IProps<T>> {\r\n class DateExpired extends Component<IProps<T>, IState> {\r\n defaultNumberOfDays: number = 30\r\n private id\r\n private mergeConfigCached: MergeConfig<T>\r\n constructor(props: IProps<T>) {\r\n super(props)\r\n this.mergeConfigCached = this.updateMergeConfig(props.slots) ?? {}\r\n this.state = {\r\n numberOfDays: this.getNumberOfDays(),\r\n switchChecked: this.mergeConfig.switchChecked\r\n }\r\n this.id = new Date().getTime().toString()\r\n }\r\n\r\n get mergeConfig(): MergeConfig<T> {\r\n return this.mergeConfigCached\r\n }\r\n\r\n get defaultValueInput(): string | number {\r\n if (this.mergeConfig.type === 'number') {\r\n return this.state.numberOfDays\r\n } else {\r\n return this.getOffsetDate(this.state.numberOfDays, 'YYYY-MM-DDTHH:mm:ss.sssZ')\r\n }\r\n }\r\n\r\n componentDidUpdate(prevProps: IProps<T>) {\r\n if (prevProps.slots !== this.props.slots || prevProps.data !== this.props.data) {\r\n this.mergeConfigCached = this.updateMergeConfig(this.props.slots)\r\n }\r\n }\r\n\r\n //#region Render\r\n render() {\r\n return (\r\n <LocalizationProvider dateAdapter={AdapterDayjs}>\r\n <Wrap className={this.getRootClasses()}>\r\n <input key={this.defaultValueInput} type='text' hidden name={this.props.name?.toString()} defaultValue={this.defaultValueInput} />\r\n <TextField {...this.mapTextFieldProps()} />\r\n <div className={dateExpiredClasses.control}>\r\n <Typography\r\n variant='caption'\r\n className={dateExpiredClasses.labelSwitch}\r\n {...{ component: 'label', htmlFor: this.id }}\r\n sx={{ color: this.state.switchChecked ? 'success.main' : '#767676' }}\r\n >\r\n {this.state.switchChecked ? 'Use Expiration Date' : 'No Expiration'}\r\n </Typography>\r\n <Switch\r\n id={this.id}\r\n size='small'\r\n color='success'\r\n checked={this.state.switchChecked}\r\n onChange={(_, checked) => this.handleSwitchChange(checked)}\r\n {...this.mergeConfig.switchProps}\r\n />\r\n </div>\r\n </Wrap>\r\n </LocalizationProvider>\r\n )\r\n }\r\n //#endregion\r\n\r\n mapTextFieldProps = (): TextFieldProps => {\r\n const { messageErrors, name, onBlur } = this.props\r\n const disabled = this.props.disabled || !this.state.switchChecked\r\n const obj: TextFieldProps = {\r\n fullWidth: true,\r\n className: dateExpiredClasses.input,\r\n label: (\r\n <span className={dateExpiredClasses.label}>\r\n Expiry date\r\n {this.state.switchChecked && <b>{this.getOffsetDate(this.state.numberOfDays)}</b>}\r\n </span>\r\n ),\r\n variant: 'outlined',\r\n type: 'number',\r\n disabled: disabled,\r\n value: this.state.switchChecked ? this.state.numberOfDays : 0,\r\n onChange: this.handleChange\r\n }\r\n if (!!name) {\r\n obj.onBlur = () => onBlur && onBlur(name)\r\n const temp = getErrorMessage(messageErrors, name)\r\n if (temp.error) {\r\n obj.error = Boolean(temp.error)\r\n obj.helperText = temp.message ?? ''\r\n }\r\n }\r\n return mergeObjects<TextFieldProps>({}, obj, this.mergeConfig.textFieldProps)\r\n }\r\n\r\n updateMergeConfig(currentSlots?: ISlots<T>): MergeConfig<T> {\r\n const { switchChecked, switchCheckedGetter } = currentSlots ?? {}\r\n const obj = mergeObjects(params, currentSlots)\r\n const { data, name, onBlur, defaultValue } = this.props\r\n const dValue = defaultValue ?? (!!data && !!name ? data[name]?.toString() : undefined)\r\n let check = !data ? false : !!dValue || !!switchChecked\r\n if (switchCheckedGetter) check = switchCheckedGetter(dValue, data)\r\n return {\r\n ...obj,\r\n switchChecked: check,\r\n defaulValue: dValue,\r\n handleBlur: () => {\r\n if (!name || !onBlur) return\r\n onBlur(name)\r\n }\r\n }\r\n }\r\n\r\n handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n const numberOfDays: number = e.target.value != '' ? parseInt(e.target.value) : 0\r\n this.setState({ numberOfDays }, () => {\r\n const err = getErrorMessage(this.props.messageErrors, this.props.name)\r\n if (numberOfDays > 0 && err.error) this.mergeConfig.handleBlur()\r\n })\r\n }\r\n\r\n handleSwitchChange = (checked: boolean) => {\r\n this.setState({ switchChecked: checked }, () => {\r\n const { name, onBlur } = this.props\r\n if (!name || !onBlur) return\r\n onBlur(name)\r\n })\r\n }\r\n\r\n getRootClasses = () => {\r\n const classes = [dateExpiredClasses.root]\r\n if (this.state.numberOfDays < 1) classes.push(dateExpiredClasses.expired)\r\n return classes.join(' ')\r\n }\r\n\r\n getNumberOfDays = (): number => {\r\n if (this.mergeConfig.type === 'number') {\r\n return tryParseIntRequired(this.mergeConfig.defaulValue, this.defaultNumberOfDays)\r\n } else {\r\n return this.getDaysUntilDate(this.mergeConfig.defaulValue, this.defaultNumberOfDays)\r\n }\r\n }\r\n\r\n getOffsetDate = (num: number, formatString = defaultFormatString): string => {\r\n return dayjsCustom().add(num, 'day').format(formatString)\r\n }\r\n\r\n getDaysUntilDate = (value?: string, defaultValue = 0): number => {\r\n try {\r\n if (!value) return defaultValue\r\n const target = dayjsCustom(value)\r\n const today = dayjsCustom()\r\n const diff = target.diff(today, 'day', true)\r\n return Math.round(diff)\r\n } catch {\r\n return defaultValue\r\n }\r\n }\r\n }\r\n return DateExpired\r\n}\r\nexport default CreateDateExpired\r\n\r\nconst Wrap = styled(Box)({\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '10px',\r\n position: 'relative',\r\n [`.${dateExpiredClasses.switch}`]: {\r\n margin: 0,\r\n flex: '0 0 auto'\r\n },\r\n [`.${dateExpiredClasses.label}`]: {\r\n b: {\r\n color: colors.blue[600],\r\n marginLeft: '8px'\r\n }\r\n },\r\n [`.${dateExpiredClasses.labelSwitch}`]: {\r\n fontWeight: 600,\r\n cursor: 'pointer'\r\n },\r\n [`.${dateExpiredClasses.control}`]: {\r\n position: 'absolute',\r\n top: 0,\r\n right: 0,\r\n height: '100%',\r\n display: 'flex',\r\n alignItems: 'center'\r\n },\r\n [`.${dateExpiredClasses.input}`]: {\r\n '.MuiInputBase-input': {\r\n paddingRight: '160px'\r\n }\r\n },\r\n [`&.${dateExpiredClasses.expired}`]: {\r\n [`.${dateExpiredClasses.label}`]: {\r\n b: {\r\n color: colors.red[600]\r\n }\r\n }\r\n }\r\n})\r\n"],"names":["dateExpiredClasses","CreateDateExpired","params","DateExpired","props","_this$updateMergeConf","_this","_classCallCheck","_callSuper","_defineProperty","_this$props","messageErrors","name","onBlur","disabled","state","switchChecked","obj","fullWidth","className","label","_jsxs","children","_jsx","getOffsetDate","numberOfDays","variant","type","value","onChange","handleChange","_temp$message","temp","getErrorMessage","error","Boolean","helperText","message","mergeObjects","mergeConfig","textFieldProps","e","target","parseInt","setState","err","handleBlur","checked","_this$props2","classes","push","join","tryParseIntRequired","defaulValue","defaultNumberOfDays","getDaysUntilDate","num","formatString","arguments","length","undefined","dayjsCustom","add","format","defaultValue","today","diff","Math","round","_unused","mergeConfigCached","updateMergeConfig","slots","getNumberOfDays","id","Date","getTime","toString","_inherits","Component","_createClass","key","get","this","prevProps","data","_this$props$name","_this2","LocalizationProvider","dateAdapter","AdapterDayjs","Wrap","getRootClasses","hidden","defaultValueInput","TextField","_objectSpread","mapTextFieldProps","Typography","component","htmlFor","sx","color","Switch","size","_","handleSwitchChange","switchProps","currentSlots","_data$name","_ref","switchCheckedGetter","_this$props3","dValue","check","styled","Box","display","alignItems","gap","position","concat","margin","flex","b","colors","blue","marginLeft","fontWeight","cursor","top","right","height","paddingRight","red"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create.date-expired.js","sources":["../../../src/form/create.date-expired.tsx"],"sourcesContent":["import React, { Component } from 'react'\r\nimport { LocalizationProvider } from '@mui/x-date-pickers'\r\nimport { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'\r\nimport { Switch, Typography, TextField, styled, Box, TextFieldProps, SwitchProps, colors, BoxProps } from '@mui/material'\r\nimport { IFormInputBase } from './types'\r\nimport { getErrorMessage } from './helpers'\r\nimport { dayjsCustom, mergeObjects, tryParseIntRequired } from '../utils'\r\n\r\nconst defaultFormatString = 'MMMM D, YYYY'\r\n\r\nconst dateExpiredClasses = {\r\n root: 'DateExpired-root',\r\n control: 'DateExpired-control',\r\n label: 'DateExpired-label',\r\n expired: 'DateExpired-expired',\r\n labelSwitch: 'DateExpired-labelSwitch',\r\n input: 'DateExpired-input',\r\n switch: 'DateExpired-switch'\r\n}\r\n\r\ninterface ISlots<T> {\r\n rootProps?: BoxProps\r\n switchProps?: SwitchProps\r\n textFieldProps?: Partial<TextFieldProps>\r\n}\r\n\r\ninterface IDateExpiredConfig<T> extends ISlots<T> {\r\n defaultValue?: any\r\n /** @default string */\r\n inputType?: 'number' | 'string'\r\n textFieldProps?: Partial<TextFieldProps>\r\n switchChecked?: boolean\r\n switchCheckedGetter?: (value: any, model?: Partial<T>) => boolean\r\n}\r\n\r\ninterface IMergeConfig<T> extends IDateExpiredConfig<T> {\r\n switchChecked: boolean\r\n handleBlur: () => void\r\n}\r\n\r\ninterface IProps<T> extends IFormInputBase<T>, IDateExpiredConfig<T> {\r\n slots?: ISlots<T>\r\n}\r\n\r\ninterface IState {\r\n numberOfDays: number\r\n switchChecked: boolean\r\n}\r\n\r\nfunction CreateDateExpired<T>(param?: IDateExpiredConfig<T>): React.ComponentType<IProps<T>> {\r\n class DateExpired extends Component<IProps<T>, IState> {\r\n defaultNumberOfDays: number = 30\r\n private id\r\n private mergeConfigCached: IMergeConfig<T>\r\n constructor(props: IProps<T>) {\r\n super(props)\r\n this.mergeConfigCached = this.updateMergeConfig(props.slots) ?? {}\r\n this.state = {\r\n numberOfDays: this.getNumberOfDays(),\r\n switchChecked: this.mergeConfig.switchChecked\r\n }\r\n this.id = new Date().getTime().toString()\r\n }\r\n\r\n get mergeConfig(): IMergeConfig<T> {\r\n return this.mergeConfigCached\r\n }\r\n\r\n get defaultValueInput(): string | number {\r\n if (!this.state.switchChecked) return ''\r\n if (this.mergeConfig.inputType === 'number') {\r\n return this.state.numberOfDays\r\n } else {\r\n return this.getOffsetDate(this.state.numberOfDays, 'YYYY-MM-DDTHH:mm:ss.sssZ')\r\n }\r\n }\r\n\r\n componentDidUpdate(prevProps: IProps<T>) {\r\n if (prevProps.slots !== this.props.slots || prevProps.data !== this.props.data) {\r\n this.mergeConfigCached = this.updateMergeConfig(this.props.slots)\r\n }\r\n }\r\n\r\n //#region Render\r\n render() {\r\n const { slots } = this.props\r\n return (\r\n <LocalizationProvider dateAdapter={AdapterDayjs}>\r\n <Wrap className={this.getRootClasses()} {...slots?.rootProps}>\r\n <input key={this.defaultValueInput} type='text' hidden name={this.props.name?.toString()} defaultValue={this.defaultValueInput} />\r\n <TextField {...this.mapTextFieldProps()} />\r\n <div className={dateExpiredClasses.control}>\r\n <Typography\r\n variant='caption'\r\n className={dateExpiredClasses.labelSwitch}\r\n {...{ component: 'label', htmlFor: this.id }}\r\n sx={{ color: this.state.switchChecked ? 'success.main' : '#767676' }}\r\n >\r\n {this.state.switchChecked ? 'Use Expiration Date' : 'No Expiration'}\r\n </Typography>\r\n <Switch\r\n id={this.id}\r\n size='small'\r\n color='success'\r\n checked={this.state.switchChecked}\r\n onChange={(_, checked) => this.handleSwitchChange(checked)}\r\n {...this.mergeConfig.switchProps}\r\n />\r\n </div>\r\n </Wrap>\r\n </LocalizationProvider>\r\n )\r\n }\r\n //#endregion\r\n\r\n mapTextFieldProps = (): TextFieldProps => {\r\n const { messageErrors, name, onBlur, slots } = this.props\r\n const disabled = this.props.disabled || !this.state.switchChecked\r\n const obj: TextFieldProps = {\r\n fullWidth: true,\r\n className: dateExpiredClasses.input,\r\n label: (\r\n <span className={dateExpiredClasses.label}>\r\n Expiry date\r\n {this.state.switchChecked && <b>{this.getOffsetDate(this.state.numberOfDays)}</b>}\r\n </span>\r\n ),\r\n variant: 'outlined',\r\n type: 'number',\r\n disabled: disabled,\r\n value: this.state.switchChecked ? this.state.numberOfDays : 0,\r\n onChange: this.handleChange,\r\n ...slots?.textFieldProps\r\n }\r\n if (!!name) {\r\n obj.onBlur = () => onBlur && onBlur(name)\r\n const temp = getErrorMessage(messageErrors, name)\r\n if (temp.error) {\r\n obj.error = Boolean(temp.error)\r\n obj.helperText = temp.message ?? ''\r\n }\r\n }\r\n return mergeObjects<TextFieldProps>({}, obj, this.mergeConfig.textFieldProps)\r\n }\r\n\r\n updateMergeConfig(currentSlots?: ISlots<T>): IMergeConfig<T> {\r\n const obj = mergeObjects(param, this.props, currentSlots)\r\n const { data, name, onBlur, defaultValue, switchChecked, switchCheckedGetter } = this.props\r\n const dValue = defaultValue ?? (!!data && !!name ? data[name]?.toString() : undefined) ?? param?.defaultValue?.toString()\r\n const effectiveSwitchChecked = switchChecked ?? param?.switchChecked\r\n let check = !data && dValue === undefined && effectiveSwitchChecked === undefined ? false : !!dValue || !!effectiveSwitchChecked\r\n if (switchCheckedGetter) check = switchCheckedGetter(dValue, data)\r\n return {\r\n ...obj,\r\n switchChecked: check,\r\n defaultValue: dValue,\r\n handleBlur: () => {\r\n if (!name || !onBlur) return\r\n onBlur(name)\r\n }\r\n }\r\n }\r\n\r\n handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n const numberOfDays: number = e.target.value != '' ? parseInt(e.target.value) : 0\r\n this.setState({ numberOfDays }, () => {\r\n const err = getErrorMessage(this.props.messageErrors, this.props.name)\r\n if (numberOfDays > 0 && err.error) this.mergeConfig.handleBlur()\r\n })\r\n }\r\n\r\n handleSwitchChange = (checked: boolean) => {\r\n this.setState({ switchChecked: checked }, () => {\r\n const { name, onBlur } = this.props\r\n if (!name || !onBlur) return\r\n onBlur(name)\r\n })\r\n }\r\n\r\n getRootClasses = () => {\r\n const classes = [dateExpiredClasses.root]\r\n if (this.state.numberOfDays < 1) classes.push(dateExpiredClasses.expired)\r\n return classes.join(' ')\r\n }\r\n\r\n getNumberOfDays = (): number => {\r\n const dValue = this.mergeConfig.defaultValue\r\n if (this.mergeConfig.inputType === 'number' || (dValue !== undefined && !isNaN(Number(dValue)))) {\r\n return tryParseIntRequired(dValue, this.defaultNumberOfDays)\r\n } else {\r\n return this.getDaysUntilDate(dValue, this.defaultNumberOfDays)\r\n }\r\n }\r\n\r\n getOffsetDate = (num: number, formatString = defaultFormatString): string => {\r\n return dayjsCustom().add(num, 'day').format(formatString)\r\n }\r\n\r\n getDaysUntilDate = (value?: string | number, defaultValue = 0): number => {\r\n try {\r\n if (!value) return defaultValue\r\n const val = typeof value === 'number' ? dayjsCustom().add(value, 'day') : dayjsCustom(value)\r\n if (!val.isValid()) return defaultValue\r\n const target = dayjsCustom(value)\r\n const today = dayjsCustom()\r\n const diff = target.diff(today, 'day', true)\r\n return Math.round(diff)\r\n } catch {\r\n return defaultValue\r\n }\r\n }\r\n }\r\n return DateExpired\r\n}\r\nexport default CreateDateExpired\r\n\r\nconst Wrap = styled(Box)({\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '10px',\r\n position: 'relative',\r\n [`.${dateExpiredClasses.switch}`]: {\r\n margin: 0,\r\n flex: '0 0 auto'\r\n },\r\n [`.${dateExpiredClasses.label}`]: {\r\n b: {\r\n color: colors.blue[600],\r\n marginLeft: '8px'\r\n }\r\n },\r\n [`.${dateExpiredClasses.labelSwitch}`]: {\r\n fontWeight: 600,\r\n cursor: 'pointer'\r\n },\r\n [`.${dateExpiredClasses.control}`]: {\r\n position: 'absolute',\r\n top: 0,\r\n right: 0,\r\n height: '100%',\r\n display: 'flex',\r\n alignItems: 'center'\r\n },\r\n [`.${dateExpiredClasses.input}`]: {\r\n '.MuiInputBase-input': {\r\n paddingRight: '160px'\r\n }\r\n },\r\n [`&.${dateExpiredClasses.expired}`]: {\r\n [`.${dateExpiredClasses.label}`]: {\r\n b: {\r\n color: colors.red[600]\r\n }\r\n }\r\n }\r\n})\r\n"],"names":["dateExpiredClasses","CreateDateExpired","param","DateExpired","props","_this$updateMergeConf","_this","_classCallCheck","_callSuper","_defineProperty","_this$props","messageErrors","name","onBlur","slots","disabled","state","switchChecked","obj","_objectSpread","fullWidth","className","label","_jsxs","children","_jsx","getOffsetDate","numberOfDays","variant","type","value","onChange","handleChange","textFieldProps","_temp$message","temp","getErrorMessage","error","Boolean","helperText","message","mergeObjects","mergeConfig","e","target","parseInt","setState","err","handleBlur","checked","_this$props2","classes","push","join","dValue","defaultValue","inputType","undefined","isNaN","Number","tryParseIntRequired","defaultNumberOfDays","getDaysUntilDate","num","formatString","arguments","length","dayjsCustom","add","format","isValid","today","diff","Math","round","_unused","mergeConfigCached","updateMergeConfig","getNumberOfDays","id","Date","getTime","toString","_inherits","Component","_createClass","key","get","this","prevProps","data","_this$props$name","_this2","LocalizationProvider","dateAdapter","AdapterDayjs","Wrap","getRootClasses","rootProps","hidden","defaultValueInput","TextField","mapTextFieldProps","Typography","component","htmlFor","sx","color","Switch","size","_","handleSwitchChange","switchProps","currentSlots","_ref","_data$name","_param$defaultValue","_this$props3","switchCheckedGetter","effectiveSwitchChecked","check","styled","Box","display","alignItems","gap","position","concat","margin","flex","b","colors","blue","marginLeft","fontWeight","cursor","top","right","height","paddingRight","red"],"mappings":"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"}
|