mirror of
https://github.com/moghtech/komodo.git
synced 2026-04-28 03:38:55 -05:00
seems to work
This commit is contained in:
@@ -54,9 +54,13 @@ export const PendingOrConfig = ({ id }: { id: string }) => {
|
||||
<Section titleOther={tabsList}>
|
||||
{pending?.hash && pending.message && (
|
||||
<Card>
|
||||
<CardHeader className="flex items-center gap-4 text-muted-foreground">
|
||||
Commit: {pending.hash}: {pending.message}
|
||||
</CardHeader>
|
||||
<div className="flex items-center gap-4 px-8 py-4">
|
||||
<div className="text-muted-foreground">Latest Commit</div>
|
||||
<div className="text-muted-foreground">|</div>
|
||||
<div>{pending.hash}</div>
|
||||
<div className="text-muted-foreground">|</div>
|
||||
<div>{pending.message}</div>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
{pending?.data.type === "Ok" &&
|
||||
@@ -103,25 +107,28 @@ const PendingView = ({
|
||||
<div className="flex gap-4 items-center m-0">
|
||||
{pending.to_create ? (
|
||||
<>
|
||||
|
|
||||
<div className="text-muted-foreground">|</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
To Create: {pending.to_create}
|
||||
<div className="text-muted-foreground">To Create:</div>
|
||||
<div>{pending.to_create}</div>
|
||||
</div>
|
||||
</>
|
||||
) : undefined}
|
||||
{pending.to_update ? (
|
||||
<>
|
||||
|
|
||||
<div className="text-muted-foreground">|</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
To Update: {pending.to_update}
|
||||
<div className="text-muted-foreground">To Update:</div>
|
||||
<div>{pending.to_update}</div>
|
||||
</div>
|
||||
</>
|
||||
) : undefined}
|
||||
{pending.to_delete ? (
|
||||
<>
|
||||
|
|
||||
<div className="text-muted-foreground">|</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
To Delete: {pending.to_delete}
|
||||
<div className="text-muted-foreground">To Delete:</div>
|
||||
<div>{pending.to_delete}</div>
|
||||
</div>
|
||||
</>
|
||||
) : undefined}
|
||||
|
||||
@@ -22,6 +22,21 @@ export const ResourceSyncTable = ({
|
||||
cell: ({ row }) => (
|
||||
<ResourceLink type="ResourceSync" id={row.original.id} />
|
||||
),
|
||||
size: 200,
|
||||
},
|
||||
{
|
||||
accessorKey: "info.repo",
|
||||
header: ({ column }) => (
|
||||
<SortableHeader column={column} title="Repo" />
|
||||
),
|
||||
size: 200,
|
||||
},
|
||||
{
|
||||
accessorKey: "info.branch",
|
||||
header: ({ column }) => (
|
||||
<SortableHeader column={column} title="Branch" />
|
||||
),
|
||||
size: 200,
|
||||
},
|
||||
{
|
||||
accessorKey: "info.state",
|
||||
|
||||
@@ -7,10 +7,7 @@ import {
|
||||
Box,
|
||||
Boxes,
|
||||
FolderTree,
|
||||
Key,
|
||||
Tag,
|
||||
User,
|
||||
Variable,
|
||||
Settings,
|
||||
} from "lucide-react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { ResourceComponents } from "./resources";
|
||||
@@ -18,14 +15,12 @@ import { Separator } from "@ui/separator";
|
||||
import { ReactNode } from "react";
|
||||
import { useAtom } from "jotai";
|
||||
import { homeViewAtom } from "@main";
|
||||
import { useUser } from "@lib/hooks";
|
||||
|
||||
export const Sidebar = () => {
|
||||
const user = useUser().data;
|
||||
const [view, setView] = useAtom(homeViewAtom);
|
||||
return (
|
||||
<Card className="h-fit m-4 hidden lg:flex">
|
||||
<CardContent className="h-fit grid gap-[2px] px-6 py-2">
|
||||
<CardContent className="h-fit grid gap-[4px] px-6 py-2">
|
||||
<SidebarLink
|
||||
label="Dashboard"
|
||||
to="/"
|
||||
@@ -82,32 +77,12 @@ export const Sidebar = () => {
|
||||
icon={<Bell className="w-4 h-4" />}
|
||||
/>
|
||||
|
||||
<SidebarLink
|
||||
label="Variables"
|
||||
to="/variables"
|
||||
icon={<Variable className="w-4 h-4" />}
|
||||
/>
|
||||
|
||||
<SidebarLink
|
||||
label="Tags"
|
||||
to="/tags"
|
||||
icon={<Tag className="w-4 h-4" />}
|
||||
/>
|
||||
|
||||
<Separator />
|
||||
|
||||
{user?.admin && (
|
||||
<SidebarLink
|
||||
label="Users"
|
||||
to="/users"
|
||||
icon={<User className="w-4 h-4" />}
|
||||
/>
|
||||
)}
|
||||
|
||||
<SidebarLink
|
||||
label="Api Keys"
|
||||
to="/keys"
|
||||
icon={<Key className="w-4 h-4" />}
|
||||
label="Settings"
|
||||
to="/settings"
|
||||
icon={<Settings className="w-4 h-4" />}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useRead, useResourceParamType, useUser } from "@lib/hooks";
|
||||
import { useRead, useResourceParamType } from "@lib/hooks";
|
||||
import { ResourceComponents } from "./resources";
|
||||
import {
|
||||
AlertTriangle,
|
||||
@@ -8,12 +8,10 @@ import {
|
||||
FileQuestion,
|
||||
FolderTree,
|
||||
Home,
|
||||
Key,
|
||||
SearchX,
|
||||
Tag,
|
||||
Settings,
|
||||
User,
|
||||
Users,
|
||||
Variable,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -117,8 +115,6 @@ export const Topbar = () => {
|
||||
};
|
||||
|
||||
const PrimaryDropdown = () => {
|
||||
const user = useUser().data;
|
||||
|
||||
const type = useResourceParamType();
|
||||
const Components = type && ResourceComponents[type];
|
||||
|
||||
@@ -133,20 +129,15 @@ const PrimaryDropdown = () => {
|
||||
]
|
||||
: location.pathname === "/"
|
||||
? [<Home className="w-4 h-4" />, "Home"]
|
||||
: location.pathname === "/keys"
|
||||
? [<Key className="w-4 h-4" />, "Api Keys"]
|
||||
: location.pathname === "/tags"
|
||||
? [<Tag className="w-4 h-4" />, "Tags"]
|
||||
: location.pathname === "/variables"
|
||||
? [<Variable className="w-4 h-4" />, "Variables"]
|
||||
: location.pathname === "/settings"
|
||||
? [<Settings className="w-4 h-4" />, "Settings"]
|
||||
: location.pathname === "/alerts"
|
||||
? [<AlertTriangle className="w-4 h-4" />, "Alerts"]
|
||||
: location.pathname === "/updates"
|
||||
? [<Bell className="w-4 h-4" />, "Updates"]
|
||||
: location.pathname.split("/")[1] === "user-groups"
|
||||
? [<Users className="w-4 h-4" />, "User Groups"]
|
||||
: location.pathname === "/users" ||
|
||||
location.pathname.split("/")[1] === "users"
|
||||
: location.pathname.split("/")[1] === "users"
|
||||
? [<User className="w-4 h-4" />, "Users"]
|
||||
: [<FileQuestion className="w-4 h-4" />, "Unknown"];
|
||||
// : [<Box className="w-4 h-4" />, "Dashboard"];
|
||||
@@ -199,32 +190,12 @@ const PrimaryDropdown = () => {
|
||||
to="/updates"
|
||||
/>
|
||||
|
||||
<DropdownLinkItem
|
||||
label="Variables"
|
||||
icon={<Variable className="w-4 h-4" />}
|
||||
to="/variables"
|
||||
/>
|
||||
|
||||
<DropdownLinkItem
|
||||
label="Tags"
|
||||
icon={<Tag className="w-4 h-4" />}
|
||||
to="/tags"
|
||||
/>
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
{user?.admin && (
|
||||
<DropdownLinkItem
|
||||
label="Users"
|
||||
icon={<User className="w-4 h-4" />}
|
||||
to="/users"
|
||||
/>
|
||||
)}
|
||||
|
||||
<DropdownLinkItem
|
||||
label="Api Keys"
|
||||
icon={<Box className="w-4 h-4" />}
|
||||
to="/keys"
|
||||
label="Settings"
|
||||
icon={<Settings className="w-4 h-4" />}
|
||||
to="/settings"
|
||||
/>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
|
||||
57
frontend/src/pages/settings/index.tsx
Normal file
57
frontend/src/pages/settings/index.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import { useLocalStorage, useUser } from "@lib/hooks";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs";
|
||||
import { CreateVariable, Variables } from "./variables";
|
||||
import { CreateTag, Tags } from "./tags";
|
||||
import { UsersPage } from "./users";
|
||||
import { CreateKey, Keys } from "./keys";
|
||||
import { Page } from "@components/layouts";
|
||||
import { useState } from "react";
|
||||
import { Input } from "@ui/input";
|
||||
|
||||
export const Settings = () => {
|
||||
const user = useUser().data;
|
||||
const [view, setView] = useLocalStorage("settings-view-v0", "Variables");
|
||||
const [search, setSearch] = useState("");
|
||||
const currentView = view === "Users" && !user?.admin ? "Variables" : view;
|
||||
return (
|
||||
<Page>
|
||||
<Tabs value={currentView} onValueChange={setView} className="grid gap-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<TabsList className="justify-start w-fit">
|
||||
<TabsTrigger value="Variables">Variables</TabsTrigger>
|
||||
<TabsTrigger value="Tags">Tags</TabsTrigger>
|
||||
{user?.admin && <TabsTrigger value="Users">Users</TabsTrigger>}
|
||||
<TabsTrigger value="Api Keys">Api Keys</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
{currentView === "Variables" && <CreateVariable />}
|
||||
{currentView === "Tags" && <CreateTag />}
|
||||
{currentView === "Api Keys" && <CreateKey />}
|
||||
{currentView === "Users" && (
|
||||
<Input
|
||||
placeholder="Search"
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="w-[250px]"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<TabsContent value="Variables">
|
||||
<Variables />
|
||||
</TabsContent>
|
||||
<TabsContent value="Tags">
|
||||
<Tags />
|
||||
</TabsContent>
|
||||
{user?.admin && (
|
||||
<TabsContent value="Users">
|
||||
<UsersPage search={search} />
|
||||
</TabsContent>
|
||||
)}
|
||||
<TabsContent value="Api Keys">
|
||||
<Keys />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Page } from "@components/layouts";
|
||||
import { ConfirmButton, CopyButton } from "@components/util";
|
||||
import { useInvalidate, useManageUser, useRead, useSetTitle } from "@lib/hooks";
|
||||
import {
|
||||
@@ -11,7 +10,7 @@ import {
|
||||
} from "@ui/dialog";
|
||||
import { Button } from "@ui/button";
|
||||
import { useToast } from "@ui/use-toast";
|
||||
import { Trash, PlusCircle, Loader2, Check, Key } from "lucide-react";
|
||||
import { Trash, PlusCircle, Loader2, Check } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Input } from "@ui/input";
|
||||
import {
|
||||
@@ -26,22 +25,14 @@ import { KeysTable } from "@components/keys/table";
|
||||
export const Keys = () => {
|
||||
useSetTitle("Api Keys");
|
||||
const keys = useRead("ListApiKeys", {}).data ?? [];
|
||||
return (
|
||||
<Page
|
||||
title="Api Keys"
|
||||
icon={<Key className="w-8 h-8" />}
|
||||
actions={<CreateKey />}
|
||||
>
|
||||
<KeysTable keys={keys} DeleteKey={DeleteKey} />
|
||||
</Page>
|
||||
);
|
||||
return <KeysTable keys={keys} DeleteKey={DeleteKey} />;
|
||||
};
|
||||
|
||||
const ONE_DAY_MS = 1000 * 60 * 60 * 24;
|
||||
|
||||
type ExpiresOptions = "90 days" | "180 days" | "1 year" | "never";
|
||||
|
||||
const CreateKey = () => {
|
||||
export const CreateKey = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [name, setName] = useState("");
|
||||
const [expires, setExpires] = useState<ExpiresOptions>("never");
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Page } from "@components/layouts";
|
||||
import { ConfirmButton } from "@components/util";
|
||||
import { useInvalidate, useRead, useSetTitle, useWrite } from "@lib/hooks";
|
||||
import {
|
||||
@@ -12,7 +11,7 @@ import {
|
||||
import { Button } from "@ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@ui/card";
|
||||
import { useToast } from "@ui/use-toast";
|
||||
import { Trash, PlusCircle, Loader2, Check, Tag } from "lucide-react";
|
||||
import { Trash, PlusCircle, Loader2, Check } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Input } from "@ui/input";
|
||||
import { UpdateUser } from "@components/updates/details";
|
||||
@@ -26,43 +25,37 @@ export const Tags = () => {
|
||||
const tags = useRead("ListTags", {}).data;
|
||||
|
||||
return (
|
||||
<Page
|
||||
title="Tags"
|
||||
icon={<Tag className="w-8 h-8" />}
|
||||
actions={<CreateTag />}
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
<Input
|
||||
placeholder="search..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="w-[200px] lg:w-[300px]"
|
||||
/>
|
||||
<DataTable
|
||||
tableKey="tags"
|
||||
data={tags?.filter((tag) => tag.name.includes(search)) ?? []}
|
||||
columns={[
|
||||
{
|
||||
header: "Name",
|
||||
accessorKey: "name",
|
||||
},
|
||||
{
|
||||
header: "Owner",
|
||||
cell: ({ row }) =>
|
||||
row.original.owner ? (
|
||||
<UpdateUser user_id={row.original.owner} />
|
||||
) : (
|
||||
"Unknown"
|
||||
),
|
||||
},
|
||||
{
|
||||
header: "Delete",
|
||||
cell: ({ row }) => <DeleteTag tag_id={row.original._id!.$oid} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</Page>
|
||||
<div className="flex flex-col gap-4">
|
||||
<Input
|
||||
placeholder="search..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="w-[200px] lg:w-[300px]"
|
||||
/>
|
||||
<DataTable
|
||||
tableKey="tags"
|
||||
data={tags?.filter((tag) => tag.name.includes(search)) ?? []}
|
||||
columns={[
|
||||
{
|
||||
header: "Name",
|
||||
accessorKey: "name",
|
||||
},
|
||||
{
|
||||
header: "Owner",
|
||||
cell: ({ row }) =>
|
||||
row.original.owner ? (
|
||||
<UpdateUser user_id={row.original.owner} />
|
||||
) : (
|
||||
"Unknown"
|
||||
),
|
||||
},
|
||||
{
|
||||
header: "Delete",
|
||||
cell: ({ row }) => <DeleteTag tag_id={row.original._id!.$oid} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -92,7 +85,7 @@ export const TagCards = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const CreateTag = () => {
|
||||
export const CreateTag = () => {
|
||||
const { toast } = useToast();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [name, setName] = useState("");
|
||||
@@ -117,7 +110,7 @@ const CreateTag = () => {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="items-center gap-2">
|
||||
<Button variant="secondary" className="items-center gap-2">
|
||||
New Tag <PlusCircle className="w-4 h-4" />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
@@ -1,33 +1,19 @@
|
||||
import { Page, Section } from "@components/layouts";
|
||||
import { Section } from "@components/layouts";
|
||||
import { NewServiceUser, NewUserGroup } from "@components/users/new";
|
||||
import { UserTable } from "@components/users/table";
|
||||
import { useRead, useSetTitle } from "@lib/hooks";
|
||||
import { DataTable } from "@ui/data-table";
|
||||
import { Input } from "@ui/input";
|
||||
import { User, Users } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export const UsersPage = () => {
|
||||
export const UsersPage = ({ search }: { search: string }) => {
|
||||
useSetTitle("Users");
|
||||
const nav = useNavigate();
|
||||
const groups = useRead("ListUserGroups", {}).data;
|
||||
const users = useRead("ListUsers", {}).data;
|
||||
const [search, setSearch] = useState("");
|
||||
const searchSplit = search.split(" ");
|
||||
return (
|
||||
<Page
|
||||
title="Users"
|
||||
icon={<User className="w-8 h-8" />}
|
||||
actions={
|
||||
<Input
|
||||
placeholder="Search"
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="w-[250px]"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div className="flex flex-col gap-6">
|
||||
{/* User Groups */}
|
||||
<Section
|
||||
title="User Groups"
|
||||
@@ -66,6 +52,6 @@ export const UsersPage = () => {
|
||||
}
|
||||
/>
|
||||
</Section>
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Page } from "@components/layouts";
|
||||
import { ConfirmButton, TextUpdateMenu } from "@components/util";
|
||||
import {
|
||||
useInvalidate,
|
||||
@@ -20,7 +19,7 @@ import {
|
||||
} from "@ui/dialog";
|
||||
import { Input } from "@ui/input";
|
||||
import { useToast } from "@ui/use-toast";
|
||||
import { Check, Loader2, PlusCircle, Trash, Variable } from "lucide-react";
|
||||
import { Check, Loader2, PlusCircle, Trash } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
export const Variables = () => {
|
||||
@@ -51,101 +50,95 @@ export const Variables = () => {
|
||||
},
|
||||
});
|
||||
return (
|
||||
<Page
|
||||
title="Variables"
|
||||
icon={<Variable className="w-8 h-8" />}
|
||||
actions={<CreateVariable />}
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
<Input
|
||||
placeholder="search..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="w-[200px] lg:w-[300px]"
|
||||
/>
|
||||
<div className="flex flex-col gap-4">
|
||||
<Input
|
||||
placeholder="search..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="w-[200px] lg:w-[300px]"
|
||||
/>
|
||||
|
||||
{/** VARIABLES */}
|
||||
<DataTable
|
||||
tableKey="variables"
|
||||
data={filtered}
|
||||
columns={[
|
||||
{
|
||||
accessorKey: "name",
|
||||
header: ({ column }) => (
|
||||
<SortableHeader column={column} title="Name" />
|
||||
),
|
||||
{/** VARIABLES */}
|
||||
<DataTable
|
||||
tableKey="variables"
|
||||
data={filtered}
|
||||
columns={[
|
||||
{
|
||||
accessorKey: "name",
|
||||
header: ({ column }) => (
|
||||
<SortableHeader column={column} title="Name" />
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "value",
|
||||
header: ({ column }) => (
|
||||
<SortableHeader column={column} title="Value" />
|
||||
),
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<TextUpdateMenu
|
||||
title={`${row.original.name} - Value`}
|
||||
placeholder="Set value"
|
||||
value={row.original.value}
|
||||
onUpdate={(value) => {
|
||||
if (row.original.value === value) {
|
||||
return;
|
||||
}
|
||||
updateValue({ name: row.original.name, value });
|
||||
}}
|
||||
triggerClassName="w-full"
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
/>
|
||||
);
|
||||
},
|
||||
{
|
||||
accessorKey: "value",
|
||||
header: ({ column }) => (
|
||||
<SortableHeader column={column} title="Value" />
|
||||
),
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<TextUpdateMenu
|
||||
title={`${row.original.name} - Value`}
|
||||
placeholder="Set value"
|
||||
value={row.original.value}
|
||||
onUpdate={(value) => {
|
||||
if (row.original.value === value) {
|
||||
return;
|
||||
}
|
||||
updateValue({ name: row.original.name, value });
|
||||
}}
|
||||
triggerClassName="w-full"
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "description",
|
||||
header: "Description",
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<TextUpdateMenu
|
||||
title={`${row.original.name} - Description`}
|
||||
placeholder="Set description"
|
||||
value={row.original.description}
|
||||
onUpdate={(description) => {
|
||||
if (row.original.description === description) {
|
||||
return;
|
||||
}
|
||||
updateDescription({
|
||||
name: row.original.name,
|
||||
description,
|
||||
});
|
||||
}}
|
||||
triggerClassName="w-full"
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
/>
|
||||
);
|
||||
},
|
||||
{
|
||||
accessorKey: "description",
|
||||
header: "Description",
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<TextUpdateMenu
|
||||
title={`${row.original.name} - Description`}
|
||||
placeholder="Set description"
|
||||
value={row.original.description}
|
||||
onUpdate={(description) => {
|
||||
if (row.original.description === description) {
|
||||
return;
|
||||
}
|
||||
updateDescription({
|
||||
name: row.original.name,
|
||||
description,
|
||||
});
|
||||
}}
|
||||
triggerClassName="w-full"
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: "Delete",
|
||||
cell: ({ row }) => <DeleteVariable name={row.original.name} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
},
|
||||
{
|
||||
header: "Delete",
|
||||
cell: ({ row }) => <DeleteVariable name={row.original.name} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{/** SECRETS */}
|
||||
{secrets.length && (
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
<div>Core Secrets:</div>
|
||||
{secrets.map((secret) => (
|
||||
<Badge variant="secondary">{secret}</Badge>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Page>
|
||||
{/** SECRETS */}
|
||||
{secrets.length && (
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
<div>Core Secrets:</div>
|
||||
{secrets.map((secret) => (
|
||||
<Badge variant="secondary">{secret}</Badge>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const CreateVariable = () => {
|
||||
export const CreateVariable = () => {
|
||||
const { toast } = useToast();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [name, setName] = useState("");
|
||||
@@ -170,7 +163,7 @@ const CreateVariable = () => {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="items-center gap-2">
|
||||
<Button variant="secondary" className="items-center gap-2">
|
||||
New Variable <PlusCircle className="w-4 h-4" />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
@@ -3,12 +3,9 @@ import { useUser } from "@lib/hooks";
|
||||
import { Login } from "@pages/login";
|
||||
import { Resource } from "@pages/resource";
|
||||
import { Resources } from "@pages/resources";
|
||||
import { Keys } from "@pages/keys";
|
||||
import { RouterProvider, createBrowserRouter } from "react-router-dom";
|
||||
import { Tree } from "@pages/home/tree";
|
||||
import { Tags } from "@pages/tags";
|
||||
import { Updates } from "@pages/updates";
|
||||
import { UsersPage } from "@pages/users";
|
||||
import { AllResources } from "@pages/home/all_resources";
|
||||
import { UserDisabled } from "@pages/user_disabled";
|
||||
import { Home } from "@pages/home";
|
||||
@@ -16,7 +13,7 @@ import { ResourceStats } from "@pages/resource_stats";
|
||||
import { Alerts } from "@pages/alerts";
|
||||
import { UserPage } from "@pages/user";
|
||||
import { UserGroupPage } from "@pages/user-group";
|
||||
import { Variables } from "@pages/variables";
|
||||
import { Settings } from "@pages/settings";
|
||||
|
||||
const ROUTER = createBrowserRouter([
|
||||
{
|
||||
@@ -24,18 +21,19 @@ const ROUTER = createBrowserRouter([
|
||||
element: <Layout />,
|
||||
children: [
|
||||
{ path: "", element: <Home /> },
|
||||
{ path: "keys", element: <Keys /> },
|
||||
{ path: "tags", element: <Tags /> },
|
||||
{ path: "settings", element: <Settings /> },
|
||||
// { path: "keys", element: <Keys /> },
|
||||
// { path: "tags", element: <Tags /> },
|
||||
{ path: "tree", element: <Tree /> },
|
||||
{ path: "alerts", element: <Alerts /> },
|
||||
{ path: "updates", element: <Updates /> },
|
||||
{ path: "variables", element: <Variables /> },
|
||||
// { path: "variables", element: <Variables /> },
|
||||
{ path: "resources", element: <AllResources /> },
|
||||
{ path: "user-groups/:id", element: <UserGroupPage /> },
|
||||
{
|
||||
path: "users",
|
||||
children: [
|
||||
{ path: "", element: <UsersPage /> },
|
||||
// { path: "", element: <UsersPage /> },
|
||||
{ path: ":id", element: <UserPage /> },
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user