Build standalone CiviCRM check-in middleware
This commit is contained in:
146
types/form.ts
Normal file
146
types/form.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* Form configuration types.
|
||||
*
|
||||
* A FormConfig declares an ordered list of stage sections. Each section has
|
||||
* its own visibility rule (so Stage 1..5 can be shown/hidden based on the
|
||||
* org's current Framework Stage), and each field within a section can also
|
||||
* carry its own visibility rule (so individual fields can be gated).
|
||||
*
|
||||
* The conditional language is intentionally narrow: a rule references one
|
||||
* field by name, an operator, and a value (or set of values). Composition
|
||||
* is via { all: [...] } / { any: [...] }. Anything else stays out of the
|
||||
* config — it goes in code.
|
||||
*/
|
||||
|
||||
export type FieldType =
|
||||
| "text"
|
||||
| "textarea"
|
||||
| "number"
|
||||
| "currency"
|
||||
| "percent"
|
||||
| "date"
|
||||
| "email"
|
||||
| "phone"
|
||||
| "boolean"
|
||||
| "select"
|
||||
| "multiselect"
|
||||
| "file"
|
||||
| "readonly"; // display-only; the value comes from API and is not editable
|
||||
|
||||
export type ConditionOp =
|
||||
| "equals"
|
||||
| "notEquals"
|
||||
| "in"
|
||||
| "notIn"
|
||||
| "isEmpty"
|
||||
| "isNotEmpty";
|
||||
|
||||
export interface SimpleCondition {
|
||||
field: string;
|
||||
op: ConditionOp;
|
||||
value?: string | number | boolean | null;
|
||||
values?: Array<string | number | boolean>;
|
||||
}
|
||||
|
||||
export interface AllCondition {
|
||||
all: VisibilityRule[];
|
||||
}
|
||||
|
||||
export interface AnyCondition {
|
||||
any: VisibilityRule[];
|
||||
}
|
||||
|
||||
export type VisibilityRule = SimpleCondition | AllCondition | AnyCondition;
|
||||
|
||||
export interface SelectOption {
|
||||
value: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface FieldConfig {
|
||||
/** Form-side machine name. Use `stage_<N>_<short>` per the spec convention. */
|
||||
name: string;
|
||||
/** Human-readable label shown to the user. */
|
||||
label: string;
|
||||
type: FieldType;
|
||||
/** Optional helper text rendered below the label. */
|
||||
help?: string;
|
||||
required?: boolean;
|
||||
placeholder?: string;
|
||||
/** For select / multiselect. */
|
||||
options?: SelectOption[];
|
||||
/** For number / currency / percent — min/max/step constraints. */
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
/** For text / textarea — max length. */
|
||||
maxLength?: number;
|
||||
/** Visibility rule. If absent, field is always visible (within its visible section). */
|
||||
visibleWhen?: VisibilityRule;
|
||||
/**
|
||||
* The CiviCRM custom-field reference, if this maps to a custom field on the
|
||||
* Org Engagement Submission activity. Format: `custom_<id>` or
|
||||
* `custom_<group_name>.<field_name>` depending on APIv4 conventions.
|
||||
* Leave undefined for fields that don't write back to Civi (e.g. transient
|
||||
* UI helpers).
|
||||
*/
|
||||
civiField?: string;
|
||||
}
|
||||
|
||||
export interface StageSectionConfig {
|
||||
/** Stage rank, 0..5. Used by the conditional engine and the accordion. */
|
||||
rank: number;
|
||||
/** Internal id, e.g. "stage_0", "stage_1", … */
|
||||
id: string;
|
||||
/** Human label, e.g. "Inquiry / Check-in", "Stage 1 — Convene & Prepare". */
|
||||
label: string;
|
||||
/** Optional intro text rendered at the top of the section. */
|
||||
intro?: string;
|
||||
/**
|
||||
* Visibility rule for the entire section. Stage 0 has no rule (always
|
||||
* visible). Stages 1–5 each declare a multi-value list match against the
|
||||
* current Framework Stage.
|
||||
*/
|
||||
visibleWhen?: VisibilityRule;
|
||||
fields: FieldConfig[];
|
||||
}
|
||||
|
||||
export interface FormConfig {
|
||||
/** Unique form identifier (e.g. "org_engagement_check_in"). */
|
||||
id: string;
|
||||
/** Public title shown in the form header. */
|
||||
title: string;
|
||||
/** Short subtitle / description. */
|
||||
subtitle?: string;
|
||||
/**
|
||||
* The form's stage-source field name. The conditional engine reads this
|
||||
* field's current value when evaluating rules that reference "current_stage".
|
||||
* Conventionally `current_stage`.
|
||||
*/
|
||||
stageField: string;
|
||||
sections: StageSectionConfig[];
|
||||
}
|
||||
|
||||
/**
|
||||
* The shape returned by /api/data. Used by the form on initial load.
|
||||
*/
|
||||
export interface FormDataPayload {
|
||||
/** The organization's display name. */
|
||||
orgName: string;
|
||||
/** Current Framework Stage (text value). */
|
||||
currentStage: string;
|
||||
/**
|
||||
* Per-field-most-recent prefill values, keyed by the FieldConfig.name.
|
||||
* Fields with no prior value are simply absent from this map.
|
||||
*/
|
||||
prefill: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The shape submitted to /api/submit.
|
||||
*/
|
||||
export interface SubmitPayload {
|
||||
cid: string;
|
||||
cs: string;
|
||||
values: Record<string, unknown>;
|
||||
}
|
||||
Reference in New Issue
Block a user