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

teableio / teable / 8477076350

29 Mar 2024 04:11AM UTC coverage: 21.636% (-0.2%) from 21.83%
8477076350

Pull #484

github

web-flow
Merge 4e5e9beeb into 039ad8b0a
Pull Request #484: feat: support increment import

1395 of 2503 branches covered (55.73%)

24 of 733 new or added lines in 23 files covered. (3.27%)

2 existing lines in 1 file now uncovered.

14552 of 67258 relevant lines covered (21.64%)

2.07 hits per line

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

0.0
/apps/nextjs-app/src/features/app/blocks/table-list/TableOperation.tsx
NEW
1
import {
×
NEW
2
  MoreHorizontal,
×
NEW
3
  Pencil,
×
NEW
4
  Settings,
×
NEW
5
  Trash2,
×
NEW
6
  Export,
×
NEW
7
  Import,
×
NEW
8
  FileCsv,
×
NEW
9
  FileExcel,
×
NEW
10
} from '@teable/icons';
×
NEW
11
import { SUPPORTEDTYPE } from '@teable/openapi';
×
12
import { useBase, useTablePermission, useTables } from '@teable/sdk/hooks';
×
13
import type { Table } from '@teable/sdk/model';
×
14
import { ConfirmDialog } from '@teable/ui-lib/base';
×
15
import {
×
16
  DropdownMenu,
×
17
  DropdownMenuContent,
×
18
  DropdownMenuItem,
×
19
  DropdownMenuTrigger,
×
NEW
20
  DropdownMenuSub,
×
NEW
21
  DropdownMenuPortal,
×
NEW
22
  DropdownMenuSubContent,
×
NEW
23
  DropdownMenuSubTrigger,
×
24
} from '@teable/ui-lib/shadcn';
×
25
import Link from 'next/link';
×
26
import { useRouter } from 'next/router';
×
27
import { useTranslation } from 'next-i18next';
×
NEW
28
import React, { useMemo, useState, useRef } from 'react';
×
29
import { tableConfig } from '@/features/i18n/table.config';
×
NEW
30
import { TableImport } from '../import-table';
×
NEW
31

×
32
interface ITableOperationProps {
×
33
  className?: string;
×
34
  table: Table;
×
35
  onRename?: () => void;
×
36
}
×
37

