dinocollab-core 2.2.37 → 2.2.39

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.
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sources":["../../../../src/data-surface/view-list/helpers.ts"],"sourcesContent":["import { TableCellProps } from '@mui/material'\r\nimport { ListDensity, TListColumn, TListColumns } from './types'\r\n\r\nexport const LIST_HEADER_HEIGHT = 48\r\nexport const LIST_DEFAULT_ROW_SPACING = 4\r\nexport const CHECKBOX_COL_WIDTH = 48\r\n\r\nexport const LIST_ROW_HEIGHT_BY_DENSITY: Record<ListDensity, number> = {\r\n compact: 36,\r\n standard: 48,\r\n comfortable: 56\r\n}\r\n\r\nexport const LIST_CELL_PADDING_BY_DENSITY: Record<ListDensity, string> = {\r\n compact: '6px 10px',\r\n standard: '10px 12px',\r\n comfortable: '12px 14px'\r\n}\r\n\r\nconst buildDefaultColumns = <T>(data: T[]): TListColumn<T>[] => {\r\n if (data.length === 0) return []\r\n const firstRow = data[0]\r\n return Object.keys(firstRow as object).map((key) => ({\r\n field: key as keyof T,\r\n label: String(key),\r\n flex: 1\r\n }))\r\n}\r\n\r\n/**\r\n * Converts TListColumns<T> Record type to TListColumn<T>[] array for internal use.\r\n */\r\nexport const columnsRecordToArray = <T>(value: T[], columnsRecord?: TListColumns<T>): TListColumn<T>[] => {\r\n if (!columnsRecord) return buildDefaultColumns(value)\r\n const keys = Object.keys(columnsRecord) as (keyof T)[]\r\n return keys.map((key) => {\r\n const colConfig = columnsRecord[key] ?? {}\r\n return { field: key, ...colConfig } as TListColumn<T>\r\n })\r\n}\r\n\r\nexport function resolveListRowHeight(density?: number | ListDensity): number {\r\n if (typeof density === 'number' && Number.isFinite(density) && density > 0) {\r\n return density\r\n }\r\n\r\n const resolvedDensity: ListDensity = typeof density === 'number' ? ListDensity.standard : (density ?? ListDensity.standard)\r\n return LIST_ROW_HEIGHT_BY_DENSITY[resolvedDensity]\r\n}\r\n\r\nexport function resolveListCellPadding(density?: number | ListDensity): string {\r\n if (typeof density === 'number') {\r\n return LIST_CELL_PADDING_BY_DENSITY[ListDensity.standard]\r\n }\r\n\r\n const resolvedDensity: ListDensity = typeof density === 'number' ? ListDensity.standard : (density ?? ListDensity.standard)\r\n return LIST_CELL_PADDING_BY_DENSITY[resolvedDensity]\r\n}\r\n\r\nexport function resolveListRowSpacing(spacing?: number): number {\r\n if (typeof spacing === 'number' && Number.isFinite(spacing) && spacing >= 0) {\r\n return spacing\r\n }\r\n\r\n return LIST_DEFAULT_ROW_SPACING\r\n}\r\n\r\n/** Default near-end threshold in pixels for triggering near-end events. */\r\nexport const LIST_DEFAULT_NEAR_END_THRESHOLD = 80\r\n/** Resolves the final near-end threshold from multiple optional values. */\r\nexport function resolveListNearEndThreshold(...threshold: (number | undefined)[]): number {\r\n const finalThreshold = threshold.filter((value): value is number => typeof value === 'number')\r\n if (finalThreshold.length === 0) return LIST_DEFAULT_NEAR_END_THRESHOLD\r\n return Math.max(0, ...finalThreshold)\r\n}\r\n\r\nexport function resolveListSpacerHeight(count: number, rowHeight: number, rowSpacing: number): number {\r\n if (count <= 0) return 0\r\n return count * rowHeight + Math.max(0, count - 1) * rowSpacing\r\n}\r\n\r\n/**\r\n * Resolves pixel widths for all columns using a flex redistribution algorithm.\r\n * Properly handles min/max constraints by iteratively redistributing overflow\r\n * from capped columns to uncapped flex siblings — similar to CSS flexbox.\r\n * Requires the actual container pixel width to compute exact values.\r\n */\r\nexport function resolveFlexColumnWidths<T>(\r\n columns: TListColumn<T>[],\r\n selectable: boolean,\r\n containerWidth: number\r\n): Array<number | string | undefined> {\r\n const checkboxWidth = selectable ? CHECKBOX_COL_WIDTH : 0\r\n let pool = containerWidth - checkboxWidth\r\n const result: Array<number | string | undefined> = new Array(columns.length).fill(undefined)\r\n\r\n if (containerWidth <= 0) {\r\n // Container not yet measured: use minWidth as best-guess for each column\r\n return columns.map((col) => {\r\n if (col.width !== undefined) return col.width\r\n return col.minWidth\r\n })\r\n }\r\n\r\n // Pass 1: allocate fixed and minWidth-only columns, collect flex columns\r\n type FlexItem = { i: number; flex: number; min: number; max: number; width: number; frozen: boolean }\r\n const flexCols: FlexItem[] = []\r\n for (let i = 0; i < columns.length; i++) {\r\n const col = columns[i]\r\n if (col.width !== undefined) {\r\n result[i] = col.width\r\n pool -= typeof col.width === 'number' ? col.width : 0\r\n } else if (!col.flex || col.flex <= 0) {\r\n const w = col.minWidth ?? 0\r\n result[i] = w > 0 ? w : undefined\r\n pool -= w\r\n } else {\r\n flexCols.push({ i, flex: col.flex, min: col.minWidth ?? 0, max: col.maxWidth ?? Infinity, width: 0, frozen: false })\r\n }\r\n }\r\n\r\n if (flexCols.length === 0 || pool <= 0) return result\r\n\r\n // Pass 2: iterative flex distribution respecting min/max constraints.\r\n // Each iteration freezes columns that hit a min/max boundary and\r\n // redistributes the leftover pool among the remaining unfrozen columns.\r\n for (let iter = 0; iter <= flexCols.length; iter++) {\r\n const active = flexCols.filter((f) => !f.frozen)\r\n if (active.length === 0) break\r\n const totalFlex = active.reduce((s, f) => s + f.flex, 0)\r\n let anyFrozen = false\r\n for (const item of active) {\r\n const raw = (item.flex / totalFlex) * pool\r\n if (raw < item.min) {\r\n item.width = item.min\r\n item.frozen = true\r\n pool -= item.min\r\n anyFrozen = true\r\n } else if (raw > item.max) {\r\n item.width = item.max\r\n item.frozen = true\r\n pool -= item.max\r\n anyFrozen = true\r\n }\r\n }\r\n if (!anyFrozen) {\r\n for (const item of active) {\r\n item.width = Math.round((item.flex / totalFlex) * pool)\r\n }\r\n break\r\n }\r\n }\r\n\r\n for (const fc of flexCols) {\r\n result[fc.i] = fc.width\r\n }\r\n return result\r\n}\r\n\r\nexport const getColumnWidth = <T>(column: TListColumn<T>, totalFixedPx: number, totalFlex: number): number | string | undefined => {\r\n // Priority 1: Explicit width always wins\r\n if (column.width !== undefined) return column.width\r\n\r\n // Priority 2: Flex-based proportional width.\r\n // Subtract all \"fixed\" columns (explicit width + minWidth-only) so flex columns only share truly remaining space.\r\n if (column.flex && column.flex > 0 && totalFlex > 0) {\r\n const flexRatio = column.flex / totalFlex\r\n const flexCalc = totalFixedPx > 0 ? `calc((100% - ${totalFixedPx}px) * ${flexRatio})` : `${flexRatio * 100}%`\r\n // When minWidth is also set, use CSS max() so the column never shrinks below minWidth.\r\n // This is necessary because tableLayout:fixed ignores CSS min-width on cells/cols.\r\n if (column.minWidth !== undefined) {\r\n return `max(${column.minWidth}px, ${flexCalc})`\r\n }\r\n return flexCalc\r\n }\r\n\r\n // Priority 3: minWidth-only column — use minWidth as the base layout width.\r\n // This ensures totalFixedPx correctly reserves space for this column,\r\n // and the CSS minWidth/maxWidth constraints are still applied via mapSxTableCell.\r\n if (column.minWidth !== undefined) return column.minWidth\r\n\r\n // Priority 4: Auto-width (no width, flex, or minWidth specified)\r\n return undefined\r\n}\r\n\r\nexport const mapSxTableCell = <T>(\r\n col: TListColumn<T>,\r\n resolvedWidth: number | string | undefined,\r\n sx?: TableCellProps['sx']\r\n): TableCellProps['sx'] => {\r\n return {\r\n width: resolvedWidth,\r\n minWidth: col.minWidth,\r\n maxWidth: col.maxWidth,\r\n ...sx\r\n }\r\n}\r\n"],"names":["LIST_HEADER_HEIGHT","LIST_DEFAULT_ROW_SPACING","CHECKBOX_COL_WIDTH","LIST_ROW_HEIGHT_BY_DENSITY","compact","standard","comfortable","LIST_CELL_PADDING_BY_DENSITY","columnsRecordToArray","value","columnsRecord","Object","keys","map","key","_columnsRecord$key","colConfig","_objectSpread","field","data","length","firstRow","label","String","flex","buildDefaultColumns","resolveListRowHeight","density","Number","isFinite","resolvedDensity","ListDensity","resolveListCellPadding","resolveListRowSpacing","spacing","LIST_DEFAULT_NEAR_END_THRESHOLD","resolveListNearEndThreshold","_len","arguments","threshold","Array","_key","finalThreshold","filter","Math","max","apply","concat","_toConsumableArray","resolveListSpacerHeight","count","rowHeight","rowSpacing","resolveFlexColumnWidths","columns","selectable","containerWidth","pool","result","fill","undefined","col","width","minWidth","flexCols","i","_col$minWidth","w","_col$minWidth2","_col$maxWidth","push","min","maxWidth","Infinity","frozen","iter","active","f","_step","totalFlex","reduce","s","anyFrozen","_iterator","_createForOfIteratorHelper","n","done","item","raw","err","e","_step2","_iterator2","round","_i","_flexCols","fc","mapSxTableCell","resolvedWidth","sx"],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","sources":["../../../../src/data-surface/view-list/helpers.ts"],"sourcesContent":["import { TableCellProps } from '@mui/material'\r\nimport { ListDensity, TListColumn, TListColumns } from './types'\r\n\r\nexport const LIST_HEADER_HEIGHT = 48\r\nexport const LIST_DEFAULT_ROW_SPACING = 4\r\nexport const CHECKBOX_COL_WIDTH = 48\r\n\r\nexport const LIST_ROW_HEIGHT_BY_DENSITY: Record<ListDensity, number> = {\r\n compact: 36,\r\n standard: 48,\r\n comfortable: 56\r\n}\r\n\r\nexport const LIST_CELL_PADDING_BY_DENSITY: Record<ListDensity, string> = {\r\n compact: '6px 10px',\r\n standard: '10px 12px',\r\n comfortable: '12px 14px'\r\n}\r\n\r\nconst buildDefaultColumns = <T>(data: T[]): TListColumn<T>[] => {\r\n if (data.length === 0) return []\r\n const firstRow = data[0]\r\n return Object.keys(firstRow as object).map((key) => ({\r\n field: key as keyof T,\r\n label: String(key),\r\n flex: 1\r\n }))\r\n}\r\n\r\n/**\r\n * Converts TListColumns<T> Record type to TListColumn<T>[] array for internal use.\r\n */\r\nexport const columnsRecordToArray = <T>(value: T[], columnsRecord?: TListColumns<T>): TListColumn<T>[] => {\r\n if (!columnsRecord) return buildDefaultColumns(value)\r\n const keys = Object.keys(columnsRecord) as (keyof T)[]\r\n return keys.map((key) => {\r\n const colConfig = columnsRecord[key] ?? {}\r\n return { field: key, ...colConfig } as TListColumn<T>\r\n })\r\n}\r\n\r\nexport function resolveListRowHeight(density?: number | ListDensity): number {\r\n if (typeof density === 'number' && Number.isFinite(density) && density > 0) {\r\n return density\r\n }\r\n\r\n const resolvedDensity: ListDensity = typeof density === 'number' ? ListDensity.standard : (density ?? ListDensity.standard)\r\n return LIST_ROW_HEIGHT_BY_DENSITY[resolvedDensity]\r\n}\r\n\r\nexport function resolveListCellPadding(density?: number | ListDensity): string {\r\n if (typeof density === 'number') {\r\n return LIST_CELL_PADDING_BY_DENSITY[ListDensity.standard]\r\n }\r\n\r\n const resolvedDensity: ListDensity = typeof density === 'number' ? ListDensity.standard : (density ?? ListDensity.standard)\r\n return LIST_CELL_PADDING_BY_DENSITY[resolvedDensity]\r\n}\r\n\r\nexport function resolveListRowSpacing(spacing?: number): number {\r\n if (typeof spacing === 'number' && Number.isFinite(spacing) && spacing >= 0) {\r\n return spacing\r\n }\r\n\r\n return LIST_DEFAULT_ROW_SPACING\r\n}\r\n\r\n/** Default near-end threshold in pixels for triggering near-end events. */\r\nexport const LIST_DEFAULT_NEAR_END_THRESHOLD = 80\r\n/** Resolves the final near-end threshold from multiple optional values. */\r\nexport function resolveListNearEndThreshold(...threshold: (number | undefined)[]): number {\r\n const finalThreshold = threshold.filter((value): value is number => typeof value === 'number')\r\n if (finalThreshold.length === 0) return LIST_DEFAULT_NEAR_END_THRESHOLD\r\n return Math.max(0, ...finalThreshold)\r\n}\r\n\r\nexport function resolveListSpacerHeight(count: number, rowHeight: number, rowSpacing: number): number {\r\n if (count <= 0) return 0\r\n return count * rowHeight + Math.max(0, count - 1) * rowSpacing\r\n}\r\n\r\n/**\r\n * Resolves pixel widths for all columns using a flex redistribution algorithm.\r\n * Properly handles min/max constraints by iteratively redistributing overflow\r\n * from capped columns to uncapped flex siblings — similar to CSS flexbox.\r\n * Requires the actual container pixel width to compute exact values.\r\n */\r\nexport function resolveFlexColumnWidths<T>(\r\n columns: TListColumn<T>[],\r\n selectable: boolean,\r\n containerWidth: number\r\n): Array<number | string | undefined> {\r\n const checkboxWidth = selectable ? CHECKBOX_COL_WIDTH : 0\r\n let pool = containerWidth - checkboxWidth\r\n const result: Array<number | string | undefined> = new Array(columns.length).fill(undefined)\r\n\r\n if (containerWidth <= 0) {\r\n // Container not yet measured: use minWidth as best-guess for each column\r\n return columns.map((col) => {\r\n if (col.width !== undefined) return col.width\r\n return col.minWidth\r\n })\r\n }\r\n\r\n // Pass 1: allocate fixed and minWidth-only columns, collect flex columns\r\n type FlexItem = { i: number; flex: number; min: number; max: number; width: number; frozen: boolean }\r\n const flexCols: FlexItem[] = []\r\n for (let i = 0; i < columns.length; i++) {\r\n const col = columns[i]\r\n if (col.width !== undefined) {\r\n result[i] = col.width\r\n pool -= typeof col.width === 'number' ? col.width : 0\r\n } else if (!col.flex || col.flex <= 0) {\r\n const w = col.minWidth ?? 0\r\n result[i] = w > 0 ? w : undefined\r\n pool -= w\r\n } else {\r\n flexCols.push({ i, flex: col.flex, min: col.minWidth ?? 0, max: col.maxWidth ?? Infinity, width: 0, frozen: false })\r\n }\r\n }\r\n\r\n if (flexCols.length === 0 || pool <= 0) return result\r\n\r\n // Pass 2: iterative flex distribution respecting min/max constraints.\r\n // Each iteration freezes columns that hit a min/max boundary and\r\n // redistributes the leftover pool among the remaining unfrozen columns.\r\n for (let iter = 0; iter <= flexCols.length; iter++) {\r\n const active = flexCols.filter((f) => !f.frozen)\r\n if (active.length === 0) break\r\n const totalFlex = active.reduce((s, f) => s + f.flex, 0)\r\n let anyFrozen = false\r\n for (const item of active) {\r\n const raw = (item.flex / totalFlex) * pool\r\n if (raw < item.min) {\r\n item.width = item.min\r\n item.frozen = true\r\n pool -= item.min\r\n anyFrozen = true\r\n } else if (raw > item.max) {\r\n item.width = item.max\r\n item.frozen = true\r\n pool -= item.max\r\n anyFrozen = true\r\n }\r\n }\r\n if (!anyFrozen) {\r\n for (const item of active) {\r\n item.width = Math.round((item.flex / totalFlex) * pool)\r\n }\r\n break\r\n }\r\n }\r\n\r\n for (const fc of flexCols) {\r\n result[fc.i] = fc.width\r\n }\r\n return result\r\n}\r\n\r\nexport const getColumnWidth = <T>(column: TListColumn<T>, totalFixedPx: number, totalFlex: number): number | string | undefined => {\r\n // Priority 1: Explicit width always wins\r\n if (column.width !== undefined) return column.width\r\n\r\n // Priority 2: Flex-based proportional width.\r\n // Subtract all \"fixed\" columns (explicit width + minWidth-only) so flex columns only share truly remaining space.\r\n if (column.flex && column.flex > 0 && totalFlex > 0) {\r\n const flexRatio = column.flex / totalFlex\r\n const flexCalc = totalFixedPx > 0 ? `calc((100% - ${totalFixedPx}px) * ${flexRatio})` : `${flexRatio * 100}%`\r\n // When minWidth is also set, use CSS max() so the column never shrinks below minWidth.\r\n // This is necessary because tableLayout:fixed ignores CSS min-width on cells/cols.\r\n if (column.minWidth !== undefined) return `max(${column.minWidth}px, ${flexCalc})`\r\n\r\n return flexCalc\r\n }\r\n\r\n // Priority 3: minWidth-only column — use minWidth as the base layout width.\r\n // This ensures totalFixedPx correctly reserves space for this column,\r\n // and the CSS minWidth/maxWidth constraints are still applied via mapSxTableCell.\r\n if (column.minWidth !== undefined) return column.minWidth\r\n\r\n // Priority 4: Auto-width (no width, flex, or minWidth specified)\r\n return undefined\r\n}\r\n\r\nexport const mapSxTableCell = <T>(\r\n col: TListColumn<T>,\r\n resolvedWidth: number | string | undefined,\r\n sx?: TableCellProps['sx']\r\n): TableCellProps['sx'] => {\r\n return {\r\n width: resolvedWidth,\r\n minWidth: col.minWidth,\r\n maxWidth: col.maxWidth,\r\n ...sx\r\n }\r\n}\r\n"],"names":["LIST_HEADER_HEIGHT","LIST_DEFAULT_ROW_SPACING","CHECKBOX_COL_WIDTH","LIST_ROW_HEIGHT_BY_DENSITY","compact","standard","comfortable","LIST_CELL_PADDING_BY_DENSITY","columnsRecordToArray","value","columnsRecord","Object","keys","map","key","_columnsRecord$key","colConfig","_objectSpread","field","data","length","firstRow","label","String","flex","buildDefaultColumns","resolveListRowHeight","density","Number","isFinite","resolvedDensity","ListDensity","resolveListCellPadding","resolveListRowSpacing","spacing","LIST_DEFAULT_NEAR_END_THRESHOLD","resolveListNearEndThreshold","_len","arguments","threshold","Array","_key","finalThreshold","filter","Math","max","apply","concat","_toConsumableArray","resolveListSpacerHeight","count","rowHeight","rowSpacing","resolveFlexColumnWidths","columns","selectable","containerWidth","pool","result","fill","undefined","col","width","minWidth","flexCols","i","_col$minWidth","w","_col$minWidth2","_col$maxWidth","push","min","maxWidth","Infinity","frozen","iter","active","f","_step","totalFlex","reduce","s","anyFrozen","_iterator","_createForOfIteratorHelper","n","done","item","raw","err","e","_step2","_iterator2","round","_i","_flexCols","fc","mapSxTableCell","resolvedWidth","sx"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{createClass as e,classCallCheck as t,defineProperty as r}from"../../_virtual/_rollupPluginBabelHelpers.js";import{createFilterBar as i}from"./index.create.js";import{createLocalFilterBuilder as m}from"./local-filter-builder.js";import{createConvertToGraphQL as o,mapLogic as l,mapSortDirection as s}from"./convert-to-graphql.js";import{isEmptyFilterState as a,removeNullValues as c,isFilterStateEqual as f,setFilterToURL as h,getFilterFromURL as p}from"./helpers.js";import u from"./menu/create-form-field-string.js";import n from"./menu/create-form-field-select.js";import F,{formatterNumber as d}from"./menu/create-form-field-number.js";import j from"./menu/create-form-field-select-multiple.js";import{createFormFieldDateTime as g,formatterDateTime as b}from"./menu/create-form-field-datetime.js";var v=e(function e(){t(this,e),r(this,"createFilterBar",i),r(this,"createConvertToGraphQL",o),r(this,"createLocalFilterBuilder",m),r(this,"createFormFieldString",u),r(this,"createFormFieldNumber",F),r(this,"createFormFieldSelect",n),r(this,"createFormFieldSelectMultiple",j),r(this,"createFormFieldDateTime",g),r(this,"mapLogic",l),r(this,"mapDirection",s),r(this,"formatterDateTime",b),r(this,"formatterNumber",d),r(this,"isEmptyFilterState",a),r(this,"removeNullValues",c),r(this,"isFilterStateEqual",f),r(this,"setFilterToURL",h),r(this,"getFilterFromURL",p)}),L=new v;export{v as DinoFilterBar,L as dinoFilterBar};
1
+ import{createClass as e,classCallCheck as t,defineProperty as r}from"../../_virtual/_rollupPluginBabelHelpers.js";import{createFilterBar as i}from"./index.create.js";import{createLocalFilterBuilder as l}from"./local-filter-builder.js";import{createConvertToGraphQL as m,mapLogic as o,mapSortDirection as a}from"./convert-to-graphql.js";import{isEmptyFilterState as s,removeNullValues as c,isFilterStateEqual as f,setFilterToURL as h,getFilterFromURL as p}from"./helpers.js";import{createFormFieldSelectWithFallback as F,createFormFieldSelectMultipleWithFallback as u}from"./menu/create-form-field-select.fallback.js";import d,{formatterNumber as n}from"./menu/create-form-field-number.js";import{createFormFieldDateTime as j,formatterDateTime as b}from"./menu/create-form-field-datetime.js";import S from"./menu/create-form-field-string.js";import g from"./menu/create-form-field-select.js";import v from"./menu/create-form-field-select-multiple.js";var L=e(function e(){t(this,e),r(this,"createFilterBar",i),r(this,"createConvertToGraphQL",m),r(this,"createLocalFilterBuilder",l),r(this,"createFormFieldString",S),r(this,"createFormFieldNumber",d),r(this,"createFormFieldDateTime",j),r(this,"createFormFieldSelect",g),r(this,"createFormFieldSelectWithFallback",F),r(this,"createFormFieldSelectMultiple",v),r(this,"createFormFieldSelectMultipleWithFallback",u),r(this,"mapLogic",o),r(this,"mapDirection",a),r(this,"formatterDateTime",b),r(this,"formatterNumber",n),r(this,"isEmptyFilterState",s),r(this,"removeNullValues",c),r(this,"isFilterStateEqual",f),r(this,"setFilterToURL",h),r(this,"getFilterFromURL",p)}),k=new L;export{L as DinoFilterBar,k as dinoFilterBar};
2
2
  //# sourceMappingURL=index.dino.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.dino.js","sources":["../../../src/filter-bar/index.dino.tsx"],"sourcesContent":["import { createFilterBar } from './index.create'\r\nimport { createLocalFilterBuilder } from './local-filter-builder'\r\nimport { createConvertToGraphQL, mapLogic, mapSortDirection } from './convert-to-graphql'\r\nimport { getFilterFromURL, isEmptyFilterState, isFilterStateEqual, removeNullValues, setFilterToURL } from './helpers'\r\nimport createFormFieldString from './menu/create-form-field-string'\r\nimport createFormFieldSelect from './menu/create-form-field-select'\r\nimport createFormFieldNumber, { formatterNumber } from './menu/create-form-field-number'\r\nimport createFormFieldSelectMultiple from './menu/create-form-field-select-multiple'\r\nimport createFormFieldDateTime, { formatterDateTime } from './menu/create-form-field-datetime'\r\n\r\nexport class DinoFilterBar {\r\n createFilterBar = createFilterBar\r\n createConvertToGraphQL = createConvertToGraphQL\r\n createLocalFilterBuilder = createLocalFilterBuilder\r\n\r\n // Form fields\r\n createFormFieldString = createFormFieldString\r\n createFormFieldNumber = createFormFieldNumber\r\n createFormFieldSelect = createFormFieldSelect\r\n createFormFieldSelectMultiple = createFormFieldSelectMultiple\r\n createFormFieldDateTime = createFormFieldDateTime\r\n\r\n // support\r\n mapLogic = mapLogic\r\n mapDirection = mapSortDirection\r\n\r\n // fortmatter\r\n formatterDateTime = formatterDateTime\r\n formatterNumber = formatterNumber\r\n\r\n // helpers\r\n isEmptyFilterState = isEmptyFilterState\r\n removeNullValues = removeNullValues\r\n isFilterStateEqual = isFilterStateEqual\r\n setFilterToURL = setFilterToURL\r\n getFilterFromURL = getFilterFromURL\r\n}\r\n\r\nexport const dinoFilterBar = new DinoFilterBar()\r\n"],"names":["DinoFilterBar","_createClass","_classCallCheck","_defineProperty","createFilterBar","createConvertToGraphQL","createLocalFilterBuilder","createFormFieldString","createFormFieldNumber","createFormFieldSelect","createFormFieldSelectMultiple","createFormFieldDateTime","mapLogic","mapSortDirection","formatterDateTime","formatterNumber","isEmptyFilterState","removeNullValues","isFilterStateEqual","setFilterToURL","getFilterFromURL","dinoFilterBar"],"mappings":"uyBAUA,IAAaA,EAAaC,EAAA,SAAAD,IAAAE,OAAAF,GAAAG,yBACNC,GAAeD,gCACRE,GAAsBF,kCACpBG,GAE3BH,+BACwBI,GAAqBJ,+BACrBK,GAAqBL,+BACrBM,GAAqBN,uCACbO,GAA6BP,iCACnCQ,GAE1BR,kBACWS,GAAQT,sBACJU,GAEfV,2BACoBW,GAAiBX,yBACnBY,GAElBZ,4BACqBa,GAAkBb,0BACpBc,GAAgBd,4BACde,GAAkBf,wBACtBgB,GAAchB,0BACZiB,EAAgB,GAGxBC,EAAgB,IAAIrB"}
1
+ {"version":3,"file":"index.dino.js","sources":["../../../src/filter-bar/index.dino.tsx"],"sourcesContent":["import { createFilterBar } from './index.create'\r\nimport { createLocalFilterBuilder } from './local-filter-builder'\r\nimport { createConvertToGraphQL, mapLogic, mapSortDirection } from './convert-to-graphql'\r\nimport { getFilterFromURL, isEmptyFilterState, isFilterStateEqual, removeNullValues, setFilterToURL } from './helpers'\r\nimport { createFormFieldSelectMultipleWithFallback, createFormFieldSelectWithFallback } from './menu/create-form-field-select.fallback'\r\nimport createFormFieldNumber, { formatterNumber } from './menu/create-form-field-number'\r\nimport createFormFieldDateTime, { formatterDateTime } from './menu/create-form-field-datetime'\r\nimport createFormFieldString from './menu/create-form-field-string'\r\nimport createFormFieldSelect from './menu/create-form-field-select'\r\nimport createFormFieldSelectMultiple from './menu/create-form-field-select-multiple'\r\n\r\nexport class DinoFilterBar {\r\n createFilterBar = createFilterBar\r\n createConvertToGraphQL = createConvertToGraphQL\r\n createLocalFilterBuilder = createLocalFilterBuilder\r\n\r\n // Form fields\r\n createFormFieldString = createFormFieldString\r\n createFormFieldNumber = createFormFieldNumber\r\n createFormFieldDateTime = createFormFieldDateTime\r\n createFormFieldSelect = createFormFieldSelect\r\n createFormFieldSelectWithFallback = createFormFieldSelectWithFallback\r\n createFormFieldSelectMultiple = createFormFieldSelectMultiple\r\n createFormFieldSelectMultipleWithFallback = createFormFieldSelectMultipleWithFallback\r\n\r\n // support\r\n mapLogic = mapLogic\r\n mapDirection = mapSortDirection\r\n\r\n // formatter\r\n formatterDateTime = formatterDateTime\r\n formatterNumber = formatterNumber\r\n\r\n // helpers\r\n isEmptyFilterState = isEmptyFilterState\r\n removeNullValues = removeNullValues\r\n isFilterStateEqual = isFilterStateEqual\r\n setFilterToURL = setFilterToURL\r\n getFilterFromURL = getFilterFromURL\r\n}\r\n\r\nexport const dinoFilterBar = new DinoFilterBar()\r\n"],"names":["DinoFilterBar","_createClass","_classCallCheck","_defineProperty","createFilterBar","createConvertToGraphQL","createLocalFilterBuilder","createFormFieldString","createFormFieldNumber","createFormFieldDateTime","createFormFieldSelect","createFormFieldSelectWithFallback","createFormFieldSelectMultiple","createFormFieldSelectMultipleWithFallback","mapLogic","mapSortDirection","formatterDateTime","formatterNumber","isEmptyFilterState","removeNullValues","isFilterStateEqual","setFilterToURL","getFilterFromURL","dinoFilterBar"],"mappings":"s7BAWA,IAAaA,EAAaC,EAAA,SAAAD,IAAAE,OAAAF,GAAAG,yBACNC,GAAeD,gCACRE,GAAsBF,kCACpBG,GAE3BH,+BACwBI,GAAqBJ,+BACrBK,GAAqBL,iCACnBM,GAAuBN,+BACzBO,GAAqBP,2CACTQ,GAAiCR,uCACrCS,GAA6BT,mDACjBU,GAE5CV,kBACWW,GAAQX,sBACJY,GAEfZ,2BACoBa,GAAiBb,yBACnBc,GAElBd,4BACqBe,GAAkBf,0BACpBgB,GAAgBhB,4BACdiB,GAAkBjB,wBACtBkB,GAAclB,0BACZmB,EAAgB,GAGxBC,EAAgB,IAAIvB"}
@@ -1,2 +1,2 @@
1
- import{slicedToArray as e,defineProperty as l,toConsumableArray as n}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useMemo as t,useState as r,useEffect as a}from"react";import{styled as u,Typography as c,Box as s,CircularProgress as d,FormGroup as v,FormControlLabel as m,Checkbox as f,Button as p}from"@mui/material";import"../../form/validator.js";import"../../form/dino-form.js";import{getErrorMessage as b}from"../../form/helpers.js";import"../../../_virtual/Reflect.js";import"../../form/decorator.form.js";import"../../form/create.form-grid-layout.units.js";import{createChipViewers as g}from"../components/chip-viewer.js";import{PopperContent as h,PopperBody as x,PopperFooter as y}from"../components/popper-custom.js";import{ButtonBack as C,ChipDark as j,FilterLogicToggle as A}from"../components/ui.units.js";function V(u){var V=g(),z=(u||{}).options,S=void 0===z?[]:z;return function(g){var z,L,O,w=t(function(){return Object.assign({},g.currentConfig,null==u?void 0:u.config)},[null==u?void 0:u.config,g.currentConfig]),R=g.value,B=void 0===R?{values:[],logic:null!==(z=null==w?void 0:w.defaultLogic)&&void 0!==z?z:"or"}:R,N=r(B.logic),T=e(N,2),_=T[0],E=T[1],F=null!==(L=null==u?void 0:u.forceLogic)&&void 0!==L?L:_,I=null!==(O=null==w?void 0:w.label)&&void 0!==O?O:w.field.toString(),M=r([]),P=e(M,2),D=P[0],H=P[1],U=r(!1),q=e(U,2),G=q[0],J=q[1];a(function(){if(null!=u&&u.fetchOptions){var e=new AbortController;return J(!0),u.fetchOptions(e.signal).then(H).catch(function(e){"AbortError"!==(null==e?void 0:e.name)&&console.error(e)}).finally(function(){return J(!1)}),function(){return e.abort()}}},[]);var K=null!=u&&u.fetchOptions?D:S,Q=t(function(){var e=Array.isArray(B.values)?B.values:[B.values];return K.filter(function(l){return e.includes(l.value)}).map(function(e){return e.value})},[]),W=r(Q),X=e(W,2),Y=X[0],Z=X[1],$=Array.isArray(B.values)?B.values:[],ee=_!==B.logic,le=Y.length!==$.length||Y.some(function(e){return!$.includes(e)}),ne=!le&&!ee,oe=r({}),ie=e(oe,2),te=ie[0],re=ie[1],ae=function(e){g.onSubmit(w.field,e,w)},ue=b(te,w.field),ce=t(function(){var e=Array.isArray(B.values)?B.values:[B.values];return{field:w.field,items:e.map(function(e){var l;return{value:e,label:null===(l=K.find(function(l){return l.value===e}))||void 0===l?void 0:l.label}})}},[w.field,B]),se=null!=(null==u?void 0:u.maxValueCount)&&Y.length>u.maxValueCount,de=null!=(null==u?void 0:u.maxValueCount)&&Y.length>=u.maxValueCount,ve=[];return(g.isLoading||G)&&ve.push("disabled"),o(k,{className:ve.join(" "),noValidate:!0,onSubmit:function(e){var n;if(e.preventDefault(),le){if(!se){var o=l({},w.field,Y),i=null===(n=g.validator)||void 0===n?void 0:n.run(o);if(re(i||{}),!i||0===Object.keys(i).length)ae({values:Y,logic:F})}}else ee&&ae({values:B.values,logic:F})},children:i(h,{title:"Filter by ".concat(I),onClose:g.onClose,slots:{beforeTitle:o(C,{size:"small",onClick:g.onBack}),afterTitle:null!=u&&u.forceLogic?null:w.singleValue?o(j,{sx:{ml:1.5},size:"small",label:"Last value only"}):o(A,{sx:{ml:1},value:F,onChange:function(e,l){E(l)}})},children:[i(x,{children:[w.description&&o(c,{variant:"caption",color:"text.secondary",sx:{mb:1,display:"block"},children:w.description}),null!=(null==u?void 0:u.maxValueCount)&&o(c,{variant:"caption",color:se?"warning.main":"text.secondary",sx:{mb:.5,display:"block"},children:null!=u&&u.maxValueCount?se?"Maximum ".concat(u.maxValueCount," value").concat(u.maxValueCount>1?"s":""," selected (limit reached)"):"Up to ".concat(u.maxValueCount," value").concat(u.maxValueCount>1?"s":""," can be selected"):""}),o(V,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:ce,onRemove:g.onRemove}),0===K.length&&G&&o(s,{sx:{display:"flex",justifyContent:"center",mt:2},children:o(d,{size:20})}),0===K.length&&!G&&o(c,{variant:"body2",color:"text.secondary",sx:{mt:2},children:"No options available"}),o(v,{className:ue.error?"error":"",children:K.map(function(e,l){var i,t=Y.includes(e.value),r=ce.items.some(function(l){return l.value===e.value})&&!0===(null==u?void 0:u.disabledAfterSubmit),a=!t&&de;return o(m,{value:e.value,disabled:r||a,label:null!==(i=e.label)&&void 0!==i?i:e.value,control:o(f,{name:w.field.toString(),checked:t,onChange:function(l){return o=e.value,i=l.target.checked,void Z(function(e){return i?[].concat(n(e),[o]):e.filter(function(e){return e!==o})});var o,i}})},e.value.toString()+l)})})]}),i(y,{children:[o(p,{size:"small",color:"error",variant:"text",disabled:!B.values||0===B.values.length,onClick:function(){var e,l;null===(e=g.onRemoveField)||void 0===e||e.call(g,w.field),!1!==(null==u||null===(l=u.config)||void 0===l?void 0:l.closeAfterClear)&&g.onClose()},children:"Clear All"}),o(s,{sx:{flex:1}}),o(p,{size:"small",color:"inherit",variant:"text",onClick:g.onClose,children:"Cancel"}),o(p,{size:"small",type:"submit",color:"primary",variant:"contained",disabled:ne,children:"Apply"})]})]})})}}var k=u("form")({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.12)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}});export{V as default};
1
+ import{slicedToArray as l,toConsumableArray as e,defineProperty as n}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useMemo as r,useState as t,useRef as a,useEffect as u}from"react";import{styled as c,Typography as s,Box as d,CircularProgress as v,Button as m,FormGroup as f,FormControlLabel as p,Checkbox as b}from"@mui/material";import g from"@mui/icons-material/Info";import{createChipViewers as h}from"../components/chip-viewer.js";import{PopperContent as x,PopperBody as y,PopperFooter as C}from"../components/popper-custom.js";import{ButtonBack as A,ChipDark as V,FilterLogicToggle as k}from"../components/ui.units.js";import{getErrorMessage as z}from"../../form/helpers.js";function j(c){var j=h(),O=(c||{}).options,L=void 0===O?[]:O;return function(h){var O,w,I,R=r(function(){return Object.assign({},h.currentConfig,null==c?void 0:c.config)},[null==c?void 0:c.config,h.currentConfig]),B=h.value,E=void 0===B?{values:[],logic:null!==(O=null==R?void 0:R.defaultLogic)&&void 0!==O?O:"or"}:B,F=t(E.logic),N=l(F,2),T=N[0],D=N[1],M=null!==(w=null==c?void 0:c.forceLogic)&&void 0!==w?w:T,P=null!==(I=null==R?void 0:R.label)&&void 0!==I?I:R.field.toString(),_=t([]),H=l(_,2),U=H[0],q=H[1],G=t(null!=c&&c.fetchOptions?"loading":"loaded"),J=l(G,2),K=J[0],Q=J[1],W=a(null),X=function(){var l;if(null!=c&&c.fetchOptions){null===(l=W.current)||void 0===l||l.abort();var e=new AbortController;W.current=e,Q("loading"),c.fetchOptions(e.signal).then(function(l){q(l),Q("loaded")}).catch(function(l){var e;null===(e=h.onError)||void 0===e||e.call(h),"AbortError"!==(null==l?void 0:l.name)&&Q("error")})}};u(function(){return X(),function(){var l;return null===(l=W.current)||void 0===l?void 0:l.abort()}},[]);var Y=null!=c&&c.fetchOptions?U:L,Z=t(function(){return Array.isArray(E.values)?e(E.values):[]}),$=l(Z,2),ll=$[0],el=$[1],nl=Array.isArray(E.values)?E.values:[],ol=T!==E.logic,il=ll.length!==nl.length||ll.some(function(l){return!nl.includes(l)}),rl=!il&&!ol,tl=t({}),al=l(tl,2),ul=al[0],cl=al[1],sl=function(l){h.onSubmit(R.field,l,R)},dl=z(ul,R.field),vl=r(function(){var l=Array.isArray(E.values)?E.values:[E.values];return{field:R.field,items:l.map(function(l){var e;return{value:l,label:null===(e=Y.find(function(e){return e.value===l}))||void 0===e?void 0:e.label}})}},[R.field,E]),ml=null!=(null==c?void 0:c.maxValueCount)&&ll.length>c.maxValueCount,fl=null!=(null==c?void 0:c.maxValueCount)&&ll.length>=c.maxValueCount,pl=[];return(h.isLoading||"loading"===K)&&pl.push("disabled"),o(S,{className:pl.join(" "),noValidate:!0,onSubmit:function(l){var e;if(l.preventDefault(),il){if(!ml){var o=n({},R.field,ll),i=null===(e=h.validator)||void 0===e?void 0:e.run(o);if(cl(i||{}),!i||0===Object.keys(i).length)sl({values:ll,logic:M})}}else ol&&sl({values:E.values,logic:M})},children:i(x,{title:"Filter by ".concat(P),onClose:h.onClose,slots:{beforeTitle:o(A,{size:"small",onClick:h.onBack}),afterTitle:null!=c&&c.forceLogic?null:R.singleValue?o(V,{sx:{ml:1.5},size:"small",label:"Last value only"}):o(k,{sx:{ml:1},value:M,onChange:function(l,e){D(e)}})},children:[i(y,{children:[R.description&&o(s,{variant:"caption",color:"text.secondary",sx:{mb:1,display:"block"},children:R.description}),null!=(null==c?void 0:c.maxValueCount)&&o(s,{variant:"caption",color:ml?"warning.main":"text.secondary",sx:{mb:.5,display:"block"},children:null!=c&&c.maxValueCount?ml?"Maximum ".concat(c.maxValueCount," value").concat(c.maxValueCount>1?"s":""," selected (limit reached)"):"Up to ".concat(c.maxValueCount," value").concat(c.maxValueCount>1?"s":""," can be selected"):""}),o(j,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:vl,onRemove:h.onRemove}),"loading"===K&&o(d,{sx:{display:"flex",justifyContent:"center",mt:2},children:o(v,{size:20})}),"error"===K&&i(d,{sx:{display:"flex",flexDirection:"column",alignItems:"center",mt:2,mb:3,gap:1},children:[o(g,{color:"error",fontSize:"large"}),o(s,{variant:"body2",color:"error",children:"Failed to load options"}),o(m,{size:"small",variant:"outlined",color:"error",onClick:X,children:"Retry"})]}),0===Y.length&&"loaded"===K&&o(s,{variant:"body2",color:"text.secondary",sx:{mt:2},children:"No options available"}),o(f,{className:dl.error?"error":"",children:Y.map(function(l,n){var i,r=ll.includes(l.value),t=vl.items.some(function(e){return e.value===l.value})&&!0===(null==c?void 0:c.disabledAfterSubmit),a=!r&&fl;return o(p,{value:l.value,disabled:t||a,label:null!==(i=l.label)&&void 0!==i?i:l.value,control:o(b,{name:R.field.toString(),checked:r,onChange:function(n){return o=l.value,i=n.target.checked,void el(function(l){return i?[].concat(e(l),[o]):l.filter(function(l){return l!==o})});var o,i}})},l.value.toString()+n)})})]}),i(C,{children:[o(m,{size:"small",color:"error",variant:"text",disabled:!E.values||0===E.values.length,onClick:function(){var l,e;null===(l=h.onRemoveField)||void 0===l||l.call(h,R.field),!1!==(null==c||null===(e=c.config)||void 0===e?void 0:e.closeAfterClear)&&h.onClose()},children:"Clear All"}),o(d,{sx:{flex:1}}),o(m,{size:"small",color:"inherit",variant:"text",onClick:h.onClose,children:"Cancel"}),o(m,{size:"small",type:"submit",color:"primary",variant:"contained",disabled:rl,children:"Apply"})]})]})})}}var S=c("form")({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.12)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}});export{j as default};
2
2
  //# sourceMappingURL=create-form-field-select-multiple.js.map
