Skip to content
7 changes: 5 additions & 2 deletions frontend/src/components/ExpertButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ export default {
computed: {
...mapState(useUxDrawersStore, ['rightDrawer']),
isExpertDrawerOpen () {
return this.rightDrawer.state && this.rightDrawer.component?.name === 'ExpertDrawer'
return (this.rightDrawer.state || this.rightDrawer.fixed)
}
},
methods: {
...mapActions('product/expert', ['openAssistantDrawer']),
onClick () {
this.openAssistantDrawer()
const openOptions = {
openPinned: this.rightDrawer.expertState.pinned
}
this.openAssistantDrawer(openOptions)
}
}
}
Expand Down
30 changes: 29 additions & 1 deletion frontend/src/components/drawers/RightDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<section
id="right-drawer"
v-click-outside="{handler: closeDrawer, exclude: ['right-drawer']}"
:class="{open: rightDrawer.state, wider: rightDrawer.wider, fixed: rightDrawer.fixed, resizing: isResizing, 'manually-resized': hasManuallyResized, pinning: isPinning, opening: isOpening, closing: isClosing}"
:class="{open: rightDrawer.state, wider: rightDrawer.wider, fixed: rightDrawer.fixed, resizing: isResizing, 'manually-resized': hasManuallyResized, pinning: isPinning, opening: isOpening && !isPinning, closing: isClosing}"
:style="drawerStyle"
data-el="right-drawer"
>
Expand Down Expand Up @@ -43,6 +43,7 @@

<script>
import { mapActions, mapState } from 'pinia'
import { mapActions as mapVuexActions } from 'vuex'

import { useUxDrawersStore } from '@/stores/ux-drawers.js'

Expand Down Expand Up @@ -105,10 +106,18 @@ export default {
watch: {
'rightDrawer.state': {
handler (isOpen, wasOpen) {
let reopenExpert = false
const isExpertDrawer = this.rightDrawer.component?.name === 'ExpertDrawer'
if (!isOpen && wasOpen && !isExpertDrawer) {
// non expert drawer is closing - check if we need to re-open expert drawer
reopenExpert = this.rightDrawer.expertState.pinned && this.rightDrawer.expertState.open
}

// Set opening flag when drawer opens
if (isOpen && !wasOpen) {
this.isOpening = true
this.isClosing = false
this.isPinning = isExpertDrawer && this.rightDrawer.fixed // no animation if drawer is to open pinned
// Clear opening flag after slide animation completes
setTimeout(() => {
this.isOpening = false
Expand All @@ -121,6 +130,10 @@ export default {
// Clear closing flag after slide animation completes
setTimeout(() => {
this.isClosing = false
// Re-open Expert drawer if needed after other drawer closes
if (reopenExpert) {
this.openAssistantDrawer({ openPinned: true })
}
}, 350)
}

Expand Down Expand Up @@ -166,6 +179,20 @@ export default {
mounted () {
// Add viewport resize listener
window.addEventListener('resize', this.onViewportResize)

const openPinned = this.rightDrawer.expertState.open && this.rightDrawer.expertState.pinned

if (openPinned && this.shouldAllowPinning) {
this.isPinning = true
setTimeout(() => {
this.openAssistantDrawer({ openPinned: true })
setTimeout(() => {
this.isPinning = false
}, 200)
}, 25)
} else {
this.isPinning = false
}
},
beforeUnmount () {
// Clean up resize listeners
Expand All @@ -177,6 +204,7 @@ export default {
}
},
methods: {
...mapVuexActions('product/expert', ['openAssistantDrawer']),
...mapActions(useUxDrawersStore, ['closeRightDrawer', 'togglePinDrawer']),
closeDrawer () {
if (this.rightDrawer.state && this.rightDrawer.closeOnClickOutside) {
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/store/modules/product/expert/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,17 @@ const actions = {
return expertApi.chat(payload)
},

openAssistantDrawer ({ dispatch, rootGetters }) {
openAssistantDrawer ({ dispatch, rootGetters }, options = {}) {
if (rootGetters['account/featuresCheck'].isExpertAssistantFeatureEnabled === false) return

dispatch(`product/expert/${OPERATOR_AGENT}/getCapabilities`, null, { root: true })

return useUxDrawersStore().openRightDrawer({ component: markRaw(ExpertDrawer) })
const openOptions = {
component: markRaw(ExpertDrawer),
fixed: options?.openPinned === true,
closeOnClickOutside: options?.openPinned !== true
}
return useUxDrawersStore().openRightDrawer(openOptions)
},

addWelcomeMessageIfNeeded ({ dispatch, state }) {
Expand Down
24 changes: 23 additions & 1 deletion frontend/src/stores/ux-drawers.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export const useUxDrawersStore = defineStore('ux-drawers', {
},
rightDrawer: {
state: false,
expertState: {
pinned: true,
open: true
},
component: null,
header: null,
wider: false,
Expand Down Expand Up @@ -59,6 +63,11 @@ export const useUxDrawersStore = defineStore('ux-drawers', {
if (this.rightDrawer.state && component.name === this.rightDrawer.component?.name) return

const openDrawer = () => {
if (component.name === 'ExpertDrawer') {
// save the ExpertDrawer pinned/open state (expertState is persistent)
this.rightDrawer.expertState.pinned = fixed
this.rightDrawer.expertState.open = true
}
this.rightDrawer.state = true
this.rightDrawer.wider = wider
this.rightDrawer.fixed = fixed
Expand All @@ -84,6 +93,11 @@ export const useUxDrawersStore = defineStore('ux-drawers', {
},

closeRightDrawer () {
if (this.rightDrawer.component?.name === 'ExpertDrawer') {
// save the ExpertDrawer pinned/open state (expertState is persistent)
this.rightDrawer.expertState.open = false
this.rightDrawer.expertState.pinned = this.rightDrawer.fixed
}
// Set closing flag to prevent reopens during transition
this.rightDrawer.closing = true

Expand Down Expand Up @@ -167,8 +181,12 @@ export const useUxDrawersStore = defineStore('ux-drawers', {
const newFixedState = !this.rightDrawer.fixed
this.rightDrawer.fixed = newFixedState
this.rightDrawer.pinned = newFixedState
// When fixed, prevent close on click outside
this.rightDrawer.closeOnClickOutside = !newFixedState
if (this.rightDrawer.component?.name === 'ExpertDrawer') {
// save the ExpertDrawer pinned/open state (expertState is persistent)
this.rightDrawer.expertState.open = this.rightDrawer.state
this.rightDrawer.expertState.pinned = newFixedState
}

// Always close overlay when toggling (whether fixing or unfixing)
const uxStore = useUxStore()
Expand All @@ -192,5 +210,9 @@ export const useUxDrawersStore = defineStore('ux-drawers', {
setLeftDrawer (component) {
this.leftDrawer.component = component ? markRaw(component) : null
}
},
persist: {
pick: ['rightDrawer.expertState'],
storage: localStorage
}
})
4 changes: 4 additions & 0 deletions test/unit/frontend/stores/ux-drawers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ describe('ux-drawers store', () => {
expect(store.rightDrawer.props).toEqual({})
expect(store.rightDrawer.on).toEqual({})
expect(store.rightDrawer.bind).toEqual({})
expect(store.rightDrawer.expertState).toEqual({
pinned: true,
open: true
})
})

it('passes through all options', () => {
Expand Down
Loading