Add risk assessment tab
Signed-off-by: Bryan Frimin <bryan@getprobo.com> Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
committed by
Sacha Al Himdani
parent
7d2d26aab5
commit
b660c0ce7f
@@ -9,7 +9,7 @@ import { tv, type VariantProps } from "tailwind-variants";
|
||||
import { Slot } from "../Slot";
|
||||
|
||||
export const button = tv({
|
||||
base: "flex items-center justify-center gap-[6px] px-3 py-2 rounded-full cursor-pointer text-sm font-medium h-8 focus:outline-none",
|
||||
base: "flex items-center justify-center gap-[6px] px-3 py-2 rounded-full cursor-pointer text-sm font-medium h-8 focus:outline-none whitespace-nowrap",
|
||||
variants: {
|
||||
variant: {
|
||||
primary:
|
||||
|
||||
@@ -80,8 +80,6 @@ export function Dropzone(props: Props) {
|
||||
hasError: !!error,
|
||||
});
|
||||
|
||||
console.log(error);
|
||||
|
||||
return (
|
||||
<div {...getRootProps()} className={wrapper()}>
|
||||
<div className={zone()}>
|
||||
|
||||
@@ -15,16 +15,17 @@ import { IconChevronGrabberVertical } from "../Icons/IconChevronGrabberVertical.
|
||||
import { tv } from "tailwind-variants";
|
||||
import { Children, type ComponentProps, type PropsWithChildren } from "react";
|
||||
|
||||
type Props = PropsWithChildren<
|
||||
type Props<T> = PropsWithChildren<
|
||||
{
|
||||
id?: string;
|
||||
placeholder?: string;
|
||||
onValueChange?: (s: string) => void;
|
||||
onValueChange?: (s: NonNullable<T>) => void;
|
||||
variant?: "default" | "editor" | "dashed";
|
||||
invalid?: boolean;
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
} & Omit<ComponentProps<typeof Root>, "onChange">
|
||||
value?: T;
|
||||
} & Omit<ComponentProps<typeof Root>, "onChange" | "value">
|
||||
>;
|
||||
|
||||
const select = tv({
|
||||
@@ -70,19 +71,19 @@ const select = tv({
|
||||
},
|
||||
});
|
||||
|
||||
export function Select({
|
||||
export function Select<T>({
|
||||
placeholder,
|
||||
children,
|
||||
onValueChange,
|
||||
value,
|
||||
...props
|
||||
}: Props) {
|
||||
}: Props<T>) {
|
||||
const { trigger, content, icon } = select({
|
||||
...props,
|
||||
});
|
||||
|
||||
return (
|
||||
<Root onValueChange={onValueChange} value={value}>
|
||||
<Root onValueChange={onValueChange} value={value as string}>
|
||||
<Trigger
|
||||
{...props}
|
||||
className={trigger({ className: props.className })}
|
||||
@@ -122,7 +123,7 @@ export function Option({ children, ...props }: ComponentProps<typeof Item>) {
|
||||
<Item
|
||||
{...props}
|
||||
className={
|
||||
"flex gap-2 items-center h-8 text-sm font-medium text-txt-primary hover:bg-tertiary-hover active:bg-tertiary-pressed cursor-pointer px-[10px]"
|
||||
"flex gap-2 items-center min-h-8 py-1 text-sm font-medium text-txt-primary hover:bg-tertiary-hover active:bg-tertiary-pressed cursor-pointer px-[10px] text-start"
|
||||
}
|
||||
>
|
||||
<ItemText asChild>
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { createContext, useContext, type PropsWithChildren } from "react";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
type HTMLAttributes,
|
||||
type PropsWithChildren,
|
||||
} from "react";
|
||||
import { Card } from "../Card/Card";
|
||||
import { Link } from "react-router";
|
||||
import clsx from "clsx";
|
||||
@@ -25,9 +30,13 @@ export function Thead({ children }: PropsWithChildren) {
|
||||
export function Th({
|
||||
children,
|
||||
className,
|
||||
}: PropsWithChildren<{ className?: string }>) {
|
||||
width,
|
||||
}: PropsWithChildren<{ className?: string; width?: number }>) {
|
||||
return (
|
||||
<th className={clsx("first:pl-6 last:pr-6 py-3", className)}>
|
||||
<th
|
||||
className={clsx("first:pl-6 last:pr-6 py-3", className)}
|
||||
style={{ width }}
|
||||
>
|
||||
{children}
|
||||
</th>
|
||||
);
|
||||
@@ -35,17 +44,21 @@ export function Th({
|
||||
|
||||
const TrContext = createContext({} as { to?: string });
|
||||
|
||||
export function Tr({ children, to }: PropsWithChildren<{ to?: string }>) {
|
||||
export function Tr({
|
||||
to,
|
||||
className,
|
||||
...props
|
||||
}: { to?: string } & HTMLAttributes<HTMLTableRowElement>) {
|
||||
return (
|
||||
<TrContext value={{ to }}>
|
||||
<tr
|
||||
{...props}
|
||||
className={clsx(
|
||||
"border-border-low border-y first:border-none last:border-none",
|
||||
to && "hover:bg-subtle",
|
||||
(to || props.onClick) && "hover:bg-subtle",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</tr>
|
||||
/>
|
||||
</TrContext>
|
||||
);
|
||||
}
|
||||
@@ -63,15 +76,17 @@ export function Td({
|
||||
noLink,
|
||||
className,
|
||||
width,
|
||||
}: PropsWithChildren<{
|
||||
...props
|
||||
}: {
|
||||
noLink?: boolean;
|
||||
className?: string;
|
||||
width?: number;
|
||||
}>) {
|
||||
colSpan?: number;
|
||||
} & HTMLAttributes<HTMLTableCellElement>) {
|
||||
const { to } = useContext(TrContext);
|
||||
if (!to || noLink) {
|
||||
return (
|
||||
<td
|
||||
{...props}
|
||||
width={width}
|
||||
className={clsx("first:pl-6 last:pr-6 py-3", className)}
|
||||
>
|
||||
@@ -81,6 +96,7 @@ export function Td({
|
||||
}
|
||||
return (
|
||||
<td
|
||||
{...props}
|
||||
width={width}
|
||||
className={clsx(
|
||||
"first:*:pl-6 *:block last:*:pr-6 *:py-3",
|
||||
|
||||
@@ -161,7 +161,6 @@ export const Typography: Story = {
|
||||
|
||||
export const Icons: Story = {
|
||||
render() {
|
||||
console.log();
|
||||
return (
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{objectKeys(icons).map((k) => {
|
||||
|
||||
21
packages/ui/src/Molecules/Select/ImpactOptions.stories.tsx
Normal file
21
packages/ui/src/Molecules/Select/ImpactOptions.stories.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ImpactOptions } from "./ImpactOptions.tsx";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { Select } from "../../Atoms/Select/Select.tsx";
|
||||
|
||||
export default {
|
||||
title: "Molecules/Select/ImpactSelect",
|
||||
component: ImpactOptions,
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof ImpactOptions>;
|
||||
|
||||
type Story = StoryObj<typeof ImpactOptions>;
|
||||
|
||||
export const Default: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Select placeholder="Select impact">
|
||||
<ImpactOptions />
|
||||
</Select>
|
||||
);
|
||||
},
|
||||
};
|
||||
47
packages/ui/src/Molecules/Select/ImpactOptions.tsx
Normal file
47
packages/ui/src/Molecules/Select/ImpactOptions.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Option } from "../../Atoms/Select/Select";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
|
||||
export function ImpactOptions() {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const descriptions = {
|
||||
LOW: {
|
||||
label: __("Low"),
|
||||
description: __("Minimal impact on business"),
|
||||
},
|
||||
MEDIUM: {
|
||||
label: __("Medium"),
|
||||
description: __("Moderate impact on business"),
|
||||
},
|
||||
HIGH: {
|
||||
label: __("High"),
|
||||
description: __("Significant business impact"),
|
||||
},
|
||||
CRITICAL: {
|
||||
label: __("Critical"),
|
||||
description: __("Critical to business operations"),
|
||||
},
|
||||
} as const;
|
||||
|
||||
return (
|
||||
<>
|
||||
{Object.entries(descriptions).map(([key, description]) => (
|
||||
<Option
|
||||
key={key}
|
||||
value={key}
|
||||
className="border-b border-border-low"
|
||||
>
|
||||
<span>
|
||||
<span className="text-sm font-bold">
|
||||
{description.label}
|
||||
</span>
|
||||
,{" "}
|
||||
<span className="text-sm text-txt-secondary">
|
||||
{description.description}
|
||||
</span>
|
||||
</span>
|
||||
</Option>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { SentitivityOptions } from "./SentitivityOptions.tsx";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { Select } from "../../Atoms/Select/Select.tsx";
|
||||
|
||||
export default {
|
||||
title: "Molecules/Select/SentitivitySelect",
|
||||
component: SentitivityOptions,
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof SentitivityOptions>;
|
||||
|
||||
type Story = StoryObj<typeof SentitivityOptions>;
|
||||
|
||||
export const Default: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Select placeholder="Select sensitivity">
|
||||
<SentitivityOptions />
|
||||
</Select>
|
||||
);
|
||||
},
|
||||
};
|
||||
51
packages/ui/src/Molecules/Select/SentitivityOptions.tsx
Normal file
51
packages/ui/src/Molecules/Select/SentitivityOptions.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Option } from "../../Atoms/Select/Select";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
|
||||
export function SentitivityOptions() {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const descriptions = {
|
||||
NONE: {
|
||||
label: __("None"),
|
||||
description: __("No sensitive data"),
|
||||
},
|
||||
LOW: {
|
||||
label: __("Low"),
|
||||
description: __("Public or non-sensitive data"),
|
||||
},
|
||||
MEDIUM: {
|
||||
label: __("Medium"),
|
||||
description: __("Internal/restricted data"),
|
||||
},
|
||||
HIGH: {
|
||||
label: __("High"),
|
||||
description: __("Confidential data"),
|
||||
},
|
||||
CRITICAL: {
|
||||
label: __("Critical"),
|
||||
description: __("Regulated/PII/financial data"),
|
||||
},
|
||||
} as const;
|
||||
|
||||
return (
|
||||
<>
|
||||
{Object.entries(descriptions).map(([key, description]) => (
|
||||
<Option
|
||||
key={key}
|
||||
value={key}
|
||||
className="border-b border-border-low"
|
||||
>
|
||||
<span>
|
||||
<span className="text-sm font-bold">
|
||||
{description.label}
|
||||
</span>
|
||||
,{" "}
|
||||
<span className="text-sm text-txt-secondary">
|
||||
{description.description}
|
||||
</span>
|
||||
</span>
|
||||
</Option>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -62,6 +62,8 @@ export { MeasureBadge } from "./Molecules/Badge/MeasureBadge";
|
||||
export { MeasureImplementation } from "./Molecules/MeasureImplementation/MeasureImplementation";
|
||||
export { FrameworkSelector } from "./Molecules/FrameworkSelector/FrameworkSelector";
|
||||
export { DocumentTypeBadge } from "./Molecules/Badge/DocumentTypeBadge";
|
||||
export { SentitivityOptions } from "./Molecules/Select/SentitivityOptions";
|
||||
export { ImpactOptions } from "./Molecules/Select/ImpactOptions";
|
||||
|
||||
// Hooks
|
||||
export { useToast, Toasts } from "./Atoms/Toasts/Toasts";
|
||||
|
||||
Reference in New Issue
Block a user