@@ -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 { useEffect, useMemo, useState } from 'react'\r\nimport { Box, Button, Checkbox, CircularProgress, FormControlLabel, FormGroup, formGroupClasses, styled, Typography } 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 /** Function to fetch options asynchronously */\r\n fetchOptions?: (signal?: AbortSignal) => Promise<IFieldSelectOption[]>\r\n /** If true, disables the field after submission. @default false */\r\n disabledAfterSubmit?: boolean\r\n /** Force a fixed logic value, hiding the logic toggle */\r\n forceLogic?: TLogic\r\n /** Maximum number of values that can be selected */\r\n maxValueCount?: number\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: staticOptions = [] } = 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 const effectiveLogic = params?.forceLogic ?? filterLogic\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n const [fetchedOptions, setFetchedOptions] = useState<IFieldSelectOption[]>([])\r\n const [isFetchLoading, setIsFetchLoading] = useState(false)\r\n\r\n useEffect(() => {\r\n if (!params?.fetchOptions) return\r\n const controller = new AbortController()\r\n setIsFetchLoading(true)\r\n params\r\n .fetchOptions(controller.signal)\r\n .then(setFetchedOptions)\r\n .catch((err) => {\r\n if (err?.name !== 'AbortError') console.error(err)\r\n })\r\n .finally(() => setIsFetchLoading(false))\r\n return () => controller.abort()\r\n }, [])\r\n\r\n const options = params?.fetchOptions ? fetchedOptions : staticOptions\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 appliedValues = Array.isArray(value.values) ? value.values : []\r\n const hasLogicChange = filterLogic !== value.logic\r\n const hasDataChange = checkedValues.length !== appliedValues.length || checkedValues.some((v) => !appliedValues.includes(v))\r\n const isApplyDisabled = !hasDataChange && !hasLogicChange\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\r\n if (!hasDataChange) {\r\n if (hasLogicChange) {\r\n handleSubmit({ values: value.values, logic: effectiveLogic })\r\n }\r\n return\r\n }\r\n\r\n if (isMaxReached) return\r\n\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: effectiveLogic }\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 isMaxReached = params?.maxValueCount != null && checkedValues.length > params.maxValueCount\r\n const isMaxReachedValid = params?.maxValueCount != null && checkedValues.length >= params.maxValueCount\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n if (params?.config?.closeAfterClear !== false) props.onClose()\r\n }\r\n\r\n const getMaxReachedText = () => {\r\n if (!params?.maxValueCount) return ''\r\n if (isMaxReached) {\r\n return `Maximum ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} selected (limit reached)`\r\n } else {\r\n return `Up to ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} can be selected`\r\n }\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (params?.forceLogic) return null\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={effectiveLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading || isFetchLoading) 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 {mergedConfig.description && (\r\n <Typography variant='caption' color='text.secondary' sx={{ mb: 1, display: 'block' }}>\r\n {mergedConfig.description}\r\n </Typography>\r\n )}\r\n {params?.maxValueCount != null && (\r\n <Typography variant='caption' color={isMaxReached ? 'warning.main' : 'text.secondary'} sx={{ mb: 0.5, display: 'block' }}>\r\n {getMaxReachedText()}\r\n </Typography>\r\n )}\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 {options.length === 0 && isFetchLoading && (\r\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: 2 }}>\r\n <CircularProgress size={20} />\r\n </Box>\r\n )}\r\n {options.length === 0 && !isFetchLoading && (\r\n <Typography variant='body2' color='text.secondary' sx={{ mt: 2 }}>\r\n No options available\r\n </Typography>\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 isSelected = filterViewerValue.items.some((item) => item.value === x.value)\r\n const disabled = isSelected && params?.disabledAfterSubmit === true\r\n const disableDueToMax = !isChecked && isMaxReachedValid\r\n return (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n disabled={disabled || disableDueToMax}\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' disabled={isApplyDisabled}>\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.12)',\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","staticOptions","props","_mergedConfig$default","_params$forceLogic","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","effectiveLogic","forceLogic","label","field","toString","_useState3","_useState4","fetchedOptions","setFetchedOptions","_useState5","_useState6","isFetchLoading","setIsFetchLoading","useEffect","fetchOptions","controller","AbortController","signal","then","err","name","console","error","abort","initialChecked","Array","isArray","filter","opt","includes","map","_useState7","_useState8","checkedValues","setCheckedValues","appliedValues","hasLogicChange","hasDataChange","length","some","v","isApplyDisabled","_useState9","_useState0","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","_options$find","find","o","isMaxReached","maxValueCount","isMaxReachedValid","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","obj","_defineProperty","validator","run","keys","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","PopperBody","description","Typography","variant","color","mb","display","borderBottom","placement","enableMinimalesticView","onRemove","Box","justifyContent","mt","CircularProgress","FormGroup","x","i","_x$label","isChecked","disabled","item","disabledAfterSubmit","disableDueToMax","FormControlLabel","control","Checkbox","checked","e","optionValue","target","prev","_toConsumableArray","PopperFooter","Button","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","flex","type","styled","position","content","inset","backgroundColor","zIndex","opacity","transition","visibility","pointerEvents"],"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 { useEffect, useMemo, useRef, useState } from 'react'\r\nimport { Box, Button, Checkbox, CircularProgress, FormControlLabel, FormGroup, formGroupClasses, styled, Typography } from '@mui/material'\r\nimport InfoIcon from '@mui/icons-material/Info'\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, TFetchStatus } 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 onError?: () => void\r\n}\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 /** Function to fetch options asynchronously */\r\n fetchOptions?: (signal?: AbortSignal) => Promise<IFieldSelectOption[]>\r\n /** If true, disables the field after submission. @default false */\r\n disabledAfterSubmit?: boolean\r\n /** Force a fixed logic value, hiding the logic toggle */\r\n forceLogic?: TLogic\r\n /** Maximum number of values that can be selected */\r\n maxValueCount?: number\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: staticOptions = [] } = 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 const effectiveLogic = params?.forceLogic ?? filterLogic\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n const [fetchedOptions, setFetchedOptions] = useState<IFieldSelectOption[]>([])\r\n const [fetchStatus, setFetchStatus] = useState<TFetchStatus>(params?.fetchOptions ? 'loading' : 'loaded')\r\n const abortRef = useRef<AbortController | null>(null)\r\n\r\n const runFetch = () => {\r\n if (!params?.fetchOptions) return\r\n abortRef.current?.abort()\r\n const controller = new AbortController()\r\n abortRef.current = controller\r\n setFetchStatus('loading')\r\n params\r\n .fetchOptions(controller.signal)\r\n .then((data) => {\r\n setFetchedOptions(data)\r\n setFetchStatus('loaded')\r\n })\r\n .catch((err) => {\r\n props.onError?.()\r\n if (err?.name !== 'AbortError') setFetchStatus('error')\r\n })\r\n }\r\n\r\n useEffect(() => {\r\n runFetch()\r\n return () => abortRef.current?.abort()\r\n }, [])\r\n\r\n const options = params?.fetchOptions ? fetchedOptions : staticOptions\r\n\r\n // Track checked values as controlled state to avoid the uncontrolled→controlled MUI warning\r\n // Initialize directly from value.values so pre-selected values are visible even before fetchOptions resolves\r\n const [checkedValues, setCheckedValues] = useState<TFieldValid[]>(() => {\r\n return Array.isArray(value.values) ? [...value.values] : []\r\n })\r\n\r\n const appliedValues = Array.isArray(value.values) ? value.values : []\r\n const hasLogicChange = filterLogic !== value.logic\r\n const hasDataChange = checkedValues.length !== appliedValues.length || checkedValues.some((v) => !appliedValues.includes(v))\r\n const isApplyDisabled = !hasDataChange && !hasLogicChange\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\r\n if (!hasDataChange) {\r\n if (hasLogicChange) handleSubmit({ values: value.values, logic: effectiveLogic })\r\n return\r\n }\r\n\r\n if (isMaxReached) return\r\n\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: effectiveLogic }\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 isMaxReached = params?.maxValueCount != null && checkedValues.length > params.maxValueCount\r\n const isMaxReachedValid = params?.maxValueCount != null && checkedValues.length >= params.maxValueCount\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n if (params?.config?.closeAfterClear !== false) props.onClose()\r\n }\r\n\r\n const getMaxReachedText = () => {\r\n if (!params?.maxValueCount) return ''\r\n if (isMaxReached) {\r\n return `Maximum ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} selected (limit reached)`\r\n } else {\r\n return `Up to ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} can be selected`\r\n }\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (params?.forceLogic) return null\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={effectiveLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading || fetchStatus === 'loading') 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 {mergedConfig.description && (\r\n <Typography variant='caption' color='text.secondary' sx={{ mb: 1, display: 'block' }}>\r\n {mergedConfig.description}\r\n </Typography>\r\n )}\r\n {params?.maxValueCount != null && (\r\n <Typography variant='caption' color={isMaxReached ? 'warning.main' : 'text.secondary'} sx={{ mb: 0.5, display: 'block' }}>\r\n {getMaxReachedText()}\r\n </Typography>\r\n )}\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 {fetchStatus === 'loading' && (\r\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: 2 }}>\r\n <CircularProgress size={20} />\r\n </Box>\r\n )}\r\n {fetchStatus === 'error' && (\r\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', mt: 2, mb: 3, gap: 1 }}>\r\n <InfoIcon color='error' fontSize='large' />\r\n <Typography variant='body2' color='error'>\r\n Failed to load options\r\n </Typography>\r\n <Button size='small' variant='outlined' color='error' onClick={runFetch}>\r\n Retry\r\n </Button>\r\n </Box>\r\n )}\r\n {options.length === 0 && fetchStatus === 'loaded' && (\r\n <Typography variant='body2' color='text.secondary' sx={{ mt: 2 }}>\r\n No options available\r\n </Typography>\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 isSelected = filterViewerValue.items.some((item) => item.value === x.value)\r\n const disabled = isSelected && params?.disabledAfterSubmit === true\r\n const disableDueToMax = !isChecked && isMaxReachedValid\r\n return (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n disabled={disabled || disableDueToMax}\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' disabled={isApplyDisabled}>\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.12)',\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","staticOptions","props","_mergedConfig$default","_params$forceLogic","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","effectiveLogic","forceLogic","label","field","toString","_useState3","_useState4","fetchedOptions","setFetchedOptions","_useState5","fetchOptions","_useState6","fetchStatus","setFetchStatus","abortRef","useRef","runFetch","_abortRef$current","current","abort","controller","AbortController","signal","then","data","err","_props$onError","onError","call","name","useEffect","_abortRef$current2","_useState7","Array","isArray","_toConsumableArray","_useState8","checkedValues","setCheckedValues","appliedValues","hasLogicChange","hasDataChange","length","some","v","includes","isApplyDisabled","_useState9","_useState0","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","map","_options$find","find","o","isMaxReached","maxValueCount","isMaxReachedValid","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","obj","_defineProperty","validator","run","keys","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","PopperBody","description","Typography","variant","color","mb","display","borderBottom","placement","enableMinimalesticView","onRemove","Box","justifyContent","mt","CircularProgress","flexDirection","alignItems","gap","InfoIcon","fontSize","Button","FormGroup","error","x","i","_x$label","isChecked","disabled","item","disabledAfterSubmit","disableDueToMax","FormControlLabel","control","Checkbox","checked","e","optionValue","target","prev","filter","PopperFooter","_props$onRemoveField","_params$config","onRemoveField","closeAfterClear","flex","type","styled","position","content","inset","backgroundColor","zIndex","opacity","transition","visibility","pointerEvents"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as r,objectSpread2 as o}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t}from"react/jsx-runtime";import{useState as e}from"react";import{ErrorPannel as i}from"./ui.units.js";import n from"./create-form-field-select.js";import f from"./create-form-field-select-multiple.js";import a from"./create-form-field-string.js";function c(f){var c=n(f),m=a({config:f.config,top:t(i,{})});return function(i){var n=e("loading"),f=r(n,2),a=f[0],u=f[1];return"loading"===a?t(c,o(o({},i),{},{onError:function(){return u("error")}})):t(m,o({},i))}}function m(n){var c=f(n),m=a({config:n.config,top:t(i,{})});return function(i){var n=e("loading"),f=r(n,2),a=f[0],u=f[1];return"loading"===a?t(c,o(o({},i),{},{onError:function(){return u("error")}})):t(m,o({},i))}}export{m as createFormFieldSelectMultipleWithFallback,c as createFormFieldSelectWithFallback};
2
+ //# sourceMappingURL=create-form-field-select.fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form-field-select.fallback.js","sources":["../../../../src/filter-bar/menu/create-form-field-select.fallback.tsx"],"sourcesContent":["import { FC, useState } from 'react'\r\nimport { TFetchStatus } from './types'\r\nimport { ErrorPannel } from './ui.units'\r\nimport createFormFieldSelect, { IFormFieldSelectParam } from './create-form-field-select'\r\nimport createFormFieldSelectMultiple, { IFormFieldSelectMultipleParam } from './create-form-field-select-multiple'\r\nimport createFormFieldString from './create-form-field-string'\r\n\r\nexport function createFormFieldSelectWithFallback<T>(params: IFormFieldSelectParam<T>) {\r\n const NormalComponent = createFormFieldSelect<T>(params)\r\n const DefaultComponent = createFormFieldString<T>({ config: params.config, top: <ErrorPannel /> })\r\n\r\n const FormFieldSelectWithFallback: FC<any> = (props) => {\r\n const [status, setStatus] = useState<TFetchStatus>('loading')\r\n if (status === 'loading') {\r\n return <NormalComponent {...props} onError={() => setStatus('error')} />\r\n } else {\r\n return <DefaultComponent {...props} />\r\n }\r\n }\r\n\r\n return FormFieldSelectWithFallback\r\n}\r\n\r\nexport function createFormFieldSelectMultipleWithFallback<T>(params: IFormFieldSelectMultipleParam<T>) {\r\n const NormalComponent = createFormFieldSelectMultiple<T>(params)\r\n const DefaultComponent = createFormFieldString<T>({ config: params.config, top: <ErrorPannel /> })\r\n\r\n const FormFieldSelectMultipleWithFallback: FC<any> = (props) => {\r\n const [status, setStatus] = useState<TFetchStatus>('loading')\r\n if (status === 'loading') {\r\n return <NormalComponent {...props} onError={() => setStatus('error')} />\r\n } else {\r\n return <DefaultComponent {...props} />\r\n }\r\n }\r\n\r\n return FormFieldSelectMultipleWithFallback\r\n}\r\n"],"names":["createFormFieldSelectWithFallback","params","NormalComponent","createFormFieldSelect","DefaultComponent","createFormFieldString","config","top","_jsx","ErrorPannel","props","_useState","useState","_useState2","_slicedToArray","status","setStatus","_objectSpread","onError","createFormFieldSelectMultipleWithFallback","createFormFieldSelectMultiple","_useState3","_useState4"],"mappings":"uWAOM,SAAUA,EAAqCC,GACnD,IAAMC,EAAkBC,EAAyBF,GAC3CG,EAAmBC,EAAyB,CAAEC,OAAQL,EAAOK,OAAQC,IAAKC,EAACC,EAAc,CAAA,KAW/F,OAT6C,SAACC,GAC5C,IAAAC,EAA4BC,EAAuB,WAAUC,EAAAC,EAAAH,EAAA,GAAtDI,EAAMF,EAAA,GAAEG,EAASH,EAAA,GACxB,MAAe,YAAXE,EACKP,EAACN,EAAee,EAAAA,KAAKP,GAAK,GAAA,CAAEQ,QAAS,WAAF,OAAQF,EAAU,QAAQ,KAE7DR,EAACJ,EAAgBa,EAAKP,CAAAA,EAAAA,GAEhC,CAGH,CAEM,SAAUS,EAA6ClB,GAC3D,IAAMC,EAAkBkB,EAAiCnB,GACnDG,EAAmBC,EAAyB,CAAEC,OAAQL,EAAOK,OAAQC,IAAKC,EAACC,EAAc,CAAA,KAW/F,OATqD,SAACC,GACpD,IAAAW,EAA4BT,EAAuB,WAAUU,EAAAR,EAAAO,EAAA,GAAtDN,EAAMO,EAAA,GAAEN,EAASM,EAAA,GACxB,MAAe,YAAXP,EACKP,EAACN,EAAee,EAAAA,KAAKP,GAAK,GAAA,CAAEQ,QAAS,WAAF,OAAQF,EAAU,QAAQ,KAE7DR,EAACJ,EAAgBa,EAAKP,CAAAA,EAAAA,GAEhC,CAGH"}
@@ -1,2 +1,2 @@
1
- import{defineProperty as e,slicedToArray as l}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,jsxs as n}from"react/jsx-runtime";import{useMemo as i,useState as r,useEffect as t}from"react";import{styled as a,radioGroupClasses as u,Typography as c,Box as s,CircularProgress as d,RadioGroup as m,FormControlLabel as v,Radio as f,Button as p}from"@mui/material";import{getErrorMessage as b}from"../../form/helpers.js";import{createChipViewers as g}from"../components/chip-viewer.js";import{ButtonBack as h,ChipDark as x,FilterLogicToggle as C}from"../components/ui.units.js";import{PopperContent as y,PopperBody as V,PopperFooter as j}from"../components/popper-custom.js";function k(a){var u=g(),k=a.options;return function(g){var A,L,M,O=i(function(){return Object.assign({},g.currentConfig,null==a?void 0:a.config)},[null==a?void 0:a.config,g.currentConfig]),S=g.value,w=void 0===S?{values:[],logic:null!==(A=null==O?void 0:O.defaultLogic)&&void 0!==A?A:"or"}:S,F=r(w.logic),R=l(F,2),B=R[0],N=R[1],T=null!==(L=a.forceLogic)&&void 0!==L?L:B,E=r(null),I=l(E,2),P=I[0],_=I[1],D=r([]),H=l(D,2),U=H[0],q=H[1],G=r(!1),J=l(G,2),K=J[0],Q=J[1];t(function(){if(a.fetchOptions){var e=new AbortController;return Q(!0),a.fetchOptions(e.signal).then(q).catch(function(e){"AbortError"!==(null==e?void 0:e.name)&&console.error(e)}).finally(function(){return Q(!1)}),function(){return e.abort()}}},[]);var W=a.fetchOptions?U:null!=k?k:[],X=B!==w.logic,Y=null!==P,Z=!Y&&!X,$=null!==(M=null==O?void 0:O.label)&&void 0!==M?M:O.field.toString(),ee=r({}),le=l(ee,2),oe=le[0],ne=le[1],ie=function(e){g.onSubmit(O.field,e,O)},re=b(oe,O.field),te=i(function(){var e=Array.isArray(w.values)?w.values:[w.values];return{field:O.field,items:e.map(function(e){var l;return{value:e,label:null===(l=W.find(function(l){return l.value===e}))||void 0===l?void 0:l.label}})}},[O.field,w,W]),ae=null!=a.maxValueCount&&te.items.length>=a.maxValueCount,ue=[];return(g.isLoading||K)&&ue.push("disabled"),o(z,{className:ue.join(" "),noValidate:!0,onSubmit:function(l){var o;if(l.preventDefault(),Y){if(!ae){var n=e({},O.field,P),i=null===(o=g.validator)||void 0===o?void 0:o.run(n);if(ne(i||{}),!i||0===Object.keys(i).length)ie({values:[P],logic:T}),_(null)}}else X&&ie({values:w.values,logic:T})},children:n(y,{title:"Filter by ".concat($),onClose:g.onClose,slots:{beforeTitle:o(h,{size:"small",onClick:g.onBack}),afterTitle:a.forceLogic?null:O.singleValue?o(x,{sx:{ml:1.5},size:"small",label:"Last value only"}):o(C,{sx:{ml:1},value:T,onChange:function(e,l){N(l)}})},children:[n(V,{children:[O.description&&o(c,{variant:"caption",color:"text.secondary",sx:{mb:1,display:"block"},children:O.description}),null!=a.maxValueCount&&o(c,{variant:"caption",color:ae?"warning.main":"text.secondary",sx:{mb:.5,display:"block"},children:a.maxValueCount?ae?"Maximum ".concat(a.maxValueCount," value").concat(a.maxValueCount>1?"s":""," selected (limit reached)"):"Up to ".concat(a.maxValueCount," value").concat(a.maxValueCount>1?"s":""," can be selected"):""}),o(u,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:te,onRemove:g.onRemove}),0===W.length&&K&&o(s,{sx:{display:"flex",justifyContent:"center",mt:2},children:o(d,{size:20})}),0===W.length&&!K&&o(c,{variant:"body2",color:"text.secondary",sx:{mt:2},children:"No options available"}),o(m,{sx:{mx:-1},name:O.field.toString(),value:null!=P?P:"",onChange:function(e){return _(e.target.value)},className:re.error?"error":"",children:W.map(function(e,l){var n,i=te.items.some(function(l){return l.value===e.value});return o(v,{disabled:i||ae,value:e.value,control:o(f,{size:"small"}),label:o(c,{variant:"body2",children:null!==(n=e.label)&&void 0!==n?n:e.value})},e.value.toString()+l)})}),re.error&&o(c,{variant:"caption",color:"error",sx:{mt:.5},children:re.message})]}),n(j,{children:[o(p,{size:"small",color:"error",variant:"text",disabled:!w.values||0===w.values.length,onClick:function(){var e,l;null===(e=g.onRemoveField)||void 0===e||e.call(g,O.field),!1!==(null==a||null===(l=a.config)||void 0===l?void 0:l.closeAfterClear)&&g.onClose()},children:"Clear All"}),o(s,{sx:{flex:1}}),o(p,{size:"small",color:"inherit",variant:"text",onClick:g.onClose,children:"Cancel"}),o(p,{size:"small",type:"submit",color:"primary",variant:"contained",disabled:Z,children:"Apply"})]})]})})}}var z=a("form")(e({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.12)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}},".".concat(u.root),{"&.error .MuiRadio-root":{color:"#d32f2f"},".MuiFormControlLabel-root":{margin:0},".MuiFormControlLabel-root:hover":{backgroundColor:"rgba(25, 118, 210, 0.04)"}}));export{k as default};
1
+ import{defineProperty as l,slicedToArray as o}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as e,jsxs as n}from"react/jsx-runtime";import{useMemo as i,useState as r,useRef as t,useEffect as a}from"react";import{styled as c,radioGroupClasses as u,Typography as s,Box as d,CircularProgress as m,Button as v,RadioGroup as f,FormControlLabel as p,Radio as b}from"@mui/material";import g from"@mui/icons-material/Info";import{getErrorMessage as h}from"../../form/helpers.js";import{createChipViewers as x}from"../components/chip-viewer.js";import{ButtonBack as C,ChipDark as y,FilterLogicToggle as z}from"../components/ui.units.js";import{PopperContent as k,PopperBody as V,PopperFooter as j}from"../components/popper-custom.js";function A(c){var u=x(),A=c.options;return function(x){var O,S,F,M=i(function(){return Object.assign({},x.currentConfig,null==c?void 0:c.config)},[null==c?void 0:c.config,x.currentConfig]),R=x.value,w=void 0===R?{values:[],logic:null!==(O=null==M?void 0:M.defaultLogic)&&void 0!==O?O:"or"}:R,I=r(w.logic),B=o(I,2),E=B[0],N=B[1],T=null!==(S=c.forceLogic)&&void 0!==S?S:E,D=r(null),P=o(D,2),_=P[0],H=P[1],U=r([]),q=o(U,2),G=q[0],J=q[1],K=r(c.fetchOptions?"loading":"loaded"),Q=o(K,2),W=Q[0],X=Q[1],Y=t(null),Z=function(){var l;if(c.fetchOptions){null===(l=Y.current)||void 0===l||l.abort();var o=new AbortController;Y.current=o,X("loading"),c.fetchOptions(o.signal).then(function(l){J(l),X("loaded")}).catch(function(l){var o;null===(o=x.onError)||void 0===o||o.call(x),"AbortError"!==(null==l?void 0:l.name)&&X("error")})}};a(function(){return Z(),function(){var l;return null===(l=Y.current)||void 0===l?void 0:l.abort()}},[]);var $=c.fetchOptions?G:null!=A?A:[],ll=E!==w.logic,ol=null!==_,el=!ol&&!ll,nl=null!==(F=null==M?void 0:M.label)&&void 0!==F?F:M.field.toString(),il=r({}),rl=o(il,2),tl=rl[0],al=rl[1],cl=function(l){x.onSubmit(M.field,l,M)},ul=h(tl,M.field),sl=i(function(){var l=Array.isArray(w.values)?w.values:[w.values];return{field:M.field,items:l.map(function(l){var o;return{value:l,label:null===(o=$.find(function(o){return o.value===l}))||void 0===o?void 0:o.label}})}},[M.field,w,$]),dl=null!=c.maxValueCount&&sl.items.length>=c.maxValueCount,ml=[];return(x.isLoading||"loading"===W)&&ml.push("disabled"),e(L,{className:ml.join(" "),noValidate:!0,onSubmit:function(o){var e;if(o.preventDefault(),ol){if(!dl){var n=l({},M.field,_),i=null===(e=x.validator)||void 0===e?void 0:e.run(n);if(al(i||{}),!i||0===Object.keys(i).length)cl({values:[_],logic:T}),H(null)}}else ll&&cl({values:w.values,logic:T})},children:n(k,{title:"Filter by ".concat(nl),onClose:x.onClose,slots:{beforeTitle:e(C,{size:"small",onClick:x.onBack}),afterTitle:c.forceLogic?null:M.singleValue?e(y,{sx:{ml:1.5},size:"small",label:"Last value only"}):e(z,{sx:{ml:1},value:T,onChange:function(l,o){N(o)}})},children:[n(V,{children:[M.description&&e(s,{variant:"caption",color:"text.secondary",sx:{mb:1,display:"block"},children:M.description}),null!=c.maxValueCount&&e(s,{variant:"caption",color:dl?"warning.main":"text.secondary",sx:{mb:.5,display:"block"},children:c.maxValueCount?dl?"Maximum ".concat(c.maxValueCount," value").concat(c.maxValueCount>1?"s":""," selected (limit reached)"):"Up to ".concat(c.maxValueCount," value").concat(c.maxValueCount>1?"s":""," can be selected"):""}),e(u,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:sl,onRemove:x.onRemove}),"loading"===W&&e(d,{sx:{display:"flex",justifyContent:"center",mt:2},children:e(m,{size:20})}),"error"===W&&n(d,{sx:{display:"flex",flexDirection:"column",alignItems:"center",mt:2,mb:3,gap:1},children:[e(g,{color:"error",fontSize:"large"}),e(s,{variant:"body2",color:"error",children:"Failed to load options"}),e(v,{size:"small",variant:"outlined",color:"error",onClick:Z,children:"Retry"})]}),0===$.length&&"loaded"===W&&e(s,{variant:"body2",color:"text.secondary",sx:{mt:2},children:"No options available"}),e(f,{sx:{mx:-1},name:M.field.toString(),value:null!=_?_:"",onChange:function(l){return H(l.target.value)},className:ul.error?"error":"",children:$.map(function(l,o){var n,i=sl.items.some(function(o){return o.value===l.value});return e(p,{disabled:i||dl,value:l.value,control:e(b,{size:"small"}),label:e(s,{variant:"body2",children:null!==(n=l.label)&&void 0!==n?n:l.value})},l.value.toString()+o)})}),ul.error&&e(s,{variant:"caption",color:"error",sx:{mt:.5},children:ul.message})]}),n(j,{children:[e(v,{size:"small",color:"error",variant:"text",disabled:!w.values||0===w.values.length,onClick:function(){var l,o;null===(l=x.onRemoveField)||void 0===l||l.call(x,M.field),!1!==(null==c||null===(o=c.config)||void 0===o?void 0:o.closeAfterClear)&&x.onClose()},children:"Clear All"}),e(d,{sx:{flex:1}}),e(v,{size:"small",color:"inherit",variant:"text",onClick:x.onClose,children:"Cancel"}),e(v,{size:"small",type:"submit",color:"primary",variant:"contained",disabled:el,children:"Apply"})]})]})})}}var L=c("form")(l({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.12)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}},".".concat(u.root),{"&.error .MuiRadio-root":{color:"#d32f2f"},".MuiFormControlLabel-root":{margin:0},".MuiFormControlLabel-root:hover":{backgroundColor:"rgba(25, 118, 210, 0.04)"}}));export{A 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 { FC, useEffect, useMemo, useState } from 'react'\r\nimport { Box, Button, CircularProgress, FormControlLabel, Radio, RadioGroup, radioGroupClasses, styled, Typography } from '@mui/material'\r\nimport { 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 /** Function to fetch options asynchronously based on user input */\r\n fetchOptions?: (signal?: AbortSignal) => Promise<IFieldSelectOption[]>\r\n /** Force a specific logic (and/or) for this field, overriding the default or user-selected logic */\r\n forceLogic?: TLogic\r\n /** Maximum number of values that can be selected for this field */\r\n maxValueCount?: number\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 const effectiveLogic = params.forceLogic ?? filterLogic\r\n const [selectedValue, setSelectedValue] = useState<TFieldValid | null>(null)\r\n const [fetchedOptions, setFetchedOptions] = useState<IFieldSelectOption[]>([])\r\n const [isFetchLoading, setIsFetchLoading] = useState(false)\r\n\r\n useEffect(() => {\r\n if (!params.fetchOptions) return\r\n const controller = new AbortController()\r\n setIsFetchLoading(true)\r\n params\r\n .fetchOptions(controller.signal)\r\n .then(setFetchedOptions)\r\n .catch((err) => {\r\n if (err?.name !== 'AbortError') console.error(err)\r\n })\r\n .finally(() => setIsFetchLoading(false))\r\n return () => controller.abort()\r\n }, [])\r\n\r\n const effectiveOptions = params.fetchOptions ? fetchedOptions : (options ?? [])\r\n const hasLogicChange = filterLogic !== value.logic\r\n const hasDataChange = selectedValue !== null\r\n const isApplyDisabled = !hasDataChange && !hasLogicChange\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\r\n if (!hasDataChange) {\r\n if (hasLogicChange) {\r\n handleSubmit({ values: value.values, logic: effectiveLogic })\r\n }\r\n return\r\n }\r\n\r\n if (isMaxReached) return\r\n\r\n const obj = { [mergedConfig.field]: selectedValue } 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: [selectedValue!] as TFieldValid[], logic: effectiveLogic }\r\n handleSubmit(newValue)\r\n setSelectedValue(null)\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: effectiveOptions.find((o) => o.value === v)?.label }))\r\n }\r\n }, [mergedConfig.field, value, effectiveOptions])\r\n\r\n const isMaxReached = params.maxValueCount != null && filterViewerValue.items.length >= params.maxValueCount\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n if (params?.config?.closeAfterClear !== false) props.onClose()\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (params.forceLogic) return null\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={effectiveLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const getMaxReachedText = () => {\r\n if (!params.maxValueCount) return ''\r\n if (isMaxReached) {\r\n return `Maximum ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} selected (limit reached)`\r\n } else {\r\n return `Up to ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} can be selected`\r\n }\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading || isFetchLoading) 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 {mergedConfig.description && (\r\n <Typography variant='caption' color='text.secondary' sx={{ mb: 1, display: 'block' }}>\r\n {mergedConfig.description}\r\n </Typography>\r\n )}\r\n {params.maxValueCount != null && (\r\n <Typography variant='caption' color={isMaxReached ? 'warning.main' : 'text.secondary'} sx={{ mb: 0.5, display: 'block' }}>\r\n {getMaxReachedText()}\r\n </Typography>\r\n )}\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 {effectiveOptions.length === 0 && isFetchLoading && (\r\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: 2 }}>\r\n <CircularProgress size={20} />\r\n </Box>\r\n )}\r\n {effectiveOptions.length === 0 && !isFetchLoading && (\r\n <Typography variant='body2' color='text.secondary' sx={{ mt: 2 }}>\r\n No options available\r\n </Typography>\r\n )}\r\n <RadioGroup\r\n sx={{ mx: -1 }}\r\n name={mergedConfig.field.toString()}\r\n value={selectedValue ?? ''}\r\n onChange={(e) => setSelectedValue(e.target.value as TFieldValid)}\r\n className={errorResult.error ? 'error' : ''}\r\n >\r\n {effectiveOptions.map((x, i) => {\r\n const isSelected = filterViewerValue.items.some((item) => item.value === x.value)\r\n const disabled = isSelected || isMaxReached\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' disabled={isApplyDisabled}>\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.12)',\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","_params$forceLogic","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","effectiveLogic","forceLogic","_useState3","_useState4","selectedValue","setSelectedValue","_useState5","_useState6","fetchedOptions","setFetchedOptions","_useState7","_useState8","isFetchLoading","setIsFetchLoading","useEffect","fetchOptions","controller","AbortController","signal","then","err","name","console","error","abort","effectiveOptions","hasLogicChange","hasDataChange","isApplyDisabled","label","field","toString","_useState9","_useState0","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","_effectiveOptions$fin","find","o","isMaxReached","maxValueCount","length","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","obj","_defineProperty","validator","run","keys","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","PopperBody","description","Typography","variant","color","mb","display","borderBottom","placement","enableMinimalesticView","onRemove","Box","justifyContent","mt","CircularProgress","RadioGroup","mx","e","target","x","i","_x$label","isSelected","some","item","FormControlLabel","disabled","control","Radio","message","PopperFooter","Button","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","flex","type","styled","position","content","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, useEffect, useMemo, useRef, useState } from 'react'\r\nimport { Box, Button, CircularProgress, FormControlLabel, Radio, RadioGroup, radioGroupClasses, styled, Typography } from '@mui/material'\r\nimport InfoIcon from '@mui/icons-material/Info'\r\nimport { 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 { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps, TFetchStatus } 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 onError?: () => void\r\n}\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 IFormFieldSelectParam<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 /** Function to fetch options asynchronously based on user input */\r\n fetchOptions?: (signal?: AbortSignal) => Promise<IFieldSelectOption[]>\r\n /** Force a specific logic (and/or) for this field, overriding the default or user-selected logic */\r\n forceLogic?: TLogic\r\n /** Maximum number of values that can be selected for this field */\r\n maxValueCount?: number\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: IFormFieldSelectParam<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 const effectiveLogic = params.forceLogic ?? filterLogic\r\n const [selectedValue, setSelectedValue] = useState<TFieldValid | null>(null)\r\n const [fetchedOptions, setFetchedOptions] = useState<IFieldSelectOption[]>([])\r\n const [fetchStatus, setFetchStatus] = useState<TFetchStatus>(params.fetchOptions ? 'loading' : 'loaded')\r\n const abortRef = useRef<AbortController | null>(null)\r\n\r\n const runFetch = () => {\r\n if (!params.fetchOptions) return\r\n abortRef.current?.abort()\r\n const controller = new AbortController()\r\n abortRef.current = controller\r\n setFetchStatus('loading')\r\n params\r\n .fetchOptions(controller.signal)\r\n .then((data) => {\r\n setFetchedOptions(data)\r\n setFetchStatus('loaded')\r\n })\r\n .catch((err) => {\r\n props.onError?.()\r\n if (err?.name !== 'AbortError') setFetchStatus('error')\r\n })\r\n }\r\n\r\n useEffect(() => {\r\n runFetch()\r\n return () => abortRef.current?.abort()\r\n }, [])\r\n\r\n const effectiveOptions = params.fetchOptions ? fetchedOptions : (options ?? [])\r\n const hasLogicChange = filterLogic !== value.logic\r\n const hasDataChange = selectedValue !== null\r\n const isApplyDisabled = !hasDataChange && !hasLogicChange\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\r\n if (!hasDataChange) {\r\n if (hasLogicChange) {\r\n handleSubmit({ values: value.values, logic: effectiveLogic })\r\n }\r\n return\r\n }\r\n\r\n if (isMaxReached) return\r\n\r\n const obj = { [mergedConfig.field]: selectedValue } 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: [selectedValue!] as TFieldValid[], logic: effectiveLogic }\r\n handleSubmit(newValue)\r\n setSelectedValue(null)\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: effectiveOptions.find((o) => o.value === v)?.label }))\r\n }\r\n }, [mergedConfig.field, value, effectiveOptions])\r\n\r\n const isMaxReached = params.maxValueCount != null && filterViewerValue.items.length >= params.maxValueCount\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n if (params?.config?.closeAfterClear !== false) props.onClose()\r\n }\r\n\r\n const renderAfterTitle = () => {\r\n if (params.forceLogic) return null\r\n if (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={effectiveLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const getMaxReachedText = () => {\r\n if (!params.maxValueCount) return ''\r\n if (isMaxReached) {\r\n return `Maximum ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} selected (limit reached)`\r\n } else {\r\n return `Up to ${params.maxValueCount} value${params.maxValueCount > 1 ? 's' : ''} can be selected`\r\n }\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading || fetchStatus === 'loading') 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 {mergedConfig.description && (\r\n <Typography variant='caption' color='text.secondary' sx={{ mb: 1, display: 'block' }}>\r\n {mergedConfig.description}\r\n </Typography>\r\n )}\r\n {params.maxValueCount != null && (\r\n <Typography variant='caption' color={isMaxReached ? 'warning.main' : 'text.secondary'} sx={{ mb: 0.5, display: 'block' }}>\r\n {getMaxReachedText()}\r\n </Typography>\r\n )}\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 {fetchStatus === 'loading' && (\r\n <Box sx={{ display: 'flex', justifyContent: 'center', mt: 2 }}>\r\n <CircularProgress size={20} />\r\n </Box>\r\n )}\r\n {fetchStatus === 'error' && (\r\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', mt: 2, mb: 3, gap: 1 }}>\r\n <InfoIcon color='error' fontSize='large' />\r\n <Typography variant='body2' color='error'>\r\n Failed to load options\r\n </Typography>\r\n <Button size='small' variant='outlined' color='error' onClick={runFetch}>\r\n Retry\r\n </Button>\r\n </Box>\r\n )}\r\n {effectiveOptions.length === 0 && fetchStatus === 'loaded' && (\r\n <Typography variant='body2' color='text.secondary' sx={{ mt: 2 }}>\r\n No options available\r\n </Typography>\r\n )}\r\n <RadioGroup\r\n sx={{ mx: -1 }}\r\n name={mergedConfig.field.toString()}\r\n value={selectedValue ?? ''}\r\n onChange={(e) => setSelectedValue(e.target.value as TFieldValid)}\r\n className={errorResult.error ? 'error' : ''}\r\n >\r\n {effectiveOptions.map((x, i) => {\r\n const isSelected = filterViewerValue.items.some((item) => item.value === x.value)\r\n const disabled = isSelected || isMaxReached\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' disabled={isApplyDisabled}>\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.12)',\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","_params$forceLogic","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","effectiveLogic","forceLogic","_useState3","_useState4","selectedValue","setSelectedValue","_useState5","_useState6","fetchedOptions","setFetchedOptions","_useState7","fetchOptions","_useState8","fetchStatus","setFetchStatus","abortRef","useRef","runFetch","_abortRef$current","current","abort","controller","AbortController","signal","then","data","err","_props$onError","onError","call","name","useEffect","_abortRef$current2","effectiveOptions","hasLogicChange","hasDataChange","isApplyDisabled","label","field","toString","_useState9","_useState0","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","_effectiveOptions$fin","find","o","isMaxReached","maxValueCount","length","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","obj","_defineProperty","validator","run","keys","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","PopperBody","description","Typography","variant","color","mb","display","borderBottom","placement","enableMinimalesticView","onRemove","Box","justifyContent","mt","CircularProgress","flexDirection","alignItems","gap","InfoIcon","fontSize","Button","RadioGroup","mx","e","target","error","x","i","_x$label","isSelected","some","item","FormControlLabel","disabled","control","Radio","message","PopperFooter","_props$onRemoveField","_params$config","onRemoveField","closeAfterClear","flex","type","styled","position","content","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents","radioGroupClasses","root","margin"],"mappings":"suBAkDA,SAASA,EAAyBC,GAChC,IAAMC,EAAcC,IACZC,EAAYH,EAAZG,QAgNR,OA9MsD,SAACC,GAAS,IAAAC,EAAAC,EAAAC,EAKxDC,EAAeC,EAAQ,WAAA,OAAMC,OAAOC,OAAO,GAAIP,EAAMQ,cAAeZ,eAAAA,EAAQa,OAAO,EAAE,CAACb,aAAAA,EAAAA,EAAQa,OAAQT,EAAMQ,gBAElHE,EAA8EV,EAAtEW,MAAAA,OAAQ,IAAHD,EAAG,CAAEE,OAAQ,GAAIC,MAAiC,QAA5BZ,EAAEG,aAAY,EAAZA,EAAcU,oBAAY,IAAAb,EAAAA,EAAI,MAAMS,EACzEK,EAAsCC,EAAiBL,EAAME,OAAOI,EAAAC,EAAAH,EAAA,GAA7DI,EAAWF,EAAA,GAAEG,EAAcH,EAAA,GAC5BI,EAAkC,QAApBnB,EAAGN,EAAO0B,kBAAU,IAAApB,EAAAA,EAAIiB,EAC5CI,EAA0CP,EAA6B,MAAKQ,EAAAN,EAAAK,EAAA,GAArEE,EAAaD,EAAA,GAAEE,EAAgBF,EAAA,GACtCG,EAA4CX,EAA+B,IAAGY,EAAAV,EAAAS,EAAA,GAAvEE,EAAcD,EAAA,GAAEE,EAAiBF,EAAA,GACxCG,EAAsCf,EAAuBpB,EAAOoC,aAAe,UAAY,UAASC,EAAAf,EAAAa,EAAA,GAAjGG,EAAWD,EAAA,GAAEE,EAAcF,EAAA,GAC5BG,EAAWC,EAA+B,MAE1CC,EAAW,WAAK,IAAAC,EACpB,GAAK3C,EAAOoC,aAAZ,CACgB,QAAhBO,EAAAH,EAASI,eAAO,IAAAD,GAAhBA,EAAkBE,QAClB,IAAMC,EAAa,IAAIC,gBACvBP,EAASI,QAAUE,EACnBP,EAAe,WACfvC,EACGoC,aAAaU,EAAWE,QACxBC,KAAK,SAACC,GACLhB,EAAkBgB,GAClBX,EAAe,SACjB,GAAE,MACK,SAACY,GAAO,IAAAC,EACA,QAAbA,EAAAhD,EAAMiD,eAAO,IAAAD,GAAbA,EAAAE,KAAAlD,GACkB,gBAAd+C,eAAAA,EAAKI,OAAuBhB,EAAe,QACjD,EAdwB,CAe3B,EAEDiB,EAAU,WAER,OADAd,IACO,WAAA,IAAAe,EAAA,OAAsB,QAAtBA,EAAMjB,EAASI,eAAO,IAAAa,OAAA,EAAhBA,EAAkBZ,OAAO,CACvC,EAAE,IAEH,IAAMa,EAAmB1D,EAAOoC,aAAeH,EAAkB9B,QAAAA,EAAW,GACtEwD,GAAiBpC,IAAgBR,EAAME,MACvC2C,GAAkC,OAAlB/B,EAChBgC,IAAmBD,KAAkBD,GAErCG,WAAKvD,EAAGC,aAAAA,EAAAA,EAAcsD,aAAK,IAAAvD,EAAAA,EAAIC,EAAauD,MAAMC,WAExDC,GAAkC7C,EAA6C,IAAG8C,GAAA5C,EAAA2C,GAAA,GAA3EE,GAASD,GAAA,GAAEE,GAAYF,GAAA,GACxBG,GAAe,SAACC,GACpBlE,EAAMmE,SAAS/D,EAAauD,MAAOO,EAAU9D,EAC9C,EA0BKgE,GAAcC,EAAgBN,GAAW3D,EAAauD,OACtDW,GAAoBjE,EAA6B,WACrD,IAAMkE,EAAQC,MAAMC,QAAQ9D,EAAMC,QAAUD,EAAMC,OAAS,CAACD,EAAMC,QAClE,MAAO,CACL+C,MAAOvD,EAAauD,MACpBY,MAAOA,EAAMG,IAAI,SAACC,GAAC,IAAAC,EAAA,MAAM,CAAEjE,MAAOgE,EAAGjB,MAAkDkB,QAA7CA,EAAEtB,EAAiBuB,KAAK,SAACC,GAAC,OAAKA,EAAEnE,QAAUgE,CAAC,UAA1CC,IAA2CA,OAA3CA,EAAAA,EAA6ClB,MAAQ,GAEpG,EAAE,CAACtD,EAAauD,MAAOhD,EAAO2C,IAEzByB,GAAuC,MAAxBnF,EAAOoF,eAAyBV,GAAkBC,MAAMU,QAAUrF,EAAOoF,cA0BxFE,GAAwB,GAG9B,OAFIlF,EAAMmF,WAA6B,YAAhBjD,IAA2BgD,GAAYE,KAAK,YAGjEC,EAACC,EAAU,CAACC,UAAWL,GAAYM,KAAK,KAAMC,cAAWtB,SA/DlC,SAACuB,GAA2C,IAAAC,EAGnE,GAFAD,EAAME,iBAEDpC,IAOL,IAAIuB,GAAJ,CAEA,IAAMc,EAAGC,EAAA,CAAA,EAAM1F,EAAauD,MAAQlC,GAChCsC,EAA2B4B,QAAlBA,EAAG3F,EAAM+F,qBAASJ,SAAfA,EAAiBK,IAAIH,GAIrC,GAFA7B,GAAaD,GAAa,KAErBA,GAA+C,IAAlCzD,OAAO2F,KAAKlC,GAAWkB,OAEvChB,GAD8B,CAAErD,OAAQ,CAACa,GAAkCZ,MAAOQ,IAElFK,EAAiB,KAVD,OANZ6B,IACFU,GAAa,CAAErD,OAAQD,EAAMC,OAAQC,MAAOQ,GAiBjD,EAyCoF6E,SACjFC,EAACC,EAAa,CACZC,MAAKC,aAAAA,OAAe5C,IACpB6C,QAASvG,EAAMuG,QACfC,MAAO,CACLC,YAAapB,EAACqB,EAAU,CAACC,KAAK,QAAQC,QAAS5G,EAAM6G,SACrDC,WAxBFlH,EAAO0B,WAAmB,KAC1BlB,EAAa2G,YAAoB1B,EAAC2B,EAAQ,CAACC,GAAI,CAAEC,GAAI,KAAOP,KAAK,QAAQjD,MAAM,oBAC5E2B,EAAC8B,EAAkB,CAAAF,GAAI,CAAEC,GAAI,GAAKvG,MAAOU,EAAgB+F,SAAU,SAACC,EAAGC,GAX9ElG,EAWyGkG,EAAK,KAuBzGpB,SAAA,CAEDC,EAACoB,EAAU,CAAArB,SAAA,CACR9F,EAAaoH,aACZnC,EAACoC,GAAWC,QAAQ,UAAUC,MAAM,iBAAiBV,GAAI,CAAEW,GAAI,EAAGC,QAAS,kBACxEzH,EAAaoH,cAGO,MAAxB5H,EAAOoF,eACNK,EAACoC,GAAWC,QAAQ,UAAUC,MAAO5C,GAAe,eAAiB,iBAAkBkC,GAAI,CAAEW,GAAI,GAAKC,QAAS,SAAS3B,SA5B3HtG,EAAOoF,cACRD,GACF,WAAAuB,OAAkB1G,EAAOoF,wBAAasB,OAAS1G,EAAOoF,cAAgB,EAAI,IAAM,GAAE,6BAElF,SAAAsB,OAAgB1G,EAAOoF,wBAAasB,OAAS1G,EAAOoF,cAAgB,EAAI,IAAM,GAAE,oBAJhD,KAgC5BK,EAACxF,EAAW,CACVoH,GAAI,CAAEW,GAAI,EAAGE,aAAc,kBAC3BpE,MAAM,UACNqE,UAAU,aACVC,0BACArH,MAAO2D,GACP2D,SAAUjI,EAAMiI,WAED,YAAhB/F,GACCmD,EAAC6C,EAAI,CAAAjB,GAAI,CAAEY,QAAS,OAAQM,eAAgB,SAAUC,GAAI,GACxDlC,SAAAb,EAACgD,EAAiB,CAAA1B,KAAM,OAGX,UAAhBzE,GACCiE,EAAC+B,EAAI,CAAAjB,GAAI,CAAEY,QAAS,OAAQS,cAAe,SAAUC,WAAY,SAAUH,GAAI,EAAGR,GAAI,EAAGY,IAAK,GAC5FtC,SAAA,CAAAb,EAACoD,EAAS,CAAAd,MAAM,QAAQe,SAAS,UACjCrD,EAACoC,GAAWC,QAAQ,QAAQC,MAAM,4CAGlCtC,EAACsD,EAAM,CAAChC,KAAK,QAAQe,QAAQ,WAAWC,MAAM,QAAQf,QAAStE,EAAQ4D,SAAA,aAK9C,IAA5B5C,EAAiB2B,QAAgC,WAAhB/C,GAChCmD,EAACoC,GAAWC,QAAQ,QAAQC,MAAM,iBAAiBV,GAAI,CAAEmB,GAAI,GAEhDlC,SAAA,yBAEfb,EAACuD,GACC3B,GAAI,CAAE4B,IAAI,GACV1F,KAAM/C,EAAauD,MAAMC,WACzBjD,MAAOc,QAAAA,EAAiB,GACxB2F,SAAU,SAAC0B,GAAC,OAAKpH,EAAiBoH,EAAEC,OAAOpI,MAAqB,EAChE4E,UAAWnB,GAAY4E,MAAQ,QAAU,GAAE9C,SAE1C5C,EAAiBoB,IAAI,SAACuE,EAAGC,GAAK,IAAAC,EACvBC,EAAa9E,GAAkBC,MAAM8E,KAAK,SAACC,GAAI,OAAKA,EAAK3I,QAAUsI,EAAEtI,QAE3E,OACE0E,EAACkE,EACC,CAAAC,SAHaJ,GAAcrE,GAK3BpE,MAAOsI,EAAEtI,MACT8I,QAASpE,EAACqE,EAAK,CAAC/C,KAAK,UACrBjD,MAAO2B,EAACoC,EAAU,CAACC,QAAQ,QAAOxB,SAASiD,QAATA,EAAEF,EAAEvF,aAAKyF,IAAAA,EAAAA,EAAIF,EAAEtI,SAH5CsI,EAAEtI,MAAMiD,WAAasF,EAM/B,KAEF9E,GAAY4E,OACX3D,EAACoC,EAAW,CAAAC,QAAQ,UAAUC,MAAM,QAAQV,GAAI,CAAEmB,GAAI,IAAKlC,SACxD9B,GAAYuF,aAInBxD,EAACyD,EACC,CAAA1D,SAAA,CAAAb,EAACsD,EAAM,CAAChC,KAAK,QAAQgB,MAAM,QAAQD,QAAQ,OAAO8B,UAAW7I,EAAMC,QAAkC,IAAxBD,EAAMC,OAAOqE,OAAc2B,QArGzF,WAAK,IAAAiD,EAAAC,UAC1BD,EAAA7J,EAAM+J,qBAAa,IAAAF,GAAnBA,EAAA3G,KAAAlD,EAAsBI,EAAauD,QACK,KAApC/D,SAAc,QAARkK,EAANlK,EAAQa,cAARqJ,IAAcA,OAAdA,EAAAA,EAAgBE,kBAA2BhK,EAAMuG,SACtD,EAoGgBL,SAAA,cACTb,EAAC6C,EAAI,CAAAjB,GAAI,CAAEgD,KAAM,KACjB5E,EAACsD,EAAM,CAAChC,KAAK,QAAQgB,MAAM,UAAUD,QAAQ,OAAOd,QAAS5G,EAAMuG,QAE1DL,SAAA,WACTb,EAACsD,EAAO,CAAAhC,KAAK,QAAQuD,KAAK,SAASvC,MAAM,UAAUD,QAAQ,YAAY8B,SAAU/F,GAExEyC,SAAA,iBAKlB,CAGH,CAIA,IAAMZ,EAAa6E,EAAO,OAAPA,CAAcrE,EAAA,CAC/BsE,SAAU,WACV,WAAY,CACVC,QAAS,KACTxC,QAAS,QACTuC,SAAU,WACVE,MAAO,EACPC,gBAAiB,sBACjBC,OAAQ,YACRC,QAAU,EACVC,QAAS,EACTC,WAAY,eACZC,WAAY,UAEd,aAAc,CACZC,cAAe,OACf,WAAY,CACVJ,OAAQ,EACRC,QAAS,EACTE,WAAY,aAEf,IAAAtE,OACIwE,EAAkBC,MAAS,CAC9B,yBAA0B,CAAEpD,MAAO,WACnC,4BAA6B,CAAEqD,OAAQ,GACvC,kCAAmC,CAAET,gBAAiB"}
@@ -1,2 +1,2 @@
1
- import{slicedToArray as e}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as i,jsxs as l}from"react/jsx-runtime";import{useMemo as o,useState as r,createRef as n}from"react";import{styled as t,Typography as a,TextField as s,Button as u,Box as c}from"@mui/material";import{createChipViewers as d}from"../components/chip-viewer.js";import{getErrorMessage as m,convertFormDataToJson as v}from"../../form/helpers.js";import{ButtonBack as p,ChipDark as f,FilterLogicToggle as b}from"../components/ui.units.js";import{PopperContent as g,PopperBody as h,PopperFooter as y}from"../components/popper-custom.js";function x(t){var x=d();return function(d){var j,z,A=o(function(){return Object.assign({},d.currentConfig,null==t?void 0:t.config)},[null==t?void 0:t.config,d.currentConfig]),k=n(),T=d.value,B=void 0===T?{values:[],logic:null!==(j=null==A?void 0:A.defaultLogic)&&void 0!==j?j:"or"}:T,F=r(B.logic),R=e(F,2),S=R[0],w=R[1],I=r(""),L=e(I,2),V=L[0],D=L[1],E=null!==(z=null==A?void 0:A.label)&&void 0!==z?z:A.field.toString(),H=r({}),M=e(H,2),O=M[0],P=M[1],_=function(e){d.onSubmit(A.field,e,A)},N=S!==B.logic,W=!V.trim()&&!N,q=m(O,A.field),G=o(function(){var e=Array.isArray(B.values)?B.values:[B.values];return{field:A.field,items:e.map(function(e){return{value:e}})}},[A.field,B]),J=[];return d.isLoading&&J.push("disabled"),i(C,{className:J.join(" "),noValidate:!0,onSubmit:function(e){var i;if(e.preventDefault(),e.stopPropagation(),V.trim()){var l=new FormData(e.currentTarget),o=v(l),r=null===(i=d.validator)||void 0===i?void 0:i.run(o);if(P(r||{}),!r||0===Object.keys(r).length){var n=A.field,t=Array.isArray(o[n])?o[n]:[o[n]];_({values:t,logic:S}),k.current&&(k.current.blur(),k.current.value=""),D("")}}else N&&_({values:B.values,logic:S})},children:l(g,{title:"Filter by ".concat(E),onClose:d.onClose,slots:{beforeTitle:i(p,{size:"small",onClick:d.onBack}),afterTitle:A.singleValue?i(f,{sx:{ml:1.5},size:"small",label:"Last value only"}):i(b,{sx:{ml:1},value:S,onChange:function(e,i){w(i)}})},children:[l(h,{children:[A.description&&i(a,{variant:"caption",color:"text.secondary",sx:{display:"block",mb:1},children:A.description}),i(x,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:G,onRemove:d.onRemove}),i(s,{inputRef:k,autoFocus:!0,name:A.field.toString(),size:"small",fullWidth:!0,placeholder:"Enter value",error:q.error,helperText:q.message,onChange:function(e){return D(e.target.value)},sx:{".MuiInputBase-root":{minHeight:"42px"}}})]}),l(y,{children:[i(u,{size:"small",color:"error",variant:"text",disabled:!B.values||0===B.values.length,onClick:function(){var e,i;null===(e=d.onRemoveField)||void 0===e||e.call(d,A.field),!1!==(null==t||null===(i=t.config)||void 0===i?void 0:i.closeAfterClear)&&d.onClose()},children:"Clear All"}),i(c,{sx:{flex:1}}),i(u,{size:"small",color:"inherit",variant:"text",onClick:d.onClose,children:"Cancel"}),i(u,{size:"small",type:"submit",color:"primary",variant:"contained",disabled:W,children:"Apply"})]})]})})}}var C=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{x as default};
1
+ import{slicedToArray as e}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as i,jsxs as l}from"react/jsx-runtime";import{useMemo as o,useState as r,createRef as n}from"react";import{styled as t,Box as a,Typography as s,TextField as u,Button as c}from"@mui/material";import{createChipViewers as d}from"../components/chip-viewer.js";import{getErrorMessage as m,convertFormDataToJson as v}from"../../form/helpers.js";import{ButtonBack as p,ChipDark as f,FilterLogicToggle as b}from"../components/ui.units.js";import{PopperContent as g,PopperBody as h,PopperFooter as y}from"../components/popper-custom.js";function x(t){var x=d();return function(d){var j,z,A=o(function(){return Object.assign({},d.currentConfig,null==t?void 0:t.config)},[null==t?void 0:t.config,d.currentConfig]),k=n(),T=d.value,B=void 0===T?{values:[],logic:null!==(j=null==A?void 0:A.defaultLogic)&&void 0!==j?j:"or"}:T,F=r(B.logic),R=e(F,2),S=R[0],w=R[1],I=r(""),L=e(I,2),V=L[0],D=L[1],E=null!==(z=null==A?void 0:A.label)&&void 0!==z?z:A.field.toString(),H=r({}),M=e(H,2),O=M[0],P=M[1],_=function(e){d.onSubmit(A.field,e,A)},N=S!==B.logic,W=!V.trim()&&!N,q=m(O,A.field),G=o(function(){var e=Array.isArray(B.values)?B.values:[B.values];return{field:A.field,items:e.map(function(e){return{value:e}})}},[A.field,B]),J=o(function(){var e=(null==t?void 0:t.top)||d.top;return e?i(a,{sx:{mb:1},children:e}):null},[null==t?void 0:t.top,d.top]),K=[];return d.isLoading&&K.push("disabled"),i(C,{className:K.join(" "),noValidate:!0,onSubmit:function(e){var i;if(e.preventDefault(),e.stopPropagation(),V.trim()){var l=new FormData(e.currentTarget),o=v(l),r=null===(i=d.validator)||void 0===i?void 0:i.run(o);if(P(r||{}),!r||0===Object.keys(r).length){var n=A.field,t=Array.isArray(o[n])?o[n]:[o[n]];_({values:t,logic:S}),k.current&&(k.current.blur(),k.current.value=""),D("")}}else N&&_({values:B.values,logic:S})},children:l(g,{title:"Filter by ".concat(E),onClose:d.onClose,slots:{beforeTitle:i(p,{size:"small",onClick:d.onBack}),afterTitle:A.singleValue?i(f,{sx:{ml:1.5},size:"small",label:"Last value only"}):i(b,{sx:{ml:1},value:S,onChange:function(e,i){w(i)}})},children:[l(h,{children:[J,A.description&&i(s,{variant:"caption",color:"text.secondary",sx:{display:"block",mb:1},children:A.description}),i(x,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:G,onRemove:d.onRemove}),i(u,{inputRef:k,autoFocus:!0,name:A.field.toString(),size:"small",fullWidth:!0,placeholder:"Enter value",error:q.error,helperText:q.message,onChange:function(e){return D(e.target.value)},sx:{".MuiInputBase-root":{minHeight:"42px"}}})]}),l(y,{children:[i(c,{size:"small",color:"error",variant:"text",disabled:!B.values||0===B.values.length,onClick:function(){var e,i;null===(e=d.onRemoveField)||void 0===e||e.call(d,A.field),!1!==(null==t||null===(i=t.config)||void 0===i?void 0:i.closeAfterClear)&&d.onClose()},children:"Clear All"}),i(a,{sx:{flex:1}}),i(c,{size:"small",color:"inherit",variant:"text",onClick:d.onClose,children:"Cancel"}),i(c,{size:"small",type:"submit",color:"primary",variant:"contained",disabled:W,children:"Apply"})]})]})})}}var C=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{x 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, Typography } 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 const [inputValue, setInputValue] = useState('')\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 hasLogicChange = filterLogic !== value.logic\r\n const isApplyDisabled = !inputValue.trim() && !hasLogicChange\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n\r\n if (!inputValue.trim()) {\r\n if (hasLogicChange) {\r\n handleSubmit({ values: value.values, logic: filterLogic })\r\n }\r\n return\r\n }\r\n\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 setInputValue('')\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 }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n if (params?.config?.closeAfterClear !== false) props.onClose()\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 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 {mergedConfig.description && (\r\n <Typography variant='caption' color='text.secondary' sx={{ display: 'block', mb: 1 }}>\r\n {mergedConfig.description}\r\n </Typography>\r\n )}\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 onChange={(e) => setInputValue(e.target.value)}\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' disabled={isApplyDisabled}>\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","_useState3","_useState4","inputValue","setInputValue","label","field","toString","_useState5","_useState6","errorData","setErrorData","handleSubmit","newValue","onSubmit","hasLogicChange","isApplyDisabled","trim","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","PopperBody","description","Typography","variant","color","display","mb","borderBottom","placement","enableMinimalesticView","onRemove","TextField","inputRef","autoFocus","name","fullWidth","placeholder","helperText","message","e","target","minHeight","PopperFooter","Button","disabled","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","Box","flex","type","styled","position","content","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, Typography } 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, ReactNode } 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 top?: ReactNode\r\n}\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 top?: ReactNode\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 const [inputValue, setInputValue] = useState('')\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 hasLogicChange = filterLogic !== value.logic\r\n const isApplyDisabled = !inputValue.trim() && !hasLogicChange\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n\r\n if (!inputValue.trim()) {\r\n if (hasLogicChange) {\r\n handleSubmit({ values: value.values, logic: filterLogic })\r\n }\r\n return\r\n }\r\n\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 setInputValue('')\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 }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n if (params?.config?.closeAfterClear !== false) props.onClose()\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 return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const renderTop = useMemo(() => {\r\n const topContent = params?.top || props.top\r\n if (topContent) return <Box sx={{ mb: 1 }}>{topContent}</Box>\r\n return null\r\n }, [params?.top, props.top])\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 {renderTop}\r\n {mergedConfig.description && (\r\n <Typography variant='caption' color='text.secondary' sx={{ display: 'block', mb: 1 }}>\r\n {mergedConfig.description}\r\n </Typography>\r\n )}\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 onChange={(e) => setInputValue(e.target.value)}\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' disabled={isApplyDisabled}>\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","_useState3","_useState4","inputValue","setInputValue","label","field","toString","_useState5","_useState6","errorData","setErrorData","handleSubmit","newValue","onSubmit","hasLogicChange","isApplyDisabled","trim","error","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","renderTop","topContent","top","_jsx","Box","sx","mb","children","rootClasses","isLoading","push","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","stopPropagation","formData","FormData","currentTarget","obj","convertFormDataToJson","validator","run","keys","length","newValues","current","blur","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","ml","FilterLogicToggle","onChange","_","nVal","PopperBody","description","Typography","variant","color","display","borderBottom","placement","enableMinimalesticView","onRemove","TextField","inputRef","autoFocus","name","fullWidth","placeholder","helperText","message","e","target","minHeight","PopperFooter","Button","disabled","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","flex","type","styled","position","content","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{jsxs as r,jsx as o}from"react/jsx-runtime";import{styled as e,Stack as i,alpha as t,Typography as n}from"@mui/material";import a from"@mui/icons-material/Info";var c=function(){return r(l,{children:[o(a,{color:"error"}),o(n,{color:"error",variant:"subtitle1",component:"p",children:"Failed to load options."})]})},l=e(i)(function(r){var o=r.theme;return{alignItems:"center",flexDirection:"row",gap:o.spacing(1),padding:o.spacing(1),backgroundColor:t(o.palette.error.light,.1),borderRadius:o.shape.borderRadius}});export{c as ErrorPannel};
2
+ //# sourceMappingURL=ui.units.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.units.js","sources":["../../../../src/filter-bar/menu/ui.units.tsx"],"sourcesContent":["import { FC } from 'react'\r\nimport { alpha, Stack, styled, Typography } from '@mui/material'\r\nimport InfoIcon from '@mui/icons-material/Info'\r\n\r\nexport const ErrorPannel: FC = () => (\r\n <ErrorPannelStyled>\r\n <InfoIcon color='error' />\r\n <Typography color='error' variant='subtitle1' component='p'>\r\n Failed to load options.\r\n </Typography>\r\n </ErrorPannelStyled>\r\n)\r\n\r\nconst ErrorPannelStyled = styled(Stack)(({ theme }) => ({\r\n alignItems: 'center',\r\n flexDirection: 'row',\r\n gap: theme.spacing(1),\r\n padding: theme.spacing(1),\r\n backgroundColor: alpha(theme.palette.error.light, 0.1),\r\n borderRadius: theme.shape.borderRadius\r\n}))\r\n"],"names":["ErrorPannel","_jsxs","ErrorPannelStyled","_jsx","InfoIcon","color","Typography","variant","component","children","styled","Stack","_ref","theme","alignItems","flexDirection","gap","spacing","padding","backgroundColor","alpha","palette","error","light","borderRadius","shape"],"mappings":"uKAIaA,IAAAA,EAAkB,WAAP,OACtBC,EAACC,aACCC,EAACC,EAAS,CAAAC,MAAM,UAChBF,EAACG,EAAW,CAAAD,MAAM,QAAQE,QAAQ,YAAYC,UAAU,IAE3CC,SAAA,8BACK,EAGhBP,EAAoBQ,EAAOC,EAAPD,CAAc,SAAAE,GAAA,IAAGC,EAAKD,EAALC,MAAK,MAAQ,CACtDC,WAAY,SACZC,cAAe,MACfC,IAAKH,EAAMI,QAAQ,GACnBC,QAASL,EAAMI,QAAQ,GACvBE,gBAAiBC,EAAMP,EAAMQ,QAAQC,MAAMC,MAAO,IAClDC,aAAcX,EAAMY,MAAMD,aAC3B"}
@@ -1,19 +1,22 @@
1
1
  import { createFilterBar } from './index.create';
