From e804d0b31e9420449de32fc39ede7b816da9f04f Mon Sep 17 00:00:00 2001
From: dicedtomato <35403473+diced@users.noreply.github.com>
Date: Mon, 27 Feb 2023 01:52:22 +0000
Subject: [PATCH] feat: more functionality within files table
---
src/components/File.tsx | 402 -----------------------
src/components/File/FileModal.tsx | 345 +++++++++++++++++++
src/components/File/index.tsx | 90 +++++
src/components/Type.tsx | 22 +-
src/components/pages/Dashboard/index.tsx | 238 +++++++++-----
src/pages/api/user/files.ts | 10 +
tsconfig.json | 4 -
yarn.lock | 94 +-----
8 files changed, 625 insertions(+), 580 deletions(-)
delete mode 100644 src/components/File.tsx
create mode 100644 src/components/File/FileModal.tsx
create mode 100644 src/components/File/index.tsx
diff --git a/src/components/File.tsx b/src/components/File.tsx
deleted file mode 100644
index fb46fe6..0000000
--- a/src/components/File.tsx
+++ /dev/null
@@ -1,402 +0,0 @@
-import {
- ActionIcon,
- Card,
- Group,
- LoadingOverlay,
- Modal,
- Select,
- SimpleGrid,
- Stack,
- Text,
- Title,
- Tooltip,
-} from '@mantine/core';
-import { useClipboard } from '@mantine/hooks';
-import { showNotification } from '@mantine/notifications';
-import useFetch from 'hooks/useFetch';
-import { useFileDelete, useFileFavorite } from 'lib/queries/files';
-import { useFolders } from 'lib/queries/folders';
-import { relativeTime } from 'lib/utils/client';
-import { useState } from 'react';
-import {
- CalendarIcon,
- ClockIcon,
- CopyIcon,
- CrossIcon,
- DeleteIcon,
- DownloadIcon,
- ExternalLinkIcon,
- EyeIcon,
- FileIcon,
- FolderMinusIcon,
- FolderPlusIcon,
- HashIcon,
- ImageIcon,
- InfoIcon,
- StarIcon,
-} from './icons';
-import MutedText from './MutedText';
-import Type from './Type';
-
-export function FileMeta({ Icon, title, subtitle, ...other }) {
- return other.tooltip ? (
-
-
-
-
- {title}
- {subtitle}
-
-
-
- ) : (
-
-
-
- {title}
- {subtitle}
-
-
- );
-}
-
-export default function File({
- image,
- disableMediaPreview,
- exifEnabled,
- refreshImages,
- reducedActions = false,
-}) {
- const [open, setOpen] = useState(false);
- const [overrideRender, setOverrideRender] = useState(false);
- const deleteFile = useFileDelete();
- const favoriteFile = useFileFavorite();
- const clipboard = useClipboard();
-
- const folders = useFolders();
-
- const loading = deleteFile.isLoading || favoriteFile.isLoading;
-
- const handleDelete = async () => {
- deleteFile.mutate(image.id, {
- onSuccess: () => {
- showNotification({
- title: 'File Deleted',
- message: '',
- color: 'green',
- icon: ,
- });
- },
-
- onError: (res: any) => {
- showNotification({
- title: 'Failed to delete file',
- message: res.error,
- color: 'red',
- icon: ,
- });
- },
-
- onSettled: () => {
- setOpen(false);
- },
- });
- };
-
- const handleCopy = () => {
- clipboard.copy(`${window.location.protocol}//${window.location.host}${image.url}`);
- setOpen(false);
- if (!navigator.clipboard)
- showNotification({
- title: 'Unable to copy to clipboard',
- message: 'Zipline is unable to copy to clipboard due to security reasons.',
- color: 'red',
- });
- else
- showNotification({
- title: 'Copied to clipboard',
- message: '',
- icon: ,
- });
- };
-
- const handleFavorite = async () => {
- favoriteFile.mutate(
- { id: image.id, favorite: !image.favorite },
- {
- onSuccess: () => {
- showNotification({
- title: 'Image is now ' + (!image.favorite ? 'favorited' : 'unfavorited'),
- message: '',
- icon: ,
- });
- },
-
- onError: (res: any) => {
- showNotification({
- title: 'Failed to favorite file',
- message: res.error,
- color: 'red',
- icon: ,
- });
- },
- }
- );
- };
-
- const inFolder = image.folderId;
-
- const refresh = () => {
- refreshImages();
- folders.refetch();
- };
-
- const removeFromFolder = async () => {
- const res = await useFetch('/api/user/folders/' + image.folderId, 'DELETE', {
- file: Number(image.id),
- });
-
- refresh();
-
- if (!res.error) {
- showNotification({
- title: 'Removed from folder',
- message: res.name,
- color: 'green',
- icon: ,
- });
- } else {
- showNotification({
- title: 'Failed to remove from folder',
- message: res.error,
- color: 'red',
- icon: ,
- });
- }
- };
-
- const addToFolder = async (t) => {
- const res = await useFetch('/api/user/folders/' + t, 'POST', {
- file: Number(image.id),
- });
-
- refresh();
-
- if (!res.error) {
- showNotification({
- title: 'Added to folder',
- message: res.name,
- color: 'green',
- icon: ,
- });
- } else {
- showNotification({
- title: 'Failed to add to folder',
- message: res.error,
- color: 'red',
- icon: ,
- });
- }
- };
-
- const createFolder = (t) => {
- useFetch('/api/user/folders', 'POST', {
- name: t,
- add: [Number(image.id)],
- }).then((res) => {
- refresh();
-
- if (!res.error) {
- showNotification({
- title: 'Created & added to folder',
- message: res.name,
- color: 'green',
- icon: ,
- });
- } else {
- showNotification({
- title: 'Failed to create folder',
- message: res.error,
- color: 'red',
- icon: ,
- });
- }
- });
- return { value: t, label: t };
- };
-
- return (
- <>
- setOpen(false)} title={{image.name}} size='xl'>
-
-
-
-
-
-
-
- {image.maxViews && (
-
- )}
-
- {image.expiresAt && !reducedActions && (
-
- )}
-
-
-
-
-
-
- {exifEnabled && !reducedActions && (
-
- window.open(`/dashboard/metadata/${image.id}`, '_blank')}
- >
-
-
-
- )}
- {reducedActions ? null : inFolder && !folders.isLoading ? (
- f.id === image.folderId)?.name ?? ''
- }"`}
- >
-
-
-
-
- ) : (
-
-
- )}
-
-
- {reducedActions ? null : (
- <>
-
-
-
-
-
-
-
-
-
-
-
- >
- )}
-
-
- window.open(image.url, '_blank')}>
-
-
-
-
-
-
-
-
-
-
-
- window.open(`/r/${encodeURI(image.name)}?download=true`, '_blank')}
- >
-
-
-
-
-
-
-
-
-
- setOpen(true)}
- disableMediaPreview={disableMediaPreview}
- />
-
-
- >
- );
-}
diff --git a/src/components/File/FileModal.tsx b/src/components/File/FileModal.tsx
new file mode 100644
index 0000000..31dd8e4
--- /dev/null
+++ b/src/components/File/FileModal.tsx
@@ -0,0 +1,345 @@
+import {
+ ActionIcon,
+ Group,
+ LoadingOverlay,
+ Modal,
+ Select,
+ SimpleGrid,
+ Stack,
+ Title,
+ Tooltip,
+} from '@mantine/core';
+import { useClipboard } from '@mantine/hooks';
+import { showNotification } from '@mantine/notifications';
+import useFetch from 'hooks/useFetch';
+import { useFileDelete, useFileFavorite } from 'lib/queries/files';
+import { useFolders } from 'lib/queries/folders';
+import { relativeTime } from 'lib/utils/client';
+import { useState } from 'react';
+import { FileMeta } from '.';
+import {
+ CalendarIcon,
+ ClockIcon,
+ CopyIcon,
+ CrossIcon,
+ DeleteIcon,
+ DownloadIcon,
+ ExternalLinkIcon,
+ EyeIcon,
+ FileIcon,
+ FolderMinusIcon,
+ FolderPlusIcon,
+ HashIcon,
+ ImageIcon,
+ InfoIcon,
+ StarIcon,
+} from '../icons';
+import Type from '../Type';
+
+export default function FileModal({
+ open,
+ setOpen,
+ file,
+ loading,
+ refresh,
+ reducedActions = false,
+ exifEnabled,
+}: {
+ open: boolean;
+ setOpen: (open: boolean) => void;
+ file: any;
+ loading: boolean;
+ refresh: () => void;
+ reducedActions?: boolean;
+ exifEnabled?: boolean;
+}) {
+ const deleteFile = useFileDelete();
+ const favoriteFile = useFileFavorite();
+ const folders = useFolders();
+
+ const [overrideRender, setOverrideRender] = useState(false);
+ const clipboard = useClipboard();
+
+ const handleDelete = async () => {
+ deleteFile.mutate(file.id, {
+ onSuccess: () => {
+ showNotification({
+ title: 'File Deleted',
+ message: '',
+ color: 'green',
+ icon: ,
+ });
+ },
+
+ onError: (res: any) => {
+ showNotification({
+ title: 'Failed to delete file',
+ message: res.error,
+ color: 'red',
+ icon: ,
+ });
+ },
+
+ onSettled: () => {
+ setOpen(false);
+ },
+ });
+ };
+
+ const handleCopy = () => {
+ clipboard.copy(`${window.location.protocol}//${window.location.host}${file.url}`);
+ setOpen(false);
+ if (!navigator.clipboard)
+ showNotification({
+ title: 'Unable to copy to clipboard',
+ message: 'Zipline is unable to copy to clipboard due to security reasons.',
+ color: 'red',
+ });
+ else
+ showNotification({
+ title: 'Copied to clipboard',
+ message: '',
+ icon: ,
+ });
+ };
+
+ const handleFavorite = async () => {
+ favoriteFile.mutate(
+ { id: file.id, favorite: !file.favorite },
+ {
+ onSuccess: () => {
+ showNotification({
+ title: 'The file is now ' + (!file.favorite ? 'favorited' : 'unfavorited'),
+ message: '',
+ icon: ,
+ });
+ },
+
+ onError: (res: any) => {
+ showNotification({
+ title: 'Failed to favorite file',
+ message: res.error,
+ color: 'red',
+ icon: ,
+ });
+ },
+ }
+ );
+ };
+
+ const inFolder = file.folderId;
+
+ const removeFromFolder = async () => {
+ const res = await useFetch('/api/user/folders/' + file.folderId, 'DELETE', {
+ file: Number(file.id),
+ });
+
+ refresh();
+
+ if (!res.error) {
+ showNotification({
+ title: 'Removed from folder',
+ message: res.name,
+ color: 'green',
+ icon: ,
+ });
+ } else {
+ showNotification({
+ title: 'Failed to remove from folder',
+ message: res.error,
+ color: 'red',
+ icon: ,
+ });
+ }
+ };
+
+ const addToFolder = async (t) => {
+ const res = await useFetch('/api/user/folders/' + t, 'POST', {
+ file: Number(file.id),
+ });
+
+ refresh();
+
+ if (!res.error) {
+ showNotification({
+ title: 'Added to folder',
+ message: res.name,
+ color: 'green',
+ icon: ,
+ });
+ } else {
+ showNotification({
+ title: 'Failed to add to folder',
+ message: res.error,
+ color: 'red',
+ icon: ,
+ });
+ }
+ };
+
+ const createFolder = (t) => {
+ useFetch('/api/user/folders', 'POST', {
+ name: t,
+ add: [Number(file.id)],
+ }).then((res) => {
+ refresh();
+
+ if (!res.error) {
+ showNotification({
+ title: 'Created & added to folder',
+ message: res.name,
+ color: 'green',
+ icon: ,
+ });
+ } else {
+ showNotification({
+ title: 'Failed to create folder',
+ message: res.error,
+ color: 'red',
+ icon: ,
+ });
+ }
+ });
+ return { value: t, label: t };
+ };
+
+ return (
+ setOpen(false)} title={{file.name}} size='xl'>
+
+
+
+
+
+
+
+ {file.maxViews && (
+
+ )}
+
+ {file.expiresAt && !reducedActions && (
+
+ )}
+
+
+
+
+
+
+ {exifEnabled && !reducedActions && (
+
+ window.open(`/dashboard/metadata/${file.id}`, '_blank')}
+ >
+
+
+
+ )}
+ {reducedActions ? null : inFolder && !folders.isLoading ? (
+ f.id === file.folderId)?.name ?? ''}"`}
+ >
+
+
+
+
+ ) : (
+
+
+ )}
+
+
+ {reducedActions ? null : (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+ window.open(file.url, '_blank')}>
+
+
+
+
+
+
+
+
+
+
+
+ window.open(`/r/${encodeURI(file.name)}?download=true`, '_blank')}
+ >
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/File/index.tsx b/src/components/File/index.tsx
new file mode 100644
index 0000000..8bfef83
--- /dev/null
+++ b/src/components/File/index.tsx
@@ -0,0 +1,90 @@
+import { Card, Group, LoadingOverlay, Stack, Text, Tooltip } from '@mantine/core';
+import { useFileDelete, useFileFavorite } from 'lib/queries/files';
+import { useFolders } from 'lib/queries/folders';
+import { useState } from 'react';
+import MutedText from '../MutedText';
+import Type from '../Type';
+import FileModal from './FileModal';
+
+export function FileMeta({ Icon, title, subtitle, ...other }) {
+ return other.tooltip ? (
+
+
+
+
+ {title}
+ {subtitle}
+
+
+
+ ) : (
+
+
+
+ {title}
+ {subtitle}
+
+
+ );
+}
+
+export default function File({
+ image,
+ disableMediaPreview,
+ exifEnabled,
+ refreshImages,
+ reducedActions = false,
+}) {
+ const [open, setOpen] = useState(false);
+ const deleteFile = useFileDelete();
+ const favoriteFile = useFileFavorite();
+ const loading = deleteFile.isLoading || favoriteFile.isLoading;
+
+ const folders = useFolders();
+
+ const refresh = () => {
+ refreshImages();
+ folders.refetch();
+ };
+
+ return (
+ <>
+
+
+
+
+
+ setOpen(true)}
+ disableMediaPreview={disableMediaPreview}
+ />
+
+
+ >
+ );
+}
diff --git a/src/components/Type.tsx b/src/components/Type.tsx
index b66aeda..099d68f 100644
--- a/src/components/Type.tsx
+++ b/src/components/Type.tsx
@@ -1,16 +1,4 @@
-import {
- Alert,
- Box,
- Button,
- Card,
- Center,
- Container,
- Group,
- Image,
- LoadingOverlay,
- Text,
-} from '@mantine/core';
-import { Prism } from '@mantine/prism';
+import { Alert, Box, Button, Card, Center, Group, Image, LoadingOverlay, Text } from '@mantine/core';
import { useEffect, useState } from 'react';
import { AudioIcon, FileIcon, ImageIcon, PlayIcon } from './icons';
import KaTeX from './render/KaTeX';
@@ -62,7 +50,7 @@ export default function Type({ file, popup = false, disableMediaPreview, ...prop
}, []);
}
- const renderRenderAlert = () => {
+ const renderAlert = () => {
return (
You are{props.overrideRender ? ' not ' : ' '}viewing a rendered version of the file
@@ -81,7 +69,7 @@ export default function Type({ file, popup = false, disableMediaPreview, ...prop
if ((shouldRenderMarkdown || shouldRenderTex) && !props.overrideRender && popup)
return (
<>
- {renderRenderAlert()}
+ {renderAlert()}
{shouldRenderMarkdown && }
{shouldRenderTex && }
@@ -90,7 +78,7 @@ export default function Type({ file, popup = false, disableMediaPreview, ...prop
);
if (media && disableMediaPreview) {
- return ;
+ return ;
}
return popup ? (
@@ -110,7 +98,7 @@ export default function Type({ file, popup = false, disableMediaPreview, ...prop
) : (
<>
- {(shouldRenderMarkdown || shouldRenderTex) && renderRenderAlert()}
+ {(shouldRenderMarkdown || shouldRenderTex) && renderAlert()}
>
)}
diff --git a/src/components/pages/Dashboard/index.tsx b/src/components/pages/Dashboard/index.tsx
index 166eac5..fce10da 100644
--- a/src/components/pages/Dashboard/index.tsx
+++ b/src/components/pages/Dashboard/index.tsx
@@ -1,42 +1,88 @@
-import { DataGrid, dateFilterFn, stringFilterFn } from '@dicedtomato/mantine-data-grid';
-import { Title, useMantineTheme, Box } from '@mantine/core';
+import { ActionIcon, Box, Group, Title, Tooltip } from '@mantine/core';
import { useClipboard } from '@mantine/hooks';
import { showNotification } from '@mantine/notifications';
-import { CopyIcon, CrossIcon, DeleteIcon, EnterIcon } from 'components/icons';
+import FileModal from 'components/File/FileModal';
+import { CopyIcon, CrossIcon, DeleteIcon, EnterIcon, FileIcon } from 'components/icons';
import Link from 'components/Link';
import MutedText from 'components/MutedText';
import useFetch from 'lib/hooks/useFetch';
-import { useFiles, useRecent } from 'lib/queries/files';
+import { usePaginatedFiles, useRecent } from 'lib/queries/files';
import { useStats } from 'lib/queries/stats';
import { userSelector } from 'lib/recoil/user';
+import { DataTable, DataTableSortStatus } from 'mantine-datatable';
+import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import RecentFiles from './RecentFiles';
import { StatCards } from './StatCards';
export default function Dashboard({ disableMediaPreview, exifEnabled }) {
const user = useRecoilValue(userSelector);
- const theme = useMantineTheme();
- const images = useFiles();
const recent = useRecent('media');
const stats = useStats();
const clipboard = useClipboard();
- const updateImages = () => {
- images.refetch();
+ // pagination
+ const [, setNumPages] = useState(0);
+ const [page, setPage] = useState(1);
+ const [numFiles, setNumFiles] = useState(0);
+
+ useEffect(() => {
+ (async () => {
+ const { count } = await useFetch('/api/user/paged?count=true');
+ setNumPages(count);
+
+ const { count: filesCount } = await useFetch('/api/user/files?count=true');
+ setNumFiles(filesCount);
+ })();
+ }, [page]);
+
+ const files = usePaginatedFiles(page);
+
+ // sorting
+ const [sortStatus, setSortStatus] = useState({
+ columnAccessor: 'date',
+ direction: 'asc',
+ });
+ const [records, setRecords] = useState(files.data);
+
+ useEffect(() => {
+ setRecords(files.data);
+ }, [files.data]);
+
+ useEffect(() => {
+ if (!records || records.length === 0) return;
+
+ const sortedRecords = [...records].sort((a, b) => {
+ if (sortStatus.direction === 'asc') {
+ return a[sortStatus.columnAccessor] > b[sortStatus.columnAccessor] ? 1 : -1;
+ }
+
+ return a[sortStatus.columnAccessor] < b[sortStatus.columnAccessor] ? 1 : -1;
+ });
+
+ setRecords(sortedRecords);
+ }, [sortStatus]);
+
+ // file modal on click
+ const [open, setOpen] = useState(false);
+ const [selectedFile, setSelectedFile] = useState(null);
+
+ const updateFiles = () => {
+ files.refetch();
recent.refetch();
stats.refetch();
};
- const deleteImage = async ({ original }) => {
+ const deleteFile = async (file) => {
const res = await useFetch('/api/user/files', 'DELETE', {
- id: original.id,
+ id: file.id,
});
if (!res.error) {
- updateImages();
+ updateFiles();
showNotification({
title: 'File Deleted',
- message: `${original.name}`,
+ message: `${file.name}`,
color: 'green',
icon: ,
});
@@ -50,8 +96,8 @@ export default function Dashboard({ disableMediaPreview, exifEnabled }) {
}
};
- const copyImage = async ({ original }) => {
- clipboard.copy(`${window.location.protocol}//${window.location.host}${original.url}`);
+ const copyFile = async (file) => {
+ clipboard.copy(`${window.location.protocol}//${window.location.host}${file.url}`);
if (!navigator.clipboard)
showNotification({
title: 'Unable to copy to clipboard',
@@ -63,22 +109,34 @@ export default function Dashboard({ disableMediaPreview, exifEnabled }) {
title: 'Copied to clipboard',
message: (
{`${window.location.protocol}//${window.location.host}${original.url}`}
+ href={`${window.location.protocol}//${window.location.host}${file.url}`}
+ >{`${window.location.protocol}//${window.location.host}${file.url}`}
),
icon: ,
});
};
- const viewImage = async ({ original }) => {
- window.open(`${window.location.protocol}//${window.location.host}${original.url}`);
+ const viewFile = async (file) => {
+ window.open(`${window.location.protocol}//${window.location.host}${file.url}`);
};
return (
+ {selectedFile && (
+
files.refetch()}
+ reducedActions={false}
+ exifEnabled={exifEnabled}
+ />
+ )}
+
Welcome back, {user?.username}
- You have {images.isSuccess ? images.data.length : '...'} files
+ You have {numFiles === 0 ? '...' : numFiles} files
@@ -90,74 +148,92 @@ export default function Dashboard({ disableMediaPreview, exifEnabled }) {
View your gallery here.
- >}
+
+ new Date(file.createdAt).toLocaleString(),
},
{
- accessorKey: 'mimetype',
- header: 'Type',
- filterFn: stringFilterFn,
- },
- {
- accessorKey: 'createdAt',
- header: 'Date',
- filterFn: dateFilterFn,
+ accessor: 'actions',
+ textAlignment: 'right',
+ render: (file) => (
+
+
+ {
+ setSelectedFile(file);
+ setOpen(true);
+ }}
+ color='blue'
+ >
+
+
+
+
+
+ viewFile(file)} color='blue'>
+
+
+
+
+ copyFile(file)} color='green'>
+
+
+ deleteFile(file)} color='red'>
+
+
+
+ ),
},
]}
+ records={records ?? []}
+ fetching={files.isLoading}
+ loaderBackgroundBlur={5}
+ loaderVariant='dots'
+ minHeight={620}
+ page={page}
+ onPageChange={setPage}
+ recordsPerPage={16}
+ totalRecords={numFiles}
+ sortStatus={sortStatus}
+ onSortStatusChange={setSortStatus}
+ rowContextMenu={{
+ shadow: 'xl',
+ borderRadius: 'md',
+ items: (file) => [
+ {
+ key: 'view',
+ icon: ,
+ title: `View ${file.name}`,
+ onClick: () => viewFile(file),
+ },
+ {
+ key: 'copy',
+ icon: ,
+ title: `Copy ${file.name}`,
+ onClick: () => copyFile(file),
+ },
+ {
+ key: 'delete',
+ icon: ,
+ title: `Delete ${file.name}`,
+ onClick: () => deleteFile(file),
+ },
+ ],
+ }}
+ onCellClick={({ record: file }) => {
+ setSelectedFile(file);
+ setOpen(true);
+ }}
/>
diff --git a/src/pages/api/user/files.ts b/src/pages/api/user/files.ts
index 9afc7f0..488d3cc 100644
--- a/src/pages/api/user/files.ts
+++ b/src/pages/api/user/files.ts
@@ -60,6 +60,16 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) {
delete image.password;
return res.json(image);
} else {
+ if (req.query.count) {
+ const count = await prisma.file.count({
+ where: {
+ userId: user.id,
+ favorite: !!req.query.favorite,
+ },
+ });
+
+ return res.json({ count });
+ }
let files: {
favorite: boolean;
createdAt: Date;
diff --git a/tsconfig.json b/tsconfig.json
index 303cf22..726cd7c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -27,12 +27,8 @@
},
"include": [
"next-env.d.ts",
- "zip-env.d.ts",
"**/*.ts",
"**/*.tsx",
- "**/**/*.ts",
- "**/**/*.tsx",
- "prisma/seed.ts"
],
"exclude": ["node_modules", "dist", ".yarn", ".next"]
}
diff --git a/yarn.lock b/yarn.lock
index 9a34d2a..63342d6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1167,33 +1167,6 @@ __metadata:
languageName: node
linkType: hard
-"@dicedtomato/mantine-data-grid@npm:0.0.23":
- version: 0.0.23
- resolution: "@dicedtomato/mantine-data-grid@npm:0.0.23"
- dependencies:
- "@emotion/react": ^11.10.4
- "@mantine/core": ^5.5.6
- "@mantine/dates": ^5.5.6
- "@mantine/hooks": ^5.5.6
- "@tanstack/react-table": ^8.5.15
- dayjs: ^1.11.4
- react: ^18.0.0
- react-dom: ^18.0.0
- tabler-icons-react: ^1.54.0
- peerDependencies:
- "@mantine/core": ^5.0.0
- "@mantine/dates": ^5.0.0
- "@mantine/hooks": ^5.0.0
- dayjs: ^1.11.4
- react: ^18.0.0
- react-dom: ^18.0.0
- peerDependenciesMeta:
- dayjs:
- optional: true
- checksum: e08bfff49f4ef58e88169fe31c1589d9e94ec5b94a8e04d39e0ddbd833ae79fe3a67350e7442d8d15ec0e3f887dd872af88eacabfce71fe2f3bd6b280811bdf3
- languageName: node
- linkType: hard
-
"@emotion/babel-plugin@npm:^11.10.5":
version: 11.10.5
resolution: "@emotion/babel-plugin@npm:11.10.5"
@@ -1243,7 +1216,7 @@ __metadata:
languageName: node
linkType: hard
-"@emotion/react@npm:^11.10.4, @emotion/react@npm:^11.10.5":
+"@emotion/react@npm:^11.10.5":
version: 11.10.5
resolution: "@emotion/react@npm:11.10.5"
dependencies:
@@ -1479,7 +1452,7 @@ __metadata:
languageName: node
linkType: hard
-"@mantine/core@npm:^5.5.6, @mantine/core@npm:^5.9.2":
+"@mantine/core@npm:^5.9.2":
version: 5.9.3
resolution: "@mantine/core@npm:5.9.3"
dependencies:
@@ -1496,20 +1469,6 @@ __metadata:
languageName: node
linkType: hard
-"@mantine/dates@npm:^5.5.6":
- version: 5.9.3
- resolution: "@mantine/dates@npm:5.9.3"
- dependencies:
- "@mantine/utils": 5.9.3
- peerDependencies:
- "@mantine/core": 5.9.3
- "@mantine/hooks": 5.9.3
- dayjs: ">=1.0.0"
- react: ">=16.8.0"
- checksum: fc7c8d19ab10c1d997a882debae74f21fa3a2a59ee834b901713e5ddd9feba7197f61fb68a9a27794071d83d7690564fc45793a6966eebf5f55dff368f837aee
- languageName: node
- linkType: hard
-
"@mantine/dropzone@npm:^5.9.2":
version: 5.9.3
resolution: "@mantine/dropzone@npm:5.9.3"
@@ -1537,7 +1496,7 @@ __metadata:
languageName: node
linkType: hard
-"@mantine/hooks@npm:^5.5.6, @mantine/hooks@npm:^5.9.2":
+"@mantine/hooks@npm:^5.9.2":
version: 5.9.3
resolution: "@mantine/hooks@npm:5.9.3"
peerDependencies:
@@ -2356,25 +2315,6 @@ __metadata:
languageName: node
linkType: hard
-"@tanstack/react-table@npm:^8.5.15":
- version: 8.7.0
- resolution: "@tanstack/react-table@npm:8.7.0"
- dependencies:
- "@tanstack/table-core": 8.7.0
- peerDependencies:
- react: ">=16"
- react-dom: ">=16"
- checksum: 5f739f619dacfd134449bc8cff819d7e1b9549b8c8b20c293f2c786098a53d20fe5755727d8abb6fa56a64583792bbc89d8b1c7cd24ac3497495d2c20bac9e77
- languageName: node
- linkType: hard
-
-"@tanstack/table-core@npm:8.7.0":
- version: 8.7.0
- resolution: "@tanstack/table-core@npm:8.7.0"
- checksum: 835511727ab5651066a4cbc98916fbc2463ec6d6ddc5c74c1fec5713eeba8e26641653c1a35b69b303f0c58f574416a09e26da44cf7e9a884cb954fc26b12afd
- languageName: node
- linkType: hard
-
"@tediousjs/connection-string@npm:^0.4.1":
version: 0.4.1
resolution: "@tediousjs/connection-string@npm:0.4.1"
@@ -4193,7 +4133,7 @@ __metadata:
languageName: node
linkType: hard
-"dayjs@npm:^1.11.4, dayjs@npm:^1.11.7":
+"dayjs@npm:^1.11.7":
version: 1.11.7
resolution: "dayjs@npm:1.11.7"
checksum: 5003a7c1dd9ed51385beb658231c3548700b82d3548c0cfbe549d85f2d08e90e972510282b7506941452c58d32136d6362f009c77ca55381a09c704e9f177ebb
@@ -7188,6 +7128,17 @@ __metadata:
languageName: node
linkType: hard
+"mantine-datatable@npm:^1.8.6":
+ version: 1.8.6
+ resolution: "mantine-datatable@npm:1.8.6"
+ peerDependencies:
+ "@mantine/core": ^5.10.4
+ "@mantine/hooks": ^5.10.4
+ react: ^18.2.0
+ checksum: a4558418067ada3e269e3d9dc0153b613b031ecd5fccd484b45a2b13e403084971870515d51c888d933eb2f4d85f6df2ad221b0c84a2bf2cd602d27938bb9029
+ languageName: node
+ linkType: hard
+
"mariadb@npm:3.0.1":
version: 3.0.1
resolution: "mariadb@npm:3.0.1"
@@ -9291,7 +9242,7 @@ __metadata:
languageName: node
linkType: hard
-"react-dom@npm:^18.0.0, react-dom@npm:^18.2.0":
+"react-dom@npm:^18.2.0":
version: 18.2.0
resolution: "react-dom@npm:18.2.0"
dependencies:
@@ -9450,7 +9401,7 @@ __metadata:
languageName: node
linkType: hard
-"react@npm:^18.0.0, react@npm:^18.2.0":
+"react@npm:^18.2.0":
version: 18.2.0
resolution: "react@npm:18.2.0"
dependencies:
@@ -10571,15 +10522,6 @@ __metadata:
languageName: node
linkType: hard
-"tabler-icons-react@npm:^1.54.0":
- version: 1.56.0
- resolution: "tabler-icons-react@npm:1.56.0"
- peerDependencies:
- react: ">= 16.8.0"
- checksum: 0b058055826fe478afa5c72641bb5207b6332b177d6ed7f505ebaad632cf33a63f0a3bf87af103af2b65bb0fc7b76f056ef03328fea7fa0c7378e30a82c3212b
- languageName: node
- linkType: hard
-
"tapable@npm:^2.2.0":
version: 2.2.1
resolution: "tapable@npm:2.2.1"
@@ -11605,7 +11547,6 @@ __metadata:
version: 0.0.0-use.local
resolution: "zipline@workspace:."
dependencies:
- "@dicedtomato/mantine-data-grid": 0.0.23
"@emotion/react": ^11.10.5
"@emotion/server": ^11.10.0
"@mantine/core": ^5.9.2
@@ -11647,6 +11588,7 @@ __metadata:
fflate: ^0.7.4
find-my-way: ^7.3.1
katex: ^0.16.4
+ mantine-datatable: ^1.8.6
minio: ^7.0.32
ms: canary
multer: ^1.4.5-lts.1