From 2375aaadc49669d35dcfb859f8f6ad0a17b1e879 Mon Sep 17 00:00:00 2001 From: Narender Raju B Date: Mon, 16 Sep 2024 10:52:22 +0100 Subject: [PATCH] FS:4616: FS-Feature/refactor import script for builder adapter (#31) * Update datetime formats for round config * make outputsas empty [] * Add multiline text component and fix org question template * add multilinetext field component type * remove backlinktext references * format date fields and add docker compose with form runner --- README.md | 53 +- app/all_questions/metadata_utils.py | 1 + app/blueprints/fund_builder/forms/round.py | 15 +- app/blueprints/fund_builder/routes.py | 7 - .../fund_builder/templates/round.html | 11 +- .../templates/view_fund_config.html | 10 +- .../~2024_09_10_1717-d69508409404_.py | 24 + app/db/models/application_config.py | 4 + app/export_config/generate_form.py | 10 +- .../generate_fund_round_form_jsons.py | 16 - .../asset-information-cof-r3-w2.json | 12 +- .../organisation-infomation.json | 502 ++++++++++++++++++ app/import_config/load_form_json.py | 2 +- app/templates/macros/wtfToGovUk.html | 14 + docker-compose-dev.yml | 53 ++ tasks/export_tasks.py | 3 - tests/test-import-form.json | 12 +- tests/test_build_forms.py | 22 +- tests/test_config_export.py | 9 +- 19 files changed, 634 insertions(+), 146 deletions(-) create mode 100644 app/db/migrations/versions/~2024_09_10_1717-d69508409404_.py create mode 100644 app/import_config/files_to_import/organisation-infomation.json create mode 100644 docker-compose-dev.yml diff --git a/README.md b/README.md index 7b8c6fdd..97bbfc89 100644 --- a/README.md +++ b/README.md @@ -48,55 +48,12 @@ Below is a docker-compose file that will start both the FAB app, and the form ru ``` workspace | - dc - | - docker-compose.yml - | - digital-form-builder + | - docker-compose-dev.yml + | - digital-form-builder-adapter | - funding-service-design-fund-application-builder ``` +To run locally using digital-form-builder-adapter + +docker-compose -f docker-compose-dev.yml up -``` -services: - fab: - hostname: fab - build: - context: ../funding-service-design-fund-application-builder - dockerfile: Dockerfile - command: ["sh", "-c", "python -m flask db upgrade && inv create-test-data && python -m flask run --host 0.0.0.0 --port 8080"] - ports: - - 8080:8080 - environment: - - FORM_RUNNER_INTERNAL_HOST=http://form-runner:3009 - - FORM_RUNNER_EXTERNAL_HOST=http://localhost:3009 - - DATABASE_URL=postgresql://postgres:password@fab-db:5432/fund_builder # pragma: allowlist secret - depends_on: [fab-db] - - fab-db: - image: postgres - environment: - - POSTGRES_PASSWORD=password - - POSTGRES_DB=fund_builder - - form-runner: - build: - context: ../digital-form-builder - dockerfile: ./fsd_config/Dockerfile - command: yarn runner startdebug - links: - - fab:fab - ports: - - 3009:3009 - - 9228:9228 - environment: - - LOG_LEVEL=debug - - 'NODE_CONFIG={"safelist": ["fab"]}' - - CONTACT_US_URL=http://localhost:3008/contact_us - - FEEDBACK_LINK=http://localhost:3008/feedback - - COOKIE_POLICY_URL=http://localhost:3008/cookie_policy - - ACCESSIBILITY_STATEMENT_URL=http://localhost:3008/accessibility_statement - - SERVICE_START_PAGE=http://localhost:3008/account - - MULTIFUND_URL=http://localhost:3008/account - - LOGOUT_URL=http://localhost:3004/sessions/sign-out - - PRIVACY_POLICY_URL=http://localhost:3008/privacy - - ELIGIBILITY_RESULT_URL=http://localhost:3008/eligibility-result - - PREVIEW_MODE=true - - NODE_ENV=development ``` diff --git a/app/all_questions/metadata_utils.py b/app/all_questions/metadata_utils.py index 08f1c15c..83c527fa 100644 --- a/app/all_questions/metadata_utils.py +++ b/app/all_questions/metadata_utils.py @@ -554,6 +554,7 @@ def generate_print_data_for_form(section_idx: int, form_metadata: dict, form_idx "freetextfield": "free_text", "checkboxesfield": "list", "multiinputfield": "table", + "multilinetextfield": "text", "clientsidefileuploadfield": "s3bucketPath", "radiosfield": "text", "emailaddressfield": "text", diff --git a/app/blueprints/fund_builder/forms/round.py b/app/blueprints/fund_builder/forms/round.py index d55b5a42..5f537207 100644 --- a/app/blueprints/fund_builder/forms/round.py +++ b/app/blueprints/fund_builder/forms/round.py @@ -17,10 +17,15 @@ class RoundForm(FlaskForm): description="Choose a unique short name with 6 or fewer characters", validators=[DataRequired(), Length(max=6)], ) - opens = DateTimeField("Opens", format="%d-%m-%Y %H:%M", validators=[DataRequired()]) - deadline = DateTimeField("Deadline", format="%d-%m-%Y %H:%M", validators=[DataRequired()]) - assessment_start = DateTimeField("Assessment Start", format="%d-%m-%Y %H:%M", validators=[DataRequired()]) - reminder_date = DateTimeField("Reminder Date", format="%d-%m-%Y %H:%M", validators=[DataRequired()]) - assessment_deadline = DateTimeField("Assessment Deadline", format="%d-%m-%Y %H:%M", validators=[DataRequired()]) + opens = DateTimeField("Opens", description="Enter date in dd-mm-yyyy hh:mi format", + format="%d-%m-%Y %H:%M", validators=[DataRequired()]) + deadline = DateTimeField("Deadline", description="Enter date in dd-mm-yyyy hh:mi format", + format="%d-%m-%Y %H:%M", validators=[DataRequired()]) + assessment_start = DateTimeField("Assessment Start", description="Enter date in dd-mm-yyyy hh:mi format", + format="%d-%m-%Y %H:%M", validators=[DataRequired()]) + reminder_date = DateTimeField("Reminder Date", description="Enter date in dd-mm-yyyy hh:mi format", + format="%d-%m-%Y %H:%M", validators=[DataRequired()]) + assessment_deadline = DateTimeField("Assessment Deadline", description="Enter date in dd-mm-yyyy hh:mi format", + format="%d-%m-%Y %H:%M", validators=[DataRequired()]) prospectus_link = URLField("Prospectus Link", validators=[DataRequired(), URL()]) privacy_notice_link = URLField("Privacy Notice Link", validators=[DataRequired(), URL()]) diff --git a/app/blueprints/fund_builder/routes.py b/app/blueprints/fund_builder/routes.py index b4158460..60c63c32 100644 --- a/app/blueprints/fund_builder/routes.py +++ b/app/blueprints/fund_builder/routes.py @@ -253,10 +253,6 @@ def preview_form(form_id): form = get_form_by_id(form_id) form_json = build_form_json(form) - # Update the savePerPageUrl to point at the dev route to save responses - form_json["outputs"][0]["outputConfiguration"][ - "savePerPageUrl" - ] = f"http://{Config.FAB_HOST}{Config.FAB_SAVE_PER_PAGE}" try: publish_response = requests.post( url=f"{Config.FORM_RUNNER_URL}/publish", json={"id": form.runner_publish_name, "configuration": form_json} @@ -276,9 +272,6 @@ def download_form_json(form_id): form = get_form_by_id(form_id) form_json = build_form_json(form) - form_json["outputs"][0]["outputConfiguration"][ - "savePerPageUrl" - ] = f"http://{Config.FAB_HOST}{Config.FAB_SAVE_PER_PAGE}" return Response( response=json.dumps(form_json), mimetype="application/json", diff --git a/app/blueprints/fund_builder/templates/round.html b/app/blueprints/fund_builder/templates/round.html index 4d64dbac..4ce61b71 100644 --- a/app/blueprints/fund_builder/templates/round.html +++ b/app/blueprints/fund_builder/templates/round.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% from "macros/wtfToGovUk.html" import input %} +{% from "macros/wtfToGovUk.html" import dateinput %} {% from "macros/wtfToGovUk.html" import yes_no %} {%- from "govuk_frontend_jinja/components/button/macro.html" import govukButton -%} {%- from "govuk_frontend_jinja/components/select/macro.html" import govukSelect -%} @@ -20,11 +21,11 @@

Create a Round

"items": all_funds})}} {{input(form.title_en)}} {{input(form.short_name)}} - {{input(form.opens)}} - {{input(form.deadline)}} - {{input(form.assessment_start)}} - {{input(form.reminder_date)}} - {{input(form.assessment_deadline)}} + {{dateinput(form.opens)}} + {{dateinput(form.deadline)}} + {{dateinput(form.assessment_start)}} + {{dateinput(form.reminder_date)}} + {{dateinput(form.assessment_deadline)}} {{input(form.prospectus_link)}} {{input(form.privacy_notice_link)}} diff --git a/app/blueprints/fund_builder/templates/view_fund_config.html b/app/blueprints/fund_builder/templates/view_fund_config.html index 2986137c..2c27c92b 100644 --- a/app/blueprints/fund_builder/templates/view_fund_config.html +++ b/app/blueprints/fund_builder/templates/view_fund_config.html @@ -90,7 +90,7 @@

