From 1fc5cc453f931d99cf690bfde78891137bf2d929 Mon Sep 17 00:00:00 2001 From: paulr34 <64710345+paulr34@users.noreply.github.com> Date: Fri, 15 Mar 2024 15:18:37 -0400 Subject: [PATCH] matter centric UI (#1278) * matter centric UI * only allow selection of server if Matter project * removing cypress tests because Zigbee and Matter GUI diverged - follow up task for separating them * centralizing data --- cypress/e2e/clusters/cluster-filter.cy.js | 42 ----- cypress/e2e/clusters/dimmable-light.cy.js | 16 -- src/components/ZclAttributeManager.vue | 200 +++++++++++---------- src/components/ZclCreateModifyEndpoint.vue | 22 +-- src/components/ZclDomainClusterView.vue | 24 ++- src/components/ZclEndpointCard.vue | 7 +- src/util/ui-options.js | 31 ++++ 7 files changed, 165 insertions(+), 177 deletions(-) create mode 100644 src/util/ui-options.js diff --git a/cypress/e2e/clusters/cluster-filter.cy.js b/cypress/e2e/clusters/cluster-filter.cy.js index 6441699e..0f9b01d4 100644 --- a/cypress/e2e/clusters/cluster-filter.cy.js +++ b/cypress/e2e/clusters/cluster-filter.cy.js @@ -29,46 +29,4 @@ describe('Testing cluster filters', () => { }) } ) - it( - 'enable power configuration cluster', - { retries: { runMode: 2, openMode: 2 } }, - () => { - cy.get('[data-test="filter-input"]').click({ force: true }) - cy.get('.q-virtual-scroll__content > :nth-child(1)').click() - cy.fixture('data').then((data) => { - cy.get('tbody').children().should('contain', data.cluster2) - }) - cy.get('#General').click({ force: true }) - cy.get( - '#General > .q-expansion-item__container > .q-expansion-item__content > .q-card > .q-card__section > .row > .q-table__container > .q-table__middle > .q-table > tbody > :nth-child(2) > :nth-child(6) > .q-field > .q-field__inner > .q-field__control' - ).click({ force: true }) - cy.fixture('data').then((data) => { - cy.get('.q-virtual-scroll__content > :nth-child(3)') - .contains(data.server1) - .click() - }) - cy.get( - '.v-step-7 > .q-field > .q-field__inner > .q-field__control' - ).click({ force: true }) - } - ) - it( - 'checks if power configuration exists', - { retries: { runMode: 2, openMode: 2 } }, - () => { - cy.get('.q-virtual-scroll__content > :nth-child(2)').click({ - force: true, - multiple: true, - }) - cy.fixture('data').then((data) => { - cy.get('tbody').children().should('contain', data.cluster2) - }) - } - ) - it('Close all the clusters', () => { - cy.dataCy('cluster-btn-closeall').click() - cy.get('[data-test=Cluster').each(($row) => { - cy.wrap($row).should('have.class', 'q-expansion-item--collapsed') - }) - }) }) diff --git a/cypress/e2e/clusters/dimmable-light.cy.js b/cypress/e2e/clusters/dimmable-light.cy.js index 88a8c6f4..1453e29d 100644 --- a/cypress/e2e/clusters/dimmable-light.cy.js +++ b/cypress/e2e/clusters/dimmable-light.cy.js @@ -25,21 +25,5 @@ describe( .type(data.cluster4) }) }) - it('Enabling Client & Server', () => { - cy.get( - ':nth-child(6) > .q-field > .q-field__inner > .q-field__control' - ).click({ force: true }) - cy.fixture('data').then((data) => { - cy.get('.q-menu').contains(data.server2).click() - }) - }) - it('Check Configuration page', () => { - cy.get(':nth-child(7) > .q-btn > .q-btn__content > .notranslate').click({ - force: true, - }) - cy.fixture('data').then((data) => { - cy.get('tr.table_body').contains(data.attribute3).should('be.visible') - }) - }) } ) diff --git a/src/components/ZclAttributeManager.vue b/src/components/ZclAttributeManager.vue index 1469d468..aa5461b7 100644 --- a/src/components/ZclAttributeManager.vue +++ b/src/components/ZclAttributeManager.vue @@ -123,8 +123,14 @@ limitations under the License. " /> </q-td> - <q-td key="singleton" :props="props" auto-width> + <q-td + key="singleton" + v-if="enableSingleton" + :props="props" + auto-width + > <q-checkbox + v-if="enableSingleton" class="q-mt-xs" :model-value="selectionSingleton" :val="hashAttributeIdClusterId(props.row.id, selectedCluster.id)" @@ -140,8 +146,9 @@ limitations under the License. " /> </q-td> - <q-td key="bounded" :props="props" auto-width> + <q-td key="bounded" v-if="enableBounded" :props="props" auto-width> <q-checkbox + v-if="enableBounded" class="q-mt-xs" :model-value="selectionBounded" :val="hashAttributeIdClusterId(props.row.id, selectedCluster.id)" @@ -410,97 +417,110 @@ export default { rowsPerPage: 0, sortBy: 'clientServer', }, - columns: [ - { - name: 'status', - required: false, - label: '', - align: 'left', - style: 'width:1%', - }, - { - name: 'included', - label: 'Enabled', - field: 'included', - align: 'left', - }, - { - name: 'attrID', - align: 'left', - label: 'Attribute ID', - field: 'attrID', - sortable: true, - style: 'max-width: 90px', - headerStyle: 'max-width: 90px', - }, - { - name: 'attrName', - label: 'Attribute', - field: 'attrName', - align: 'left', - sortable: true, - }, - { - name: 'required', - label: 'Required', - field: 'required', - align: 'left', - sortable: true, - }, - { - name: 'clientServer', - label: 'Client/Server', - field: 'clientServer', - align: 'left', - sortable: true, - }, - { - name: 'mfgID', - label: 'Mfg Code', - align: 'left', - field: 'mfgID', - sortable: true, - }, - { - name: 'storageOption', - label: 'Storage Option', - align: 'left', - field: 'storageOption', - sortable: true, - }, - { - name: 'singleton', - align: 'left', - label: 'Singleton', - field: 'singleton', - sortable: true, - }, - { - name: 'bounded', - align: 'left', - label: 'Bounded', - field: 'bounded', - sortable: true, - }, - { - name: 'type', - align: 'left', - label: 'Type', - field: 'type', - sortable: true, - }, - { - name: 'default', - align: 'left', - label: 'Default', - field: 'default', - style: 'min-width: 180px', - headerStyle: 'min-width: 180px', - }, - ], + columns: [], forcedExternal: [], + enableSingleton: false, + enableBounded: false, } }, + mounted() { + this.columns = [ + { + name: 'status', + required: false, + label: '', + align: 'left', + style: 'width:1%', + }, + { + name: 'included', + label: 'Enabled', + field: 'included', + align: 'left', + }, + { + name: 'attrID', + align: 'left', + label: 'Attribute ID', + field: 'attrID', + sortable: true, + style: 'max-width: 90px', + headerStyle: 'max-width: 90px', + }, + { + name: 'attrName', + label: 'Attribute', + field: 'attrName', + align: 'left', + sortable: true, + }, + { + name: 'required', + label: 'Required', + field: 'required', + align: 'left', + sortable: true, + }, + { + name: 'clientServer', + label: 'Client/Server', + field: 'clientServer', + align: 'left', + sortable: true, + }, + { + name: 'mfgID', + label: 'Mfg Code', + align: 'left', + field: 'mfgID', + sortable: true, + }, + { + name: 'storageOption', + label: 'Storage Option', + align: 'left', + field: 'storageOption', + sortable: true, + }, + ...(this.enableSingleton + ? [ + { + name: 'singleton', + align: 'left', + label: 'Singleton', + field: 'singleton', + sortable: true, + }, + ] + : []), + ...(this.enableBounded + ? [ + { + name: 'bounded', + align: 'left', + label: 'Bounded', + field: 'bounded', + sortable: true, + }, + ] + : []), + { + name: 'type', + align: 'left', + label: 'Type', + field: 'type', + sortable: true, + }, + { + name: 'default', + align: 'left', + label: 'Default', + field: 'default', + style: 'min-width: 180px', + headerStyle: 'min-width: 180px', + }, + ] + }, created() { if (this.$serverGet != null) { this.forcedExternal = [] diff --git a/src/components/ZclCreateModifyEndpoint.vue b/src/components/ZclCreateModifyEndpoint.vue index 3a1f6226..83f1c104 100644 --- a/src/components/ZclCreateModifyEndpoint.vue +++ b/src/components/ZclCreateModifyEndpoint.vue @@ -32,7 +32,7 @@ limitations under the License. min="0" /> <q-input - v-if="$store.state.zap.isProfileIdShown" + v-if="enableProfileId" label="Profile ID" v-model="computedProfileId" ref="profile" @@ -136,6 +136,7 @@ limitations under the License. <div class="q-gutter-md row"> <q-input + v-if="enableNetworkId" label="Network" type="number" v-model="shownEndpoint.networkIdentifier" @@ -198,6 +199,7 @@ limitations under the License. import * as RestApi from '../../src-shared/rest-api' import * as DbEnum from '../../src-shared/db-enum' import CommonMixin from '../util/common-mixin' +import uiOptions from '../util/ui-options' const _ = require('lodash') import * as dbEnum from '../../src-shared/db-enum.js' @@ -205,7 +207,7 @@ export default { name: 'ZclCreateModifyEndpoint', props: ['endpointReference'], emits: ['saveOrCreateValidated', 'updateData'], - mixins: [CommonMixin], + mixins: [CommonMixin, uiOptions], watch: { deviceTypeRefAndDeviceIdPair(val) { this.setDeviceTypeCallback(val) @@ -254,13 +256,6 @@ export default { } else { this.shownEndpoint.endpointIdentifier = this.getSmallestUnusedEndpointId() } - - const enableMatterFeatures = - this.$store.state.zap.selectedZapConfig?.zclProperties?.category === - 'matter' - this.enableMultipleDevice = enableMatterFeatures - this.enablePrimaryDevice = enableMatterFeatures - this.enableParentEndpoint = enableMatterFeatures }, data() { return { @@ -275,9 +270,6 @@ export default { saveOrCreateCloseFlag: false, deviceTypeTmp: [], // Temp store for the selected device types primaryDeviceTypeTmp: null, // Temp store for the selected primary device type - enableMultipleDevice: false, - enablePrimaryDevice: false, - enableParentEndpoint: false, endpointIds: [], } }, @@ -484,14 +476,10 @@ export default { } }, saveOrCreateHandler() { - let profile = this.$store.state.zap.isProfileIdShown - ? this.$refs.profile.validate() - : true - + let profile = this.enableProfileId ? this.$refs.profile.validate() : true if ( this.$refs.endpoint.validate() && this.$refs.device.validate() && - this.$refs.network.validate() && (this.$refs.version?.validate?.() ?? !this.$refs.version?.includes((v) => !(v >= 0))) && profile diff --git a/src/components/ZclDomainClusterView.vue b/src/components/ZclDomainClusterView.vue index 06455f88..19753300 100644 --- a/src/components/ZclDomainClusterView.vue +++ b/src/components/ZclDomainClusterView.vue @@ -219,6 +219,7 @@ limitations under the License. <script> import CommonMixin from '../util/common-mixin' import restApi from '../../src-shared/rest-api' +import uiOptions from '../util/ui-options' let ZclClusterRoleAction = { Add: 'add', @@ -230,8 +231,23 @@ let ZclClusterRole = { server: 'server', client: 'client' } export default { name: 'ZclDomainClusterView', props: ['domainName', 'clusters'], - mixins: [CommonMixin], + mixins: [CommonMixin, uiOptions], computed: { + clusterSelectionOptions() { + if (this.enableServerOnly) { + return [ + { label: 'Not Enabled', client: false, server: false }, + { label: 'Server', client: false, server: true }, + ] + } else { + return [ + { label: 'Not Enabled', client: false, server: false }, + { label: 'Client', client: true, server: false }, + { label: 'Server', client: false, server: true }, + { label: 'Client & Server', client: true, server: true }, + ] + } + }, showStatus: { get() { return !this.$store.state.zap.standalone @@ -524,12 +540,6 @@ export default { ZclClusterRole, showEnableAllClustersDialog: false, uc_label: 'uc label', - clusterSelectionOptions: [ - { label: 'Not Enabled', client: false, server: false }, - { label: 'Client', client: true, server: false }, - { label: 'Server', client: false, server: true }, - { label: 'Client & Server', client: true, server: true }, - ], columns: [ { name: 'status', diff --git a/src/components/ZclEndpointCard.vue b/src/components/ZclEndpointCard.vue index bb9708ff..0626bd01 100644 --- a/src/components/ZclEndpointCard.vue +++ b/src/components/ZclEndpointCard.vue @@ -265,6 +265,7 @@ limitations under the License. <script> import ZclCreateModifyEndpoint from './ZclCreateModifyEndpoint.vue' import CommonMixin from '../util/common-mixin' +import uiOptions from '../util/ui-options' import * as Storage from '../util/storage' import restApi from '../../src-shared/rest-api' import * as Util from '../util/util' @@ -273,7 +274,7 @@ import * as dbEnum from '../../src-shared/db-enum.js' export default { name: 'ZclEndpointCard', props: ['endpointReference'], - mixins: [CommonMixin], + mixins: [CommonMixin, uiOptions], components: { ZclCreateModifyEndpoint }, data() { return { @@ -552,10 +553,6 @@ export default { this.selectedReporting = [] this.getEndpointCardData() //only show Matter features if Matter is selected - const enableMatterFeatures = - this.$store.state.zap.selectedZapConfig?.zclProperties?.category === - 'matter' - this.enableParentEndpoint = enableMatterFeatures } }, } diff --git a/src/util/ui-options.js b/src/util/ui-options.js new file mode 100644 index 00000000..6a9952b8 --- /dev/null +++ b/src/util/ui-options.js @@ -0,0 +1,31 @@ +// mixin.js +export default { + data() { + return { + enableProfileId: false, + enableNetworkId: false, + enableMultipleDevice: false, + enablePrimaryDevice: false, + enableParentEndpoint: false, + enableServerOnly: false, + enableSingleton: false, + enableBounded: false, + } + }, + mounted() { + const enableZigbeeFeatures = + this.$store.state.zap.selectedZapConfig?.zclProperties?.category === + 'zigbee' + this.enableProfileId = enableZigbeeFeatures + this.enableNetworkId = enableZigbeeFeatures + this.enableSingleton = enableZigbeeFeatures + this.enableBounded = enableZigbeeFeatures + const enableMatterFeatures = + this.$store.state.zap.selectedZapConfig?.zclProperties?.category === + 'matter' + this.enableMultipleDevice = enableMatterFeatures + this.enablePrimaryDevice = enableMatterFeatures + this.enableParentEndpoint = enableMatterFeatures + this.enableServerOnly = enableMatterFeatures + }, +} -- GitLab