Skip to content

Commit 46cd558

Browse files
authored
Merge pull request #107 from CivicDataLab/105-dataset-listing-in-organization-dashboard
Dataset listing under organization dashboard with normal pagination and delete functionality
2 parents b33af50 + ec80258 commit 46cd558

2 files changed

Lines changed: 246 additions & 20 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Tab, TabList, Tabs } from 'opub-ui';
2+
3+
export const Navigation = ({
4+
setNavigationTab,
5+
options,
6+
}: {
7+
setNavigationTab: (url: string) => void;
8+
options: Array<{
9+
label: string;
10+
url: string;
11+
selected: boolean;
12+
}>;
13+
}) => {
14+
const handleTabClick = (url: string) => {
15+
setNavigationTab(url);
16+
};
17+
18+
return (
19+
<div>
20+
<Tabs defaultValue="drafts">
21+
<TabList fitted>
22+
{options.map((item, index) => (
23+
<Tab
24+
value={item.url}
25+
key={index}
26+
onClick={() => handleTabClick(item.url)}
27+
>
28+
{item.label}
29+
</Tab>
30+
))}
31+
</TabList>
32+
</Tabs>
33+
</div>
34+
);
35+
};

app/[locale]/dashboard/organization/[organizationId]/dataset/page.tsx

