dinocollab-core 2.2.27 → 2.2.29

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,2 +1,2 @@
1
- export{KeySpecial}from"../src/filter-bar/types.js";export{createFilterBar}from"../src/filter-bar/index.create.js";export{HintIcon,HintList,createHintIcon}from"../src/filter-bar/components/hint-icon.js";export{TableFileterConverter,createConvertToGraphQL,mapLogic,mapSortDirection}from"../src/filter-bar/convert-to-graphql.js";export{LocalFilterBuilder,createLocalFilterBuilder}from"../src/filter-bar/local-filter-builder.js";export{DinoFilterBar,dinoFilterBar}from"../src/filter-bar/index.dino.js";export{createFormFieldDateTime,formatterDateTime}from"../src/filter-bar/menu/create-form-field-datetime.js";export{mergeSingleValueToStoreFilter,mergeValueToStoreFilter}from"../src/filter-bar/hooks.js";
1
+ export{KeySpecial}from"../src/filter-bar/types.js";export{createFilterBar}from"../src/filter-bar/index.create.js";export{HintIcon,HintList,createHintIcon}from"../src/filter-bar/components/hint-icon.js";export{TableFileterConverter,createConvertToGraphQL,mapLogic,mapSortDirection}from"../src/filter-bar/convert-to-graphql.js";export{LocalFilterBuilder,createLocalFilterBuilder}from"../src/filter-bar/local-filter-builder.js";export{DinoFilterBar,dinoFilterBar}from"../src/filter-bar/index.dino.js";export{createFormFieldDateTime,formatterDateTime}from"../src/filter-bar/menu/create-form-field-datetime.js";export{decodeNumberValue,encodeNumberValue,formatNumberChipLabel,formatterNumber}from"../src/filter-bar/menu/create-form-field-number.js";export{mergeSingleValueToStoreFilter,mergeValueToStoreFilter}from"../src/filter-bar/hooks.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- import{createClass as t,objectWithoutProperties as e,typeof as r,classCallCheck as i,defineProperty as l}from"../../_virtual/_rollupPluginBabelHelpers.js";import{KeySpecial as a}from"./types.js";import{getSeedFromURL as o,setSeedToURL as n,removeSeedFromURL as u}from"./helpers.js";import{createRequestBuilder as s}from"../http-service/graphql/request-param.js";var c=["mode"],f=function(t){return"or"===t?"Or":"And"},v=function(t){return"asc"===t?"ASC":"DESC"};function d(t,i,l,a){var o=a||{},n=o.mode,u=e(o,c),s=r(l);switch(s){case"string":"equal"===n?i.filter(t,l.toString(),u):i.filterContains(t,l.toString(),u);break;case"number":i.filterNumber(t,"==",l.toString(),u);break;default:console.warn("Unsupported value type for filtering: ".concat(s,". Value:"),l)}}var h=function(){return t(function t(e){var r=this;i(this,t),l(this,"autoMap",function(t){(r.currentObjectMap=t,r.state.storeFilter)&&Object.keys(r.state.storeFilter).forEach(function(e){var i,l=t[e],a=null===(i=r.state.storeFilter)||void 0===i?void 0:i[e];if(l){var o=l.targetfield,n=l.operation;if(l.custom)return void l.custom(r.graphqlBuilder,a,r.state.storeFilter);switch(n){case"equal":return void r.filterEqual(e,o);case"equalAndAny":return void r.filterEqual(e,o,{isAny:!0});case"datetime":return void r.filterDatetime(e,o);default:return void r.filterContains(e,o)}}});return r}),l(this,"prebuild",function(t){return r.prebuildFunc=t,r}),this.state=e,this.graphqlBuilder=s({ignoreEmpty:!0})},[{key:"filterScope",value:function(t,e){var r=this;if(this.state.storeFilter){var i=(null==e?void 0:e.logic)||this.state.filterLogic||"and",l=f(i);this.graphqlBuilder.scope(function(e){return t(e,r.state.storeFilter),e},{logic:l})}return this}},{key:"filterEqual",value:function(t,e,r){var i,l,a=null!==(i=null===(l=this.state.storeFilter)||void 0===l?void 0:l[t])&&void 0!==i?i:{values:[]},o=Array.isArray(a.values)?a.values:[a.values];if(!o||o.length<1||!e)return this;var n=f(a.logic);return this.filterScope(function(t){if(null!=r&&r.isAny)t.filterCustom("".concat(null==e?void 0:e.toString(),".isAny(").concat(JSON.stringify(o),")"),{logic:n});else for(var i=0;i<o.length;i++)d(e,t,o[i],{logic:n,mode:"equal"})},r),this}},{key:"filterContains",value:function(t,e,r){var i,l,a=null!==(i=null===(l=this.state.storeFilter)||void 0===l?void 0:l[t])&&void 0!==i?i:{values:[]},o=Array.isArray(a.values)?a.values:[a.values];if(!o||o.length<1||!e)return this;var n=f(a.logic);return this.filterScope(function(t){for(var r=0;r<o.length;r++)d(e,t,o[r],{logic:n,mode:"contains"})},r),this}},{key:"filterDatetime",value:function(t,e,r){var i,l,a=null!==(i=null===(l=this.state.storeFilter)||void 0===l?void 0:l[t])&&void 0!==i?i:{values:[]},o=Array.isArray(a.values)?a.values:[a.values];if(!o||o.length<1||!e)return this;if("range"===a.dateLogic&&o.length>=2){this.filterScope(function(t){t.filterGreaterEqual(e,o[0].toString(),{}),t.filterLessEqual(e,o[1].toString(),{logic:"And"})},r)}else if(1==o.length){this.filterScope(function(t){switch(a.dateLogic){case"before":t.filterLessEqual(e,o[0].toString());break;case"after":t.filterGreaterEqual(e,o[0].toString());break;default:t.filterEqual(e,o[0].toString())}},r)}return this}},{key:"sort",value:function(t){var e,r,i=this.state.storeSort,l=null!==(e=null==t?void 0:t.seed)&&void 0!==e?e:{},s=l.targetField,c=l.autoSave,f=void 0!==c&&c,d=s?null===(r=this.currentObjectMap)||void 0===r?void 0:r[s]:void 0,h=o();if((null==i?void 0:i.field)===a.sortShuffle){if(null==d||!d.targetfield)return this;var g=null!=h?h:(new Date).getTime().toString();this.graphqlBuilder.seed(d.targetfield,g),f&&n(g)}else{var p;h&&u();var y=null!=i&&i.field?null===(p=this.currentObjectMap)||void 0===p?void 0:p[null==i?void 0:i.field]:void 0;if(null==y||!y.targetfield)return this;this.graphqlBuilder.sort(y.targetfield,{direction:v(null==i?void 0:i.direction)})}return this}},{key:"quickSearch",value:function(t){var e,r,i=this;this.currentObjectMap||console.warn("No autoMap config found, quick search will not work properly without target field mapping.");var l=null!==(e=null===(r=this.state.storeFilter)||void 0===r?void 0:r.quickSearch)&&void 0!==e?e:{values:[],logic:"or"},a=Array.isArray(l.values)?l.values:[l.values];if(!a||a.length<1)return this;var o=f(l.logic),n=Array.isArray(t)?t:[t];return this.filterScope(function(t){n.forEach(function(e){var r,n=null===(r=i.currentObjectMap)||void 0===r?void 0:r[e];if(n&&a.length>0)if(n.custom)n.custom(t,l,i.state.storeFilter);else if(n.targetfield)for(var u=0;u<a.length;u++)d(n.targetfield,t,a[u],{logic:o})})}),this}},{key:"build",value:function(){return this.prebuildFunc&&this.prebuildFunc(this.graphqlBuilder),this.graphqlBuilder.build()}}])}(),g=function(t){return new h(t)};export{h as TableFileterConverter,g as createConvertToGraphQL,f as mapLogic,v as mapSortDirection};
1
+ import{createClass as t,createForOfIteratorHelper as e,objectWithoutProperties as r,typeof as i,classCallCheck as l,defineProperty as a}from"../../_virtual/_rollupPluginBabelHelpers.js";import{KeySpecial as o}from"./types.js";import{getSeedFromURL as n,setSeedToURL as u,removeSeedFromURL as s}from"./helpers.js";import{createRequestBuilder as f}from"../http-service/graphql/request-param.js";import{decodeNumberValue as c}from"./menu/create-form-field-number.js";var v=["mode"],d=function(t){return"or"===t?"Or":"And"},h=function(t){return"asc"===t?"ASC":"DESC"};function g(t,e,l,a){var o=a||{},n=o.mode,u=r(o,v),s=i(l);switch(s){case"string":"equal"===n?e.filter(t,l.toString(),u):e.filterContains(t,l.toString(),u);break;case"number":e.filterNumber(t,"==",l.toString(),u);break;default:console.warn("Unsupported value type for filtering: ".concat(s,". Value:"),l)}}var p=function(){return t(function t(e){var r=this;l(this,t),a(this,"autoMap",function(t){(r.currentObjectMap=t,r.state.storeFilter)&&Object.keys(r.state.storeFilter).forEach(function(e){var i,l=t[e],a=null===(i=r.state.storeFilter)||void 0===i?void 0:i[e];if(l){var o=l.targetfield,n=l.operation;if(l.custom)return void l.custom(r.graphqlBuilder,a,r.state.storeFilter);switch(n){case"equal":return void r.filterEqual(e,o);case"equalAndAny":return void r.filterEqual(e,o,{isAny:!0});case"datetime":return void r.filterDatetime(e,o);case"number":return void r.filterNumber(e,o);default:return void r.filterContains(e,o)}}});return r}),a(this,"prebuild",function(t){return r.prebuildFunc=t,r}),this.state=e,this.graphqlBuilder=f({ignoreEmpty:!0})},[{key:"filterScope",value:function(t,e){var r=this;if(this.state.storeFilter){var i=(null==e?void 0:e.logic)||this.state.filterLogic||"and",l=d(i);this.graphqlBuilder.scope(function(e){return t(e,r.state.storeFilter),e},{logic:l})}return this}},{key:"filterEqual",value:function(t,e,r){var i,l,a=null!==(i=null===(l=this.state.storeFilter)||void 0===l?void 0:l[t])&&void 0!==i?i:{values:[]},o=Array.isArray(a.values)?a.values:[a.values];if(!o||o.length<1||!e)return this;var n=d(a.logic);return this.filterScope(function(t){if(null!=r&&r.isAny)t.filterCustom("".concat(null==e?void 0:e.toString(),".isAny(").concat(JSON.stringify(o),")"),{logic:n});else for(var i=0;i<o.length;i++)g(e,t,o[i],{logic:n,mode:"equal"})},r),this}},{key:"filterContains",value:function(t,e,r){var i,l,a=null!==(i=null===(l=this.state.storeFilter)||void 0===l?void 0:l[t])&&void 0!==i?i:{values:[]},o=Array.isArray(a.values)?a.values:[a.values];if(!o||o.length<1||!e)return this;var n=d(a.logic);return this.filterScope(function(t){for(var r=0;r<o.length;r++)g(e,t,o[r],{logic:n,mode:"contains"})},r),this}},{key:"filterDatetime",value:function(t,e,r){var i,l,a=null!==(i=null===(l=this.state.storeFilter)||void 0===l?void 0:l[t])&&void 0!==i?i:{values:[]},o=Array.isArray(a.values)?a.values:[a.values];if(!o||o.length<1||!e)return this;if("range"===a.dateLogic&&o.length>=2){this.filterScope(function(t){t.filterGreaterEqual(e,o[0].toString(),{}),t.filterLessEqual(e,o[1].toString(),{logic:"And"})},r)}else if(1==o.length){this.filterScope(function(t){switch(a.dateLogic){case"before":t.filterLessEqual(e,o[0].toString());break;case"after":t.filterGreaterEqual(e,o[0].toString());break;default:t.filterEqual(e,o[0].toString())}},r)}return this}},{key:"filterNumber",value:function(t,r,i){var l,a,o=null!==(l=null===(a=this.state.storeFilter)||void 0===a?void 0:a[t])&&void 0!==l?l:{values:[]},n=Array.isArray(o.values)?o.values:[o.values];if(!n||n.length<1||!r)return this;var u={eq:"==",lt:"<",lte:"<=",gt:">",gte:">="},s=d(o.logic);return this.filterScope(function(t){var i,l=e(n);try{for(l.s();!(i=l.n()).done;){var a=i.value,o=c(a);if(o){var f=u[o.operator];t.filterNumber(r,f,o.num.toString(),{logic:s})}}}catch(t){l.e(t)}finally{l.f()}},i),this}},{key:"sort",value:function(t){var e,r,i=this.state.storeSort,l=null!==(e=null==t?void 0:t.seed)&&void 0!==e?e:{},a=l.targetField,f=l.autoSave,c=void 0!==f&&f,v=a?null===(r=this.currentObjectMap)||void 0===r?void 0:r[a]:void 0,d=n();if((null==i?void 0:i.field)===o.sortShuffle){if(null==v||!v.targetfield)return this;var g=null!=d?d:(new Date).getTime().toString();this.graphqlBuilder.seed(v.targetfield,g),c&&u(g)}else{var p;d&&s();var m=null!=i&&i.field?null===(p=this.currentObjectMap)||void 0===p?void 0:p[null==i?void 0:i.field]:void 0;if(null==m||!m.targetfield)return this;this.graphqlBuilder.sort(m.targetfield,{direction:h(null==i?void 0:i.direction)})}return this}},{key:"quickSearch",value:function(t){var e,r,i=this;this.currentObjectMap||console.warn("No autoMap config found, quick search will not work properly without target field mapping.");var l=null!==(e=null===(r=this.state.storeFilter)||void 0===r?void 0:r.quickSearch)&&void 0!==e?e:{values:[],logic:"or"},a=Array.isArray(l.values)?l.values:[l.values];if(!a||a.length<1)return this;var o=d(l.logic),n=Array.isArray(t)?t:[t];return this.filterScope(function(t){n.forEach(function(e){var r,n=null===(r=i.currentObjectMap)||void 0===r?void 0:r[e];if(n&&a.length>0)if(n.custom)n.custom(t,l,i.state.storeFilter);else if(n.targetfield)for(var u=0;u<a.length;u++)g(n.targetfield,t,a[u],{logic:o})})}),this}},{key:"build",value:function(){return this.prebuildFunc&&this.prebuildFunc(this.graphqlBuilder),this.graphqlBuilder.build()}}])}(),m=function(t){return new p(t)};export{p as TableFileterConverter,m as createConvertToGraphQL,d as mapLogic,h as mapSortDirection};
2
2
  //# sourceMappingURL=convert-to-graphql.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"convert-to-graphql.js","sources":["../../../src/filter-bar/convert-to-graphql.ts"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { KeySpecial } from './types'\r\nimport { getSeedFromURL, removeSeedFromURL, setSeedToURL } from './helpers'\r\nimport { createRequestBuilder, IFilterOption, RequestParam } from '../http-service/graphql/request-param'\r\n// types\r\nimport type { TFilterState, TFieldStore, TFieldValue, TLogic, TDirection, TFieldType, TFieldValid, TDateLogic } from './types'\r\n\r\ntype TFilterScopeFn<TSource, TTarget extends object, U extends object = {}> = (\r\n currentBuilder: RequestParam<TTarget, U>,\r\n store?: TFieldStore<TSource>\r\n) => void\r\n\r\n/**\r\n * @en\r\n * - Utility class to convert filter state from a filter bar into a GraphQL query builder.\r\n * - Supports mapping filter fields to different GraphQL fields, custom filter logic, and sorting.\r\n * @vi\r\n * - Lớp tiện ích để chuyển đổi trạng thái filter từ filter bar thành builder truy vấn GraphQL.\r\n * - Hỗ trợ ánh xạ các trường filter sang các trường GraphQL khác, logic filter tùy chỉnh và sắp xếp.\r\n */\r\ntype TAutoMapFieldCustomFn<TSource, TTarget extends object, U extends object = {}> = (\r\n currentBuilder: RequestParam<TTarget, U>,\r\n value?: NonNullable<TFieldStore<TSource>>[keyof TFieldStore<TSource>],\r\n store?: TFieldStore<TSource>\r\n) => void\r\n\r\ntype TAutoMapConfig<TSource, TTarget extends object, U extends object = {}> = {\r\n /**\r\n * @en The target field in the GraphQL schema that this filter field maps to. If not provided, the source field name will be used as the target field.\r\n * @vi Trường đích trong schema GraphQL mà trường filter này ánh xạ tới. Nếu không cung cấp, tên trường nguồn sẽ được sử dụng làm trường đích.\r\n */\r\n targetfield?: keyof TTarget\r\n /**\r\n * @en The operation to apply for the filter field. @default 'contains'\r\n * @vi Thao tác áp dụng cho trường filter. @default 'contains'\r\n */\r\n operation?: 'equal' | 'contains' | 'datetime' | 'equalAndAny'\r\n /**\r\n * @en\r\n * - Custom function to apply complex filter logic that doesn't fit standard 'equal' or 'contains' operations.\r\n * - Receives the current GraphQL builder, the value of the filter field, and the entire filter store for context.\r\n * @vi\r\n * - Hàm tùy chỉnh để áp dụng logic filter phức tạp không phù hợp với các thao tác 'equal' hoặc 'contains' tiêu chuẩn.\r\n * - Nhận builder GraphQL hiện tại, giá trị của trường filter và toàn bộ store filter để có ngữ cảnh.\r\n */\r\n custom?: TAutoMapFieldCustomFn<TSource, TTarget, U>\r\n}\r\n\r\ntype TAutoMapConfigs<TSource, TTarget extends object, U extends object = {}> = Partial<Record<keyof TSource, TAutoMapConfig<TSource, TTarget, U>>>\r\n\r\ntype TFilterOption = {\r\n logic?: TLogic\r\n}\r\n\r\nexport const mapLogic = (logic?: TLogic): 'And' | 'Or' => {\r\n return logic === 'or' ? 'Or' : 'And'\r\n}\r\n\r\nexport const mapSortDirection = (direction?: TDirection): 'ASC' | 'DESC' => {\r\n return direction === 'asc' ? 'ASC' : 'DESC'\r\n}\r\n\r\ntype TFilterByTypeOptions = Partial<IFilterOption> & {\r\n mode?: 'equal' | 'contains'\r\n}\r\n\r\nfunction filterByType<TTarget extends object, U extends object = {}>(\r\n field: keyof TTarget,\r\n builder: RequestParam<TTarget, U>,\r\n value: TFieldValid,\r\n option?: TFilterByTypeOptions\r\n) {\r\n const { mode, ...restOption } = option || {}\r\n const valueType = typeof value\r\n switch (valueType) {\r\n case 'string':\r\n if (mode === 'equal') {\r\n builder.filter(field, value.toString(), restOption)\r\n } else {\r\n builder.filterContains(field, value.toString(), restOption)\r\n }\r\n break\r\n case 'number':\r\n builder.filterNumber(field, '==', value.toString(), restOption)\r\n break\r\n default:\r\n console.warn(`Unsupported value type for filtering: ${valueType}. Value:`, value)\r\n }\r\n}\r\n\r\nexport class TableFileterConverter<TSource extends Record<string, any>, TTarget extends object, U extends object = {}> {\r\n private state: TFilterState<TSource>\r\n private graphqlBuilder: RequestParam<TTarget, U>\r\n constructor(state: TFilterState<TSource>) {\r\n this.state = state\r\n this.graphqlBuilder = createRequestBuilder<TTarget, U>({ ignoreEmpty: true })\r\n }\r\n\r\n filterScope(fn: TFilterScopeFn<TSource, TTarget, U>, options?: TFilterOption) {\r\n if (this.state.storeFilter) {\r\n const mergedLogic = options?.logic || this.state.filterLogic || 'and'\r\n const logic = mapLogic(mergedLogic)\r\n this.graphqlBuilder.scope(\r\n (b) => {\r\n fn(b as unknown as RequestParam<TTarget, U>, this.state.storeFilter)\r\n return b\r\n },\r\n { logic }\r\n )\r\n }\r\n return this\r\n }\r\n\r\n filterEqual(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption & { isAny?: boolean }) {\r\n const fieldValue: TFieldValue = this.state.storeFilter?.[field] ?? { values: [] }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty || !targetField) return this\r\n\r\n const logic = mapLogic(fieldValue.logic)\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n if (options?.isAny) {\r\n builder.filterCustom(`${targetField?.toString()}.isAny(${JSON.stringify(values)})`, { logic })\r\n } else {\r\n for (let index = 0; index < values.length; index++) {\r\n filterByType(targetField, builder, values[index], { logic, mode: 'equal' })\r\n }\r\n }\r\n }\r\n\r\n this.filterScope(fn, options)\r\n return this\r\n }\r\n\r\n filterContains(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption) {\r\n const fieldValue: TFieldValue = this.state.storeFilter?.[field] ?? { values: [] }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty || !targetField) return this\r\n\r\n const finalLogic = mapLogic(fieldValue.logic)\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n for (let index = 0; index < values.length; index++) {\r\n filterByType(targetField, builder, values[index], { logic: finalLogic, mode: 'contains' })\r\n }\r\n }\r\n this.filterScope(fn, options)\r\n return this\r\n }\r\n\r\n filterDatetime(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption) {\r\n const fieldValue: TFieldValue = this.state.storeFilter?.[field] ?? { values: [] }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty || !targetField) return this\r\n\r\n if (fieldValue.dateLogic === 'range' && values.length >= 2) {\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n builder.filterGreaterEqual(targetField, values[0].toString(), {})\r\n builder.filterLessEqual(targetField, values[1].toString(), { logic: 'And' })\r\n }\r\n this.filterScope(fn, options)\r\n } else if (values.length == 1) {\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n switch (fieldValue.dateLogic) {\r\n case 'before':\r\n builder.filterLessEqual(targetField, values[0].toString())\r\n break\r\n case 'after':\r\n builder.filterGreaterEqual(targetField, values[0].toString())\r\n break\r\n case 'on':\r\n default:\r\n builder.filterEqual(targetField, values[0].toString())\r\n break\r\n }\r\n }\r\n this.filterScope(fn, options)\r\n }\r\n return this\r\n }\r\n\r\n sort(param?: { seed: { targetField?: TFieldType<TSource>; autoSave?: boolean } }) {\r\n const store = this.state.storeSort\r\n const { targetField: seedTargetField, autoSave = false } = param?.seed ?? {}\r\n const seedField = seedTargetField ? this.currentObjectMap?.[seedTargetField] : undefined\r\n const seedFromURL = getSeedFromURL()\r\n if (store?.field === KeySpecial.sortShuffle) {\r\n if (!seedField?.targetfield) return this\r\n const seedValue = seedFromURL ?? new Date().getTime().toString()\r\n this.graphqlBuilder.seed(seedField.targetfield, seedValue)\r\n if (autoSave) setSeedToURL(seedValue)\r\n } else {\r\n if (seedFromURL) removeSeedFromURL()\r\n const field = store?.field ? this.currentObjectMap?.[store?.field] : undefined\r\n if (!field?.targetfield) return this\r\n this.graphqlBuilder.sort(field.targetfield, { direction: mapSortDirection(store?.direction) })\r\n }\r\n return this\r\n }\r\n\r\n quickSearch(fields: TFieldType<TSource> | TFieldType<TSource>[]) {\r\n if (!this.currentObjectMap) {\r\n console.warn('No autoMap config found, quick search will not work properly without target field mapping.')\r\n }\r\n const fieldValue: TFieldValue = this.state.storeFilter?.quickSearch ?? { values: [], logic: 'or' }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty) return this\r\n\r\n const logic = mapLogic(fieldValue.logic)\r\n const targetFields = Array.isArray(fields) ? fields : [fields]\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n targetFields.forEach((field) => {\r\n const fieldMap = this.currentObjectMap?.[field]\r\n if (fieldMap && values.length > 0) {\r\n if (fieldMap.custom) {\r\n fieldMap.custom(builder, fieldValue, this.state.storeFilter)\r\n } else if (fieldMap.targetfield) {\r\n for (let index = 0; index < values.length; index++) {\r\n filterByType(fieldMap.targetfield, builder, values[index], { logic })\r\n }\r\n }\r\n }\r\n })\r\n }\r\n this.filterScope(fn)\r\n return this\r\n }\r\n\r\n private currentObjectMap?: TAutoMapConfigs<TSource, TTarget, U>\r\n autoMap = (objMap: TAutoMapConfigs<TSource, TTarget, U>) => {\r\n this.currentObjectMap = objMap\r\n\r\n if (this.state.storeFilter) {\r\n const keys = Object.keys(this.state.storeFilter) as (keyof TFieldStore<TSource>)[]\r\n // filter the keys that exist in objMap\r\n keys.forEach((key) => {\r\n const mapConfig = objMap[key]\r\n const fieldValue: TFieldValue | undefined = this.state.storeFilter?.[key]\r\n if (mapConfig) {\r\n const { targetfield, operation } = mapConfig\r\n if (mapConfig.custom) {\r\n mapConfig.custom(this.graphqlBuilder, fieldValue, this.state.storeFilter)\r\n return // skip the rest logic if custom function is provided\r\n }\r\n switch (operation) {\r\n case 'equal':\r\n this.filterEqual(key, targetfield)\r\n return // break is not needed here because of the return statement\r\n case 'equalAndAny':\r\n this.filterEqual(key, targetfield, { isAny: true })\r\n return // break is not needed here because of the return statement\r\n case 'datetime':\r\n this.filterDatetime(key, targetfield)\r\n return // break is not needed here because of the return statement\r\n case 'contains':\r\n default:\r\n this.filterContains(key, targetfield)\r\n return // break is not needed here because of the return statement\r\n }\r\n }\r\n })\r\n }\r\n return this\r\n }\r\n\r\n private prebuildFunc?: (rp: RequestParam<TTarget, U>) => RequestParam<TTarget, U>\r\n prebuild = (func: (requestParam: RequestParam<TTarget, U>) => RequestParam<TTarget, U>) => {\r\n this.prebuildFunc = func\r\n return this\r\n }\r\n\r\n build() {\r\n if (this.prebuildFunc) this.prebuildFunc(this.graphqlBuilder)\r\n return this.graphqlBuilder.build()\r\n }\r\n}\r\n\r\nexport const createConvertToGraphQL = <TSource extends Record<string, any>, TTarget extends object, U extends object = {}>(\r\n state: TFilterState<TSource>\r\n) => {\r\n return new TableFileterConverter<TSource, TTarget, U>(state)\r\n}\r\n"],"names":["mapLogic","logic","mapSortDirection","direction","filterByType","field","builder","value","option","_ref","mode","restOption","_objectWithoutProperties","_excluded","valueType","_typeof","filter","toString","filterContains","filterNumber","console","warn","concat","TableFileterConverter","_createClass","state","_this","this","_classCallCheck","_defineProperty","objMap","currentObjectMap","storeFilter","Object","keys","forEach","key","_this$state$storeFilt","mapConfig","fieldValue","targetfield","operation","custom","graphqlBuilder","filterEqual","isAny","filterDatetime","func","prebuildFunc","createRequestBuilder","ignoreEmpty","fn","options","_this2","mergedLogic","filterLogic","scope","b","targetField","_this$state$storeFilt2","_this$state$storeFilt3","values","Array","isArray","length","filterScope","filterCustom","JSON","stringify","index","_this$state$storeFilt4","_this$state$storeFilt5","finalLogic","_this$state$storeFilt6","_this$state$storeFilt7","dateLogic","filterGreaterEqual","filterLessEqual","param","_param$seed","_this$currentObjectMa","store","storeSort","_ref2","seed","seedTargetField","_ref2$autoSave","autoSave","seedField","undefined","seedFromURL","getSeedFromURL","KeySpecial","sortShuffle","seedValue","Date","getTime","setSeedToURL","_this$currentObjectMa2","removeSeedFromURL","sort","fields","_this$state$storeFilt8","_this$state$storeFilt9","_this3","quickSearch","targetFields","_this3$currentObjectM","fieldMap","build","createConvertToGraphQL"],"mappings":"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"}
