@tachybase/client 1.6.18 → 1.6.19

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,6 +1,7 @@
1
1
  import { Schema } from '@tachybase/schema';
2
2
  import { FilterTarget } from '../block-provider/hooks';
3
3
  import { Collection_deprecated, CollectionFieldOptions_deprecated, FieldOptions, useCollection_deprecated } from '../collection-manager';
4
+ import { type DatePickerRangeValueMode, type DatePickerRangeValueSource } from '../schema-component/antd/date-picker/util';
4
5
  import { DataBlock } from './FilterProvider';
5
6
  export declare enum FilterBlockType {
6
7
  FORM = 0,
@@ -23,6 +24,9 @@ export declare const getSupportFieldsByForeignKey: (filterBlockCollection: Retur
23
24
  export declare const useSupportedBlocks: (filterBlockType: FilterBlockType) => DataBlock[];
24
25
  type NormalizeDateBetweenOptions = {
25
26
  useDefaultDateBoundary?: boolean;
27
+ valueMode?: DatePickerRangeValueMode;
28
+ valueSource?: DatePickerRangeValueSource;
29
+ preferDateBoundaryFallback?: boolean;
26
30
  };
27
31
  export declare const normalizeDateBetweenValue: (value: any[], options?: NormalizeDateBetweenOptions) => any[];
28
32
  export declare const shouldUseDefaultDateBoundary: (fieldSchema?: any) => boolean;
@@ -6,6 +6,7 @@ import lodash from "lodash";
6
6
  import { findFilterTargets } from "../block-provider/hooks/index.mjs";
7
7
  import { useCollectionManager_deprecated, useCollection_deprecated } from "../collection-manager/index.mjs";
8
8
  import { removeNullCondition } from "../schema-component/index.mjs";
9
+ import { isDatePickerDefaultRangeBoundaryValue, resolveDatePickerRangeValueInfo } from "../schema-component/antd/date-picker/util.mjs";
9
10
  import { findFilterOperators, getDefaultFilterOperatorValue } from "../schema-component/antd/form-item/SchemaSettingOptions.mjs";
10
11
  import { useFilterBlock } from "./FilterProvider.mjs";
11
12
  import { getFilterSourceDefaultFilter } from "./incomingFilterFromSources.mjs";
@@ -88,32 +89,41 @@ const resolveFilterOperator = function(schema, path) {
88
89
  if (!operatorList.length || !fieldSchema) return;
89
90
  return getDefaultFilterOperatorValue(fieldSchema, operatorList);
90
91
  };
92
+ const getDatePickerComponent = (fieldSchema)=>{
93
+ var _fieldSchema_xcomponentprops;
94
+ return (null == fieldSchema ? void 0 : fieldSchema['x-component']) || (null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.component);
95
+ };
96
+ const getDatePickerShowTime = (fieldSchema)=>{
97
+ var _fieldSchema_xcomponentprops;
98
+ return null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.showTime;
99
+ };
91
100
  const isDateOnlyString = (value)=>'string' == typeof value && /^\d{4}-\d{2}-\d{2}$/.test(value);
92
101
  const hasExplicitTime = (value)=>'string' == typeof value && /[T\s]\d{2}:\d{2}/.test(value);
93
- const isDefaultDateBoundaryValue = (value, boundary)=>{
94
- if (isDateOnlyString(value)) return true;
95
- if ('string' != typeof value) return false;
96
- const match = value.match(/^\d{4}-\d{2}-\d{2}[T\s](\d{2}:\d{2}:\d{2})(?:\.\d{3})?(?:Z|[+-]\d\d:\d\d)?$/);
97
- if (!match) return false;
98
- return 'start' === boundary ? '00:00:00' === match[1] : '23:59:59' === match[1];
99
- };
100
- const normalizeDefaultDateBoundaryInput = (value)=>{
102
+ const normalizeLocalDateBoundaryInput = (value)=>{
101
103
  if ('string' != typeof value) return value;
102
104
  return value.replace(/Z$/, '').replace(/[+-]\d\d:\d\d$/, '');
103
105
  };
104
106
  const normalizeDateBetweenBoundary = function(value, boundary) {
105
107
  let options = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
106
- const rawValue = options.useDefaultDateBoundary ? normalizeDefaultDateBoundaryInput(value) : value;
107
- const m = dayjs(rawValue);
108
+ const m = dayjs(value);
108
109
  if (!m.isValid()) return value;
109
- if (!options.useDefaultDateBoundary && hasExplicitTime(rawValue) && !isDateOnlyString(rawValue)) return m.toISOString();
110
+ if (isDateOnlyString(value)) return ('start' === boundary ? m.startOf('day') : m.endOf('day')).toISOString();
111
+ if ('date' === options.valueMode) {
112
+ if ('retained-local-date-boundary' === options.valueSource) return m.toISOString();
113
+ const localBoundary = dayjs(normalizeLocalDateBoundaryInput(value));
114
+ return ('start' === boundary ? localBoundary.startOf('day') : localBoundary.endOf('day')).toISOString();
115
+ }
116
+ if (hasExplicitTime(value)) return m.toISOString();
117
+ if (!options.useDefaultDateBoundary) return m.toISOString();
110
118
  return ('start' === boundary ? m.startOf('day') : m.endOf('day')).toISOString();
111
119
  };
112
- const shouldApplyDefaultDateBoundary = function(start, end) {
113
- let options = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
120
+ const shouldApplyDefaultDateBoundary = function(start, end, value) {
121
+ let options = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {};
122
+ if ('datetime' === options.valueMode) return false;
123
+ if ('date' === options.valueMode) return true;
114
124
  if (!options.useDefaultDateBoundary) return false;
115
125
  if (isDateOnlyString(start) || isDateOnlyString(end)) return true;
116
- return isDefaultDateBoundaryValue(start, 'start') && isDefaultDateBoundaryValue(end, 'end');
126
+ return options.preferDateBoundaryFallback && 'date' === options.valueMode && isDatePickerDefaultRangeBoundaryValue(start, 'start') && isDatePickerDefaultRangeBoundaryValue(end, 'end');
117
127
  };
118
128
  const normalizeDateBetweenValue = function(value) {
119
129
  let options = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
@@ -123,19 +133,14 @@ const normalizeDateBetweenValue = function(value) {
123
133
  const end = 1 === normalized.length ? normalized[0] : normalized[normalized.length - 1];
124
134
  const boundaryOptions = {
125
135
  ...options,
126
- useDefaultDateBoundary: shouldApplyDefaultDateBoundary(start, end, options)
136
+ useDefaultDateBoundary: shouldApplyDefaultDateBoundary(start, end, value, options)
127
137
  };
128
138
  return [
129
139
  normalizeDateBetweenBoundary(start, 'start', boundaryOptions),
130
140
  normalizeDateBetweenBoundary(end, 'end', boundaryOptions)
131
141
  ];
132
142
  };
133
- const shouldUseDefaultDateBoundary = (fieldSchema)=>{
134
- var _fieldSchema_xcomponentprops;
135
- if (!fieldSchema) return false;
136
- const component = fieldSchema['x-component'] || (null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.component);
137
- return 'DatePicker.RangePicker' === component;
138
- };
143
+ const shouldUseDefaultDateBoundary = (fieldSchema)=>'DatePicker.RangePicker' === getDatePickerComponent(fieldSchema);
139
144
  const transformToFilter = (values, fieldSchema, getCollectionJoinField, collectionName, getOperatorList)=>{
140
145
  const { operators } = findFilterOperators(fieldSchema);
141
146
  values = flatten(values, {
@@ -177,8 +182,16 @@ const transformToFilter = (values, fieldSchema, getCollectionJoinField, collecti
177
182
  };
178
183
  } else if ('$dateBetween' === operator) {
179
184
  if (Array.isArray(value)) {
185
+ const valueInfo = resolveDatePickerRangeValueInfo(value, {
186
+ component: getDatePickerComponent(currentFieldSchema),
187
+ showTime: getDatePickerShowTime(currentFieldSchema),
188
+ preferDateBoundaryFallback: shouldUseDefaultDateBoundary(currentFieldSchema)
189
+ });
180
190
  value = normalizeDateBetweenValue(value, {
181
- useDefaultDateBoundary: shouldUseDefaultDateBoundary(currentFieldSchema)
191
+ useDefaultDateBoundary: shouldUseDefaultDateBoundary(currentFieldSchema),
192
+ valueMode: valueInfo.mode,
193
+ valueSource: valueInfo.source,
194
+ preferDateBoundaryFallback: 'retained-date-boundary' === valueInfo.source
182
195
  });
183
196
  if (!value) return null;
184
197
  }
@@ -4,7 +4,25 @@ export interface Moment2strOptions {
4
4
  gmt?: boolean;
5
5
  utc?: boolean;
6
6
  picker?: 'year' | 'month' | 'week' | 'quarter';
7
+ value?: any;
8
+ component?: string;
7
9
  }
10
+ export declare const DATE_PICKER_RANGE_VALUE_MODE: unique symbol;
11
+ export type DatePickerRangeValueMode = 'date' | 'datetime';
12
+ export type DatePickerRangeValueSource = 'metadata' | 'schema' | 'retained-date-boundary' | 'retained-local-date-boundary' | 'unknown';
13
+ export interface DatePickerRangeValueInfo {
14
+ mode?: DatePickerRangeValueMode;
15
+ source: DatePickerRangeValueSource;
16
+ }
17
+ export declare const getRangeValueMode: (value: any) => DatePickerRangeValueMode | undefined;
18
+ export declare const markRangeValueMode: (value: any[], mode: DatePickerRangeValueMode) => any[];
19
+ export declare const isDatePickerDefaultRangeBoundaryValue: (value: any, boundary: "start" | "end") => boolean;
20
+ export declare const isDatePickerDefaultRangeBoundaryPair: (value: any) => boolean;
21
+ export declare const resolveDatePickerRangeValueInfo: (value: any, options?: {
22
+ showTime?: boolean;
23
+ component?: string;
24
+ preferDateBoundaryFallback?: boolean;
25
+ }) => DatePickerRangeValueInfo;
8
26
  export declare const normalizeDatePickerParseOptions: (options?: Moment2strOptions) => Moment2strOptions;
9
27
  export declare const moment2str: (value?: Dayjs | null, options?: Moment2strOptions) => any;
10
28
  export declare const mapDatePicker: () => (props: any) => any;
@@ -20,9 +20,63 @@ const toLocalByPicker = (value, picker)=>{
20
20
  if (!value || !dayjs.isDayjs(value)) return value;
21
21
  return toStringByPicker(value, picker, 'local');
22
22
  };
23
+ const DATE_PICKER_RANGE_VALUE_MODE = Symbol.for('tachybase.datePicker.rangeValueMode');
24
+ const getRangeValueMode = (value)=>Array.isArray(value) ? value[DATE_PICKER_RANGE_VALUE_MODE] : void 0;
25
+ const markRangeValueMode = (value, mode)=>{
26
+ Object.defineProperty(value, DATE_PICKER_RANGE_VALUE_MODE, {
27
+ configurable: true,
28
+ enumerable: false,
29
+ value: mode
30
+ });
31
+ return value;
32
+ };
33
+ const isDatePickerDefaultRangeBoundaryValue = (value, boundary)=>{
34
+ if ('string' != typeof value) return false;
35
+ const match = value.match(/^\d{4}-\d{2}-\d{2}[T\s](\d{2}:\d{2}:\d{2})(?:\.\d{3})?(?:Z|[+-]\d\d:\d\d)?$/);
36
+ if (!match) return false;
37
+ return 'start' === boundary ? '00:00:00' === match[1] : '23:59:59' === match[1];
38
+ };
39
+ const isDatePickerDefaultRangeBoundaryPair = (value)=>Array.isArray(value) && value.length >= 2 && isDatePickerDefaultRangeBoundaryValue(value[0], 'start') && isDatePickerDefaultRangeBoundaryValue(value[value.length - 1], 'end');
40
+ const isDatePickerLocalRangeBoundaryValue = (value, boundary)=>{
41
+ const m = dayjs(value);
42
+ if (!m.isValid()) return false;
43
+ return 'start' === boundary ? '00:00:00' === m.format('HH:mm:ss') : '23:59:59' === m.format('HH:mm:ss');
44
+ };
45
+ const isDatePickerRetainedLocalBoundaryPair = (value)=>Array.isArray(value) && value.length >= 2 && isDatePickerLocalRangeBoundaryValue(value[0], 'start') && isDatePickerLocalRangeBoundaryValue(value[value.length - 1], 'end');
46
+ const resolveDatePickerRangeValueInfo = function(value) {
47
+ let options = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
48
+ const metadataMode = getRangeValueMode(value);
49
+ if (metadataMode) return {
50
+ mode: metadataMode,
51
+ source: 'metadata'
52
+ };
53
+ if ('DatePicker.RangePicker' === options.component && !options.showTime) return {
54
+ mode: 'date',
55
+ source: 'schema'
56
+ };
57
+ if (options.preferDateBoundaryFallback && options.showTime && isDatePickerRetainedLocalBoundaryPair(value)) return {
58
+ mode: 'date',
59
+ source: 'retained-local-date-boundary'
60
+ };
61
+ if (options.preferDateBoundaryFallback && isDatePickerDefaultRangeBoundaryPair(value)) return {
62
+ mode: 'date',
63
+ source: 'retained-date-boundary'
64
+ };
65
+ return {
66
+ source: 'unknown'
67
+ };
68
+ };
23
69
  const normalizeDatePickerParseOptions = function() {
24
70
  let options = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
25
- if (false === options.utc || options.showTime || 'boolean' == typeof options.gmt || options.picker) return options;
71
+ if (false === options.utc || 'boolean' == typeof options.gmt || options.picker) return options;
72
+ const rangeValueInfo = resolveDatePickerRangeValueInfo(options.value, {
73
+ component: options.component,
74
+ showTime: options.showTime,
75
+ preferDateBoundaryFallback: 'DatePicker.RangePicker' === options.component
76
+ });
77
+ if (options.showTime) {
78
+ if ('date' !== rangeValueInfo.mode || 'retained-local-date-boundary' === rangeValueInfo.source) return options;
79
+ }
26
80
  return {
27
81
  ...options,
28
82
  gmt: true
@@ -64,12 +118,15 @@ const mapRangePicker = function() {
64
118
  return {
65
119
  ...props,
66
120
  format: format,
67
- value: str2moment(props.value, normalizeDatePickerParseOptions(props)),
121
+ value: str2moment(props.value, normalizeDatePickerParseOptions({
122
+ ...props,
123
+ component: 'DatePicker.RangePicker'
124
+ })),
68
125
  onChange: (value)=>{
69
- if (onChange) onChange(value ? [
126
+ if (onChange) onChange(value ? markRangeValueMode([
70
127
  moment2str(getRangeStart(value[0], props), props),
71
128
  moment2str(getRangeEnd(value[1], props), props)
72
- ] : []);
129
+ ], props.showTime ? 'datetime' : 'date') : []);
73
130
  }
74
131
  };
75
132
  };
@@ -198,4 +255,4 @@ const getDateExact = ()=>({
198
255
  tomorrowLocal: ()=>dayjs().add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
199
256
  tomorrowDate: ()=>dayjs().add(1, 'day').format('YYYY-MM-DD')
200
257
  });
201
- export { getDateExact, getDateRanges, mapDatePicker, mapRangePicker, moment2str, normalizeDatePickerParseOptions };
258
+ export { DATE_PICKER_RANGE_VALUE_MODE, getDateExact, getDateRanges, getRangeValueMode, isDatePickerDefaultRangeBoundaryPair, isDatePickerDefaultRangeBoundaryValue, mapDatePicker, mapRangePicker, markRangeValueMode, moment2str, normalizeDatePickerParseOptions, resolveDatePickerRangeValueInfo };
@@ -6,6 +6,7 @@ import { useBlockRequestContext } from "../../../block-provider/index.mjs";
6
6
  import { useCollectionManager_deprecated, useCollection_deprecated } from "../../../collection-manager/index.mjs";
7
7
  import { FILTER_OPERATORS_WITH_ARRAY_VALUES, mergeFilter, normalizeDateBetweenValue, shouldUseDefaultDateBoundary } from "../../../filter-provider/utils.mjs";
8
8
  import { useDataLoadingMode } from "../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem.mjs";
9
+ import { resolveDatePickerRangeValueInfo } from "../date-picker/util.mjs";
9
10
  import { hasDuplicateKeys } from "./utils.mjs";
10
11
  const useGetFilterOptions = ()=>{
11
12
  const { getCollectionFields } = useCollectionManager_deprecated();
@@ -107,7 +108,9 @@ const useFilterFieldOptions = (fields)=>{
107
108
  };
108
109
  const isEmpty = (obj)=>Array.isArray(obj) && 0 === obj.length || obj && 0 === Object.keys(obj).length && Object.getPrototypeOf(obj) === Object.prototype;
109
110
  const CUSTOM_FILTER_VARIABLE_REGEXP = /^\{\{\$nFilter\.([^}]+)\}\}$/;
110
- const getCustomFilterValue = (items, key)=>{
111
+ const getCustomFilterValue = function(items, key) {
112
+ let rawItems = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
113
+ if (rawItems && key in rawItems) return rawItems[key];
111
114
  if (key in items) return items[key];
112
115
  const arrayItems = Object.keys(items).filter((itemKey)=>itemKey.startsWith("".concat(key, ".")) && /^\d+$/.test(itemKey.slice(key.length + 1))).sort((a, b)=>Number(a.slice(key.length + 1)) - Number(b.slice(key.length + 1))).map((itemKey)=>items[itemKey]);
113
116
  return arrayItems.length ? arrayItems : void 0;
@@ -132,18 +135,37 @@ const findCustomFieldSchema = (schema, key)=>{
132
135
  }
133
136
  return null;
134
137
  };
138
+ const getDatePickerComponent = (fieldSchema)=>{
139
+ var _fieldSchema_xcomponentprops;
140
+ return (null == fieldSchema ? void 0 : fieldSchema['x-component']) || (null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.component);
141
+ };
142
+ const getDatePickerShowTime = (fieldSchema)=>{
143
+ var _fieldSchema_xcomponentprops;
144
+ return null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.showTime;
145
+ };
135
146
  const expandArrayValueFilter = function(filterSchemaItem, filterKey, value, customFlat) {
136
147
  let options = arguments.length > 4 && void 0 !== arguments[4] ? arguments[4] : {};
137
148
  const pathParts = filterKey.split('.');
138
149
  const operator = pathParts.pop();
139
150
  if ('$dateBetween' === operator && Array.isArray(value)) {
140
- filterSchemaItem[filterKey] = normalizeDateBetweenValue(value, options);
151
+ const valueInfo = resolveDatePickerRangeValueInfo(value, {
152
+ component: options.component,
153
+ showTime: options.showTime,
154
+ preferDateBoundaryFallback: options.useDefaultDateBoundary
155
+ });
156
+ filterSchemaItem[filterKey] = normalizeDateBetweenValue(value, {
157
+ useDefaultDateBoundary: options.useDefaultDateBoundary,
158
+ valueMode: valueInfo.mode,
159
+ valueSource: valueInfo.source,
160
+ preferDateBoundaryFallback: 'retained-date-boundary' === valueInfo.source
161
+ });
141
162
  return;
142
163
  }
143
164
  if (!Array.isArray(value) || FILTER_OPERATORS_WITH_ARRAY_VALUES.has(operator || '')) {
144
165
  filterSchemaItem[filterKey] = value;
145
166
  return;
146
167
  }
168
+ if (0 === value.length) return void delete filterSchemaItem[filterKey];
147
169
  let branchEndIndex = -1;
148
170
  for(let index = pathParts.length - 2; index >= 0; index--)if ([
149
171
  '$and',
@@ -176,8 +198,10 @@ const getCustomCondition = function(filter, fieldSchema) {
176
198
  const match = 'string' == typeof filterSchemaItem[filterKey] && filterSchemaItem[filterKey].match(CUSTOM_FILTER_VARIABLE_REGEXP);
177
199
  if (!match) continue;
178
200
  const customFieldSchema = findCustomFieldSchema(fieldSchema, match[1]);
179
- expandArrayValueFilter(filterSchemaItem, filterKey, getCustomFilterValue(items, match[1]), customFlat, {
180
- useDefaultDateBoundary: shouldUseDefaultDateBoundary(customFieldSchema)
201
+ expandArrayValueFilter(filterSchemaItem, filterKey, getCustomFilterValue(items, match[1], filter || {}), customFlat, {
202
+ useDefaultDateBoundary: shouldUseDefaultDateBoundary(customFieldSchema),
203
+ component: getDatePickerComponent(customFieldSchema),
204
+ showTime: getDatePickerShowTime(customFieldSchema)
181
205
  });
182
206
  }
183
207
  for(const item in filterSchemaItem)if (!filterSchemaItem[item] || filterSchemaItem[item].includes('$nFilter')) delete filterSchemaItem[item];
@@ -58,6 +58,7 @@ var external_lodash_default = /*#__PURE__*/ __webpack_require__.n(external_lodas
58
58
  const index_js_namespaceObject = require("../block-provider/hooks/index.js");
59
59
  const external_collection_manager_index_js_namespaceObject = require("../collection-manager/index.js");
60
60
  const external_schema_component_index_js_namespaceObject = require("../schema-component/index.js");
61
+ const util_js_namespaceObject = require("../schema-component/antd/date-picker/util.js");
61
62
  const SchemaSettingOptions_js_namespaceObject = require("../schema-component/antd/form-item/SchemaSettingOptions.js");
62
63
  const external_FilterProvider_js_namespaceObject = require("./FilterProvider.js");
63
64
  const external_incomingFilterFromSources_js_namespaceObject = require("./incomingFilterFromSources.js");
@@ -140,32 +141,41 @@ const resolveFilterOperator = function(schema, path) {
140
141
  if (!operatorList.length || !fieldSchema) return;
141
142
  return (0, SchemaSettingOptions_js_namespaceObject.getDefaultFilterOperatorValue)(fieldSchema, operatorList);
142
143
  };
144
+ const getDatePickerComponent = (fieldSchema)=>{
145
+ var _fieldSchema_xcomponentprops;
146
+ return (null == fieldSchema ? void 0 : fieldSchema['x-component']) || (null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.component);
147
+ };
148
+ const getDatePickerShowTime = (fieldSchema)=>{
149
+ var _fieldSchema_xcomponentprops;
150
+ return null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.showTime;
151
+ };
143
152
  const isDateOnlyString = (value)=>'string' == typeof value && /^\d{4}-\d{2}-\d{2}$/.test(value);
144
153
  const hasExplicitTime = (value)=>'string' == typeof value && /[T\s]\d{2}:\d{2}/.test(value);
145
- const isDefaultDateBoundaryValue = (value, boundary)=>{
146
- if (isDateOnlyString(value)) return true;
147
- if ('string' != typeof value) return false;
148
- const match = value.match(/^\d{4}-\d{2}-\d{2}[T\s](\d{2}:\d{2}:\d{2})(?:\.\d{3})?(?:Z|[+-]\d\d:\d\d)?$/);
149
- if (!match) return false;
150
- return 'start' === boundary ? '00:00:00' === match[1] : '23:59:59' === match[1];
151
- };
152
- const normalizeDefaultDateBoundaryInput = (value)=>{
154
+ const normalizeLocalDateBoundaryInput = (value)=>{
153
155
  if ('string' != typeof value) return value;
154
156
  return value.replace(/Z$/, '').replace(/[+-]\d\d:\d\d$/, '');
155
157
  };
156
158
  const normalizeDateBetweenBoundary = function(value, boundary) {
157
159
  let options = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
158
- const rawValue = options.useDefaultDateBoundary ? normalizeDefaultDateBoundaryInput(value) : value;
159
- const m = external_dayjs_default()(rawValue);
160
+ const m = external_dayjs_default()(value);
160
161
  if (!m.isValid()) return value;
161
- if (!options.useDefaultDateBoundary && hasExplicitTime(rawValue) && !isDateOnlyString(rawValue)) return m.toISOString();
162
+ if (isDateOnlyString(value)) return ('start' === boundary ? m.startOf('day') : m.endOf('day')).toISOString();
163
+ if ('date' === options.valueMode) {
164
+ if ('retained-local-date-boundary' === options.valueSource) return m.toISOString();
165
+ const localBoundary = external_dayjs_default()(normalizeLocalDateBoundaryInput(value));
166
+ return ('start' === boundary ? localBoundary.startOf('day') : localBoundary.endOf('day')).toISOString();
167
+ }
168
+ if (hasExplicitTime(value)) return m.toISOString();
169
+ if (!options.useDefaultDateBoundary) return m.toISOString();
162
170
  return ('start' === boundary ? m.startOf('day') : m.endOf('day')).toISOString();
163
171
  };
164
- const shouldApplyDefaultDateBoundary = function(start, end) {
165
- let options = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
172
+ const shouldApplyDefaultDateBoundary = function(start, end, value) {
173
+ let options = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {};
174
+ if ('datetime' === options.valueMode) return false;
175
+ if ('date' === options.valueMode) return true;
166
176
  if (!options.useDefaultDateBoundary) return false;
167
177
  if (isDateOnlyString(start) || isDateOnlyString(end)) return true;
168
- return isDefaultDateBoundaryValue(start, 'start') && isDefaultDateBoundaryValue(end, 'end');
178
+ return options.preferDateBoundaryFallback && 'date' === options.valueMode && (0, util_js_namespaceObject.isDatePickerDefaultRangeBoundaryValue)(start, 'start') && (0, util_js_namespaceObject.isDatePickerDefaultRangeBoundaryValue)(end, 'end');
169
179
  };
170
180
  const normalizeDateBetweenValue = function(value) {
171
181
  let options = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
@@ -175,19 +185,14 @@ const normalizeDateBetweenValue = function(value) {
175
185
  const end = 1 === normalized.length ? normalized[0] : normalized[normalized.length - 1];
176
186
  const boundaryOptions = {
177
187
  ...options,
178
- useDefaultDateBoundary: shouldApplyDefaultDateBoundary(start, end, options)
188
+ useDefaultDateBoundary: shouldApplyDefaultDateBoundary(start, end, value, options)
179
189
  };
180
190
  return [
181
191
  normalizeDateBetweenBoundary(start, 'start', boundaryOptions),
182
192
  normalizeDateBetweenBoundary(end, 'end', boundaryOptions)
183
193
  ];
184
194
  };
185
- const shouldUseDefaultDateBoundary = (fieldSchema)=>{
186
- var _fieldSchema_xcomponentprops;
187
- if (!fieldSchema) return false;
188
- const component = fieldSchema['x-component'] || (null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.component);
189
- return 'DatePicker.RangePicker' === component;
190
- };
195
+ const shouldUseDefaultDateBoundary = (fieldSchema)=>'DatePicker.RangePicker' === getDatePickerComponent(fieldSchema);
191
196
  const transformToFilter = (values, fieldSchema, getCollectionJoinField, collectionName, getOperatorList)=>{
192
197
  const { operators } = (0, SchemaSettingOptions_js_namespaceObject.findFilterOperators)(fieldSchema);
193
198
  values = (0, client_namespaceObject.flatten)(values, {
@@ -229,8 +234,16 @@ const transformToFilter = (values, fieldSchema, getCollectionJoinField, collecti
229
234
  };
230
235
  } else if ('$dateBetween' === operator) {
231
236
  if (Array.isArray(value)) {
237
+ const valueInfo = (0, util_js_namespaceObject.resolveDatePickerRangeValueInfo)(value, {
238
+ component: getDatePickerComponent(currentFieldSchema),
239
+ showTime: getDatePickerShowTime(currentFieldSchema),
240
+ preferDateBoundaryFallback: shouldUseDefaultDateBoundary(currentFieldSchema)
241
+ });
232
242
  value = normalizeDateBetweenValue(value, {
233
- useDefaultDateBoundary: shouldUseDefaultDateBoundary(currentFieldSchema)
243
+ useDefaultDateBoundary: shouldUseDefaultDateBoundary(currentFieldSchema),
244
+ valueMode: valueInfo.mode,
245
+ valueSource: valueInfo.source,
246
+ preferDateBoundaryFallback: 'retained-date-boundary' === valueInfo.source
234
247
  });
235
248
  if (!value) return null;
236
249
  }
@@ -33,11 +33,17 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
+ getRangeValueMode: ()=>getRangeValueMode,
36
37
  mapRangePicker: ()=>mapRangePicker,
37
- moment2str: ()=>moment2str,
38
+ isDatePickerDefaultRangeBoundaryValue: ()=>isDatePickerDefaultRangeBoundaryValue,
38
39
  mapDatePicker: ()=>mapDatePicker,
39
40
  normalizeDatePickerParseOptions: ()=>normalizeDatePickerParseOptions,
41
+ resolveDatePickerRangeValueInfo: ()=>resolveDatePickerRangeValueInfo,
42
+ markRangeValueMode: ()=>markRangeValueMode,
43
+ moment2str: ()=>moment2str,
44
+ DATE_PICKER_RANGE_VALUE_MODE: ()=>DATE_PICKER_RANGE_VALUE_MODE,
40
45
  getDateExact: ()=>getDateExact,
46
+ isDatePickerDefaultRangeBoundaryPair: ()=>isDatePickerDefaultRangeBoundaryPair,
41
47
  getDateRanges: ()=>getDateRanges
42
48
  });
43
49
  const client_namespaceObject = require("@tego/client");
@@ -63,9 +69,63 @@ const toLocalByPicker = (value, picker)=>{
63
69
  if (!value || !external_dayjs_default().isDayjs(value)) return value;
64
70
  return toStringByPicker(value, picker, 'local');
65
71
  };
72
+ const DATE_PICKER_RANGE_VALUE_MODE = Symbol.for('tachybase.datePicker.rangeValueMode');
73
+ const getRangeValueMode = (value)=>Array.isArray(value) ? value[DATE_PICKER_RANGE_VALUE_MODE] : void 0;
74
+ const markRangeValueMode = (value, mode)=>{
75
+ Object.defineProperty(value, DATE_PICKER_RANGE_VALUE_MODE, {
76
+ configurable: true,
77
+ enumerable: false,
78
+ value: mode
79
+ });
80
+ return value;
81
+ };
82
+ const isDatePickerDefaultRangeBoundaryValue = (value, boundary)=>{
83
+ if ('string' != typeof value) return false;
84
+ const match = value.match(/^\d{4}-\d{2}-\d{2}[T\s](\d{2}:\d{2}:\d{2})(?:\.\d{3})?(?:Z|[+-]\d\d:\d\d)?$/);
85
+ if (!match) return false;
86
+ return 'start' === boundary ? '00:00:00' === match[1] : '23:59:59' === match[1];
87
+ };
88
+ const isDatePickerDefaultRangeBoundaryPair = (value)=>Array.isArray(value) && value.length >= 2 && isDatePickerDefaultRangeBoundaryValue(value[0], 'start') && isDatePickerDefaultRangeBoundaryValue(value[value.length - 1], 'end');
89
+ const isDatePickerLocalRangeBoundaryValue = (value, boundary)=>{
90
+ const m = external_dayjs_default()(value);
91
+ if (!m.isValid()) return false;
92
+ return 'start' === boundary ? '00:00:00' === m.format('HH:mm:ss') : '23:59:59' === m.format('HH:mm:ss');
93
+ };
94
+ const isDatePickerRetainedLocalBoundaryPair = (value)=>Array.isArray(value) && value.length >= 2 && isDatePickerLocalRangeBoundaryValue(value[0], 'start') && isDatePickerLocalRangeBoundaryValue(value[value.length - 1], 'end');
95
+ const resolveDatePickerRangeValueInfo = function(value) {
96
+ let options = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
97
+ const metadataMode = getRangeValueMode(value);
98
+ if (metadataMode) return {
99
+ mode: metadataMode,
100
+ source: 'metadata'
101
+ };
102
+ if ('DatePicker.RangePicker' === options.component && !options.showTime) return {
103
+ mode: 'date',
104
+ source: 'schema'
105
+ };
106
+ if (options.preferDateBoundaryFallback && options.showTime && isDatePickerRetainedLocalBoundaryPair(value)) return {
107
+ mode: 'date',
108
+ source: 'retained-local-date-boundary'
109
+ };
110
+ if (options.preferDateBoundaryFallback && isDatePickerDefaultRangeBoundaryPair(value)) return {
111
+ mode: 'date',
112
+ source: 'retained-date-boundary'
113
+ };
114
+ return {
115
+ source: 'unknown'
116
+ };
117
+ };
66
118
  const normalizeDatePickerParseOptions = function() {
67
119
  let options = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
68
- if (false === options.utc || options.showTime || 'boolean' == typeof options.gmt || options.picker) return options;
120
+ if (false === options.utc || 'boolean' == typeof options.gmt || options.picker) return options;
121
+ const rangeValueInfo = resolveDatePickerRangeValueInfo(options.value, {
122
+ component: options.component,
123
+ showTime: options.showTime,
124
+ preferDateBoundaryFallback: 'DatePicker.RangePicker' === options.component
125
+ });
126
+ if (options.showTime) {
127
+ if ('date' !== rangeValueInfo.mode || 'retained-local-date-boundary' === rangeValueInfo.source) return options;
128
+ }
69
129
  return {
70
130
  ...options,
71
131
  gmt: true
@@ -107,12 +167,15 @@ const mapRangePicker = function() {
107
167
  return {
108
168
  ...props,
109
169
  format: format,
110
- value: (0, client_namespaceObject.str2moment)(props.value, normalizeDatePickerParseOptions(props)),
170
+ value: (0, client_namespaceObject.str2moment)(props.value, normalizeDatePickerParseOptions({
171
+ ...props,
172
+ component: 'DatePicker.RangePicker'
173
+ })),
111
174
  onChange: (value)=>{
112
- if (onChange) onChange(value ? [
175
+ if (onChange) onChange(value ? markRangeValueMode([
113
176
  moment2str(getRangeStart(value[0], props), props),
114
177
  moment2str(getRangeEnd(value[1], props), props)
115
- ] : []);
178
+ ], props.showTime ? 'datetime' : 'date') : []);
116
179
  }
117
180
  };
118
181
  };
@@ -241,19 +304,31 @@ const getDateExact = ()=>({
241
304
  tomorrowLocal: ()=>external_dayjs_default()().add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
242
305
  tomorrowDate: ()=>external_dayjs_default()().add(1, 'day').format('YYYY-MM-DD')
243
306
  });
307
+ exports.DATE_PICKER_RANGE_VALUE_MODE = __webpack_exports__.DATE_PICKER_RANGE_VALUE_MODE;
244
308
  exports.getDateExact = __webpack_exports__.getDateExact;
245
309
  exports.getDateRanges = __webpack_exports__.getDateRanges;
310
+ exports.getRangeValueMode = __webpack_exports__.getRangeValueMode;
311
+ exports.isDatePickerDefaultRangeBoundaryPair = __webpack_exports__.isDatePickerDefaultRangeBoundaryPair;
312
+ exports.isDatePickerDefaultRangeBoundaryValue = __webpack_exports__.isDatePickerDefaultRangeBoundaryValue;
246
313
  exports.mapDatePicker = __webpack_exports__.mapDatePicker;
247
314
  exports.mapRangePicker = __webpack_exports__.mapRangePicker;
315
+ exports.markRangeValueMode = __webpack_exports__.markRangeValueMode;
248
316
  exports.moment2str = __webpack_exports__.moment2str;
249
317
  exports.normalizeDatePickerParseOptions = __webpack_exports__.normalizeDatePickerParseOptions;
318
+ exports.resolveDatePickerRangeValueInfo = __webpack_exports__.resolveDatePickerRangeValueInfo;
250
319
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
320
+ "DATE_PICKER_RANGE_VALUE_MODE",
251
321
  "getDateExact",
252
322
  "getDateRanges",
323
+ "getRangeValueMode",
324
+ "isDatePickerDefaultRangeBoundaryPair",
325
+ "isDatePickerDefaultRangeBoundaryValue",
253
326
  "mapDatePicker",
254
327
  "mapRangePicker",
328
+ "markRangeValueMode",
255
329
  "moment2str",
256
- "normalizeDatePickerParseOptions"
330
+ "normalizeDatePickerParseOptions",
331
+ "resolveDatePickerRangeValueInfo"
257
332
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
258
333
  Object.defineProperty(exports, '__esModule', {
259
334
  value: true
@@ -52,6 +52,7 @@ const index_js_namespaceObject = require("../../../block-provider/index.js");
52
52
  const external_collection_manager_index_js_namespaceObject = require("../../../collection-manager/index.js");
53
53
  const utils_js_namespaceObject = require("../../../filter-provider/utils.js");
54
54
  const setDataLoadingModeSettingsItem_js_namespaceObject = require("../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem.js");
55
+ const util_js_namespaceObject = require("../date-picker/util.js");
55
56
  const external_utils_js_namespaceObject = require("./utils.js");
56
57
  const useGetFilterOptions = ()=>{
57
58
  const { getCollectionFields } = (0, external_collection_manager_index_js_namespaceObject.useCollectionManager_deprecated)();
@@ -153,7 +154,9 @@ const useFilterFieldOptions = (fields)=>{
153
154
  };
154
155
  const isEmpty = (obj)=>Array.isArray(obj) && 0 === obj.length || obj && 0 === Object.keys(obj).length && Object.getPrototypeOf(obj) === Object.prototype;
155
156
  const CUSTOM_FILTER_VARIABLE_REGEXP = /^\{\{\$nFilter\.([^}]+)\}\}$/;
156
- const getCustomFilterValue = (items, key)=>{
157
+ const getCustomFilterValue = function(items, key) {
158
+ let rawItems = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
159
+ if (rawItems && key in rawItems) return rawItems[key];
157
160
  if (key in items) return items[key];
158
161
  const arrayItems = Object.keys(items).filter((itemKey)=>itemKey.startsWith("".concat(key, ".")) && /^\d+$/.test(itemKey.slice(key.length + 1))).sort((a, b)=>Number(a.slice(key.length + 1)) - Number(b.slice(key.length + 1))).map((itemKey)=>items[itemKey]);
159
162
  return arrayItems.length ? arrayItems : void 0;
@@ -178,18 +181,37 @@ const findCustomFieldSchema = (schema, key)=>{
178
181
  }
179
182
  return null;
180
183
  };
184
+ const getDatePickerComponent = (fieldSchema)=>{
185
+ var _fieldSchema_xcomponentprops;
186
+ return (null == fieldSchema ? void 0 : fieldSchema['x-component']) || (null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.component);
187
+ };
188
+ const getDatePickerShowTime = (fieldSchema)=>{
189
+ var _fieldSchema_xcomponentprops;
190
+ return null == fieldSchema ? void 0 : null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.showTime;
191
+ };
181
192
  const expandArrayValueFilter = function(filterSchemaItem, filterKey, value, customFlat) {
182
193
  let options = arguments.length > 4 && void 0 !== arguments[4] ? arguments[4] : {};
183
194
  const pathParts = filterKey.split('.');
184
195
  const operator = pathParts.pop();
185
196
  if ('$dateBetween' === operator && Array.isArray(value)) {
186
- filterSchemaItem[filterKey] = (0, utils_js_namespaceObject.normalizeDateBetweenValue)(value, options);
197
+ const valueInfo = (0, util_js_namespaceObject.resolveDatePickerRangeValueInfo)(value, {
198
+ component: options.component,
199
+ showTime: options.showTime,
200
+ preferDateBoundaryFallback: options.useDefaultDateBoundary
201
+ });
202
+ filterSchemaItem[filterKey] = (0, utils_js_namespaceObject.normalizeDateBetweenValue)(value, {
203
+ useDefaultDateBoundary: options.useDefaultDateBoundary,
204
+ valueMode: valueInfo.mode,
205
+ valueSource: valueInfo.source,
206
+ preferDateBoundaryFallback: 'retained-date-boundary' === valueInfo.source
207
+ });
187
208
  return;
188
209
  }
189
210
  if (!Array.isArray(value) || utils_js_namespaceObject.FILTER_OPERATORS_WITH_ARRAY_VALUES.has(operator || '')) {
190
211
  filterSchemaItem[filterKey] = value;
191
212
  return;
192
213
  }
214
+ if (0 === value.length) return void delete filterSchemaItem[filterKey];
193
215
  let branchEndIndex = -1;
194
216
  for(let index = pathParts.length - 2; index >= 0; index--)if ([
195
217
  '$and',
@@ -222,8 +244,10 @@ const getCustomCondition = function(filter, fieldSchema) {
222
244
  const match = 'string' == typeof filterSchemaItem[filterKey] && filterSchemaItem[filterKey].match(CUSTOM_FILTER_VARIABLE_REGEXP);
223
245
  if (!match) continue;
224
246
  const customFieldSchema = findCustomFieldSchema(fieldSchema, match[1]);
225
- expandArrayValueFilter(filterSchemaItem, filterKey, getCustomFilterValue(items, match[1]), customFlat, {
226
- useDefaultDateBoundary: (0, utils_js_namespaceObject.shouldUseDefaultDateBoundary)(customFieldSchema)
247
+ expandArrayValueFilter(filterSchemaItem, filterKey, getCustomFilterValue(items, match[1], filter || {}), customFlat, {
248
+ useDefaultDateBoundary: (0, utils_js_namespaceObject.shouldUseDefaultDateBoundary)(customFieldSchema),
249
+ component: getDatePickerComponent(customFieldSchema),
250
+ showTime: getDatePickerShowTime(customFieldSchema)
227
251
  });
228
252
  }
229
253
  for(const item in filterSchemaItem)if (!filterSchemaItem[item] || filterSchemaItem[item].includes('$nFilter')) delete filterSchemaItem[item];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tachybase/client",
3
- "version": "1.6.18",
3
+ "version": "1.6.19",
4
4
  "homepage": "https://github.com/tegojs/tego-standard#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/tegojs/tego-standard/issues"