finalize new media settings ui

This commit is contained in:
dswbx
2025-02-06 13:58:29 +01:00
parent 46cf310ad6
commit 9a4c2bd530
11 changed files with 58 additions and 103 deletions

View File

@@ -22,7 +22,7 @@ export type AnyOfFieldContext = {
select: (index: number | null) => void;
options: string[];
errors: JsonError[];
selectSchema: any;
selectSchema: JSONSchema;
};
const AnyOfContext = createContext<AnyOfFieldContext>(undefined!);
@@ -39,8 +39,9 @@ const Root = ({ path = "", schema: _schema, children }: AnyOfFieldRootProps) =>
const [selected, setSelected] = useState<number | null>(matchedIndex > -1 ? matchedIndex : null);
const options = schemas.map((s, i) => s.title ?? `Option ${i + 1}`);
const selectSchema = {
type: "string",
enum: options
};
} satisfies JSONSchema;
//console.log("AnyOf:root", { value, matchedIndex, selected, schema });
const selectedSchema =

View File

@@ -35,36 +35,36 @@ export const ArrayField = ({
};
}
const Wrapper = ({ children }) => (
<FieldWrapper pointer={path} schema={schema} wrapper="fieldset">
{children}
</FieldWrapper>
);
// if unique items with enum
if (schema.uniqueItems && typeof schema.items === "object" && "enum" in schema.items) {
return (
<Wrapper>
<Formy.Select
<FieldWrapper pointer={path} schema={schema} wrapper="fieldset">
<FieldComponent
required
options={schema.items.enum}
schema={schema.items}
multiple
value={value}
className="h-auto"
onChange={(e) => {
onChange={(e: any) => {
// @ts-ignore
const selected = Array.from(e.target.selectedOptions).map((o) => o.value);
console.log("selected", selected);
setValue(pointer, selected);
}}
/>
</Wrapper>
</FieldWrapper>
);
}
return (
<Wrapper>
<FieldWrapper pointer={path} schema={schema} wrapper="fieldset">
{value?.map((v, index: number) => {
const pointer = `${path}/${index}`.replace(/\/+/g, "/");
const [, , subschema] = getMultiSchemaMatched(schema.items, v);
let subschema = schema.items;
if (itemsMultiSchema) {
const [, , _subschema] = getMultiSchemaMatched(schema.items, v);
subschema = _subschema;
}
return (
<div key={pointer} className="flex flex-row gap-2">
<FieldComponent
@@ -80,22 +80,24 @@ export const ArrayField = ({
</div>
);
})}
{itemsMultiSchema ? (
<Dropdown
dropdownWrapperProps={{
className: "min-w-0"
}}
items={itemsMultiSchema.map((s, i) => ({
label: s!.title ?? `Option ${i + 1}`,
onClick: () => handleAdd(ctx.lib.getTemplate(undefined, s!))
}))}
onClickItem={console.log}
>
<Button IconLeft={IconLibraryPlus}>Add</Button>
</Dropdown>
) : (
<Button onClick={() => handleAdd()}>Add</Button>
)}
</Wrapper>
<div className="flex flex-row">
{itemsMultiSchema ? (
<Dropdown
dropdownWrapperProps={{
className: "min-w-0"
}}
items={itemsMultiSchema.map((s, i) => ({
label: s!.title ?? `Option ${i + 1}`,
onClick: () => handleAdd(ctx.lib.getTemplate(undefined, s!))
}))}
onClickItem={console.log}
>
<Button IconLeft={IconLibraryPlus}>Add</Button>
</Dropdown>
) : (
<Button onClick={() => handleAdd()}>Add</Button>
)}
</div>
</FieldWrapper>
);
};

View File

@@ -5,7 +5,7 @@ import { ArrayField } from "./ArrayField";
import { FieldWrapper } from "./FieldWrapper";
import { useFieldContext } from "./Form";
import { ObjectField } from "./ObjectField";
import { coerce, isType, isTypeSchema } from "./utils";
import { coerce, enumToOptions, isType, isTypeSchema } from "./utils";
export type FieldProps = {
name: string;
@@ -77,17 +77,12 @@ export const FieldComponent = ({
schema,
...props
}: { schema: JSONSchema } & ComponentPropsWithoutRef<"input">) => {
if (!schema || typeof schema === "boolean") return null;
//console.log("field", props.name, props.disabled);
if (!isTypeSchema(schema)) return null;
if (schema.enum) {
if (!Array.isArray(schema.enum)) return null;
let options = schema.enum;
if (schema.enum.every((v) => typeof v === "string")) {
options = schema.enum.map((v, i) => ({ value: i, label: v }));
}
return <Formy.Select id={props.name} {...(props as any)} options={options} />;
return (
<Formy.Select id={props.name} {...(props as any)} options={enumToOptions(schema.enum)} />
);
}
if (isType(schema.type, ["number", "integer"])) {

View File

@@ -45,6 +45,7 @@ export function FieldWrapper({
>
{debug && (
<div className="absolute right-0 top-0">
{/* @todo: use radix */}
<Popover>
<Popover.Target>
<IconButton Icon={IconBug} size="xs" className="opacity-30" />

View File

@@ -223,3 +223,10 @@ export function omitSchema<Given extends JSONSchema>(_schema: Given, keys: strin
export function isTypeSchema(schema?: JSONSchema): schema is Exclude<JSONSchema, boolean> {
return typeof schema === "object" && "type" in schema && !isType(schema.type, "error");
}
export function enumToOptions(_enum: any) {
if (!Array.isArray(_enum)) return [];
return _enum.map((v, i) =>
typeof v === "string" ? { value: v, label: v } : { value: i, label: v }
);
}