diff --git a/packages/builder/src/components/commandPalette/CommandPalette.svelte b/packages/builder/src/components/commandPalette/CommandPalette.svelte index 3a369446a3..5421e2f123 100644 --- a/packages/builder/src/components/commandPalette/CommandPalette.svelte +++ b/packages/builder/src/components/commandPalette/CommandPalette.svelte @@ -55,7 +55,7 @@ name: "Automations", description: "", icon: "Compass", - action: () => $goto("./automate"), + action: () => $goto("./automation"), }, { type: "Publish", @@ -127,7 +127,7 @@ type: "Automation", name: automation.name, icon: "ShareAndroid", - action: () => $goto(`./automate/${automation._id}`), + action: () => $goto(`./automation/${automation._id}`), })), ...Constants.Themes.map(theme => ({ type: "Change Builder Theme", diff --git a/packages/builder/src/components/deploy/AppActions.svelte b/packages/builder/src/components/deploy/AppActions.svelte index 84feb4f189..def44646dd 100644 --- a/packages/builder/src/components/deploy/AppActions.svelte +++ b/packages/builder/src/components/deploy/AppActions.svelte @@ -24,12 +24,18 @@ import { onMount } from "svelte" import DeployModal from "components/deploy/DeployModal.svelte" import { apps } from "stores/portal" - import { store } from "builderStore" + import { + store, + screenHistoryStore, + automationHistoryStore, + } from "builderStore" import TourWrap from "components/portal/onboarding/TourWrap.svelte" import { TOUR_STEP_KEYS } from "components/portal/onboarding/tours.js" import { url, goto } from "@roxi/routify" + import { isEqual, cloneDeep } from "lodash" export let application + export let loaded let unpublishModal let updateAppModal @@ -40,7 +46,7 @@ let appActionPopoverOpen = false let appActionPopoverAnchor - let publishing + let publishing = false $: filteredApps = $apps.filter(app => app.devId === application) $: selectedApp = filteredApps?.length ? filteredApps[0] : null @@ -58,6 +64,81 @@ $store.version && $store.upgradableVersion !== $store.version + let cachedVersion = $store.version + "" + let versionAltered = false + let screensAltered = false + let automationsAltered = false + + let publishRecord = { + screenHistory: null, + automationHistory: null, + } + + //Meta Changes + let appMeta = {} + let appMetaUpdated = false + let appMetaInitialised = false + + const unsub = store.subscribe(state => { + let { name, url: appUrl, navigation, theme, customTheme, icon } = state + const update = { + name, + url: appUrl, + navigation: { ...cloneDeep(navigation) }, + theme, + customTheme, + icon, + } + + if (!isEqual(update, appMeta)) { + if (!appMetaInitialised) { + appMetaInitialised = true + } else { + appMetaUpdated = true + } + appMeta = { + ...(appMeta || {}), + ...update, + } + } + }) + + const monitorHistoryStore = (historyStore, publishedHistoryId, cb) => { + if (!historyStore.history.length || historyStore.loading) { + return + } + if (!historyStore.canUndo) { + cb(publishedHistoryId != -1) + return + } + const historyEntry = historyStore.history[historyStore.position - 1] + + if (historyEntry) { + cb(publishedHistoryId != historyEntry.id) + } + } + + $: monitorHistoryStore( + $screenHistoryStore, + publishRecord.screenHistory, + updated => { + screensAltered = updated + } + ) + + $: monitorHistoryStore( + $automationHistoryStore, + publishRecord.automationHistory, + updated => { + automationsAltered = updated + } + ) + + $: versionAltered = cachedVersion != $store.version + $: altered = + screensAltered || appMetaUpdated || automationsAltered || versionAltered + $: canPublish = (!isPublished || altered) && !publishing && loaded + const initialiseApp = async () => { const applicationPkg = await API.fetchAppPackage($store.devId) await store.actions.initialise(applicationPkg) @@ -112,6 +193,27 @@ } } + const resetAppHistory = (historyStore, historyKey) => { + if (historyStore.history.length) { + const historyEntryPos = historyStore.position + const historyEntry = historyStore.history[historyEntryPos - 1] + + publishRecord = { + ...publishRecord, + [historyKey]: historyEntry?.id || -1, + } + } + } + + const resetStateTracking = () => { + resetAppHistory($automationHistoryStore, "automationHistory") + resetAppHistory($screenHistoryStore, "screenHistory") + automationsAltered = false + screensAltered = false + appMetaUpdated = false + cachedVersion = $store.version + "" + } + async function publishApp() { try { publishing = true @@ -124,7 +226,9 @@ }) await completePublish() + resetStateTracking() } catch (error) { + console.error(error) analytics.captureException(error) notifications.error("Error publishing app") } @@ -153,6 +257,7 @@ type: "success", icon: "GlobeStrike", }) + publishRecord = {} } catch (err) { notifications.error("Error unpublishing app") } @@ -176,7 +281,7 @@ {#if $store.hasLock} -
+
{#if updateAvailable} @@ -317,7 +422,7 @@ cta on:click={publishApp} id={"builder-app-publish-button"} - disabled={publishing} + disabled={!canPublish} > Publish @@ -349,8 +454,20 @@ /> - - + + +{:else} +
+
+ + Preview + +
+
{/if}