Skip to content

Commit

Permalink
Merge pull request #3402 from ingef/iterate-disclosure-type
Browse files Browse the repository at this point in the history
Iterate disclosure type
  • Loading branch information
Kadrian authored Apr 22, 2024
2 parents 957b5c1 + 2878584 commit 9f10eb9
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 21 deletions.
1 change: 1 addition & 0 deletions frontend/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
],
"parser": "@typescript-eslint/parser",
"rules": {
"no-debugger": "warn",
"eqeqeq": "error",
"jsx-a11y/accessible-emoji": "off",
"no-case-declarations": "off",
Expand Down
25 changes: 13 additions & 12 deletions frontend/src/js/external-forms/config-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface TranslatableString {
export type Forms = Form[];

export type NonFormField = Headline | Description;
export type FormField = Field | Tabs | Group | Disclosure;
export type FormField = Field | Tabs | Group;
export type FormFieldWithValue = Exclude<FormField, Group>;

export type GeneralField = FormField | NonFormField;
Expand All @@ -37,17 +37,6 @@ export interface Group {
fields: GeneralField[];
}

export interface Disclosure {
type: "DISCLOSURE_LIST";
creatable?: boolean;
defaultOpen?: boolean;
name: string;
label: TranslatableString;
createNewLabel?: TranslatableString;
tooltip?: TranslatableString;
fields: GeneralField[];
}

export interface Tabs {
name: string; // Sent to backend API
type: "TABS";
Expand All @@ -72,6 +61,7 @@ type GREATER_THAN_ZERO_VALIDATION = "GREATER_THAN_ZERO";
/* FIELDS AND THEIR VALIDATIONS */
/* ------------------------------ */
export type Field =
| DisclosureListField
| CheckboxField
| StringField
| TextareaField
Expand Down Expand Up @@ -109,6 +99,17 @@ export interface Description {

/* ------------------------------ */

export interface DisclosureListField extends CommonField {
type: "DISCLOSURE_LIST";
creatable?: boolean;
defaultOpen?: boolean;
createNewLabel?: TranslatableString;
fields: GeneralField[];
onlyOneOpenAtATime?: boolean;
}

/* ------------------------------ */

export type CheckboxField = CommonField & {
type: "CHECKBOX";
defaultValue?: boolean; // Default: False
Expand Down
54 changes: 47 additions & 7 deletions frontend/src/js/external-forms/form/fields/DisclosureListField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { TransparentButton } from "../../../button/TransparentButton";
import { exists } from "../../../common/helpers/exists";
import FaIcon from "../../../icon/FaIcon";
import InfoTooltip from "../../../tooltip/InfoTooltip";
import { Disclosure } from "../../config-types";
import { DisclosureListField as DisclosureListFieldT } from "../../config-types";
import {
getFieldKey,
getInitialValue,
Expand All @@ -39,18 +39,20 @@ const Summary = tw("summary")`
const DisclosureField = ({
field,
index,
isOpen,
toggleOpen,
remove,
canRemove,
commonProps,
}: {
field: Disclosure;
field: DisclosureListFieldT;
index: number;
isOpen: boolean;
toggleOpen: () => void;
remove: (index: number) => void;
canRemove?: boolean;
commonProps: Omit<ComponentProps<typeof Field>, "field">;
}) => {
const [isOpen, setOpen] = useState(false);

if (field.fields.length === 0) return null;

const { formType, locale } = commonProps;
Expand All @@ -59,7 +61,17 @@ const DisclosureField = ({
<details
className="overflow-hidden rounded border border-gray-400"
open={isOpen}
onToggle={() => setOpen(!isOpen)}
onToggle={(e) => {
if (
(isOpen && e.currentTarget.open) ||
(!isOpen && !e.currentTarget.open)
) {
// Without this, we're getting open/close flickering
return;
}

toggleOpen();
}}
>
<Summary>
<div className="flex items-center gap-3">
Expand Down Expand Up @@ -93,22 +105,48 @@ const DisclosureField = ({
);
};

const useOpenState = ({
defaultOpen,
onlyOneOpenAtATime = false,
}: {
defaultOpen?: string;
onlyOneOpenAtATime?: boolean;
}) => {
const [isOpen, setIsOpen] = useState<Record<string, boolean>>(
defaultOpen ? { [defaultOpen]: true } : {},
);

const toggleOpen = (id: string) => {
setIsOpen((prev) => ({
...(onlyOneOpenAtATime ? {} : prev),
[id]: !prev[id],
}));
};

return { isOpen, toggleOpen };
};

export const DisclosureListField = ({
field,
defaultValue,
commonProps,
datasetId,
}: {
field: Disclosure;
field: DisclosureListFieldT;
defaultValue: unknown;
commonProps: Omit<ComponentProps<typeof Field>, "field">;
datasetId: string | null;
}) => {
const { fields, append, remove, replace } = useFieldArray({
// gets control through context
// gets `control` through context
name: field.name,
});

const { isOpen, toggleOpen } = useOpenState({
onlyOneOpenAtATime: field.onlyOneOpenAtATime,
defaultOpen: field.defaultOpen ? fields[0]?.id : undefined,
});

useEffect(
function applyDefaultValue() {
if (
Expand Down Expand Up @@ -138,6 +176,8 @@ export const DisclosureListField = ({
field={field}
index={index}
remove={remove}
isOpen={isOpen[fd.id]}
toggleOpen={() => toggleOpen(fd.id)}
canRemove={fields.length > 1}
commonProps={commonProps}
/>
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/js/external-forms/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { isValidSelect } from "../model/select";
import {
CheckboxField,
ConceptListField,
DisclosureListField,
Field,
FormField,
} from "./config-types";
Expand Down Expand Up @@ -125,6 +126,7 @@ const DEFAULT_VALIDATION_BY_TYPE: Record<
// MULTI_SELECT: null,
// @ts-ignore TODO: Refactor using generics to try and tie the `field` to its `value`
DATE_RANGE: validateDateRange,
DISCLOSURE_LIST: null,
};

function getNotEmptyValidation(fieldType: string) {
Expand All @@ -147,9 +149,12 @@ function getConfigurableValidations(fieldType: string) {

const isFieldWithValidations = (
field: FormField,
): field is Exclude<Field, CheckboxField> => {
): field is Exclude<Field, CheckboxField | DisclosureListField> => {
return (
field.type !== "TABS" && field.type !== "GROUP" && field.type !== "CHECKBOX"
field.type !== "TABS" &&
field.type !== "GROUP" &&
field.type !== "CHECKBOX" &&
field.type !== "DISCLOSURE_LIST"
);
};

Expand Down

0 comments on commit 9f10eb9

Please sign in to comment.