×
38
export const TableOperation = (props: ITableOperationProps) => {
×
39
  const { table, className, onRename } = props;
×
NEW
40
  const [deleteConfirm, setDeleteConfirm] = useState(false);
×
NEW
41
  const [importVisible, setImportVisible] = useState(false);
×
NEW
42
  const [importType, setImportType] = useState(SUPPORTEDTYPE.CSV);
×
43
  const permission = useTablePermission();
×
44
  const base = useBase();
×
45
  const tables = useTables();
×
46
  const router = useRouter();
×
47
  const { baseId, tableId: routerTableId } = router.query;
×
48
  const { t } = useTranslation(tableConfig.i18nNamespaces);
×
49
  const iframeRef = useRef<HTMLIFrameElement>(null);
×
50

×
51
  const menuPermission = useMemo(() => {
×
52
    return {
×
53
      deleteTable: permission['table|delete'],
×
54
    };
×
55
  }, [permission]);
×
56

×
57
  const deleteTable = async () => {
×
58
    const tableId = table?.id;
×
59
    if (!tableId) {
×
60
      return;
×
61
    }
×
62
    await base.deleteTable(tableId);
×
63
    const firstTableId = tables.find((t) => t.id !== tableId)?.id;
×
64
    if (routerTableId === tableId) {
×
65
      router.push(
×
66
        firstTableId
×
67
          ? {
×
68
              pathname: '/base/[baseId]/[tableId]',
×
69
              query: { baseId, tableId: firstTableId },
×
70
            }
×
71
          : {
×
72
              pathname: '/base/[baseId]',
×
73
              query: { baseId },
×
74
            }
×
75
      );
×
76
    }
×
77
  };
×
78

×
79
  if (!Object.values(menuPermission).some(Boolean)) {
×
80
    return null;
×
81
  }
×
82

×
83
  return (
×
84
    // eslint-disable-next-line jsx-a11y/no-static-element-interactions
×
85
    <div onMouseDown={(e) => e.stopPropagation()}>
×
86
      {menuPermission.deleteTable && (
×
87
        <DropdownMenu>
×
88
          <DropdownMenuTrigger asChild>
×
89
            <div>
×
90
              <MoreHorizontal className={className} />
×
91
            </div>
×
92
          </DropdownMenuTrigger>
×
93
          <DropdownMenuContent
×
94
            align="end"
×
95
            className="min-w-[160px]"
×
96
            onClick={(e) => e.stopPropagation()}
×
97
          >
×
98
            <DropdownMenuItem onClick={() => onRename?.()}>
×
99
              <Pencil className="mr-2" />
×
100
              {t('table:table.rename')}
×
101
            </DropdownMenuItem>
×
102
            <DropdownMenuItem asChild>
×
103
              <Link
×
104
                href={{
×
105
                  pathname: '/base/[baseId]/[tableId]/design',
×
106
                  query: { baseId, tableId: table.id },
×
107
                }}
×
108
                title={t('table:table.design')}
×
109
              >
×
110
                <Settings className="mr-2" />
×
111
                {t('table:table.design')}
×
112
              </Link>
×
113
            </DropdownMenuItem>
×
114
            <DropdownMenuItem
×
115
              onClick={() => {
×
116
                if (iframeRef.current) {
×
117
                  iframeRef.current.src = `/api/export/${table.id}`;
×
118
                }
×
119
              }}
×
120
            >
×
121
              <Export className="mr-2" />
×
122
              {t('table:import.menu.downAsCsv')}
×
123
            </DropdownMenuItem>
×
NEW
124
            <DropdownMenuSub>
×
NEW
125
              <DropdownMenuSubTrigger>
×
NEW
126
                <Import className="mr-2" />
×
NEW
127
                <span>{t('table:import.menu.importData')}</span>
×
NEW
128
              </DropdownMenuSubTrigger>
×
NEW
129
              <DropdownMenuPortal>
×
NEW
130
                <DropdownMenuSubContent>
×
NEW
131
                  <DropdownMenuItem
×
NEW
132
                    onClick={() => {
×
NEW
133
                      setImportVisible(true);
×
NEW
134
                      setImportType(SUPPORTEDTYPE.CSV);
×
NEW
135
                    }}
×
NEW
136
                  >
×
NEW
137
                    <FileCsv className="mr-2 size-4" />
×
NEW
138
                    <span>{t('table:import.menu.csvFile')}</span>
×
NEW
139
                  </DropdownMenuItem>
×
NEW
140
                  <DropdownMenuItem
×
NEW
141
                    onClick={() => {
×
NEW
142
                      setImportVisible(true);
×
NEW
143
                      setImportType(SUPPORTEDTYPE.EXCEL);
×
NEW
144
                    }}
×
NEW
145
                  >
×
NEW
146
                    <FileExcel className="mr-2 size-4" />
×
NEW
147
                    <span>{t('table:import.menu.excelFile')}</span>
×
NEW
148
                  </DropdownMenuItem>
×
NEW
149
                </DropdownMenuSubContent>
×
NEW
150
              </DropdownMenuPortal>
×
NEW
151
            </DropdownMenuSub>
×
152
            <DropdownMenuItem className="text-destructive" onClick={() => setDeleteConfirm(true)}>
×
153
              <Trash2 className="mr-2" />
×
154
              {t('common:actions.delete')}
×
155
            </DropdownMenuItem>
×
156
          </DropdownMenuContent>
×
157
        </DropdownMenu>
×
158
      )}
×
NEW
159

×
NEW
160
      {importVisible && (
×
NEW
161
        <TableImport
×
NEW
162
          open={importVisible}
×
NEW
163
          tableId={table.id}
×
NEW
164
          fileType={importType}
×
NEW
165
          onOpenChange={(open: boolean) => setImportVisible(open)}
×
NEW
166
        ></TableImport>
×
NEW
167
      )}
×
NEW
168

×
169
      <ConfirmDialog
×
170
        open={deleteConfirm}
×
171
        onOpenChange={setDeleteConfirm}
×
172
        title={t('table:table.deleteConfirm', { tableName: table?.name })}
×
173
        cancelText={t('common:actions.cancel')}
×
174
        confirmText={t('common:actions.confirm')}
×
175
        content={
×
176
          <div className="space-y-2 text-sm">
×
177
            <p>1. {t('table:table.deleteTip1')}</p>
×
178
            <p>2. {t('table:table.deleteTip2')}</p>
×
179
          </div>
×
180
        }
×
181
        onCancel={() => setDeleteConfirm(false)}
×
182
        onConfirm={deleteTable}
×
183
      />
×
184
      <iframe ref={iframeRef} title="This for export csv download" style={{ display: 'none' }} />
×
185
    </div>
×
186
  );
×
187
};
×
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