2
2
  import { getFilterFromURL, isEmptyFilterState, isFilterStateEqual, removeNullValues, setFilterToURL } from './helpers';
3
+ import { createFormFieldSelectMultipleWithFallback, createFormFieldSelectWithFallback } from './menu/create-form-field-select.fallback';
4
+ import createFormFieldNumber, { formatterNumber } from './menu/create-form-field-number';
5
+ import createFormFieldDateTime, { formatterDateTime } from './menu/create-form-field-datetime';
3
6
  import createFormFieldString from './menu/create-form-field-string';
4
7
  import createFormFieldSelect from './menu/create-form-field-select';
5
- import createFormFieldNumber, { formatterNumber } from './menu/create-form-field-number';
6
8
  import createFormFieldSelectMultiple from './menu/create-form-field-select-multiple';
7
- import createFormFieldDateTime, { formatterDateTime } from './menu/create-form-field-datetime';
8
9
  export declare class DinoFilterBar {
9
10
  createFilterBar: typeof createFilterBar;
10
11
  createConvertToGraphQL: <TSource extends Record<string, any>, TTarget extends object, U extends object = {}>(state: import("./types").TFilterState<TSource>) => import("./convert-to-graphql").TableFileterConverter<TSource, TTarget, U>;
11
12
  createLocalFilterBuilder: <T>(data: T[], filterState: import("./types").TFilterState<T>) => import("./local-filter-builder").LocalFilterBuilder<T>;
12
13
  createFormFieldString: typeof createFormFieldString;
13
14
  createFormFieldNumber: typeof createFormFieldNumber;
15
+ createFormFieldDateTime: typeof createFormFieldDateTime;
14
16
  createFormFieldSelect: typeof createFormFieldSelect;
17
+ createFormFieldSelectWithFallback: typeof createFormFieldSelectWithFallback;
15
18
  createFormFieldSelectMultiple: typeof createFormFieldSelectMultiple;
16
- createFormFieldDateTime: typeof createFormFieldDateTime;
19
+ createFormFieldSelectMultipleWithFallback: typeof createFormFieldSelectMultipleWithFallback;
17
20
  mapLogic: (logic?: import("./types").TLogic | undefined) => "Or" | "And";
18
21
  mapDirection: (direction?: import("./types").TDirection | undefined) => "ASC" | "DESC";
19
22
  formatterDateTime: typeof formatterDateTime;
@@ -4,6 +4,7 @@ import type { TLogic } from '../types';
4
4
  import type { IFieldMenuConfig, IFilterMenuFormProps } from './types';
5
5
  /** Props for the `FormFieldSelectMultiple` component returned by `createFormFieldSelectMultiple`. Extends the base filter-menu form props. */
6
6
  export interface IFormFieldSelectMultipleProps<T> extends IFilterMenuFormProps<T> {
7
+ onError?: () => void;
7
8
  }
8
9
  /** Parameters passed to `createFormFieldSelectMultiple` to configure the generated component. */
9
10
  export interface IFormFieldSelectMultipleParam<T> {
@@ -1,8 +1,9 @@
1
1
  import { FC } from 'react';
2
- import type { IFieldMenuConfig, IFilterMenuFormProps } from './types';
3
2
  import type { TFieldValid, TLogic } from '../types';
3
+ import type { IFieldMenuConfig, IFilterMenuFormProps } from './types';
4
4
  /** Props for the `FormFieldSelect` component returned by `createFormFieldSelect`. Extends the base filter-menu form props. */
5
5
  export interface IFormFieldSelectProps<T> extends IFilterMenuFormProps<T> {
6
+ onError?: () => void;
6
7
  }
7
8
  /** A single option item rendered as a radio button inside the select filter menu. */
8
9
  export interface IFieldSelectOption {
@@ -10,7 +11,7 @@ export interface IFieldSelectOption {
10
11
  label?: string;
11
12
  }
12
13
  /** Parameters passed to `createFormFieldSelect` to configure the generated component. */
13
- export interface IFormFieldSelectParams<T> {
14
+ export interface IFormFieldSelectParam<T> {
14
15
  /** Optional configuration for the form field */
15
16
  config?: IFieldMenuConfig<T>;
16
17
  /** List of options for the select field */
@@ -36,5 +37,5 @@ export interface IFormFieldSelectParams<T> {
36
37
  * @param params - Static configuration (option list, optional field config override)
37
38
  * @returns A React FC ready to be used as a filter-menu field component
38
39
  */
39
- declare function createFormFieldSelect<T>(params: IFormFieldSelectParams<T>): FC<IFormFieldSelectProps<T>>;
40
+ declare function createFormFieldSelect<T>(params: IFormFieldSelectParam<T>): FC<IFormFieldSelectProps<T>>;
40
41
  export default createFormFieldSelect;
@@ -0,0 +1,5 @@
1
+ import { FC } from 'react';
2
+ import { IFormFieldSelectParam } from './create-form-field-select';
3
+ import { IFormFieldSelectMultipleParam } from './create-form-field-select-multiple';
4
+ export declare function createFormFieldSelectWithFallback<T>(params: IFormFieldSelectParam<T>): FC<any>;
5
+ export declare function createFormFieldSelectMultipleWithFallback<T>(params: IFormFieldSelectMultipleParam<T>): FC<any>;
@@ -1,12 +1,14 @@
1
- import type { FC } from 'react';
1
+ import type { FC, ReactNode } from 'react';
2
2
  import type { IFieldMenuConfig, IFilterMenuFormProps } from './types';
3
3
  /** Props for the `FormFieldString` component returned by `createFormFieldString`. Extends the base filter-menu form props. */
4
4
  export interface IFormFieldStringProps<T> extends IFilterMenuFormProps<T> {
5
+ top?: ReactNode;
5
6
  }
6
7
  /** Parameters passed to `createFormFieldString` to configure the generated component. */
7
8
  export interface IFormFieldStringParam<T> {
8
9
  /** Optional configuration for the form field */
9
10
  config?: IFieldMenuConfig<T>;
11
+ top?: ReactNode;
10
12
  }
11
13
  /**
12
14
  * Factory function that creates a `FormFieldString` filter-menu component.
@@ -2,6 +2,7 @@ import type { ComponentType, ReactNode } from 'react';
2
2
  import type { BoxProps, PopperProps } from '@mui/material';
3
3
  import type { FormValidator, IFormValidatorConfig } from '../../form/validator';
4
4
  import type { TFieldModelValid, TFieldType, TFieldValid, TFieldValue, TLogic } from '../types';
5
+ export type TFetchStatus = 'loading' | 'loaded' | 'error';
5
6
  export interface IFieldMenuConfig<T> {
6
7
  /** The field this menu config applies to. Should be unique across all configs in the same menu. */
7
8
  field: TFieldType<T>;
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const ErrorPannel: FC;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinocollab-core",
3
- "version": "2.2.37",
3
+ "version": "2.2.39",
4
4
  "description": "Dinocollab core - libraries for building collaborative applications with React 18",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",