Skip to content

Commit

Permalink
configure: wip column dnd + bulk export
Browse files Browse the repository at this point in the history
  • Loading branch information
oscartbeaumont committed Jul 25, 2024
1 parent 76c9253 commit 656b4d6
Show file tree
Hide file tree
Showing 5 changed files with 378 additions and 34 deletions.
35 changes: 28 additions & 7 deletions apps/configure/src/components/search/FilterBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
Expand All @@ -13,7 +14,7 @@ import {
TooltipTrigger,
} from "@mattrax/ui";
import { useNavigate } from "@solidjs/router";
import { createMutation, createQuery } from "@tanstack/solid-query";
import { createMutation } from "@tanstack/solid-query";
import clsx from "clsx";
import {
type Accessor,
Expand Down Expand Up @@ -127,13 +128,33 @@ function AppliedFilters(props: {
<FilterText>Type</FilterText>
</StaticSection>

<InteractiveSection class="border-l px-2">
is
</InteractiveSection>
<DropdownMenu>
<DropdownMenuTrigger
as={InteractiveSection}
class="border-l px-2 hover:bg-gray-200"
>
is
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>is</DropdownMenuItem>
<DropdownMenuItem>is not</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

<InteractiveSection class="gap-1 border-l border-app-darkerBox/70 py-0.5 pl-1.5 pr-2 text-sm">
{filter.value}
</InteractiveSection>
<DropdownMenu>
<DropdownMenuTrigger
as={InteractiveSection}
class="gap-1 border-l border-gray-800/70 py-0.5 pl-1.5 pr-2 text-sm hover:bg-gray-200"
>
{filter.value}
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuCheckboxItem>
{filter.value}
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem>b</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>

<RemoveFilter
onClick={() =>
Expand Down
92 changes: 90 additions & 2 deletions apps/configure/src/components/search/configuration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const typeColumn = (type: string) =>
// Badge width + padding
size: 66.82 + 2 * 16,
render: () => <Badge variant="secondary">{type.toUpperCase()}</Badge>,
raw: () => type.toUpperCase(),
}) as const;

export const entities = {
Expand All @@ -27,10 +28,12 @@ export const entities = {
{user.name}
</a>
),
raw: (user) => user.name,
},
email: {
header: "Email",
render: (user) => <p>{user.upn}</p>,
raw: (user) => user.upn,
},
// column.accessor("provider.variant", {
// header: "Provider",
Expand All @@ -56,8 +59,22 @@ export const entities = {
// TODO: Link to OAuth provider
// TODO: Actions
},
// TODO: Define filters
// TODO: Define bulk actions like delete
actions: {
delete: {
title: "Delete",
variant: "destructive",
apply: async (data) => alert("TODO: Bulk delete"),
},
// TODO: Assign to group
},
// filters: {
// device: {
// type: "enum",
// target: "device",
// value: "Device",
// },
// }
// },
}),
devices: defineEntity({
load: async () => await (await db).getAll("devices"),
Expand All @@ -73,16 +90,60 @@ export const entities = {
{device.name}
</a>
),
raw: (device) => device.name,
},
model: {
header: "Model",
render: (device) => <p>{device.model}</p>,
raw: (device) => device.model,

Check failure on line 98 in apps/configure/src/components/search/configuration.tsx

View workflow job for this annotation

GitHub Actions / Typecheck

Type 'string | undefined' is not assignable to type 'string'.
},
manufacturer: {
header: "Manufacturer",
render: (device) => <p>{device.manufacturer}</p>,
raw: (device) => device.manufacturer,

Check failure on line 103 in apps/configure/src/components/search/configuration.tsx

View workflow job for this annotation

GitHub Actions / Typecheck

Type 'string | undefined' is not assignable to type 'string'.
},
},
actions: {
sync: {
title: "Sync",
apply: async (data) => alert("TODO: Sync"),
},
// TODO: Make these devices actions only available on supported OS's
diagnostics: {
title: "Collect diagnostics",
apply: async (data) => alert("TODO: Collect diagnostics"),
},
rename: {
title: "Rename",
apply: async (data) => alert("TODO: Rename"),
},
delete: {
title: "Delete",
variant: "destructive",
apply: async (data) => alert("TODO: Bulk delete"),
},
retire: {
title: "Retire",
variant: "destructive",
apply: async (data) => alert("TODO: Retire device"),
},
wipe: {
title: "Wipe",
variant: "destructive",
apply: async (data) => alert("TODO: Wipe"),
},
reset: {
title: "Autopilot reset",
variant: "destructive",
apply: async (data) => alert("TODO: Autopilot reset"),
},
restart: {
title: "Restart",
variant: "destructive",
apply: async (data) => alert("TODO: Restart"),
},
// TODO: Maybe "Send notification"???
},
}),
groups: defineEntity({
load: async () => await (await db).getAll("groups"),
Expand All @@ -98,10 +159,19 @@ export const entities = {
{group.name}
</a>
),
raw: (group) => group.name,
},
description: {
header: "Description",
render: (group) => <p>{group.description}</p>,
raw: (group) => group.description,

Check failure on line 167 in apps/configure/src/components/search/configuration.tsx

View workflow job for this annotation

GitHub Actions / Typecheck

Type 'string | undefined' is not assignable to type 'string'.
},
},
actions: {
delete: {
title: "Delete",
variant: "destructive",
apply: async (data) => alert("TODO: Bulk delete"),
},
},
}),
Expand All @@ -119,10 +189,19 @@ export const entities = {
{policy.name}
</a>
),
raw: (policy) => policy.name,
},
description: {
header: "Description",
render: (group) => <p>{group.description}</p>,
raw: (group) => group.description,

Check failure on line 197 in apps/configure/src/components/search/configuration.tsx

View workflow job for this annotation

GitHub Actions / Typecheck

Type 'string | undefined' is not assignable to type 'string'.
},
},
actions: {
delete: {
title: "Delete",
variant: "destructive",
apply: async (data) => alert("TODO: Bulk delete"),
},
},
}),
Expand All @@ -140,10 +219,19 @@ export const entities = {
{app.name}
</a>
),
raw: (app) => app.name,
},
description: {
header: "Description",
render: (group) => <p>{group.description}</p>,
raw: (group) => group.description,
},
},
actions: {
delete: {
title: "Delete",
variant: "destructive",
apply: async (data) => alert("TODO: Bulk delete"),
},
},
}),
Expand Down
20 changes: 20 additions & 0 deletions apps/configure/src/components/search/filters.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ButtonProps } from "@mattrax/ui";
import type { JSX } from "solid-js";

// TODO: Rest of the possibilities + clean this up
Expand All @@ -22,6 +23,8 @@ export function defineEntity<T>(entity: Entity<T>) {
export type Entity<T> = {
load: () => Promise<T[]>;
columns: ColumnDefinitions<T>;
filters?: never[];
actions: ActionDefinitions<T>;
};

export type ColumnDefinitions<T> = Record<
Expand All @@ -36,5 +39,22 @@ export type ColumnDefinitions<T> = Record<
size?: "auto" | number;
// The content to render in the individual table cell.
render: (data: T) => JSX.Element;
// Render to raw data. Used for csv and json exporting.
raw: (data: T) => string;
}
>;

export type ActionDefinitions<T> = Record<
// Used to uniquely identify the semantic meaning of the column.
// These will be merged across entities using the first `title` that is discovered.
// The apply function will still be called on the specific entity to ensure links and the like remain correct.
string,
{
// The title of the action.
title: string;
// Button variant
variant?: ButtonProps["variant"];
// The function to run when the action is applied.
apply: (data: T[]) => Promise<void>;
}
>;
Loading

0 comments on commit 656b4d6

Please sign in to comment.