@followupus/common 0.8.6 → 0.8.8

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,4 +1,4 @@
1
- import { IBaseCustomColumn, IBaseGroup, IFilter, IFilterCondition, IPureBoard } from "./types";
1
+ import { IBaseCustomColumn, IBaseGroup, IFilter, IFilterCondition, IPureBoard, IBaseItem } from "./types";
2
2
  export declare const COLUMN_TYPES: {
3
3
  NUMBER: string;
4
4
  TEXT: string;
@@ -53,8 +53,10 @@ export declare const DATE_GROUPS: {
53
53
  FUTURE: string;
54
54
  };
55
55
  export declare const isLinkedColumns: (columnType?: string) => boolean;
56
+ export declare const getColumnTypeFromId: (columnId: string) => string | undefined;
56
57
  export declare const getColumnValueType: (columnType: string) => "string" | "number" | "object" | "stringArray" | "objectArray";
57
58
  export declare const getDateGroupKey: (dateStr: string) => string | null;
58
- export declare const getValidConditions: (filter: IFilter, headers?: IBaseCustomColumn[], currentUserId?: string) => IFilterCondition[];
59
+ export declare const getValidConditions: (filter: IFilter, headers?: IBaseCustomColumn[], currentUserId?: string, escapeHeaderCheck?: boolean) => IFilterCondition[];
59
60
  export declare const filterItemsByConditions: (groups: IBaseGroup[], filter: IFilter, headers?: IBaseCustomColumn[], currentUserId?: string) => IBaseGroup[];
61
+ export declare const isItemMatchedByConditions: (item: IBaseItem, filter: IFilter, headers?: IBaseCustomColumn[], currentUserId?: string) => boolean;
60
62
  export declare const filterBoardTree: (board: IPureBoard, filter: IFilter, currentUserId?: string) => IPureBoard;
@@ -121,6 +121,9 @@ export const isLinkedColumns = (columnType) => {
121
121
  return false;
122
122
  return [COLUMN_TYPES.LINKED_COLUMN, COLUMN_TYPES.REF_LINED_COLUMN].includes(columnType);
123
123
  };
124
+ export const getColumnTypeFromId = (columnId) => {
125
+ return Object.values(COLUMN_TYPES).find(type => columnId.startsWith(type));
126
+ };
124
127
  export const getColumnValueType = (columnType) => {
125
128
  switch (columnType) {
126
129
  case COLUMN_TYPES.PEOPLE:
@@ -174,7 +177,7 @@ export const getDateGroupKey = (dateStr) => {
174
177
  }
175
178
  return DATE_GROUPS.FUTURE;
176
179
  };
177
- export const getValidConditions = (filter, headers, currentUserId) => {
180
+ export const getValidConditions = (filter, headers, currentUserId, escapeHeaderCheck) => {
178
181
  const newFilter = _.cloneDeep(filter);
179
182
  if (!newFilter.criteria?.length || !headers?.length) {
180
183
  return [];
@@ -185,9 +188,10 @@ export const getValidConditions = (filter, headers, currentUserId) => {
185
188
  if (isLinkedColumns(validHeader?.type)) {
186
189
  checkHeader = validHeader?.linked;
187
190
  }
188
- if (!checkHeader)
191
+ if (!checkHeader && !escapeHeaderCheck)
189
192
  return;
190
- if (checkHeader?.type === COLUMN_TYPES.PEOPLE) {
193
+ if (checkHeader?.type === COLUMN_TYPES.PEOPLE ||
194
+ c.columnId?.startsWith(COLUMN_TYPES.PEOPLE)) {
191
195
  if (c.value?.find(val => val === THEMSELVES) && currentUserId) {
192
196
  const idx = c.value.findIndex(val => val === THEMSELVES);
193
197
  if (idx > -1)
@@ -198,15 +202,18 @@ export const getValidConditions = (filter, headers, currentUserId) => {
198
202
  // for dropdown, if set the option is in filter condition, and user delete the option. should ignore it or make the option can't be deleted
199
203
  return newFilter.criteria.filter(c => {
200
204
  const validHeader = headers.find(h => h.columnId === c.columnId);
201
- if (!validHeader)
205
+ if (!validHeader && !escapeHeaderCheck)
202
206
  return false;
203
207
  let checkHeader = validHeader;
204
- if (isLinkedColumns(validHeader.type)) {
205
- checkHeader = validHeader.linked;
208
+ if (isLinkedColumns(validHeader?.type)) {
209
+ checkHeader = validHeader?.linked;
206
210
  }
207
- if (!checkHeader)
211
+ if (!checkHeader && !escapeHeaderCheck)
208
212
  return false;
209
- const validOperate = COLUMN_OP_TYPES[checkHeader.type]?.includes(c.op);
213
+ const columnType = checkHeader?.type || getColumnTypeFromId(c.columnId);
214
+ if (!columnType)
215
+ return false;
216
+ const validOperate = COLUMN_OP_TYPES[columnType]?.includes(c.op);
210
217
  if (!validOperate)
211
218
  return false;
212
219
  const isDropdown = [
@@ -214,14 +221,15 @@ export const getValidConditions = (filter, headers, currentUserId) => {
214
221
  COLUMN_TYPES.STATUS,
215
222
  COLUMN_TYPES.PRIORITY,
216
223
  COLUMN_TYPES.TAGS,
217
- ].includes(checkHeader.type);
224
+ ].includes(columnType);
218
225
  switch (c.op) {
219
226
  case OP_TYPES.IS:
220
227
  case OP_TYPES.IS_NOT:
221
228
  return (c.blank ||
222
229
  (!!c.value?.filter(v => !!v || v === 0)?.length &&
223
230
  (!isDropdown ||
224
- c.value.some(v => checkHeader.dropdowns?.find(d => d.key === v)))));
231
+ escapeHeaderCheck ||
232
+ c.value.some(v => checkHeader?.dropdowns?.find(d => d.key === v)))));
225
233
  case OP_TYPES.EMPTY:
226
234
  case OP_TYPES.NOT_EMPTY:
227
235
  return true;
@@ -364,6 +372,90 @@ const isLessEqual = (itemVal, condition) => {
364
372
  return parseVal ? itemVal <= parseVal : false;
365
373
  }
366
374
  };
375
+ const checkItemMatched = (item, validConditions, headers) => {
376
+ let isItemMatched = false;
377
+ for (const condition of validConditions) {
378
+ const header = headers?.find(h => h.columnId === condition.columnId);
379
+ const isLinkedColumn = isLinkedColumns(header?.type);
380
+ let checkHeader = header;
381
+ if (isLinkedColumn) {
382
+ checkHeader = header?.linked;
383
+ }
384
+ const valueType = getColumnValueType(checkHeader?.type ?? "");
385
+ const checkConditionFn = (itemVal) => {
386
+ let match = false;
387
+ const isDate = checkHeader?.type === COLUMN_TYPES.DATE;
388
+ switch (condition.op) {
389
+ case OP_TYPES.IS:
390
+ match = isDate
391
+ ? isDateInConditionValues(itemVal, condition)
392
+ : isInConditionValues(itemVal, valueType, condition);
393
+ break;
394
+ case OP_TYPES.IS_NOT:
395
+ match = isDate
396
+ ? !isDateInConditionValues(itemVal, condition)
397
+ : !isInConditionValues(itemVal, valueType, condition);
398
+ break;
399
+ case OP_TYPES.EMPTY:
400
+ match = isEmpty(itemVal, valueType);
401
+ break;
402
+ case OP_TYPES.NOT_EMPTY:
403
+ match = !isEmpty(itemVal, valueType);
404
+ break;
405
+ case OP_TYPES.CONTAINS:
406
+ match = isContains(itemVal, valueType, condition);
407
+ break;
408
+ case OP_TYPES.NOT_CONTAINS:
409
+ match = !isContains(itemVal, valueType, condition);
410
+ break;
411
+ case OP_TYPES.EQUAL:
412
+ match = isEquals(itemVal, valueType, condition);
413
+ break;
414
+ case OP_TYPES.NOT_EQUAL:
415
+ match = !isEquals(itemVal, valueType, condition);
416
+ break;
417
+ case OP_TYPES.GREATER:
418
+ match =
419
+ typeof itemVal === "number" ? isGreater(itemVal, condition) : false;
420
+ break;
421
+ case OP_TYPES.GREATER_EQUAL:
422
+ match =
423
+ typeof itemVal === "number"
424
+ ? isGreaterEqual(itemVal, condition)
425
+ : false;
426
+ break;
427
+ case OP_TYPES.LESS_EQUAL:
428
+ match =
429
+ typeof itemVal === "number"
430
+ ? isLessEqual(itemVal, condition)
431
+ : false;
432
+ break;
433
+ case OP_TYPES.LESS:
434
+ match =
435
+ typeof itemVal === "number" ? isLess(itemVal, condition) : false;
436
+ break;
437
+ default:
438
+ break;
439
+ }
440
+ return match;
441
+ };
442
+ const itemValue = isLinkedColumn
443
+ ? item.data?.[condition.columnId]
444
+ : item.data?.[condition.columnId]?.value;
445
+ if (isLinkedColumn) {
446
+ isItemMatched = !!itemValue?.some((item) => {
447
+ const val = item.value;
448
+ return checkConditionFn(val);
449
+ });
450
+ }
451
+ else {
452
+ isItemMatched = checkConditionFn(itemValue);
453
+ }
454
+ if (!isItemMatched)
455
+ return false;
456
+ }
457
+ return isItemMatched;
458
+ };
367
459
  export const filterItemsByConditions = (groups, filter, headers, currentUserId) => {
368
460
  if (!headers?.length)
369
461
  return groups;
@@ -373,96 +465,20 @@ export const filterItemsByConditions = (groups, filter, headers, currentUserId)
373
465
  }
374
466
  groups.forEach(g => {
375
467
  g.items = g.items?.filter(item => {
376
- let isItemMatched = false;
377
- for (const condition of validConditions) {
378
- const header = headers?.find(h => h.columnId === condition.columnId);
379
- const isLinkedColumn = isLinkedColumns(header?.type);
380
- let checkHeader = header;
381
- if (isLinkedColumn) {
382
- checkHeader = header?.linked;
383
- }
384
- const valueType = getColumnValueType(checkHeader?.type ?? "");
385
- const checkConditionFn = (itemVal) => {
386
- let match = false;
387
- const isDate = checkHeader?.type === COLUMN_TYPES.DATE;
388
- switch (condition.op) {
389
- case OP_TYPES.IS:
390
- match = isDate
391
- ? isDateInConditionValues(itemVal, condition)
392
- : isInConditionValues(itemVal, valueType, condition);
393
- break;
394
- case OP_TYPES.IS_NOT:
395
- match = isDate
396
- ? !isDateInConditionValues(itemVal, condition)
397
- : !isInConditionValues(itemVal, valueType, condition);
398
- break;
399
- case OP_TYPES.EMPTY:
400
- match = isEmpty(itemVal, valueType);
401
- break;
402
- case OP_TYPES.NOT_EMPTY:
403
- match = !isEmpty(itemVal, valueType);
404
- break;
405
- case OP_TYPES.CONTAINS:
406
- match = isContains(itemVal, valueType, condition);
407
- break;
408
- case OP_TYPES.NOT_CONTAINS:
409
- match = !isContains(itemVal, valueType, condition);
410
- break;
411
- case OP_TYPES.EQUAL:
412
- match = isEquals(itemVal, valueType, condition);
413
- break;
414
- case OP_TYPES.NOT_EQUAL:
415
- match = !isEquals(itemVal, valueType, condition);
416
- break;
417
- case OP_TYPES.GREATER:
418
- match =
419
- typeof itemVal === "number"
420
- ? isGreater(itemVal, condition)
421
- : false;
422
- break;
423
- case OP_TYPES.GREATER_EQUAL:
424
- match =
425
- typeof itemVal === "number"
426
- ? isGreaterEqual(itemVal, condition)
427
- : false;
428
- break;
429
- case OP_TYPES.LESS_EQUAL:
430
- match =
431
- typeof itemVal === "number"
432
- ? isLessEqual(itemVal, condition)
433
- : false;
434
- break;
435
- case OP_TYPES.LESS:
436
- match =
437
- typeof itemVal === "number"
438
- ? isLess(itemVal, condition)
439
- : false;
440
- break;
441
- default:
442
- break;
443
- }
444
- return match;
445
- };
446
- const itemValue = isLinkedColumn
447
- ? item.data?.[condition.columnId]
448
- : item.data?.[condition.columnId]?.value;
449
- if (isLinkedColumn) {
450
- isItemMatched = !!itemValue?.some((item) => {
451
- const val = item.value;
452
- return checkConditionFn(val);
453
- });
454
- }
455
- else {
456
- isItemMatched = checkConditionFn(itemValue);
457
- }
458
- if (!isItemMatched)
459
- return false;
460
- }
461
- return isItemMatched;
468
+ return checkItemMatched(item, validConditions, headers);
462
469
  });
463
470
  });
464
471
  return groups;
465
472
  };
473
+ export const isItemMatchedByConditions = (item, filter, headers, currentUserId) => {
474
+ if (!headers?.length)
475
+ return true;
476
+ const validConditions = getValidConditions(filter, headers, currentUserId);
477
+ if (!validConditions?.length) {
478
+ return true;
479
+ }
480
+ return checkItemMatched(item, validConditions, headers);
481
+ };
466
482
  export const filterBoardTree = (board, filter, currentUserId) => {
467
483
  if (!board?.groups?.length || !board?.headers?.length || !filter)
468
484
  return board;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@followupus/common",
3
- "version": "0.8.6",
3
+ "version": "0.8.8",
4
4
  "description": "followup common utils npm package with TypeScript and VSCode",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",