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

teableio / teable / 8536869866

03 Apr 2024 10:05AM CUT coverage: 21.234% (-0.3%) from 21.535%
8536869866

Pull #514

github

web-flow
Merge 91a25d710 into 45ee7ebb3
Pull Request #514: refactor: user and link selector

1394 of 2532 branches covered (55.06%)

27 of 1620 new or added lines in 60 files covered. (1.67%)

4 existing lines in 2 files now uncovered.

14588 of 68702 relevant lines covered (21.23%)

2.02 hits per line

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

0.0
/packages/sdk/src/components/editor/user/EditorBase.tsx
NEW
1
import type { IUserCellValue } from '@teable/core';
×
NEW
2
import { Check } from '@teable/icons';
×
NEW
3
import {
×
NEW
4
  Command,
×
NEW
5
  CommandEmpty,
×
NEW
6
  CommandGroup,
×
NEW
7
  CommandInput,
×
NEW
8
  CommandItem,
×
NEW
9
  CommandList,
×
NEW
10
  Skeleton,
×
NEW
11
  cn,
×
NEW
12
} from '@teable/ui-lib';
×
NEW
13
import type { ForwardRefRenderFunction } from 'react';
×
NEW
14
import { useCallback, useImperativeHandle, useRef, forwardRef } from 'react';
×
NEW
15
import { useTranslation } from '../../../context/app/i18n';
×
NEW
16
import type { ICellEditor, IEditorRef } from '../type';
×
NEW
17
import type { ICollaborator } from './types';
×
NEW
18
import { UserOption } from './UserOption';
×
NEW
19

×
NEW
20
export interface IUserEditorBaseProps extends ICellEditor<IUserCellValue | IUserCellValue[]> {
×
NEW
21
  isMultiple?: boolean;
×
NEW
22
  onChange?: (value?: IUserCellValue | IUserCellValue[]) => void;
×
NEW
23
  className?: string;
×
NEW
24
  collaborators?: ICollaborator[];
×
NEW
25
  isLoading?: boolean;
×
NEW
26
}
×
NEW
27

×
NEW
28
export type IUserEditorRef = IEditorRef<IUserCellValue | IUserCellValue[] | undefined>;
×
NEW
29

×
NEW
30
const UserEditorBaseRef: ForwardRefRenderFunction<IUserEditorRef, IUserEditorBaseProps> = (
×
NEW
31
  props,
×
NEW
32
  ref
×
NEW
33
) => {
×
NEW
34
  const {
×
NEW
35
    value: cellValue,
×
NEW
36
    style,
×
NEW
37
    className,
×
NEW
38
    isLoading,
×
NEW
39
    isMultiple,
×
NEW
40
    collaborators,
×
NEW
41
    onChange,
×
NEW
42
  } = props;
×
NEW
43
  const inputRef = useRef<HTMLInputElement | null>(null);
×
NEW
44
  const { t } = useTranslation();
×
NEW
45

×
NEW
46
  useImperativeHandle(ref, () => ({
×
NEW
47
    focus: () => {
×
NEW
48
      inputRef.current?.focus();
×
NEW
49
    },
×
NEW
50
  }));
×
NEW
51

×
NEW
52
  const onSelect = (value: IUserCellValue) => {
×
NEW
53
    if (isMultiple) {
×
NEW
54
      const innerValue = (cellValue || []) as IUserCellValue[];
×
NEW
55
      const newValue = innerValue.some((v) => v.id === value.id)
×
NEW
56
        ? innerValue.filter((v) => v.id !== value.id)
×
NEW
57
        : [...innerValue, value];
×
NEW
58
      onChange?.(newValue);
×
NEW
59
      return;
×
NEW
60
    }
×
NEW
61
    onChange?.(value.id === (cellValue as IUserCellValue)?.id ? undefined : value);
×
NEW
62
  };
×
NEW
63

×
NEW
64
  const activeStatus = useCallback(
×
NEW
65
    (value: string) => {
×
NEW
66
      const originValue = isMultiple
×
NEW
67
        ? (cellValue as IUserCellValue[])?.map((user) => user?.id)
×
NEW
68
        : [(cellValue as IUserCellValue)?.id];
×
NEW
69

×
NEW
70
      return originValue?.includes(value);
×
NEW
71
    },
×
NEW
72
    [cellValue, isMultiple]
×
NEW
73
  );
×
NEW
74

×
NEW
75
  return (
×
NEW
76
    <Command className={className} style={style}>
×
NEW
77
      <CommandInput ref={inputRef} placeholder={t('editor.user.searchPlaceholder')} />
×
NEW
78
      <CommandList>
×
NEW
79
        <CommandEmpty>{t('common.search.empty')}</CommandEmpty>
×
NEW
80
        <CommandGroup aria-valuetext="name">
×
NEW
81
          {isLoading ? (
×
NEW
82
            <CommandItem className="flex items-center space-x-4">
×
NEW
83
              <Skeleton className="size-7 rounded-full" />
×
NEW
84
              <Skeleton className="h-4 w-32" />
×
NEW
85
            </CommandItem>
×
NEW
86
          ) : (
×
NEW
87
            collaborators?.map(({ userId, userName, avatar, email }) => (
×
NEW
88
              <CommandItem
×
NEW
89
                key={userId}
×
NEW
90
                value={userName}
×
NEW
91
                onSelect={() => onSelect({ id: userId, title: userName, avatarUrl: avatar })}
×
NEW
92
                className="flex justify-between"
×
NEW
93
              >
×
NEW
94
                <UserOption name={userName} email={email} avatar={avatar} />
×
NEW
95
                <Check
×
NEW
96
                  className={cn('ml-2 h-4 w-4', activeStatus(userId) ? 'opacity-100' : 'opacity-0')}
×
NEW
97
                />
×
NEW
98
              </CommandItem>
×
NEW
99
            ))
×
NEW
100
          )}
×
NEW
101
        </CommandGroup>
×
NEW
102
      </CommandList>
×
NEW
103
    </Command>
×
NEW
104
  );
×
NEW
105
};
×
NEW
106

×
NEW
107
export const UserEditorBase = forwardRef(UserEditorBaseRef);
×
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