Add policies version history

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Jonathan
2025-05-27 10:12:56 +02:00
committed by Sacha Al Himdani
parent abe0ce1dde
commit 2e6741942b
36 changed files with 1710 additions and 883 deletions

View File

@@ -8,63 +8,100 @@ import {
Close,
} from "@radix-ui/react-dialog";
import { IconCrossLargeX } from "../../Atoms/Icons";
import { type HTMLAttributes, type ReactNode } from "react";
import {
Children,
cloneElement,
isValidElement,
useRef,
useState,
type ComponentProps,
type CSSProperties,
type HTMLAttributes,
type ReactElement,
type ReactNode,
type RefObject,
} from "react";
import { Button } from "../../Atoms/Button/Button";
import { useTranslate } from "@probo/i18n";
import clsx from "clsx";
import { tv } from "tailwind-variants";
export const dialog = tv({
slots: {
overlay:
"fixed inset-0 z-50 bg-dialog/40 duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
content:
"text-txt-secondary text-sm fixed inset-0 m-auto z-50 w-full h-max bg-level-2 rounded-2xl max-w-5xl w-[95%] duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-top-5 data-[state=open]:slide-in-from-top-5",
header: "flex justify-between items-center p-3 border-b border-b-border-low",
title: "text-sm font-medium text-txt-primary",
footer: "flex justify-end items-center p-3 border-t border-t-border-low gap-2",
},
});
type Props = {
trigger?: ReactNode;
title: ReactNode;
title?: ReactNode;
children?: ReactNode;
onOpenChange?: (open: boolean) => void;
open?: boolean;
defaultOpen?: boolean;
className?: string;
ref?: RefObject<{ open: () => void; close: () => void } | null>;
};
export const useDialogRef = () => {
return useRef<{ open: () => void; close: () => void } | null>(null);
};
export function Dialog({
trigger,
title,
children,
onOpenChange,
open,
className,
ref,
defaultOpen,
}: Props) {
const { overlay, content, header, title: titleClassname } = dialog();
const [open, setOpen] = useState(!!defaultOpen);
if (ref) {
ref.current = {
open() {
setOpen(true);
},
close() {
setOpen(false);
},
};
}
return (
<Root open={open} onOpenChange={onOpenChange}>
<Root open={open} onOpenChange={setOpen}>
{trigger && <Trigger asChild>{trigger}</Trigger>}
<Portal>
<Overlay
className={clsx(
"fixed inset-0 z-50 bg-dialog/40",
`duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`,
)}
/>
<Overlay className={overlay()} />
<Content
aria-describedby={undefined}
className={clsx(
"fixed inset-0 m-auto z-50 w-full h-max bg-level-2 rounded-2xl max-w-5xl w-[95%]",
className,
`duration-200
data-[state=open]:animate-in data-[state=closed]:animate-out
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0
data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
data-[state=closed]:slide-out-to-top-5
data-[state=open]:slide-in-from-top-5`,
)}
className={content({ className })}
>
<div className="flex justify-between items-center p-3 border-b border-b-border-low">
<Title className="text-sm font-medium text-txt-primary">
{title}
</Title>
{title ? (
<div className={header()}>
<Title className={titleClassname()}> {title}</Title>
<Close asChild>
<Button
tabIndex={-1}
variant="tertiary"
icon={IconCrossLargeX}
/>
</Close>
</div>
) : (
<Close asChild>
<Button
tabIndex={-1}
variant="tertiary"
className="absolute top-4 right-4"
icon={IconCrossLargeX}
/>
</Close>
</div>
)}
{children}
</Content>
</Portal>
@@ -80,8 +117,9 @@ export function DialogFooter({
exitLabel?: string;
}) {
const { __ } = useTranslate();
const { footer } = dialog();
return (
<footer className="flex justify-end items-center p-3 border-t border-t-border-low gap-2">
<footer className={footer()}>
<Close asChild>
<Button variant="secondary">{exitLabel ?? __("Cancel")}</Button>
</Close>
@@ -91,19 +129,51 @@ export function DialogFooter({
}
export function DialogContent(
props: HTMLAttributes<HTMLDivElement> & { padded?: boolean },
props: HTMLAttributes<HTMLDivElement> & {
padded?: boolean;
scrollableChildren?: boolean;
},
) {
let children = props.children;
if (props.scrollableChildren) {
children = Children.map(props.children, (c) => {
if (
isValidElement<{
className?: string;
style?: CSSProperties;
}>(c)
) {
return cloneElement(c, {
...c.props,
className: clsx(c.props.className, "overflow-y-auto"),
style: {
maxHeight: "var(--maxHeight)",
...c.props.style,
},
});
}
return c;
});
}
return (
<div
{...props}
children={children}
className={clsx(
"overflow-y-auto",
props.className,
props.padded && "p-6",
)}
style={{
maxHeight: "min(640px, calc(100vh - 140px))",
}}
style={
{
"--maxHeight": "min(640px, calc(100vh - 140px))",
maxHeight: "var(--maxHeight)",
} as CSSProperties
}
/>
);
}
export function DialogTitle(props: ComponentProps<typeof Title>) {
return <Title {...props} />;
}