mirror of
https://github.com/stefanpejcic/openpanel
synced 2025-06-26 18:28:26 +00:00
no packages and conf copied
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
export const ActiveItemBackground = ({ active }: { active?: boolean }) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-left-0",
|
||||
"re-top-0",
|
||||
"re-h-full",
|
||||
"re-w-full",
|
||||
active ? "re-scale-100" : "re-scale-0",
|
||||
"re-transition-all",
|
||||
"re-duration-300",
|
||||
"re-ease-[cubic-bezier(.25,.75,.5,1.25)]",
|
||||
)}
|
||||
style={{
|
||||
background:
|
||||
"url(https://refine.ams3.cdn.digitaloceanspaces.com/devtools/active-background-icon.png)",
|
||||
backgroundSize: "36px 36px",
|
||||
backgroundPosition: "center",
|
||||
backgroundRepeat: "no-repeat",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,451 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { AvailablePackageType } from "@refinedev/devtools-shared";
|
||||
|
||||
import { CloseIcon } from "./icons/close";
|
||||
import { SearchIcon } from "./icons/search";
|
||||
import { AddPackageItem } from "./add-package.item";
|
||||
import { Modal } from "./modal";
|
||||
import { Highlight } from "./highlight";
|
||||
import { PlusCircleIcon } from "./icons/plus-circle";
|
||||
import { Button } from "./button";
|
||||
import { getAvailablePackages } from "src/utils/packages";
|
||||
import { UpdateIcon } from "./icons/update";
|
||||
import { CheckIcon } from "./icons/check";
|
||||
import { InfoIcon } from "./icons/info";
|
||||
|
||||
type Props = {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
installedPackages: string[];
|
||||
onInstall: (packagesToInstall: string[]) => Promise<boolean>;
|
||||
dismissOnOverlayClick?: boolean;
|
||||
};
|
||||
|
||||
export const AddPackageDrawer = ({
|
||||
visible,
|
||||
onClose,
|
||||
installedPackages,
|
||||
onInstall,
|
||||
dismissOnOverlayClick = true,
|
||||
}: Props) => {
|
||||
const [delayedVisible, setDelayedVisible] = React.useState(visible);
|
||||
const [installModal, setInstallModal] = React.useState<string | null>(null);
|
||||
|
||||
const [packages, setPackages] = React.useState<AvailablePackageType[]>([]);
|
||||
|
||||
const [search, setSearch] = React.useState("");
|
||||
|
||||
React.useEffect(() => {
|
||||
getAvailablePackages().then((pkgs) => setPackages(pkgs));
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setDelayedVisible(visible);
|
||||
}, 200);
|
||||
}, [visible]);
|
||||
|
||||
const onCloseInternal = React.useCallback(() => {
|
||||
setDelayedVisible(false);
|
||||
setTimeout(() => {
|
||||
onClose();
|
||||
}, 200);
|
||||
}, [onClose]);
|
||||
|
||||
const [status, setStatus] = React.useState<
|
||||
"idle" | "installing" | "error" | "done"
|
||||
>("idle");
|
||||
|
||||
const updatePackage = React.useCallback(async () => {
|
||||
if (installModal) {
|
||||
const installCommand =
|
||||
packages.find((el) => el.name === installModal)?.install ?? "";
|
||||
const packagesToInstall = installCommand
|
||||
.replace("npm install ", "")
|
||||
.split(" ");
|
||||
|
||||
setStatus("installing");
|
||||
const response = await onInstall(packagesToInstall);
|
||||
if (response) {
|
||||
setStatus("done");
|
||||
setInstallModal(null);
|
||||
getAvailablePackages().then((pkgs) => {
|
||||
setPackages(pkgs);
|
||||
});
|
||||
} else {
|
||||
setStatus("error");
|
||||
}
|
||||
}
|
||||
}, [installModal]);
|
||||
|
||||
const data = React.useMemo(() => {
|
||||
const filtered = packages
|
||||
.filter((pkg) => !installedPackages.includes(pkg.name))
|
||||
.filter((pkg) => pkg.name.includes(search));
|
||||
|
||||
return filtered;
|
||||
}, [packages, installedPackages, search]);
|
||||
|
||||
const icon = React.useMemo(() => {
|
||||
switch (status) {
|
||||
case "installing":
|
||||
return (
|
||||
<UpdateIcon className="re-text-gray-0 re-animate-spin" />
|
||||
);
|
||||
case "done":
|
||||
return <CheckIcon className="re-text-gray-0" />;
|
||||
case "error":
|
||||
return <InfoIcon className="re-text-gray-0 re-rotate-180" />;
|
||||
case "idle":
|
||||
default:
|
||||
return <PlusCircleIcon className="re-text-gray-0" />;
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
const statusText = React.useMemo(() => {
|
||||
switch (status) {
|
||||
case "installing":
|
||||
return "Installing";
|
||||
case "done":
|
||||
return "Installed";
|
||||
case "error":
|
||||
return "Error";
|
||||
case "idle":
|
||||
default:
|
||||
return "Install";
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-z-10",
|
||||
"re-fixed",
|
||||
"re-left-0",
|
||||
"re-top-0",
|
||||
"re-h-full",
|
||||
"re-w-full",
|
||||
!visible && "re-hidden",
|
||||
visible && "re-block",
|
||||
!visible && "re-pointer-events-none",
|
||||
visible && "re-pointer-events-auto",
|
||||
)}
|
||||
onClick={dismissOnOverlayClick ? onCloseInternal : undefined}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-w-full",
|
||||
"re-h-full",
|
||||
"re-backdrop-blur-sm",
|
||||
"re-bg-gray-900",
|
||||
"re-bg-opacity-50",
|
||||
"re-transition-all",
|
||||
"re-ease-in-out",
|
||||
"re-duration-200",
|
||||
!delayedVisible && "re-pointer-events-none",
|
||||
delayedVisible && "re-pointer-events-auto",
|
||||
)}
|
||||
style={{
|
||||
transformOrigin: "center right",
|
||||
transform: `${
|
||||
delayedVisible ? "scale(1)" : "scale(0)"
|
||||
} translate3d(0,0,0)`,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-right-0",
|
||||
"re-top-0",
|
||||
"re-h-auto",
|
||||
"re-w-[400px]",
|
||||
"re-overflow-auto",
|
||||
"re-border-l",
|
||||
"re-border-l-gray-700",
|
||||
"re-bg-gray-800",
|
||||
"re-transition-transform",
|
||||
"re-duration-200",
|
||||
"re-ease-in-out",
|
||||
"re-shadow-2xl",
|
||||
delayedVisible && "re-translate-x-0",
|
||||
!delayedVisible && "re-translate-x-full",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-h-full",
|
||||
)}
|
||||
style={{
|
||||
transformOrigin: "center right",
|
||||
transform: `${
|
||||
delayedVisible ? "translateX(0px)" : "translateX(100%)"
|
||||
} translateZ(0)`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-5",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-flex-shrink-0",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-gray-300",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-font-semibold",
|
||||
)}
|
||||
>
|
||||
Explore refine packages
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onCloseInternal}
|
||||
className={clsx(
|
||||
"re-w-6",
|
||||
"re-h-6",
|
||||
"re-appearance-none",
|
||||
"re-bg-none",
|
||||
"re-border-none",
|
||||
"re-outline-none",
|
||||
"re-text-gray-500",
|
||||
)}
|
||||
>
|
||||
<CloseIcon className="re-w-6 re-h-6" />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-flex-1",
|
||||
"re-overflow-hidden",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-pt-5",
|
||||
"re-px-5",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-w-full",
|
||||
"re-rounded-lg",
|
||||
)}
|
||||
>
|
||||
<div className={clsx("re-relative", "re-w-full")}>
|
||||
<input
|
||||
type="text"
|
||||
className={clsx(
|
||||
"re-w-full",
|
||||
"re-py-[7px]",
|
||||
"re-pr-2",
|
||||
"re-rounded-lg",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-bg-gray-900",
|
||||
"re-outline-none",
|
||||
"re-text-gray-300",
|
||||
"re-placeholder-gray-500",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-pl-10",
|
||||
)}
|
||||
placeholder="Search packages"
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-pointer-events-none",
|
||||
"re-absolute",
|
||||
"re-h-full",
|
||||
"re-top-0",
|
||||
"re-left-0",
|
||||
"re-pl-3",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
)}
|
||||
>
|
||||
<SearchIcon
|
||||
className={clsx(
|
||||
"re-text-gray-500",
|
||||
"re-w-4",
|
||||
"re-h-4",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-overflow-scroll",
|
||||
"re-flex-1",
|
||||
"re-px-5",
|
||||
"re-pb-5",
|
||||
"re-pt-5",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-6",
|
||||
)}
|
||||
>
|
||||
{data.map((pkg) => (
|
||||
<AddPackageItem
|
||||
key={pkg.name}
|
||||
{...pkg}
|
||||
onInstall={() => setInstallModal(pkg.name)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
visible={Boolean(installModal)}
|
||||
onClose={() => setInstallModal(null)}
|
||||
overlay
|
||||
header={
|
||||
<div className={clsx("re-flex", "re-flex-col", "re-gap-2")}>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-gray-300",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-font-semibold",
|
||||
)}
|
||||
>
|
||||
{
|
||||
packages.find((el) => el.name === installModal)
|
||||
?.name
|
||||
}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-gray-400",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-font-normal",
|
||||
)}
|
||||
>
|
||||
{packages.find((el) => el.name === installModal)
|
||||
?.description ?? ""}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
footer={
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-row",
|
||||
"re-gap-2",
|
||||
"re-items-center",
|
||||
"re-justify-end",
|
||||
)}
|
||||
>
|
||||
<Button
|
||||
onClick={() => updatePackage()}
|
||||
className={clsx(
|
||||
"re-gap-2",
|
||||
"re-bg-alt-blue",
|
||||
"re-flex-nowrap",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
"!re-pl-2",
|
||||
)}
|
||||
>
|
||||
{icon}
|
||||
<span className="re-text-gray-0">{statusText}</span>
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-5",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-text-gray-300",
|
||||
"re-font-semibold",
|
||||
)}
|
||||
>
|
||||
How to install?
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-bg-gray-700",
|
||||
"re-rounded-lg",
|
||||
"re-p-4",
|
||||
"re-text-sm",
|
||||
"re-overflow-auto",
|
||||
)}
|
||||
>
|
||||
<Highlight
|
||||
code={
|
||||
packages.find((el) => el.name === installModal)
|
||||
?.install ?? ""
|
||||
}
|
||||
language="bash"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-5",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-text-gray-300",
|
||||
"re-font-semibold",
|
||||
)}
|
||||
>
|
||||
How to use?
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-bg-gray-700",
|
||||
"re-rounded-lg",
|
||||
"re-p-4",
|
||||
"re-text-sm",
|
||||
"re-overflow-auto",
|
||||
)}
|
||||
>
|
||||
<Highlight
|
||||
code={
|
||||
packages.find((el) => el.name === installModal)
|
||||
?.usage ?? ""
|
||||
}
|
||||
language="tsx"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,117 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { Button } from "./button";
|
||||
import { PlusCircleIcon } from "./icons/plus-circle";
|
||||
import { AvailablePackageType } from "@refinedev/devtools-shared";
|
||||
|
||||
type PackageItemProps = {
|
||||
onInstall?: () => void;
|
||||
} & AvailablePackageType;
|
||||
|
||||
export const AddPackageItem = ({
|
||||
name,
|
||||
description,
|
||||
onInstall,
|
||||
}: PackageItemProps) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-rounded-lg",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-bg-gray-800",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-py-4",
|
||||
"re-px-4",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-font-semibold",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
{name}
|
||||
</div>
|
||||
<Button
|
||||
onClick={onInstall}
|
||||
className={clsx(
|
||||
"re-gap-2",
|
||||
"re-text-alt-blue",
|
||||
"re-bg-alt-blue",
|
||||
"re-bg-opacity-[0.15]",
|
||||
"re-flex-nowrap",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
"!re-px-2",
|
||||
)}
|
||||
>
|
||||
<PlusCircleIcon className="re-text-alt-blue" />
|
||||
<span className="re-text-alt-blue">Install</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-leading-5",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
{description ?? ""}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-4",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<a
|
||||
href={name.replace(
|
||||
"@refinedev/",
|
||||
"https://c.refine.dev/",
|
||||
)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={clsx("re-text-alt-blue", "re-text-xs")}
|
||||
>
|
||||
changelog
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href={name.replace(
|
||||
"@refinedev/",
|
||||
"https://d.refine.dev/",
|
||||
)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={clsx("re-text-alt-blue", "re-text-xs")}
|
||||
>
|
||||
documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,41 +0,0 @@
|
||||
import React from "react";
|
||||
import { isAuthenticated } from "src/utils/auth";
|
||||
|
||||
export const Authenticated = ({
|
||||
children,
|
||||
fallback,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
fallback: React.ReactNode;
|
||||
}) => {
|
||||
const [authenticated, setAuthenticated] = React.useState<
|
||||
"loading" | "success" | "error"
|
||||
>("loading");
|
||||
|
||||
const checkAuth = React.useCallback(async () => {
|
||||
try {
|
||||
const authStatus = await isAuthenticated();
|
||||
if (authStatus) {
|
||||
setAuthenticated("success");
|
||||
} else {
|
||||
setAuthenticated("error");
|
||||
}
|
||||
} catch (_error) {
|
||||
setAuthenticated("error");
|
||||
}
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
checkAuth();
|
||||
}, [checkAuth]);
|
||||
|
||||
if (authenticated === "error") {
|
||||
return <>{fallback}</>;
|
||||
}
|
||||
|
||||
if (authenticated === "success") {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const Button = React.forwardRef<HTMLButtonElement, Props>(
|
||||
function Button({ children, onClick, className }, ref) {
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
onClick={onClick}
|
||||
className={clsx(
|
||||
"re-rounded",
|
||||
"re-py-2",
|
||||
"re-px-4",
|
||||
"re-text-xs",
|
||||
"re-text-gray-0",
|
||||
"re-bg-brand-blue",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -1,83 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { CheckboxFilledIcon } from "./icons/checkbox-filled";
|
||||
import { CheckboxEmptyIcon } from "./icons/checkbox-empty";
|
||||
|
||||
type Props = {
|
||||
options: {
|
||||
label: string;
|
||||
value: string;
|
||||
}[];
|
||||
values: string[];
|
||||
onChange: (values: string[]) => void;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const CheckboxGroup = ({
|
||||
options,
|
||||
values,
|
||||
onChange,
|
||||
className,
|
||||
}: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-relative",
|
||||
"re-flex",
|
||||
"re-flex-1",
|
||||
"re-gap-3",
|
||||
"re-min-h-[32px]",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{options.map(({ label, value }) => {
|
||||
const selected = values.includes(value);
|
||||
|
||||
return (
|
||||
<button
|
||||
key={value}
|
||||
type="button"
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-gap-1.5",
|
||||
"re-items-center",
|
||||
"re-bg-none",
|
||||
"re-border-none",
|
||||
"re-appearance-none",
|
||||
"re-outline-none",
|
||||
)}
|
||||
onClick={() => {
|
||||
if (values.includes(value)) {
|
||||
onChange(values.filter((v) => v !== value));
|
||||
} else {
|
||||
onChange([...values, value]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-flex-shrink-0",
|
||||
"re-w-3",
|
||||
"re-h-3",
|
||||
)}
|
||||
>
|
||||
{selected && (
|
||||
<CheckboxFilledIcon className="re-pointer-events-none" />
|
||||
)}
|
||||
{!selected && (
|
||||
<CheckboxEmptyIcon className="re-pointer-events-none" />
|
||||
)}
|
||||
</span>
|
||||
<span
|
||||
className={clsx("re-text-xs", "re-text-gray-300")}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
import clsx from "clsx";
|
||||
import * as React from "react";
|
||||
|
||||
export const ComingSoonText = (props: { className?: string }) => {
|
||||
return (
|
||||
<h2
|
||||
className={clsx(
|
||||
"re-bg-coming-soon-text",
|
||||
"re-drop-shadow-coming-soon-text",
|
||||
"re-text-2xl lg:re-text-[32px] lg:re-leading-10",
|
||||
"re-bg-clip-text",
|
||||
"re-text-transparent",
|
||||
"re-font-semibold",
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
Coming Soon!
|
||||
</h2>
|
||||
);
|
||||
};
|
||||
@@ -1,232 +0,0 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import { OptionsIcon } from "src/components/icons/options";
|
||||
import { PlaygroundIcon } from "src/components/icons/playground";
|
||||
import { ResourceViewerIcon } from "src/components/icons/resource-viewer";
|
||||
import { SnippetsIcon } from "src/components/icons/snippets";
|
||||
import { InferencerPreviewIcon } from "src/components/icons/inferencer-preview";
|
||||
import { ActiveItemBackground } from "src/components/active-item-background";
|
||||
import { ComingSoonText } from "src/components/coming-soon-text";
|
||||
|
||||
const slides = [
|
||||
{
|
||||
image: "https://refine.ams3.cdn.digitaloceanspaces.com/devtools/login/slide1.png",
|
||||
icon: <ResourceViewerIcon className={clsx("re-z-[1]")} />,
|
||||
title: "Resource Viewer",
|
||||
},
|
||||
{
|
||||
image: "https://refine.ams3.cdn.digitaloceanspaces.com/devtools/login/slide2.png",
|
||||
icon: <OptionsIcon className={clsx("re-z-[1]")} />,
|
||||
title: "Refine status",
|
||||
},
|
||||
{
|
||||
image: "https://refine.ams3.cdn.digitaloceanspaces.com/devtools/login/slide3.png",
|
||||
icon: <PlaygroundIcon className={clsx("re-z-[1]")} />,
|
||||
title: "Playground",
|
||||
},
|
||||
{
|
||||
image: "https://refine.ams3.cdn.digitaloceanspaces.com/devtools/login/slide4.png",
|
||||
icon: <InferencerPreviewIcon className={clsx("re-z-[1]")} />,
|
||||
title: "Inferencer preview",
|
||||
},
|
||||
{
|
||||
image: "https://refine.ams3.cdn.digitaloceanspaces.com/devtools/login/slide5.png",
|
||||
icon: <SnippetsIcon className={clsx("re-z-[1]")} />,
|
||||
title: "Snippets",
|
||||
},
|
||||
];
|
||||
|
||||
export const FeatureSlide = (props: { className?: string }) => {
|
||||
const slideTimeout = useRef<NodeJS.Timeout | null | undefined>(undefined);
|
||||
const [slideIndex, setSlideIndex] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (slideTimeout.current === null) return;
|
||||
|
||||
slideTimeout.current = setTimeout(() => {
|
||||
setSlideIndex((prev) => {
|
||||
return prev === slides.length - 1 ? 0 : prev + 1;
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
return () => {
|
||||
if (slideTimeout.current) {
|
||||
clearTimeout(slideTimeout.current);
|
||||
}
|
||||
};
|
||||
}, [slideIndex]);
|
||||
|
||||
const handleSlideChange = (id: number) => {
|
||||
setSlideIndex(id);
|
||||
if (slideTimeout.current) {
|
||||
clearTimeout(slideTimeout.current);
|
||||
slideTimeout.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-h-full",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-items-center re-justify-center",
|
||||
"re-py-4 tall:re-py-8 re-px-8",
|
||||
"re-gap-4 tall:re-gap-8",
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<ComingSoonText />
|
||||
<div
|
||||
className={clsx(
|
||||
"tall:re-mt-6",
|
||||
"re-w-full re-h-full re-max-h-[416px]",
|
||||
"re-relative",
|
||||
)}
|
||||
>
|
||||
{slides.map((_slide, index) => {
|
||||
const active = index === slideIndex;
|
||||
|
||||
return (
|
||||
<img
|
||||
key={index}
|
||||
src={slides[slideIndex].image}
|
||||
alt={slides[slideIndex].title}
|
||||
className={clsx(
|
||||
"re-absolute re-top-0 re-left-0 re-w-full re-h-full re-object-contain",
|
||||
active ? "re-visible" : "re-invisible",
|
||||
active ? "re-opacity-100" : "re-opacity-0",
|
||||
"re-transition-opacity re-ease-in re-duration-300",
|
||||
)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-gap-2",
|
||||
"re-p-2",
|
||||
"re-bg-gray-900",
|
||||
"re-rounded-lg",
|
||||
)}
|
||||
>
|
||||
{slides.map((slide, index) => {
|
||||
const active = index === slideIndex;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={clsx(
|
||||
"re-relative",
|
||||
active
|
||||
? "re-text-alt-cyan"
|
||||
: "re-text-gray-500",
|
||||
!active && "hover:re-text-alt-cyan",
|
||||
)}
|
||||
>
|
||||
<ActiveItemBackground active={active} />
|
||||
<button
|
||||
onClick={() => handleSlideChange(index)}
|
||||
className={clsx(
|
||||
"re-w-12 re-h-12",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
)}
|
||||
>
|
||||
{slide.icon}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const FeatureSlideMobile = (props: { className?: string }) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-max-w-[640px]",
|
||||
"re-w-full",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-gap-4",
|
||||
"re-p-6",
|
||||
"re-bg-gray-800",
|
||||
"re-rounded-lg",
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<ComingSoonText />
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-full",
|
||||
"re-h-16",
|
||||
"re-relative",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-py-6",
|
||||
"re-overflow-hidden",
|
||||
"re-bg-gray-900",
|
||||
"re-rounded-full",
|
||||
"after:re-absolute after:re-z-10 before:re-absolute before:re-z-10",
|
||||
"after:re-rounded-full before:re-rounded-full",
|
||||
"after:re-bg-feature-slide-mobile-after before:re-bg-feature-slide-mobile-before",
|
||||
"after:re-right-0 before:re-left-0",
|
||||
"after:re-h-[120px] before:re-h-[120px]",
|
||||
"after:re-w-[120px] before:re-w-[120px]",
|
||||
"re-border re-border-t-[#3a3b4aa3] re-border-r-[#3a3b4abb] re-border-b-[#3a3b4a] re-border-l-[#3a3b4abb]",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-left-0",
|
||||
"re-w-auto",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-gap-5",
|
||||
"re-pr-5",
|
||||
"re-animate-feature-slide-mobile-items",
|
||||
)}
|
||||
>
|
||||
{[...slides, ...slides].map((slide, i) => {
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
<div className={clsx("re-text-alt-cyan")}>
|
||||
{slide.icon}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-whitespace-nowrap",
|
||||
"re-bg-gradient-to-r re-from-white re-to-[#FFFFFF80]",
|
||||
"re-bg-clip-text re-text-transparent",
|
||||
)}
|
||||
>
|
||||
{slide.title}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,133 +0,0 @@
|
||||
import React from "react";
|
||||
import dayjs from "dayjs";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { FeedSection } from "@refinedev/devtools-shared";
|
||||
|
||||
type Props = {
|
||||
item: FeedSection;
|
||||
};
|
||||
|
||||
export const FeedItem = ({ item }: Props) => {
|
||||
const isNew = dayjs().diff(dayjs(item.date), "day") <= 3;
|
||||
const isFeatured = item.featured;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-rounded-lg",
|
||||
"re-bg-gray-900",
|
||||
isFeatured && "re-bg-feed-item-featured",
|
||||
isNew && "re-bg-feed-item-new",
|
||||
"re-p-6",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-4",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
{item.avatar && (
|
||||
<img
|
||||
src={item.avatar}
|
||||
className={clsx(
|
||||
"re-w-5",
|
||||
"re-h-5",
|
||||
"re-rounded-lg",
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<div className={clsx("re-text-xs", "re-text-gray-500")}>
|
||||
{item.author}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-sm",
|
||||
"re-leading-4",
|
||||
"re-text-gray-600",
|
||||
"re-font-black",
|
||||
)}
|
||||
>
|
||||
·
|
||||
</div>
|
||||
<div className={clsx("re-text-xs", "re-text-gray-500")}>
|
||||
{dayjs(item.date).format("DD MMM, HH:mm")}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
isFeatured || isNew ? "re-flex" : "re-hidden",
|
||||
"re-text-[8px]",
|
||||
"re-leading-[10px]",
|
||||
"re-border",
|
||||
isFeatured && "re-text-alt-pink",
|
||||
isFeatured && "re-border-alt-pink",
|
||||
isNew && "re-text-alt-cyan",
|
||||
isNew && "re-border-alt-cyan",
|
||||
"re-py-0.5",
|
||||
"re-px-1.5",
|
||||
"re-rounded-xl",
|
||||
"re-bg-gray-900",
|
||||
"re-bg-opacity-10",
|
||||
"re-border-opacity-20",
|
||||
"re-uppercase",
|
||||
"re-font-semibold",
|
||||
)}
|
||||
>
|
||||
{isFeatured ? "featured" : isNew ? "new" : ""}
|
||||
</div>
|
||||
</div>
|
||||
{item.cover && (
|
||||
<img
|
||||
src={item.cover}
|
||||
className={clsx(
|
||||
"re-w-full",
|
||||
"re-aspect-[10/6]",
|
||||
"re-bg-gray-900",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-rounded",
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<div className={clsx("re-flex", "re-flex-col", "re-gap-2")}>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-sm",
|
||||
"re-text-gray-300",
|
||||
"re-font-semibold",
|
||||
)}
|
||||
>
|
||||
{item.title}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-prose",
|
||||
"prose",
|
||||
"re-text-gray-400",
|
||||
"re-text-xs",
|
||||
"re-leading-5",
|
||||
"prose-a:re-text-alt-blue",
|
||||
"prose-a:re-underline",
|
||||
)}
|
||||
dangerouslySetInnerHTML={{ __html: item.content }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import type { Feed as FeedType } from "@refinedev/devtools-shared";
|
||||
import { FeedItem } from "src/components/feed-item";
|
||||
|
||||
export const Feed = () => {
|
||||
const [feed, setFeed] = React.useState<FeedType | null>(null);
|
||||
|
||||
const fetchFeed = React.useCallback(async () => {
|
||||
try {
|
||||
const response = await fetch("api/feed");
|
||||
const { data } = (await response.json()) as {
|
||||
data: FeedType | null;
|
||||
};
|
||||
setFeed(data);
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
fetchFeed();
|
||||
}, [fetchFeed]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-h-full",
|
||||
"re-w-full",
|
||||
"large:re-max-w-[380px]",
|
||||
"re-justify-center",
|
||||
"re-mx-auto",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-sm",
|
||||
"re-text-gray-0",
|
||||
"re-font-semibold",
|
||||
"re-leading-8",
|
||||
"re-flex-shrink-0",
|
||||
)}
|
||||
>
|
||||
Updates from the refine team
|
||||
</div>
|
||||
<div className={clsx("re-flex-1", "re-overflow-auto")}>
|
||||
<div className={clsx("re-flex", "re-flex-col", "re-gap-8")}>
|
||||
<div className="re-h-px re-w-full re-flex-shrink-0" />
|
||||
{feed?.map((item, index) => (
|
||||
<FeedItem key={index} item={item} />
|
||||
))}
|
||||
<div className="re-h-px re-w-full re-flex-shrink-0" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export const FilterField = ({ label, children }: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-start",
|
||||
"re-justify-start",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-left",
|
||||
"re-w-20",
|
||||
"re-text-gray-300",
|
||||
"re-capitalize",
|
||||
"re-text-xs",
|
||||
"re-leading-8",
|
||||
"re-flex-shrink-0",
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { ChevronDownIcon } from "./icons/chevron-down";
|
||||
import { CloseIcon } from "./icons/close";
|
||||
|
||||
type FilterInputProps = {
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
onChange: (value?: string) => void;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const FilterInput = ({
|
||||
placeholder,
|
||||
value,
|
||||
onChange,
|
||||
className,
|
||||
}: FilterInputProps) => {
|
||||
return (
|
||||
<input
|
||||
type="text"
|
||||
className={clsx(
|
||||
"re-appearance-none",
|
||||
"re-outline-none",
|
||||
"re-relative",
|
||||
"re-flex",
|
||||
"re-flex-1",
|
||||
"re-rounded",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-bg-gray-900",
|
||||
"re-py-[7px]",
|
||||
"re-px-1.5",
|
||||
"re-text-xs",
|
||||
"re-leading-4",
|
||||
"re-placeholder-gray-500",
|
||||
"re-text-gray-300",
|
||||
className,
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}}
|
||||
onChange={(event) => {
|
||||
if (event.target.value) {
|
||||
onChange(event.target.value);
|
||||
} else {
|
||||
onChange(undefined);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,115 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import Gravatar from "react-gravatar";
|
||||
|
||||
import { getMe } from "src/utils/me";
|
||||
|
||||
import { MeResponse } from "src/interfaces/api";
|
||||
import { logoutUser } from "src/utils/auth";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export const HeaderAuthStatus = () => {
|
||||
const [me, setMe] = React.useState<MeResponse | null>(null);
|
||||
const [logoutVisible, setLogoutVisible] = React.useState(false);
|
||||
const buttonRef = React.useRef<HTMLButtonElement>(null);
|
||||
const navigate = useNavigate();
|
||||
|
||||
React.useEffect(() => {
|
||||
getMe().then((res) => (res ? setMe(res) : null));
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (logoutVisible) {
|
||||
const listener = (e: MouseEvent) => {
|
||||
if (buttonRef.current?.contains(e.target as Node)) return;
|
||||
|
||||
setLogoutVisible(false);
|
||||
};
|
||||
|
||||
document.addEventListener("click", listener);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("click", listener);
|
||||
};
|
||||
}
|
||||
|
||||
return () => 0;
|
||||
}, [logoutVisible]);
|
||||
|
||||
const logout = React.useCallback(() => {
|
||||
logoutUser().then(() => {
|
||||
setTimeout(() => {
|
||||
navigate("/login");
|
||||
}, 100);
|
||||
});
|
||||
}, [navigate]);
|
||||
|
||||
return (
|
||||
<div className={clsx("re-px-2")}>
|
||||
{me && (
|
||||
<button
|
||||
type="button"
|
||||
ref={buttonRef}
|
||||
className={clsx(
|
||||
"re-appearance-none",
|
||||
"re-border-none",
|
||||
"re-bg-none",
|
||||
"relative",
|
||||
"re-w-8",
|
||||
"re-h-8",
|
||||
"re-rounded-full",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-group",
|
||||
)}
|
||||
onClick={() => setLogoutVisible(!logoutVisible)}
|
||||
>
|
||||
<Gravatar
|
||||
email={me?.email ?? ""}
|
||||
size={32}
|
||||
style={{ borderRadius: "50%" }}
|
||||
/>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-top-14",
|
||||
"re-right-2.5",
|
||||
"re-bg-gray-800",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-shadow-xl",
|
||||
"re-drop-shadow-md",
|
||||
"re-rounded",
|
||||
"re-transition-all",
|
||||
"re-duration-100",
|
||||
"re-ease-in-out",
|
||||
"re-origin-top-right",
|
||||
logoutVisible ? "re-scale-y-100" : "re-scale-y-0",
|
||||
logoutVisible ? "re-opacity-100" : "re-opacity-0",
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(
|
||||
"re-block",
|
||||
"re-rounded",
|
||||
"re-m-0",
|
||||
"re-appearance-none",
|
||||
"re-border-none",
|
||||
"re-px-4",
|
||||
"re-py-2",
|
||||
"re-text-xs",
|
||||
"re-text-gray-300",
|
||||
"hover:re-bg-gray-700",
|
||||
)}
|
||||
onClick={logout}
|
||||
>
|
||||
Sign out
|
||||
</button>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,151 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { LogoIcon } from "./icons/logo";
|
||||
import { ContactIcon } from "./icons/contact";
|
||||
import { NotificationIcon } from "./icons/notification";
|
||||
import {
|
||||
DevToolsContext,
|
||||
DevtoolsEvent,
|
||||
receive,
|
||||
} from "@refinedev/devtools-shared";
|
||||
import { HeaderAuthStatus } from "./header-auth-status";
|
||||
|
||||
export const Header = () => {
|
||||
const [connectedApp, setConnectedApp] = React.useState<string | null>(null);
|
||||
const { ws } = React.useContext(DevToolsContext);
|
||||
|
||||
const fetchConnectedApp = React.useCallback(async () => {
|
||||
try {
|
||||
const response = await fetch("api/connected-app");
|
||||
const data = (await response.json()) as { url: string | null };
|
||||
setConnectedApp(data.url);
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
fetchConnectedApp();
|
||||
}, [fetchConnectedApp]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!ws) return () => 0;
|
||||
|
||||
const unsubscribeConnected = receive(
|
||||
ws,
|
||||
DevtoolsEvent.DEVTOOLS_CONNECTED_APP,
|
||||
(data) => {
|
||||
setConnectedApp(data.url);
|
||||
},
|
||||
);
|
||||
|
||||
const unsubscribeDisconnected = receive(
|
||||
ws,
|
||||
DevtoolsEvent.DEVTOOLS_DISCONNECTED_APP,
|
||||
() => {
|
||||
setConnectedApp(null);
|
||||
},
|
||||
);
|
||||
|
||||
return () => {
|
||||
unsubscribeConnected();
|
||||
unsubscribeDisconnected();
|
||||
};
|
||||
}, [ws]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-shrink-0",
|
||||
"re-bg-gray-800",
|
||||
"re-py-2",
|
||||
"re-pr-1",
|
||||
"re-pl-px",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-flex",
|
||||
"re-w-full",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
)}
|
||||
>
|
||||
<div className="re-flex-shrink-0 re-min-w-[200px]">
|
||||
<LogoIcon className="re-h-9" />
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-bg-gray-900",
|
||||
"re-flex-1",
|
||||
"re-border-gray-700",
|
||||
"re-py-1.5",
|
||||
"re-px-2",
|
||||
"re-rounded-lg",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-block",
|
||||
"re-h-2",
|
||||
"re-w-2",
|
||||
"re-rounded-full",
|
||||
connectedApp && "re-bg-alt-green",
|
||||
!connectedApp && "re-bg-alt-red",
|
||||
"re-flex-shrink-0",
|
||||
"re-mr-2",
|
||||
)}
|
||||
/>
|
||||
|
||||
<span className="re-font-mono re-whitespace-nowrap re-text-ellipsis re-overflow-hidden">
|
||||
{connectedApp ?? "No App Connected"}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-end",
|
||||
"re-gap-2",
|
||||
"re-flex-shrink-0",
|
||||
"re-min-w-[200px]",
|
||||
)}
|
||||
>
|
||||
{false && (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-9",
|
||||
"re-h-9",
|
||||
"re-text-gray-500",
|
||||
"re-flex",
|
||||
"re-justify-center",
|
||||
"re-items-center",
|
||||
)}
|
||||
>
|
||||
<ContactIcon />
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-9",
|
||||
"re-h-9",
|
||||
"re-text-gray-500",
|
||||
"re-flex",
|
||||
"re-justify-center",
|
||||
"re-items-center",
|
||||
)}
|
||||
>
|
||||
<NotificationIcon />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<HeaderAuthStatus />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
import React from "react";
|
||||
import HighlightPrism, { Language, defaultProps } from "prism-react-renderer";
|
||||
import theme from "prism-react-renderer/themes/nightOwl";
|
||||
|
||||
type Props = {
|
||||
code: string;
|
||||
language: Language;
|
||||
size?: string;
|
||||
};
|
||||
|
||||
export const Highlight = ({ code, language, size }: Props) => {
|
||||
return (
|
||||
<HighlightPrism
|
||||
{...defaultProps}
|
||||
theme={{
|
||||
plain: {
|
||||
...theme.plain,
|
||||
backgroundColor: "transparent",
|
||||
...(size ? { fontSize: size } : {}),
|
||||
},
|
||||
styles: theme.styles,
|
||||
}}
|
||||
code={code}
|
||||
language={language}
|
||||
>
|
||||
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
||||
<pre className={className} style={style}>
|
||||
{tokens.map((line, i) => (
|
||||
<div key={i} {...getLineProps({ line, key: i })}>
|
||||
{line.map((token, key) => (
|
||||
<span
|
||||
key={key}
|
||||
{...getTokenProps({
|
||||
token,
|
||||
key,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</pre>
|
||||
)}
|
||||
</HighlightPrism>
|
||||
);
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const ArrowCircleRightIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 0.999999 12 0.999999C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 -8.1423e-07 12 -5.24537e-07C5.37258 -2.34843e-07 2.34843e-07 5.37258 5.24537e-07 12C8.1423e-07 18.6274 5.37258 24 12 24ZM10.1464 7.85355C9.95118 7.65829 9.95118 7.34171 10.1464 7.14645C10.3417 6.95118 10.6583 6.95118 10.8536 7.14645L15.3536 11.6464C15.5488 11.8417 15.5488 12.1583 15.3536 12.3536L10.8536 16.8536C10.6583 17.0488 10.3417 17.0488 10.1464 16.8536C9.95118 16.6583 9.95118 16.3417 10.1464 16.1464L14.2929 12L10.1464 7.85355Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const CalendarIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={25}
|
||||
height={24}
|
||||
viewBox="0 0 25 24"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M9.5.75a.75.75 0 0 0-1.5 0v.75h-.3A7.2 7.2 0 0 0 .5 8.7v8.1A7.2 7.2 0 0 0 7.7 24h9.6a7.2 7.2 0 0 0 7.2-7.2V8.7a7.202 7.202 0 0 0-6-7.1v1.527A5.702 5.702 0 0 1 23 8.7v8.1a5.7 5.7 0 0 1-5.7 5.7H7.7A5.7 5.7 0 0 1 2 16.8V8.7A5.7 5.7 0 0 1 7.7 3H8v.75a.75.75 0 0 0 1.5 0v-3Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M17 .75a.75.75 0 0 0-1.5 0v.75H11V3h4.5v.75a.75.75 0 0 0 1.5 0v-3ZM8 12a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9.5 15a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM12.5 12a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM14 15a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM17 12a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,31 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const ChatbotIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M7.5 12.5C8.19035 12.5 8.75 11.9404 8.75 11.25C8.75 10.5596 8.19035 10 7.5 10C6.80965 10 6.25 10.5596 6.25 11.25C6.25 11.9404 6.80965 12.5 7.5 12.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M13.75 11.25C13.75 11.9404 13.1903 12.5 12.5 12.5C11.8097 12.5 11.25 11.9404 11.25 11.25C11.25 10.5596 11.8097 10 12.5 10C13.1903 10 13.75 10.5596 13.75 11.25Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M8.75 15C8.40481 15 8.125 15.2798 8.125 15.625C8.125 15.9702 8.40481 16.25 8.75 16.25H11.25C11.5952 16.25 11.875 15.9702 11.875 15.625C11.875 15.2798 11.5952 15 11.25 15H8.75Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M10.625 3.64332C11.3533 3.38593 11.875 2.6914 11.875 1.87501C11.875 0.839472 11.0355 0 10 0C8.96446 0 8.125 0.839472 8.125 1.87501C8.125 2.6914 8.64674 3.38593 9.375 3.64332V5H5C3.61927 5 2.5 6.11929 2.5 7.5V8.75H1.25C0.559654 8.75 0 9.30964 0 10V15C0 15.6904 0.559654 16.25 1.25 16.25H2.5V17.5C2.5 18.8807 3.61927 20 5 20H15C16.3807 20 17.5 18.8807 17.5 17.5V16.25H18.75C19.4403 16.25 20 15.6904 20 15V10C20 9.30964 19.4403 8.75 18.75 8.75H17.5V7.5C17.5 6.11929 16.3807 5 15 5H10.625V3.64332ZM16.25 17.5C16.25 18.1904 15.6903 18.75 15 18.75H5C4.30965 18.75 3.75 18.1904 3.75 17.5V7.5C3.75 6.80965 4.30965 6.25 5 6.25H15C15.6903 6.25 16.25 6.80965 16.25 7.5V17.5ZM18.75 15H17.5V10H18.75V15ZM2.5 15V10H1.25V15H2.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const CheckAltIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fill="#14141F"
|
||||
fillRule="evenodd"
|
||||
d="M4.293 7.293a1 1 0 0 1 1.414 0L7 8.586l3.293-3.293a1 1 0 1 1 1.414 1.414l-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 0-1.414Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const CheckIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<g fill="currentColor">
|
||||
<path d="M11.354 6.354a.5.5 0 0 0-.708-.708L7 9.293 5.354 7.646a.5.5 0 1 0-.708.708l2 2a.5.5 0 0 0 .708 0l4-4Z" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-1 0A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const CheckboxEmptyIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={12}
|
||||
height={12}
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<rect width={11} height={11} x={0.5} y={0.5} fill="#14141F" rx={2.5} />
|
||||
<rect
|
||||
width={11}
|
||||
height={11}
|
||||
x={0.5}
|
||||
y={0.5}
|
||||
stroke="#303450"
|
||||
rx={2.5}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,20 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const CheckboxFilledIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={12}
|
||||
height={12}
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<rect width={12} height={12} fill="#0080FF" rx={3} />
|
||||
<path
|
||||
stroke="#fff"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="m3 6 2 2 4-4"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,19 +0,0 @@
|
||||
import * as React from "react";
|
||||
|
||||
export const ChevronDownIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M5.047 6.288A.5.5 0 0 1 5.5 6h5a.5.5 0 0 1 .384.82l-2.5 3a.5.5 0 0 1-.768 0l-2.5-3a.5.5 0 0 1-.069-.532Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const CloseIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={12}
|
||||
height={12}
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M4.39 3.86a.375.375 0 1 0-.53.53L5.47 6 3.86 7.61a.375.375 0 0 0 .53.53L6 6.53l1.61 1.61a.375.375 0 0 0 .53-.53L6.53 6l1.61-1.61a.375.375 0 1 0-.53-.53L6 5.47 4.39 3.86Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M12 6A6 6 0 1 1 0 6a6 6 0 0 1 12 0Zm-.75 0A5.25 5.25 0 1 1 .75 6a5.25 5.25 0 0 1 10.5 0Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,31 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const ContactIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M6.25 9.37501C6.94036 9.37501 7.5 8.81536 7.5 8.12501C7.5 7.43466 6.94036 6.87501 6.25 6.87501C5.55964 6.87501 5 7.43466 5 8.12501C5 8.81536 5.55964 9.37501 6.25 9.37501Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M11.25 8.12608C11.25 8.81643 10.6904 9.37607 10 9.37607C9.30964 9.37607 8.75 8.81643 8.75 8.12608C8.75 7.43572 9.30964 6.87608 10 6.87608C10.6904 6.87608 11.25 7.43572 11.25 8.12608Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M13.75 9.37501C14.4404 9.37501 15 8.81536 15 8.12501C15 7.43466 14.4404 6.87501 13.75 6.87501C13.0596 6.87501 12.5 7.43466 12.5 8.12501C12.5 8.81536 13.0596 9.37501 13.75 9.37501Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M3.625 0.626099C1.62297 0.626099 0 2.24907 0 4.2511V12.0011C0 14.0031 1.62297 15.6261 3.625 15.6261H5V17.8584C5 19.2059 6.62918 19.8807 7.582 18.9279L10.8839 15.6261H16.375C18.377 15.6261 20 14.0031 20 12.0011V4.2511C20 2.24907 18.377 0.626099 16.375 0.626099H3.625ZM1.25 4.2511C1.25 2.93942 2.31332 1.8761 3.625 1.8761H16.375C17.6867 1.8761 18.75 2.93942 18.75 4.2511V12.0011C18.75 13.3127 17.6867 14.3761 16.375 14.3761H10.6768C10.4779 14.3761 10.2871 14.4551 10.1464 14.5957L6.69812 18.044C6.53275 18.2094 6.25 18.0923 6.25 17.8584V15.1261C6.25 14.7118 5.91421 14.3761 5.5 14.3761H3.625C2.31332 14.3761 1.25 13.3127 1.25 12.0011V4.2511Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const CopyIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M3.9 0A3.9 3.9 0 0 0 0 3.9v8.6a.5.5 0 0 0 1 0V3.9A2.9 2.9 0 0 1 3.9 1h8.6a.5.5 0 0 0 0-1H3.9Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M5.9 3A2.9 2.9 0 0 0 3 5.9v7.2A2.9 2.9 0 0 0 5.9 16h7.2a2.9 2.9 0 0 0 2.9-2.9V5.9A2.9 2.9 0 0 0 13.1 3H5.9ZM4 5.9C4 4.85 4.85 4 5.9 4h7.2c1.05 0 1.9.85 1.9 1.9v7.2a1.9 1.9 0 0 1-1.9 1.9H5.9A1.9 1.9 0 0 1 4 13.1V5.9Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const FilterIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.70711 6.70711C5.89464 6.89464 6 7.149 6 7.41421V15L10 12V7.41421C10 7.149 10.1054 6.89464 10.2929 6.70711L14.7929 2.20711C14.9255 2.0745 15 1.89464 15 1.70711C15 1.31658 14.6834 1 14.2929 1H1.70711C1.31658 1 1 1.31658 1 1.70711C1 1.89464 1.0745 2.0745 1.20711 2.20711L5.70711 6.70711ZM0 1.70711C0 0.764298 0.764298 0 1.70711 0H14.2929C15.2357 0 16 0.764298 16 1.70711C16 2.15986 15.8201 2.59407 15.5 2.91421L11 7.41421V12C11 12.3148 10.8518 12.6111 10.6 12.8L6.6 15.8C6.29698 16.0273 5.89157 16.0638 5.55279 15.8944C5.214 15.725 5 15.3788 5 15V7.41421L0.5 2.91421C0.179855 2.59407 0 2.15986 0 1.70711Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,17 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const GithubIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={32}
|
||||
height={32}
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M0 16.406C0 7.346 7.164 0 16 0s16 7.346 16 16.406c0 7.245-4.578 13.393-10.932 15.564-.81.16-1.1-.35-1.1-.788 0-.18.003-.493.006-.913.005-.846.013-2.122.013-3.589 0-1.53-.51-2.529-1.086-3.037 3.561-.407 7.305-1.796 7.305-8.096 0-1.79-.62-3.254-1.646-4.403.167-.413.716-2.081-.156-4.341 0 0-1.34-.44-4.395 1.681A14.976 14.976 0 0 0 16 7.933a14.928 14.928 0 0 0-4.006.551c-3.057-2.122-4.4-1.681-4.4-1.681-.867 2.26-.321 3.928-.154 4.34-1.023 1.15-1.648 2.614-1.648 4.404 0 6.284 3.735 7.691 7.288 8.107-.455.41-.871 1.136-1.014 2.195-.912.418-3.227 1.144-4.656-1.364 0 0-.847-1.573-2.453-1.69 0 0-1.56-.021-.109.998 0 0 1.047.505 1.776 2.401 0 0 .938 2.926 5.391 1.934.003.796.01 1.567.015 2.149.004.418.006.741.006.905 0 .435-.294.943-1.094.79C4.584 29.806 0 23.654 0 16.407Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,17 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const GoogleIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={32}
|
||||
height={32}
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M22.614 8.733c-1.703-1.586-3.855-2.4-6.267-2.4-4.264 0-7.874 2.814-9.168 6.614A9.46 9.46 0 0 0 6.662 16c0 1.067.177 2.093.517 3.053 1.294 3.8 4.904 6.614 9.168 6.614 2.207 0 4.074-.587 5.545-1.547 1.716-1.133 2.874-2.8 3.27-4.773h-8.815v-6.014h15.394c.164.974.259 1.974.259 3.027 0 4.867-1.77 8.973-4.85 11.76C24.453 30.56 20.761 32 16.347 32c-6.389 0-11.906-3.6-14.59-8.827A15.542 15.542 0 0 1 0 16c0-2.587.64-5.013 1.757-7.173C4.441 3.6 9.958 0 16.347 0c4.414 0 8.106 1.587 10.926 4.173l-4.66 4.56Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,17 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const HiddenItemsBgIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={40}
|
||||
height={40}
|
||||
viewBox="0 0 40 40"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M2.944 4.03A2.449 2.449 0 0 1 4.03 2.943C5.764 2.065 10.817 0 20 0s14.236 2.065 15.97 2.944c.472.24.847.614 1.086 1.085C37.934 5.764 40 10.817 40 20s-2.065 14.236-2.944 15.97a2.448 2.448 0 0 1-1.085 1.086C34.236 37.934 29.183 40 20 40S5.764 37.935 4.03 37.056a2.449 2.449 0 0 1-1.086-1.085C2.065 34.236 0 29.183 0 20S2.065 5.764 2.944 4.03Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const HorizontalDotsIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={16}
|
||||
height={4}
|
||||
viewBox="0 0 16 4"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M4 2C4 3.10455 3.10455 4 2 4C0.895447 4 0 3.10455 0 2C0 0.895447 0.895447 0 2 0C3.10455 0 4 0.895447 4 2Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M10 2C10 3.10455 9.10455 4 8 4C6.89545 4 6 3.10455 6 2C6 0.895447 6.89545 0 8 0C9.10455 0 10 0.895447 10 2Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M14 4C15.1046 4 16 3.10455 16 2C16 0.895447 15.1046 0 14 0C12.8954 0 12 0.895447 12 2C12 3.10455 12.8954 4 14 4Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,17 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const HourglassIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={12}
|
||||
height={16}
|
||||
viewBox="0 0 12 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2v1.102a2 2 0 0 0 .671 1.495L3.66 7.253a1 1 0 0 1 0 1.494L.671 11.403A2 2 0 0 0 0 12.898V14a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-1.102a2 2 0 0 0-.671-1.495L8.34 8.747a1 1 0 0 1 0-1.494l2.988-2.656A2 2 0 0 0 12 3.102V2Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,43 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const InferencerPreviewIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M12.5243 2.73853C12.5243 4.12721 11.3942 5.25295 10 5.25295C8.60593 5.25295 7.47577 4.12721 7.47577 2.73853C7.47577 1.34986 8.60593 0.224121 10 0.224121C11.3942 0.224121 12.5243 1.34986 12.5243 2.73853ZM11.2622 2.73853C11.2622 3.43287 10.6971 3.99574 10 3.99574C9.30299 3.99574 8.73791 3.43287 8.73791 2.73853C8.73791 2.0442 9.30299 1.48133 10 1.48133C10.6971 1.48133 11.2622 2.0442 11.2622 2.73853Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M13.4605 4.27217C13.6514 3.8453 13.7651 3.37658 13.7838 2.88364C16.8073 4.30022 18.9003 7.36183 18.9003 10.9104C18.9003 11.1625 18.8897 11.4122 18.869 11.659C18.4311 11.4289 17.9668 11.2928 17.5002 11.2443C17.5051 11.1336 17.5076 11.0223 17.5076 10.9104C17.5076 8.0234 15.8653 5.51852 13.4605 4.27217Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M14.0411 17.2139C12.8745 17.9575 11.4878 18.3886 10 18.3886C8.51236 18.3886 7.12574 17.9576 5.95918 17.2141C5.68373 17.5921 5.33334 17.9244 4.91447 18.187C6.35604 19.1885 8.10918 19.7758 10 19.7758C11.891 19.7758 13.6441 19.1885 15.0857 18.1869C14.6669 17.9243 14.3165 17.592 14.0411 17.2139Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M2.49248 10.9104C2.49248 11.0223 2.49495 11.1336 2.49984 11.2444C2.0333 11.2929 1.56899 11.429 1.13107 11.6591C1.11035 11.4122 1.09978 11.1625 1.09978 10.9104C1.09978 7.36174 3.19292 4.30007 6.21649 2.88353C6.2352 3.37648 6.34888 3.8452 6.53983 4.27207C4.13491 5.51839 2.49248 8.02332 2.49248 10.9104Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M19.291 16.2536C19.9881 15.051 19.5744 13.5132 18.367 12.8188C17.1597 12.1245 15.6159 12.5366 14.9188 13.7392C14.2218 14.9418 14.6354 16.4796 15.8428 17.1739C17.0501 17.8683 18.5939 17.4562 19.291 16.2536ZM18.198 15.625C18.5465 15.0237 18.3396 14.2548 17.736 13.9076C17.1323 13.5605 16.3604 13.7665 16.0119 14.3678C15.6633 14.9691 15.8702 15.738 16.4738 16.0852C17.0775 16.4323 17.8494 16.2263 18.198 15.625Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M4.15745 17.1737C2.9501 17.8681 1.40628 17.456 0.709216 16.2534C0.0121555 15.0508 0.425823 13.513 1.63317 12.8186C2.84051 12.1243 4.38434 12.5364 5.0814 13.739C5.77846 14.9416 5.36479 16.4794 4.15745 17.1737ZM3.52638 16.085C2.92271 16.4321 2.15079 16.2261 1.80226 15.6248C1.45373 15.0235 1.66057 14.2546 2.26424 13.9074C2.86791 13.5603 3.63982 13.7663 3.98835 14.3676C4.33688 14.9689 4.13005 15.7378 3.52638 16.085Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const InfoIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<g fill="currentColor">
|
||||
<path d="M8 7a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0V8a1 1 0 0 1 1-1ZM8 6a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16Zm0-1A7 7 0 1 0 8 1a7 7 0 0 0 0 14Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
File diff suppressed because one or more lines are too long
@@ -1,18 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const MaximizeIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
{...props}
|
||||
>
|
||||
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" />
|
||||
</svg>
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const MonitorIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M12.4495 5.3788C12.351 5.149 12.125 5 11.875 5C11.625 5 11.399 5.149 11.3005 5.3788L8.125 12.7884L6.82447 9.7538C6.72598 9.524 6.50002 9.375 6.25 9.375H4.375C4.02982 9.375 3.75 9.65482 3.75 10C3.75 10.3452 4.02982 10.625 4.375 10.625H5.83788L7.55054 14.6212C7.64902 14.851 7.87498 15 8.125 15C8.37502 15 8.60098 14.851 8.69947 14.6212L11.875 7.21162L13.1755 10.2462C13.274 10.476 13.5 10.625 13.75 10.625H15.625C15.9702 10.625 16.25 10.3452 16.25 10C16.25 9.65482 15.9702 9.375 15.625 9.375H14.1621L12.4495 5.3788Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0 6C0 2.68629 2.68629 0 6 0H14C17.3137 0 20 2.68629 20 6V14C20 17.3137 17.3137 20 14 20H6C2.68629 20 0 17.3137 0 14V6ZM6 1.25H14C16.6234 1.25 18.75 3.37665 18.75 6V14C18.75 16.6234 16.6234 18.75 14 18.75H6C3.37665 18.75 1.25 16.6234 1.25 14V6C1.25 3.37665 3.37665 1.25 6 1.25Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const NotificationIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M12.2492 3.5927C12.4099 3.26259 12.5 2.89182 12.5 2.5C12.5 1.11929 11.3807 0 10 0C8.61929 0 7.5 1.11929 7.5 2.5C7.5 2.89182 7.59014 3.26259 7.75081 3.5927C5.76373 4.46051 4.375 6.44308 4.375 8.75V10.5492C4.375 11.2323 4.10362 11.8875 3.62056 12.3706L3.07138 12.9197C2.70553 13.2856 2.5 13.7818 2.5 14.2992C2.5 15.3766 3.37341 16.25 4.45083 16.25H15.5492C16.6266 16.25 17.5 15.3766 17.5 14.2992C17.5 13.7818 17.2945 13.2856 16.9286 12.9197L16.3794 12.3706C15.8964 11.8875 15.625 11.2323 15.625 10.5492V8.75C15.625 6.44308 14.2363 4.46051 12.2492 3.5927ZM11.0234 3.21788C11.1662 3.01473 11.25 2.76715 11.25 2.5C11.25 1.80964 10.6904 1.25 10 1.25C9.30964 1.25 8.75 1.80964 8.75 2.5C8.75 2.76715 8.83381 3.01473 8.97657 3.21788C9.30843 3.15688 9.6505 3.125 10 3.125C10.3495 3.125 10.6916 3.15688 11.0234 3.21788ZM10 4.375C7.58375 4.375 5.625 6.33375 5.625 8.75V10.5492C5.625 11.5638 5.22192 12.537 4.50444 13.2544L3.95527 13.8036C3.82384 13.935 3.75 14.1133 3.75 14.2992C3.75 14.6862 4.06377 15 4.45083 15H15.5492C15.9362 15 16.25 14.6862 16.25 14.2992C16.25 14.1133 16.1762 13.935 16.0447 13.8036L15.4956 13.2544C14.7781 12.537 14.375 11.5638 14.375 10.5492V8.75C14.375 6.33375 12.4162 4.375 10 4.375Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M6.46333 17.5C6.97812 18.9565 8.36717 20 9.99994 20C11.6327 20 13.0218 18.9565 13.5366 17.5H12.1655C11.7332 18.2473 10.9253 18.75 9.99994 18.75C9.07459 18.75 8.26666 18.2473 7.8344 17.5H6.46333Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,31 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const OptionsIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M10.5462 7.5C10.2687 8.57827 9.2899 9.375 8.125 9.375C6.9601 9.375 5.98129 8.57827 5.70376 7.5H4.375C4.02982 7.5 3.75 7.22018 3.75 6.875C3.75 6.52982 4.02982 6.25 4.375 6.25H5.70376C5.98129 5.17173 6.9601 4.375 8.125 4.375C9.2899 4.375 10.2687 5.17173 10.5462 6.25H15.625C15.9702 6.25 16.25 6.52982 16.25 6.875C16.25 7.22018 15.9702 7.5 15.625 7.5H10.5462ZM9.375 6.875C9.375 7.56536 8.81536 8.125 8.125 8.125C7.43464 8.125 6.875 7.56536 6.875 6.875C6.875 6.18464 7.43464 5.625 8.125 5.625C8.81536 5.625 9.375 6.18464 9.375 6.875Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M11.875 15.625C10.7101 15.625 9.73129 14.8283 9.45376 13.75H4.375C4.02982 13.75 3.75 13.4702 3.75 13.125C3.75 12.7798 4.02982 12.5 4.375 12.5H9.45376C9.73129 11.4217 10.7101 10.625 11.875 10.625C13.0399 10.625 14.0187 11.4217 14.2962 12.5H15.625C15.9702 12.5 16.25 12.7798 16.25 13.125C16.25 13.4702 15.9702 13.75 15.625 13.75H14.2962C14.0187 14.8283 13.0399 15.625 11.875 15.625ZM11.875 14.375C11.1846 14.375 10.625 13.8154 10.625 13.125C10.625 12.4346 11.1846 11.875 11.875 11.875C12.5654 11.875 13.125 12.4346 13.125 13.125C13.125 13.8154 12.5654 14.375 11.875 14.375Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M6 0C2.68629 0 0 2.68629 0 6V14C0 17.3137 2.68629 20 6 20H14C17.3137 20 20 17.3137 20 14V6C20 2.68629 17.3137 0 14 0H6ZM14 1.25H6C3.37665 1.25 1.25 3.37665 1.25 6V14C1.25 16.6234 3.37665 18.75 6 18.75H14C16.6234 18.75 18.75 16.6234 18.75 14V6C18.75 3.37665 16.6234 1.25 14 1.25Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,37 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const OverviewIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0 2.91667C0 1.30584 1.30584 0 2.91667 0H5.83333C7.44416 0 8.75 1.30584 8.75 2.91667V5.83333C8.75 7.44416 7.44416 8.75 5.83333 8.75H2.91667C1.30584 8.75 0 7.44416 0 5.83333V2.91667ZM2.91667 1.25H5.83333C6.75381 1.25 7.5 1.99619 7.5 2.91667V5.83333C7.5 6.75381 6.75381 7.5 5.83333 7.5H2.91667C1.99619 7.5 1.25 6.75381 1.25 5.83333V2.91667C1.25 1.99619 1.99619 1.25 2.91667 1.25Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0 14.1667C0 12.5558 1.30584 11.25 2.91667 11.25H5.83333C7.44416 11.25 8.75 12.5558 8.75 14.1667V17.0833C8.75 18.6942 7.44416 20 5.83333 20H2.91667C1.30584 20 0 18.6942 0 17.0833V14.1667ZM2.91667 12.5H5.83333C6.75381 12.5 7.5 13.2462 7.5 14.1667V17.0833C7.5 18.0038 6.75381 18.75 5.83333 18.75H2.91667C1.99619 18.75 1.25 18.0038 1.25 17.0833V14.1667C1.25 13.2462 1.99619 12.5 2.91667 12.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M14.1667 11.25C12.5558 11.25 11.25 12.5558 11.25 14.1667V17.0833C11.25 18.6942 12.5558 20 14.1667 20H17.0833C18.6942 20 20 18.6942 20 17.0833V14.1667C20 12.5558 18.6942 11.25 17.0833 11.25H14.1667ZM17.0833 12.5H14.1667C13.2462 12.5 12.5 13.2462 12.5 14.1667V17.0833C12.5 18.0038 13.2462 18.75 14.1667 18.75H17.0833C18.0038 18.75 18.75 18.0038 18.75 17.0833V14.1667C18.75 13.2462 18.0038 12.5 17.0833 12.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M11.25 2.91667C11.25 1.30584 12.5558 0 14.1667 0H17.0833C18.6942 0 20 1.30584 20 2.91667V5.83333C20 7.44416 18.6942 8.75 17.0833 8.75H14.1667C12.5558 8.75 11.25 7.44416 11.25 5.83333V2.91667ZM14.1667 1.25H17.0833C18.0038 1.25 18.75 1.99619 18.75 2.91667V5.83333C18.75 6.75381 18.0038 7.5 17.0833 7.5H14.1667C13.2462 7.5 12.5 6.75381 12.5 5.83333V2.91667C12.5 1.99619 13.2462 1.25 14.1667 1.25Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const PackageOverviewIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M8.50929 0.351909C9.44771 -0.117303 10.5523 -0.117303 11.4907 0.351909L18.1574 3.68524C19.2867 4.24988 20 5.40409 20 6.66667V13.3333C20 14.5959 19.2867 15.7501 18.1574 16.3148L11.4907 19.6481C10.5523 20.1173 9.44771 20.1173 8.50929 19.6481L1.84262 16.3148C0.713341 15.7501 0 14.5959 0 13.3333V6.66667C0 5.40409 0.713341 4.24988 1.84262 3.68524L8.50929 0.351909ZM9.0683 1.46994C9.65482 1.17669 10.3452 1.17669 10.9317 1.46994L17.5984 4.80328C18.3042 5.15618 18.75 5.87756 18.75 6.66667V13.3333C18.75 14.1224 18.3042 14.8438 17.5984 15.1967L10.9317 18.5301C10.3452 18.8233 9.65482 18.8233 9.0683 18.5301L2.40164 15.1967C1.69584 14.8438 1.25 14.1224 1.25 13.3333V6.66667C1.25 5.87756 1.69584 5.15618 2.40164 4.80328L5.00559 3.5013L12.5772 7.57832C12.9146 7.76 13.125 8.11227 13.125 8.49548L13.125 11.875C13.125 12.2202 13.4048 12.5 13.75 12.5C14.0952 12.5 14.375 12.2202 14.375 11.875L14.375 8.49548C14.375 7.65241 13.9121 6.87743 13.1698 6.47773L6.3727 2.81775L9.0683 1.46994Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,35 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const PlaygroundIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M4.375 4.6875C4.89277 4.6875 5.3125 4.26777 5.3125 3.75C5.3125 3.23223 4.89277 2.8125 4.375 2.8125C3.85723 2.8125 3.4375 3.23223 3.4375 3.75C3.4375 4.26777 3.85723 4.6875 4.375 4.6875Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M8.4375 3.75C8.4375 4.26777 8.01777 4.6875 7.5 4.6875C6.98223 4.6875 6.5625 4.26777 6.5625 3.75C6.5625 3.23223 6.98223 2.8125 7.5 2.8125C8.01777 2.8125 8.4375 3.23223 8.4375 3.75Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M8.56697 11.0669C8.81104 10.8229 8.81105 10.4271 8.56697 10.1831C8.3229 9.93898 7.92717 9.93898 7.68309 10.1831L5.18305 12.6831C5.06584 12.8003 4.99999 12.9592 4.99999 13.125C4.99999 13.2908 5.06584 13.4497 5.18305 13.5669L7.68309 16.0669C7.92717 16.311 8.3229 16.311 8.56697 16.0669C8.81105 15.8229 8.81104 15.4271 8.56697 15.1831L6.50888 13.125L8.56697 11.0669Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M12.317 10.1831C12.0729 9.93898 11.6772 9.93898 11.4331 10.1831C11.189 10.4271 11.189 10.8229 11.4331 11.0669L13.4912 13.125L11.4331 15.1831C11.189 15.4271 11.189 15.8229 11.4331 16.0669C11.6772 16.311 12.0729 16.311 12.317 16.0669L14.817 13.5669C14.9342 13.4497 15 13.2908 15 13.125C15 12.9592 14.9342 12.8003 14.817 12.6831L12.317 10.1831Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M4.5 0C2.01472 0 0 2.01472 0 4.5V14C0 17.3137 2.68629 20 6 20H14C17.3137 20 20 17.3137 20 14V4.5C20 2.01472 17.9853 0 15.5 0H4.5ZM15.5 1.25H4.5C2.70507 1.25 1.25 2.70507 1.25 4.5V6.25H18.75V4.5C18.75 2.70507 17.2949 1.25 15.5 1.25ZM1.25 14V7.5H18.75V14C18.75 16.6234 16.6234 18.75 14 18.75H6C3.37665 18.75 1.25 16.6234 1.25 14Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const PlusCircleIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M8 5a.5.5 0 0 1 .5.5v2h2a.5.5 0 0 1 0 1h-2v2a.5.5 0 0 1-1 0v-2h-2a.5.5 0 0 1 0-1h2v-2A.5.5 0 0 1 8 5Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16Zm0-1A7 7 0 1 0 8 1a7 7 0 0 0 0 14Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,27 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const ResizeHandleIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={10}
|
||||
height={26}
|
||||
viewBox="0 0 10 26"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<rect x={0.5} y={0.5} width={9} height={25} rx={4.5} fill="#1D1E30" />
|
||||
<path
|
||||
d="M7 5C7 6.10457 6.10457 7 5 7C3.89543 7 3 6.10457 3 5C3 3.89543 3.89543 3 5 3C6.10457 3 7 3.89543 7 5Z"
|
||||
fill="#303450"
|
||||
/>
|
||||
<path
|
||||
d="M7 13C7 14.1046 6.10457 15 5 15C3.89543 15 3 14.1046 3 13C3 11.8954 3.89543 11 5 11C6.10457 11 7 11.8954 7 13Z"
|
||||
fill="#303450"
|
||||
/>
|
||||
<path
|
||||
d="M7 21C7 22.1046 6.10457 23 5 23C3.89543 23 3 22.1046 3 21C3 19.8954 3.89543 19 5 19C6.10457 19 7 19.8954 7 21Z"
|
||||
fill="#303450"
|
||||
/>
|
||||
<rect x={0.5} y={0.5} width={9} height={25} rx={4.5} stroke="#303450" />
|
||||
</svg>
|
||||
);
|
||||
@@ -1,35 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const ResourceViewerIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M6 1.25H14C16.6234 1.25 18.75 3.37665 18.75 6V10.2647L20 11.5147V6C20 2.68629 17.3137 0 14 0H6C2.68629 0 0 2.68629 0 6V14C0 17.3137 2.68629 20 6 20H11.5147L10.2647 18.75H6C3.37665 18.75 1.25 16.6234 1.25 14V6C1.25 3.37665 3.37665 1.25 6 1.25Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M17.1728 18.0567C16.5598 18.4933 15.8099 18.75 15 18.75C12.9289 18.75 11.25 17.0711 11.25 15C11.25 12.9289 12.9289 11.25 15 11.25C17.0711 11.25 18.75 12.9289 18.75 15C18.75 15.8099 18.4933 16.5598 18.0567 17.1728L19.8169 18.9331C20.061 19.1771 20.061 19.5729 19.8169 19.8169C19.5729 20.061 19.1771 20.061 18.9331 19.8169L17.1728 18.0567ZM17.5 15C17.5 16.3807 16.3807 17.5 15 17.5C13.6193 17.5 12.5 16.3807 12.5 15C12.5 13.6193 13.6193 12.5 15 12.5C16.3807 12.5 17.5 13.6193 17.5 15Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M4.375 9.375C4.02982 9.375 3.75 9.65482 3.75 10C3.75 10.3452 4.02982 10.625 4.375 10.625H10.625C10.9702 10.625 11.25 10.3452 11.25 10C11.25 9.65482 10.9702 9.375 10.625 9.375H4.375Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M3.75 12.5C3.75 12.1548 4.02982 11.875 4.375 11.875H8.125C8.47018 11.875 8.75 12.1548 8.75 12.5C8.75 12.8452 8.47018 13.125 8.125 13.125H4.375C4.02982 13.125 3.75 12.8452 3.75 12.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M4.375 6.875C4.02982 6.875 3.75 7.15482 3.75 7.5C3.75 7.84518 4.02982 8.125 4.375 8.125H13.125C13.4702 8.125 13.75 7.84518 13.75 7.5C13.75 7.15482 13.4702 6.875 13.125 6.875H4.375Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const SearchIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M11.584 12.29a7 7 0 1 1 .707-.707l3.563 3.563a.5.5 0 0 1-.708.708l-3.562-3.563ZM13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const SettingsIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M13.7789 10C13.7789 12.0711 12.087 13.75 9.9999 13.75C7.9128 13.75 6.22087 12.0711 6.22087 10C6.22087 7.92893 7.9128 6.25 9.9999 6.25C12.087 6.25 13.7789 7.92893 13.7789 10ZM12.5193 10C12.5193 11.3807 11.3913 12.5 9.9999 12.5C8.6085 12.5 7.48055 11.3807 7.48055 10C7.48055 8.61929 8.6085 7.5 9.9999 7.5C11.3913 7.5 12.5193 8.61929 12.5193 10Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M12.8064 0.854715L13.7267 3.59456L16.5781 3.01556C17.1093 2.90769 17.6504 3.14923 17.9215 3.61518L19.5329 6.38482C19.804 6.85077 19.7443 7.4366 19.3845 7.83916L17.4536 10L19.3845 12.1608C19.7443 12.5634 19.804 13.1492 19.5329 13.6152L17.9215 16.3848C17.6504 16.8508 17.1092 17.0923 16.578 16.9844L13.7267 16.4054L12.8064 19.1453C12.6349 19.6557 12.1535 20 11.6113 20H8.38848C7.84627 20 7.3649 19.6557 7.19344 19.1453L6.27309 16.4054L3.42177 16.9844C2.89058 17.0923 2.34942 16.8508 2.07832 16.3848L0.466885 13.6152C0.195783 13.1492 0.255567 12.5634 0.615304 12.1608L2.54627 10L0.615294 7.83916C0.255558 7.43659 0.195773 6.85077 0.466876 6.38482L2.07831 3.61518C2.34941 3.14923 2.89057 2.90769 3.42176 3.01556L6.27309 3.59456L7.19344 0.854715C7.3649 0.344288 7.84627 0 8.38848 0H11.6113C12.1535 0 12.6349 0.344288 12.8064 0.854715ZM7.46813 16.0102C7.26656 15.4101 6.64503 15.054 6.02055 15.1808L3.16923 15.7598L1.5578 12.9902L3.48876 10.8293C3.91167 10.3561 3.91167 9.64392 3.48876 9.17067L1.55779 7.00982L3.16922 4.24018L6.02055 4.81918C6.64503 4.94599 7.26655 4.58991 7.46813 3.98984L8.38848 1.25L11.6113 1.25L12.5317 3.98984C12.7333 4.58991 13.3548 4.94599 13.9793 4.81918L16.8306 4.24018L18.442 7.00982L16.5111 9.17067C16.0881 9.64392 16.0881 10.3561 16.5111 10.8293L18.442 12.9902L16.8306 15.7598L13.9793 15.1808C13.3548 15.054 12.7333 15.4101 12.5317 16.0102L11.6113 18.75L8.38848 18.75L7.46813 16.0102Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,52 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const SidebarActiveIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={40}
|
||||
height={40}
|
||||
viewBox="0 0 40 40"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M2.94445 4.02921C3.18317 3.55814 3.55814 3.18317 4.02921 2.94445C5.76431 2.06517 10.817 0 20 0C29.183 0 34.2357 2.06517 35.9708 2.94445C36.4419 3.18317 36.8168 3.55814 37.0555 4.02921C37.9348 5.76431 40 10.817 40 20C40 29.183 37.9348 34.2357 37.0555 35.9708C36.8168 36.4419 36.4419 36.8168 35.9708 37.0555C34.2357 37.9348 29.183 40 20 40C10.817 40 5.76431 37.9348 4.02921 37.0555C3.55814 36.8168 3.18317 36.4419 2.94445 35.9708C2.06517 34.2357 0 29.183 0 20C0 10.817 2.06517 5.76431 2.94445 4.02921Z"
|
||||
fill="#1D1E30"
|
||||
/>
|
||||
<path
|
||||
d="M2.94445 4.02921C3.18317 3.55814 3.55814 3.18317 4.02921 2.94445C5.76431 2.06517 10.817 0 20 0C29.183 0 34.2357 2.06517 35.9708 2.94445C36.4419 3.18317 36.8168 3.55814 37.0555 4.02921C37.9348 5.76431 40 10.817 40 20C40 29.183 37.9348 34.2357 37.0555 35.9708C36.8168 36.4419 36.4419 36.8168 35.9708 37.0555C34.2357 37.9348 29.183 40 20 40C10.817 40 5.76431 37.9348 4.02921 37.0555C3.55814 36.8168 3.18317 36.4419 2.94445 35.9708C2.06517 34.2357 0 29.183 0 20C0 10.817 2.06517 5.76431 2.94445 4.02921Z"
|
||||
fill="url(#paint0_radial_501_1018)"
|
||||
fillOpacity={0.25}
|
||||
/>
|
||||
<path
|
||||
d="M4.25523 3.39045C5.91991 2.54685 10.8951 0.5 20 0.5C29.1049 0.5 34.0801 2.54685 35.7448 3.39045C36.121 3.58111 36.4189 3.87901 36.6095 4.25523C37.4531 5.91991 39.5 10.8951 39.5 20C39.5 29.1049 37.4531 34.0801 36.6095 35.7448C36.4189 36.121 36.121 36.4189 35.7448 36.6095C34.0801 37.4531 29.1049 39.5 20 39.5C10.8951 39.5 5.91991 37.4531 4.25523 36.6095C3.87901 36.4189 3.58111 36.121 3.39045 35.7448C2.54685 34.0801 0.5 29.1049 0.5 20C0.5 10.8951 2.54685 5.91991 3.39045 4.25523C3.58111 3.87901 3.87901 3.58111 4.25523 3.39045Z"
|
||||
stroke="url(#paint1_linear_501_1018)"
|
||||
strokeOpacity={0.25}
|
||||
/>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id="paint0_radial_501_1018"
|
||||
cx={0}
|
||||
cy={0}
|
||||
r={1}
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(20 20) rotate(90) scale(20)"
|
||||
>
|
||||
<stop stopColor="#47EBEB" />
|
||||
<stop offset={1} stopColor="#303450" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear_501_1018"
|
||||
x1={0}
|
||||
y1={0}
|
||||
x2={40}
|
||||
y2={40}
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#47EBEB" />
|
||||
<stop offset={0.5} stopColor="#303450" stopOpacity={0} />
|
||||
<stop offset={1} stopColor="#47EBEB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,56 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const SlidingBackground = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={48}
|
||||
height={56}
|
||||
viewBox="0 0 48 56"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<g fillOpacity={0.1} clipPath="url(#sliding-background-clip)">
|
||||
<path
|
||||
fill="url(#sliding-background-gradient)"
|
||||
d="M8 0h8l-56 56h-8L8 0Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#sliding-background-gradient)"
|
||||
d="M32 0h-8l-56 56h8L32 0Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#sliding-background-gradient)"
|
||||
d="M40 0h8L-8 56h-8L40 0Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#sliding-background-gradient)"
|
||||
d="M64 0h-8L0 56h8L64 0Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#sliding-background-gradient)"
|
||||
d="M72 0h8L24 56h-8L72 0Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#sliding-background-gradient)"
|
||||
d="M96 0h-8L32 56h8L96 0Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="sliding-background-gradient"
|
||||
x1={-190}
|
||||
x2={-190}
|
||||
y1={0}
|
||||
y2={56}
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="currentColor" stopOpacity={0} />
|
||||
<stop offset={0.5} stopColor="#currentColor" />
|
||||
<stop offset={1} stopColor="#currentColor" stopOpacity={0} />
|
||||
</linearGradient>
|
||||
<clipPath id="sliding-background-clip">
|
||||
<path fill="#fff" d="M0 0h48v56H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,31 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const SnippetsIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M7.5 5.625C7.5 5.27982 7.77982 5 8.125 5H14.375C14.7202 5 15 5.27982 15 5.625C15 5.97018 14.7202 6.25 14.375 6.25H8.125C7.77982 6.25 7.5 5.97018 7.5 5.625Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M7.5 8.125C7.5 7.77982 7.77982 7.5 8.125 7.5H14.375C14.7202 7.5 15 7.77982 15 8.125C15 8.47018 14.7202 8.75 14.375 8.75H8.125C7.77982 8.75 7.5 8.47018 7.5 8.125Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M7.5 10.625C7.5 10.2798 7.77982 10 8.125 10H11.875C12.2202 10 12.5 10.2798 12.5 10.625C12.5 10.9702 12.2202 11.25 11.875 11.25H8.125C7.77982 11.25 7.5 10.9702 7.5 10.625Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M17.5 14.4823V3.125C17.5 1.39911 16.1009 0 14.375 0H3.125C1.39911 0 0 1.39911 0 3.125C0 3.98777 0.350462 4.76988 0.915291 5.33471C1.0325 5.45192 1.19147 5.51777 1.35723 5.51777H5V16.875C5 18.6009 6.39911 20 8.125 20L16.875 20C18.6009 20 20 18.6009 20 16.875C20 16.0123 19.6495 15.2302 19.0847 14.6653C18.9675 14.5481 18.8085 14.4823 18.6428 14.4823L17.5 14.4823ZM3.125 1.25C2.08947 1.25 1.25 2.08947 1.25 3.125C1.25 3.55536 1.39442 3.95117 1.63831 4.26777H5V3.125C5 2.08947 4.16053 1.25 3.125 1.25ZM5.62523 1.25C6.01753 1.77229 6.25 2.4215 6.25 3.125V16.875C6.25 17.9105 7.08947 18.75 8.125 18.75C9.16053 18.75 10 17.9105 10 16.875C10 16.3571 9.79082 15.8892 9.45083 15.5492C9.27208 15.3704 9.21861 15.1016 9.31534 14.868C9.41208 14.6345 9.63998 14.4822 9.89277 14.4822L16.25 14.4823V3.125C16.25 2.08947 15.4105 1.25 14.375 1.25H5.62523ZM10.6252 18.75L16.875 18.75C17.9105 18.75 18.75 17.9106 18.75 16.875C18.75 16.4447 18.6056 16.0489 18.3617 15.7323L11.0343 15.7322C11.1735 16.0862 11.25 16.4718 11.25 16.875C11.25 17.5785 11.0175 18.2277 10.6252 18.75Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,27 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const TicketIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={20}
|
||||
height={20}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M12.5 6.66667C12.8452 6.66667 13.125 6.96514 13.125 7.33333V8.66667C13.125 9.03486 12.8452 9.33333 12.5 9.33333C12.1548 9.33333 11.875 9.03486 11.875 8.66667V7.33333C11.875 6.96514 12.1548 6.66667 12.5 6.66667Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M13.125 11.3333C13.125 10.9651 12.8452 10.6667 12.5 10.6667C12.1548 10.6667 11.875 10.9651 11.875 11.3333V12.6667C11.875 13.0349 12.1548 13.3333 12.5 13.3333C12.8452 13.3333 13.125 13.0349 13.125 12.6667V11.3333Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M20 5.2V7.33333C18.6193 7.33333 17.5 8.52724 17.5 10C17.5 11.4728 18.6193 12.6667 20 12.6667V14.8C20 16.5673 18.6569 18 17 18H3C1.34315 18 0 16.5673 0 14.8V12.6667C1.38071 12.6667 2.5 11.4728 2.5 10C2.5 8.52724 1.38071 7.33333 0 7.33333V5.2C0 3.43269 1.34315 2 3 2H17C18.6569 2 20 3.43269 20 5.2ZM1.25 5.2C1.25 4.16907 2.0335 3.33333 3 3.33333H11.875V4.66667C11.875 5.03486 12.1548 5.33333 12.5 5.33333C12.8452 5.33333 13.125 5.03486 13.125 4.66667V3.33333H17C17.9665 3.33333 18.75 4.16907 18.75 5.2V6.22761C17.2935 6.77672 16.25 8.25838 16.25 10C16.25 11.7416 17.2935 13.2233 18.75 13.7724V14.8C18.75 15.8309 17.9665 16.6667 17 16.6667H13.125V15.3333C13.125 14.9651 12.8452 14.6667 12.5 14.6667C12.1548 14.6667 11.875 14.9651 11.875 15.3333V16.6667H3C2.0335 16.6667 1.25 15.8309 1.25 14.8V13.7724C2.70649 13.2233 3.75 11.7416 3.75 10C3.75 8.25838 2.70649 6.77672 1.25 6.22761V5.2Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const UpdateIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M1.993 4.403A6.996 6.996 0 0 1 8 1a6.995 6.995 0 0 1 5.923 3.267.5.5 0 0 0 .845-.534A7.995 7.995 0 0 0 8 0a7.999 7.999 0 0 0-8 8 .5.5 0 0 0 .724.447l3-1.5a.5.5 0 0 0 .118-.812L1.993 4.403Zm13.77 3.172A.5.5 0 0 1 16 8a8 8 0 0 1-8 8 7.995 7.995 0 0 1-6.768-3.733.5.5 0 1 1 .845-.534A6.995 6.995 0 0 0 8 15a6.996 6.996 0 0 0 6.007-3.403l-1.849-1.732a.5.5 0 0 1 .118-.812l3-1.5a.5.5 0 0 1 .487.022Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const WarningIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fill="#fff"
|
||||
fillRule="evenodd"
|
||||
d="M7 8a1 1 0 1 0 2 0V5a1 1 0 1 0-2 0v3Zm0 3a1 1 0 1 1 2 0 1 1 0 0 1-2 0Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,24 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const InitialLayout = ({ children }: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-bg-gray-900",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-h-auto",
|
||||
"re-p-0",
|
||||
"re-min-h-screen",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
type Props = {
|
||||
label?: string;
|
||||
required?: boolean;
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
onChange?: (value: string) => void;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const Input = ({
|
||||
label,
|
||||
required,
|
||||
placeholder,
|
||||
value,
|
||||
onChange,
|
||||
className,
|
||||
}: Props) => {
|
||||
return (
|
||||
<label className={clsx(className)}>
|
||||
{label && (
|
||||
<span
|
||||
className={clsx(
|
||||
"re-block",
|
||||
"re-mb-2",
|
||||
"re-text-gray-300",
|
||||
"re-text-base",
|
||||
"re-leading-7",
|
||||
"re-font-normal",
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
{required && (
|
||||
<span className="re-text-alt-red">{" * "}</span>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
<input
|
||||
type="text"
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={(e) => onChange?.(e.target.value)}
|
||||
className={clsx(
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-bg-transparent",
|
||||
"re-rounded",
|
||||
"re-placeholder-gray-500",
|
||||
"re-text-gray-300",
|
||||
"re-outline-none",
|
||||
"re-py-2.5",
|
||||
"re-px-3",
|
||||
"re-w-full",
|
||||
)}
|
||||
/>
|
||||
</label>
|
||||
);
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
import ReactJson from "react-json-view";
|
||||
import { MaximizeIcon } from "./icons/maximize";
|
||||
import { Modal } from "./modal";
|
||||
|
||||
export const JsonViewer = ({ data, label }: { data: any; label: string }) => {
|
||||
const [modalVisible, setModalVisible] = React.useState(false);
|
||||
|
||||
return (
|
||||
<div className={clsx("re-relative")}>
|
||||
<ReactJson
|
||||
src={data}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
theme="flat"
|
||||
style={{
|
||||
backgroundColor: "#303450",
|
||||
padding: "8px",
|
||||
borderRadius: "8px",
|
||||
overflow: "auto",
|
||||
maxHeight: "160px",
|
||||
}}
|
||||
collapsed={2}
|
||||
name={false}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setModalVisible(true)}
|
||||
className={clsx(
|
||||
"re-group",
|
||||
"re-absolute",
|
||||
"re-right-2",
|
||||
"re-top-2",
|
||||
"re-bg-gray-900",
|
||||
"re-bg-opacity-50",
|
||||
"hover:re-bg-opacity-75",
|
||||
"re-p-1",
|
||||
"re-rounded",
|
||||
"re-border-0",
|
||||
"re-outline-none",
|
||||
"re-appearance-none",
|
||||
"re-transition-colors",
|
||||
"re-duration-200",
|
||||
"re-ease-in-out",
|
||||
)}
|
||||
>
|
||||
<MaximizeIcon
|
||||
className={clsx(
|
||||
"re-w-4",
|
||||
"re-h-4",
|
||||
"group-hover:re-scale-110",
|
||||
"re-transition-transform",
|
||||
"re-duration-200",
|
||||
"re-ease-in-out",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
<Modal
|
||||
overlay
|
||||
visible={modalVisible}
|
||||
onClose={() => setModalVisible(false)}
|
||||
className={clsx(
|
||||
"re-min-w-[520px]",
|
||||
"re-w-3/4",
|
||||
"re-max-w-[90%]",
|
||||
)}
|
||||
header={
|
||||
<span className={clsx("re-capitalize", "re-font-semibold")}>
|
||||
{label}
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<div className={clsx("re-p-2")}>
|
||||
<ReactJson
|
||||
src={data}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
theme="flat"
|
||||
style={{
|
||||
backgroundColor: "#303450",
|
||||
padding: "8px",
|
||||
borderRadius: "8px",
|
||||
overflow: "auto",
|
||||
maxHeight: "calc(100vh - 96px - 65px - 16px - 2px)",
|
||||
minHeight: "calc(100vh - 96px - 65px - 16px - 2px)",
|
||||
}}
|
||||
collapsed={2}
|
||||
name={false}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
import { Header } from "./header";
|
||||
import { ProjectIdFixBanner } from "./project-id-fix-banner";
|
||||
import { Sidebar } from "./sidebar";
|
||||
|
||||
type Props = React.PropsWithChildren<{}>;
|
||||
|
||||
export const Layout = ({ children }: Props) => {
|
||||
return (
|
||||
<div
|
||||
id="re-devtools-ui-layout"
|
||||
className={clsx(
|
||||
"re-bg-gray-900",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-h-full",
|
||||
)}
|
||||
>
|
||||
<Header />
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-1",
|
||||
"re-w-full",
|
||||
"re-h-full",
|
||||
"re-overflow-hidden",
|
||||
"re-h-[calc(100vh-36px-8px-8px-1px)]",
|
||||
)}
|
||||
>
|
||||
<Sidebar />
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-px-4",
|
||||
"re-pt-4",
|
||||
"md:re-px-6",
|
||||
"md:re-pt-6",
|
||||
"lg:re-px-8",
|
||||
"lg:re-pt-8",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-pb-0",
|
||||
)}
|
||||
>
|
||||
<ProjectIdFixBanner />
|
||||
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
import React from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { setLastLocation } from "src/utils/last-location";
|
||||
|
||||
export const LocationChangeHandler = () => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (
|
||||
typeof window !== "undefined" &&
|
||||
typeof localStorage !== "undefined"
|
||||
) {
|
||||
setLastLocation(pathname);
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -1,153 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { CloseIcon } from "./icons/close";
|
||||
|
||||
type ModalProps = {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
header?: React.ReactNode;
|
||||
footer?: React.ReactNode;
|
||||
overlay?: boolean;
|
||||
};
|
||||
|
||||
export const Modal = ({
|
||||
visible,
|
||||
onClose,
|
||||
className,
|
||||
children,
|
||||
header,
|
||||
footer,
|
||||
overlay,
|
||||
}: ModalProps) => {
|
||||
const [delayedVisible, setDelayedVisible] = React.useState(visible);
|
||||
|
||||
React.useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setDelayedVisible(visible);
|
||||
}, 200);
|
||||
}, [visible]);
|
||||
|
||||
const onCloseInternal = React.useCallback(() => {
|
||||
setDelayedVisible(false);
|
||||
setTimeout(() => {
|
||||
onClose();
|
||||
}, 200);
|
||||
}, [onClose]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-z-10",
|
||||
"re-fixed",
|
||||
"re-left-0",
|
||||
"re-top-0",
|
||||
"re-w-full",
|
||||
"re-h-full",
|
||||
!visible && "re-hidden",
|
||||
visible && "re-block",
|
||||
!visible && "re-pointer-events-none",
|
||||
visible && "re-pointer-events-auto",
|
||||
)}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onCloseInternal();
|
||||
}}
|
||||
>
|
||||
{overlay && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-w-full",
|
||||
"re-h-full",
|
||||
"re-backdrop-blur-sm",
|
||||
"re-bg-gray-900",
|
||||
"re-bg-opacity-50",
|
||||
"re-transition-all",
|
||||
"re-ease-in-out",
|
||||
"re-duration-200",
|
||||
"re-origin-center",
|
||||
!delayedVisible && "re-pointer-events-none",
|
||||
delayedVisible && "re-pointer-events-auto",
|
||||
)}
|
||||
style={{
|
||||
transform: `${
|
||||
delayedVisible ? "scale(1)" : "scale(0)"
|
||||
} translate3d(0,0,0)`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-left-0",
|
||||
"re-top-12",
|
||||
"re-max-h-[calc(100%-48px-48px)]",
|
||||
"re-h-auto",
|
||||
"re-w-[520px]",
|
||||
"re-overflow-auto",
|
||||
"re-border",
|
||||
"re-rounded-2xl",
|
||||
"re-border-gray-700",
|
||||
"re-bg-gray-800",
|
||||
"re-transition-transform",
|
||||
"re-duration-200",
|
||||
"re-ease-in-out",
|
||||
"re-shadow-2xl",
|
||||
delayedVisible && "re-scale-100",
|
||||
!delayedVisible && "re-scale-0",
|
||||
"re-translate-x-[calc(50vw-50%)]",
|
||||
"re-origin-center",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-right-5",
|
||||
"re-top-5",
|
||||
"re-w-6",
|
||||
"re-h-6",
|
||||
)}
|
||||
onClick={onCloseInternal}
|
||||
>
|
||||
<CloseIcon className="re-text-gray-500 re-w-5 re-h-5" />
|
||||
</button>
|
||||
{header && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-py-5",
|
||||
"re-pl-5",
|
||||
"re-pr-10",
|
||||
)}
|
||||
>
|
||||
{header}
|
||||
</div>
|
||||
)}
|
||||
<div className={clsx("re-flex-1", "re-overflow-auto")}>
|
||||
<div className={clsx("re-flex", "re-flex-col")}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
{footer && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-border-t",
|
||||
"re-border-t-gray-700",
|
||||
"re-p-5",
|
||||
)}
|
||||
>
|
||||
{footer}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,140 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { Filters } from "./monitor-filters";
|
||||
import { CloseIcon } from "./icons/close";
|
||||
|
||||
type Props = {
|
||||
filters: Filters;
|
||||
onClear: () => void;
|
||||
};
|
||||
|
||||
const filterLabels: Record<keyof Filters, string> = {
|
||||
scope: "Scope",
|
||||
hook: "Hook",
|
||||
parent: "Parent",
|
||||
resource: "Resource",
|
||||
status: "Status",
|
||||
};
|
||||
|
||||
const filterKeys: (keyof Filters)[] = [
|
||||
"scope",
|
||||
"hook",
|
||||
"resource",
|
||||
"parent",
|
||||
"status",
|
||||
];
|
||||
|
||||
const prettyPrint = (value: string) => {
|
||||
// replace `-` with space and capitalize
|
||||
return value.charAt(0).toUpperCase() + value.slice(1).replace(/-/g, " ");
|
||||
};
|
||||
|
||||
export const MonitorAppliedFilterGroup = ({ filters, onClear }: Props) => {
|
||||
const hasFilters =
|
||||
filters.hook.length > 0 ||
|
||||
filters.scope.length > 0 ||
|
||||
filters.status.length > 0 ||
|
||||
filters.parent.length > 0 ||
|
||||
filters.resource;
|
||||
|
||||
const renderSection = (key: keyof Filters) => {
|
||||
const value = filters[key];
|
||||
const mapValue = typeof value === "string" ? [value] : value;
|
||||
|
||||
if (!value || value.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-py-1",
|
||||
"re-px-2",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-gap-1",
|
||||
"re-border-l",
|
||||
"re-border-l-gray-700",
|
||||
)}
|
||||
>
|
||||
<div className={clsx("re-text-xs", "re-text-gray-300")}>
|
||||
{`${filterLabels[key]}:`}
|
||||
</div>
|
||||
<div className={clsx("re-flex", "re-items-center", "re-gap-1")}>
|
||||
{mapValue?.map((el) => {
|
||||
const prettyValue =
|
||||
key === "scope" ? prettyPrint(el) : el;
|
||||
return (
|
||||
<div
|
||||
key={el}
|
||||
className={clsx(
|
||||
"re-py-0.5",
|
||||
"re-px-1",
|
||||
"re-bg-gray-700",
|
||||
"re-rounded-sm",
|
||||
"re-text-gray-300",
|
||||
"re-text-xs",
|
||||
"re-flex-shrink-0",
|
||||
"re-whitespace-nowrap",
|
||||
"re-break-keep",
|
||||
)}
|
||||
>
|
||||
{prettyValue}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-left-full",
|
||||
"re-top-0",
|
||||
"re-h-full",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-border-l-0",
|
||||
"re-rounded-tr",
|
||||
"re-rounded-br",
|
||||
hasFilters && "re-flex",
|
||||
!hasFilters && "re-hidden",
|
||||
)}
|
||||
>
|
||||
{filterKeys.map((key) => renderSection(key as any))}
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-2",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-border-l",
|
||||
"re-border-l-gray-700",
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(
|
||||
"re-appearance-none",
|
||||
"re-border-none",
|
||||
"re-bg-none",
|
||||
"re-outline-none",
|
||||
"re-p-0",
|
||||
"re-m-0",
|
||||
)}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onClear();
|
||||
}}
|
||||
>
|
||||
<CloseIcon
|
||||
className={clsx("re-text-gray-500", "re-w-4", "re-h-4")}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,447 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { Activity } from "src/interfaces/activity";
|
||||
import { Status } from "./status";
|
||||
import { TraceList } from "./trace-list";
|
||||
import dayjs from "dayjs";
|
||||
import { Owners } from "./owners";
|
||||
import { JsonViewer } from "./json-viewer";
|
||||
import { excludeKeys } from "src/utils/exclude-keys";
|
||||
import { getResourceValue } from "src/utils/get-resource-value";
|
||||
import { ResourceValue } from "./resource-value";
|
||||
import { RefineHook, scopes } from "@refinedev/devtools-shared";
|
||||
import { getOwners } from "src/utils/get-owners";
|
||||
|
||||
export const MonitorDetails = ({ activity }: { activity?: Activity }) => {
|
||||
return (
|
||||
<div className={clsx("re-h-full", "re-text-gray-300", "re-relative")}>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-w-full",
|
||||
"re-h-full",
|
||||
"re-overflow-auto",
|
||||
)}
|
||||
>
|
||||
{activity ? (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-pt-2",
|
||||
"re-pb-4",
|
||||
"re-bg-gray-800",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-rounded-tl-lg",
|
||||
"re-rounded-tr-lg",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-w-full",
|
||||
"re-text-xs",
|
||||
"re-py-1",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-20",
|
||||
"re-flex-shrink-0",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
Resource:
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-capitalize",
|
||||
)}
|
||||
>
|
||||
<ResourceValue
|
||||
resource={getResourceValue(activity)}
|
||||
scope={
|
||||
scopes[
|
||||
activity.hookName as RefineHook
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-w-full",
|
||||
"re-text-xs",
|
||||
"re-py-1",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-20",
|
||||
"re-flex-shrink-0",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
Hook name:
|
||||
</div>
|
||||
<div className={clsx("re-flex-1")}>
|
||||
{activity?.hookName}
|
||||
{activity.type === "query" && (
|
||||
<span
|
||||
className={clsx(
|
||||
"re-ml-2",
|
||||
"re-rounded-xl",
|
||||
"re-py-0.5",
|
||||
"re-px-1",
|
||||
"re-text-[10px]",
|
||||
"re-text-alt-blue",
|
||||
"re-bg-alt-blue",
|
||||
"re-bg-opacity-20",
|
||||
"re-border",
|
||||
"re-border-alt-blue",
|
||||
)}
|
||||
>
|
||||
Query
|
||||
</span>
|
||||
)}
|
||||
{activity.type === "mutation" && (
|
||||
<span
|
||||
className={clsx(
|
||||
"re-ml-2",
|
||||
"re-rounded-xl",
|
||||
"re-py-0.5",
|
||||
"re-px-1",
|
||||
"re-text-[10px]",
|
||||
"re-text-alt-cyan",
|
||||
"re-bg-alt-cyan",
|
||||
"re-bg-opacity-20",
|
||||
"re-border",
|
||||
"re-border-alt-cyan",
|
||||
)}
|
||||
>
|
||||
Mutation
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-w-full",
|
||||
"re-text-xs",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-[72px]",
|
||||
"re-flex-shrink-0",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
Trace:
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"no-scrollbar",
|
||||
"re-overflow-auto",
|
||||
)}
|
||||
>
|
||||
<TraceList trace={activity.trace} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-py-4",
|
||||
"re-px-2",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-text-xs",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-w-full",
|
||||
"re-text-xs",
|
||||
"re-py-1",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-20",
|
||||
"re-flex-shrink-0",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
Status:
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-capitalize",
|
||||
)}
|
||||
>
|
||||
<Status activity={activity} />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-w-full",
|
||||
"re-text-xs",
|
||||
"re-py-1",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-20",
|
||||
"re-flex-shrink-0",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
Created At:
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-capitalize",
|
||||
)}
|
||||
>
|
||||
{dayjs(activity.createdAt).format(
|
||||
"HH:mm:ss:SSS",
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-start",
|
||||
"re-w-full",
|
||||
"re-text-xs",
|
||||
"re-py-1",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-20",
|
||||
"re-flex-shrink-0",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
Updated At:
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-capitalize",
|
||||
)}
|
||||
>
|
||||
{dayjs(activity.updatedAt).format(
|
||||
"HH:mm:ss:SSS",
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={clsx("re-flex", "re-flex-col")}>
|
||||
{getOwners(activity).length > 0 && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-py-4",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-font-semibold",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
Owner(s)
|
||||
</div>
|
||||
<Owners activity={activity} />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-py-4",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-font-semibold",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
Key
|
||||
</div>
|
||||
<JsonViewer
|
||||
data={activity.key ?? []}
|
||||
label="Key"
|
||||
/>
|
||||
</div>
|
||||
{activity.type === "mutation" &&
|
||||
activity.variables && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-py-4",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-font-semibold",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
Variables
|
||||
</div>
|
||||
<JsonViewer
|
||||
data={activity.variables ?? {}}
|
||||
label="Variables"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{activity.state.data && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-py-4",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-font-semibold",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
Data
|
||||
</div>
|
||||
<JsonViewer
|
||||
data={activity.state.data ?? {}}
|
||||
label="Data"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{activity.state.error && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-py-4",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-font-semibold",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
Error
|
||||
</div>
|
||||
<JsonViewer
|
||||
data={activity.state.error ?? {}}
|
||||
label="Error"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{activity.state && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-py-4",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-font-semibold",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
Extra
|
||||
</div>
|
||||
<JsonViewer
|
||||
data={excludeKeys(activity.state, [
|
||||
"data",
|
||||
"error",
|
||||
"status",
|
||||
])}
|
||||
label="Extra"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-full",
|
||||
"re-h-full",
|
||||
"re-flex",
|
||||
"re-justify-center",
|
||||
"re-items-center",
|
||||
"re-text-gray-600",
|
||||
)}
|
||||
>
|
||||
No activity selected
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,339 +0,0 @@
|
||||
import React, { useMemo } from "react";
|
||||
import clsx from "clsx";
|
||||
import { Select } from "./select";
|
||||
import { Button } from "./button";
|
||||
import { FilterIcon } from "./icons/filter";
|
||||
import { FilterInput } from "./filter-input";
|
||||
import { FilterField } from "./filter-field";
|
||||
import { CheckboxGroup } from "./checkbox-group";
|
||||
import { scopes } from "@refinedev/devtools-shared";
|
||||
import { MonitorAppliedFilterGroup } from "./monitor-applied-filter-group";
|
||||
import { Activity } from "src/interfaces/activity";
|
||||
|
||||
export type Filters = {
|
||||
scope: string[];
|
||||
hook: string[];
|
||||
parent: string[];
|
||||
resource: string | undefined;
|
||||
status: Array<"loading" | "success" | "error" | "idle" | "paused">;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
filters: Filters;
|
||||
activities: Activity[];
|
||||
onSubmit: (filters: Filters) => void;
|
||||
};
|
||||
|
||||
const filterScopes = [
|
||||
{
|
||||
label: "Auth",
|
||||
value: "auth",
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
value: "data",
|
||||
},
|
||||
{
|
||||
label: "Access Control",
|
||||
value: "access-control",
|
||||
},
|
||||
{
|
||||
label: "Audit Log",
|
||||
value: "audit-log",
|
||||
},
|
||||
];
|
||||
|
||||
const filterHooks = Object.keys(scopes).map((hookname) => ({
|
||||
label: hookname,
|
||||
value: hookname,
|
||||
}));
|
||||
|
||||
const filterStatus = [
|
||||
{
|
||||
label: "Success",
|
||||
value: "success",
|
||||
},
|
||||
{
|
||||
label: "Error",
|
||||
value: "error",
|
||||
},
|
||||
{
|
||||
label: "Loading",
|
||||
value: "loading",
|
||||
},
|
||||
{
|
||||
label: "Idle",
|
||||
value: "idle",
|
||||
},
|
||||
{
|
||||
label: "Paused",
|
||||
value: "paused",
|
||||
},
|
||||
];
|
||||
|
||||
export const MonitorFilters = ({
|
||||
filters: defaultFilters,
|
||||
activities,
|
||||
onSubmit,
|
||||
}: Props) => {
|
||||
const [filters, setFilters] = React.useState<Filters>(defaultFilters);
|
||||
|
||||
const hasFilters =
|
||||
defaultFilters.hook.length > 0 ||
|
||||
defaultFilters.scope.length > 0 ||
|
||||
defaultFilters.status.length > 0 ||
|
||||
defaultFilters.parent.length > 0 ||
|
||||
defaultFilters.resource;
|
||||
|
||||
const panelRef = React.useRef<HTMLButtonElement>(null);
|
||||
const [panelVisible, setPanelVisible] = React.useState(false);
|
||||
|
||||
const filterParent = useMemo(() => {
|
||||
const traces = activities
|
||||
.map((activity) => activity.trace?.map((t) => t.function))
|
||||
.flatMap((t) => t);
|
||||
|
||||
const tracesUnique = Array.from(new Set(traces)).filter(
|
||||
(t) => !!t,
|
||||
) as string[];
|
||||
|
||||
const tracesWithoutScopes = tracesUnique.filter(
|
||||
(trace) => Object.keys(scopes).includes(trace) === false,
|
||||
);
|
||||
|
||||
tracesWithoutScopes.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
const traceOptions = tracesWithoutScopes.map((trace) => {
|
||||
return {
|
||||
label: trace,
|
||||
value: trace,
|
||||
};
|
||||
});
|
||||
|
||||
return traceOptions;
|
||||
}, [activities]);
|
||||
|
||||
const onApply = () => {
|
||||
onSubmit(filters);
|
||||
setPanelVisible(false);
|
||||
};
|
||||
|
||||
const onToggle = () => {
|
||||
setPanelVisible((p) => !p);
|
||||
};
|
||||
|
||||
const onCancel = () => {
|
||||
setPanelVisible(false);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (panelVisible) {
|
||||
const listener = (event: MouseEvent) => {
|
||||
if (
|
||||
panelRef.current &&
|
||||
!panelRef.current.contains(event.target as Node)
|
||||
) {
|
||||
setPanelVisible(false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("mousedown", listener);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", listener);
|
||||
};
|
||||
}
|
||||
|
||||
return () => 0;
|
||||
}, [panelVisible]);
|
||||
|
||||
return (
|
||||
<Button
|
||||
ref={panelRef}
|
||||
className={clsx(
|
||||
"re-ml-4",
|
||||
"!re-px-2",
|
||||
"!re-py-2",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-gap-2",
|
||||
"re-bg-alt-blue",
|
||||
"re-bg-opacity-[0.15]",
|
||||
"!re-text-alt-blue",
|
||||
"re-relative",
|
||||
hasFilters && "re-rounded-tr-none",
|
||||
hasFilters && "re-rounded-br-none",
|
||||
hasFilters && "re-border-r re-border-r-gray-700",
|
||||
)}
|
||||
onClick={onToggle}
|
||||
>
|
||||
<FilterIcon />
|
||||
<span className="re-text-alt-blue">Filters</span>
|
||||
<MonitorAppliedFilterGroup
|
||||
filters={defaultFilters}
|
||||
onClear={() => {
|
||||
const emptyFilters = {
|
||||
scope: [],
|
||||
hook: [],
|
||||
parent: [],
|
||||
resource: undefined,
|
||||
status: [],
|
||||
};
|
||||
setFilters(emptyFilters);
|
||||
onSubmit(emptyFilters);
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
}}
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-top-10",
|
||||
"re--left-2",
|
||||
"re-z-[2]",
|
||||
"re-transition-[opacity,transform]",
|
||||
"re-duration-200",
|
||||
"re-ease-in-out",
|
||||
"re-origin-top-left",
|
||||
panelVisible
|
||||
? "re-scale-100 re-opacity-100"
|
||||
: "re-scale-0 re-opacity-0",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-shadow-monitor-filters",
|
||||
"re-shadow-gray-900",
|
||||
"re-bg-gray-800",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-rounded",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-w-[600px]",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-p-4",
|
||||
"re-gap-4",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<FilterField label="Scope">
|
||||
<Select
|
||||
type="multiple"
|
||||
value={filters.scope}
|
||||
onChange={(v) =>
|
||||
setFilters((p) => ({
|
||||
...p,
|
||||
scope: v,
|
||||
}))
|
||||
}
|
||||
placeholder="Select Scope"
|
||||
options={filterScopes}
|
||||
/>
|
||||
</FilterField>
|
||||
<FilterField label="Hook">
|
||||
<Select
|
||||
type="multiple"
|
||||
value={filters.hook}
|
||||
onChange={(v) =>
|
||||
setFilters((p) => ({
|
||||
...p,
|
||||
hook: v,
|
||||
}))
|
||||
}
|
||||
placeholder="Select Hook"
|
||||
options={filterHooks}
|
||||
/>
|
||||
</FilterField>
|
||||
<FilterField label="Parent">
|
||||
<Select
|
||||
type="multiple"
|
||||
value={filters.parent}
|
||||
onChange={(v) =>
|
||||
setFilters((p) => ({
|
||||
...p,
|
||||
parent: v,
|
||||
}))
|
||||
}
|
||||
placeholder="Select Parent"
|
||||
options={filterParent}
|
||||
/>
|
||||
</FilterField>
|
||||
<FilterField label="Resource">
|
||||
<FilterInput
|
||||
value={filters.resource}
|
||||
onChange={(v) =>
|
||||
setFilters((p) => ({
|
||||
...p,
|
||||
resource: v,
|
||||
}))
|
||||
}
|
||||
placeholder="Type to filter by Resource"
|
||||
/>
|
||||
</FilterField>
|
||||
<FilterField label="Status">
|
||||
<CheckboxGroup
|
||||
options={filterStatus}
|
||||
onChange={(v) =>
|
||||
setFilters((p) => ({
|
||||
...p,
|
||||
status: v as any,
|
||||
}))
|
||||
}
|
||||
values={filters.status}
|
||||
/>
|
||||
</FilterField>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-5",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onCancel}
|
||||
className={clsx(
|
||||
"re-rounded",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-py-2",
|
||||
"re-px-4",
|
||||
"re-text-xs",
|
||||
"re-capitalize",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onApply}
|
||||
className={clsx(
|
||||
"re-rounded",
|
||||
"re-py-2",
|
||||
"re-px-4",
|
||||
"re-text-xs",
|
||||
"re-capitalize",
|
||||
"re-text-gray-0",
|
||||
"re-bg-brand-blue",
|
||||
)}
|
||||
>
|
||||
Apply filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import React, { useContext } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
DevToolsContext,
|
||||
DevtoolsEvent,
|
||||
receive,
|
||||
} from "@refinedev/devtools-shared";
|
||||
|
||||
export const MonitorHighlightHandler = () => {
|
||||
const navigate = useNavigate();
|
||||
const { ws } = useContext(DevToolsContext);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!ws) return () => 0;
|
||||
|
||||
const unsub = receive(
|
||||
ws,
|
||||
DevtoolsEvent.DEVTOOLS_HIGHLIGHT_IN_MONITOR_ACTION,
|
||||
({ name }) => {
|
||||
if (name) {
|
||||
navigate(`/monitor?highlight=${name}`);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return () => {
|
||||
unsub();
|
||||
};
|
||||
}, [ws, navigate]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -1,209 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { ColumnDef, Table, flexRender } from "@tanstack/react-table";
|
||||
import { Activity } from "src/interfaces/activity";
|
||||
import { ChevronDownIcon } from "./icons/chevron-down";
|
||||
|
||||
type Props = {
|
||||
table: Table<Activity>;
|
||||
columns: ColumnDef<Activity>[];
|
||||
selected: string | null;
|
||||
onSelect: (identifier: string | null) => void;
|
||||
};
|
||||
|
||||
export const MonitorTable = ({ table, columns, selected, onSelect }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<div className={clsx("re-flex-1")}>
|
||||
<table className={clsx("re-w-full", "re-rounded-lg")}>
|
||||
<thead
|
||||
className={clsx(
|
||||
"re-bg-gray-800",
|
||||
"re-rounded-lg",
|
||||
"re-sticky",
|
||||
"re-left-0",
|
||||
"re-top-0",
|
||||
"after:re-h-px",
|
||||
"after:re-w-full",
|
||||
"after:re-absolute",
|
||||
"after:re-left-0",
|
||||
"after:re-bottom-0",
|
||||
"after:re-bg-gray-700",
|
||||
"re-z-[1]",
|
||||
)}
|
||||
>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<tr
|
||||
key={headerGroup.id}
|
||||
className={clsx(
|
||||
"re-border-b",
|
||||
"re-border-gray-700",
|
||||
)}
|
||||
>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<th
|
||||
key={header.id}
|
||||
className={clsx(
|
||||
"re-p-2",
|
||||
"re-text-gray-300",
|
||||
"re-text-xs",
|
||||
"re-font-semibold",
|
||||
"re-text-left",
|
||||
)}
|
||||
style={{
|
||||
minWidth:
|
||||
columns[header.index].minSize,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
{...{
|
||||
className:
|
||||
header.column.getCanSort()
|
||||
? "re-cursor-pointer re-select-none hover:re-underline re-flex re-items-center"
|
||||
: "",
|
||||
onClick:
|
||||
header.column.getToggleSortingHandler(),
|
||||
}}
|
||||
>
|
||||
{flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
{{
|
||||
asc: (
|
||||
<ChevronDownIcon className="re-rotate-180" />
|
||||
),
|
||||
desc: (
|
||||
<ChevronDownIcon className="re-rotate-0" />
|
||||
),
|
||||
}[
|
||||
header.column.getIsSorted() as string
|
||||
] ?? null}
|
||||
</div>
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody>
|
||||
{table.getRowModel().rows.map((row) => {
|
||||
const isSelected =
|
||||
row.original.identifier === selected;
|
||||
|
||||
return (
|
||||
<tr
|
||||
key={row.original.identifier}
|
||||
className={clsx(
|
||||
isSelected && "re-bg-gray-800",
|
||||
!isSelected && "hover:re-bg-gray-800",
|
||||
!isSelected && "hover:re-bg-opacity-50",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-text-gray-300",
|
||||
"last-of-type:re-border-b-0",
|
||||
"re-text-xs",
|
||||
"re-cursor-pointer",
|
||||
)}
|
||||
onClick={() => {
|
||||
onSelect(
|
||||
selected === row.original.identifier
|
||||
? null
|
||||
: row.original.identifier,
|
||||
);
|
||||
}}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<td
|
||||
key={cell.id}
|
||||
className={clsx("re-p-2")}
|
||||
>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext(),
|
||||
)}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-border-t",
|
||||
"re-border-t-gray-700",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-py-2",
|
||||
"re-px-2",
|
||||
"re-sticky",
|
||||
"re-left-0",
|
||||
"re-bottom-0",
|
||||
"re-z-[1]",
|
||||
"re-bg-gray-900",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-gap-2",
|
||||
"re-flex-wrap",
|
||||
)}
|
||||
>
|
||||
<button
|
||||
className={clsx(
|
||||
"re-py-1",
|
||||
"re-px-3",
|
||||
"re-text-xs",
|
||||
"hover:re-bg-gray-800",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-text-gray-300",
|
||||
"re-rounded-2xl",
|
||||
"re-cursor-pointer",
|
||||
)}
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</button>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-break-keep",
|
||||
"re-whitespace-nowrap",
|
||||
"re-text-gray-300",
|
||||
"re-text-xs",
|
||||
)}
|
||||
>
|
||||
{`${
|
||||
table.getState().pagination.pageIndex + 1
|
||||
} of ${table.getPageCount()}`}
|
||||
</span>
|
||||
<button
|
||||
className={clsx(
|
||||
"re-py-1",
|
||||
"re-px-3",
|
||||
"re-text-xs",
|
||||
"hover:re-bg-gray-800",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-text-gray-300",
|
||||
"re-rounded-2xl",
|
||||
"re-cursor-pointer",
|
||||
)}
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
import React from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { logoutUser } from "src/utils/auth";
|
||||
import { getMe } from "src/utils/me";
|
||||
|
||||
export const Onboarded = ({
|
||||
children,
|
||||
fallback,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
fallback: React.ReactNode;
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const [onboarding, setOnboarding] = React.useState<
|
||||
"loading" | "success" | "missing"
|
||||
>("loading");
|
||||
|
||||
const checkOnboarding = React.useCallback(async () => {
|
||||
try {
|
||||
const meResponse = await getMe();
|
||||
if (
|
||||
meResponse?.company &&
|
||||
meResponse?.name &&
|
||||
meResponse?.jobTitle
|
||||
) {
|
||||
setOnboarding("success");
|
||||
} else if (meResponse !== null) {
|
||||
setOnboarding("missing");
|
||||
} else {
|
||||
logoutUser().then(() => {
|
||||
setTimeout(() => {
|
||||
navigate("/login");
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
} catch (_error) {
|
||||
setOnboarding("success");
|
||||
}
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
checkOnboarding();
|
||||
}, [checkOnboarding]);
|
||||
|
||||
if (onboarding === "missing") {
|
||||
return <>{fallback}</>;
|
||||
}
|
||||
|
||||
if (onboarding === "success") {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
import React from "react";
|
||||
import { cleanFilePath } from "src/utils/clean-file-path";
|
||||
import { Activity } from "src/interfaces/activity";
|
||||
import clsx from "clsx";
|
||||
import { getOwners } from "src/utils/get-owners";
|
||||
import { DevToolsContext } from "@refinedev/devtools-shared";
|
||||
|
||||
export const Owners = ({ activity }: { activity: Activity }) => {
|
||||
const { devtoolsUrl } = React.useContext(DevToolsContext);
|
||||
|
||||
const owners = getOwners(activity);
|
||||
|
||||
return (
|
||||
<ul className={clsx("re-list-disc", "re-list-inside")}>
|
||||
{owners.map((owner, i) => {
|
||||
const cleanPath = cleanFilePath(owner.file);
|
||||
|
||||
const openerUrl = `${devtoolsUrl}/open-in-editor/${cleanPath}?line=${
|
||||
owner.line ?? 1
|
||||
}&column=${owner.column ?? 1}`;
|
||||
|
||||
return (
|
||||
<li key={i}>
|
||||
<div
|
||||
className={clsx(
|
||||
"re--ml-2",
|
||||
"re-inline-flex",
|
||||
"re-flex-col",
|
||||
"re-items-start",
|
||||
"re-gap-1",
|
||||
"re-max-w-[calc(100%-20px)]",
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-text-gray-300",
|
||||
"re-font-mono",
|
||||
"re-break-all",
|
||||
)}
|
||||
>
|
||||
{owner.function}
|
||||
</span>
|
||||
<a
|
||||
href={openerUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={clsx(
|
||||
"re-no-underline",
|
||||
"hover:re-underline",
|
||||
"re-text-[10px]",
|
||||
"re-text-gray-500",
|
||||
"re-break-all",
|
||||
)}
|
||||
>
|
||||
{"at "}
|
||||
{cleanPath}
|
||||
{owner.line && `:${owner.line}`}
|
||||
{owner.column && `:${owner.column}`}
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
@@ -1,308 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import {
|
||||
PackageLatestVersionType,
|
||||
PackageType,
|
||||
} from "@refinedev/devtools-shared";
|
||||
import semverDiff from "semver-diff";
|
||||
import { UpdateIcon } from "./icons/update";
|
||||
import { CheckIcon } from "./icons/check";
|
||||
import { InfoIcon } from "./icons/info";
|
||||
import { getLatestInfo } from "src/utils/packages";
|
||||
|
||||
type Props = {
|
||||
item: PackageType;
|
||||
blocked?: boolean;
|
||||
onUpdate: (packageName: string) => Promise<boolean>;
|
||||
onOutdated: (packageName: string) => void;
|
||||
};
|
||||
|
||||
export const PackageItem = ({ item, blocked, onUpdate, onOutdated }: Props) => {
|
||||
const [latestLoading, setLatestLoading] = React.useState(true);
|
||||
const [latestData, setLatestData] =
|
||||
React.useState<PackageLatestVersionType | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
setLatestLoading(true);
|
||||
|
||||
getLatestInfo(item.name)
|
||||
.then((data) => {
|
||||
setLatestData(data);
|
||||
})
|
||||
.catch(() => 0)
|
||||
.finally(() => {
|
||||
setLatestLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const updateKind =
|
||||
latestData && item.currentVersion && latestData.latestVersion
|
||||
? semverDiff(item.currentVersion, latestData.latestVersion)
|
||||
: undefined;
|
||||
|
||||
const hasUpdate = typeof updateKind !== "undefined";
|
||||
|
||||
const [status, setStatus] = React.useState<
|
||||
"idle" | "updating" | "done" | "error"
|
||||
>("idle");
|
||||
|
||||
const icon = React.useMemo(() => {
|
||||
switch (status) {
|
||||
case "updating":
|
||||
return <UpdateIcon className="re-animate-spin" />;
|
||||
case "done":
|
||||
return <CheckIcon />;
|
||||
case "error":
|
||||
return <InfoIcon className="re-rotate-180" />;
|
||||
case "idle":
|
||||
default:
|
||||
return <UpdateIcon />;
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
const statusText = React.useMemo(() => {
|
||||
switch (status) {
|
||||
case "updating":
|
||||
return "Updating";
|
||||
case "done":
|
||||
return "Updated";
|
||||
case "error":
|
||||
return "Error";
|
||||
case "idle":
|
||||
default:
|
||||
return "Update";
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
const updatePackage = React.useCallback(async () => {
|
||||
if (status !== "idle") return;
|
||||
try {
|
||||
setStatus("updating");
|
||||
const response = await onUpdate?.(item.name);
|
||||
|
||||
if (response) {
|
||||
setStatus("done");
|
||||
} else {
|
||||
setStatus("error");
|
||||
}
|
||||
} catch (err) {
|
||||
setStatus("error");
|
||||
//
|
||||
}
|
||||
}, [item.name, status]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (hasUpdate) {
|
||||
onOutdated(item.name);
|
||||
}
|
||||
}, [hasUpdate]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-rounded-lg",
|
||||
"re-bg-gray-900",
|
||||
hasUpdate && "re-bg-package-item-has-updates",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-px-4",
|
||||
"re-pt-4",
|
||||
"re-pb-6",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-3",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-base",
|
||||
"re-leading-8",
|
||||
"re-font-semibold",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
{item.name}
|
||||
</div>
|
||||
{hasUpdate && (
|
||||
<button
|
||||
type="button"
|
||||
disabled={
|
||||
(blocked && status === "idle") ||
|
||||
status !== "idle"
|
||||
}
|
||||
onClick={updatePackage}
|
||||
className={clsx(
|
||||
"re-py-2",
|
||||
"re-pl-2",
|
||||
"re-pr-3",
|
||||
"re-rounded",
|
||||
(status === "idle" || status === "updating") &&
|
||||
"re-bg-alt-blue re-text-alt-blue",
|
||||
status === "done" &&
|
||||
"re-bg-alt-green re-text-alt-green",
|
||||
status === "error" &&
|
||||
"re-bg-alt-red re-text-alt-red",
|
||||
"re-bg-opacity-[0.15]",
|
||||
"re-text-xs",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-flex-shrink-0",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
{icon}
|
||||
<span>{statusText}</span>
|
||||
</button>
|
||||
)}
|
||||
{!hasUpdate && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-gray-500",
|
||||
"re-text-xs",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
{latestLoading ? (
|
||||
<span className="re-block re-h-4 re-w-20 re-bg-gray-700 re-animate-pulse re-rounded-md" />
|
||||
) : (
|
||||
<>
|
||||
<CheckIcon />
|
||||
<span>Up to date</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-xs",
|
||||
"re-leading-5",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
{item.description ?? ""}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-4",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-3",
|
||||
"re-flex-shrink-0",
|
||||
)}
|
||||
>
|
||||
{hasUpdate && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-alt-green",
|
||||
"re-text-xs",
|
||||
"re-leading-5",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-flex-shrink-0",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
<InfoIcon />
|
||||
<span>
|
||||
<span>{"There's a "}</span>
|
||||
<span className="re-font-semibold">
|
||||
{updateKind}
|
||||
</span>
|
||||
<span>{" release "}</span>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-py-1",
|
||||
"re-px-2",
|
||||
"re-rounded",
|
||||
"re-bg-alt-green",
|
||||
"re-bg-opacity-30",
|
||||
"re-text-alt-green",
|
||||
"re-font-mono",
|
||||
"re-font-bold",
|
||||
"re-leading-4",
|
||||
)}
|
||||
>
|
||||
{latestData && latestData.latestVersion
|
||||
? `v${latestData.latestVersion}`
|
||||
: ""}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-gap-2",
|
||||
"re-text-xs",
|
||||
"re-text-gray-500",
|
||||
)}
|
||||
>
|
||||
{item.documentation && (
|
||||
<>
|
||||
<a
|
||||
href={item.documentation}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
documentation
|
||||
</a>
|
||||
<span className="re-font-black re-text-gray-600 re-text-base re-leading-4">
|
||||
·
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
{item.changelog && (
|
||||
<>
|
||||
<a
|
||||
href={item.changelog}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
changelog
|
||||
</a>
|
||||
<span className="re-font-black re-text-gray-600 re-text-base re-leading-4">
|
||||
·
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
<span
|
||||
className={clsx(
|
||||
"re-block",
|
||||
"re-py-1",
|
||||
"re-px-2",
|
||||
"re-rounded",
|
||||
"re-bg-gray-700",
|
||||
"re-text-gray-400",
|
||||
"re-font-mono",
|
||||
"re-font-bold",
|
||||
)}
|
||||
>
|
||||
v{item.currentVersion}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,207 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { Fireworks } from "@fireworks-js/react";
|
||||
import type { FireworksHandlers } from "@fireworks-js/react";
|
||||
import { PackageType } from "@refinedev/devtools-shared";
|
||||
|
||||
import { getInstalledPackages, installPackages } from "src/utils/packages";
|
||||
import { PackageItem } from "src/components/package-item";
|
||||
import { Button } from "./button";
|
||||
import { AddPackageDrawer } from "./add-package-drawer";
|
||||
import { PlusCircleIcon } from "./icons/plus-circle";
|
||||
import { UpdateIcon } from "./icons/update";
|
||||
|
||||
export const Packages = () => {
|
||||
const ref = React.useRef<FireworksHandlers>(null);
|
||||
const [packages, setPackages] = React.useState<PackageType[]>([]);
|
||||
const [visible, setVisible] = React.useState(false);
|
||||
const [outdatedPackages, setOutdatedPackages] = React.useState<string[]>(
|
||||
[],
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
getInstalledPackages().then((data) => {
|
||||
setPackages(data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const fireworks = React.useCallback(() => {
|
||||
if (ref.current) {
|
||||
ref.current.start();
|
||||
setTimeout(() => {
|
||||
ref.current?.waitStop();
|
||||
}, 3000);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const [installingAll, setInstallingAll] = React.useState(false);
|
||||
const [installInProgress, setInstallInProgress] = React.useState(false);
|
||||
|
||||
const onInstall = React.useCallback(async (packagesToInstall: string[]) => {
|
||||
setInstallInProgress(true);
|
||||
const state = await installPackages(packagesToInstall);
|
||||
|
||||
if (state) {
|
||||
fireworks();
|
||||
getInstalledPackages({ force: true }).then((data) => {
|
||||
setPackages(data);
|
||||
});
|
||||
setOutdatedPackages((p) =>
|
||||
p.filter((item) => !packagesToInstall.includes(item)),
|
||||
);
|
||||
}
|
||||
|
||||
setInstallInProgress(false);
|
||||
|
||||
return state;
|
||||
}, []);
|
||||
|
||||
const onOutdated = React.useCallback((packages: string[]) => {
|
||||
setOutdatedPackages((p) => [...p, ...packages]);
|
||||
}, []);
|
||||
|
||||
const onUpdateAll = React.useCallback(async () => {
|
||||
if (installingAll) {
|
||||
return;
|
||||
}
|
||||
setInstallingAll(true);
|
||||
await onInstall(outdatedPackages);
|
||||
setInstallingAll(false);
|
||||
}, [outdatedPackages, installingAll, onInstall]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex-1",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-h-full",
|
||||
"re-w-full",
|
||||
"re-justify-start",
|
||||
"re-mx-auto",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
"re-flex-shrink-0",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-text-gray-0",
|
||||
"re-font-semibold",
|
||||
)}
|
||||
>
|
||||
Package Overview
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-gap-4",
|
||||
)}
|
||||
>
|
||||
<Button
|
||||
onClick={() => setVisible(true)}
|
||||
className={clsx(
|
||||
"re-gap-2",
|
||||
"re-text-alt-blue",
|
||||
"re-bg-alt-blue",
|
||||
"re-bg-opacity-[0.15]",
|
||||
"re-flex-nowrap",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
"!re-px-2",
|
||||
)}
|
||||
>
|
||||
<PlusCircleIcon className="re-text-alt-blue" />
|
||||
<span className="re-text-alt-blue">
|
||||
More packages
|
||||
</span>
|
||||
</Button>
|
||||
{outdatedPackages.length > 0 && (
|
||||
<Button
|
||||
onClick={() => onUpdateAll()}
|
||||
className={clsx(
|
||||
"re-gap-2",
|
||||
"re-text-gray-0",
|
||||
"re-bg-alt-blue",
|
||||
"re-flex-nowrap",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-between",
|
||||
"!re-px-2",
|
||||
)}
|
||||
>
|
||||
<UpdateIcon
|
||||
className={clsx(
|
||||
"re-text-gray-0",
|
||||
installingAll ? "re-animate-spin" : "",
|
||||
)}
|
||||
/>
|
||||
<span className="re-text-gray-0">
|
||||
Update all
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={clsx("re-flex-1", "re-overflow-auto")}>
|
||||
<div
|
||||
className={clsx("re-grid", "re-gap-8", "re-py-8")}
|
||||
style={{
|
||||
gridTemplateColumns:
|
||||
"repeat(auto-fill, minmax(380px, 1fr))",
|
||||
}}
|
||||
>
|
||||
{packages.map((item) => (
|
||||
<PackageItem
|
||||
key={item.name}
|
||||
item={item}
|
||||
onUpdate={(v) => onInstall([v])}
|
||||
onOutdated={(v) => onOutdated([v])}
|
||||
blocked={installInProgress}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AddPackageDrawer
|
||||
installedPackages={packages.map((item) => item.name)}
|
||||
onClose={() => {
|
||||
setVisible(false);
|
||||
getInstalledPackages().then((data) => {
|
||||
setPackages(data);
|
||||
});
|
||||
}}
|
||||
onInstall={(pkgs) => onInstall(pkgs)}
|
||||
dismissOnOverlayClick
|
||||
visible={visible}
|
||||
/>
|
||||
<Fireworks
|
||||
ref={ref}
|
||||
autostart={false}
|
||||
options={{
|
||||
intensity: 38,
|
||||
explosion: 8,
|
||||
}}
|
||||
style={{
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
position: "fixed",
|
||||
zIndex: 99999,
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,114 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { WarningIcon } from "./icons/warning";
|
||||
import { Button } from "./button";
|
||||
import { HourglassIcon } from "./icons/hourglass";
|
||||
import { CheckAltIcon } from "./icons/check-alt";
|
||||
import {
|
||||
fetchNewProjectId,
|
||||
getCurrentProjectIdStatus,
|
||||
updateProjectId,
|
||||
} from "src/utils/project-id";
|
||||
import { ProjectIdFixModal } from "./project-id-fix-modal";
|
||||
|
||||
export const ProjectIdFixBanner = () => {
|
||||
const [projectId, setProjectId] = React.useState<string | null>(null);
|
||||
const [modalVisible, setModalVisible] = React.useState(false);
|
||||
const [status, setStatus] = React.useState<
|
||||
"hidden" | "warning" | "fixing" | "success"
|
||||
>("hidden");
|
||||
|
||||
const getProjectIdStatus = React.useCallback(async () => {
|
||||
getCurrentProjectIdStatus().then((s) => {
|
||||
if (s || typeof s === "undefined") {
|
||||
setStatus("hidden");
|
||||
} else {
|
||||
setStatus("warning");
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const getNewProjectId = React.useCallback(async () => {
|
||||
const newProjectId = await fetchNewProjectId();
|
||||
|
||||
if (newProjectId) {
|
||||
setProjectId(newProjectId);
|
||||
}
|
||||
|
||||
return newProjectId;
|
||||
}, []);
|
||||
|
||||
const fixProjectId = React.useCallback(async () => {
|
||||
setStatus("fixing");
|
||||
const newProjectId = await getNewProjectId();
|
||||
if (!newProjectId) {
|
||||
setStatus("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await updateProjectId(newProjectId);
|
||||
if (response) {
|
||||
setStatus("success");
|
||||
setTimeout(() => {
|
||||
setStatus("hidden");
|
||||
}, 2000);
|
||||
} else {
|
||||
setModalVisible(true);
|
||||
}
|
||||
}, [getNewProjectId]);
|
||||
|
||||
React.useEffect(() => {
|
||||
getProjectIdStatus();
|
||||
}, [getProjectIdStatus]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
status === "hidden" && "re-hidden",
|
||||
status === "warning" && "re-bg-project-id-warning",
|
||||
status === "fixing" && "re-bg-project-id-loading",
|
||||
status === "success" && "re-bg-project-id-success",
|
||||
"re-mb-4",
|
||||
"re-px-5",
|
||||
"re-h-14",
|
||||
"re-rounded-lg",
|
||||
"re-bg-gray-800",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-gap-3",
|
||||
"re-flex-shrink-0",
|
||||
)}
|
||||
>
|
||||
{status === "warning" && (
|
||||
<WarningIcon className="re-text-alt-red" />
|
||||
)}
|
||||
{status === "fixing" && (
|
||||
<HourglassIcon className="re-text-alt-blue re-w-4 re-animate-pulse-spin" />
|
||||
)}
|
||||
{status === "success" && (
|
||||
<CheckAltIcon className="re-text-alt-green" />
|
||||
)}
|
||||
<span className={clsx("re-text-xs", "re-text-gray-0")}>
|
||||
{status === "warning" &&
|
||||
"Project ID is missing. Fix it to not miss out any features of the devtools!"}
|
||||
{status === "fixing" && "Please wait while fixing..."}
|
||||
{status === "success" && "Fixing completed!"}
|
||||
</span>
|
||||
{status === "warning" && (
|
||||
<Button className={clsx("re-ml-3")} onClick={fixProjectId}>
|
||||
Fix it
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<ProjectIdFixModal
|
||||
visible={modalVisible}
|
||||
projectId={projectId ?? ""}
|
||||
onClose={() => {
|
||||
setModalVisible(false);
|
||||
setStatus("hidden");
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,271 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { Modal } from "./modal";
|
||||
import { CheckAltIcon } from "./icons/check-alt";
|
||||
import { CopyIcon } from "./icons/copy";
|
||||
import { Highlight } from "./highlight";
|
||||
|
||||
const getRefineComponentText = (projectId: string) => {
|
||||
return `
|
||||
const App = () => {
|
||||
return (
|
||||
<Refine
|
||||
options={{
|
||||
projectId: "${projectId}",
|
||||
}}
|
||||
>
|
||||
{/* ... */}
|
||||
</Refine>
|
||||
);
|
||||
}
|
||||
`.trim();
|
||||
};
|
||||
|
||||
const getPackageJsonText = (projectId: string) => {
|
||||
return `
|
||||
{
|
||||
"name": "your-project",
|
||||
"refine": {
|
||||
"projectId": "${projectId}"
|
||||
}
|
||||
}
|
||||
`.trim();
|
||||
};
|
||||
|
||||
type Props = {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
export const ProjectIdFixModal = ({ visible, onClose, projectId }: Props) => {
|
||||
const [copied, setCopied] = React.useState(false);
|
||||
|
||||
const onCopy = React.useCallback(() => {
|
||||
if (projectId) {
|
||||
if (navigator.clipboard) {
|
||||
try {
|
||||
navigator.clipboard.writeText(projectId);
|
||||
setCopied(true);
|
||||
} catch (_) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [projectId]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (copied) {
|
||||
setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 1000);
|
||||
}
|
||||
}, [copied]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
onClose={onClose}
|
||||
overlay
|
||||
header={
|
||||
<div
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-4",
|
||||
"re-w-[calc(100%+20px)]",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-gray-300",
|
||||
"re-font-semibold",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
)}
|
||||
>
|
||||
Project ID
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-rounded-lg",
|
||||
"re-py-2",
|
||||
"re-px-4",
|
||||
"re-text-gray-0",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-font-mono",
|
||||
"re-bg-gray-700",
|
||||
"re-relative",
|
||||
)}
|
||||
>
|
||||
{projectId}
|
||||
<button
|
||||
type="button"
|
||||
onClick={onCopy}
|
||||
className={clsx(
|
||||
"re-w-8",
|
||||
"re-h-8",
|
||||
"re-rounded-lg",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-absolute",
|
||||
"re-right-1",
|
||||
"re-top-1",
|
||||
"re-bg-gray-800",
|
||||
"re-bg-opacity-75",
|
||||
"re-opacity-50",
|
||||
"hover:re-opacity-100",
|
||||
"re-transition-opacity",
|
||||
"re-ease-in-out",
|
||||
"re-duration-150",
|
||||
)}
|
||||
>
|
||||
{copied ? (
|
||||
<CheckAltIcon className="re-text-alt-green" />
|
||||
) : (
|
||||
<CopyIcon className="re-text-gray-300" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
"re-text-gray-400",
|
||||
)}
|
||||
>
|
||||
We could not add the project id to your project due to
|
||||
an error. You can follow these steps to add project id
|
||||
yourself
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className={clsx("re-flex", "re-flex-col")}>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-p-5",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-base",
|
||||
"re-text-gray-400",
|
||||
"re-leading-7",
|
||||
"re-flex",
|
||||
"re-gap-1",
|
||||
)}
|
||||
>
|
||||
<span className="re-text-gray-300 re-font-semibold">
|
||||
{"1)"}
|
||||
</span>
|
||||
<span>Add it to your</span>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-rounded",
|
||||
"re-text-sm",
|
||||
"re-leading-5",
|
||||
"re-bg-gray-700",
|
||||
"re-px-1.5",
|
||||
"re-py-1",
|
||||
"re-font-mono",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
package.json
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-4",
|
||||
"re-rounded-lg",
|
||||
"re-bg-gray-700",
|
||||
)}
|
||||
>
|
||||
<Highlight
|
||||
language="json"
|
||||
size="12px"
|
||||
code={getPackageJsonText(projectId ?? "")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-border-b",
|
||||
"re-border-b-gray-700",
|
||||
"re-p-5",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-text-base",
|
||||
"re-text-gray-400",
|
||||
"re-leading-7",
|
||||
"re-flex",
|
||||
"re-gap-1",
|
||||
)}
|
||||
>
|
||||
<span className="re-text-gray-300 re-font-semibold">
|
||||
{"2)"}
|
||||
</span>
|
||||
<span>Add it to your</span>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-rounded",
|
||||
"re-text-sm",
|
||||
"re-leading-5",
|
||||
"re-bg-gray-700",
|
||||
"re-px-1.5",
|
||||
"re-py-1",
|
||||
"re-font-mono",
|
||||
"re-text-gray-300",
|
||||
)}
|
||||
>
|
||||
{"<Refine />"}
|
||||
</span>
|
||||
<span>component</span>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-4",
|
||||
"re-rounded-lg",
|
||||
"re-bg-gray-700",
|
||||
"re-text-xs",
|
||||
)}
|
||||
>
|
||||
<Highlight
|
||||
size="12px"
|
||||
language="jsx"
|
||||
code={getRefineComponentText(projectId ?? "")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-p-5",
|
||||
"re-flex",
|
||||
"re-flex-col",
|
||||
"re-gap-2",
|
||||
"re-text-gray-400",
|
||||
"re-text-sm",
|
||||
"re-leading-6",
|
||||
)}
|
||||
>
|
||||
{
|
||||
"That's it! You're now ready for the upcoming features of the refine devtools!"
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -1,112 +0,0 @@
|
||||
import React from "react";
|
||||
import { acknowledgeRaffle, raffle } from "src/utils/me";
|
||||
import { Modal } from "./modal";
|
||||
import clsx from "clsx";
|
||||
import { CalendarIcon } from "./icons/calendar";
|
||||
|
||||
const CALENDLY_URL = "#";
|
||||
|
||||
export const RaffleHandler = () => {
|
||||
const [ran, setRan] = React.useState(false);
|
||||
const [calendlyURL, setCalendlyURL] = React.useState("");
|
||||
const [raffleModal, setRaffleModal] = React.useState(false);
|
||||
|
||||
const submitRaffle = React.useCallback(async () => {
|
||||
const response = await raffle();
|
||||
|
||||
if (response.raffle) {
|
||||
setCalendlyURL(response.calendlyURL);
|
||||
setRaffleModal(true);
|
||||
} else {
|
||||
setRaffleModal(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onCloseModal = React.useCallback(() => {
|
||||
acknowledgeRaffle();
|
||||
setRaffleModal(false);
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
const time = 60 * 1000 * (ran ? 5 : 0.5);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
submitRaffle();
|
||||
if (!ran) {
|
||||
setRan(true);
|
||||
}
|
||||
}, time);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [ran]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
overlay
|
||||
visible={raffleModal}
|
||||
onClose={onCloseModal}
|
||||
header={
|
||||
<div className={clsx("re-flex")}>
|
||||
<h1
|
||||
className={clsx(
|
||||
"re-text-gray-300",
|
||||
"re-font-semibold",
|
||||
"re-text-lg",
|
||||
)}
|
||||
>
|
||||
{"Let's chat!"}
|
||||
</h1>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={clsx("re-p-5", "re-flex", "re-flex-col", "re-gap-5")}
|
||||
>
|
||||
<img
|
||||
src="https://refine.ams3.cdn.digitaloceanspaces.com/devtools/refine-swag.webp"
|
||||
className={clsx(
|
||||
"re-hidden",
|
||||
"tall:re-block",
|
||||
"re-w-full",
|
||||
"re-h-auto",
|
||||
"re-object-cover",
|
||||
"re-rounded-lg",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-overflow-hidden",
|
||||
)}
|
||||
/>
|
||||
<p className={clsx("re-text-base", "re-text-gray-300")}>
|
||||
At Refine, we believe in the power of small conversations
|
||||
with our users, your experiences shape our improvements.
|
||||
</p>
|
||||
<p className={clsx("re-text-base", "re-text-gray-300")}>
|
||||
Book a 15-minute meeting with Civan, our CEO, and recieve
|
||||
our swag Kit as a thank you gift!
|
||||
</p>
|
||||
<a
|
||||
href={calendlyURL}
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-gap-4",
|
||||
"re-text-gray-0",
|
||||
"re-text-base",
|
||||
"re-w-full",
|
||||
"re-p-3",
|
||||
"re-rounded",
|
||||
"re-bg-brand-blue",
|
||||
)}
|
||||
>
|
||||
<CalendarIcon />
|
||||
<span>Book Now</span>
|
||||
</a>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from "react";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export const RelativeTimeValue = ({
|
||||
value,
|
||||
...props
|
||||
}: {
|
||||
value: number;
|
||||
} & React.HTMLAttributes<HTMLSpanElement>) => {
|
||||
const [time, setTime] = React.useState(dayjs(value).format("HH:mm:ss:SSS"));
|
||||
|
||||
React.useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setTime(dayjs(value).fromNow());
|
||||
}, 10000);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [value]);
|
||||
|
||||
return <span {...props}>{time}</span>;
|
||||
};
|
||||
@@ -1,134 +0,0 @@
|
||||
import React from "react";
|
||||
import { ResizeHandleIcon } from "./icons/resize-handle";
|
||||
import clsx from "clsx";
|
||||
|
||||
type Props = {
|
||||
left: React.ReactNode;
|
||||
right: React.ReactNode;
|
||||
leftClassName?: string;
|
||||
rightClassName?: string;
|
||||
className?: string;
|
||||
defaultPercentage?: number;
|
||||
maxPercentage?: number;
|
||||
};
|
||||
|
||||
export const ResizablePane = ({
|
||||
left,
|
||||
right,
|
||||
leftClassName,
|
||||
rightClassName,
|
||||
className,
|
||||
defaultPercentage = 60,
|
||||
maxPercentage = 75,
|
||||
}: Props) => {
|
||||
const [viewPercentage, setViewPercentage] =
|
||||
React.useState(defaultPercentage);
|
||||
const [resizing, setResizing] = React.useState(false);
|
||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleMouseUp = () => {
|
||||
setResizing(false);
|
||||
};
|
||||
|
||||
if (resizing !== null) {
|
||||
window.addEventListener("mouseup", handleMouseUp);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}, [resizing]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
if (resizing) {
|
||||
const containerRect =
|
||||
containerRef.current?.getBoundingClientRect();
|
||||
|
||||
if (!containerRect) return;
|
||||
|
||||
const newViewPercentage = Math.min(
|
||||
maxPercentage,
|
||||
Math.max(
|
||||
100 - maxPercentage,
|
||||
((e.clientX - containerRect.left) /
|
||||
containerRect.width) *
|
||||
100,
|
||||
),
|
||||
);
|
||||
|
||||
setViewPercentage(newViewPercentage);
|
||||
}
|
||||
};
|
||||
|
||||
if (resizing !== null) {
|
||||
window.addEventListener("mousemove", handleMouseMove);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("mousemove", handleMouseMove);
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}, [resizing]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const currentCursor = document.body.style.cursor;
|
||||
|
||||
if (resizing) {
|
||||
document.body.style.cursor = "col-resize";
|
||||
} else {
|
||||
document.body.style.cursor = "auto";
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.body.style.cursor = currentCursor;
|
||||
};
|
||||
}, [resizing]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx("re-flex-1", "re-grid", className)}
|
||||
style={{
|
||||
gridTemplateColumns: `minmax(0, ${
|
||||
viewPercentage / 100
|
||||
}fr) 16px minmax(0, ${(100 - viewPercentage) / 100}fr)`,
|
||||
}}
|
||||
ref={containerRef}
|
||||
>
|
||||
<div className={leftClassName}>{left}</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-4",
|
||||
"re-flex-shrink-0",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(
|
||||
"re-h-full",
|
||||
"re-w-2.5",
|
||||
"re-appearance-none",
|
||||
"re-outline-none",
|
||||
"re-bg-transparent",
|
||||
"re-border-0",
|
||||
"re-cursor-col-resize",
|
||||
)}
|
||||
onMouseDown={(event) => {
|
||||
setResizing(true);
|
||||
event.preventDefault();
|
||||
}}
|
||||
>
|
||||
<ResizeHandleIcon />
|
||||
</button>
|
||||
</div>
|
||||
<div className={rightClassName}>{right}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import { Scopes } from "@refinedev/devtools-shared";
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
export type Props = {
|
||||
resource: string;
|
||||
scope: Scopes;
|
||||
};
|
||||
|
||||
export const ResourceValue: React.FC<Props> = ({ resource, scope }) => {
|
||||
if (scope === "auth") {
|
||||
return (
|
||||
<span
|
||||
className={clsx(
|
||||
"re-rounded-xl",
|
||||
"re-py-0.5",
|
||||
"re-px-1",
|
||||
"re-text-[10px]",
|
||||
"re-text-alt-pink",
|
||||
"re-bg-alt-pink",
|
||||
"re-bg-opacity-20",
|
||||
"re-border",
|
||||
"re-border-alt-pink",
|
||||
)}
|
||||
>
|
||||
Auth
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return <>{resource}</>;
|
||||
};
|
||||
@@ -1,242 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { ChevronDownIcon } from "./icons/chevron-down";
|
||||
import { CloseIcon } from "./icons/close";
|
||||
|
||||
type SelectCommonProps = {
|
||||
placeholder?: string;
|
||||
hint?: string;
|
||||
className?: string;
|
||||
options: {
|
||||
label: string;
|
||||
value: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
type SelectSingleProps = {
|
||||
type: "single";
|
||||
value?: string;
|
||||
onChange?: (value: string | undefined) => void;
|
||||
};
|
||||
|
||||
type SelectMultiProps = {
|
||||
type: "multiple";
|
||||
value?: string[];
|
||||
onChange?: (value: string[]) => void;
|
||||
};
|
||||
|
||||
type SelectProps<TType extends "multiple" | "single"> = SelectCommonProps &
|
||||
(TType extends "multiple" ? SelectMultiProps : SelectSingleProps);
|
||||
|
||||
export const Select = <TType extends "multiple" | "single">({
|
||||
type,
|
||||
options,
|
||||
placeholder,
|
||||
hint,
|
||||
value,
|
||||
onChange,
|
||||
className,
|
||||
}: SelectProps<TType>) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-relative",
|
||||
"re-flex",
|
||||
"re-flex-1",
|
||||
"re-rounded",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-bg-gray-900",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-z-[2]",
|
||||
"re-min-h-[32px]",
|
||||
"re-h-full",
|
||||
"re-flex-1",
|
||||
"re-py-1.5",
|
||||
"re-pl-1.5",
|
||||
"re-pr-8",
|
||||
"re-pointer-events-none",
|
||||
"re-flex",
|
||||
"re-flex-wrap",
|
||||
"re-items-center",
|
||||
"re-gap-2",
|
||||
)}
|
||||
>
|
||||
{((Array.isArray(value) && value.length === 0) || !value) && (
|
||||
<span
|
||||
className={clsx(
|
||||
"re-text-gray-500",
|
||||
"re-text-xs",
|
||||
"re-leading-4",
|
||||
)}
|
||||
>
|
||||
{placeholder}
|
||||
</span>
|
||||
)}
|
||||
{type === "multiple" && (
|
||||
<>
|
||||
{(value as string[])?.map((item) => (
|
||||
<div
|
||||
key={item}
|
||||
className={clsx(
|
||||
"re-py-0.5",
|
||||
"re-pl-2",
|
||||
"re-pr-1",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-flex-nowrap",
|
||||
"re-gap-2",
|
||||
"re-rounded-sm",
|
||||
"re-bg-gray-800",
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={clsx(
|
||||
"re-text-gray-300",
|
||||
"re-text-xs",
|
||||
"re-whitespace-nowrap",
|
||||
"re-break-keep",
|
||||
)}
|
||||
>
|
||||
{
|
||||
options?.find((i) => i.value === item)
|
||||
?.label
|
||||
}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (type === "multiple") {
|
||||
const newValue = [
|
||||
...((value as string[]) ?? []),
|
||||
].filter((v) => v !== item);
|
||||
onChange?.(newValue as any);
|
||||
}
|
||||
}}
|
||||
className={clsx(
|
||||
"re-pointer-events-auto",
|
||||
"re-text-gray-500",
|
||||
"re-flex-shrink-0",
|
||||
"re-appearance-none",
|
||||
"re-outline-none",
|
||||
"re-border-none",
|
||||
"re-bg-none",
|
||||
"re-px-0",
|
||||
"re-py-0.5",
|
||||
)}
|
||||
>
|
||||
<CloseIcon />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
{type === "single" && value && (
|
||||
<span
|
||||
className={clsx(
|
||||
"re-text-gray-300",
|
||||
"re-text-xs",
|
||||
"re-leading-4",
|
||||
)}
|
||||
>
|
||||
{options?.find((i) => i.value === value)?.label}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{type === "single" && value ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
onChange?.(undefined as any);
|
||||
}}
|
||||
className={clsx(
|
||||
"re-z-[2]",
|
||||
"re-appearance-none",
|
||||
"re-border-none",
|
||||
"re-bg-none",
|
||||
"re-pointer-events-auto",
|
||||
"re-absolute",
|
||||
"re-right-0",
|
||||
"re-h-full",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-p-2",
|
||||
"re-text-gray-500",
|
||||
)}
|
||||
>
|
||||
<CloseIcon />
|
||||
</button>
|
||||
) : (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-pointer-events-none",
|
||||
"re-absolute",
|
||||
"re-right-0",
|
||||
"re-h-full",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-p-2",
|
||||
"re-text-gray-700",
|
||||
)}
|
||||
>
|
||||
<ChevronDownIcon />
|
||||
</div>
|
||||
)}
|
||||
<select
|
||||
id="filter-1"
|
||||
className={clsx(
|
||||
"re-opacity-0",
|
||||
"re-w-full",
|
||||
"re-h-full",
|
||||
"re-absolute",
|
||||
"re-left-0",
|
||||
"re-top-0",
|
||||
"re-bg-none",
|
||||
"re-bg-transparent",
|
||||
"re-appearance-none",
|
||||
"re-border-none",
|
||||
"re-outline-none",
|
||||
)}
|
||||
value=""
|
||||
onChange={(event) => {
|
||||
if (!event.target.value) return;
|
||||
|
||||
if (type === "multiple") {
|
||||
const newValue = [
|
||||
...((value as any) ?? []),
|
||||
event.target.value,
|
||||
];
|
||||
|
||||
onChange?.(newValue as any);
|
||||
} else {
|
||||
const newValue = event.target.value;
|
||||
|
||||
onChange?.(newValue as any);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<option value="" selected disabled>
|
||||
{hint ?? placeholder ?? ""}
|
||||
</option>
|
||||
{(type === "multiple"
|
||||
? options.filter((i) => !value?.includes(i.value))
|
||||
: options
|
||||
).map((option) => (
|
||||
<option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,447 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { OverviewIcon } from "./icons/overview";
|
||||
import { MonitorIcon } from "./icons/monitor";
|
||||
// import { ResourceViewerIcon } from "./icons/resource-viewer";
|
||||
// import { PackageOverviewIcon } from "./icons/package-overview";
|
||||
// import { OptionsIcon } from "./icons/options";
|
||||
import { PlaygroundIcon } from "./icons/playground";
|
||||
import { InferencerPreviewIcon } from "./icons/inferencer-preview";
|
||||
// import { SnippetsIcon } from "./icons/snippets";
|
||||
import { ChatbotIcon } from "./icons/chatbot";
|
||||
// import { TicketIcon } from "./icons/ticket";
|
||||
// import { SettingsIcon } from "./icons/settings";
|
||||
|
||||
import { NavLink, useLocation } from "react-router-dom";
|
||||
import { HiddenItemsBgIcon } from "./icons/hidden-items-bg";
|
||||
import { ActiveItemBackground } from "./active-item-background";
|
||||
|
||||
const SidebarItem = ({
|
||||
item: { icon, path, soon, label: itemLabel },
|
||||
index,
|
||||
separator,
|
||||
active,
|
||||
hideLabel,
|
||||
}: {
|
||||
item: (typeof items)[number];
|
||||
separator?: boolean;
|
||||
index: number;
|
||||
active?: boolean;
|
||||
hideLabel?: boolean;
|
||||
}) => {
|
||||
const timeoutRef = React.useRef<number | null>(null);
|
||||
const [hover, setHover] = React.useState(false);
|
||||
const Icon = icon ?? React.Fragment;
|
||||
|
||||
const Element = soon ? "div" : NavLink;
|
||||
|
||||
const label = itemLabel;
|
||||
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<Element
|
||||
to={path ?? "/"}
|
||||
onMouseEnter={() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setHover(true);
|
||||
}, 150);
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setHover(false);
|
||||
}, 150);
|
||||
}}
|
||||
className={clsx(
|
||||
"re-relative",
|
||||
"re-flex-shrink-0",
|
||||
"re-w-10",
|
||||
"re-h-10",
|
||||
active ? "re-text-alt-cyan" : "re-text-gray-500",
|
||||
!active && "hover:re-text-alt-cyan",
|
||||
"re-transition-colors",
|
||||
"re-duration-200",
|
||||
"re-ease-in-out",
|
||||
"re-flex",
|
||||
"re-justify-center",
|
||||
"re-gap-4",
|
||||
"re-items-center",
|
||||
"re-group",
|
||||
)}
|
||||
>
|
||||
<ActiveItemBackground active={active} />
|
||||
<Icon className={clsx("re-z-[1]", soon && "re-opacity-50")} />
|
||||
{soon && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-select-none",
|
||||
"re-absolute",
|
||||
"re-h-[11px]",
|
||||
"re-bottom-[-2.5px]",
|
||||
"re-right-[4.5px]",
|
||||
"re-text-[7px]",
|
||||
"re-leading-[7px]",
|
||||
"re-z-[2]",
|
||||
"re",
|
||||
"re-text-center",
|
||||
"re-font-semibold",
|
||||
"re-text-alt-cyan",
|
||||
"re-bg-alt-cyan",
|
||||
"re-bg-opacity-10",
|
||||
"re-border",
|
||||
"re-border-opacity-20",
|
||||
"re-border-alt-cyan",
|
||||
"re-py-px",
|
||||
"re-px-1",
|
||||
"re-rounded-lg",
|
||||
)}
|
||||
>
|
||||
SOON
|
||||
</div>
|
||||
)}
|
||||
{!hideLabel && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-transition-transform",
|
||||
!hover && "re-scale-y-0 re--translate-x-6",
|
||||
hover && "re-scale-y-100 re-translate-x-0",
|
||||
"re-absolute",
|
||||
"re-left-[42px]",
|
||||
"re-top-0",
|
||||
"re-h-full",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-text-sm",
|
||||
"re-break-keep",
|
||||
"re-whitespace-nowrap",
|
||||
"re-z-[2]",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-2",
|
||||
"re-py-1",
|
||||
"re-border",
|
||||
"re-border-gray-600",
|
||||
"re-bg-gray-700",
|
||||
"re-shadow-md",
|
||||
"re-rounded",
|
||||
"re-text-gray-0",
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Element>
|
||||
{separator && (
|
||||
<div
|
||||
className={clsx(
|
||||
"re-w-full",
|
||||
"re-h-0",
|
||||
"re--mt-1",
|
||||
"re--mb-[5px]",
|
||||
"re-border-b",
|
||||
"re-border-b-gray-600",
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const SidebarHiddenItemsItem = ({
|
||||
index,
|
||||
hiddenItems,
|
||||
active,
|
||||
}: {
|
||||
item: (typeof items)[number];
|
||||
hiddenItems: typeof items;
|
||||
separator?: boolean;
|
||||
index: number;
|
||||
active?: boolean;
|
||||
}) => {
|
||||
const timeoutRef = React.useRef<number | null>(null);
|
||||
const [hover, setHover] = React.useState(false);
|
||||
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<div
|
||||
onMouseEnter={() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setHover(true);
|
||||
}, 150);
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setHover(false);
|
||||
}, 150);
|
||||
}}
|
||||
className={clsx(
|
||||
"re-cursor-pointer",
|
||||
"re-relative",
|
||||
"re-flex-shrink-0",
|
||||
"re-w-10",
|
||||
"re-h-10",
|
||||
active ? "re-text-alt-cyan" : "re-text-gray-500",
|
||||
!active && "hover:re-text-alt-cyan",
|
||||
"re-transition-colors",
|
||||
"re-duration-200",
|
||||
"re-ease-in-out",
|
||||
"re-flex",
|
||||
"re-justify-center",
|
||||
"re-items-center",
|
||||
"re-group",
|
||||
)}
|
||||
>
|
||||
<HiddenItemsBgIcon className="re-z-[1] re-text-gray-700 re-w-9 re-h-9" />
|
||||
<span
|
||||
className={clsx(
|
||||
"re-absolute",
|
||||
"re-left-0",
|
||||
"re-right-0",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-z-[1]",
|
||||
"re-text-gray-300",
|
||||
"re-text-sm",
|
||||
)}
|
||||
>
|
||||
+{hiddenItems.length}
|
||||
</span>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-transition-transform",
|
||||
!hover && "re-scale-x-0 re--translate-x-6",
|
||||
hover && "re-scale-x-100 re-translate-x-0",
|
||||
"re-absolute",
|
||||
"re-left-[42px]",
|
||||
"re-bottom-[-2px]",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-justify-center",
|
||||
"re-text-sm",
|
||||
"re-break-keep",
|
||||
"re-whitespace-nowrap",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"re-px-3",
|
||||
"re-pt-0",
|
||||
"re-pb-1",
|
||||
"re-border",
|
||||
"re-border-gray-600",
|
||||
"re-bg-gray-900",
|
||||
"re-shadow-md",
|
||||
"re-flex",
|
||||
"re-items-center",
|
||||
"re-gap-2",
|
||||
"re-rounded",
|
||||
)}
|
||||
>
|
||||
{hiddenItems.map((item, index) => {
|
||||
return (
|
||||
<SidebarItem
|
||||
item={item}
|
||||
key={index}
|
||||
index={index}
|
||||
active={false}
|
||||
hideLabel
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
type SidebarItemType = {
|
||||
icon?: React.ComponentType<React.ComponentProps<"svg">>;
|
||||
label: string;
|
||||
path?: string;
|
||||
section?: string;
|
||||
soon?: boolean;
|
||||
};
|
||||
|
||||
const items: SidebarItemType[] = [
|
||||
{
|
||||
icon: OverviewIcon,
|
||||
label: "Overview",
|
||||
path: "/overview",
|
||||
section: "first",
|
||||
},
|
||||
{
|
||||
icon: MonitorIcon,
|
||||
label: "Monitor",
|
||||
path: "/monitor",
|
||||
section: "first",
|
||||
},
|
||||
// {
|
||||
// icon: ResourceViewerIcon,
|
||||
// label: "Resource Viewer",
|
||||
// path: "/resource-viewer",
|
||||
// section: "first",
|
||||
// soon: true,
|
||||
// },
|
||||
// {
|
||||
// icon: OptionsIcon,
|
||||
// label: "Options",
|
||||
// path: "/options",
|
||||
// section: "first",
|
||||
// soon: true,
|
||||
// },
|
||||
{
|
||||
icon: PlaygroundIcon,
|
||||
label: "Playground",
|
||||
path: "/playground",
|
||||
section: "second",
|
||||
soon: true,
|
||||
},
|
||||
{
|
||||
icon: InferencerPreviewIcon,
|
||||
label: "Inferencer Preview",
|
||||
path: "/inferencer-preview",
|
||||
section: "second",
|
||||
soon: true,
|
||||
},
|
||||
// {
|
||||
// icon: SnippetsIcon,
|
||||
// label: "Snippets",
|
||||
// path: "/snippets",
|
||||
// section: "second",
|
||||
// soon: true,
|
||||
// },
|
||||
{
|
||||
icon: ChatbotIcon,
|
||||
label: "Chatbot",
|
||||
path: "/chatbot",
|
||||
section: "second",
|
||||
soon: true,
|
||||
},
|
||||
// {
|
||||
// icon: SettingsIcon,
|
||||
// label: "Settings",
|
||||
// path: "/settings",
|
||||
// section: "fourth",
|
||||
// soon: true,
|
||||
// },
|
||||
];
|
||||
|
||||
const ITEM_HEIGHT = 40;
|
||||
const ITEM_GAP = 10;
|
||||
|
||||
export const Sidebar = () => {
|
||||
const itemContainerRef = React.useRef<HTMLDivElement>(null);
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const [itemsToRender, setItemsToRender] = React.useState<typeof items>([]);
|
||||
const [hiddenItems, setHiddenItems] = React.useState<typeof items>([]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleResize = () => {
|
||||
if (!itemContainerRef.current) {
|
||||
setItemsToRender([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const { clientHeight } = itemContainerRef.current;
|
||||
|
||||
const itemCount = Math.floor(
|
||||
clientHeight / (ITEM_HEIGHT + ITEM_GAP),
|
||||
);
|
||||
|
||||
const realItemCount =
|
||||
itemCount === items.length ? itemCount : itemCount - 1;
|
||||
|
||||
const remainingItemElement = {
|
||||
label: "__hidden_elements__",
|
||||
};
|
||||
|
||||
setItemsToRender([
|
||||
...items.slice(0, realItemCount),
|
||||
...(realItemCount < items.length ? [remainingItemElement] : []),
|
||||
]);
|
||||
setHiddenItems(items.slice(realItemCount));
|
||||
};
|
||||
|
||||
handleResize();
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<nav
|
||||
className={clsx(
|
||||
"re-flex-shrink-0",
|
||||
"re-min-h-full",
|
||||
"re-bg-gray-900",
|
||||
"re-border-r",
|
||||
"re-border-r-gray-700",
|
||||
"re-px-1.5",
|
||||
"re-pt-2",
|
||||
"re-flex",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
ref={itemContainerRef}
|
||||
className={clsx(
|
||||
"re-flex",
|
||||
"re-flex-1",
|
||||
"re-flex-col",
|
||||
"re-gap-2.5",
|
||||
"re-w-10",
|
||||
"re-flex-shrink-0",
|
||||
)}
|
||||
>
|
||||
{itemsToRender.map((item, index, array) => {
|
||||
const nextItemSection = array[index + 1]?.section;
|
||||
if (item.label === "__hidden_elements__") {
|
||||
return (
|
||||
<SidebarHiddenItemsItem
|
||||
key={index}
|
||||
item={item}
|
||||
hiddenItems={hiddenItems}
|
||||
index={index}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<SidebarItem
|
||||
key={index}
|
||||
item={item}
|
||||
index={index}
|
||||
active={pathname === item.path}
|
||||
separator={Boolean(
|
||||
nextItemSection &&
|
||||
nextItemSection !== item.section,
|
||||
)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
import React from "react";
|
||||
import { Activity } from "src/interfaces/activity";
|
||||
|
||||
export const Status = ({ activity }: { activity: Activity }) => {
|
||||
const status = activity.status;
|
||||
|
||||
const dataUpdateCount =
|
||||
activity.type === "query" ? activity.state.dataUpdateCount : 0;
|
||||
const fetchStatus =
|
||||
activity.type === "query" ? activity.state.fetchStatus : "idle";
|
||||
|
||||
let state: typeof status | "initial" | "refetching" = status;
|
||||
|
||||
if (status === "loading" && dataUpdateCount === 0) {
|
||||
state = "initial";
|
||||
}
|
||||
if (
|
||||
(status === "success" || status === "error") &&
|
||||
fetchStatus === "fetching"
|
||||
) {
|
||||
state = "refetching";
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case "initial":
|
||||
case "idle":
|
||||
return (
|
||||
<span className="re-text-gray-500 re-capitalize">{state}</span>
|
||||
);
|
||||
case "loading":
|
||||
case "refetching":
|
||||
return (
|
||||
<span className="re-text-alt-yellow re-capitalize">
|
||||
{state}
|
||||
</span>
|
||||
);
|
||||
case "error":
|
||||
return (
|
||||
<span className="re-text-alt-red re-capitalize">{state}</span>
|
||||
);
|
||||
case "success":
|
||||
return (
|
||||
<span className="re-text-alt-green re-capitalize">{state}</span>
|
||||
);
|
||||
default:
|
||||
return <span>{state}</span>;
|
||||
}
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { TraceType } from "@refinedev/devtools-shared";
|
||||
|
||||
export const TraceList = ({ trace }: { trace?: TraceType[] }) => {
|
||||
return (
|
||||
<div className={clsx("re-flex", "trace-list")}>
|
||||
{[...(trace ?? [])].reverse().map((t, i, arr) => (
|
||||
<div
|
||||
key={`${t}-${i}`}
|
||||
className={clsx(
|
||||
"trace-item",
|
||||
i > 0 && "-re-ml-px",
|
||||
i === 0 && "re-pl-2",
|
||||
i === arr.length - 1 && "re-pr-2",
|
||||
i === 0 && "re-rounded-l-xl",
|
||||
i === arr.length - 1 && "re-rounded-r-xl",
|
||||
"re-border",
|
||||
"re-border-gray-700",
|
||||
"re-py-1",
|
||||
"re-pl-1.5",
|
||||
"re-pr-2",
|
||||
"re-text-gray-300",
|
||||
"re-text-xs",
|
||||
)}
|
||||
>
|
||||
{t.function}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user