Add snapshots

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-19 14:28:13 +02:00
parent 9a7add8577
commit e12d04c947
49 changed files with 5560 additions and 185 deletions

View File

@@ -0,0 +1,17 @@
import { useTranslate } from "@probo/i18n";
import { Option } from "@probo/ui";
import { snapshotTypes, getSnapshotTypeLabel } from "@probo/helpers";
export function SnapshotTypeOptions() {
const { __ } = useTranslate();
return (
<>
{snapshotTypes.map((type) => (
<Option key={type} value={type}>
{getSnapshotTypeLabel(__, type)}
</Option>
))}
</>
);
}

View File

@@ -1,23 +1,32 @@
import { Avatar, Field, Option, Select, Badge, Button, IconCrossLargeX } from "@probo/ui";
import { Suspense, useState, type ComponentProps } from "react";
import { useTranslate } from "@probo/i18n";
import { type Control, Controller } from "react-hook-form";
import { type Control, Controller, type FieldValues } from "react-hook-form";
import { useVendors } from "/hooks/graph/VendorGraph.ts";
import { faviconUrl } from "@probo/helpers";
import type { Path } from "react-hook-form";
type Props = {
type Vendor = {
id: string;
name: string;
websiteUrl: string | null | undefined;
};
type Props<T extends FieldValues = FieldValues> = {
organizationId: string;
control: Control<any>;
control: Control<T>;
name: string;
label?: string;
error?: string;
selectedVendors?: Vendor[];
} & ComponentProps<typeof Field>;
export function VendorsMultiSelectField({
export function VendorsMultiSelectField<T extends FieldValues = FieldValues>({
organizationId,
control,
selectedVendors = [],
...props
}: Props) {
}: Props<T>) {
return (
<Field {...props}>
<Suspense
@@ -28,29 +37,40 @@ export function VendorsMultiSelectField({
control={control}
name={props.name}
disabled={props.disabled}
selectedVendors={selectedVendors}
/>
</Suspense>
</Field>
);
}
function VendorsMultiSelectWithQuery(
props: Pick<Props, "organizationId" | "control" | "name" | "disabled">
function VendorsMultiSelectWithQuery<T extends FieldValues = FieldValues>(
props: Pick<Props<T>, "organizationId" | "control" | "name" | "disabled" | "selectedVendors">
) {
const { __ } = useTranslate();
const { name, organizationId, control } = props;
const { name, organizationId, control, selectedVendors = [] } = props;
const vendors = useVendors(organizationId);
const [isOpen, setIsOpen] = useState(false);
const allVendors = [...vendors];
if (props.disabled) {
selectedVendors.forEach(selectedVendor => {
if (!allVendors.find(v => v.id === selectedVendor.id)) {
allVendors.push(selectedVendor);
}
});
}
return (
<>
<Controller
control={control}
name={name}
name={name as Path<T>}
render={({ field }) => {
const selectedVendorIds = Array.isArray(field.value) ? field.value : [];
const selectedVendors = vendors.filter(v => selectedVendorIds.includes(v.id));
const availableVendors = vendors.filter(v => !selectedVendorIds.includes(v.id));
const selectedVendorIds = (Array.isArray(field.value) ? field.value : []) as string[];
const selectedVendors = allVendors.filter(v => selectedVendorIds.includes(v.id));
const availableVendors = allVendors.filter(v => !selectedVendorIds.includes(v.id));
const handleAddVendor = (vendorId: string) => {
const newValue = [...selectedVendorIds, vendorId];
@@ -65,7 +85,7 @@ function VendorsMultiSelectWithQuery(
return (
<div className="space-y-2">
{availableVendors.length > 0 && (
{availableVendors.length > 0 && !props.disabled && (
<Select
disabled={props.disabled}
id={name}
@@ -108,12 +128,14 @@ function VendorsMultiSelectWithQuery(
size="s"
/>
<span>{vendor.name}</span>
<Button
variant="tertiary"
icon={IconCrossLargeX}
onClick={() => handleRemoveVendor(vendor.id)}
className="h-4 w-4 p-0 hover:bg-transparent"
/>
{!props.disabled && (
<Button
variant="tertiary"
icon={IconCrossLargeX}
onClick={() => handleRemoveVendor(vendor.id)}
className="h-4 w-4 p-0 hover:bg-transparent"
/>
)}
</Badge>
))}
</div>