diff --git a/package.json b/package.json
index b115a63..42a462b 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@trpc/server": "^10.38.4",
"@types/uuid": "^9.0.3",
"antd": "^5.9.3",
+ "array-move": "^3.0.1",
"axios": "^1.5.0",
"badge-maker": "^3.3.1",
"bcryptjs": "^2.4.3",
@@ -58,6 +59,7 @@
"puppeteer": "^21.3.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-easy-sort": "^1.5.3",
"react-router": "^6.15.0",
"react-router-dom": "^6.15.0",
"request-ip": "^3.3.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c3aa936..e71d96e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -31,6 +31,9 @@ dependencies:
antd:
specifier: ^5.9.3
version: 5.9.3(react-dom@18.2.0)(react@18.2.0)
+ array-move:
+ specifier: ^3.0.1
+ version: 3.0.1
axios:
specifier: ^1.5.0
version: 1.5.0
@@ -127,6 +130,9 @@ dependencies:
react-dom:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
+ react-easy-sort:
+ specifier: ^1.5.3
+ version: 1.5.3(react-dom@18.2.0)(react@18.2.0)
react-router:
specifier: ^6.15.0
version: 6.15.0(react@18.2.0)
@@ -2417,6 +2423,11 @@ packages:
resolution: {integrity: sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==}
dev: false
+ /array-move@3.0.1:
+ resolution: {integrity: sha512-H3Of6NIn2nNU1gsVDqDnYKY/LCdWvCMMOWifNGhKcVQgiZ6nOek39aESOvro6zmueP07exSl93YLvkN4fZOkSg==}
+ engines: {node: '>=10'}
+ dev: false
+
/array-tree-filter@2.1.0:
resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==}
dev: false
@@ -5753,6 +5764,19 @@ packages:
scheduler: 0.23.0
dev: false
+ /react-easy-sort@1.5.3(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-d5DVqmlqGfpRcE2blMkZ/H8AvsY6KZmUG5nOeUrV5INWMbqDIXTRBkkBnJvNOQT6mupAjl4wokgQcur5zRMYxw==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ react: '>=16.4.0'
+ react-dom: '>=16.4.0'
+ dependencies:
+ array-move: 3.0.1
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ tslib: 2.0.1
+ dev: false
+
/react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
dev: false
@@ -6577,6 +6601,10 @@ packages:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: false
+ /tslib@2.0.1:
+ resolution: {integrity: sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==}
+ dev: false
+
/tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
dev: false
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 467f22a..2375a0a 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -23,10 +23,11 @@ model User {
}
model Workspace {
- id String @id @unique @default(cuid()) @db.VarChar(30)
- name String @db.VarChar(100)
- createdAt DateTime @default(now()) @db.Timestamptz(6)
- updatedAt DateTime @updatedAt @db.Timestamptz(6)
+ id String @id @unique @default(cuid()) @db.VarChar(30)
+ name String @db.VarChar(100)
+ dashboardOrder String[]
+ createdAt DateTime @default(now()) @db.Timestamptz(6)
+ updatedAt DateTime @updatedAt @db.Timestamptz(6)
users WorkspacesOnUsers[]
websites Website[]
diff --git a/src/client/pages/Dashboard.tsx b/src/client/pages/Dashboard.tsx
index ccb79f4..99d24c6 100644
--- a/src/client/pages/Dashboard.tsx
+++ b/src/client/pages/Dashboard.tsx
@@ -1,19 +1,24 @@
-import React, { Fragment } from 'react';
+import React, { Fragment, useMemo, useState } from 'react';
import { ArrowRightOutlined, EditOutlined } from '@ant-design/icons';
import { Button, Divider } from 'antd';
import { WebsiteOverview } from '../components/website/WebsiteOverview';
-import { useCurrentWorkspaceId } from '../store/user';
+import { useCurrentWorkspace } from '../store/user';
import { Loading } from '../components/Loading';
import { useWorspaceWebsites } from '../api/model/website';
import { NoWorkspaceTip } from '../components/NoWorkspaceTip';
import { useNavigate } from 'react-router';
+import { useEvent } from '../hooks/useEvent';
+import arrayMove from 'array-move';
+import SortableList, { SortableItem } from 'react-easy-sort';
+import { defaultErrorHandler, defaultSuccessHandler, trpc } from '../api/trpc';
export const Dashboard: React.FC = React.memo(() => {
- const workspaceId = useCurrentWorkspaceId()!;
- const { isLoading, websites } = useWorspaceWebsites(workspaceId);
+ const workspace = useCurrentWorkspace();
const navigate = useNavigate();
+ const [isEditLayout, setIsEditLayout] = useState(false);
+ const { isLoading, websiteList, handleSortEnd } = useDashboardWebsiteList();
- if (!workspaceId) {
+ if (!workspace) {
return