From 4429d742b3fc783635be10282f342751ddb4e720 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sat, 7 Dec 2024 01:35:59 +0200 Subject: [PATCH] document conditions --- app/controllers/templates_controller.rb | 2 +- app/javascript/form.js | 1 + app/javascript/submission_form/form.vue | 50 ++++++++++++++++- app/javascript/template_builder/area.vue | 2 +- app/javascript/template_builder/builder.vue | 17 ++++++ .../template_builder/conditions_modal.vue | 32 ++++++----- app/javascript/template_builder/field.vue | 4 +- app/javascript/template_builder/fields.vue | 12 +++++ app/javascript/template_builder/preview.vue | 48 ++++++++++++++++- app/views/submissions/show.html.erb | 7 +-- .../submit_form/_submission_form.html.erb | 2 +- app/views/submit_form/show.html.erb | 53 ++++++++++--------- lib/submissions.rb | 38 +++++++++++++ .../generate_combined_attachment.rb | 2 + .../generate_preview_attachments.rb | 4 +- .../generate_result_attachments.rb | 36 ++++++++----- lib/submitters/submit_values.rb | 7 +++ 17 files changed, 252 insertions(+), 65 deletions(-) diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index 306476b2..0d414755 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -109,7 +109,7 @@ class TemplatesController < ApplicationController def template_params params.require(:template).permit( :name, - { schema: [%i[attachment_uuid name]], + { schema: [[:attachment_uuid, :name, { conditions: [%i[field_uuid value action operation]] }]], submitters: [%i[name uuid is_requester linked_to_uuid invite_by_uuid email]], fields: [[:uuid, :submitter_uuid, :name, :type, :required, :readonly, :default_value, diff --git a/app/javascript/form.js b/app/javascript/form.js index 604d06a4..f9583da6 100644 --- a/app/javascript/form.js +++ b/app/javascript/form.js @@ -15,6 +15,7 @@ safeRegisterElement('submission-form', class extends HTMLElement { this.app = createApp(Form, { submitter: JSON.parse(this.dataset.submitter), inviteSubmitters: JSON.parse(this.dataset.inviteSubmitters), + schema: JSON.parse(this.dataset.schema), canSendEmail: this.dataset.canSendEmail === 'true', previousSignatureValue: this.dataset.previousSignatureValue, goToLast: this.dataset.goToLast === 'true', diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index 53b666d5..f8c4031d 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -652,6 +652,11 @@ export default { required: false, default: null }, + schema: { + type: Array, + required: false, + default: () => [] + }, attachments: { type: Array, required: false, @@ -841,6 +846,21 @@ export default { isMobile () { return /android|iphone|ipad/i.test(navigator.userAgent) }, + attachmentConditionsIndex () { + return this.schema.reduce((acc, item) => { + if (item.conditions?.length) { + if (item.conditions.every((c) => this.fieldsUuidIndex[c.field_uuid])) { + acc[item.attachment_uuid] = this.checkFieldConditions(item) + } else { + acc[item.attachment_uuid] = true + } + } else { + acc[item.attachment_uuid] = true + } + + return acc + }, {}) + }, emptyValueRequiredStep () { return this.stepFields.find((fields, index) => { return fields.some((f) => { @@ -921,7 +941,7 @@ export default { return this.currentStepFields[0] }, readonlyConditionalFields () { - return this.fields.filter((f) => f.readonly && f.conditions?.length && this.checkFieldConditions(f)) + return this.fields.filter((f) => f.readonly && f.conditions?.length && this.checkFieldConditions(f) && this.checkFieldDocumentsConditions(f)) }, stepFields () { const verificationFields = [] @@ -943,7 +963,7 @@ export default { return sortedFields.reduce((acc, f) => { const prevStep = acc[acc.length - 1] - if (this.checkFieldConditions(f)) { + if (this.checkFieldConditions(f) && this.checkFieldDocumentsConditions(f)) { if (f.type === 'checkbox' && Array.isArray(prevStep) && prevStep[0].type === 'checkbox' && !f.description) { prevStep.push(f) } else { @@ -976,6 +996,23 @@ export default { if (isEmpty(value) && this.currentStep > 0) { this.currentStep -= 1 } + }, + attachmentConditionsIndex: { + deep: true, + immediate: true, + handler (value) { + this.$nextTick(() => { + const root = this.$root.$el.parentNode.getRootNode() + + for (const key in value) { + const doc = root.querySelector(`[id="document-${key}"`) + + if (doc) { + doc.classList.toggle('hidden', !value[key]) + } + } + }) + } } }, beforeUnmount () { @@ -1057,6 +1094,15 @@ export default { onOrientationChange (event) { this.orientation = event.target.type }, + checkFieldDocumentsConditions (field) { + if (field.areas?.length) { + return field.areas.some((area) => { + return this.attachmentConditionsIndex[area.attachment_uuid] + }) + } else { + return true + } + }, checkFieldConditions (field) { if (field.conditions?.length) { const result = field.conditions.reduce((acc, cond) => { diff --git a/app/javascript/template_builder/area.vue b/app/javascript/template_builder/area.vue index 61439a78..6211bf51 100644 --- a/app/javascript/template_builder/area.vue +++ b/app/javascript/template_builder/area.vue @@ -257,7 +257,7 @@ :to="modalContainerEl" > diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index d8a9c3dc..99550031 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -362,6 +362,7 @@ :default-submitters="defaultSubmitters" :draw-field-type="drawFieldType" :default-fields="[...defaultRequiredFields, ...defaultFields]" + :template="template" :default-required-fields="defaultRequiredFields" :field-types="fieldTypes" :with-sticky-submitters="withStickySubmitters" @@ -1023,6 +1024,22 @@ export default { if (!field.areas.length) { this.template.fields.splice(this.template.fields.indexOf(field), 1) + + this.template.fields.forEach((f) => { + (f.conditions || []).forEach((c) => { + if (c.field_uuid === field.uuid) { + f.conditions.splice(f.conditions.indexOf(c), 1) + } + }) + }) + + this.template.schema.forEach((item) => { + (item.conditions || []).forEach((c) => { + if (c.field_uuid === field.uuid) { + item.conditions.splice(item.conditions.indexOf(c), 1) + } + }) + }) } this.save() diff --git a/app/javascript/template_builder/conditions_modal.vue b/app/javascript/template_builder/conditions_modal.vue index 3fbe1313..5bcc0129 100644 --- a/app/javascript/template_builder/conditions_modal.vue +++ b/app/javascript/template_builder/conditions_modal.vue @@ -9,7 +9,7 @@