@followupus/common 0.10.20 → 0.10.22

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.
@@ -22,24 +22,25 @@ export declare const OBJECT_TYPE: {
22
22
  ACTION: string;
23
23
  };
24
24
  export declare const COLUMN_TYPES: {
25
- NUMBER: string;
26
25
  TEXT: string;
27
- DROPDOWN: string;
28
26
  DATE: string;
29
27
  STATUS: string;
30
28
  PRIORITY: string;
31
- LINK: string;
32
- TAGS: string;
33
- EMAIL: string;
34
29
  PEOPLE: string;
35
- LINKED_COLUMN: string;
36
- REF_LINED_COLUMN: string;
37
- FILES: string;
30
+ EMAIL: string;
31
+ PHONE: string;
38
32
  HOURS: string;
33
+ TIME_TRACKING: string;
39
34
  TIMELINE: string;
40
- PHONE: string;
41
35
  CURRENCY: string;
42
- TIME_TRACKING: string;
36
+ NUMBER: string;
37
+ DROPDOWN: string;
38
+ TAGS: string;
39
+ LINK: string;
40
+ FILES: string;
41
+ AUTO_NUMBER: string;
42
+ LINKED_COLUMN: string;
43
+ REF_LINED_COLUMN: string;
43
44
  CREATED_BY: string;
44
45
  CREATED_AT: string;
45
46
  };
@@ -99,7 +100,12 @@ export declare const getColumnTypeFromId: (columnId: string) => string | undefin
99
100
  export declare const getColumnValueType: (columnType: string) => "string" | "number" | "object" | "stringArray" | "objectArray";
100
101
  export declare const getFilterDateGroupKeys: (dateStr: string) => string[] | null;
101
102
  export declare const getDateGroupKey: (dateStr: string) => string | null;
103
+ export declare const extractDomain: (url?: string) => string | undefined;
102
104
  export declare const getValidConditions: (filter: IFilter, headers?: IBaseCustomColumn[], currentUserId?: string, escapeHeaderCheck?: boolean) => IFilterCondition[];
105
+ export declare const isDateMatchConditionValue: (dateVal: string, conditionValue: string | {
106
+ start: string;
107
+ end: string;
108
+ }) => boolean;
103
109
  export declare const isDateInConditionValues: (itemVal: any, condition: IFilterCondition) => boolean;
104
110
  export declare const filterItemsByConditions: (groups: IBaseGroup[], filter: IFilter, headers?: IBaseCustomColumn[], currentUserId?: string) => IBaseGroup[];
105
111
  export declare const isItemMatchedByConditions: (item: IBaseItem, filter: IFilter, headers?: IBaseCustomColumn[], currentUserId?: string) => boolean;
@@ -1,5 +1,7 @@
1
+ import { phoneCountryList } from "./phone.js";
1
2
  import dayjs from "dayjs";
2
3
  import _ from "lodash";
4
+ // the key order is used for Add Column Menu order, keep it
3
5
  //One-to-One Matching UI.