1
+ {"version":3,"file":"convert-to-graphql.js","sources":["../../../src/filter-bar/convert-to-graphql.ts"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n// imports\r\nimport { KeySpecial } from './types'\r\nimport { getSeedFromURL, removeSeedFromURL, setSeedToURL } from './helpers'\r\nimport { createRequestBuilder, IFilterOption, RequestParam } from '../http-service/graphql/request-param'\r\nimport { decodeNumberValue } from './menu/create-form-field-number'\r\n// types\r\nimport type { TFilterState, TFieldStore, TFieldValue, TLogic, TDirection, TFieldType, TFieldValid, TDateLogic, TNumberOperator } from './types'\r\n\r\ntype TFilterScopeFn<TSource, TTarget extends object, U extends object = {}> = (\r\n currentBuilder: RequestParam<TTarget, U>,\r\n store?: TFieldStore<TSource>\r\n) => void\r\n\r\n/**\r\n * @en\r\n * - Utility class to convert filter state from a filter bar into a GraphQL query builder.\r\n * - Supports mapping filter fields to different GraphQL fields, custom filter logic, and sorting.\r\n * @vi\r\n * - Lớp tiện ích để chuyển đổi trạng thái filter từ filter bar thành builder truy vấn GraphQL.\r\n * - Hỗ trợ ánh xạ các trường filter sang các trường GraphQL khác, logic filter tùy chỉnh và sắp xếp.\r\n */\r\ntype TAutoMapFieldCustomFn<TSource, TTarget extends object, U extends object = {}> = (\r\n currentBuilder: RequestParam<TTarget, U>,\r\n value?: NonNullable<TFieldStore<TSource>>[keyof TFieldStore<TSource>],\r\n store?: TFieldStore<TSource>\r\n) => void\r\n\r\ntype TAutoMapConfig<TSource, TTarget extends object, U extends object = {}> = {\r\n /**\r\n * @en The target field in the GraphQL schema that this filter field maps to. If not provided, the source field name will be used as the target field.\r\n * @vi Trường đích trong schema GraphQL mà trường filter này ánh xạ tới. Nếu không cung cấp, tên trường nguồn sẽ được sử dụng làm trường đích.\r\n */\r\n targetfield?: keyof TTarget\r\n /**\r\n * @en The operation to apply for the filter field. @default 'contains'\r\n * @vi Thao tác áp dụng cho trường filter. @default 'contains'\r\n */\r\n operation?: 'equal' | 'equalAndAny' | 'contains' | 'datetime' | 'number'\r\n /**\r\n * @en\r\n * - Custom function to apply complex filter logic that doesn't fit standard 'equal' or 'contains' operations.\r\n * - Receives the current GraphQL builder, the value of the filter field, and the entire filter store for context.\r\n * @vi\r\n * - Hàm tùy chỉnh để áp dụng logic filter phức tạp không phù hợp với các thao tác 'equal' hoặc 'contains' tiêu chuẩn.\r\n * - Nhận builder GraphQL hiện tại, giá trị của trường filter và toàn bộ store filter để có ngữ cảnh.\r\n */\r\n custom?: TAutoMapFieldCustomFn<TSource, TTarget, U>\r\n}\r\n\r\ntype TAutoMapConfigs<TSource, TTarget extends object, U extends object = {}> = Partial<Record<keyof TSource, TAutoMapConfig<TSource, TTarget, U>>>\r\n\r\ntype TFilterOption = {\r\n logic?: TLogic\r\n}\r\n\r\nexport const mapLogic = (logic?: TLogic): 'And' | 'Or' => {\r\n return logic === 'or' ? 'Or' : 'And'\r\n}\r\n\r\nexport const mapSortDirection = (direction?: TDirection): 'ASC' | 'DESC' => {\r\n return direction === 'asc' ? 'ASC' : 'DESC'\r\n}\r\n\r\ntype TFilterByTypeOptions = Partial<IFilterOption> & {\r\n mode?: 'equal' | 'contains'\r\n}\r\n\r\nfunction filterByType<TTarget extends object, U extends object = {}>(\r\n field: keyof TTarget,\r\n builder: RequestParam<TTarget, U>,\r\n value: TFieldValid,\r\n option?: TFilterByTypeOptions\r\n) {\r\n const { mode, ...restOption } = option || {}\r\n const valueType = typeof value\r\n switch (valueType) {\r\n case 'string':\r\n if (mode === 'equal') {\r\n builder.filter(field, value.toString(), restOption)\r\n } else {\r\n builder.filterContains(field, value.toString(), restOption)\r\n }\r\n break\r\n case 'number':\r\n builder.filterNumber(field, '==', value.toString(), restOption)\r\n break\r\n default:\r\n console.warn(`Unsupported value type for filtering: ${valueType}. Value:`, value)\r\n }\r\n}\r\n\r\nexport class TableFileterConverter<TSource extends Record<string, any>, TTarget extends object, U extends object = {}> {\r\n private state: TFilterState<TSource>\r\n private graphqlBuilder: RequestParam<TTarget, U>\r\n constructor(state: TFilterState<TSource>) {\r\n this.state = state\r\n this.graphqlBuilder = createRequestBuilder<TTarget, U>({ ignoreEmpty: true })\r\n }\r\n\r\n filterScope(fn: TFilterScopeFn<TSource, TTarget, U>, options?: TFilterOption) {\r\n if (this.state.storeFilter) {\r\n const mergedLogic = options?.logic || this.state.filterLogic || 'and'\r\n const logic = mapLogic(mergedLogic)\r\n this.graphqlBuilder.scope(\r\n (b) => {\r\n fn(b as unknown as RequestParam<TTarget, U>, this.state.storeFilter)\r\n return b\r\n },\r\n { logic }\r\n )\r\n }\r\n return this\r\n }\r\n\r\n filterEqual(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption & { isAny?: boolean }) {\r\n const fieldValue: TFieldValue = this.state.storeFilter?.[field] ?? { values: [] }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty || !targetField) return this\r\n\r\n const logic = mapLogic(fieldValue.logic)\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n if (options?.isAny) {\r\n builder.filterCustom(`${targetField?.toString()}.isAny(${JSON.stringify(values)})`, { logic })\r\n } else {\r\n for (let index = 0; index < values.length; index++) {\r\n filterByType(targetField, builder, values[index], { logic, mode: 'equal' })\r\n }\r\n }\r\n }\r\n\r\n this.filterScope(fn, options)\r\n return this\r\n }\r\n\r\n filterContains(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption) {\r\n const fieldValue: TFieldValue = this.state.storeFilter?.[field] ?? { values: [] }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty || !targetField) return this\r\n\r\n const finalLogic = mapLogic(fieldValue.logic)\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n for (let index = 0; index < values.length; index++) {\r\n filterByType(targetField, builder, values[index], { logic: finalLogic, mode: 'contains' })\r\n }\r\n }\r\n this.filterScope(fn, options)\r\n return this\r\n }\r\n\r\n filterDatetime(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption) {\r\n const fieldValue: TFieldValue = this.state.storeFilter?.[field] ?? { values: [] }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty || !targetField) return this\r\n\r\n if (fieldValue.dateLogic === 'range' && values.length >= 2) {\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n builder.filterGreaterEqual(targetField, values[0].toString(), {})\r\n builder.filterLessEqual(targetField, values[1].toString(), { logic: 'And' })\r\n }\r\n this.filterScope(fn, options)\r\n } else if (values.length == 1) {\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n switch (fieldValue.dateLogic) {\r\n case 'before':\r\n builder.filterLessEqual(targetField, values[0].toString())\r\n break\r\n case 'after':\r\n builder.filterGreaterEqual(targetField, values[0].toString())\r\n break\r\n case 'on':\r\n default:\r\n builder.filterEqual(targetField, values[0].toString())\r\n break\r\n }\r\n }\r\n this.filterScope(fn, options)\r\n }\r\n return this\r\n }\r\n\r\n filterNumber(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption) {\r\n const fieldValue: TFieldValue = this.state.storeFilter?.[field] ?? { values: [] }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty || !targetField) return this\r\n\r\n const operatorMap: Record<TNumberOperator, string> = {\r\n eq: '==',\r\n lt: '<',\r\n lte: '<=',\r\n gt: '>',\r\n gte: '>='\r\n }\r\n\r\n const logic = mapLogic(fieldValue.logic)\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n for (const encoded of values) {\r\n const decoded = decodeNumberValue(encoded)\r\n if (!decoded) continue\r\n const op = operatorMap[decoded.operator]\r\n builder.filterNumber(targetField, op, decoded.num.toString(), { logic })\r\n }\r\n }\r\n this.filterScope(fn, options)\r\n return this\r\n }\r\n\r\n sort(param?: { seed: { targetField?: TFieldType<TSource>; autoSave?: boolean } }) {\r\n const store = this.state.storeSort\r\n const { targetField: seedTargetField, autoSave = false } = param?.seed ?? {}\r\n const seedField = seedTargetField ? this.currentObjectMap?.[seedTargetField] : undefined\r\n const seedFromURL = getSeedFromURL()\r\n if (store?.field === KeySpecial.sortShuffle) {\r\n if (!seedField?.targetfield) return this\r\n const seedValue = seedFromURL ?? new Date().getTime().toString()\r\n this.graphqlBuilder.seed(seedField.targetfield, seedValue)\r\n if (autoSave) setSeedToURL(seedValue)\r\n } else {\r\n if (seedFromURL) removeSeedFromURL()\r\n const field = store?.field ? this.currentObjectMap?.[store?.field] : undefined\r\n if (!field?.targetfield) return this\r\n this.graphqlBuilder.sort(field.targetfield, { direction: mapSortDirection(store?.direction) })\r\n }\r\n return this\r\n }\r\n\r\n quickSearch(fields: TFieldType<TSource> | TFieldType<TSource>[]) {\r\n if (!this.currentObjectMap) {\r\n console.warn('No autoMap config found, quick search will not work properly without target field mapping.')\r\n }\r\n const fieldValue: TFieldValue = this.state.storeFilter?.quickSearch ?? { values: [], logic: 'or' }\r\n const values = Array.isArray(fieldValue.values) ? fieldValue.values : [fieldValue.values]\r\n const isValueEmpty = !values || values.length < 1\r\n if (isValueEmpty) return this\r\n\r\n const logic = mapLogic(fieldValue.logic)\r\n const targetFields = Array.isArray(fields) ? fields : [fields]\r\n const fn: TFilterScopeFn<TSource, TTarget, U> = (builder) => {\r\n targetFields.forEach((field) => {\r\n const fieldMap = this.currentObjectMap?.[field]\r\n if (fieldMap && values.length > 0) {\r\n if (fieldMap.custom) {\r\n fieldMap.custom(builder, fieldValue, this.state.storeFilter)\r\n } else if (fieldMap.targetfield) {\r\n for (let index = 0; index < values.length; index++) {\r\n filterByType(fieldMap.targetfield, builder, values[index], { logic })\r\n }\r\n }\r\n }\r\n })\r\n }\r\n this.filterScope(fn)\r\n return this\r\n }\r\n\r\n private currentObjectMap?: TAutoMapConfigs<TSource, TTarget, U>\r\n autoMap = (objMap: TAutoMapConfigs<TSource, TTarget, U>) => {\r\n this.currentObjectMap = objMap\r\n\r\n if (this.state.storeFilter) {\r\n const keys = Object.keys(this.state.storeFilter) as (keyof TFieldStore<TSource>)[]\r\n // filter the keys that exist in objMap\r\n keys.forEach((key) => {\r\n const mapConfig = objMap[key]\r\n const fieldValue: TFieldValue | undefined = this.state.storeFilter?.[key]\r\n if (mapConfig) {\r\n const { targetfield, operation } = mapConfig\r\n if (mapConfig.custom) {\r\n mapConfig.custom(this.graphqlBuilder, fieldValue, this.state.storeFilter)\r\n return // skip the rest logic if custom function is provided\r\n }\r\n switch (operation) {\r\n case 'equal':\r\n this.filterEqual(key, targetfield)\r\n return // break is not needed here because of the return statement\r\n case 'equalAndAny':\r\n this.filterEqual(key, targetfield, { isAny: true })\r\n return // break is not needed here because of the return statement\r\n case 'datetime':\r\n this.filterDatetime(key, targetfield)\r\n return // break is not needed here because of the return statement\r\n case 'number':\r\n this.filterNumber(key, targetfield)\r\n return // break is not needed here because of the return statement\r\n case 'contains':\r\n default:\r\n this.filterContains(key, targetfield)\r\n return // break is not needed here because of the return statement\r\n }\r\n }\r\n })\r\n }\r\n return this\r\n }\r\n\r\n private prebuildFunc?: (rp: RequestParam<TTarget, U>) => RequestParam<TTarget, U>\r\n prebuild = (func: (requestParam: RequestParam<TTarget, U>) => RequestParam<TTarget, U>) => {\r\n this.prebuildFunc = func\r\n return this\r\n }\r\n\r\n build() {\r\n if (this.prebuildFunc) this.prebuildFunc(this.graphqlBuilder)\r\n return this.graphqlBuilder.build()\r\n }\r\n}\r\n\r\nexport const createConvertToGraphQL = <TSource extends Record<string, any>, TTarget extends object, U extends object = {}>(\r\n state: TFilterState<TSource>\r\n) => {\r\n return new TableFileterConverter<TSource, TTarget, U>(state)\r\n}\r\n"],"names":["mapLogic","logic","mapSortDirection","direction","filterByType","field","builder","value","option","_ref","mode","restOption","_objectWithoutProperties","_excluded","valueType","_typeof","filter","toString","filterContains","filterNumber","console","warn","concat","TableFileterConverter","_createClass","state","_this","this","_classCallCheck","_defineProperty","objMap","currentObjectMap","storeFilter","Object","keys","forEach","key","_this$state$storeFilt","mapConfig","fieldValue","targetfield","operation","custom","graphqlBuilder","filterEqual","isAny","filterDatetime","func","prebuildFunc","createRequestBuilder","ignoreEmpty","fn","options","_this2","mergedLogic","filterLogic","scope","b","targetField","_this$state$storeFilt2","_this$state$storeFilt3","values","Array","isArray","length","filterScope","filterCustom","JSON","stringify","index","_this$state$storeFilt4","_this$state$storeFilt5","finalLogic","_this$state$storeFilt6","_this$state$storeFilt7","dateLogic","filterGreaterEqual","filterLessEqual","_this$state$storeFilt8","_this$state$storeFilt9","operatorMap","eq","lt","lte","gt","gte","_step","_iterator","_createForOfIteratorHelper","s","n","done","encoded","decoded","decodeNumberValue","op","operator","num","err","e","f","param","_param$seed","_this$currentObjectMa","store","storeSort","_ref2","seed","seedTargetField","_ref2$autoSave","autoSave","seedField","undefined","seedFromURL","getSeedFromURL","KeySpecial","sortShuffle","seedValue","Date","getTime","setSeedToURL","_this$currentObjectMa2","removeSeedFromURL","sort","fields","_this$state$storeFilt0","_this$state$storeFilt1","_this3","quickSearch","targetFields","_this3$currentObjectM","fieldMap","build","createConvertToGraphQL"],"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 l}from"./local-filter-builder.js";import{createConvertToGraphQL as o,mapLogic as s,mapSortDirection as m}from"./convert-to-graphql.js";import{isEmptyFilterState as a,removeNullValues as c,isFilterStateEqual as f,setFilterToURL as p,getFilterFromURL as h}from"./helpers.js";import n from"./menu/create-form-field-string.js";import u from"./menu/create-form-field-select.js";import F from"./menu/create-form-field-select-multiple.js";import{createFormFieldDateTime as d,formatterDateTime as j}from"./menu/create-form-field-datetime.js";var g=e(function e(){t(this,e),r(this,"createFilterBar",i),r(this,"createConvertToGraphQL",o),r(this,"createLocalFilterBuilder",l),r(this,"createFormFieldString",n),r(this,"createFormFieldSelect",u),r(this,"createFormFieldSelectMultiple",F),r(this,"createFormFieldDateTime",d),r(this,"mapLogic",s),r(this,"mapDirection",m),r(this,"formatterDateTime",j),r(this,"isEmptyFilterState",a),r(this,"removeNullValues",c),r(this,"isFilterStateEqual",f),r(this,"setFilterToURL",p),r(this,"getFilterFromURL",h)}),v=new g;export{g as DinoFilterBar,v 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 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};
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 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 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\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","createFormFieldSelect","createFormFieldSelectMultiple","createFormFieldDateTime","mapLogic","mapSortDirection","formatterDateTime","isEmptyFilterState","removeNullValues","isFilterStateEqual","setFilterToURL","getFilterFromURL","dinoFilterBar"],"mappings":"+tBASA,IAAaA,EAAaC,EAAA,SAAAD,IAAAE,OAAAF,GAAAG,yBACNC,GAAeD,gCACRE,GAAsBF,kCACpBG,GAE3BH,+BACwBI,GAAqBJ,+BACrBK,GAAqBL,uCACbM,GAA6BN,iCACnCO,GAE1BP,kBACWQ,GAAQR,sBACJS,GAEfT,2BACoBU,GAEpBV,4BACqBW,GAAkBX,0BACpBY,GAAgBZ,4BACda,GAAkBb,wBACtBc,GAAcd,0BACZe,EAAgB,GAGxBC,EAAgB,IAAInB"}
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"}
@@ -0,0 +1,2 @@
1
+ import{slicedToArray as e,defineProperty as l}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as i,jsxs as n}from"react/jsx-runtime";import{useMemo as o,useState as r,createRef as t}from"react";import{styled as a,Typography as u,ToggleButtonGroup as s,ToggleButton as c,TextField as d,Button as v,Box as p}from"@mui/material";import{createChipViewers as f}from"../components/chip-viewer.js";import{getErrorMessage as m}from"../../form/helpers.js";import{ButtonBack as g,FilterLogicToggle as b}from"../components/ui.units.js";import{PopperContent as h,PopperBody as x,PopperFooter as y}from"../components/popper-custom.js";var C={eq:"=",lt:"<",lte:"≤",gt:">",gte:"≥"},z=["eq","lt","lte","gt","gte"];function j(e,l){return"".concat(e,":").concat(l)}function k(e){if("string"!=typeof e)return null;var l=e.indexOf(":");if(-1===l)return null;var i=e.slice(0,l),n=parseFloat(e.slice(l+1));return!z.includes(i)||isNaN(n)?null:{operator:i,num:n}}function A(e){var l=k(e);return l?"".concat(C[l.operator]," ").concat(l.num):String(e)}function N(a){var k=f();return function(f){var N,S,B,T,O=o(function(){return Object.assign({},f.currentConfig,null==a?void 0:a.config)},[null==a?void 0:a.config,f.currentConfig]),P=t(),R=f.value,q=void 0===R?{values:[],logic:null!==(N=null==O?void 0:O.defaultLogic)&&void 0!==N?N:"and"}:R,w=r(q.logic),I=e(w,2),M=I[0],V=I[1],E=r(null!==(S=null==a?void 0:a.defaultOperator)&&void 0!==S?S:"eq"),H=e(E,2),L=H[0],_=H[1],D=r(""),W=e(D,2),G=W[0],J=W[1],K=null!==(B=null==O?void 0:O.label)&&void 0!==B?B:O.field.toString(),Q=r({}),U=e(Q,2),X=U[0],Y=U[1],Z=function(e){f.onSubmit(O.field,e,O)},$=q.values.length>=2&&M!==q.logic,ee=m(X,O.field),le=o(function(){var e=Array.isArray(q.values)?q.values:[q.values];return{field:O.field,items:e.map(function(e){return{value:e,label:A(e)}})}},[O.field,q]),ie=!(""!==G.trim()&&!isNaN(parseFloat(G)))&&!$,ne=[];return f.isLoading&&ne.push("disabled"),i(F,{className:ne.join(" "),noValidate:!0,onSubmit:function(e){var i,n,o;e.preventDefault(),e.stopPropagation();var r=parseFloat(null!==(i=null===(n=P.current)||void 0===n?void 0:n.value)&&void 0!==i?i:"");if(isNaN(r))$&&Z({values:q.values,logic:M});else{var t=l({},O.field,r),a=null===(o=f.validator)||void 0===o?void 0:o.run(t);if(Y(a||{}),!a||0===Object.keys(a).length){var u=j(L,r);Z({values:[u],logic:M}),P.current&&(P.current.blur(),P.current.value=""),J("")}}},children:n(h,{title:"Filter by ".concat(K),onClose:f.onClose,slots:{beforeTitle:i(g,{size:"small",onClick:f.onBack}),afterTitle:O.singleValue||!q.values||q.values.length<2?null:i(b,{sx:{ml:1},value:M,onChange:function(e,l){V(l)}})},children:[n(x,{children:[O.description&&i(u,{variant:"caption",color:"text.secondary",sx:{display:"block",mb:1},children:O.description}),i(k,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:le,onRemove:f.onRemove}),i(s,{exclusive:!0,size:"small",value:L,onChange:function(e,l){l&&_(l)},sx:{mb:1,width:"100%",".MuiToggleButton-root":{flex:1,py:.25,fontSize:"0.8rem"}},children:z.map(function(e){return i(c,{value:e,children:C[e]},e)})}),i(d,{inputRef:P,autoFocus:!0,type:"number",name:O.field.toString(),size:"small",fullWidth:!0,placeholder:"Enter number",error:ee.error,helperText:ee.message,inputProps:{step:null!==(T=null==a?void 0:a.step)&&void 0!==T?T:1,min:null==a?void 0:a.min,max:null==a?void 0:a.max},onChange:function(e){return J(e.target.value)},sx:{".MuiInputBase-root":{minHeight:"42px"}}})]}),n(y,{children:[i(v,{size:"small",color:"error",variant:"text",disabled:!q.values||0===q.values.length,onClick:function(){var e,l;null===(e=f.onRemoveField)||void 0===e||e.call(f,O.field),!1!==(null==a||null===(l=a.config)||void 0===l?void 0:l.closeAfterClear)&&f.onClose()},children:"Clear All"}),i(p,{sx:{flex:1}}),i(v,{size:"small",color:"inherit",variant:"text",onClick:f.onClose,children:"Cancel"}),i(v,{size:"small",type:"submit",color:"primary",variant:"contained",disabled:ie,children:"Apply"})]})]})})}}var F=a("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"}}});function S(){return function(e){return A(e)}}export{k as decodeNumberValue,N as default,j as encodeNumberValue,A as formatNumberChipLabel,S as formatterNumber};
2
+ //# sourceMappingURL=create-form-field-number.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form-field-number.js","sources":["../../../../src/filter-bar/menu/create-form-field-number.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, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material'\r\nimport { createChipViewers } from '../components/chip-viewer'\r\nimport { getErrorMessage } from '../../form/helpers'\r\nimport { ButtonBack, 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, TNumberOperator } from '../types'\r\n\r\n// ---------------------------------------------------------------------------\r\n// Constants\r\n// ---------------------------------------------------------------------------\r\n\r\nconst OPERATOR_SYMBOLS: Record<TNumberOperator, string> = {\r\n eq: '=',\r\n lt: '<',\r\n lte: '≤',\r\n gt: '>',\r\n gte: '≥'\r\n}\r\n\r\nconst OPERATORS: TNumberOperator[] = ['eq', 'lt', 'lte', 'gt', 'gte']\r\n\r\n// ---------------------------------------------------------------------------\r\n// Encode / decode helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Encodes operator + number into a single string stored in `values[]`. e.g. `\"gt:18\"` */\r\nexport function encodeNumberValue(operator: TNumberOperator, num: number): string {\r\n return `${operator}:${num}`\r\n}\r\n\r\n/** Decodes an encoded number value back into its parts. Returns `null` if invalid. */\r\nexport function decodeNumberValue(encoded: TFieldValid): { operator: TNumberOperator; num: number } | null {\r\n if (typeof encoded !== 'string') return null\r\n const colonIdx = encoded.indexOf(':')\r\n if (colonIdx === -1) return null\r\n const op = encoded.slice(0, colonIdx) as TNumberOperator\r\n const num = parseFloat(encoded.slice(colonIdx + 1))\r\n if (!OPERATORS.includes(op) || isNaN(num)) return null\r\n return { operator: op, num }\r\n}\r\n\r\n/** Returns a human-readable chip label for an encoded number value, e.g. `\"> 18\"`. */\r\nexport function formatNumberChipLabel(encoded: TFieldValid): string {\r\n const decoded = decodeNumberValue(encoded)\r\n if (!decoded) return String(encoded)\r\n return `${OPERATOR_SYMBOLS[decoded.operator]} ${decoded.num}`\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Public interfaces\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Props for the `FormFieldNumber` component returned by `createFormFieldNumber`. Extends the base filter-menu form props. */\r\nexport interface IFormFieldNumberProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\n/** Parameters passed to `createFormFieldNumber` to configure the generated component. */\r\nexport interface IFormFieldNumberParam<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** Default operator shown when the menu first opens. @default 'eq' */\r\n defaultOperator?: TNumberOperator\r\n /** Step for the number input. @default 1 */\r\n step?: number\r\n /** Min allowed value */\r\n min?: number\r\n /** Max allowed value */\r\n max?: number\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Factory\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Factory function that creates a `FormFieldNumber` filter-menu component.\r\n *\r\n * The generated component renders a number input with a comparison-operator\r\n * toggle (`=`, `<`, `≤`, `>`, `≥`) inside a popper/menu panel. It supports:\r\n * - OR / AND logic toggle when more than one value is applied\r\n * - Chip viewers showing the currently applied values with operator labels\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 * Each submitted value is encoded as `\"<operator>:<number>\"` (e.g. `\"gt:18\"`)\r\n * and stored in `TFieldValue.values[]`. Use `decodeNumberValue` / `formatNumberChipLabel`\r\n * to decode them when building query logic.\r\n *\r\n * @param params - Static configuration (optional field config override, default operator, step, min, max)\r\n * @returns A React FC ready to be used as a number filter-menu field component\r\n */\r\nfunction createFormFieldNumber<T>(params?: IFormFieldNumberParam<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n\r\n const FormFieldNumber: FC<IFormFieldNumberProps<T>> = (props) => {\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 ?? 'and' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n const [operator, setOperator] = useState<TNumberOperator>(params?.defaultOperator ?? 'eq')\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 = value.values.length >= 2 && filterLogic !== value.logic\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n\r\n const rawNum = parseFloat(refInput.current?.value ?? '')\r\n\r\n // Submit logic change only (no new value)\r\n if (isNaN(rawNum)) {\r\n if (hasLogicChange) {\r\n handleSubmit({ values: value.values, logic: filterLogic })\r\n }\r\n return\r\n }\r\n\r\n const obj = { [mergedConfig.field]: rawNum } as Partial<TFieldModelValid<T>>\r\n const validationError = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(validationError || {})\r\n\r\n if (!validationError || Object.keys(validationError).length === 0) {\r\n const encoded = encodeNumberValue(operator, rawNum)\r\n const newValue: TFieldValue = { values: [encoded], 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 {\r\n field: mergedConfig.field,\r\n items: items.map((v) => ({ value: v, label: formatNumberChipLabel(v) }))\r\n }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n }\r\n\r\n const hasValidInput = inputValue.trim() !== '' && !isNaN(parseFloat(inputValue))\r\n const isApplyDisabled = !hasValidInput && !hasLogicChange\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 null\r\n if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n {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 <ToggleButtonGroup\r\n exclusive\r\n size='small'\r\n value={operator}\r\n onChange={(_, val) => {\r\n if (val) setOperator(val)\r\n }}\r\n sx={{ mb: 1, width: '100%', '.MuiToggleButton-root': { flex: 1, py: 0.25, fontSize: '0.8rem' } }}\r\n >\r\n {OPERATORS.map((op) => (\r\n <ToggleButton key={op} value={op}>\r\n {OPERATOR_SYMBOLS[op]}\r\n </ToggleButton>\r\n ))}\r\n </ToggleButtonGroup>\r\n <TextField\r\n inputRef={refInput}\r\n autoFocus\r\n type='number'\r\n name={mergedConfig.field.toString()}\r\n size='small'\r\n fullWidth\r\n placeholder='Enter number'\r\n error={error.error}\r\n helperText={error.message}\r\n inputProps={{ step: params?.step ?? 1, min: params?.min, max: params?.max }}\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 FormFieldNumber\r\n}\r\n\r\nexport default createFormFieldNumber\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,\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\r\n// ---------------------------------------------------------------------------\r\n// Utilities\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Creates a labelFormatter for use in summaryConfig.\r\n * Formats encoded number values (e.g. `\"gt:18\"`) to a human-readable label (e.g. `\"> 18\"`).\r\n *\r\n * @example\r\n * summaryConfig: {\r\n * labelFormatter: { age: formatterNumber() }\r\n * }\r\n */\r\nexport function formatterNumber() {\r\n return (value: TFieldValid): string | undefined => {\r\n return formatNumberChipLabel(value)\r\n }\r\n}\r\n"],"names":["OPERATOR_SYMBOLS","eq","lt","lte","gt","gte","OPERATORS","encodeNumberValue","operator","num","concat","decodeNumberValue","encoded","colonIdx","indexOf","op","slice","parseFloat","includes","isNaN","formatNumberChipLabel","decoded","String","createFormFieldNumber","params","ChipViewers","createChipViewers","props","_mergedConfig$default","_params$defaultOperat","_mergedConfig$label","_params$step","mergedConfig","useMemo","Object","assign","currentConfig","config","refInput","createRef","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","_useState3","defaultOperator","_useState4","setOperator","_useState5","_useState6","inputValue","setInputValue","label","field","toString","_useState7","_useState8","errorData","setErrorData","handleSubmit","newValue","onSubmit","hasLogicChange","length","error","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","isApplyDisabled","trim","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_refInput$current$val","_refInput$current","_props$validator","preventDefault","stopPropagation","rawNum","current","obj","_defineProperty","validationError","validator","run","keys","blur","children","_jsxs","PopperContent","title","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","FilterLogicToggle","sx","ml","onChange","_","nVal","PopperBody","description","Typography","variant","color","display","mb","borderBottom","placement","enableMinimalesticView","onRemove","ToggleButtonGroup","exclusive","val","width","flex","py","fontSize","ToggleButton","TextField","inputRef","autoFocus","type","name","fullWidth","placeholder","helperText","message","inputProps","step","min","max","e","target","minHeight","PopperFooter","Button","disabled","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","Box","styled","position","content","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents","formatterNumber"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{slicedToArray as e,defineProperty as l,toConsumableArray as i}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as n,jsxs as o}from"react/jsx-runtime";import{useMemo as r,useState as t}from"react";import{styled as a,FormGroup as u,FormControlLabel as s,Checkbox as c,Button as v,Box as d}from"@mui/material";import{createChipViewers as f}from"../components/chip-viewer.js";import{PopperContent as m,PopperBody as p,PopperFooter as b}from"../components/popper-custom.js";import{ButtonBack as g,ChipDark as h,FilterLogicToggle as y}from"../components/ui.units.js";import{getErrorMessage as C}from"../../form/helpers.js";function x(a){var x=f(),j=(a||{}).options,k=void 0===j?[]:j;return function(f){var j,z,S=r(function(){return Object.assign({},f.currentConfig,null==a?void 0:a.config)},[null==a?void 0:a.config,f.currentConfig]),B=f.value,L=void 0===B?{values:[],logic:null!==(j=null==S?void 0:S.defaultLogic)&&void 0!==j?j:"and"}:B,R=t(L.logic),T=e(R,2),V=T[0],w=T[1],F=null!==(z=null==S?void 0:S.label)&&void 0!==z?z:S.field.toString(),I=r(function(){var e=Array.isArray(L.values)?L.values:[L.values];return k.filter(function(l){return e.includes(l.value)}).map(function(e){return e.value})},[]),N=t(I),O=e(N,2),P=O[0],_=O[1],D=t({}),E=e(D,2),H=E[0],M=E[1],q=function(e){f.onSubmit(S.field,e,S)},G=C(H,S.field),J=r(function(){var e=Array.isArray(L.values)?L.values:[L.values];return{field:S.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}})}},[S.field,L]),K=[];return f.isLoading&&K.push("disabled"),n(A,{className:K.join(" "),noValidate:!0,onSubmit:function(e){var i;e.preventDefault();var n=l({},S.field,P),o=null===(i=f.validator)||void 0===i?void 0:i.run(n);(M(o||{}),o&&0!==Object.keys(o).length)||q({values:P,logic:V})},children:o(m,{title:"Filter by ".concat(F),onClose:f.onClose,slots:{beforeTitle:n(g,{size:"small",onClick:f.onBack}),afterTitle:S.singleValue?n(h,{sx:{ml:1.5},size:"small",label:"Last value only"}):!L.values||L.values.length<2?null:n(y,{sx:{ml:1},value:V,onChange:function(e,l){return function(e){w(e);var l={values:L.values,logic:e};q(l)}(l)}})},children:[o(p,{children:[n(x,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:J,onRemove:f.onRemove}),n(u,{className:G.error?"error":"",children:k.map(function(e,l){var o,r=P.includes(e.value),t=J.items.length>0&&J.items.some(function(l){return l.value===e.value});return n(s,{value:e.value,disabled:t&&!0===(null==a?void 0:a.disabledAfterSubmit),label:null!==(o=e.label)&&void 0!==o?o:e.value,control:n(c,{name:S.field.toString(),checked:r,onChange:function(l){return n=e.value,o=l.target.checked,void _(function(e){return o?[].concat(i(e),[n]):e.filter(function(e){return e!==n})});var n,o}})},e.value.toString()+l)})})]}),o(b,{children:[n(v,{size:"small",color:"error",variant:"text",disabled:!L.values||0===L.values.length,onClick:function(){var e,l;null===(e=f.onRemoveField)||void 0===e||e.call(f,S.field),!1!==(null==a||null===(l=a.config)||void 0===l?void 0:l.closeAfterClear)&&f.onClose()},children:"Clear All"}),n(d,{sx:{flex:1}}),n(v,{size:"small",color:"inherit",variant:"text",onClick:f.onClose,children:"Cancel"}),n(v,{size:"small",type:"submit",color:"primary",variant:"contained",children:"Apply"})]})]})})}}var A=a("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 l,defineProperty as e,toConsumableArray as n}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as i,jsxs as o}from"react/jsx-runtime";import{useMemo as a,useState as t}from"react";import{styled as r,Typography as u,FormGroup as c,FormControlLabel as s,Checkbox as d,Button as v,Box as m}from"@mui/material";import{createChipViewers as f}from"../components/chip-viewer.js";import{PopperContent as p,PopperBody as b,PopperFooter as g}from"../components/popper-custom.js";import{ButtonBack as x,ChipDark as h,FilterLogicToggle as C}from"../components/ui.units.js";import{getErrorMessage as y}from"../../form/helpers.js";function V(r){var V=f(),A=(r||{}).options,j=void 0===A?[]:A;return function(f){var A,z,S,L=a(function(){return Object.assign({},f.currentConfig,null==r?void 0:r.config)},[null==r?void 0:r.config,f.currentConfig]),w=f.value,B=void 0===w?{values:[],logic:null!==(A=null==L?void 0:L.defaultLogic)&&void 0!==A?A:"and"}:w,R=t(B.logic),T=l(R,2),F=T[0],I=T[1],M=null!==(z=null==r?void 0:r.forceLogic)&&void 0!==z?z:F,N=null!==(S=null==L?void 0:L.label)&&void 0!==S?S:L.field.toString(),O=a(function(){var l=Array.isArray(B.values)?B.values:[B.values];return j.filter(function(e){return l.includes(e.value)}).map(function(l){return l.value})},[]),P=t(O),_=l(P,2),D=_[0],E=_[1],H=t({}),U=l(H,2),q=U[0],G=U[1],J=function(l){f.onSubmit(L.field,l,L)},K=y(q,L.field),Q=a(function(){var l=Array.isArray(B.values)?B.values:[B.values];return{field:L.field,items:l.map(function(l){var e;return{value:l,label:null===(e=j.find(function(e){return e.value===l}))||void 0===e?void 0:e.label}})}},[L.field,B]),W=null!=(null==r?void 0:r.maxValueCount)&&D.length>r.maxValueCount,X=null!=(null==r?void 0:r.maxValueCount)&&D.length>=r.maxValueCount,Y=[];return f.isLoading&&Y.push("disabled"),i(k,{className:Y.join(" "),noValidate:!0,onSubmit:function(l){var n;if(l.preventDefault(),!W){var i=e({},L.field,D),o=null===(n=f.validator)||void 0===n?void 0:n.run(i);if(G(o||{}),!o||0===Object.keys(o).length)J({values:D,logic:M})}},children:o(p,{title:"Filter by ".concat(N),onClose:f.onClose,slots:{beforeTitle:i(x,{size:"small",onClick:f.onBack}),afterTitle:L.singleValue?i(h,{sx:{ml:1.5},size:"small",label:"Last value only"}):null!=r&&r.forceLogic||!B.values||B.values.length<2?null:i(C,{sx:{ml:1},value:M,onChange:function(l,e){return function(l){I(l);var e={values:B.values,logic:l};J(e)}(e)}})},children:[o(b,{children:[L.description&&i(u,{variant:"caption",color:"text.secondary",sx:{mb:1,display:"block"},children:L.description}),null!=(null==r?void 0:r.maxValueCount)&&i(u,{variant:"caption",color:W?"warning.main":"text.secondary",sx:{mb:.5,display:"block"},children:null!=r&&r.maxValueCount?W?"Maximum ".concat(r.maxValueCount," value").concat(r.maxValueCount>1?"s":""," selected (limit reached)"):"Up to ".concat(r.maxValueCount," value").concat(r.maxValueCount>1?"s":""," can be selected"):""}),i(V,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:Q,onRemove:f.onRemove}),i(c,{className:K.error?"error":"",children:j.map(function(l,e){var o,a=D.includes(l.value),t=Q.items.some(function(e){return e.value===l.value})&&!0===(null==r?void 0:r.disabledAfterSubmit),u=!a&&X;return i(s,{value:l.value,disabled:t||u,label:null!==(o=l.label)&&void 0!==o?o:l.value,control:i(d,{name:L.field.toString(),checked:a,onChange:function(e){return i=l.value,o=e.target.checked,void E(function(l){return o?[].concat(n(l),[i]):l.filter(function(l){return l!==i})});var i,o}})},l.value.toString()+e)})})]}),o(g,{children:[i(v,{size:"small",color:"error",variant:"text",disabled:!B.values||0===B.values.length,onClick:function(){var l,e;null===(l=f.onRemoveField)||void 0===l||l.call(f,L.field),!1!==(null==r||null===(e=r.config)||void 0===e?void 0:e.closeAfterClear)&&f.onClose()},children:"Clear All"}),i(m,{sx:{flex:1}}),i(v,{size:"small",color:"inherit",variant:"text",onClick:f.onClose,children:"Cancel"}),i(v,{size:"small",type:"submit",color:"primary",variant:"contained",children:"Apply"})]})]})})}}var k=r("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{V 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 { useMemo, useState } from 'react'\r\nimport { Box, Button, Checkbox, FormControlLabel, FormGroup, formGroupClasses, styled } from '@mui/material'\r\nimport { getErrorMessage } from '../../form'\r\nimport { createChipViewers, TChipViewerGroup } from '../components/chip-viewer'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\n// types\r\nimport type { FC } from 'react'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { IFieldSelectOption } from './create-form-field-select'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\n\r\n/** Props for the `FormFieldSelectMultiple` component returned by `createFormFieldSelectMultiple`. Extends the base filter-menu form props. */\r\nexport interface IFormFieldSelectMultipleProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\n/** Parameters passed to `createFormFieldSelectMultiple` to configure the generated component. */\r\nexport interface IFormFieldSelectMultipleParam<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** List of options for the select field */\r\n options: IFieldSelectOption[]\r\n /** If true, disables the field after submission. @default false */\r\n disabledAfterSubmit?: boolean\r\n}\r\n\r\n/**\r\n * Factory function that creates a `FormFieldSelectMultiple` filter-menu component.\r\n *\r\n * The generated component renders a checkbox list of options inside a\r\n * popper/menu panel, allowing the user to select **multiple values** at once.\r\n * It supports:\r\n * - Controlled checkbox state to prevent uncontrolled→controlled React warnings\r\n * - OR / AND logic toggle when more than one value is applied\r\n * - Chip viewers showing the currently applied values\r\n * - Built-in validation via an optional `validator` prop\r\n * - A loading overlay that disables interaction while `isLoading` is true\r\n *\r\n * @param params - Static configuration (option list, optional field config override)\r\n * @returns A React FC ready to be used as a multi-select filter-menu field component\r\n */\r\nfunction createFormFieldSelectMultiple<T>(params?: IFormFieldSelectMultipleParam<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n const { options = [] } = params || {}\r\n\r\n const FormFieldSelectMultiple: FC<IFormFieldSelectMultipleProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const { value = { values: [], logic: mergedConfig?.defaultLogic ?? 'and' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n // Track checked values as controlled state to avoid the uncontrolled→controlled MUI warning\r\n const initialChecked = useMemo<TFieldValid[]>(() => {\r\n const values = Array.isArray(value.values) ? value.values : [value.values]\r\n return options.filter((opt) => values.includes(opt.value)).map((opt) => opt.value)\r\n }, [])\r\n const [checkedValues, setCheckedValues] = useState<TFieldValid[]>(initialChecked)\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n\r\n const handleCheckboxChange = (optionValue: TFieldValid, checked: boolean) => {\r\n setCheckedValues((prev) => (checked ? [...prev, optionValue] : prev.filter((v) => v !== optionValue)))\r\n }\r\n\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n const obj = { [mergedConfig.field]: checkedValues } as Partial<TFieldModelValid<T>>\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const newValue: TFieldValue = { values: checkedValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n }\r\n }\r\n\r\n const errorResult = getErrorMessage(errorData, mergedConfig.field)\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return {\r\n field: mergedConfig.field,\r\n items: items.map((v) => ({ value: v, label: options.find((o) => o.value === v)?.label }))\r\n }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n 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 if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <FormGroup className={errorResult.error ? 'error' : ''}>\r\n {options.map((x, i) => {\r\n const isChecked = checkedValues.includes(x.value as TFieldValid)\r\n const disabled = filterViewerValue.items.length > 0 && filterViewerValue.items.some((item) => item.value === x.value)\r\n return (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n disabled={disabled && params?.disabledAfterSubmit === true}\r\n label={x.label ?? x.value}\r\n control={\r\n <Checkbox\r\n name={mergedConfig.field.toString()}\r\n checked={isChecked}\r\n onChange={(e) => handleCheckboxChange(x.value as TFieldValid, e.target.checked)}\r\n />\r\n }\r\n />\r\n )\r\n })}\r\n </FormGroup>\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelectMultiple\r\n}\r\n\r\nexport default createFormFieldSelectMultiple\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n }\r\n // [`.${formGroupClasses.root}`]: {}\r\n})\r\n"],"names":["createFormFieldSelectMultiple","params","ChipViewers","createChipViewers","_ref$options","options","props","_mergedConfig$default","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","initialChecked","Array","isArray","filter","opt","includes","map","_useState3","_useState4","checkedValues","setCheckedValues","_useState5","_useState6","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","v","_options$find","find","o","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","obj","_defineProperty","validator","run","keys","length","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","FormGroup","error","x","i","_x$label","isChecked","disabled","some","item","FormControlLabel","disabledAfterSubmit","control","Checkbox","name","checked","e","optionValue","target","prev","_toConsumableArray","PopperFooter","Button","color","variant","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","Box","flex","type","styled","position","content","display","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 { useMemo, useState } from 'react'\r\nimport { Box, Button, Checkbox, 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 /** 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 = [] } = 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 ?? 'and' } } = 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 // Track checked values as controlled state to avoid the uncontrolled→controlled MUI warning\r\n const initialChecked = useMemo<TFieldValid[]>(() => {\r\n const values = Array.isArray(value.values) ? value.values : [value.values]\r\n return options.filter((opt) => values.includes(opt.value)).map((opt) => opt.value)\r\n }, [])\r\n const [checkedValues, setCheckedValues] = useState<TFieldValid[]>(initialChecked)\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n\r\n const handleCheckboxChange = (optionValue: TFieldValid, checked: boolean) => {\r\n setCheckedValues((prev) => (checked ? [...prev, optionValue] : prev.filter((v) => v !== optionValue)))\r\n }\r\n\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n if (isMaxReached) return\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 const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n 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 (mergedConfig.singleValue) return <ChipDark sx={{ ml: 1.5 }} size='small' label='Last value only' />\r\n if (params?.forceLogic || !value.values || value.values.length < 2) return null\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) 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 <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'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelectMultiple\r\n}\r\n\r\nexport default createFormFieldSelectMultiple\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n }\r\n // [`.${formGroupClasses.root}`]: {}\r\n})\r\n"],"names":["createFormFieldSelectMultiple","params","ChipViewers","createChipViewers","_ref$options","options","props","_mergedConfig$default","_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","initialChecked","Array","isArray","filter","opt","includes","map","_useState3","_useState4","checkedValues","setCheckedValues","_useState5","_useState6","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","v","_options$find","find","o","isMaxReached","maxValueCount","length","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","newLogic","handleChangeLogic","PopperBody","description","Typography","variant","color","mb","display","borderBottom","placement","enableMinimalesticView","onRemove","FormGroup","error","x","i","_x$label","isChecked","disabled","some","item","disabledAfterSubmit","disableDueToMax","FormControlLabel","control","Checkbox","name","checked","e","optionValue","target","prev","_toConsumableArray","PopperFooter","Button","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","Box","flex","type","styled","position","content","inset","backgroundColor","zIndex","opacity","transition","visibility","pointerEvents"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{defineProperty as e,slicedToArray as l}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useMemo as r,useState as n}from"react";import{styled as a,radioGroupClasses as t,RadioGroup as s,FormControlLabel as u,Typography as c,Radio as v,Button as d,Box as m}from"@mui/material";import{getErrorMessage as f,convertFormDataToJson as p}from"../../form/helpers.js";import{createChipViewers as b}from"../components/chip-viewer.js";import{ButtonBack as g,ChipDark as h,FilterLogicToggle as y}from"../components/ui.units.js";import{PopperContent as C,PopperBody as x,PopperFooter as j}from"../components/popper-custom.js";function z(e){var a=b(),t=e.options;return function(b){var z,k,F=r(function(){return Object.assign({},b.currentConfig,null==e?void 0:e.config)},[null==e?void 0:e.config,b.currentConfig]),L=b.value,S=void 0===L?{values:[],logic:null!==(z=null==F?void 0:F.defaultLogic)&&void 0!==z?z:"and"}:L,M=n(S.logic),R=l(M,2),T=R[0],w=R[1],B=null!==(k=null==F?void 0:F.label)&&void 0!==k?k:F.field.toString(),V=n({}),D=l(V,2),I=D[0],N=D[1],O=function(e){b.onSubmit(F.field,e,F)},P=f(I,F.field),_=r(function(){var e=Array.isArray(S.values)?S.values:[S.values];return{field:F.field,items:e.map(function(e){var l;return{value:e,label:null===(l=t.find(function(l){return l.value===e}))||void 0===l?void 0:l.label}})}},[F.field,S]),E=[];return b.isLoading&&E.push("disabled"),o(A,{className:E.join(" "),noValidate:!0,onSubmit:function(e){var l;e.preventDefault();var o=new FormData(e.currentTarget),i=p(o),r=null===(l=b.validator)||void 0===l?void 0:l.run(i);if(N(r||{}),!r||0===Object.keys(r).length){var n=F.field,a=Array.isArray(i[n])?i[n]:[i[n]];O({values:a,logic:T})}},children:i(C,{title:"Filter by ".concat(B),onClose:b.onClose,slots:{beforeTitle:o(g,{size:"small",onClick:b.onBack}),afterTitle:F.singleValue?o(h,{sx:{ml:1.5},size:"small",label:"Last value only"}):!S.values||S.values.length<2?null:o(y,{sx:{ml:1},value:T,onChange:function(e,l){return function(e){w(e);var l={values:S.values,logic:e};O(l)}(l)}})},children:[i(x,{children:[o(a,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:_,onRemove:b.onRemove}),o(s,{sx:{mx:-1},name:F.field.toString(),className:P.error?"error":"",children:t.map(function(e,l){var i,r=_.items.length>0&&_.items.some(function(l){return l.value===e.value});return o(u,{disabled:r,value:e.value,control:o(v,{size:"small"}),label:o(c,{variant:"body2",children:null!==(i=e.label)&&void 0!==i?i:e.value})},e.value.toString()+l)})}),P.error&&o(c,{variant:"caption",color:"error",sx:{mt:.5},children:P.message})]}),i(j,{children:[o(d,{size:"small",color:"error",variant:"text",disabled:!S.values||0===S.values.length,onClick:function(){var l,o;null===(l=b.onRemoveField)||void 0===l||l.call(b,F.field),!1!==(null==e||null===(o=e.config)||void 0===o?void 0:o.closeAfterClear)&&b.onClose()},children:"Clear All"}),o(m,{sx:{flex:1}}),o(d,{size:"small",color:"inherit",variant:"text",onClick:b.onClose,children:"Cancel"}),o(d,{size:"small",type:"submit",color:"primary",variant:"contained",children:"Apply"})]})]})})}}var A=a("form")(e({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.2)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}},".".concat(t.root),{"&.error .MuiRadio-root":{color:"#d32f2f"},".MuiFormControlLabel-root":{margin:0},".MuiFormControlLabel-root:hover":{backgroundColor:"rgba(25, 118, 210, 0.04)"}}));export{z as default};
1
+ import{defineProperty as e,slicedToArray as l}from"../../../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useMemo as n,useState as r}from"react";import{styled as a,radioGroupClasses as t,Typography as u,RadioGroup as c,FormControlLabel as s,Radio as d,Button as m,Box as v}from"@mui/material";import{getErrorMessage as f,convertFormDataToJson as p}from"../../form/helpers.js";import{createChipViewers as b}from"../components/chip-viewer.js";import{ButtonBack as g,ChipDark as x,FilterLogicToggle as h}from"../components/ui.units.js";import{PopperContent as C,PopperBody as y,PopperFooter as V}from"../components/popper-custom.js";function k(e){var a=b(),t=e.options;return function(b){var k,z,A,L=n(function(){return Object.assign({},b.currentConfig,null==e?void 0:e.config)},[null==e?void 0:e.config,b.currentConfig]),F=b.value,M=void 0===F?{values:[],logic:null!==(k=null==L?void 0:L.defaultLogic)&&void 0!==k?k:"and"}:F,S=r(M.logic),w=l(S,2),R=w[0],T=w[1],B=null!==(z=e.forceLogic)&&void 0!==z?z:R,D=null!==(A=null==L?void 0:L.label)&&void 0!==A?A:L.field.toString(),I=r({}),N=l(I,2),O=N[0],P=N[1],_=function(e){b.onSubmit(L.field,e,L)},E=f(O,L.field),H=n(function(){var e=Array.isArray(M.values)?M.values:[M.values];return{field:L.field,items:e.map(function(e){var l;return{value:e,label:null===(l=t.find(function(l){return l.value===e}))||void 0===l?void 0:l.label}})}},[L.field,M]),U=null!=e.maxValueCount&&H.items.length>=e.maxValueCount,q=[];return b.isLoading&&q.push("disabled"),o(j,{className:q.join(" "),noValidate:!0,onSubmit:function(e){var l;if(e.preventDefault(),!U){var o=new FormData(e.currentTarget),i=p(o),n=null===(l=b.validator)||void 0===l?void 0:l.run(i);if(P(n||{}),!n||0===Object.keys(n).length){var r=L.field,a=Array.isArray(i[r])?i[r]:[i[r]];_({values:a,logic:B})}}},children:i(C,{title:"Filter by ".concat(D),onClose:b.onClose,slots:{beforeTitle:o(g,{size:"small",onClick:b.onBack}),afterTitle:L.singleValue?o(x,{sx:{ml:1.5},size:"small",label:"Last value only"}):e.forceLogic||!M.values||M.values.length<2?null:o(h,{sx:{ml:1},value:B,onChange:function(e,l){return function(e){T(e);var l={values:M.values,logic:e};_(l)}(l)}})},children:[i(y,{children:[L.description&&o(u,{variant:"caption",color:"text.secondary",sx:{mb:1,display:"block"},children:L.description}),null!=e.maxValueCount&&o(u,{variant:"caption",color:U?"warning.main":"text.secondary",sx:{mb:.5,display:"block"},children:e.maxValueCount?U?"Maximum ".concat(e.maxValueCount," value").concat(e.maxValueCount>1?"s":""," selected (limit reached)"):"Up to ".concat(e.maxValueCount," value").concat(e.maxValueCount>1?"s":""," can be selected"):""}),o(a,{sx:{mb:1,borderBottom:"none!important"},label:"Applied",placement:"horizontal",enableMinimalesticView:!0,value:H,onRemove:b.onRemove}),o(c,{sx:{mx:-1},name:L.field.toString(),className:E.error?"error":"",children:t.map(function(e,l){var i,n=H.items.some(function(l){return l.value===e.value});return o(s,{disabled:n||U,value:e.value,control:o(d,{size:"small"}),label:o(u,{variant:"body2",children:null!==(i=e.label)&&void 0!==i?i:e.value})},e.value.toString()+l)})}),E.error&&o(u,{variant:"caption",color:"error",sx:{mt:.5},children:E.message})]}),i(V,{children:[o(m,{size:"small",color:"error",variant:"text",disabled:!M.values||0===M.values.length,onClick:function(){var l,o;null===(l=b.onRemoveField)||void 0===l||l.call(b,L.field),!1!==(null==e||null===(o=e.config)||void 0===o?void 0:o.closeAfterClear)&&b.onClose()},children:"Clear All"}),o(v,{sx:{flex:1}}),o(m,{size:"small",color:"inherit",variant:"text",onClick:b.onClose,children:"Cancel"}),o(m,{size:"small",type:"submit",color:"primary",variant:"contained",children:"Apply"})]})]})})}}var j=a("form")(e({position:"relative","&::after":{content:'""',display:"block",position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.2)",filter:"blur(2px)",zIndex:-1,opacity:0,transition:"opacity 0.3s",visibility:"hidden"},"&.disabled":{pointerEvents:"none","&::after":{zIndex:1,opacity:1,visibility:"visible"}}},".".concat(t.root),{"&.error .MuiRadio-root":{color:"#d32f2f"},".MuiFormControlLabel-root":{margin:0},".MuiFormControlLabel-root:hover":{backgroundColor:"rgba(25, 118, 210, 0.04)"}}));export{k 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, useMemo, useState } from 'react'\r\nimport { Box, Button, FormControlLabel, Radio, RadioGroup, radioGroupClasses, styled, Typography } from '@mui/material'\r\nimport { convertFormDataToJson, getErrorMessage } from '../../form/helpers'\r\nimport { createChipViewers, TChipViewerGroup } from '../components/chip-viewer'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\n\r\n/** Props for the `FormFieldSelect` component returned by `createFormFieldSelect`. Extends the base filter-menu form props. */\r\nexport interface IFormFieldSelectProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\n/** A single option item rendered as a radio button inside the select filter menu. */\r\nexport interface IFieldSelectOption {\r\n value: TFieldValid\r\n label?: string\r\n}\r\n\r\n/** Parameters passed to `createFormFieldSelect` to configure the generated component. */\r\nexport interface IFormFieldSelectParams<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** List of options for the select field */\r\n options: IFieldSelectOption[]\r\n}\r\n\r\n/**\r\n * Factory function that creates a `FormFieldSelect` filter-menu component.\r\n *\r\n * The generated component renders a radio-button list of options inside a\r\n * popper/menu panel. It supports:\r\n * - Single or multi-value selection (controlled by `config.singleValue`)\r\n * - OR / AND logic toggle when more than one value is selected\r\n * - Chip viewers showing the currently applied values\r\n * - Built-in validation via an optional `validator` prop\r\n * - A loading overlay that disables interaction while `isLoading` is true\r\n *\r\n * @param params - Static configuration (option list, optional field config override)\r\n * @returns A React FC ready to be used as a filter-menu field component\r\n */\r\nfunction createFormFieldSelect<T>(params: IFormFieldSelectParams<T>) {\r\n const ChipViewers = createChipViewers<T>()\r\n const { options } = params\r\n\r\n const FormFieldSelect: FC<IFormFieldSelectProps<T>> = (props) => {\r\n /** Merge `props.currentConfig` with `params.config` (if provided).\r\n * Fields from `params.config` override the corresponding keys in `props.currentConfig`.\r\n * Any keys not present in `params.config` are preserved from `props.currentConfig`.\r\n */\r\n const mergedConfig = useMemo(() => Object.assign({}, props.currentConfig, params?.config), [params?.config, props.currentConfig])\r\n\r\n const { value = { values: [], logic: mergedConfig?.defaultLogic ?? 'and' } } = props\r\n const [filterLogic, setFilterLogic] = useState<TLogic>(value.logic!)\r\n\r\n const label = mergedConfig?.label ?? mergedConfig.field.toString()\r\n\r\n const [errorData, setErrorData] = useState<IPartialError<TFieldModelValid<T>>>({})\r\n const handleSubmit = (newValue: TFieldValue) => {\r\n props.onSubmit(mergedConfig.field, newValue, mergedConfig)\r\n }\r\n\r\n const handleSubmitForm = (event: React.FormEvent<HTMLFormElement>) => {\r\n event.preventDefault()\r\n const formData = new FormData(event.currentTarget)\r\n const obj = convertFormDataToJson<TFieldModelValid<T>>(formData)\r\n let errorData = props.validator?.run(obj) as IPartialError<TFieldModelValid<T>>\r\n\r\n setErrorData(errorData || {})\r\n\r\n if (!errorData || Object.keys(errorData).length === 0) {\r\n const { field } = mergedConfig\r\n const newValues = (Array.isArray(obj[field]) ? obj[field] : [obj[field]]) as TFieldValid[]\r\n const newValue: TFieldValue = { values: newValues, logic: filterLogic }\r\n handleSubmit(newValue)\r\n }\r\n }\r\n\r\n const errorResult = getErrorMessage(errorData, mergedConfig.field)\r\n const filterViewerValue = useMemo<TChipViewerGroup<T>>(() => {\r\n const items = Array.isArray(value.values) ? value.values : [value.values]\r\n return {\r\n field: mergedConfig.field,\r\n items: items.map((v) => ({ value: v, label: options.find((o) => o.value === v)?.label }))\r\n }\r\n }, [mergedConfig.field, value])\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n 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 if (!value.values || value.values.length < 2) return null\r\n return <FilterLogicToggle sx={{ ml: 1 }} value={filterLogic} onChange={(_, nVal) => handleChangeLogic(nVal)} />\r\n }\r\n\r\n const rootClasses: string[] = []\r\n if (props.isLoading) rootClasses.push('disabled')\r\n\r\n return (\r\n <RootStyled className={rootClasses.join(' ')} noValidate onSubmit={handleSubmitForm}>\r\n <PopperContent\r\n title={`Filter by ${label}`}\r\n onClose={props.onClose}\r\n slots={{\r\n beforeTitle: <ButtonBack size='small' onClick={props.onBack} />,\r\n afterTitle: renderAfterTitle()\r\n }}\r\n >\r\n <PopperBody>\r\n <ChipViewers\r\n sx={{ mb: 1, borderBottom: 'none!important' }}\r\n label='Applied'\r\n placement='horizontal'\r\n enableMinimalesticView\r\n value={filterViewerValue}\r\n onRemove={props.onRemove}\r\n />\r\n <RadioGroup sx={{ mx: -1 }} name={mergedConfig.field.toString()} className={errorResult.error ? 'error' : ''}>\r\n {options.map((x, i) => {\r\n const disabled = filterViewerValue.items.length > 0 && filterViewerValue.items.some((item) => item.value === x.value)\r\n return (\r\n <FormControlLabel\r\n disabled={disabled}\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n control={<Radio size='small' />}\r\n label={<Typography variant='body2'>{x.label ?? x.value}</Typography>}\r\n />\r\n )\r\n })}\r\n </RadioGroup>\r\n {errorResult.error && (\r\n <Typography variant='caption' color='error' sx={{ mt: 0.5 }}>\r\n {errorResult.message}\r\n </Typography>\r\n )}\r\n </PopperBody>\r\n <PopperFooter>\r\n <Button size='small' color='error' variant='text' disabled={!value.values || value.values.length === 0} onClick={handleClearAll}>\r\n Clear All\r\n </Button>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size='small' color='inherit' variant='text' onClick={props.onClose}>\r\n Cancel\r\n </Button>\r\n <Button size='small' type='submit' color='primary' variant='contained'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelect\r\n}\r\n\r\nexport default createFormFieldSelect\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n },\r\n [`.${radioGroupClasses.root}`]: {\r\n '&.error .MuiRadio-root': { color: '#d32f2f' },\r\n '.MuiFormControlLabel-root': { margin: 0 },\r\n '.MuiFormControlLabel-root:hover': { backgroundColor: 'rgba(25, 118, 210, 0.04)' }\r\n }\r\n})\r\n"],"names":["createFormFieldSelect","params","ChipViewers","createChipViewers","options","props","_mergedConfig$default","_mergedConfig$label","mergedConfig","useMemo","Object","assign","currentConfig","config","_props$value","value","values","logic","defaultLogic","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","label","field","toString","_useState3","_useState4","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","_options$find","find","o","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","formData","FormData","currentTarget","obj","convertFormDataToJson","validator","run","keys","length","newValues","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","mb","borderBottom","placement","enableMinimalesticView","onRemove","RadioGroup","mx","name","error","x","i","_x$label","disabled","some","item","FormControlLabel","control","Radio","Typography","variant","color","mt","message","PopperFooter","Button","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","Box","flex","type","styled","_defineProperty","position","content","display","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents","radioGroupClasses","root","margin"],"mappings":"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"}
1
+ {"version":3,"file":"create-form-field-select.js","sources":["../../../../src/filter-bar/menu/create-form-field-select.tsx"],"sourcesContent":["import { FC, useMemo, useState } from 'react'\r\nimport { Box, Button, FormControlLabel, Radio, RadioGroup, radioGroupClasses, styled, Typography } from '@mui/material'\r\nimport { convertFormDataToJson, getErrorMessage } from '../../form/helpers'\r\nimport { createChipViewers, TChipViewerGroup } from '../components/chip-viewer'\r\nimport { ButtonBack, ChipDark, FilterLogicToggle } from '../components/ui.units'\r\nimport { PopperBody, PopperContent, PopperFooter } from '../components/popper-custom'\r\nimport type { IPartialError } from '../../form/validator'\r\nimport type { IFieldMenuConfig, IFilterMenuFormProps } from './types'\r\nimport type { TFieldModelValid, TFieldValid, TFieldValue, TLogic } from '../types'\r\n\r\n/** Props for the `FormFieldSelect` component returned by `createFormFieldSelect`. Extends the base filter-menu form props. */\r\nexport interface IFormFieldSelectProps<T> extends IFilterMenuFormProps<T> {}\r\n\r\n/** A single option item rendered as a radio button inside the select filter menu. */\r\nexport interface IFieldSelectOption {\r\n value: TFieldValid\r\n label?: string\r\n}\r\n\r\n/** Parameters passed to `createFormFieldSelect` to configure the generated component. */\r\nexport interface IFormFieldSelectParams<T> {\r\n /** Optional configuration for the form field */\r\n config?: IFieldMenuConfig<T>\r\n /** List of options for the select field */\r\n options: IFieldSelectOption[]\r\n forceLogic?: TLogic\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 ?? 'and' } } = 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 [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 if (isMaxReached) return\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: 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 && filterViewerValue.items.length >= params.maxValueCount\r\n\r\n const handleChangeLogic = (newLogic: TLogic) => {\r\n setFilterLogic(newLogic)\r\n const newValue: TFieldValue = { values: value.values, logic: newLogic }\r\n handleSubmit(newValue)\r\n }\r\n\r\n const handleClearAll = () => {\r\n props.onRemoveField?.(mergedConfig.field)\r\n 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 if (params.forceLogic || !value.values || value.values.length < 2) return null\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) 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 <RadioGroup sx={{ mx: -1 }} name={mergedConfig.field.toString()} className={errorResult.error ? 'error' : ''}>\r\n {options.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'>\r\n Apply\r\n </Button>\r\n </PopperFooter>\r\n </PopperContent>\r\n </RootStyled>\r\n )\r\n }\r\n\r\n return FormFieldSelect\r\n}\r\n\r\nexport default createFormFieldSelect\r\n\r\nconst RootStyled = styled('form')({\r\n position: 'relative',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n position: 'absolute',\r\n inset: 0, // top: 0, left: 0, right: 0, bottom: 0\r\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\r\n filter: 'blur(2px)',\r\n zIndex: -1,\r\n opacity: 0,\r\n transition: 'opacity 0.3s',\r\n visibility: 'hidden'\r\n },\r\n '&.disabled': {\r\n pointerEvents: 'none',\r\n '&::after': {\r\n zIndex: 1,\r\n opacity: 1,\r\n visibility: 'visible'\r\n }\r\n },\r\n [`.${radioGroupClasses.root}`]: {\r\n '&.error .MuiRadio-root': { color: '#d32f2f' },\r\n '.MuiFormControlLabel-root': { margin: 0 },\r\n '.MuiFormControlLabel-root:hover': { backgroundColor: 'rgba(25, 118, 210, 0.04)' }\r\n }\r\n})\r\n"],"names":["createFormFieldSelect","params","ChipViewers","createChipViewers","options","props","_mergedConfig$default","_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","errorData","setErrorData","handleSubmit","newValue","onSubmit","errorResult","getErrorMessage","filterViewerValue","items","Array","isArray","map","v","_options$find","find","o","isMaxReached","maxValueCount","length","rootClasses","isLoading","push","_jsx","RootStyled","className","join","noValidate","event","_props$validator","preventDefault","formData","FormData","currentTarget","obj","convertFormDataToJson","validator","run","keys","newValues","children","_jsxs","PopperContent","title","concat","onClose","slots","beforeTitle","ButtonBack","size","onClick","onBack","afterTitle","singleValue","ChipDark","sx","ml","FilterLogicToggle","onChange","_","nVal","newLogic","handleChangeLogic","PopperBody","description","Typography","variant","color","mb","display","borderBottom","placement","enableMinimalesticView","onRemove","RadioGroup","mx","name","error","x","i","_x$label","isSelected","some","item","FormControlLabel","disabled","control","Radio","mt","message","PopperFooter","Button","_props$onRemoveField","_params$config","onRemoveField","call","closeAfterClear","Box","flex","type","styled","_defineProperty","position","content","inset","backgroundColor","filter","zIndex","opacity","transition","visibility","pointerEvents","radioGroupClasses","root","margin"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../../src/filter-bar/types.ts"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n/**\r\n * @en\r\n * - Allowed primitive values for filter fields.\r\n * - Runtime types: string, number, boolean.\r\n * - Use ISO date strings or a discriminated union if date/serialization handling is needed.\r\n * @vi\r\n * - Gia tri nguyen thuy hop le cho cac field filter.\r\n * - Kieu runtime: string, number, boolean.\r\n * - Neu can xu ly Date qua mang/serialize thi dung chuoi ISO hoac discriminated union.\r\n */\r\nexport type TFieldValid = string | number | boolean\r\n/**\r\n * @en\r\n * - Special UI-only filter keys (e.g. quickSearch).\r\n * - Kept as const so `TypeScript` preserves literal types.\r\n * @vi\r\n * - Khoa filter dac biet cho UI (vi dụ: quickSearch).\r\n * - Giu const de `TypeScript` giu literal types.\r\n */\r\nexport const KeySpecial = {\r\n quickSearch: 'quickSearch',\r\n sortShuffle: 'sortShuffle'\r\n} as const\r\nexport type KeySpecial = keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Union of model field keys and special filter keys used by the filter system.\r\n * - Purpose: allow filters to reference either a model property or a special UI key.\r\n * @vi\r\n * - Tap hop cac khoa cua model va cac khoa filter dac biet cho he thong filter.\r\n * - Muc dich: cho phep filter tham chieu truong model hoac key UI dac biet.\r\n */\r\nexport type TFieldType<T> = keyof T | keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Merge external model with special filter keys so filters can reference both.\r\n * - Purpose: extend a model type with UI special keys (e.g. quickSearch) for safe typing.\r\n * @vi\r\n * - Gop model ngoai voi cac key filter dac biet de filter co the tham chieu ca hai.\r\n * - Muc dich: mo rong kieu model de chua cac key UI (vd quickSearch) de type an toan.\r\n */\r\nexport type TFieldModelValid<T> = T & Record<keyof typeof KeySpecial, any>\r\n\r\n/**\r\n * @en Sorting direction for fields.\r\n * @vi Huong sap xep cho cac truong.\r\n */\r\nexport type TDirection = 'asc' | 'desc'\r\n/**\r\n * @en Interface for defining sorting behavior on a field.\r\n * @vi Giao dien de dinh nghia cach sap xep tren mot truong.\r\n */\r\nexport type TFieldSort<T> = {\r\n field: TFieldType<T>\r\n /** Sorting direction. Optional. Default is 'desc'. */\r\n direction?: TDirection\r\n}\r\n/**\r\n * @en Definition of core types for the filter bar system, including filter values, field types, and overall filter state structure.\r\n * @vi Dinh nghia cac kieu co ban cho he thong filter bar, bao gom gia tri filter, kieu field va cau truc tong the cua filter state.\r\n */\r\nexport type TLogic = 'and' | 'or'\r\n\r\nexport type TDateLogic = 'before' | 'after' | 'on' | 'range'\r\n/**\r\n * @en\r\n * - Structure for storing filter values and their logical relationship (AND/OR) for each field.\r\n * @vi\r\n * - Cau truc de luu tru cac gia tri filter va moi quan he logic (AND/OR) cho moi field.\r\n */\r\nexport type TFieldValue = {\r\n /** Logical operator for combining values within this field. Default is 'and'. */\r\n logic?: TLogic\r\n /** Logical operator for date-specific filtering. Optional. */\r\n dateLogic?: TDateLogic\r\n values: TFieldValid[]\r\n}\r\n/**\r\n * @en\r\n * - Type for storing active filters in the filter state, mapping field keys to their filter values.\r\n * @vi\r\n * - Kieu de luu tru cac filter dang hoat dong trong filter state, map cac khoa field voi gia tri filter cua chung.\r\n */\r\nexport type TFieldStore<T> = Partial<Record<TFieldType<T>, TFieldValue>>\r\n/**\r\n * @en\r\n * - Overall filter state structure, including the logical operator for combining filters and optional storage for active filters and sorting.\r\n * @vi\r\n * - Cau truc tong the cho filter state, bao gom toan tu logic de ket hop cac filter va luu tru tuy chon cho cac filter dang hoat dong va sap xep.\r\n */\r\nexport type TFilterState<T> = {\r\n /** Logical operator for combining filters. Default is 'and'. */\r\n filterLogic?: TLogic\r\n storeFilter?: TFieldStore<T>\r\n storeSort?: TFieldSort<T>\r\n}\r\n"],"names":["KeySpecial","quickSearch","sortShuffle"],"mappings":"AAqBO,IAAMA,EAAa,CACxBC,YAAa,cACbC,YAAa"}
1
+ {"version":3,"file":"types.js","sources":["../../../src/filter-bar/types.ts"],"sourcesContent":["// Copyright (c) 2024-present, Dinocollab Technologies, Inc. and its affiliates. All rights reserved.\r\n\r\n/**\r\n * @en\r\n * - Allowed primitive values for filter fields.\r\n * - Runtime types: string, number, boolean.\r\n * - Use ISO date strings or a discriminated union if date/serialization handling is needed.\r\n * @vi\r\n * - Gia tri nguyen thuy hop le cho cac field filter.\r\n * - Kieu runtime: string, number, boolean.\r\n * - Neu can xu ly Date qua mang/serialize thi dung chuoi ISO hoac discriminated union.\r\n */\r\nexport type TFieldValid = string | number | boolean\r\n/**\r\n * @en\r\n * - Special UI-only filter keys (e.g. quickSearch).\r\n * - Kept as const so `TypeScript` preserves literal types.\r\n * @vi\r\n * - Khoa filter dac biet cho UI (vi dụ: quickSearch).\r\n * - Giu const de `TypeScript` giu literal types.\r\n */\r\nexport const KeySpecial = {\r\n quickSearch: 'quickSearch',\r\n sortShuffle: 'sortShuffle'\r\n} as const\r\nexport type KeySpecial = keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Union of model field keys and special filter keys used by the filter system.\r\n * - Purpose: allow filters to reference either a model property or a special UI key.\r\n * @vi\r\n * - Tap hop cac khoa cua model va cac khoa filter dac biet cho he thong filter.\r\n * - Muc dich: cho phep filter tham chieu truong model hoac key UI dac biet.\r\n */\r\nexport type TFieldType<T> = keyof T | keyof typeof KeySpecial\r\n/**\r\n * @en\r\n * - Merge external model with special filter keys so filters can reference both.\r\n * - Purpose: extend a model type with UI special keys (e.g. quickSearch) for safe typing.\r\n * @vi\r\n * - Gop model ngoai voi cac key filter dac biet de filter co the tham chieu ca hai.\r\n * - Muc dich: mo rong kieu model de chua cac key UI (vd quickSearch) de type an toan.\r\n */\r\nexport type TFieldModelValid<T> = T & Record<keyof typeof KeySpecial, any>\r\n\r\n/**\r\n * @en Sorting direction for fields.\r\n * @vi Huong sap xep cho cac truong.\r\n */\r\nexport type TDirection = 'asc' | 'desc'\r\n/**\r\n * @en Interface for defining sorting behavior on a field.\r\n * @vi Giao dien de dinh nghia cach sap xep tren mot truong.\r\n */\r\nexport type TFieldSort<T> = {\r\n field: TFieldType<T>\r\n /** Sorting direction. Optional. Default is 'desc'. */\r\n direction?: TDirection\r\n}\r\n/**\r\n * @en Definition of core types for the filter bar system, including filter values, field types, and overall filter state structure.\r\n * @vi Dinh nghia cac kieu co ban cho he thong filter bar, bao gom gia tri filter, kieu field va cau truc tong the cua filter state.\r\n */\r\nexport type TLogic = 'and' | 'or'\r\n\r\nexport type TDateLogic = 'before' | 'after' | 'on' | 'range'\r\n\r\nexport type TNumberOperator = 'eq' | 'lt' | 'lte' | 'gt' | 'gte'\r\n/**\r\n * @en\r\n * - Structure for storing filter values and their logical relationship (AND/OR) for each field.\r\n * @vi\r\n * - Cau truc de luu tru cac gia tri filter va moi quan he logic (AND/OR) cho moi field.\r\n */\r\nexport type TFieldValue = {\r\n /** Logical operator for combining values within this field. Default is 'and'. */\r\n logic?: TLogic\r\n /** Logical operator for date-specific filtering. Optional. */\r\n dateLogic?: TDateLogic\r\n values: TFieldValid[]\r\n}\r\n/**\r\n * @en\r\n * - Type for storing active filters in the filter state, mapping field keys to their filter values.\r\n * @vi\r\n * - Kieu de luu tru cac filter dang hoat dong trong filter state, map cac khoa field voi gia tri filter cua chung.\r\n */\r\nexport type TFieldStore<T> = Partial<Record<TFieldType<T>, TFieldValue>>\r\n/**\r\n * @en\r\n * - Overall filter state structure, including the logical operator for combining filters and optional storage for active filters and sorting.\r\n * @vi\r\n * - Cau truc tong the cho filter state, bao gom toan tu logic de ket hop cac filter va luu tru tuy chon cho cac filter dang hoat dong va sap xep.\r\n */\r\nexport type TFilterState<T> = {\r\n /** Logical operator for combining filters. Default is 'and'. */\r\n filterLogic?: TLogic\r\n storeFilter?: TFieldStore<T>\r\n storeSort?: TFieldSort<T>\r\n}\r\n"],"names":["KeySpecial","quickSearch","sortShuffle"],"mappings":"AAqBO,IAAMA,EAAa,CACxBC,YAAa,cACbC,YAAa"}
@@ -20,7 +20,7 @@ type TAutoMapConfig<TSource, TTarget extends object, U extends object = {}> = {
20
20
  * @en The operation to apply for the filter field. @default 'contains'
21
21
  * @vi Thao tác áp dụng cho trường filter. @default 'contains'
22
22
  */
23
- operation?: 'equal' | 'contains' | 'datetime' | 'equalAndAny';
23
+ operation?: 'equal' | 'equalAndAny' | 'contains' | 'datetime' | 'number';
24
24
  /**
25
25
  * @en
26
26
  * - Custom function to apply complex filter logic that doesn't fit standard 'equal' or 'contains' operations.
@@ -47,6 +47,7 @@ export declare class TableFileterConverter<TSource extends Record<string, any>,
47
47
  }): this;
48
48
  filterContains(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption): this;
49
49
  filterDatetime(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption): this;
50
+ filterNumber(field: TFieldType<TSource>, targetField?: keyof TTarget, options?: TFilterOption): this;
50
51
  sort(param?: {
51
52
  seed: {
52
53
  targetField?: TFieldType<TSource>;
@@ -7,4 +7,5 @@ export * from './index.dino';
7
7
  export type { IFieldSelectOption } from './menu/create-form-field-select';
8
8
  export type { IFormFieldDateTimeParam, TDateTimePickerType, TDateTimeMode } from './menu/create-form-field-datetime';
9
9
  export * from './menu/create-form-field-datetime';
10
+ export * from './menu/create-form-field-number';
10
11
  export { mergeValueToStoreFilter, mergeSingleValueToStoreFilter } from './hooks';
@@ -2,6 +2,7 @@ import { createFilterBar } from './index.create';
2
2
  import { getFilterFromURL, isEmptyFilterState, isFilterStateEqual, removeNullValues, setFilterToURL } from './helpers';
3
3
  import createFormFieldString from './menu/create-form-field-string';
4
4
  import createFormFieldSelect from './menu/create-form-field-select';
5
+ import createFormFieldNumber, { formatterNumber } from './menu/create-form-field-number';
5
6
  import createFormFieldSelectMultiple from './menu/create-form-field-select-multiple';
6
7
  import createFormFieldDateTime, { formatterDateTime } from './menu/create-form-field-datetime';
7
8
  export declare class DinoFilterBar {
@@ -9,12 +10,14 @@ export declare class DinoFilterBar {
9
10
  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>;
10
11
  createLocalFilterBuilder: <T>(data: T[], filterState: import("./types").TFilterState<T>) => import("./local-filter-builder").LocalFilterBuilder<T>;
11
12
  createFormFieldString: typeof createFormFieldString;
13
+ createFormFieldNumber: typeof createFormFieldNumber;
12
14
  createFormFieldSelect: typeof createFormFieldSelect;
13
15
  createFormFieldSelectMultiple: typeof createFormFieldSelectMultiple;
14
16
  createFormFieldDateTime: typeof createFormFieldDateTime;
15
17
  mapLogic: (logic?: import("./types").TLogic | undefined) => "Or" | "And";
16
18
  mapDirection: (direction?: import("./types").TDirection | undefined) => "ASC" | "DESC";
17
19
  formatterDateTime: typeof formatterDateTime;
20
+ formatterNumber: typeof formatterNumber;
18
21
  isEmptyFilterState: typeof isEmptyFilterState;
19
22
  removeNullValues: typeof removeNullValues;
20
23
  isFilterStateEqual: typeof isFilterStateEqual;
@@ -0,0 +1,58 @@
1
+ import type { FC } from 'react';
2
+ import type { IFieldMenuConfig, IFilterMenuFormProps } from './types';
3
+ import type { TFieldValid, TNumberOperator } from '../types';
4
+ /** Encodes operator + number into a single string stored in `values[]`. e.g. `"gt:18"` */
5
+ export declare function encodeNumberValue(operator: TNumberOperator, num: number): string;
6
+ /** Decodes an encoded number value back into its parts. Returns `null` if invalid. */
7
+ export declare function decodeNumberValue(encoded: TFieldValid): {
8
+ operator: TNumberOperator;
9
+ num: number;
10
+ } | null;
11
+ /** Returns a human-readable chip label for an encoded number value, e.g. `"> 18"`. */
12
+ export declare function formatNumberChipLabel(encoded: TFieldValid): string;
13
+ /** Props for the `FormFieldNumber` component returned by `createFormFieldNumber`. Extends the base filter-menu form props. */
14
+ export interface IFormFieldNumberProps<T> extends IFilterMenuFormProps<T> {
15
+ }
16
+ /** Parameters passed to `createFormFieldNumber` to configure the generated component. */
17
+ export interface IFormFieldNumberParam<T> {
18
+ /** Optional configuration for the form field */
19
+ config?: IFieldMenuConfig<T>;
20
+ /** Default operator shown when the menu first opens. @default 'eq' */
21
+ defaultOperator?: TNumberOperator;
22
+ /** Step for the number input. @default 1 */
23
+ step?: number;
24
+ /** Min allowed value */
25
+ min?: number;
26
+ /** Max allowed value */
27
+ max?: number;
28
+ }
29
+ /**
30
+ * Factory function that creates a `FormFieldNumber` filter-menu component.
31
+ *
32
+ * The generated component renders a number input with a comparison-operator
33
+ * toggle (`=`, `<`, `≤`, `>`, `≥`) inside a popper/menu panel. It supports:
34
+ * - OR / AND logic toggle when more than one value is applied
35
+ * - Chip viewers showing the currently applied values with operator labels
36
+ * - Auto-focus and input reset after each successful submission
37
+ * - Built-in validation via an optional `validator` prop
38
+ * - A loading overlay that disables interaction while `isLoading` is true
39
+ *
40
+ * Each submitted value is encoded as `"<operator>:<number>"` (e.g. `"gt:18"`)
41
+ * and stored in `TFieldValue.values[]`. Use `decodeNumberValue` / `formatNumberChipLabel`
42
+ * to decode them when building query logic.
43
+ *
44
+ * @param params - Static configuration (optional field config override, default operator, step, min, max)
45
+ * @returns A React FC ready to be used as a number filter-menu field component
46
+ */
47
+ declare function createFormFieldNumber<T>(params?: IFormFieldNumberParam<T>): FC<IFormFieldNumberProps<T>>;
48
+ export default createFormFieldNumber;
49
+ /**
50
+ * Creates a labelFormatter for use in summaryConfig.
51
+ * Formats encoded number values (e.g. `"gt:18"`) to a human-readable label (e.g. `"> 18"`).
52
+ *
53
+ * @example
54
+ * summaryConfig: {
55
+ * labelFormatter: { age: formatterNumber() }
56
+ * }
57
+ */
58
+ export declare function formatterNumber(): (value: TFieldValid) => string | undefined;
@@ -1,5 +1,6 @@
1
1
  import type { FC } from 'react';
2
2
  import type { IFieldSelectOption } from './create-form-field-select';
3
+ import type { TLogic } from '../types';
3
4
  import type { IFieldMenuConfig, IFilterMenuFormProps } from './types';
4
5
  /** Props for the `FormFieldSelectMultiple` component returned by `createFormFieldSelectMultiple`. Extends the base filter-menu form props. */
5
6
  export interface IFormFieldSelectMultipleProps<T> extends IFilterMenuFormProps<T> {
@@ -12,6 +13,10 @@ export interface IFormFieldSelectMultipleParam<T> {
12
13
  options: IFieldSelectOption[];
13
14
  /** If true, disables the field after submission. @default false */
14
15
  disabledAfterSubmit?: boolean;
16
+ /** Force a fixed logic value, hiding the logic toggle */
17
+ forceLogic?: TLogic;
18
+ /** Maximum number of values that can be selected */
19
+ maxValueCount?: number;
15
20
  }
16
21
  /**
17
22
  * Factory function that creates a `FormFieldSelectMultiple` filter-menu component.
@@ -1,6 +1,6 @@
1
1
  import { FC } from 'react';
2
2
  import type { IFieldMenuConfig, IFilterMenuFormProps } from './types';
3
- import type { TFieldValid } from '../types';
3
+ import type { TFieldValid, TLogic } 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
6
  }
@@ -15,6 +15,8 @@ export interface IFormFieldSelectParams<T> {
15
15
  config?: IFieldMenuConfig<T>;
16
16
  /** List of options for the select field */
17
17
  options: IFieldSelectOption[];
18
+ forceLogic?: TLogic;
19
+ maxValueCount?: number;
18
20
  }
19
21
  /**
20
22
  * Factory function that creates a `FormFieldSelect` filter-menu component.
@@ -60,6 +60,7 @@ export type TFieldSort<T> = {
60
60
  */
61
61
  export type TLogic = 'and' | 'or';
62
62
  export type TDateLogic = 'before' | 'after' | 'on' | 'range';
63
+ export type TNumberOperator = 'eq' | 'lt' | 'lte' | 'gt' | 'gte';
63
64
  /**
64
65
  * @en
65
66
  * - Structure for storing filter values and their logical relationship (AND/OR) for each field.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinocollab-core",
3
- "version": "2.2.27",
3
+ "version": "2.2.29",
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",