From cb1a4844a0cc1e0ad769aff20f5574f283b5bee8 Mon Sep 17 00:00:00 2001 From: pbalint <pbalint@gmail.com> Date: Tue, 12 Dec 2023 17:36:04 +0100 Subject: [PATCH] Changes for renderer API integration into IDE (#1215) -Implemented optional save button, enabled by a query parameter and controlled by the dirty state -Added listeners for cross-iframe messages -Added notification to parent app when ZAP has finished loading --- .../ide-integration/studio-rest-api.js | 2 +- src/App.vue | 44 +++++++++++++++++-- src/components/ZCLToolbar.vue | 19 ++++++++ src/store/zap/actions.js | 8 ++++ src/store/zap/mutations.js | 11 +++++ src/store/zap/state.js | 2 + 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src-electron/ide-integration/studio-rest-api.js b/src-electron/ide-integration/studio-rest-api.js index 008ae79e..89dc0752 100644 --- a/src-electron/ide-integration/studio-rest-api.js +++ b/src-electron/ide-integration/studio-rest-api.js @@ -103,7 +103,7 @@ async function isComponentTogglingDisabled(db, sessionId) { * @returns URL for rest api. */ function restApiUrl(api, path, queryParams = {}) { - let base = localhost + studioHttpPort + api + path + let base = localhost + studioHttpPort + api + encodeURIComponent(path) let params = Object.entries(queryParams) if (params.length) { let queries = new URLSearchParams() diff --git a/src/App.vue b/src/App.vue index 784abdc4..75e84c7d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -34,16 +34,30 @@ limitations under the License. import { defineComponent } from 'vue' import { QSpinnerGears } from 'quasar' import ZclTour from './tutorials/ZclTour.vue' - -// import VueTour from './tutorials/VueTour.vue' - import CommonMixin from './util/common-mixin' + const rendApi = require(`../src-shared/rend-api.js`) const restApi = require(`../src-shared/rest-api.js`) const observable = require('./util/observable.js') const dbEnum = require(`../src-shared/db-enum.js`) const storage = require('./util/storage.js') +window.addEventListener('message', (event) => { + const eventData = event?.data?.eventData + switch (event?.data?.eventId) { + case 'theme': + window[rendApi.GLOBAL_SYMBOL_EXECUTE](rendApi.id.setDarkTheme, eventData.theme === 'dark') + break + case 'save': + if (eventData.shouldSave) { + window[rendApi.GLOBAL_SYMBOL_EXECUTE](rendApi.id.save) + } + break + } + }, + false +) + async function initLoad(store) { let promises = [] promises.push(store.dispatch('zap/loadInitialData')) @@ -180,6 +194,16 @@ export default defineComponent({ this.$store.dispatch('zap/setStandalone', query['standalone']) } + if (`setSaveButtonVisible` in query) { + this.$store.dispatch( + 'zap/setSaveButtonVisible', + query[`setSaveButtonVisible`] === 'true' + ) + } else { + // If we don't specify it, default is off. + this.$store.dispatch('zap/setSaveButtonVisible', false) + } + this.zclDialogTitle = 'ZCL tab!' this.zclDialogText = 'Welcome to ZCL tab. This is just a test of a dialog.' @@ -206,6 +230,13 @@ export default defineComponent({ this.$store.dispatch('zap/updateSelectedUcComponentState', resp) } ) + + this.$onWebSocket( + dbEnum.wsCategory.dirtyFlag, + (resp) => { + this.$store.dispatch('zap/setDirtyState', resp) + } + ) }, addClassToBody() { if (this.uiThemeCategory === 'zigbee') { @@ -233,6 +264,13 @@ export default defineComponent({ }, mounted() { this.addClassToBody() + window?.parent?.postMessage({ + eventId: 'mounted', + eventData: { + hasMounted: true + } + }, + '*') }, unmounted() { if (this.uiThemeCategory === 'zigbee') { diff --git a/src/components/ZCLToolbar.vue b/src/components/ZCLToolbar.vue index 61c309d3..a25a6122 100644 --- a/src/components/ZCLToolbar.vue +++ b/src/components/ZCLToolbar.vue @@ -38,6 +38,20 @@ <div>Generate</div> </div> </q-btn> + <q-btn + id="save" + color="grey" + flat + no-caps + class="cursor-pointer" + @click="saveChanges" + v-if="this.$store.state.zap.saveButtonVisible && this.$store.state.zap.isDirty" + > + <div class="text-center"> + <q-icon name="o_save" /> + <div>Save</div> + </div> + </q-btn> <q-btn v-if="isCoreDocumentationAvailable" id="documentation" @@ -250,6 +264,11 @@ export default { ) } }, + saveChanges() { + window[rendApi.GLOBAL_SYMBOL_EXECUTE] ( + rendApi.id.save + ) + }, // This function will start vue tour steps startTour, togglePreviewTab() { diff --git a/src/store/zap/actions.js b/src/store/zap/actions.js index 03513c32..ff17e160 100644 --- a/src/store/zap/actions.js +++ b/src/store/zap/actions.js @@ -752,6 +752,10 @@ export function setDebugNavBar(context, debugNavBar) { context.commit('setDebugNavBar', debugNavBar) } +export function setSaveButtonVisible(context, saveButtonVisible) { + context.commit('setSaveButtonVisible', saveButtonVisible) +} + export function setStandalone(context, standalone) { context.commit('setStandalone', standalone) } @@ -818,6 +822,10 @@ export function updateSelectedUcComponentState(context, projectInfo) { }) } +export function setDirtyState(context, isDirty) { + context.commit('setDirtyState', isDirty) +} + export function loadZclClusterToUcComponentDependencyMap(context) { axiosRequests .$serverGet(`/zclExtension/cluster/component`) diff --git a/src/store/zap/mutations.js b/src/store/zap/mutations.js index ec8d4964..a9d4b8f4 100644 --- a/src/store/zap/mutations.js +++ b/src/store/zap/mutations.js @@ -452,6 +452,10 @@ export function setDebugNavBar(state, debugNavBar) { state.debugNavBar = debugNavBar } +export function setSaveButtonVisible(state, saveButtonVisible) { + state.saveButtonVisible = saveButtonVisible +} + export function setStandalone(state, standalone) { state.standalone = standalone } @@ -627,3 +631,10 @@ export function updateIsClusterOptionChanged(state, value) { export function updateNotificationCount(state, value) { state.notificationCount = value } + +export function setDirtyState(state, isDirty) { + if (state.isDirty != isDirty) { + state.isDirty = isDirty; + window.parent?.postMessage({eventId: 'dirty', eventData: { isDirty: isDirty }}, '*') + } +} \ No newline at end of file diff --git a/src/store/zap/state.js b/src/store/zap/state.js index 27f508d2..2c933b26 100644 --- a/src/store/zap/state.js +++ b/src/store/zap/state.js @@ -45,6 +45,8 @@ export default function () { selectedGenericOptions: {}, projectPackages: [], allPackages: [], + isDirty: false, + saveButtonVisible: false, clusterManager: { openDomains: {}, lastSelectedDomain: null, -- GitLab