• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 8387093605

22 Mar 2024 07:48AM CUT coverage: 28.027% (-0.2%) from 28.222%
8387093605

Pull #484

github

web-flow
Merge 174ef76f7 into a06c6afb1
Pull Request #484: feat: support increment import

2099 of 3218 branches covered (65.23%)

24 of 703 new or added lines in 18 files covered. (3.41%)

49 existing lines in 6 files now uncovered.

25815 of 92109 relevant lines covered (28.03%)

5.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/sdk/src/components/filter/component/filterDatePicker/FilterDatePicker.tsx
1
import type { IDateTimeFieldOperator, IDateFilter, ITimeZoneString } from '@teable/core';
×
2
import { exactDate, FieldType, getValidFilterSubOperators } from '@teable/core';
×
3
import { Input } from '@teable/ui-lib';
×
4
import { useCallback, useEffect, useMemo, useState } from 'react';
×
5
import type { DateField } from '../../../../model';
×
6
import { DateEditor } from '../../../editor';
×
7
import { BaseSingleSelect } from '../base';
×
8
import {
×
9
  DATEPICKEROPTIONS,
×
10
  defaultValue,
×
11
  INPUTOPTIONS,
×
12
  withInDefaultValue,
×
13
  defaultMapping,
×
14
} from './constant';
×
15

×
16
interface IFilerDatePickerProps {
×
17
  value: IDateFilter | null;
×
18
  field: DateField;
×
19
  operator: string;
×
20
  onSelect: (value: IDateFilter | null) => void;
×
21
}
×
22

×
23
// eslint-disable-next-line @typescript-eslint/no-explicit-any
×
24
const isDateMetaValue = (value: any) => {
×
25
  return !!(value?.mode && value?.timeZone);
×
26
};
×
27

×
28
function FilterDatePicker(props: IFilerDatePickerProps) {
×
29
  const { value: initValue, operator, onSelect, field } = props;
×
30
  const [innerValue, setInnerValue] = useState<IDateFilter | null>(initValue);
×
31

×
32
  const defaultConfig = useMemo(() => {
×
33
    if (operator !== 'isWithIn') {
×
34
      return defaultValue;
×
35
    }
×
36
    return withInDefaultValue;
×
37
  }, [operator]);
×
38

×
39
  useEffect(() => {
×
40
    if (!initValue) {
×
41
      setInnerValue(defaultConfig);
×
42
    } else {
×
43
      setInnerValue(initValue);
×
44
    }
×
45

×
46
    if (!isDateMetaValue(initValue)) {
×
47
      onSelect(null);
×
48
    }
×
49
  }, [defaultConfig, initValue, onSelect]);
×
50

×
51
  const mergedOnSelect = useCallback(
×
52
    (val: string | null) => {
×
53
      const mergedValue = {
×
54
        mode: val as IDateFilter['mode'],
×
55
        timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
×
56
      };
×
57
      setInnerValue(mergedValue as IDateFilter);
×
58
      if (val !== null && !INPUTOPTIONS.includes(val) && !DATEPICKEROPTIONS.includes(val)) {
×
59
        onSelect?.(mergedValue as IDateFilter);
×
60
      }
×
61
    },
×
62
    [onSelect]
×
63
  );
×
64

×
65
  const datePickerSelect = useCallback(
×
66
    (val: string | null | undefined) => {
×
67
      const mergedValue = val
×
68
        ? {
×
69
            mode: exactDate.value,
×
70
            exactDate: val,
×
71
            timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone as ITimeZoneString,
×
72
          }
×
73
        : null;
×
74
      onSelect?.(mergedValue);
×
75
    },
×
76
    [onSelect]
×
77
  );
×
78

×
79
  const selectOptions = useMemo(() => {
×
80
    const optionMapping = getValidFilterSubOperators(
×
81
      FieldType.Date,
×
82
      operator as IDateTimeFieldOperator
×
83
    );
×
84
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
×
85
    const options = optionMapping!.map((operator) => ({
×
86
      label: defaultMapping[operator],
×
87
      value: operator,
×
88
    }));
×
89
    // change the operator to another type
×
90
    if (innerValue && !options.some((option) => option.value === innerValue?.mode)) {
×
91
      const newValue = { ...innerValue };
×
92
      newValue.mode = defaultConfig.mode;
×
93
      onSelect?.(newValue);
×
94
    }
×
95
    return options;
×
96
  }, [defaultConfig.mode, innerValue, onSelect, operator]);
×
97

×
98
  const inputCreator = useMemo(() => {
×
99
    const isDatePick = innerValue?.mode && DATEPICKEROPTIONS.includes(innerValue?.mode);
×
100
    const isInput = innerValue?.mode && INPUTOPTIONS.includes(innerValue?.mode);
×
101
    switch (true) {
×
102
      case isDatePick:
×
103
        return (
×
104
          <DateEditor
×
105
            value={innerValue?.exactDate}
×
106
            onChange={datePickerSelect}
×
107
            options={field.options}
×
108
            disableTimePicker={true}
×
109
            className="w-max"
×
110
          />
×
111
        );
×
112
      case isInput:
×
113
        return (
×
114
          <Input
×
115
            placeholder="Enter days"
×
116
            defaultValue={innerValue?.numberOfDays ?? ''}
×
117
            className="m-1 h-8 w-24 placeholder:text-[13px]"
×
118
            onInput={(e) => {
×
119
              // limit the number positive
×
120
              e.currentTarget.value = e.currentTarget.value?.replace(/\D/g, '');
×
121
            }}
×
122
            onChange={(e) => {
×
123
              const value = e.target.value;
×
124
              if (innerValue && value !== '') {
×
125
                const newValue: IDateFilter = { ...innerValue };
×
126
                newValue.numberOfDays = Number(value);
×
127
                onSelect?.(newValue);
×
128
              }
×
129
            }}
×
130
          />
×
131
        );
×
132
    }
×
133
    return null;
×
134
  }, [innerValue, datePickerSelect, field, onSelect]);
×
135

×
136
  return (
×
137
    <>
×
138
      <BaseSingleSelect
×
139
        options={selectOptions}
×
140
        onSelect={mergedOnSelect}
×
141
        value={innerValue?.mode || null}
×
142
        className="max-w-xs"
×
143
        popoverClassName="w-max"
×
144
      />
×
145
      {inputCreator}
×
146
    </>
×
147
  );
×
148
}
×
149

×
UNCOV
150
export { FilterDatePicker };
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc