- Implement folder account options helper for filtering access items based on person ID and date. - Create FolderAccessAccountField component for selecting accounts with profile integration. - Develop AssetLocalIdentities component for managing local identities associated with assets. - Introduce LocalIdentityOwner component to display and manage local identity ownership. - Add LocalIdentityEditor for creating, associating, and retiring local identities. - Implement local identity API for fetching and executing local identity commands. - Create tests for local identity UI components to ensure functionality and correctness. - Add NetworkShareOptions class for structured and paginated SMB selection. - Introduce NetworkShareAddress component for displaying and copying network share addresses. - Create RemoteOptionList and RemoteOptionPicker components for remote option selection with pagination and search. - Add tests for RemoteOptionList to validate rendering and behavior under various states.
118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
import { Button } from "@repo/shadcn-ui/components/button";
|
|
import { Input } from "@repo/shadcn-ui/components/input";
|
|
import type { ReactNode } from "react";
|
|
import { useId, useState } from "react";
|
|
|
|
import { FormActions, FormBody, FormDialog } from "./form-dialog";
|
|
import type { RemotePickerOption } from "./remote-option-list";
|
|
import { RemoteOptionList } from "./remote-option-list";
|
|
|
|
export type { RemotePickerOption } from "./remote-option-list";
|
|
|
|
/** Presenta exclusivamente la página recibida; el consumidor controla consulta, filtros y paginación remota. */
|
|
export function RemoteOptionPicker({
|
|
title,
|
|
items,
|
|
pending,
|
|
error,
|
|
search,
|
|
onSearch,
|
|
onRetry,
|
|
onSelect,
|
|
onClose,
|
|
pagination,
|
|
labels,
|
|
}: {
|
|
title: string;
|
|
items: readonly RemotePickerOption[];
|
|
pending: boolean;
|
|
error: string | undefined;
|
|
search: string;
|
|
onSearch: (search: string) => void;
|
|
onRetry: () => Promise<unknown>;
|
|
onSelect: (option: RemotePickerOption) => void;
|
|
onClose: () => void;
|
|
pagination: ReactNode;
|
|
labels: {
|
|
search: string;
|
|
selection: string;
|
|
name: string;
|
|
description: string;
|
|
empty: string;
|
|
loading: string;
|
|
confirm: string;
|
|
cancel: string;
|
|
retry: string;
|
|
};
|
|
}) {
|
|
const id = useId();
|
|
const [selected, setSelected] = useState<RemotePickerOption>();
|
|
|
|
return (
|
|
<FormDialog
|
|
cancelLabel={labels.cancel}
|
|
formActions
|
|
layout="picker"
|
|
onOpenChange={(open) => {
|
|
if (!open) {
|
|
onClose();
|
|
}
|
|
}}
|
|
open
|
|
size="medium"
|
|
title={title}
|
|
>
|
|
<FormBody contentLayout="fill">
|
|
<label className="sr-only" htmlFor={id}>
|
|
{labels.search}
|
|
</label>
|
|
<Input
|
|
data-quick-search=""
|
|
id={id}
|
|
maxLength={100}
|
|
onChange={(event) => onSearch(event.target.value)}
|
|
placeholder={labels.search}
|
|
value={search}
|
|
/>
|
|
{pending && <p role="status">{labels.loading}</p>}
|
|
{error && (
|
|
<div role="alert">
|
|
<p>{error}</p>
|
|
<Button
|
|
onClick={async () => {
|
|
await onRetry();
|
|
}}
|
|
variant="outline"
|
|
>
|
|
{labels.retry}
|
|
</Button>
|
|
</div>
|
|
)}
|
|
<RemoteOptionList
|
|
error={error}
|
|
items={items}
|
|
labels={labels}
|
|
onSelect={setSelected}
|
|
pending={pending}
|
|
title={title}
|
|
value={selected?.id ?? ""}
|
|
/>
|
|
{pagination}
|
|
</FormBody>
|
|
<FormActions>
|
|
<Button
|
|
disabled={!selected || pending || !!error || selected.disabled}
|
|
onClick={() => {
|
|
if (selected && !selected.disabled) {
|
|
onSelect(selected);
|
|
onClose();
|
|
}
|
|
}}
|
|
>
|
|
{labels.confirm}
|
|
</Button>
|
|
</FormActions>
|
|
</FormDialog>
|
|
);
|
|
}
|