Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions frontend/src/composables/EditorLandingTab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useRoute, useRouter } from 'vue-router'

import { useAccountSettingsStore } from '@/stores/account-settings.js'

/**
* The immersive editor routes choose their landing tab (Expert or Overview) in a route
* redirect, which runs before the instance or device has been loaded. At that point the
* active team is whatever the session last had, or nothing at all, rather than the team
* that owns the entity being opened.
*
* Call `syncLandingTab` once the entity and its team are loaded. It moves away from the
* Expert tab when the owning team has Expert disabled, and onto it when the redirect
* landed on Overview only because the owning team was not yet known.
*/
export function useEditorLandingTab ({ editorRouteName, expertRouteName, overviewRouteName }) {
const route = useRoute()
const router = useRouter()
const accountSettings = useAccountSettingsStore()

function syncLandingTab () {
const { isExpertAssistantFeatureEnabled, isExpertInsightsFeatureEnabled } = accountSettings.featuresCheck
const expertEnabled = isExpertAssistantFeatureEnabled || isExpertInsightsFeatureEnabled
const onExpert = route.name === expertRouteName
const landedViaRedirect = route.redirectedFrom?.name === editorRouteName

if (onExpert && !expertEnabled) {
return router.replace({ name: overviewRouteName, params: route.params })
}
if (!onExpert && expertEnabled && landedViaRedirect) {
return router.replace({ name: expertRouteName, params: route.params })
}
}

return { syncLandingTab }
}
4 changes: 3 additions & 1 deletion frontend/src/mixins/Instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ export default {
}
try {
const data = await InstanceApi.getInstance(instanceId)
// Load the owning team before exposing the instance, so anything
// reacting to the instance sees the right team and feature checks.
await useAccountStore().setTeam(data.team.slug)
this.instance = { ...{ deviceSettings: {} }, ...this.instance, ...data }
useAccountStore().setTeam(this.instance.team.slug)
this.instance.deviceSettings = await InstanceApi.getInstanceDeviceSettings(instanceId)
if (this.instance.deviceSettings?.targetSnapshot) {
this.instance.targetSnapshot = await SnapshotApi.getSnapshot(instanceId, this.instance.deviceSettings.targetSnapshot)
Expand Down
15 changes: 14 additions & 1 deletion frontend/src/pages/device/Editor/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import DrawerTrigger from '../../../components/immersive-editor/DrawerTrigger.vu
import EditorDrawer from '../../../components/immersive-editor/EditorDrawer.vue'
import EditorWrapper from '../../../components/immersive-editor/RemoteInstanceEditorWrapper.vue'
import { useDeviceHelper } from '../../../composables/DeviceHelper.js'
import { useEditorLandingTab } from '../../../composables/EditorLandingTab.js'
import usePermissions from '../../../composables/Permissions.js'
import Alerts from '../../../services/alerts.js'
import { isInstanceOnNR5Plus } from '../../../utils/instanceVersion'
Expand Down Expand Up @@ -115,7 +116,14 @@ export default {
getDeviceEditorProxy
} = useDeviceHelper()

const { syncLandingTab } = useEditorLandingTab({
editorRouteName: 'device-editor',
expertRouteName: 'device-editor-expert',
overviewRouteName: 'device-editor-overview'
})

return {
syncLandingTab,
device,
hasPermission,
restartDevice,
Expand Down Expand Up @@ -303,8 +311,13 @@ export default {
}
}

// Load the owning team before exposing the device, so the device
// watcher and the landing tab check see the right feature checks.
await useAccountStore().setTeam(device.team.slug)
this.device = device
await useAccountStore().setTeam(this.device.team.slug)
if (this.isEditorAvailable) {
this.syncLandingTab()
}
},
showConfirmDeleteDialog () {
this.showDeleteDeviceDialog()
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/pages/instance/Editor/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import DrawerTrigger from '../../../components/immersive-editor/DrawerTrigger.vu
import EditorDrawer from '../../../components/immersive-editor/EditorDrawer.vue'
import EditorWrapper from '../../../components/immersive-editor/HostedInstanceEditorWrapper.vue'
import InstanceActionsButton from '../../../components/instance/ActionButton.vue'
import { useEditorLandingTab } from '../../../composables/EditorLandingTab.js'
import usePermissions from '../../../composables/Permissions.js'
import instanceMixin from '../../../mixins/Instance.js'

Expand All @@ -85,10 +86,16 @@ export default {
mixins: [instanceMixin],
setup () {
const { hasAMinimumTeamRoleOf, isVisitingAdmin } = usePermissions()
const { syncLandingTab } = useEditorLandingTab({
editorRouteName: 'instance-editor',
expertRouteName: 'instance-editor-expert',
overviewRouteName: 'instance-editor-overview'
})

return {
isVisitingAdmin,
hasAMinimumTeamRoleOf
hasAMinimumTeamRoleOf,
syncLandingTab
}
},
data () {
Expand Down Expand Up @@ -177,6 +184,9 @@ export default {
watch: {
instance (instance) {
this.setInstance(instance)
},
'instance.id' () {
this.syncLandingTab()
}
},
unmounted () {
Expand Down
Loading