init tags

This commit is contained in:
kv
2024-01-16 02:43:59 -08:00
parent 597e466d84
commit 453600a70c
5 changed files with 148 additions and 0 deletions
+6
View File
@@ -23,9 +23,11 @@ import {
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "@ui/card";
import { Logout, ResourceTypeDropdown, ResourcesDropdown } from "./util";
import { HeaderUpdates } from "./updates/header";
import { ManageTags, ResourceTags } from "./tags";
export const Layout = () => {
const type = useResourceParamType();
@@ -169,6 +171,10 @@ export const ResourceCard = ({
<CardContent className="text-sm text-muted-foreground">
<Components.Info id={id} />
</CardContent>
<CardFooter className="flex items-center justify-end gap-2">
<ResourceTags target={{ type, id }} />
<ManageTags target={{ type, id }} />
</CardFooter>
</Card>
</Link>
);
+98
View File
@@ -0,0 +1,98 @@
import { useRead, useWrite } from "@lib/hooks";
import { Types } from "@monitor/client";
import { Badge } from "@ui/badge";
import { Checkbox } from "@ui/checkbox";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from "@ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@ui/popover";
import { Pen } from "lucide-react";
import { useEffect, useState } from "react";
type TargetExcludingSystem = Exclude<Types.ResourceTarget, { type: "System" }>;
export const ResourceTags = ({ target }: { target: TargetExcludingSystem }) => {
const { type, id } = target;
const resource = useRead(`List${type}s`, {}).data?.find((d) => d.id === id);
const tags = useRead("ListTags", {}).data;
console.log(resource);
return (
<>
{resource?.tags.map((id) => (
<Badge>{tags?.find((t) => t._id?.$oid === id)?.name}</Badge>
))}
</>
);
};
export function ManageTags({ target }: { target: TargetExcludingSystem }) {
const resource = useRead(`List${target.type}s`, {}).data?.find(
(d) => d.id === target.id
);
const [open, setOpen] = useState(false);
const [input, setInput] = useState("");
const [tags, setTags] = useState(resource?.tags ?? []);
const all_tags = useRead("ListTags", {}).data;
const { mutate: update } = useWrite("UpdateTagsOnResource");
useEffect(() => {
update({ target, tags });
}, [target, tags, update]);
const { mutateAsync: create } = useWrite("CreateTag");
const update_tags = (tag: Types.CustomTag) => {
const included = tags.some((id) => id === tag._id?.$oid);
if (included) return setTags((t) => t.filter((id) => id !== tag._id?.$oid));
else return setTags((t) => [...t, tag._id?.$oid as string]);
};
if (!resource) return null;
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger disabled={!tags}>
<Badge className="flex gap-2">
Edit Tags <Pen className="w-3" />
</Badge>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandInput
placeholder="Search Tags"
className="h-9"
value={input}
onValueChange={setInput}
/>
<CommandEmpty
onClick={async () =>
!!input && update_tags(await create({ name: input }))
}
>
Create Tag
</CommandEmpty>
<CommandGroup>
{all_tags?.map((tag) => (
<CommandItem
key={tag._id?.$oid}
value={tag._id?.$oid}
onSelect={() => update_tags(tag)}
className="flex items-center justify-between"
>
{tag.name}
<Checkbox checked={tags.some((id) => id === tag._id?.$oid)} />
</CommandItem>
))}
</CommandGroup>
</Command>
</PopoverContent>
</Popover>
);
}
+5
View File
@@ -1,6 +1,7 @@
import { Page } from "@components/layouts";
import { ResourcePermissions } from "@components/permissions";
import { ResourceComponents } from "@components/resources";
import { ManageTags, ResourceTags } from "@components/tags";
import { ResourceUpdates } from "@components/updates/resource";
import { usePushRecentlyViewed, useResourceParamType } from "@lib/hooks";
import { useParams } from "react-router-dom";
@@ -26,6 +27,10 @@ export const Resource = () => {
<div className="flex gap-8">
<Components.Info id={id} />
</div>
<div className="flex gap-8">
<ResourceTags target={{ id, type }} />
<ManageTags target={{ id, type }} />
</div>
</div>
}
actions={<Components.Actions id={id} />}