Skip to content

Commit

Permalink
Vault
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed Nov 29, 2023
1 parent 6602b85 commit 008ba92
Show file tree
Hide file tree
Showing 14 changed files with 412 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
import { Breadcrumbs } from "@/components/breadcrumbs";
import { Table } from "@/components/tables/vault";
import { Button } from "@midday/ui/button";
import { Icons } from "@midday/ui/icons";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Vault | Midday",
};

export default function Vault({ params }) {
const disableActions = ["transactions", "inbox", "exports"].includes(
params.folders?.slice(-1)?.at(0)
);

return (
<div>
<Breadcrumbs folders={params?.folders} />
<div className="flex justify-between items-center mt-6 h-[32px]">
<Breadcrumbs folders={params?.folders} />

{!disableActions && (
<div className="flex space-x-2">
<Button variant="outline" className="w-[32px] h-[32px]" size="icon">
<Icons.FileUpload />
</Button>
<Button variant="outline" className="w-[32px] h-[32px]" size="icon">
<Icons.CreateNewFolder />
</Button>
</div>
)}
</div>
<Table path={params?.folders?.join("/")} />
</div>
);
Expand Down
32 changes: 30 additions & 2 deletions apps/dashboard/src/components/breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
export function Breadcrumbs({ folders }) {
return folders?.map((folder) => <span key={folder}>{folder}</span>);
"use client";

import { useI18n } from "@/locales/client";
import { Icons } from "@midday/ui/icons";
import Link from "next/link";
import { translatedFolderName } from "./tables/vault/data-table-row";

export function Breadcrumbs({ folders = [] }) {
const t = useI18n();

const allFolders = ["all", ...folders];

const links = allFolders?.map((folder, index) => {
const isLast = folders.length === index;
const href = folder === "all" ? "/vault" : `/vault/${folder}`;

return (
<div className="flex items-center" key={folder}>
<Link href={href} className="max-w-[100px] truncate">
<span key={folder}>{translatedFolderName(t, folder)}</span>
</Link>

{folders.length > 0 && !isLast && (
<Icons.ArrowRight className="text-[#878787] mx-1" size={16} />
)}
</div>
);
});

return <div className="flex">{links}</div>;
}
8 changes: 6 additions & 2 deletions apps/dashboard/src/components/file-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Icons } from "@midday/ui/icons";

export function FileIcon({ mimetype, name }) {
export function FileIcon({ mimetype, name, isFolder }) {
if (name === "exports") {
return <Icons.DriveFileMove size={16} className="text-[#878787]" />;
}

if (name === "inbox") {
return <Icons.FolderOpen size={16} className="text-[#878787]" />;
return <Icons.FolderSpecial size={16} className="text-[#878787]" />;
}

if (name === "transactions") {
Expand All @@ -17,6 +17,10 @@ export function FileIcon({ mimetype, name }) {
return <Icons.BrokenImage size={16} className="text-[#878787]" />;
}

if (isFolder) {
return <Icons.Folder size={16} className="text-[#878787]" />;
}

switch (mimetype) {
case "application/pdf":
return <Icons.Pdf size={16} className="text-[#878787]" />;
Expand Down
94 changes: 73 additions & 21 deletions apps/dashboard/src/components/tables/vault/data-table-row.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,89 @@
"use client";

import { FileIcon } from "@/components/file-icon";
import { useI18n } from "@/locales/client";
import { formatSize } from "@/utils/format";
import { Icons } from "@midday/ui/icons";
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuTrigger,
} from "@midday/ui/context-menu";
import { TableCell, TableRow } from "@midday/ui/table";
import { format } from "date-fns";
import { usePathname, useRouter } from "next/navigation";

export const translatedFolderName = (t: any, folder: string) => {
switch (folder) {
case "all":
return t("folders.all");
case "inbox":
return t("folders.inbox");
case "transactions":
return t("folders.transactions");
case "exports":
return t("folders.exports");

default:
return folder;
}
};

export function DataTableRow({ data }) {
const t = useI18n();
const router = useRouter();
const pathname = usePathname();

const handleNavigate = () => router.push(`${pathname}/${data.name}`);
const handleNavigate = () => {
if (data.isFolder) {
router.push(`${pathname}/${data.name}`);
}
};

return (
<TableRow className="h-[45px]" onClick={handleNavigate}>
<TableCell>
<div className="flex items-center space-x-2">
<FileIcon mimetype={data?.metadata?.mimetype} name={data.name} />
<span>{data.name}</span>
{data?.metadata?.size && (
<span className="text-[#878787]">
{formatSize(data.metadata.size)}
</span>
)}
</div>
</TableCell>
<TableCell>
{data?.created_at && format(new Date(data.created_at), "MMM d, yyyy")}
</TableCell>
<TableCell>
<Icons.MoreHoriz size={16} />
</TableCell>
</TableRow>
<ContextMenu>
<ContextMenuTrigger asChild>
<TableRow className="h-[45px] cursor-default" onClick={handleNavigate}>
<TableCell>
<div className="flex items-center space-x-2">
<FileIcon
mimetype={data?.metadata?.mimetype}
name={data.name}
isFolder={data.isFolder}
/>
<span>{translatedFolderName(t, data.name)}</span>
{data?.metadata?.size && (
<span className="text-[#878787]">
{formatSize(data.metadata.size)}
</span>
)}
</div>
</TableCell>
<TableCell>
{data?.created_at ? format(new Date(data.created_at), "Pp") : "-"}
</TableCell>
<TableCell>
{data?.updated_at ? format(new Date(data.updated_at), "Pp") : "-"}
</TableCell>
</TableRow>
</ContextMenuTrigger>

<ContextMenuContent>
<ContextMenuSub>
<ContextMenuSubTrigger>Get URL</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Expire in 1 week</ContextMenuItem>
<ContextMenuItem>Expire in 1 month</ContextMenuItem>
<ContextMenuItem>Expire in 1 year</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuItem>Rename</ContextMenuItem>
<ContextMenuItem>Download</ContextMenuItem>
<ContextMenuItem>Delete</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);
}
4 changes: 2 additions & 2 deletions apps/dashboard/src/components/tables/vault/data-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export function DataTable({ data }) {
<TableHeader>
<TableRow>
<TableHead className="w-[60%]">Name</TableHead>
<TableHead className="w-full">Uploaded</TableHead>
<TableHead className="text-right w-full">Actions</TableHead>
<TableHead className="w-[15%]">Created at</TableHead>
<TableHead className="w-full">Last modified at</TableHead>
</TableRow>
</TableHeader>
<TableBody>
Expand Down
32 changes: 32 additions & 0 deletions apps/dashboard/src/components/tables/vault/empty-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
type Props = {
type: string;
};

export function EmptyTable({ type }: Props) {
switch (type) {
case "inbox":
return (
<div className="border border-t-0 p-4 h-[calc(100vh-240px)] flex justify-center items-center">
<div className="items-center flex flex-col text-center">
<h2 className="mb-2">This is your inbox</h2>
<p className="text-sm text-[#878787]">
Everything that will be sent to your <br />
Midday email will end up here.
</p>
</div>
</div>
);

default:
return (
<div className="border border-t-0 p-4 h-[calc(100vh-240px)] flex justify-center items-center">
<div className="items-center flex flex-col text-center">
<h2 className="mb-2">Drop your files here</h2>
<p className="text-sm text-[#878787]">
Or upload them via the <br /> "Upload file" button above
</p>
</div>
</div>
);
}
}
4 changes: 3 additions & 1 deletion apps/dashboard/src/components/tables/vault/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { getVault } from "@midday/supabase/cached-queries";
import { DataTable } from "./data-table";
import { EmptyTable } from "./empty-table";

export async function Table({ path }) {
const { data } = await getVault({ path });

return (
<div className="mt-8">
<div className="mt-6">
<DataTable data={data} />
{data.length === 0 && <EmptyTable type={path} />}
</div>
);
}
6 changes: 6 additions & 0 deletions apps/dashboard/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,10 @@ export default {
profit_loss: "Profit/Loss",
income: "Income",
},
folders: {
all: "All",
exports: "Exports",
inbox: "Inbox",
transactions: "Transactions",
},
} as const;
6 changes: 6 additions & 0 deletions apps/dashboard/src/locales/sv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,10 @@ export default {
profit_loss: "Vinst/Förlust",
income: "Inkomst",
},
folders: {
all: "Alla",
exports: "Exporteringar",
inbox: "Inbox",
transactions: "Transaktioner",
},
} as const;
Binary file modified bun.lockb
Binary file not shown.
24 changes: 21 additions & 3 deletions packages/supabase/src/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,10 +475,17 @@ type GetVaultParams = {
path?: string;
};

const defaultFolders = [{ id: "inbox" }, { id: "exports" }];

export async function getVaultQuery(supabase: Client, params: GetVaultParams) {
const { teamId, path } = params;

const defaultFolders = path
? []
: [
{ name: "inbox", isFolder: true },
{ name: "exports", isFolder: true },
{ name: "transactions", isFolder: true },
];

let basePath = teamId;

if (path) {
Expand All @@ -487,7 +494,18 @@ export async function getVaultQuery(supabase: Client, params: GetVaultParams) {

const { data } = await supabase.storage.from("vault").list(basePath);

const filteredData =
data
?.filter((file) => file.name !== ".emptyFolderPlaceholder")
.map((item) => ({ ...item, isFolder: !item.id })) ?? [];

const mergedMap = new Map(
[...defaultFolders, ...filteredData].map((obj) => [obj.name, obj])
);

const mergedArray = Array.from(mergedMap.values());

return {
data: data?.filter((file) => file.name !== ".emptyFolderPlaceholder"),
data: mergedArray,
};
}
2 changes: 2 additions & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"exports": {
"./calendar": "./src/components/calendar.tsx",
"./card": "./src/components/card.tsx",
"./context-menu": "./src/components/context-menu.tsx",
"./alert": "./src/components/alert.tsx",
"./alert-dialog": "./src/components/alert-dialog.tsx",
"./avatar": "./src/components/avatar.tsx",
Expand Down Expand Up @@ -61,6 +62,7 @@
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-context-menu": "^2.1.5",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
Expand Down
Loading

0 comments on commit 008ba92

Please sign in to comment.