diff --git a/src/components/computed-properties.vue b/src/components/computed-properties.vue index cfea940b3..a8e020150 100644 --- a/src/components/computed-properties.vue +++ b/src/components/computed-properties.vue @@ -15,79 +15,73 @@ @hidden="displayTableList" > diff --git a/src/components/sortable/sortableList/sortableList.scss b/src/components/sortable/sortableList/sortableList.scss index 117efdf5e..14be0d65c 100644 --- a/src/components/sortable/sortableList/sortableList.scss +++ b/src/components/sortable/sortableList/sortableList.scss @@ -2,44 +2,57 @@ $border-color: #cdddee; .sortable { &-list { - display: flex; + display: table; flex-direction: column; + width: 100%; border: 1px solid $border-color !important; - &-header { - display: flex; - align-items: center; + &-tr { + display: table-row; + + &:last-child > .sortable-list-td { + border-bottom: none; + } + } + + &-td { + display: table-cell; border-bottom: 1px solid $border-color; + + &:first-child { + width: 9%; + } + + &:nth-child(2) { + width: 40%; + } + + &:not(:first-child):not(:nth-child(2)):not(:last-child) { + width: auto; + } + + &:last-child { + width: 1%; + white-space: nowrap; + } } - &-title { - padding-left: 16px; + &-header { + padding: 16px 0 16px 16px; font-size: 14px; - font-weight: bold; + font-weight: 700; color: #566877; + text-transform: uppercase; } } - &-container { - display: flex; - flex-direction: column; - width: 100%; - height: 340px; - overflow-x: auto; - } - &-item { - display: flex; - align-items: center; - height: 56px; - border-bottom: 1px solid $border-color; cursor: move; &-icon { display: flex; justify-content: center; align-items: center; - width: 64px; height: 56px; } @@ -47,8 +60,7 @@ $border-color: #cdddee; color: #6A7888; } - &-name { - flex-grow: 1; + &-prop { padding: 8px 16px; font-size: 15px; color: #556271; @@ -65,6 +77,10 @@ $border-color: #cdddee; margin: 9px 0; border-right: 1px solid $border-color; } + + &-disabled > .sortable-item-prop { + color: rgba(85, 98, 113, 0.5); + } } } diff --git a/src/components/vue-form-builder.vue b/src/components/vue-form-builder.vue index a5eddd9ea..2bd11d336 100644 --- a/src/components/vue-form-builder.vue +++ b/src/components/vue-form-builder.vue @@ -368,16 +368,18 @@ :ok-title="$t('DONE')" ok-only ok-variant="secondary" - header-class = "modal-header-custom" + header-class="modal-header-custom" > - - + + + ","content":"Required"}],"placeholder":null,"defaultValue":{"mode":"basic","value":"{{first_name_calc}}"}},"component":"FormInput","inspector":[{"type":"FormInput","field":"name","config":{"name":"Variable Name","label":"Variable Name","helper":"A variable name is a symbolic name to reference information.","validation":"regex:\/^([a-zA-Z]([a-zA-Z0-9_]?)+\\.?)+(? Date ##\/##\/####
SSN ###-##-####
Phone (###) ###-####","validation":null}},{"type":"FormInput","field":"customCssSelector","config":{"label":"CSS Selector Name","helper":"Use this in your custom css rules","validation":"regex: [-?[_a-zA-Z]+[_-a-zA-Z0-9]*]"}},{"type":"FormInput","field":"ariaLabel","config":{"label":"Aria Label","helper":"Attribute designed to help assistive technology (e.g. screen readers) attach a label"}},{"type":"FormInput","field":"tabindex","config":{"label":"Tab Order","helper":"Order in which a user will move focus from one control to another by pressing the Tab key","validation":"regex: [0-9]*"}}],"editor-control":"FormInput","editor-component":"FormInput"},{"label":"Line Input","config":{"icon":"far fa-square","name":"last_name","type":"text","label":"Last Name","helper":null,"readonly":false,"dataFormat":"string","validation":[{"value":"required","helper":"Checks if the length of the String representation of the value is >","content":"Required"}],"placeholder":null,"defaultValue":{"mode":"basic","value":null}},"component":"FormInput","inspector":[{"type":"FormInput","field":"name","config":{"name":"Variable Name","label":"Variable Name","helper":"A variable name is a symbolic name to reference information.","validation":"regex:\/^([a-zA-Z]([a-zA-Z0-9_]?)+\\.?)+(? Date ##\/##\/####
SSN ###-##-####
Phone (###) ###-####","validation":null}},{"type":"FormInput","field":"customCssSelector","config":{"label":"CSS Selector Name","helper":"Use this in your custom css rules","validation":"regex: [-?[_a-zA-Z]+[_-a-zA-Z0-9]*]"}},{"type":"FormInput","field":"ariaLabel","config":{"label":"Aria Label","helper":"Attribute designed to help assistive technology (e.g. screen readers) attach a label"}},{"type":"FormInput","field":"tabindex","config":{"label":"Tab Order","helper":"Order in which a user will move focus from one control to another by pressing the Tab key","validation":"regex: [0-9]*"}}],"editor-control":"FormInput","editor-component":"FormInput"},{"label":"Line Input","config":{"icon":"far fa-square","name":"full_name","type":"text","label":"Full Name","helper":null,"readonly":false,"dataFormat":"string","validation":[{"value":"required","helper":"Checks if the length of the String representation of the value is >","content":"Required"}],"placeholder":null,"defaultValue":{"mode":"basic","value":null}},"component":"FormInput","inspector":[{"type":"FormInput","field":"name","config":{"name":"Variable Name","label":"Variable Name","helper":"A variable name is a symbolic name to reference information.","validation":"regex:\/^([a-zA-Z]([a-zA-Z0-9_]?)+\\.?)+(? Date ##\/##\/####
SSN ###-##-####
Phone (###) ###-####","validation":null}},{"type":"FormInput","field":"customCssSelector","config":{"label":"CSS Selector Name","helper":"Use this in your custom css rules","validation":"regex: [-?[_a-zA-Z]+[_-a-zA-Z0-9]*]"}},{"type":"FormInput","field":"ariaLabel","config":{"label":"Aria Label","helper":"Attribute designed to help assistive technology (e.g. screen readers) attach a label"}},{"type":"FormInput","field":"tabindex","config":{"label":"Tab Order","helper":"Order in which a user will move focus from one control to another by pressing the Tab key","validation":"regex: [0-9]*"}}],"editor-control":"FormInput","editor-component":"FormInput"},{"label":"Line Input","config":{"icon":"far fa-square","name":"email","type":"text","label":"Email","helper":null,"readonly":false,"dataFormat":"string","validation":[{"value":"required","helper":"Checks if the length of the String representation of the value is >","content":"Required"}],"placeholder":null,"defaultValue":{"mode":"basic","value":"{{first_name_calc}}"}},"component":"FormInput","inspector":[{"type":"FormInput","field":"name","config":{"name":"Variable Name","label":"Variable Name","helper":"A variable name is a symbolic name to reference information.","validation":"regex:\/^([a-zA-Z]([a-zA-Z0-9_]?)+\\.?)+(? Date ##\/##\/####
SSN ###-##-####
Phone (###) ###-####","validation":null}},{"type":"FormInput","field":"customCssSelector","config":{"label":"CSS Selector Name","helper":"Use this in your custom css rules","validation":"regex: [-?[_a-zA-Z]+[_-a-zA-Z0-9]*]"}},{"type":"FormInput","field":"ariaLabel","config":{"label":"Aria Label","helper":"Attribute designed to help assistive technology (e.g. screen readers) attach a label"}},{"type":"FormInput","field":"tabindex","config":{"label":"Tab Order","helper":"Order in which a user will move focus from one control to another by pressing the Tab key","validation":"regex: [0-9]*"}}],"editor-control":"FormInput","editor-component":"FormInput"},{"label":"Submit Button","config":{"icon":"fas fa-share-square","name":null,"event":"submit","label":"Save","loading":false,"tooltip":[],"variant":"primary","fieldValue":null,"loadingLabel":"Loading...","defaultSubmit":true},"component":"FormButton","inspector":[{"type":"FormInput","field":"label","config":{"label":"Label","helper":"The label describes the button's text"}},{"type":"FormInput","field":"name","config":{"name":"Variable Name","label":"Variable Name","helper":"A variable name is a symbolic name to reference information.","validation":"regex:\/^(?:[A-Za-z])(?:[0-9A-Z_.a-z])*(? Date ##\/##\/####
SSN ###-##-####
Phone (###) ###-####","validation":null}},{"type":"FormInput","field":"customCssSelector","config":{"label":"CSS Selector Name","helper":"Use this in your custom css rules","validation":"regex: [-?[_a-zA-Z]+[_-a-zA-Z0-9]*]"}},{"type":"FormInput","field":"ariaLabel","config":{"label":"Aria Label","helper":"Attribute designed to help assistive technology (e.g. screen readers) attach a label"}},{"type":"FormInput","field":"tabindex","config":{"label":"Tab Order","helper":"Order in which a user will move focus from one control to another by pressing the Tab key","validation":"regex: [0-9]*"}}],"editor-control":"FormSubmit","editor-component":"FormButton"}],"order":1}],"computed":[{"id":15,"name":"first_name","type":"javascript","order":1,"byPass":false,"formula":"return this.first_name.toLowerCase()","property":"first_name_calc"},{"id":16,"name":"last_name","type":"javascript","order":2,"byPass":false,"formula":"return this.first_name.toUpperCase()","property":"last_name"},{"id":17,"name":"email","type":"javascript","order":3,"byPass":false,"formula":"return this.first_name + \"@email.com\"","property":"email"},{"id":18,"name":"full_name","type":"javascript","order":4,"byPass":false,"formula":"return this.first_name + \" \" + this.last_name","property":"full_name"}],"custom_css":null,"created_at":"2024-05-22T02:10:33+00:00","updated_at":"2024-06-11T16:25:37+00:00","status":"ACTIVE","key":null,"watchers":[],"translations":null,"is_template":0,"asset_type":null,"projects":"[]","categories":[{"id":1,"uuid":"9c19b7a0-e236-43a1-b6c0-6e11753ae5b1","name":"Uncategorized","status":"ACTIVE","is_system":0,"created_at":"2024-05-22T01:51:28+00:00","updated_at":"2024-05-22T01:51:28+00:00","pivot":{"category_type":"ProcessMaker\\Models\\ScreenCategory","assignable_id":11,"category_id":1}}]}],"screen_categories":[],"scripts":[]} diff --git a/tests/e2e/specs/CalcDragAndDrop.spec.js b/tests/e2e/specs/CalcDragAndDrop.spec.js new file mode 100644 index 000000000..35564c990 --- /dev/null +++ b/tests/e2e/specs/CalcDragAndDrop.spec.js @@ -0,0 +1,134 @@ +describe('Calcs list Drag&Drop', () => { + const clickTopBarCalcs = () => { + cy.get('[data-cy="topbar-calcs"]').click(); + }; + + const dragAndDrop = (source, target) => { + const dataTransfer = new DataTransfer(); + + cy.get(source).trigger('dragstart', { dataTransfer }); + cy.get(target) + .trigger('dragenter') + .trigger('dragover', { dataTransfer }) + .trigger('drop', { dataTransfer }); + cy.get(source).trigger('dragend'); + }; + + beforeEach(() => { + cy.visit('/'); + + cy.loadFromJson('FOUR-13453.json', 0); + }); + + it('should drag and drop first row to third row', () => { + clickTopBarCalcs(); + + cy.get('[data-cy="calcs-table"] [data-test="item-1"]').eq(0).as('firstRow'); + cy.get('[data-cy="calcs-table"] [data-test="item-3"]').eq(0).as('thirdRow'); + + cy.get('@firstRow').contains('first_name_calc'); + cy.get('@thirdRow').contains('email'); + + dragAndDrop('@firstRow', '@thirdRow'); + + cy.get('[data-cy="calcs-table"] [data-test="item-1"]').eq(0).contains('last_name'); + cy.get('[data-cy="calcs-table"] [data-test="item-3"]').eq(0).contains('first_name_calc'); + }); + + it('should drag and drop second row to last row', () => { + clickTopBarCalcs(); + + cy.get('[data-cy="calcs-table"] [data-test="item-2"]').eq(0).as('secondRow'); + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).as('lastRow'); + + cy.get('@secondRow').contains('last_name'); + cy.get('@lastRow').contains('full_name'); + + dragAndDrop('@secondRow', '@lastRow'); + + cy.get('[data-cy="calcs-table"] [data-test="item-2"]').eq(0).contains('email'); + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).contains('last_name'); + }); + + it('should drag and drop last row to first row', () => { + clickTopBarCalcs(); + + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).as('lastRow'); + cy.get('[data-cy="calcs-table"] [data-test="item-1"]').eq(0).as('firstRow'); + + cy.get('@lastRow').contains('full_name'); + cy.get('@firstRow').contains('first_name'); + + dragAndDrop('@lastRow', '@firstRow'); + + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).contains('email'); + cy.get('[data-cy="calcs-table"] [data-test="item-1"]').eq(0).contains('full_name'); + }); + + it('should drag and drop to sort in ascending mode', () => { + clickTopBarCalcs(); + + cy.get('[data-cy="calcs-table"] [data-test="item-1"]').eq(0).as('firstRow'); + cy.get('[data-cy="calcs-table"] [data-test="item-2"]').eq(0).as('secondRow'); + cy.get('[data-cy="calcs-table"] [data-test="item-3"]').eq(0).as('thirdRow'); + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).as('lastRow'); + + cy.get('@firstRow').contains('first_name'); + cy.get('@secondRow').contains('last_name'); + cy.get('@thirdRow').contains('email'); + cy.get('@lastRow').contains('full_name'); + + dragAndDrop('@lastRow', '@secondRow'); + + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).contains('email'); + cy.get('[data-cy="calcs-table"] [data-test="item-2"]').eq(0).contains('full_name'); + + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).as('lastRow'); + + dragAndDrop('@lastRow', '@firstRow'); + + cy.get('[data-cy="calcs-table"] [data-test="item-4"]').eq(0).contains('last_name'); + cy.get('[data-cy="calcs-table"] [data-test="item-1"]').eq(0).contains('email'); + }); + + it('should edit the name of the first calc', () => { + clickTopBarCalcs(); + + cy.get('[data-cy="calcs-table"] [data-test="item-1"]').eq(0).as('firstRow'); + + cy.get('@firstRow').contains('first_name_calc'); + + cy.get('@firstRow').find('[data-cy="calcs-table-edit"]').click(); + + cy.get('[data-cy="calcs-property-name"]').clear().type("form_input_1"); + cy.get('[data-cy="calcs-button-save"]').click(); + + cy.get('@firstRow').contains('form_input_1'); + }); + + it('should delete the third calc', () => { + clickTopBarCalcs(); + + cy.get('[data-cy="calcs-table"] [data-test="item-3"]').eq(0).as('thirdRow'); + + cy.get('@thirdRow').contains('email'); + + cy.get('@thirdRow').find('[data-cy="calcs-table-remove"]').click(); + + cy.get('[data-cy="calcs-table"] [data-test="item-3"]').should('not.exist'); + }); + + it('should bypass the second calc', () => { + clickTopBarCalcs(); + + cy.get('[data-cy="calcs-table"] [data-test="item-2"]').eq(0).as('secondRow'); + + cy.get('@secondRow').contains('last_name'); + + cy.get('@secondRow').should('not.have.class', 'sortable-item-disabled'); + + cy.get('@secondRow').find('[data-test="calcs-bypass"]').click(); + + cy.get('@secondRow').should('have.class', 'sortable-item-disabled'); + }); +}); diff --git a/tests/e2e/specs/ComputedFields.spec.js b/tests/e2e/specs/ComputedFields.spec.js index 3c2813033..5a06cffb6 100644 --- a/tests/e2e/specs/ComputedFields.spec.js +++ b/tests/e2e/specs/ComputedFields.spec.js @@ -45,10 +45,7 @@ describe("Computed fields", () => { .clear() .type("pow(form_input_2, 2)"); cy.get('[data-cy="calcs-button-save"]').click(); - cy.get('[data-cy="calcs-table"]').should( - "contain.text", - "form_input_1 = form_input_2 ^ 2" - ); + cy.get('[data-cy="calcs-table"]').should('contain.text', 'form_input_1'); cy.get('[data-cy="calcs-modal"] .close').click(); // Edit the created calculated property @@ -63,10 +60,7 @@ describe("Computed fields", () => { .clear() .type("form_input_1 * 100"); cy.get('[data-cy="calcs-button-save"]').click(); - cy.get('[data-cy="calcs-table"]').should( - "contain.text", - "form_input_2 = form_input_1 * 100" - ); + cy.get('[data-cy="calcs-table"]').should('contain.text', 'form_input_2'); cy.get('[data-cy="calcs-modal"] .close').click(); // Delete the created calculated property @@ -94,7 +88,7 @@ describe("Computed fields", () => { cy.get('[data-cy="calcs-button-save"]').click(); cy.get('[data-cy="calcs-table"]').should( "contain.text", - "form_input_1 = form_input_2 ^ 2" + "form_input_1" ); cy.get('[data-cy="calcs-modal"] .close').click();