-
-
- {data.length === 0 && }
-
+
+
+
+
+
+
+
+ {data.length === 0 && }
+
+
+
);
}
diff --git a/apps/dashboard/src/components/tables/vault/upload-zone.tsx b/apps/dashboard/src/components/tables/vault/upload-zone.tsx
index aceafe3ad2..fe7e2941b4 100644
--- a/apps/dashboard/src/components/tables/vault/upload-zone.tsx
+++ b/apps/dashboard/src/components/tables/vault/upload-zone.tsx
@@ -1,7 +1,7 @@
"use client";
-import { createFolderAction } from "@/actions/create-folder-action";
import { invalidateCacheAction } from "@/actions/invalidate-cache-action";
+import { useVaultContext } from "@/store/vault/hook";
import { resumableUpload } from "@/utils/upload";
import { createClient } from "@midday/supabase/client";
import { getCurrentUserTeamQuery } from "@midday/supabase/queries";
@@ -13,7 +13,6 @@ import {
} from "@midday/ui/context-menu";
import { useToast } from "@midday/ui/use-toast";
import { cn } from "@midday/ui/utils";
-import { useAction } from "next-safe-action/hook";
import { useParams } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { useDropzone } from "react-dropzone";
@@ -26,8 +25,12 @@ export function UploadZone({ children }) {
const uploadProgress = useRef([]);
const params = useParams();
const folders = params?.folders ?? [];
- const folderPath = folders.join("/");
const { toast, dismiss, update } = useToast();
+ const { createFolder } = useVaultContext((s) => s);
+
+ const isDefaultFolder = ["inbox", "exports", "transactions"].includes(
+ folders.at(0)
+ );
useEffect(() => {
if (!toastId && showProgress) {
@@ -48,21 +51,6 @@ export function UploadZone({ children }) {
}
}, [showProgress, progress, toastId]);
- const isDefaultFolder = ["inbox", "exports", "transactions"].includes(
- folders.at(0)
- );
-
- const createFolder = useAction(createFolderAction, {
- onError: () => {
- toast({
- duration: 2500,
- variant: "error",
- title:
- "The folder already exists in the current directory. Please use a different name.",
- });
- },
- });
-
const onDrop = async (files) => {
// Set default progress
uploadProgress.current = files.map(() => 0);
@@ -149,25 +137,7 @@ export function UploadZone({ children }) {
{!isDefaultFolder && (
-
- createFolder.execute({
- path: folderPath,
- name: "Untitled folder",
- })
- }
- >
- Upload file
-
-
-
- createFolder.execute({
- path: folderPath,
- name: "Untitled folder",
- })
- }
- >
+
Create folder
diff --git a/apps/dashboard/src/store/vault/hook.ts b/apps/dashboard/src/store/vault/hook.ts
new file mode 100644
index 0000000000..b0fd06a4ba
--- /dev/null
+++ b/apps/dashboard/src/store/vault/hook.ts
@@ -0,0 +1,13 @@
+import { useContext } from "react";
+import { useStore } from "zustand";
+import { VaultContext, VaultState } from "./store";
+
+export function useVaultContext
(selector: (state: VaultState) => T): T {
+ const store = useContext(VaultContext);
+
+ if (!store) {
+ throw new Error("Missing VaultContext.Provider in the tree");
+ }
+
+ return useStore(store, selector);
+}
diff --git a/apps/dashboard/src/store/vault/provider.tsx b/apps/dashboard/src/store/vault/provider.tsx
new file mode 100644
index 0000000000..3381cb6eb8
--- /dev/null
+++ b/apps/dashboard/src/store/vault/provider.tsx
@@ -0,0 +1,13 @@
+"use client";
+
+import { VaultContext, VaultProps, createVaultStore } from "./store";
+
+type VaultProviderProps = React.PropsWithChildren;
+
+export function VaultProvider({ children, ...props }: VaultProviderProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/apps/dashboard/src/store/vault/store.ts b/apps/dashboard/src/store/vault/store.ts
new file mode 100644
index 0000000000..862c487ffd
--- /dev/null
+++ b/apps/dashboard/src/store/vault/store.ts
@@ -0,0 +1,64 @@
+import { createContext } from "react";
+import { createStore } from "zustand";
+
+type Item = {
+ id?: string;
+ name: string;
+ isFolder?: boolean;
+ isEditing?: boolean;
+};
+
+export interface VaultProps {
+ data: Item[];
+}
+
+export interface VaultState extends VaultProps {
+ addItems: (items: Item[]) => void;
+ deleteItem: (id: string) => void;
+ createFolder: (item: Item) => void;
+ updateItem: (id: string, payload: Item) => void;
+}
+
+export type VaultStore = ReturnType;
+export const VaultContext = createContext(null);
+
+export const createVaultStore = (initProps?: Partial) => {
+ const DEFAULT_PROPS: VaultProps = {
+ data: [],
+ };
+
+ return createStore()((set) => ({
+ ...DEFAULT_PROPS,
+ ...initProps,
+
+ addItems: (items) =>
+ set((state) => ({
+ data: [...state.data, ...items],
+ })),
+
+ deleteItem: (id) =>
+ set((state) => ({
+ data: state.data.filter((item) =>
+ item.isFolder ? item.name !== id : item.id !== id
+ ),
+ })),
+
+ createFolder: (item) =>
+ set((state) => ({
+ data: [
+ ...state.data,
+ {
+ ...item,
+ isEditing: true,
+ isFolder: true,
+ id: item.name,
+ },
+ ],
+ })),
+
+ updateItem: (id, payload) =>
+ set((state) => ({
+ data: state.data.map((d) => (d.id === id ? payload : d)),
+ })),
+ }));
+};
diff --git a/bun.lockb b/bun.lockb
index 1d477e29ad..a4020ff576 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/packages/jobs/package.json b/packages/jobs/package.json
index 2d829ba571..c1dc3ffa09 100644
--- a/packages/jobs/package.json
+++ b/packages/jobs/package.json
@@ -10,9 +10,9 @@
"check:types": "tsc --noEmit"
},
"dependencies": {
- "@trigger.dev/react": "^2.3.5",
- "@trigger.dev/sdk": "^2.3.5",
- "@trigger.dev/supabase": "^2.3.5"
+ "@trigger.dev/react": "^2.3.6",
+ "@trigger.dev/sdk": "^2.3.6",
+ "@trigger.dev/supabase": "^2.3.6"
}
}
\ No newline at end of file
diff --git a/packages/supabase/src/queries/cached-queries.ts b/packages/supabase/src/queries/cached-queries.ts
index 2f06e1001f..6658e91384 100644
--- a/packages/supabase/src/queries/cached-queries.ts
+++ b/packages/supabase/src/queries/cached-queries.ts
@@ -171,6 +171,7 @@ export const getVault = async (params) => {
["vault", teamId],
{
tags: [`vault_${teamId}`],
+ revalidate: 10,
}
)(params);
};
diff --git a/packages/supabase/src/queries/index.ts b/packages/supabase/src/queries/index.ts
index bf9dd671f5..9d8c036cb2 100644
--- a/packages/supabase/src/queries/index.ts
+++ b/packages/supabase/src/queries/index.ts
@@ -500,7 +500,9 @@ export async function getVaultQuery(supabase: Client, params: GetVaultParams) {
basePath = `${basePath}/${path}`;
}
- const { data } = await supabase.storage.from("vault").list(basePath);
+ const { data } = await supabase.storage.from("vault").list(basePath, {
+ sortBy: { column: "name", order: "asc" },
+ });
const filteredData =
data
diff --git a/packages/ui/package.json b/packages/ui/package.json
index ea19ff40e7..656d574121 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -17,7 +17,7 @@
},
"devDependencies": {
"autoprefixer": "^10.4.16",
- "typescript": "^5.3.2"
+ "typescript": "^5.3.3"
},
"exports": {
"./calendar": "./src/components/calendar.tsx",
@@ -59,7 +59,7 @@
"./utils": "./src/utils"
},
"dependencies": {
- "@mui/icons-material": "^5.14.19",
+ "@mui/icons-material": "^5.15.0",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-avatar": "^1.0.4",
@@ -84,7 +84,7 @@
"clsx": "^2.0.0",
"cmdk": "^0.2.0",
"date-fns": "^2.30.0",
- "lucide-react": "^0.294.0",
+ "lucide-react": "^0.295.0",
"react-day-picker": "^8.9.1",
"react-icons": "^4.12.0",
"tailwind-merge": "2.0.0",