{{round.title_json["en"]}}

"text": "Opens Date" }, "value": { - "text": round.opens + "text": round.opens.strftime('%d-%m-%Y %H:%M') }, }, @@ -99,7 +99,7 @@

{{round.title_json["en"]}}

"text": "Deadline Date" }, "value": { - "text": round.deadline + "text": round.deadline.strftime('%d-%m-%Y %H:%M') }, }, @@ -108,7 +108,7 @@

{{round.title_json["en"]}}

"text": "Assessment Start Date" }, "value": { - "text": round.assessment_start + "text": round.assessment_start.strftime('%d-%m-%Y %H:%M') }, }, @@ -117,7 +117,7 @@

{{round.title_json["en"]}}

"text": "Assessment Deadline Date" }, "value": { - "text": round.assessment_deadline + "text": round.assessment_deadline.strftime('%d-%m-%Y %H:%M') }, }, @@ -126,7 +126,7 @@

{{round.title_json["en"]}}

"text": "Reminder Date" }, "value": { - "text": round.reminder_date + "text": round.reminder_date.strftime('%d-%m-%Y %H:%M') }, }, { diff --git a/app/db/migrations/versions/~2024_09_10_1717-d69508409404_.py b/app/db/migrations/versions/~2024_09_10_1717-d69508409404_.py new file mode 100644 index 00000000..799a85c9 --- /dev/null +++ b/app/db/migrations/versions/~2024_09_10_1717-d69508409404_.py @@ -0,0 +1,24 @@ +"""empty message + +Revision ID: d69508409404 +Revises: 117417bed885 +Create Date: 2024-09-10 17:17:58.014693 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'd69508409404' +down_revision = '117417bed885' +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("ALTER TYPE componenttype ADD VALUE 'MULTILINE_TEXT_FIELD';") + + +def downgrade(): + pass diff --git a/app/db/models/application_config.py b/app/db/models/application_config.py index d0810f60..a4cd0f3a 100644 --- a/app/db/models/application_config.py +++ b/app/db/models/application_config.py @@ -40,6 +40,8 @@ class ComponentType(Enum): CHECKBOXES_FIELD = "CheckboxesField" CLIENT_SIDE_FILE_UPLOAD_FIELD = "ClientSideFileUploadField" WEBSITE_FIELD = "WebsiteField" + MULTILINE_TEXT_FIELD = "MultilineTextField" + @dataclass @@ -226,6 +228,8 @@ def assessment_display_type(self): "yesnofield": "text", "freetextfield": "free_text", "checkboxesfield": "list", + #TODO add multilinetext field and update types of components in sync with formrunner + #"multilinetextfield": "list", "multiinputfield": "table", "clientsidefileuploadfield": "s3bucketPath", "radiosfield": "text", diff --git a/app/export_config/generate_form.py b/app/export_config/generate_form.py index de888b60..67f9dca0 100644 --- a/app/export_config/generate_form.py +++ b/app/export_config/generate_form.py @@ -9,20 +9,12 @@ BASIC_FORM_STRUCTURE = { "metadata": {}, "startPage": None, - "backLinkText": "Go back to application overview", "pages": [], "lists": [], "conditions": [], "fees": [], "sections": [], - "outputs": [ - { - "name": "update-form", - "title": "Update form in application store", - "type": "savePerPage", - "outputConfiguration": {"savePerPageUrl": True}, - } - ], + "outputs": [], "skipSummary": False, "name": "", } diff --git a/app/export_config/generate_fund_round_form_jsons.py b/app/export_config/generate_fund_round_form_jsons.py index 7538f369..0ab22cad 100644 --- a/app/export_config/generate_fund_round_form_jsons.py +++ b/app/export_config/generate_fund_round_form_jsons.py @@ -14,7 +14,6 @@ "name": {"type": "string"}, "metadata": {"type": "object"}, "startPage": {"type": "string"}, - "backLinkText": {"type": "string"}, "sections": {"type": "array"}, "pages": { "type": "array", @@ -52,20 +51,6 @@ "fees": {"type": "array"}, "outputs": { "type": "array", - "items": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "title": {"type": "string"}, - "type": {"type": "string"}, - "outputConfiguration": { - "type": "object", - "properties": {"savePerPageUrl": {"type": "boolean"}}, - "required": ["savePerPageUrl"], - }, - }, - "required": ["name", "title", "type", "outputConfiguration"], - }, }, "skipSummary": {"type": "boolean"}, # Add other top-level keys as needed @@ -73,7 +58,6 @@ "required": [ "metadata", "startPage", - "backLinkText", "pages", "lists", "conditions", diff --git a/app/import_config/files_to_import/asset-information-cof-r3-w2.json b/app/import_config/files_to_import/asset-information-cof-r3-w2.json index 4f5ce545..7091801e 100644 --- a/app/import_config/files_to_import/asset-information-cof-r3-w2.json +++ b/app/import_config/files_to_import/asset-information-cof-r3-w2.json @@ -1,7 +1,6 @@ { "metadata": {}, "startPage": "/asset-information", - "backLinkText": "Go back to application overview", "pages": [ { "title": "Asset information", @@ -980,16 +979,7 @@ } ], "fees": [], - "outputs": [ - { - "name": "update-form", - "title": "Update form in application store", - "type": "savePerPage", - "outputConfiguration": { - "savePerPageUrl": "True" - } - } - ], + "outputs": [], "version": 2, "skipSummary": false, "name": "Apply for funding to save an asset in your community", diff --git a/app/import_config/files_to_import/organisation-infomation.json b/app/import_config/files_to_import/organisation-infomation.json new file mode 100644 index 00000000..c6ba7f13 --- /dev/null +++ b/app/import_config/files_to_import/organisation-infomation.json @@ -0,0 +1,502 @@ +{ + "metadata": {}, + "startPage": "/name-your-application", + "pages": [ + { + "path": "/name-your-application", + "title": "Name your application", + "components": [ + { + "name": "COlBrB", + "options": {}, + "type": "TextField", + "title": "Name your organisation", + "hint": "This is what your application will be called and will help you find it when you save and return. ", + "schema": {} + } + ], + "next": [ + { + "path": "/organisation-name" + } + ], + "controller": "./pages/start.js" + }, + { + "path": "/organisation-name", + "title": "Organisation name", + "components": [ + { + "name": "yptqZX", + "options": {}, + "type": "TextField", + "title": "Organisation name", + "hint": "This must match your registered legal \norganisation name.", + "schema": {} + }, + { + "name": "BIxPht", + "options": { + "exposeToContext": true + }, + "type": "YesNoField", + "title": "Does your organisation use any other names?", + "schema": {} + } + ], + "next": [ + { + "path": "/alternative-organisation-names", + "condition": "lgQzEs" + }, + { + "path": "/registered-organisation-address" + } + ] + }, + { + "path": "/alternative-organisation-names", + "title": "Alternative organisation names", + "components": [ + { + "name": "Ianpnw", + "options": {}, + "type": "TextField", + "title": "Alternative name 1", + "schema": {} + }, + { + "name": "CTyQWf", + "options": { + "required": false + }, + "type": "TextField", + "title": "Alternative name 2", + "schema": {} + }, + { + "name": "XWsTKi", + "options": { + "required": false + }, + "type": "TextField", + "title": "Alternative name 3", + "schema": {} + } + ], + "next": [ + { + "path": "/registered-organisation-address" + } + ] + }, + { + "path": "/registered-organisation-address", + "title": "Registered organisation address", + "components": [ + { + "name": "fWPSFw", + "options": {}, + "type": "UkAddressField", + "title": "Registered organisation address", + "schema": {} + }, + { + "name": "sBRPjm", + "options": { + "required": true, + "exposeToContext": true + }, + "type": "YesNoField", + "title": "Is your correspondence address different to the organisation address? ", + "values": { + "type": "listRef" + }, + "schema": {} + } + ], + "next": [ + { + "path": "/how-long-has-your-organisation-been-operating" + }, + { + "path": "/alternative-organisation-address", + "condition": "IDVkcD" + } + ] + }, + { + "path": "/alternative-organisation-address", + "title": "Alternative organisation address", + "components": [ + { + "name": "vFAPcU", + "options": {}, + "type": "UkAddressField", + "title": "Alternative organisation address", + "schema": {} + } + ], + "next": [ + { + "path": "/how-long-has-your-organisation-been-operating" + } + ] + }, + { + "path": "/how-long-has-your-organisation-been-operating", + "title": "How long has your organisation been operating?", + "components": [ + { + "name": "zJCwtU", + "options": {}, + "type": "RadiosField", + "title": "How long has your organisation been operating?", + "hint": "Select one option.", + "list": "RfMTRE", + "schema": {} + } + ], + "next": [ + { + "path": "/how-is-your-organisation-classified" + } + ] + }, + { + "path": "/how-is-your-organisation-classified", + "title": "How is your organisation classified?", + "components": [ + { + "name": "TiKRCy", + "options": { + "exposeToContext": true + }, + "type": "RadiosField", + "title": "How is your organisation classified?", + "list": "hIdeMS", + "schema": {}, + "values": { + "type": "listRef" + } + } + ], + "next": [ + { + "path": "/type-of-organisation", + "condition": "JbdMiD" + }, + { + "path": "/what-is-your-organisations-main-purpose" + } + ] + }, + { + "path": "/type-of-organisation", + "title": "Type of organisation", + "components": [ + { + "name": "Gwffox", + "options": {}, + "type": "TextField", + "title": "Type of organisation", + "schema": {} + } + ], + "next": [ + { + "path": "/what-is-your-organisations-main-purpose" + } + ] + }, + { + "path": "/what-is-your-organisations-main-purpose", + "title": "What is your organisation's main purpose?", + "components": [ + { + "name": "NHrbzp", + "options": {}, + "type": "MultilineTextField", + "title": "What is your organisation's main purpose?", + "schema": {} + } + ], + "next": [ + { + "path": "/what-are-your-organisations-charitable-objects" + } + ] + }, + { + "path": "/what-are-your-organisations-charitable-objects", + "title": "What are your organisation's charitable objects?", + "components": [ + { + "name": "YajnbX", + "options": {}, + "type": "MultilineTextField", + "title": "What are your organisation's charitable objects?", + "schema": {} + } + ], + "next": [ + { + "path": "/tell-us-about-your-organisations-main-activities" + } + ] + }, + { + "path": "/tell-us-about-your-organisations-main-activities", + "title": "Tell us about your organisation's main activities", + "components": [ + { + "name": "oPRoIH", + "options": {}, + "type": "MultilineTextField", + "title": "Main activity 1", + "schema": {} + }, + { + "name": "NyRDZz", + "options": { + "required": false + }, + "type": "MultilineTextField", + "title": "Activity 2", + "schema": {} + }, + { + "name": "uzcNFr", + "options": { + "required": false + }, + "type": "MultilineTextField", + "title": "Activity 3", + "schema": {} + } + ], + "next": [ + { + "path": "/website-and-social-media" + } + ] + }, + { + "path": "/website-and-social-media", + "title": "Website and social media", + "components": [ + { + "name": "mKRYeZ", + "options": { + "required": false + }, + "type": "WebsiteField", + "title": "Website", + "schema": {} + }, + { + "name": "MchsWa", + "options": { + "required": false + }, + "type": "WebsiteField", + "title": "Social media link 1", + "hint": "For example, your company's Facebook, Instagram or Twitter accounts (if applicable)", + "schema": {} + }, + { + "name": "vuzmuP", + "options": { + "required": false + }, + "type": "WebsiteField", + "title": "Social media link 2", + "hint": "For example, your company's Facebook, Instagram or Twitter accounts (if applicable)", + "schema": {} + }, + { + "name": "GUdRfh", + "options": {}, + "type": "WebsiteField", + "hint": "For example, your company's Facebook, Instagram or Twitter accounts (if applicable)", + "title": "Social media link 3", + "schema": {} + } + ], + "next": [ + { + "path": "/check-your-answers-JhIdAf" + } + ] + }, + { + "path": "/check-your-answers-JhIdAf", + "title": "Check your answers", + "components": [], + "next": [], + "controller": "./pages/summary.js" + } + ], + "lists": [ + { + "title": "orgslist", + "name": "MKPFgi", + "type": "string", + "items": [ + { + "text": "org1", + "value": "org1", + "condition": "FRfKzH" + }, + { + "text": "org2", + "value": "org2", + "condition": "FOtfdc" + } + ] + }, + { + "title": "other", + "name": "bErzTp", + "type": "string", + "items": [ + { + "text": "others", + "value": "other" + } + ] + }, + { + "title": "Organisation operating time", + "name": "RfMTRE", + "type": "string", + "items": [ + { + "text": "Less than 1 year", + "value": "Less than 1 year" + }, + { + "text": "More than 1 year, but less than 3", + "value": "More than 1 year, but less than 3" + }, + { + "text": "More than 3 years", + "value": "More than 3 years" + } + ] + }, + { + "title": "Organisation classification", + "name": "hIdeMS", + "type": "string", + "items": [ + { + "text": "Charitable incorporated organisation (CIO)", + "value": "Charitable incorporated organisation (CIO)" + }, + { + "text": "Co-operative", + "description": "For example, a community benefit society", + "value": "Co-operative" + }, + { + "text": "Community interest company (CIC)", + "value": "Community interest company (CIC)" + }, + { + "text": "Company limited by guarantee", + "value": "Company limited by guarantee" + }, + { + "text": "None of these", + "value": "None of these" + } + ] + } + ], + "sections": [], + "conditions": [ + { + "displayName": "Alternative organisation name", + "name": "lgQzEs", + "value": { + "name": "Alternative organisation name", + "conditions": [ + { + "field": { + "name": "BIxPht", + "type": "YesNoField", + "display": "Does your organisation use any other names?" + }, + "operator": "is", + "value": { + "type": "Value", + "value": "true", + "display": "true" + } + } + ] + } + }, + { + "displayName": "Alternative organisation address", + "name": "IDVkcD", + "value": { + "name": "Alternative organisation address", + "conditions": [ + { + "field": { + "name": "sBRPjm", + "type": "YesNoField", + "display": "Is your correspondence address different to the organisation address? " + }, + "operator": "is", + "value": { + "type": "Value", + "value": "true", + "display": "true" + } + } + ] + } + }, + { + "displayName": "Other organisation type", + "name": "JbdMiD", + "value": { + "name": "Other organisation type", + "conditions": [ + { + "field": { + "name": "TiKRCy", + "type": "RadiosField", + "display": "How is your organisation classified?" + }, + "operator": "is", + "value": { + "type": "Value", + "value": "None of these", + "display": "None of these" + } + } + ] + } + } + ], + "fees": [], + "outputs": [], + "version": 2, + "skipSummary": false, + "feeOptions": { + "allowSubmissionWithoutPayment": true, + "maxAttempts": 3, + "showPaymentSkippedWarningPage": false + }, + "markAsComplete": false, + "name": "Organisation information template (September 2024)", + "feedback": { + "feedbackForm": false, + "url": "" + }, + "phaseBanner": {} +} \ No newline at end of file diff --git a/app/import_config/load_form_json.py b/app/import_config/load_form_json.py index e5bb5324..254a0ced 100644 --- a/app/import_config/load_form_json.py +++ b/app/import_config/load_form_json.py @@ -168,7 +168,7 @@ def insert_form_config(form_config, form_id): db.session.flush() # flush to make components available for conditions add_conditions_to_components(db, page, form_config["conditions"]) insert_page_default_next_page(form_config.get("pages", None), inserted_pages) - db + db.session.flush() return inserted_pages, inserted_components diff --git a/app/templates/macros/wtfToGovUk.html b/app/templates/macros/wtfToGovUk.html index 7139289a..ef3d8c4f 100644 --- a/app/templates/macros/wtfToGovUk.html +++ b/app/templates/macros/wtfToGovUk.html @@ -16,6 +16,20 @@ }) }} {%endmacro%} +{% macro dateinput(form_field) %} +{{ govukInput({ +"label": { +"text": form_field.label , +"isPageHeading": false +}, +"id": form_field.id, +"name": form_field.name , +"value": form_field.data.strftime('%d-%m-%Y %H:%M') if form_field.data else '', +"errorMessage": {"text": form_field.errors[0]} if (form_field.errors | length > 0) else None, +"hint":{"text":form_field.description} +}) }} +{%endmacro%} + {% macro yes_no(form_field) %} {{ govukRadios({ "name": form_field.name, diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 00000000..a52277c9 --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,53 @@ +services: + fab: + hostname: fab + build: + context: ../funding-service-design-fund-application-builder + dockerfile: Dockerfile + args: + - USE_DEV_REQUIREMENTS=true + volumes: ['../funding-service-design-fund-application-builder:/app'] + command: ["sh", "-c", "python -m flask db upgrade && python -m debugpy --listen 0.0.0.0:5601 -m flask run --no-debugger --host 0.0.0.0 --port 8080"] + ports: + - 8080:8080 + - 5686:5601 + environment: + - FORM_RUNNER_INTERNAL_HOST=http://form-runner:3009 + - FORM_RUNNER_EXTERNAL_HOST=http://localhost:3009 + - DATABASE_URL=postgresql://postgres:password@fab-db:5432/fund_builder # pragma: allowlist secret + - FLASK_DEBUG=0 + - FLASK_ENV=development + depends_on: [fab-db, form-runner] + + fab-db: + image: postgres + container_name: fab-db + ports: + - 5432:5432 + volumes: + - ~/apps/postgres:/var/lib/postgresql/data + environment: + - POSTGRES_PASSWORD=password + - POSTGRES_DB=fund_builder + - DATABASE_URL=postgresql://postgres:password@fab-db:5432/fund_builder + - DATABASE_URL_UNIT_TEST=postgresql://postgres:password@fab-db:5432/fab_unit_test + + form-runner: + container_name: form-runner + build: + context: ../digital-form-builder-adapter + dockerfile: ./runner/Dockerfile + ports: + - "3009:3009" + - 9228:9228 + command: yarn runner dev + environment: + - CHOKIDAR_USEPOLLING=true + - PREVIEW_MODE=true + - LAST_COMMIT + - LAST_TAG + - JWT_AUTH_ENABLED=false + - LOG_LEVEL=debug + - 'NODE_CONFIG={"safelist": ["fab"]}' + - PREVIEW_MODE=true + - NODE_ENV=development \ No newline at end of file diff --git a/tasks/export_tasks.py b/tasks/export_tasks.py index f5476263..12a3288f 100644 --- a/tasks/export_tasks.py +++ b/tasks/export_tasks.py @@ -63,9 +63,6 @@ def publish_form_json_to_runner(c, filename): with open(filename, "r") as file: form_json = file.read() form_dict = json.loads(form_json) - form_dict["outputs"][0]["outputConfiguration"][ - "savePerPageUrl" - ] = f"http://{Config.FAB_HOST}{Config.FAB_SAVE_PER_PAGE}" try: publish_response = requests.post( url=f"{Config.FORM_RUNNER_URL}/publish", diff --git a/tests/test-import-form.json b/tests/test-import-form.json index 4f5ce545..7091801e 100644 --- a/tests/test-import-form.json +++ b/tests/test-import-form.json @@ -1,7 +1,6 @@ { "metadata": {}, "startPage": "/asset-information", - "backLinkText": "Go back to application overview", "pages": [ { "title": "Asset information", @@ -980,16 +979,7 @@ } ], "fees": [], - "outputs": [ - { - "name": "update-form", - "title": "Update form in application store", - "type": "savePerPage", - "outputConfiguration": { - "savePerPageUrl": "True" - } - } - ], + "outputs": [], "version": 2, "skipSummary": false, "name": "Apply for funding to save an asset in your community", diff --git a/tests/test_build_forms.py b/tests/test_build_forms.py index b8bb4b81..fa85b7c3 100644 --- a/tests/test_build_forms.py +++ b/tests/test_build_forms.py @@ -367,16 +367,7 @@ # ], # "fees": [], # "sections": [], -# "outputs": [ -# { -# "name": "update-form", -# "title": "Update form in application store", -# "type": "savePerPage", -# "outputConfiguration": { -# "savePerPageUrl": "https://webhook.site/a8d808ca-bf5e-4aea-aebc-f3d9bc93a435" -# }, -# } -# ], +# "outputs": [], # "skipSummary": False, # "name": "Generated by question bank 2024-06-18 13:54:24.954418", # }, @@ -572,16 +563,7 @@ # ], # "fees": [], # "sections": [], -# "outputs": [ -# { -# "name": "update-form", -# "title": "Update form in application store", -# "type": "savePerPage", -# "outputConfiguration": { -# "savePerPageUrl": "https://webhook.site/a8d808ca-bf5e-4aea-aebc-f3d9bc93a435" -# }, -# } -# ], +# "outputs": [], # "skipSummary": False, # "name": "Generated by question bank 2024-06-18 13:54:24.954418", # }, diff --git a/tests/test_config_export.py b/tests/test_config_export.py index 4fc873a4..4ed45198 100644 --- a/tests/test_config_export.py +++ b/tests/test_config_export.py @@ -155,8 +155,8 @@ def test_generate_form_jsons_for_round_valid_input(seed_dynamic_data): { "path": output_base_path / round_short_name / "form_runner" / f"{form_publish_name}.json", "expected_output": ( - '{"metadata": {}, "startPage": "/intro-about-your-organisation", "backLinkText": ' - '"Go back to application overview", "pages": [{"path": "/organisation-name", "title": ' + '{"metadata": {}, "startPage": "/intro-about-your-organisation", ' + '"pages": [{"path": "/organisation-name", "title": ' '"Organisation Name", "components": [{"options": {"hideTitle": false, "classes": ""}, ' '"type": "TextField", "title": "What is your organisation\'s name?", "hint": "This ' 'must match the regsitered legal organisation name", "schema": {}, "name": ' @@ -171,9 +171,8 @@ def test_generate_form_jsons_for_round_valid_input(seed_dynamic_data): ' "title": "Check your answers", "components": [], "next": [], "section": "uLwBuz", "controller":' ' "./pages/summary.js"}], "lists": [{"type": "string", "items": [{"text": "Charity", "value":' ' "charity"}, {"text": "Public Limited Company", "value": "plc"}], "name": "classifications_list",' - ' "title": null}], "conditions": [], "fees": [], "sections": [], "outputs": [{"name": "update-form",' - ' "title": "Update form in application store", "type": "savePerPage", "outputConfiguration":' - ' {"savePerPageUrl": true}}], "skipSummary": false, "name": "About your organisation"}' + ' "title": null}], "conditions": [], "fees": [], "sections": [], "outputs": [], "skipSummary": false,' + ' "name": "About your organisation"}' ), } ]