Lines changed: 211 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,217 @@
1-
import { Page } from './page-layout';
2-
3-
// const allDatasetsQueryDoc = graphql(`
4-
// query allDatasetsQuery {
5-
// all_datasets {
6-
// id
7-
// title
8-
// description
9-
// }
10-
// }
11-
// `);
12-
13-
export default async function DatasetPage() {
14-
// const queryClient = getQueryClient();
15-
// await queryClient.prefetchQuery(['all_datasets'], () =>
16-
// GraphQL(allDatasetsQueryDoc)
17-
// );
18-
// const dehydratedState = dehydrate(queryClient);
1+
'use client';
2+
3+
import { useEffect } from 'react';
4+
import { useRouter } from 'next/navigation';
5+
import { graphql } from '@/gql';
6+
import { useMutation, useQuery } from '@tanstack/react-query';
7+
import { parseAsString, useQueryState } from 'next-usequerystate';
8+
import { DataTable, IconButton, toast } from 'opub-ui';
9+
10+
import { GraphQL } from '@/lib/api';
11+
import { Icons } from '@/components/icons';
12+
import { LinkButton } from '@/components/Link';
13+
import { Loading } from '@/components/loading';
14+
import { ActionBar } from './components/action-bar';
15+
import { Content } from './components/content';
16+
import { Navigation } from './components/navigate-org-datasets';
17+
18+
const allDatasetsQueryDoc: any = graphql(`
19+
query allDatasetsQuery($filters: DatasetFilter) {
20+
datasets(filters: $filters) {
21+
title
22+
id
23+
created
24+
modified
25+
}
26+
}
27+
`);
28+
29+
const createDatasetMutationDoc: any = graphql(`
30+
mutation GenerateDatasetName {
31+
addDataset {
32+
__typename
33+
... on TypeDataset {
34+
id
35+
created
36+
}
37+
... on OperationInfo {
38+
messages {
39+
kind
40+
message
41+
}
42+
}
43+
}
44+
}
45+
`);
46+
47+
const deleteDatasetMutationDoc: any = graphql(`
48+
mutation deleteDatasetMutation($datasetId: UUID!) {
49+
deleteDataset(datasetId: $datasetId)
50+
}
51+
`);
52+
53+
export default function DatasetPage({
54+
params,
55+
}: {
56+
params: { organizationId: string };
57+
}) {
58+
const router = useRouter();
59+
60+
const [navigationTab, setNavigationTab] = useQueryState('tab', parseAsString);
61+
62+
let navigationOptions = [
63+
{
64+
label: 'Drafts',
65+
url: `drafts`,
66+
selected: navigationTab === 'drafts',
67+
},
68+
{
69+
label: 'Under Moderation',
70+
url: `under-moderation`,
71+
selected: navigationTab === 'under-moderation',
72+
},
73+
{
74+
label: 'Needs Review',
75+
url: `needs-review`,
76+
selected: navigationTab === 'needs-review',
77+
},
78+
{
79+
label: 'Published',
80+
url: `published`,
81+
selected: navigationTab === 'published',
82+
},
83+
];
84+
85+
useEffect(() => {
86+
if (navigationTab === null || navigationTab === undefined)
87+
setNavigationTab('drafts');
88+
}, [navigationTab]);
89+
90+
const AllDatasetsQuery: { data: any; isLoading: boolean; refetch: any } =
91+
useQuery([`fetch_datasets_org_dashboard`], () =>
92+
GraphQL(allDatasetsQueryDoc, [])
93+
);
94+
95+
const DeleteDatasetMutation: {
96+
mutate: any;
97+
isLoading: boolean;
98+
error: any;
99+
} = useMutation(
100+
[`delete_dataset`],
101+
(data: { datasetId: string }) =>
102+
GraphQL(deleteDatasetMutationDoc, { datasetId: data.datasetId }),
103+
{
104+
onSuccess: () => {
105+
toast(`Deleted dataset successfully`);
106+
AllDatasetsQuery.refetch();
107+
},
108+
onError: (err: any) => {
109+
toast('Error: ' + err.message.split(':')[0]);
110+
},
111+
}
112+
);
113+
114+
const CreateDatasetMutation: { mutate: any; isLoading: boolean; error: any } =
115+
useMutation(() => GraphQL(createDatasetMutationDoc, []), {
116+
onSuccess: (data: any) => {
117+
router.push(
118+
`/dashboard/organization/${params.organizationId}/dataset/${data?.addDataset?.id}/edit/resources`
119+
);
120+
},
121+
onError: (err: any) => {
122+
console.log('Error ::: ', err);
123+
},
124+
});
125+
126+
const datasetsListColumns = [
127+
{
128+
accessorKey: 'title',
129+
header: 'Title',
130+
cell: ({ row }: any) => (
131+
<LinkButton
132+
kind="tertiary"
133+
size="medium"
134+
href={`/dashboard/organization/${params.organizationId}/dataset/${row.original.id}/edit/resources`}
135+
>
136+
{row.original.title}
137+
</LinkButton>
138+
),
139+
},
140+
{ accessorKey: 'created', header: 'Date Created' },
141+
{ accessorKey: 'modified', header: 'Date Modified' },
142+
{
143+
accessorKey: 'delete',
144+
header: 'Delete',
145+
cell: ({ row }: any) => (
146+
<IconButton
147+
size="medium"
148+
icon={Icons.delete}
149+
color="interactive"
150+
onClick={() =>
151+
DeleteDatasetMutation.mutate({
152+
datasetId: row.original?.dataset?.id,
153+
})
154+
}
155+
>
156+
Delete
157+
</IconButton>
158+
),
159+
},
160+
];
161+
162+
const generateTableData = (list: Array<any>) => {
163+
return list.map((item) => {
164+
return {
165+
title: item.title,
166+
id: item.id,
167+
created: new Date(item.created).toLocaleString('en-GB', {
168+
day: '2-digit',
169+
month: '2-digit',
170+
year: 'numeric',
171+
}),
172+
modified: new Date(item.modified).toLocaleString('en-GB', {
173+
day: '2-digit',
174+
month: '2-digit',
175+
year: 'numeric',
176+
}),
177+
};
178+
});
179+
};
19180

20181
return (
21182
<>
22-
<div className="flex h-full flex-col">
23-
<Page />
183+
<div className="mt-8 flex h-full flex-col">
184+
<Navigation
185+
setNavigationTab={setNavigationTab}
186+
options={navigationOptions}
187+
/>
188+
189+
{AllDatasetsQuery.data?.datasets.length > 0 ? (
190+
<div className="mt-6">
191+
<ActionBar
192+
title={
193+
navigationOptions.find((item) => item.selected)?.label || ''
194+
}
195+
primaryAction={{
196+
content: 'Add New Dataset',
197+
onAction: () => CreateDatasetMutation.mutate(),
198+
}}
199+
/>
200+
201+
<DataTable
202+
columns={datasetsListColumns}
203+
rows={generateTableData(AllDatasetsQuery.data.datasets)}
204+
hideSelection
205+
hideViewSelector
206+
/>
207+
</div>
208+
) : AllDatasetsQuery.isLoading ? (
209+
<Loading />
210+
) : (
211+
<Content />
212+
)}
213+
214+
{/* <Page /> */}
24215
</div>
25216
</>
26217
);

0 commit comments

Comments
 (0)