@tulip-systems/drive 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +662 -0
- package/package.json +113 -0
- package/src/components/content.tsx +13 -0
- package/src/components/context.client.tsx +12 -0
- package/src/components/dnd.client.tsx +47 -0
- package/src/components/grid-card.client.tsx +252 -0
- package/src/components/grid.client.tsx +96 -0
- package/src/components/navigation/breadcrumbs.client.tsx +125 -0
- package/src/components/navigation/header.client.tsx +45 -0
- package/src/components/navigation/toolbar.client.tsx +35 -0
- package/src/components/navigation/view-switcher.client.tsx +32 -0
- package/src/components/selection.client.tsx +48 -0
- package/src/components/view.client.tsx +67 -0
- package/src/config/filters.ts +14 -0
- package/src/config/types.tsx +90 -0
- package/src/entry.client.ts +7 -0
- package/src/entry.server.ts +4 -0
- package/src/entry.ts +10 -0
- package/src/lib/constants.ts +19 -0
- package/src/lib/contracts.ts +121 -0
- package/src/lib/dto.ts +83 -0
- package/src/lib/helpers.server.ts +14 -0
- package/src/lib/helpers.ts +32 -0
- package/src/lib/search-params.ts +5 -0
- package/src/lib/validators.ts +89 -0
- package/src/providers/google/components/command-file-update.tsx +100 -0
- package/src/providers/google/components/command-folder-create.tsx +104 -0
- package/src/providers/google/components/command-folder-update.tsx +100 -0
- package/src/providers/google/components/content.client.tsx +6 -0
- package/src/providers/google/components/navigation.client.tsx +21 -0
- package/src/providers/google/components/provider.client.tsx +60 -0
- package/src/providers/google/components/view.client.tsx +158 -0
- package/src/providers/google/config/columns-data.tsx +81 -0
- package/src/providers/google/config/filters.ts +3 -0
- package/src/providers/google/entry.client.ts +10 -0
- package/src/providers/google/entry.server.ts +5 -0
- package/src/providers/google/entry.ts +12 -0
- package/src/providers/google/lib/constants.ts +10 -0
- package/src/providers/google/lib/dto.ts +104 -0
- package/src/providers/google/lib/helpers.ts +37 -0
- package/src/providers/google/lib/router.server.ts +62 -0
- package/src/providers/google/lib/schema.ts +9 -0
- package/src/providers/google/lib/search-params.ts +7 -0
- package/src/providers/google/lib/service.server.ts +792 -0
- package/src/providers/google/lib/validators.ts +148 -0
- package/src/providers/local/components/command-file-update.tsx +93 -0
- package/src/providers/local/components/command-file-upload.tsx +29 -0
- package/src/providers/local/components/command-folder-create.tsx +100 -0
- package/src/providers/local/components/command-folder-update.tsx +93 -0
- package/src/providers/local/components/content.client.tsx +3 -0
- package/src/providers/local/components/navigation.client.tsx +23 -0
- package/src/providers/local/components/provider.client.tsx +90 -0
- package/src/providers/local/components/upload-zone-context.client.tsx +43 -0
- package/src/providers/local/components/upload-zone.client.tsx +182 -0
- package/src/providers/local/components/view.client.tsx +145 -0
- package/src/providers/local/config/columns-data.tsx +81 -0
- package/src/providers/local/config/filters.ts +14 -0
- package/src/providers/local/entry.client.ts +18 -0
- package/src/providers/local/entry.server.ts +7 -0
- package/src/providers/local/entry.ts +14 -0
- package/src/providers/local/lib/constants.ts +23 -0
- package/src/providers/local/lib/helpers.ts +105 -0
- package/src/providers/local/lib/route-handler.server.ts +153 -0
- package/src/providers/local/lib/router.server.ts +137 -0
- package/src/providers/local/lib/schema.ts +104 -0
- package/src/providers/local/lib/search-params.ts +4 -0
- package/src/providers/local/lib/service.server.ts +1116 -0
- package/src/providers/local/lib/upload.client.ts +177 -0
- package/src/providers/local/lib/validators.ts +154 -0
- package/src/styles.css +1 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { resolveFiltersSchema, tableQuerySchema } from "@tulip-systems/core/data-tables";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { driveTreeFilters } from "@/config/filters";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create drive folder input schema
|
|
7
|
+
* @description zod schema for validating the input of the create drive folder command
|
|
8
|
+
*/
|
|
9
|
+
export const createDriveFolderInputSchema = z.object({
|
|
10
|
+
name: z.string(),
|
|
11
|
+
namespace: z.string(),
|
|
12
|
+
parentId: z.string().nullable().optional(),
|
|
13
|
+
});
|
|
14
|
+
export type CreateDriveFolderInput = z.input<typeof createDriveFolderInputSchema>;
|
|
15
|
+
export type CreateDriveFolderSchema = z.infer<typeof createDriveFolderInputSchema>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Update drive node input schema
|
|
19
|
+
*/
|
|
20
|
+
export const updateDriveNodeInputSchema = z.object({
|
|
21
|
+
name: z.string().optional(),
|
|
22
|
+
});
|
|
23
|
+
export type UpdateDriveNodeInput = z.input<typeof updateDriveNodeInputSchema>;
|
|
24
|
+
export type UpdateDriveNodeSchema = z.infer<typeof updateDriveNodeInputSchema>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Upload drive file input schema
|
|
28
|
+
* @description zod schema for validating the input of the upload drive file command
|
|
29
|
+
*/
|
|
30
|
+
export const uploadDriveFileInputSchema = z.object({
|
|
31
|
+
name: z.string(),
|
|
32
|
+
namespace: z.string(),
|
|
33
|
+
parentId: z.string().nullable().optional(),
|
|
34
|
+
contentType: z.string().nullable().optional(),
|
|
35
|
+
size: z.number().nullable().optional(),
|
|
36
|
+
});
|
|
37
|
+
export type UploadDriveFileInput = z.input<typeof uploadDriveFileInputSchema>;
|
|
38
|
+
export type UploadDriveFileSchema = z.infer<typeof uploadDriveFileInputSchema>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Presign drive file input schema
|
|
42
|
+
* @description zod schema for validating the input of the presign drive file command
|
|
43
|
+
*/
|
|
44
|
+
export const presignDriveFileInputSchema = z.object({
|
|
45
|
+
name: z.string(),
|
|
46
|
+
namespace: z.string(),
|
|
47
|
+
parentId: z.string().nullable().optional(),
|
|
48
|
+
contentType: z.string().nullable().optional(),
|
|
49
|
+
size: z.number().nullable().optional(),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export type PresignDriveFileInput = z.input<typeof presignDriveFileInputSchema>;
|
|
53
|
+
export type PresignDriveFileSchema = z.infer<typeof presignDriveFileInputSchema>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Table filters
|
|
57
|
+
*/
|
|
58
|
+
export const driveTableFiltersSchema = resolveFiltersSchema(driveTreeFilters)
|
|
59
|
+
.partial()
|
|
60
|
+
.extend({
|
|
61
|
+
namespace: z.string(),
|
|
62
|
+
parentId: z.string().nullable(),
|
|
63
|
+
})
|
|
64
|
+
.transform((input) => ({
|
|
65
|
+
...input,
|
|
66
|
+
isArchived: input?.isArchived ?? false,
|
|
67
|
+
}));
|
|
68
|
+
|
|
69
|
+
export type NodesTableFilters = z.infer<typeof driveTableFiltersSchema>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* List tree input schema
|
|
73
|
+
*/
|
|
74
|
+
export const listDriveTreeInputSchema = tableQuerySchema.extend({
|
|
75
|
+
filters: driveTableFiltersSchema,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
export type ListDriveTreeInput = z.input<typeof listDriveTreeInputSchema>;
|
|
79
|
+
export type ListDriveTreeSchema = z.infer<typeof listDriveTreeInputSchema>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get nodes by parent id input schema
|
|
83
|
+
*/
|
|
84
|
+
export const getNodesByParentIdInputSchema = tableQuerySchema
|
|
85
|
+
.pick({ order: true, sort: true, search: true })
|
|
86
|
+
.extend({ filters: driveTableFiltersSchema });
|
|
87
|
+
|
|
88
|
+
export type GetDriveNodesByParentIdInput = z.input<typeof getNodesByParentIdInputSchema>;
|
|
89
|
+
export type GetDriveNodesByParentIdSchema = z.infer<typeof getNodesByParentIdInputSchema>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
4
|
+
import type { DefaultError, MutationOptions } from "@tanstack/react-query";
|
|
5
|
+
import {
|
|
6
|
+
CommandFormDialog,
|
|
7
|
+
CommandFormDialogCancel,
|
|
8
|
+
CommandFormDialogContent,
|
|
9
|
+
CommandFormDialogFields,
|
|
10
|
+
CommandFormDialogFooter,
|
|
11
|
+
CommandFormDialogHeader,
|
|
12
|
+
CommandFormDialogSubmit,
|
|
13
|
+
CommandFormDialogTitle,
|
|
14
|
+
CommandFormDialogTrigger,
|
|
15
|
+
CommandLabel,
|
|
16
|
+
} from "@tulip-systems/core/commands/client";
|
|
17
|
+
import { Input } from "@tulip-systems/core/components";
|
|
18
|
+
import {
|
|
19
|
+
Form,
|
|
20
|
+
FormControl,
|
|
21
|
+
FormField,
|
|
22
|
+
FormItem,
|
|
23
|
+
FormLabel,
|
|
24
|
+
FormMessage,
|
|
25
|
+
} from "@tulip-systems/core/components/client";
|
|
26
|
+
import { FilePen } from "lucide-react";
|
|
27
|
+
import { useForm } from "react-hook-form";
|
|
28
|
+
import {
|
|
29
|
+
type UpdateGoogleDriveNodeInput,
|
|
30
|
+
updateGoogleDriveNodeInputSchema,
|
|
31
|
+
} from "../lib/validators";
|
|
32
|
+
|
|
33
|
+
export type GoogleDriveFileUpdateCommandProps<
|
|
34
|
+
TData = unknown,
|
|
35
|
+
TError = DefaultError,
|
|
36
|
+
TVariables = unknown,
|
|
37
|
+
TOnMutateResult = unknown,
|
|
38
|
+
> = {
|
|
39
|
+
defaultValues: Partial<UpdateGoogleDriveNodeInput>;
|
|
40
|
+
variables: (values: UpdateGoogleDriveNodeInput) => TVariables;
|
|
41
|
+
mutation: MutationOptions<TData, TError, TVariables, TOnMutateResult>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* File update command
|
|
46
|
+
* @description command to update a Google Drive file
|
|
47
|
+
*/
|
|
48
|
+
export function GoogleDriveFileUpdateCommand<
|
|
49
|
+
TData = unknown,
|
|
50
|
+
TError = DefaultError,
|
|
51
|
+
TVariables = unknown,
|
|
52
|
+
TOnMutateResult = unknown,
|
|
53
|
+
>({
|
|
54
|
+
defaultValues,
|
|
55
|
+
variables,
|
|
56
|
+
mutation,
|
|
57
|
+
}: GoogleDriveFileUpdateCommandProps<TData, TError, TVariables, TOnMutateResult>) {
|
|
58
|
+
const form = useForm<UpdateGoogleDriveNodeInput>({
|
|
59
|
+
resolver: zodResolver(updateGoogleDriveNodeInputSchema),
|
|
60
|
+
defaultValues,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Form {...form}>
|
|
65
|
+
<CommandFormDialog>
|
|
66
|
+
<CommandFormDialogTrigger label="Wijzigen">
|
|
67
|
+
<FilePen className="size-4" />
|
|
68
|
+
<CommandLabel />
|
|
69
|
+
</CommandFormDialogTrigger>
|
|
70
|
+
|
|
71
|
+
<CommandFormDialogContent variables={variables} mutation={mutation}>
|
|
72
|
+
<CommandFormDialogHeader>
|
|
73
|
+
<CommandFormDialogTitle>Bestand wijzigen</CommandFormDialogTitle>
|
|
74
|
+
</CommandFormDialogHeader>
|
|
75
|
+
|
|
76
|
+
<CommandFormDialogFields>
|
|
77
|
+
<FormField
|
|
78
|
+
control={form.control}
|
|
79
|
+
name="name"
|
|
80
|
+
render={({ field }) => (
|
|
81
|
+
<FormItem>
|
|
82
|
+
<FormLabel>Naam</FormLabel>
|
|
83
|
+
<FormControl>
|
|
84
|
+
<Input {...field} value={field.value ?? ""} />
|
|
85
|
+
</FormControl>
|
|
86
|
+
<FormMessage />
|
|
87
|
+
</FormItem>
|
|
88
|
+
)}
|
|
89
|
+
/>
|
|
90
|
+
</CommandFormDialogFields>
|
|
91
|
+
|
|
92
|
+
<CommandFormDialogFooter>
|
|
93
|
+
<CommandFormDialogCancel>Annuleren</CommandFormDialogCancel>
|
|
94
|
+
<CommandFormDialogSubmit>Opslaan</CommandFormDialogSubmit>
|
|
95
|
+
</CommandFormDialogFooter>
|
|
96
|
+
</CommandFormDialogContent>
|
|
97
|
+
</CommandFormDialog>
|
|
98
|
+
</Form>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
4
|
+
import type { DefaultError, MutationOptions } from "@tanstack/react-query";
|
|
5
|
+
import {
|
|
6
|
+
CommandFormDialog,
|
|
7
|
+
CommandFormDialogCancel,
|
|
8
|
+
CommandFormDialogContent,
|
|
9
|
+
CommandFormDialogFields,
|
|
10
|
+
CommandFormDialogFooter,
|
|
11
|
+
CommandFormDialogHeader,
|
|
12
|
+
CommandFormDialogSubmit,
|
|
13
|
+
CommandFormDialogTitle,
|
|
14
|
+
CommandFormDialogTrigger,
|
|
15
|
+
CommandLabel,
|
|
16
|
+
} from "@tulip-systems/core/commands/client";
|
|
17
|
+
import { Input } from "@tulip-systems/core/components";
|
|
18
|
+
import {
|
|
19
|
+
Form,
|
|
20
|
+
FormControl,
|
|
21
|
+
FormField,
|
|
22
|
+
FormItem,
|
|
23
|
+
FormLabel,
|
|
24
|
+
FormMessage,
|
|
25
|
+
} from "@tulip-systems/core/components/client";
|
|
26
|
+
import { FolderPlus } from "lucide-react";
|
|
27
|
+
import { useQueryStates } from "nuqs";
|
|
28
|
+
import { useForm } from "react-hook-form";
|
|
29
|
+
import { driveTreeSearchParams } from "@/lib/search-params";
|
|
30
|
+
import {
|
|
31
|
+
type CreateGoogleDriveFolderInput,
|
|
32
|
+
createGoogleDriveFolderInputSchema,
|
|
33
|
+
} from "../lib/validators";
|
|
34
|
+
|
|
35
|
+
export type GoogleDriveFoldersCreateCommandProps<
|
|
36
|
+
TData = unknown,
|
|
37
|
+
TError = DefaultError,
|
|
38
|
+
TVariables = unknown,
|
|
39
|
+
TOnMutateResult = unknown,
|
|
40
|
+
> = {
|
|
41
|
+
defaultValues?: Partial<CreateGoogleDriveFolderInput>;
|
|
42
|
+
variables: (values: CreateGoogleDriveFolderInput) => TVariables;
|
|
43
|
+
mutation: MutationOptions<TData, TError, TVariables, TOnMutateResult>;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Folders create command
|
|
48
|
+
* @description command to create a Google Drive folder
|
|
49
|
+
*/
|
|
50
|
+
export function GoogleDriveFoldersCreateCommand<
|
|
51
|
+
TData = unknown,
|
|
52
|
+
TError = DefaultError,
|
|
53
|
+
TVariables = unknown,
|
|
54
|
+
TOnMutateResult = unknown,
|
|
55
|
+
>({
|
|
56
|
+
defaultValues,
|
|
57
|
+
variables,
|
|
58
|
+
mutation,
|
|
59
|
+
}: GoogleDriveFoldersCreateCommandProps<TData, TError, TVariables, TOnMutateResult>) {
|
|
60
|
+
const [{ parentId }] = useQueryStates(driveTreeSearchParams);
|
|
61
|
+
|
|
62
|
+
const form = useForm<CreateGoogleDriveFolderInput>({
|
|
63
|
+
resolver: zodResolver(createGoogleDriveFolderInputSchema),
|
|
64
|
+
defaultValues: { ...defaultValues, parentId },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Form {...form}>
|
|
69
|
+
<CommandFormDialog>
|
|
70
|
+
<CommandFormDialogTrigger label="Folder toevoegen" hotkey="mod+i">
|
|
71
|
+
<FolderPlus className="size-4" />
|
|
72
|
+
<CommandLabel />
|
|
73
|
+
</CommandFormDialogTrigger>
|
|
74
|
+
|
|
75
|
+
<CommandFormDialogContent variables={variables} mutation={mutation}>
|
|
76
|
+
<CommandFormDialogHeader>
|
|
77
|
+
<CommandFormDialogTitle>Folder toevoegen</CommandFormDialogTitle>
|
|
78
|
+
</CommandFormDialogHeader>
|
|
79
|
+
|
|
80
|
+
<CommandFormDialogFields>
|
|
81
|
+
<FormField
|
|
82
|
+
control={form.control}
|
|
83
|
+
name="name"
|
|
84
|
+
render={({ field }) => (
|
|
85
|
+
<FormItem>
|
|
86
|
+
<FormLabel>Naam</FormLabel>
|
|
87
|
+
<FormControl>
|
|
88
|
+
<Input {...field} value={field.value ?? ""} />
|
|
89
|
+
</FormControl>
|
|
90
|
+
<FormMessage />
|
|
91
|
+
</FormItem>
|
|
92
|
+
)}
|
|
93
|
+
/>
|
|
94
|
+
</CommandFormDialogFields>
|
|
95
|
+
|
|
96
|
+
<CommandFormDialogFooter>
|
|
97
|
+
<CommandFormDialogCancel>Annuleren</CommandFormDialogCancel>
|
|
98
|
+
<CommandFormDialogSubmit>Toevoegen</CommandFormDialogSubmit>
|
|
99
|
+
</CommandFormDialogFooter>
|
|
100
|
+
</CommandFormDialogContent>
|
|
101
|
+
</CommandFormDialog>
|
|
102
|
+
</Form>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
4
|
+
import type { DefaultError, MutationOptions } from "@tanstack/react-query";
|
|
5
|
+
import {
|
|
6
|
+
CommandFormDialog,
|
|
7
|
+
CommandFormDialogCancel,
|
|
8
|
+
CommandFormDialogContent,
|
|
9
|
+
CommandFormDialogFields,
|
|
10
|
+
CommandFormDialogFooter,
|
|
11
|
+
CommandFormDialogHeader,
|
|
12
|
+
CommandFormDialogSubmit,
|
|
13
|
+
CommandFormDialogTitle,
|
|
14
|
+
CommandFormDialogTrigger,
|
|
15
|
+
CommandLabel,
|
|
16
|
+
} from "@tulip-systems/core/commands/client";
|
|
17
|
+
import { Input } from "@tulip-systems/core/components";
|
|
18
|
+
import {
|
|
19
|
+
Form,
|
|
20
|
+
FormControl,
|
|
21
|
+
FormField,
|
|
22
|
+
FormItem,
|
|
23
|
+
FormLabel,
|
|
24
|
+
FormMessage,
|
|
25
|
+
} from "@tulip-systems/core/components/client";
|
|
26
|
+
import { FolderPen } from "lucide-react";
|
|
27
|
+
import { useForm } from "react-hook-form";
|
|
28
|
+
import {
|
|
29
|
+
type UpdateGoogleDriveNodeInput,
|
|
30
|
+
updateGoogleDriveNodeInputSchema,
|
|
31
|
+
} from "../lib/validators";
|
|
32
|
+
|
|
33
|
+
export type GoogleDriveFoldersUpdateCommandProps<
|
|
34
|
+
TData = unknown,
|
|
35
|
+
TError = DefaultError,
|
|
36
|
+
TVariables = unknown,
|
|
37
|
+
TOnMutateResult = unknown,
|
|
38
|
+
> = {
|
|
39
|
+
defaultValues: Partial<UpdateGoogleDriveNodeInput>;
|
|
40
|
+
variables: (values: UpdateGoogleDriveNodeInput) => TVariables;
|
|
41
|
+
mutation: MutationOptions<TData, TError, TVariables, TOnMutateResult>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Folders update command
|
|
46
|
+
* @description command to update a Google Drive folder
|
|
47
|
+
*/
|
|
48
|
+
export function GoogleDriveFoldersUpdateCommand<
|
|
49
|
+
TData = unknown,
|
|
50
|
+
TError = DefaultError,
|
|
51
|
+
TVariables = unknown,
|
|
52
|
+
TOnMutateResult = unknown,
|
|
53
|
+
>({
|
|
54
|
+
defaultValues,
|
|
55
|
+
variables,
|
|
56
|
+
mutation,
|
|
57
|
+
}: GoogleDriveFoldersUpdateCommandProps<TData, TError, TVariables, TOnMutateResult>) {
|
|
58
|
+
const form = useForm<UpdateGoogleDriveNodeInput>({
|
|
59
|
+
resolver: zodResolver(updateGoogleDriveNodeInputSchema),
|
|
60
|
+
defaultValues,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Form {...form}>
|
|
65
|
+
<CommandFormDialog>
|
|
66
|
+
<CommandFormDialogTrigger label="Wijzigen">
|
|
67
|
+
<FolderPen className="size-4" />
|
|
68
|
+
<CommandLabel />
|
|
69
|
+
</CommandFormDialogTrigger>
|
|
70
|
+
|
|
71
|
+
<CommandFormDialogContent variables={variables} mutation={mutation}>
|
|
72
|
+
<CommandFormDialogHeader>
|
|
73
|
+
<CommandFormDialogTitle>Folder wijzigen</CommandFormDialogTitle>
|
|
74
|
+
</CommandFormDialogHeader>
|
|
75
|
+
|
|
76
|
+
<CommandFormDialogFields>
|
|
77
|
+
<FormField
|
|
78
|
+
control={form.control}
|
|
79
|
+
name="name"
|
|
80
|
+
render={({ field }) => (
|
|
81
|
+
<FormItem>
|
|
82
|
+
<FormLabel>Naam</FormLabel>
|
|
83
|
+
<FormControl>
|
|
84
|
+
<Input {...field} value={field.value ?? ""} />
|
|
85
|
+
</FormControl>
|
|
86
|
+
<FormMessage />
|
|
87
|
+
</FormItem>
|
|
88
|
+
)}
|
|
89
|
+
/>
|
|
90
|
+
</CommandFormDialogFields>
|
|
91
|
+
|
|
92
|
+
<CommandFormDialogFooter>
|
|
93
|
+
<CommandFormDialogCancel>Annuleren</CommandFormDialogCancel>
|
|
94
|
+
<CommandFormDialogSubmit>Opslaan</CommandFormDialogSubmit>
|
|
95
|
+
</CommandFormDialogFooter>
|
|
96
|
+
</CommandFormDialogContent>
|
|
97
|
+
</CommandFormDialog>
|
|
98
|
+
</Form>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
DriveHeader,
|
|
5
|
+
DriveHeaderBreadcrumbs,
|
|
6
|
+
DriveHeaderTools,
|
|
7
|
+
} from "@/components/navigation/header.client";
|
|
8
|
+
import {
|
|
9
|
+
DriveToolbar,
|
|
10
|
+
DriveToolbarBreadcrumbs,
|
|
11
|
+
DriveToolbarTools,
|
|
12
|
+
} from "@/components/navigation/toolbar.client";
|
|
13
|
+
import { DriveViewSwitcher } from "@/components/navigation/view-switcher.client";
|
|
14
|
+
|
|
15
|
+
export const GoogleDriveHeader = DriveHeader;
|
|
16
|
+
export const GoogleDriveHeaderBreadcrumbs = DriveHeaderBreadcrumbs;
|
|
17
|
+
export const GoogleDriveHeaderTools = DriveHeaderTools;
|
|
18
|
+
export const GoogleDriveToolbar = DriveToolbar;
|
|
19
|
+
export const GoogleDriveToolbarBreadcrumbs = DriveToolbarBreadcrumbs;
|
|
20
|
+
export const GoogleDriveToolbarTools = DriveToolbarTools;
|
|
21
|
+
export const GoogleDriveViewSwitcher = DriveViewSwitcher;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Allowed } from "@tulip-systems/core/auth/client";
|
|
4
|
+
import { createContext, type PropsWithChildren, use } from "react";
|
|
5
|
+
import type { DriveContextValue } from "@/components/context.client";
|
|
6
|
+
import { DriveDragDropProvider } from "@/components/dnd.client";
|
|
7
|
+
import {
|
|
8
|
+
type DriveSelectionContextValue,
|
|
9
|
+
DriveSelectionProvider,
|
|
10
|
+
} from "@/components/selection.client";
|
|
11
|
+
import { DriveViewProvider, type DriveViewProviderProps } from "@/components/view.client";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* GoogleDriveContextValue
|
|
15
|
+
*/
|
|
16
|
+
export type GoogleDriveContextValue = DriveContextValue;
|
|
17
|
+
|
|
18
|
+
export const GoogleDriveContext = createContext({} as GoogleDriveContextValue);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* useDriveContext
|
|
22
|
+
*/
|
|
23
|
+
export function useGoogleDriveContext() {
|
|
24
|
+
const context = use(GoogleDriveContext);
|
|
25
|
+
if (!context) throw new Error("DriveContext not found!");
|
|
26
|
+
return context;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* DriveContextProvider
|
|
31
|
+
*/
|
|
32
|
+
type GoogleDriveProviderProps = PropsWithChildren<
|
|
33
|
+
GoogleDriveContextValue &
|
|
34
|
+
Partial<DriveSelectionContextValue> &
|
|
35
|
+
Pick<DriveViewProviderProps, "initialView">
|
|
36
|
+
>;
|
|
37
|
+
|
|
38
|
+
export function GoogleDriveProvider({
|
|
39
|
+
initialView = "grid",
|
|
40
|
+
namespace,
|
|
41
|
+
permission,
|
|
42
|
+
meta,
|
|
43
|
+
selection,
|
|
44
|
+
selectionConditions,
|
|
45
|
+
children,
|
|
46
|
+
}: GoogleDriveProviderProps) {
|
|
47
|
+
return (
|
|
48
|
+
<Allowed permission={permission}>
|
|
49
|
+
<DriveSelectionProvider selection={selection} selectionConditions={selectionConditions}>
|
|
50
|
+
<DriveViewProvider initialView={initialView}>
|
|
51
|
+
<DriveDragDropProvider>
|
|
52
|
+
<GoogleDriveContext value={{ namespace, permission, meta }}>
|
|
53
|
+
{children}
|
|
54
|
+
</GoogleDriveContext>
|
|
55
|
+
</DriveDragDropProvider>
|
|
56
|
+
</DriveViewProvider>
|
|
57
|
+
</DriveSelectionProvider>
|
|
58
|
+
</Allowed>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { VisibilityState } from "@tanstack/react-table";
|
|
4
|
+
import type { CommandDef } from "@tulip-systems/core/commands";
|
|
5
|
+
import { FloatingCommandMenu } from "@tulip-systems/core/commands/client";
|
|
6
|
+
import { type TableColumnDef, TableLayout, TableSkeleton } from "@tulip-systems/core/data-tables";
|
|
7
|
+
import {
|
|
8
|
+
createTableConfig,
|
|
9
|
+
DataTable,
|
|
10
|
+
type InfiniteStrategyMeta,
|
|
11
|
+
TableConfigProvider,
|
|
12
|
+
type useInfiniteStrategy,
|
|
13
|
+
useTableConfigContext,
|
|
14
|
+
} from "@tulip-systems/core/data-tables/client";
|
|
15
|
+
import { type ComponentProps, useMemo } from "react";
|
|
16
|
+
import {
|
|
17
|
+
DriveGrid,
|
|
18
|
+
DriveGridBottombar,
|
|
19
|
+
DriveGridEmpty,
|
|
20
|
+
DriveGridLoading,
|
|
21
|
+
} from "@/components/grid.client";
|
|
22
|
+
import { DriveGridCard, DriveGridCardSkeleton } from "@/components/grid-card.client";
|
|
23
|
+
import { useDriveSelectionContext } from "@/components/selection.client";
|
|
24
|
+
import { useDriveViewContext } from "@/components/view.client";
|
|
25
|
+
import { googleDriveColumns } from "../config/columns-data";
|
|
26
|
+
import type { GoogleDriveNode } from "../lib/validators";
|
|
27
|
+
import { useGoogleDriveContext } from "./provider.client";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* GoogleDriveContent
|
|
31
|
+
*/
|
|
32
|
+
type GoogleDriveViewProviderProps<TData extends GoogleDriveNode = GoogleDriveNode> =
|
|
33
|
+
ComponentProps<"div"> & {
|
|
34
|
+
queryData: TData[];
|
|
35
|
+
columns?: TableColumnDef<TData>[];
|
|
36
|
+
strategy: ReturnType<typeof useInfiniteStrategy>;
|
|
37
|
+
commands?: CommandDef<TData>[];
|
|
38
|
+
columnVisibility?: VisibilityState;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function GoogleDriveViewProvider<TData extends GoogleDriveNode = GoogleDriveNode>({
|
|
42
|
+
queryData,
|
|
43
|
+
columns = googleDriveColumns as TableColumnDef<TData>[],
|
|
44
|
+
strategy,
|
|
45
|
+
commands,
|
|
46
|
+
columnVisibility,
|
|
47
|
+
children,
|
|
48
|
+
...props
|
|
49
|
+
}: GoogleDriveViewProviderProps<TData>) {
|
|
50
|
+
const { meta } = useGoogleDriveContext();
|
|
51
|
+
const { selection } = useDriveSelectionContext();
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Table
|
|
55
|
+
*/
|
|
56
|
+
const config = createTableConfig<TData>({
|
|
57
|
+
queryData,
|
|
58
|
+
columns,
|
|
59
|
+
strategy,
|
|
60
|
+
commands,
|
|
61
|
+
meta,
|
|
62
|
+
columnVisibility,
|
|
63
|
+
selection,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<TableConfigProvider config={config}>
|
|
68
|
+
<TableLayout {...props}>{children}</TableLayout>
|
|
69
|
+
</TableConfigProvider>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* GoogleDriveView
|
|
75
|
+
*/
|
|
76
|
+
export function GoogleDriveView() {
|
|
77
|
+
const { view } = useDriveViewContext();
|
|
78
|
+
|
|
79
|
+
if (view === "grid") {
|
|
80
|
+
return <GoogleDriveGrid />;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (view === "list") {
|
|
84
|
+
return <GoogleDriveList />;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* GoogleDriveGrid
|
|
92
|
+
*/
|
|
93
|
+
function GoogleDriveGrid(props: ComponentProps<"div">) {
|
|
94
|
+
const { queryData, strategy, commands, selection, meta } =
|
|
95
|
+
useTableConfigContext<GoogleDriveNode>();
|
|
96
|
+
const { rowCount, paginationState } = strategy;
|
|
97
|
+
const { isFetching, isFetchingNextPage, fetchNextPage } = strategy.meta as InfiniteStrategyMeta;
|
|
98
|
+
|
|
99
|
+
const hasNextPage = rowCount == null ? false : queryData.length < rowCount;
|
|
100
|
+
|
|
101
|
+
const selectedData = useMemo(
|
|
102
|
+
() => queryData.filter((node) => selection?.rowSelection?.[node.id] === true),
|
|
103
|
+
[queryData, selection?.rowSelection],
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<DriveGrid {...props}>
|
|
108
|
+
{queryData.length > 0 ? (
|
|
109
|
+
queryData.map((node) => <DriveGridCard key={node.id} node={node} commands={commands} />)
|
|
110
|
+
) : (
|
|
111
|
+
<DriveGridEmpty title="Geen resultaten gevonden" />
|
|
112
|
+
)}
|
|
113
|
+
|
|
114
|
+
{isFetchingNextPage &&
|
|
115
|
+
Array.from({ length: paginationState?.pageSize ?? 0 }).map((_, index) => (
|
|
116
|
+
<DriveGridCardSkeleton key={index} />
|
|
117
|
+
))}
|
|
118
|
+
|
|
119
|
+
<DriveGridBottombar
|
|
120
|
+
hasNextPage={hasNextPage}
|
|
121
|
+
fetchNextPage={fetchNextPage}
|
|
122
|
+
isFetching={isFetching}
|
|
123
|
+
isFetchingNextPage={isFetchingNextPage}
|
|
124
|
+
/>
|
|
125
|
+
|
|
126
|
+
{commands && commands.length > 0 && (
|
|
127
|
+
<FloatingCommandMenu
|
|
128
|
+
data={selectedData as never}
|
|
129
|
+
commands={commands as never}
|
|
130
|
+
meta={meta}
|
|
131
|
+
state={selectedData.length > 0 ? "open" : "closed"}
|
|
132
|
+
onSuccess={() => selection?.setRowSelection?.({})}
|
|
133
|
+
/>
|
|
134
|
+
)}
|
|
135
|
+
</DriveGrid>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* GoogleDriveList
|
|
141
|
+
*/
|
|
142
|
+
function GoogleDriveList(props: ComponentProps<typeof DataTable>) {
|
|
143
|
+
return <DataTable {...props} />;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* GoogleDriveViewLoading
|
|
148
|
+
*/
|
|
149
|
+
export function GoogleDriveViewLoading({ ...props }: ComponentProps<"div">) {
|
|
150
|
+
const { view } = useDriveViewContext();
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div {...props}>
|
|
154
|
+
{view === "grid" && <DriveGridLoading {...props} />}
|
|
155
|
+
{view === "list" && <TableSkeleton {...props} />}
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
}
|