154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
import { apiFetch, apiPath, type ApiSettings } from "@govoplan/core-webui";
|
|
|
|
|
|
export type FormValueType = "text" | "multiline_text" | "integer" | "number" | "boolean" | "date" | "datetime" | "email" | "choice" | "multi_choice" | "object" | "list";
|
|
|
|
export type FormCondition =
|
|
| { kind: "predicate"; field_key: string; operator: "eq" | "neq" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "is_empty" | "is_not_empty"; value?: unknown }
|
|
| { kind: "all" | "any"; conditions: FormCondition[] }
|
|
| { kind: "not"; conditions: [FormCondition] };
|
|
|
|
export type FormFieldDefinition = {
|
|
key: string;
|
|
label: string;
|
|
value_type: FormValueType;
|
|
required: boolean;
|
|
help_text?: string | null;
|
|
options: string[];
|
|
constraints: Record<string, unknown>;
|
|
default_value?: unknown;
|
|
visibility_condition?: FormCondition | null;
|
|
accessibility?: Record<string, unknown>;
|
|
};
|
|
|
|
export type FormSectionDefinition = {
|
|
key: string;
|
|
title: string;
|
|
description?: string | null;
|
|
field_keys: string[];
|
|
visibility_condition?: FormCondition | null;
|
|
};
|
|
|
|
export type FormPageDefinition = {
|
|
key: string;
|
|
title: string;
|
|
description?: string | null;
|
|
sections: FormSectionDefinition[];
|
|
visibility_condition?: FormCondition | null;
|
|
};
|
|
|
|
export type FormLocalization = {
|
|
locale: string;
|
|
title?: string | null;
|
|
description?: string | null;
|
|
field_labels: Record<string, string>;
|
|
field_help_texts: Record<string, string>;
|
|
option_labels: Record<string, Record<string, string>>;
|
|
page_titles: Record<string, string>;
|
|
section_titles: Record<string, string>;
|
|
};
|
|
|
|
export type FormDefinition = {
|
|
reference: {
|
|
kind: "form";
|
|
owner_module: "forms";
|
|
object_id: string;
|
|
tenant_id: string;
|
|
version: string;
|
|
};
|
|
key: string;
|
|
temporal: {
|
|
revision: string;
|
|
valid_from?: string | null;
|
|
valid_to?: string | null;
|
|
recorded_at: string;
|
|
superseded_at?: string | null;
|
|
change_reason: string;
|
|
};
|
|
title: string;
|
|
description?: string | null;
|
|
fields: FormFieldDefinition[];
|
|
publication_state: "draft" | "published" | "retired";
|
|
allow_drafts: boolean;
|
|
max_attachments: number;
|
|
signature_requirement: "none" | "optional" | "required";
|
|
policy_refs: string[];
|
|
handoff_kinds: string[];
|
|
pages?: FormPageDefinition[];
|
|
fallback_locale?: string | null;
|
|
localizations?: FormLocalization[];
|
|
accessibility?: Record<string, unknown>;
|
|
metadata: Record<string, unknown>;
|
|
};
|
|
|
|
export type FormPackageFragment = {
|
|
kind: "govoplan.forms.definition";
|
|
contract_version: "0.1.0";
|
|
definition: FormDefinition;
|
|
definition_sha256: string;
|
|
provenance: Record<string, unknown>;
|
|
};
|
|
|
|
export function listFormDefinitions(
|
|
settings: ApiSettings,
|
|
options: { query?: string; states?: string[]; offset?: number; limit?: number } = {},
|
|
signal?: AbortSignal
|
|
): Promise<{ definitions: FormDefinition[]; total: number }> {
|
|
return apiFetch(settings, apiPath("/api/v1/forms/definitions", {
|
|
q: options.query,
|
|
publication_state: options.states,
|
|
offset: options.offset ?? 0,
|
|
limit: options.limit ?? 200
|
|
}), { signal });
|
|
}
|
|
|
|
export function saveFormDefinition(
|
|
settings: ApiSettings,
|
|
definition: FormDefinition,
|
|
expectedRevision?: string | null
|
|
): Promise<FormDefinition> {
|
|
return apiFetch(settings, `/api/v1/forms/definitions/${encodeURIComponent(definition.reference.object_id)}`, {
|
|
method: "PUT",
|
|
body: JSON.stringify({
|
|
definition,
|
|
expected_revision: expectedRevision ?? null
|
|
})
|
|
});
|
|
}
|
|
|
|
export function exportFormDefinitionPackage(
|
|
settings: ApiSettings,
|
|
formId: string,
|
|
revision: string
|
|
): Promise<FormPackageFragment> {
|
|
return apiFetch(settings, apiPath(`/api/v1/forms/definitions/${encodeURIComponent(formId)}/package`, { revision }));
|
|
}
|
|
|
|
export function assessFormDefinitionPackage(
|
|
settings: ApiSettings,
|
|
fragment: FormPackageFragment
|
|
): Promise<{ outcome: string; requires_remap: boolean; current_revision?: string | null }> {
|
|
return apiFetch(settings, "/api/v1/forms/packages/assess", {
|
|
method: "POST",
|
|
body: JSON.stringify({ fragment })
|
|
});
|
|
}
|
|
|
|
export function importFormDefinitionPackage(
|
|
settings: ApiSettings,
|
|
fragment: FormPackageFragment,
|
|
options: { targetFormId?: string; targetKey?: string; expectedRevision?: string; changeReason: string }
|
|
): Promise<FormDefinition> {
|
|
return apiFetch(settings, "/api/v1/forms/packages/import", {
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
fragment,
|
|
target_form_id: options.targetFormId || null,
|
|
target_key: options.targetKey || null,
|
|
expected_revision: options.expectedRevision || null,
|
|
change_reason: options.changeReason,
|
|
recorded_at: new Date().toISOString()
|
|
})
|
|
});
|
|
}
|