forked from github-starred/komodo
init tags
This commit is contained in:
@@ -11,10 +11,12 @@
|
||||
"regen-client": "cd ../client/ts && yarn build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-progress": "^1.0.3",
|
||||
"@radix-ui/react-select": "^2.0.0",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
|
||||
@@ -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
frontend/src/components/tags/index.tsx
Normal file
98
frontend/src/components/tags/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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} />}
|
||||
|
||||
@@ -548,6 +548,21 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
|
||||
"@radix-ui/react-checkbox@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz#98f22c38d5010dd6df4c5744cac74087e3275f4b"
|
||||
integrity sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.1"
|
||||
"@radix-ui/react-compose-refs" "1.0.1"
|
||||
"@radix-ui/react-context" "1.0.1"
|
||||
"@radix-ui/react-presence" "1.0.1"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.1"
|
||||
"@radix-ui/react-use-previous" "1.0.1"
|
||||
"@radix-ui/react-use-size" "1.0.1"
|
||||
|
||||
"@radix-ui/react-collection@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159"
|
||||
@@ -762,6 +777,28 @@
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "2.5.5"
|
||||
|
||||
"@radix-ui/react-popover@^1.0.7":
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.0.7.tgz#23eb7e3327330cb75ec7b4092d685398c1654e3c"
|
||||
integrity sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.1"
|
||||
"@radix-ui/react-compose-refs" "1.0.1"
|
||||
"@radix-ui/react-context" "1.0.1"
|
||||
"@radix-ui/react-dismissable-layer" "1.0.5"
|
||||
"@radix-ui/react-focus-guards" "1.0.1"
|
||||
"@radix-ui/react-focus-scope" "1.0.4"
|
||||
"@radix-ui/react-id" "1.0.1"
|
||||
"@radix-ui/react-popper" "1.1.3"
|
||||
"@radix-ui/react-portal" "1.0.4"
|
||||
"@radix-ui/react-presence" "1.0.1"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
"@radix-ui/react-slot" "1.0.2"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.1"
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "2.5.5"
|
||||
|
||||
"@radix-ui/react-popper@1.1.3":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42"
|
||||
|
||||
Reference in New Issue
Block a user