Skip to content

Commit

Permalink
Merge branch 'main' into playwright-config
Browse files Browse the repository at this point in the history
  • Loading branch information
denniskigen authored Aug 16, 2023
2 parents bf34d81 + f3da811 commit be40ecf
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 74 deletions.
9 changes: 6 additions & 3 deletions e2e/pages/form-builder-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export class FormBuilderPage {
this.page.getByRole("button", { name: /start building/i });
readonly interactiveFormNameInput = () =>
this.page.getByRole("textbox", { name: /form name/i });
readonly interactiveFormDescriptionInput = () =>
this.page.getByRole("textbox", { name: /form description/i });
readonly createFormButton = () =>
this.page.getByRole("button", { name: /create form/i });
readonly addPageButton = () =>
Expand Down Expand Up @@ -91,6 +93,9 @@ export class FormBuilderPage {
await this.interactiveBuilderTab().click();
await this.startBuildingButton().click();
await this.interactiveFormNameInput().fill("Covid-19 Screening");
await this.interactiveFormDescriptionInput().fill(
"A test form for recording COVID-19 screening information"
);
await this.createFormButton().click();
await expect(this.page.getByText(/form created/i)).toBeVisible();

Expand Down Expand Up @@ -129,13 +134,11 @@ export class FormBuilderPage {
await this.formNameInput().fill(formName);
await this.formVersionInput().click();
await this.formVersionInput().fill("1.0");
await this.formDescriptionInput().click();
await this.formDescriptionInput().fill("this is test form description");
await this.formEncounterType().selectOption("Admission");
await this.formSaveButton().click();
}

async searchForm(formName: string) {
await this.page.getByRole('searchbox').fill(formName);
await this.page.getByRole("searchbox").fill(formName);
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"test-e2e": "playwright test",
"verify": "turbo lint typescript coverage",
"coverage": "yarn test --coverage --passWithNoTests",
"prepare": "husky install",
"postinstall": "husky install",
"extract-translations": "i18next 'src/**/*.component.tsx' --config ./i18next-parser.config.js",
"ci:bump-form-engine-lib": "yarn up @openmrs/openmrs-form-engine-lib@next"
},
Expand Down
12 changes: 6 additions & 6 deletions src/components/action-buttons/action-buttons.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ import type { TFunction } from "react-i18next";
import type { RouteParams, Schema } from "../../types";
import { publishForm, unpublishForm } from "../../forms.resource";
import { useForm } from "../../hooks/useForm";
import SaveFormModal from "../modals/save-form.component";
import SaveFormModal from "../modals/save-form-modal.component";
import styles from "./action-buttons.scss";

type ActionButtonsProps = {
schema: Schema;
t: TFunction;
};

type Status =
| "idle"
| "publishing"
Expand All @@ -25,11 +30,6 @@ type Status =
| "unpublished"
| "error";

type ActionButtonsProps = {
schema: Schema;
t: TFunction;
};

function ActionButtons({ schema, t }: ActionButtonsProps) {
const { formUuid } = useParams<RouteParams>();
const { form, mutate } = useForm(formUuid);
Expand Down
3 changes: 1 addition & 2 deletions src/components/form-editor/form-editor.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,14 @@ const FormEditor: React.FC = () => {
</Column>
<Column lg={8} md={8} className={styles.column}>
<Tabs>
<TabList aria-label="Form preview">
<TabList aria-label="Form previews">
<Tab>{t("preview", "Preview")}</Tab>
<Tab>{t("interactiveBuilder", "Interactive Builder")}</Tab>
</TabList>
<TabPanels>
<TabPanel>
<FormRenderer
schema={schema}
onSchemaChange={updateSchema}
isLoading={isLoadingFormOrSchema}
/>
</TabPanel>
Expand Down
67 changes: 48 additions & 19 deletions src/components/interactive-builder/new-form-modal.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ModalBody,
ModalFooter,
ModalHeader,
Stack,
TextInput,
} from "@carbon/react";
import { showToast, showNotification } from "@openmrs/esm-framework";
Expand All @@ -16,8 +17,8 @@ import type { Schema } from "../../types";
type NewFormModalProps = {
schema: Schema;
onSchemaChange: (schema: Schema) => void;
showModal: boolean;
onModalChange: (showModal: boolean) => void;
showModal: boolean;
};

const NewFormModal: React.FC<NewFormModalProps> = ({
Expand All @@ -28,11 +29,12 @@ const NewFormModal: React.FC<NewFormModalProps> = ({
}) => {
const { t } = useTranslation();
const [formName, setFormName] = useState("");
const [formDescription, setFormDescription] = useState("");

const updateFormName = () => {
const updateSchema = (updates: Partial<Schema>) => {
try {
schema.name = formName;
onSchemaChange({ ...schema });
const updatedSchema = { ...schema, ...updates };
onSchemaChange(updatedSchema);

showToast({
title: t("success", "Success!"),
Expand All @@ -50,6 +52,17 @@ const NewFormModal: React.FC<NewFormModalProps> = ({
}
};

const handleCreateForm = () => {
if (formName) {
updateSchema({
name: formName,
description: formDescription,
});

onModalChange(false);
}
};

return (
<ComposedModal
open={showModal}
Expand All @@ -59,27 +72,43 @@ const NewFormModal: React.FC<NewFormModalProps> = ({
<ModalHeader title={t("createNewForm", "Create a new form")} />
<Form onSubmit={(event) => event.preventDefault()}>
<ModalBody>
<FormGroup legendText={""}>
<TextInput
id="formName"
labelText={t("formName", "Form name")}
value={formName}
onChange={(event) => setFormName(event.target.value)}
/>
</FormGroup>
<Stack gap={5}>
<FormGroup legendText={""}>
<TextInput
id="formName"
labelText={t("formName", "Form name")}
placeholder={t(
"formNamePlaceholder",
"What the form is called in the system"
)}
value={formName}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setFormName(event.target.value)
}
/>
</FormGroup>
<FormGroup legendText={""}>
<TextInput
id="formDescription"
labelText={t("formDescription", "Form description")}
placeholder={t(
"formDescriptionPlaceholder",
"A short description of the form e.g. A form for collecting COVID-19 symptoms"
)}
value={formDescription}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setFormDescription(event.target.value)
}
/>
</FormGroup>
</Stack>
</ModalBody>
</Form>
<ModalFooter>
<Button kind="secondary" onClick={() => onModalChange(false)}>
{t("cancel", "Cancel")}
</Button>
<Button
disabled={!formName}
onClick={() => {
updateFormName();
onModalChange(false);
}}
>
<Button disabled={!formName} onClick={handleCreateForm}>
<span>{t("createForm", "Create Form")}</span>
</Button>
</ModalFooter>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { SyntheticEvent, useCallback, useState } from "react";
import React, { SyntheticEvent, useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import {
Expand Down Expand Up @@ -29,7 +29,7 @@ import {
import type { EncounterType, Resource, RouteParams, Schema } from "../../types";
import { useEncounterTypes } from "../../hooks/useEncounterTypes";
import { useForm } from "../../hooks/useForm";
import styles from "./save-form.scss";
import styles from "./save-form-modal.scss";

type FormGroupData = {
name: string;
Expand All @@ -56,18 +56,25 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
const [saveState, setSaveState] = useState("");
const [isSavingForm, setIsSavingForm] = useState(false);
const [isInvalidVersion, setIsInvalidVersion] = useState(false);
const [name, setName] = useState(form?.name);
const [description, setDescription] = useState(form?.description);
const [encounterType, setEncounterType] = useState(
form?.encounterType?.uuid || ""
);
const [version, setVersion] = useState(form?.version);
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [encounterType, setEncounterType] = useState("");
const [version, setVersion] = useState("");

const clearDraftFormSchema = useCallback(
() => localStorage.removeItem("formSchema"),
[]
);

useEffect(() => {
if (schema) {
setName(schema.name);
setDescription(schema.description);
setEncounterType(schema.encounterType);
setVersion(schema.version);
}
}, [schema]);

const checkVersionValidity = (version: string) => {
if (!version) return setIsInvalidVersion(false);

Expand Down Expand Up @@ -297,27 +304,28 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
<FormGroup legendText={""}>
<Stack gap={5}>
<TextInput
defaultValue={schema?.name || form?.name}
id="name"
labelText={t("formName", "Form name")}
onChange={(event) => setName(event.target.value)}
placeholder="e.g. OHRI Express Care Patient Encounter Form"
placeholder={t(
"formNamePlaceholder",
"e.g. OHRI Express Care Patient Encounter Form"
)}
required
value={name}
/>
{saveState === "update" ? (
<TextInput
id="uuid"
labelText="UUID (auto-generated)"
labelText={t("autogeneratedUuid", "UUID (auto-generated")}
disabled
value={schema?.uuid || form?.uuid}
value={form?.uuid}
/>
) : null}
<TextInput
defaultValue={schema?.version || form?.version}
id="version"
labelText="Version"
labelText={t("version", "Version")}
placeholder="e.g. 1.0"
required
onChange={(event) => {
checkVersionValidity(event.target.value);

Expand All @@ -330,33 +338,38 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
"invalidVersionWarning",
"Version can only start with with a number"
)}
required
value={version}
/>
<Select
id="encounterType"
defaultValue={encounterType}
onChange={(event) => setEncounterType(event.target.value)}
labelText={t("encounterType", "Encounter Type")}
onChange={(event) => setEncounterType(event.target.value)}
required
value={encounterType}
>
{!form?.encounterType ? (
{!encounterType ? (
<SelectItem
text={t(
"chooseEncounterType",
"Choose an encounter type to link your form to"
)}
value=""
/>
) : null}
{encounterTypes?.map((encounterType, key) => (
<SelectItem
key={key}
value={encounterType.uuid}
text={encounterType.name}
/>
))}
{encounterTypes?.length > 0 &&
encounterTypes.map((encounterType) => (
<SelectItem
key={encounterType.uuid}
value={encounterType.uuid}
text={encounterType.name}
>
{encounterType.name}
</SelectItem>
))}
</Select>
<TextArea
labelText={t("description", "Description")}
defaultValue={saveState === "update" ? form?.description : ""}
onChange={(event) => setDescription(event.target.value)}
cols={6}
rows={3}
Expand All @@ -366,6 +379,7 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
"e.g. A form used to collect encounter data for clients in the Express Care program."
)}
required
value={description}
/>
</Stack>
</FormGroup>
Expand Down
File renamed without changes.
32 changes: 17 additions & 15 deletions src/components/schema-editor/schema-editor.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,26 +135,28 @@ const SchemaEditor: React.FC<SchemaEditorProps> = ({
/>
) : null}

{isNewSchema ? (
{isNewSchema && !stringifiedSchema ? (
<Button kind="secondary" onClick={inputDummySchema}>
{t("inputDummySchema", "Input dummy schema")}
</Button>
) : null}

<Button
disabled={isRendering}
kind="primary"
onClick={renderSchemaChanges}
>
{isRendering ? (
<InlineLoading
className={styles.spinner}
description={t("rendering", "Rendering") + "..."}
/>
) : (
<span>{t("renderChanges", "Render changes")}</span>
)}
</Button>
{schema ? (
<Button
disabled={isRendering}
kind="primary"
onClick={renderSchemaChanges}
>
{isRendering ? (
<InlineLoading
className={styles.spinner}
description={t("render", "Render" + "...")}
/>
) : (
<span>{t("renderChanges", "Render changes")}</span>
)}
</Button>
) : null}
</div>

{invalidJsonErrorMessage ? (
Expand Down
Loading

0 comments on commit be40ecf

Please sign in to comment.