4
6
  export const ACTION_TYPE = {
5
7
  CREATE: "CREATE",
@@ -25,24 +27,25 @@ export const OBJECT_TYPE = {
25
27
  ACTION: "action",
26
28
  };
27
29
  export const COLUMN_TYPES = {
28
- NUMBER: "number",
29
30
  TEXT: "string",
30
- DROPDOWN: "dropdown",
31
31
  DATE: "date",
32
32
  STATUS: "status",
33
33
  PRIORITY: "priority",
34
- LINK: "link",
35
- TAGS: "tags",
36
- EMAIL: "email",
37
34
  PEOPLE: "people",
38
- LINKED_COLUMN: "linked_column",
39
- REF_LINED_COLUMN: "ref_linked_column",
40
- FILES: "files",
35
+ EMAIL: "email",
36
+ PHONE: "phone",
41
37
  HOURS: "hours",
38
+ TIME_TRACKING: "time_tracking",
42
39
  TIMELINE: "timeline",
43
- PHONE: "phone",
44
40
  CURRENCY: "currency",
45
- TIME_TRACKING: "time_tracking",
41
+ NUMBER: "number",
42
+ DROPDOWN: "dropdown",
43
+ TAGS: "tags",
44
+ LINK: "link",
45
+ FILES: "files",
46
+ AUTO_NUMBER: "auto_number",
47
+ LINKED_COLUMN: "linked_column",
48
+ REF_LINED_COLUMN: "ref_linked_column",
46
49
  CREATED_BY: "created_by",
47
50
  CREATED_AT: "created_at",
48
51
  };
@@ -72,6 +75,18 @@ export const COLUMN_OP_TYPES = {
72
75
  OP_TYPES.EMPTY,
73
76
  OP_TYPES.NOT_EMPTY,
74
77
  ],
78
+ [COLUMN_TYPES.LINK]: [
79
+ OP_TYPES.CONTAINS,
80
+ OP_TYPES.NOT_CONTAINS,
81
+ OP_TYPES.EMPTY,
82
+ OP_TYPES.NOT_EMPTY,
83
+ ],
84
+ [COLUMN_TYPES.PHONE]: [
85
+ OP_TYPES.CONTAINS,
86
+ OP_TYPES.NOT_CONTAINS,
87
+ OP_TYPES.EMPTY,
88
+ OP_TYPES.NOT_EMPTY,
89
+ ],
75
90
  [COLUMN_TYPES.EMAIL]: [
76
91
  OP_TYPES.CONTAINS,
77
92
  OP_TYPES.NOT_CONTAINS,
@@ -168,6 +183,8 @@ export const AUTOMATION_OP_TYPES = {
168
183
  OP_TYPES.NOT_EMPTY,
169
184
  ],
170
185
  [COLUMN_TYPES.EMAIL]: [OP_TYPES.CONTAINS, OP_TYPES.NOT_CONTAINS],
186
+ [COLUMN_TYPES.LINK]: [OP_TYPES.CONTAINS, OP_TYPES.NOT_CONTAINS],
187
+ [COLUMN_TYPES.PHONE]: [OP_TYPES.CONTAINS, OP_TYPES.NOT_CONTAINS],
171
188
  // [COLUMN_TYPES.DATE]: [
172
189
  // OP_TYPES.EQUAL,
173
190
  // OP_TYPES.NOT_EQUAL,
@@ -236,6 +253,7 @@ export const getColumnValueType = (columnType) => {
236
253
  case COLUMN_TYPES.TIMELINE:
237
254
  case COLUMN_TYPES.TIME_TRACKING:
238
255
  case COLUMN_TYPES.LINK:
256
+ case COLUMN_TYPES.PHONE:
239
257
  return "object";
240
258
  case COLUMN_TYPES.NUMBER:
241
259
  case COLUMN_TYPES.HOURS:
@@ -311,6 +329,22 @@ export const getDateGroupKey = (dateStr) => {
311
329
  }
312
330
  return DATE_GROUPS.FUTURE;
313
331
  };
332
+ export const extractDomain = (url) => {
333
+ const regex = /^(?:https?:\/\/)?(?:www\.)?([^/:]+)/i;
334
+ const match = url?.match(regex);
335
+ return match ? match[1] : undefined;
336
+ };
337
+ // export const extractDomainName = (url?: string) => {
338
+ // const regex = /^(?:https?:\/\/)?(?:www\.)?([^/:]+)/i;
339
+ // const match = url?.match(regex);
340
+ // if (!match) return undefined;
341
+ // const domainParts = match[1].split(".");
342
+ // if (domainParts.length > 1) {
343
+ // domainParts.pop();
344
+ // }
345
+ //
346
+ // return domainParts.join(".");
347
+ // };
314
348
  export const getValidConditions = (filter, headers, currentUserId, escapeHeaderCheck) => {
315
349
  const newFilter = _.cloneDeep(filter);
316
350
  if (!newFilter?.criteria?.length || !headers?.length) {
@@ -413,29 +447,34 @@ const isInConditionValues = (itemVal, valueType, condition) => {
413
447
  }
414
448
  return false;
415
449
  };
450
+ export const isDateMatchConditionValue = (dateVal, conditionValue) => {
451
+ const checkDate = dayjs(dateVal);
452
+ if (!checkDate.isValid())
453
+ return false;
454
+ if (conditionValue && typeof conditionValue === "object") {
455
+ // range
456
+ const startDt = dayjs(conditionValue.start);
457
+ const endDt = dayjs(conditionValue.end);
458
+ return (startDt.isValid() &&
459
+ endDt.isValid() &&
460
+ (checkDate.isAfter(startDt, "date") ||
461
+ checkDate.isSame(startDt, "date")) &&
462
+ (checkDate.isBefore(endDt, "date") || checkDate.isSame(endDt, "date")));
463
+ }
464
+ else if (dayjs(conditionValue).isValid()) {
465
+ return checkDate.isSame(dayjs(conditionValue), "date");
466
+ }
467
+ else {
468
+ const groupKeys = getFilterDateGroupKeys(dateVal);
469
+ return !!groupKeys?.includes(conditionValue);
470
+ }
471
+ };
416
472
  export const isDateInConditionValues = (itemVal, condition) => {
417
473
  if (!itemVal || !dayjs(itemVal).isValid()) {
418
474
  return !!condition.blank;
419
475
  }
420
- const itemDate = dayjs(itemVal);
421
476
  return !!condition.value?.some(c => {
422
- if (c && typeof c === "object") {
423
- // range
424
- const startDt = dayjs(c.start);
425
- const endDt = dayjs(c.end);
426
- return (startDt.isValid() &&
427
- endDt.isValid() &&
428
- (itemDate.isAfter(startDt, "date") ||
429
- itemDate.isSame(startDt, "date")) &&
430
- (itemDate.isBefore(endDt, "date") || itemDate.isSame(endDt, "date")));
431
- }
432
- else if (dayjs(c).isValid()) {
433
- return itemDate.isSame(dayjs(c), "date");
434
- }
435
- else {
436
- const groupKeys = getFilterDateGroupKeys(itemVal);
437
- return !!groupKeys?.includes(c);
438
- }
477
+ return isDateMatchConditionValue(itemVal, c);
439
478
  });
440
479
  // if (!groupKey) return !!condition.blank;
441
480
  // return !!condition.value?.find((dateGroup) => dateGroup === groupKey);
@@ -466,7 +505,13 @@ const isDateAfterConditionValues = (itemVal, condition) => {
466
505
  }
467
506
  });
468
507
  };
469
- const isEmpty = (itemVal, valueType) => {
508
+ const isEmpty = (itemVal, valueType, columnType) => {
509
+ const isLink = columnType === COLUMN_TYPES.LINK;
510
+ const isPhone = columnType === COLUMN_TYPES.PHONE;
511
+ if (isLink)
512
+ return !itemVal?.url;
513
+ if (isPhone)
514
+ return !itemVal?.value;
470
515
  switch (valueType) {
471
516
  case "number":
472
517
  case "string":
@@ -482,13 +527,28 @@ const isEmpty = (itemVal, valueType) => {
482
527
  }
483
528
  return true;
484
529
  };
485
- const isContains = (itemVal, valueType, condition) => {
530
+ const isContains = (itemVal, valueType, condition, columnType) => {
531
+ const isLink = columnType === COLUMN_TYPES.LINK;
532
+ const isPhone = columnType === COLUMN_TYPES.PHONE;
486
533
  const checkVal = condition.value?.length
487
534
  ? condition.value[0]
488
535
  : "";
489
536
  const ignoreCaseCheck = (val, contains) => {
490
537
  return !!val?.toLowerCase()?.includes(contains?.toLowerCase());
491
538
  };
539
+ if (isLink) {
540
+ return (ignoreCaseCheck(itemVal?.title ?? "", checkVal) ||
541
+ ignoreCaseCheck(extractDomain(itemVal?.url ?? "") ?? "", checkVal));
542
+ }
543
+ if (isPhone) {
544
+ const phoneNum = itemVal?.value && itemVal?.iso2
545
+ ? (phoneCountryList.find(k => k.iso2 === itemVal.iso2)?.code ?? "") +
546
+ itemVal.value
547
+ : "";
548
+ return !!phoneNum
549
+ ?.replaceAll(/\D/g, "")
550
+ ?.includes(checkVal?.replaceAll(/\D/g, ""));
551
+ }
492
552
  switch (valueType) {
493
553
  case "number":
494
554
  return itemVal || itemVal === 0
@@ -595,16 +655,16 @@ const checkItemMatched = (item, validConditions, headers, matchAny) => {
595
655
  match = isDate && isDateAfterConditionValues(itemVal, condition);
596
656
  break;
597
657
  case OP_TYPES.EMPTY:
598
- match = isEmpty(itemVal, valueType);
658
+ match = isEmpty(itemVal, valueType, checkHeader?.type);
599
659
  break;
600
660
  case OP_TYPES.NOT_EMPTY:
601
- match = !isEmpty(itemVal, valueType);
661
+ match = !isEmpty(itemVal, valueType, checkHeader?.type);
602
662
  break;
603
663
  case OP_TYPES.CONTAINS:
604
- match = isContains(itemVal, valueType, condition);
664
+ match = isContains(itemVal, valueType, condition, checkHeader?.type);
605
665
  break;
606
666
  case OP_TYPES.NOT_CONTAINS:
607
- match = !isContains(itemVal, valueType, condition);
667
+ match = !isContains(itemVal, valueType, condition, checkHeader?.type);
608
668
  break;
609
669
  case OP_TYPES.EQUAL:
610
670
  match = isEquals(itemVal, valueType, condition);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@followupus/common",
3
- "version": "0.10.20",
3
+ "version": "0.10.22",
4
4
  "description": "followup common utils npm package with TypeScript and VSCode",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",