Skip to content

Commit

Permalink
feat: Refactor the layout to implement the left pane using a QDrawer (c…
Browse files Browse the repository at this point in the history
…lose #901)
  • Loading branch information
cnouguier committed Jul 11, 2024
1 parent 5b12ab4 commit 0b57392
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 91 deletions.
92 changes: 86 additions & 6 deletions core/client/components/layout/KLayout.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
<template>
<q-layout
v-if="layout"
v-bind="layout.options"
:view="layout.view"
>
<!-- Left pane -->
<div v-if="hasLeftPaneComponents">
<q-page-sticky
v-if="leftPane.opener"
position="left"
:offset="openerOffset"
class="k-sticky"
>
<KOpener
id="left-opener"
v-model="isLeftPaneOpened"
position="left"
/>
</q-page-sticky>
<q-drawer
id="left-pane"
v-model="isLeftPaneOpened"
:width="leftPane.width"
side="left"
overlay
no-swipe-open
no-swipe-close
no-swipe-backdrop
>
<KPanel
id="left-panel"
:content="leftPane.components"
:mode="leftPane.mode"
:filter="leftPane.filter"
/>
</q-drawer>
</div>
<!-- Header -->
<q-header
v-if="header.components"
v-if="hasHeaderComponents"
v-model="isHeaderVisible"
>
<KPanel
Expand All @@ -17,7 +48,7 @@
</q-header>
<!-- Footer -->
<q-footer
v-if="footer.components"
v-if="hasFooterComponents"
v-model="isFooterVisible"
>
<KPanel
Expand All @@ -35,16 +66,36 @@
</template>

<script setup>
import { computed } from 'vue'
import { ref, computed, watch } from 'vue'
import { Layout } from '../../layout'
import KOpener from './KOpener.vue'
import KPanel from '../KPanel.vue'
// Data
const layout = Layout.get()
const leftPane = Layout.getPane('left')
const header = Layout.getHeader()
const footer = Layout.getFooter()
const openerOffset = ref([0, 0])
// Compputed
// Computed
const hasLeftPaneComponents = computed(() => {
return !_.isEmpty(leftPane.components)
})
const hasHeaderComponents = computed(() => {
return !_.isEmpty(header.components)
})
const hasFooterComponents = computed(() => {
return !_.isEmpty(footer.components)
})
const isLeftPaneOpened = computed({
get: function () {
return leftPane.visible
},
set: function (value) {
Layout.setPaneVisible('left', value)
}
})
const isHeaderVisible = computed({
get: function () {
return header.visible
Expand All @@ -61,4 +112,33 @@ const isFooterVisible = computed({
Layout.setFooterVisible(value)
}
})
// Functions
function clickOutsideLeftPanelListener (event) {
const leftPanelElement = document.getElementById('left-panel')
if (leftPanelElement && leftPanelElement.contains(event.target)) return
const leftOpenerElement = document.getElementById('left-opener')
if (leftOpenerElement && leftOpenerElement.contains(event.target)) return
Layout.setPaneVisible('left', false)
}
// Watch
watch(() => leftPane.visible, (visible) => {
if (visible) {
setTimeout(() => {
openerOffset.value = [leftPane.width, 0]
document.addEventListener('click', clickOutsideLeftPanelListener, true)
}, 100)
} else {
document.removeEventListener('click', clickOutsideLeftPanelListener, true)
openerOffset.value = [0, 0]
}
}, { immediate: true })
</script>

<style lang="scss">
.k-sticky {
z-index: $sticky-z-index;
}
</style>
33 changes: 14 additions & 19 deletions core/client/components/layout/KOpener.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</template>

<script setup>
import { ref, computed } from 'vue'
import { ref } from 'vue'
import { useQuasar } from 'quasar'
// Props
Expand All @@ -47,27 +47,22 @@ const hasTouch = $q.platform.has.touch
const isHovered = ref(false)
const icon = ref(null)
// Computed
const isOpened = computed(() => {
return props.modelValue
})
// Functions
function onMouseOver () {
if (hasTouch) return
isHovered.value = true
switch (props.position) {
case 'left':
icon.value = isOpened.value ? 'las la-angle-left' : 'las la-angle-right'
icon.value = props.modelValue ? 'las la-angle-left' : 'las la-angle-right'
break
case 'right':
icon.value = isOpened.value ? 'las la-angle-right' : 'las la-angle-left'
icon.value = props.modelValue ? 'las la-angle-right' : 'las la-angle-left'
break
case 'top':
icon.value = isOpened.value ? 'las la-angle-up' : 'las la-angle-down'
icon.value = props.modelValue ? 'las la-angle-up' : 'las la-angle-down'
break
default: // bottom
icon.value = isOpened.value ? 'las la-angle-down' : 'las la-angle-up'
icon.value = props.modelValue ? 'las la-angle-down' : 'las la-angle-up'
}
}
function onMouseLeave () {
Expand All @@ -79,24 +74,24 @@ function onSwipe ({ evt, ...info }) {
if (!info && !info.direction) return
switch (props.position) {
case 'left':
if (info.direction === 'left' && isOpened.value) onClick()
if (info.direction === 'right' && !isOpened.value) onClick()
if (info.direction === 'left' && props.modelValue) onClick()
if (info.direction === 'right' && !props.modelValue) onClick()
break
case 'right':
if (info.direction === 'left' && !isOpened.value) onClick()
if (info.direction === 'right' && isOpened.value) onClick()
if (info.direction === 'left' && !props.modelValue) onClick()
if (info.direction === 'right' && props.modelValue) onClick()
break
case 'top':
if (info.direction === 'up' && isOpened.value) onClick()
if (info.direction === 'down' && !isOpened.value) onClick()
if (info.direction === 'up' && props.modelValue) onClick()
if (info.direction === 'down' && !props.modelValue) onClick()
break
default: // bottom
if (info.direction === 'up' && !isOpened.value) onClick()
if (info.direction === 'down' && isOpened.value) onClick()
if (info.direction === 'up' && !props.modelValue) onClick()
if (info.direction === 'down' && props.modelValue) onClick()
}
}
function onClick () {
emit('update:modelValue', !isOpened.value)
emit('update:modelValue', !props.modelValue)
}
</script>

Expand Down
70 changes: 8 additions & 62 deletions core/client/components/layout/KPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
Managed stickies
Be careful of the order
-->
<!-- bottom pane -->
<!-- Bottom pane -->
<q-page-sticky position="bottom" class="k-sticky">
<div id="bottom-pane" v-show="hasBottomPaneComponents" class="column items-center">
<KOpener id="bottom-opener" v-if="bottomPane.opener" v-model="isBottomPaneOpened" position="bottom" />
Expand All @@ -34,7 +34,7 @@
</div>
</div>
</q-page-sticky>
<!-- right pane -->
<!-- Right pane -->
<q-page-sticky position="right" class="k-sticky">
<div id="right-pane" v-show="hasRightPaneComponents" class="row items-center">
<KOpener id="right-opener" v-if="rightPane.opener" v-model="isRightPaneOpened" position="right" />
Expand All @@ -51,7 +51,7 @@
</div>
</div>
</q-page-sticky>
<!-- top pane -->
<!-- Top pane -->
<q-page-sticky position="top" class="k-sticky">
<div id="top-pane" v-show="hasTopPaneComponents" class="column items-center">
<div>
Expand All @@ -67,7 +67,7 @@
<KOpener id="top-opener" v-if="topPane.opener" v-model="isTopPaneOpened" position="top" />
</div>
</q-page-sticky>
<!-- fab -->
<!-- Fab -->
<q-page-sticky :position="fab.position" :offset="fab.offset" class="k-sticky">
<KFab
id="fab"
Expand All @@ -76,7 +76,7 @@
:actions-align="fabBehaviour.actionsAlign"
/>
</q-page-sticky>
<!-- windows -->
<!-- Windows -->
<q-page-sticky position="top-left" :offset="leftWindow.position" class="k-sticky">
<KWindow
id="left-window"
Expand Down Expand Up @@ -113,23 +113,6 @@
:style="`max-width: ${bottomWindowSize[0]}px; max-height: ${bottomWindowSize[1]};px`"
/>
</q-page-sticky>
<!-- left pane -->
<q-page-sticky position="left" class="k-sticky">
<div id="left-pane" v-show="hasLeftPaneComponents" class="row items-center">
<div>
<KPanel
id="left-panel"
v-show="leftPane.visible"
:content="leftPane.components"
:mode="leftPane.mode"
direction="vertical"
class="k-left-pane"
@triggered="setLeftPaneVisible(false)"
/>
</div>
<KOpener id="left-opener" v-if="leftPane.opener" v-model="isLeftPaneOpened" position="left" />
</div>
</q-page-sticky>
</q-page>
</template>

Expand Down Expand Up @@ -157,7 +140,6 @@ const emit = defineEmits(['content-resized'])
// Data
const page = Layout.getPage()
const fab = Layout.getFab()
const leftPane = Layout.getPane('left')
const topPane = Layout.getPane('top')
const rightPane = Layout.getPane('right')
const bottomPane = Layout.getPane('bottom')
Expand All @@ -178,7 +160,7 @@ const contentStyleFunction = computed(() => {
return {
paddingTop: `${topPadding.value}px`,
paddingBottom: `${bottomPadding.value}px`,
widht: `calc(100vw - ${widthOffset}px)`,
width: `calc(100vw - ${widthOffset}px)`,
height: `calc(100vh - ${heightOffset}px)`
}
})
Expand All @@ -190,14 +172,6 @@ const isTopPaneOpened = computed({
setTopPaneVisible(value)
}
})
const isLeftPaneOpened = computed({
get: function () {
return leftPane.visible
},
set: function (value) {
setLeftPaneVisible(value)
}
})
const isRightPaneOpened = computed({
get: function () {
return rightPane.visible
Expand All @@ -214,9 +188,6 @@ const isBottomPaneOpened = computed({
setBottomPaneVisible(value)
}
})
const hasLeftPaneComponents = computed(() => {
return !_.isEmpty(leftPane.components)
})
const hasTopPaneComponents = computed(() => {
return !_.isEmpty(topPane.components)
})
Expand Down Expand Up @@ -247,17 +218,6 @@ const fabBehaviour = computed(() => {
}
})
// Watch
watch(() => leftPane.visible, (visible) => {
if (visible) {
setTimeout(() => {
document.addEventListener('click', clickOutsideLeftPanelListener, true)
}, 500)
} else {
document.removeEventListener('click', clickOutsideLeftPanelListener, true)
}
}, { immediate: true })
// Functions
function layoutOffsetListener (offset) {
// Catch layout offset and returns default Quasar function. "offset" is a Number
Expand All @@ -281,22 +241,12 @@ function onBottomPaneResized (size) {
function setTopPaneVisible (visible) {
Layout.setPaneVisible('top', visible)
}
function setLeftPaneVisible (visible) {
Layout.setPaneVisible('left', visible)
}
function setRightPaneVisible (visible) {
Layout.setPaneVisible('right', visible)
}
function setBottomPaneVisible (visible) {
Layout.setPaneVisible('bottom', visible)
}
function clickOutsideLeftPanelListener (event) {
const leftPanelElement = document.getElementById('left-panel')
if (leftPanelElement && leftPanelElement.contains(event.target)) return
const leftOpenerElement = document.getElementById('left-opener')
if (leftOpenerElement && leftOpenerElement.contains(event.target)) return
setLeftPaneVisible(false)
}
</script>

<style lang="scss">
Expand All @@ -306,17 +256,13 @@ body {
.k-sticky {
z-index: $sticky-z-index;
}
.k-pane, .k-left-pane {
.k-pane {
background-color: #FFFFFF;
border: solid 1px lightgrey;
border-radius: 3px;
position: relative;
}
.k-pane:hover, .k-left-pane:hover {
.k-pane:hover {
border: solid 1px $primary;
}
.k-left-pane {
height: 100vh;
width: $left-pane-width;
}
</style>
2 changes: 1 addition & 1 deletion core/client/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const defaults = {
page: { ...contentDefaults },
fab: { ...contentDefaults, icon: 'las la-ellipsis-v', position: 'bottom-right', offset: [16, 16] },
panes: {
left: { ...contentDefaults, opener: false },
left: { ...contentDefaults, opener: false, width: 300 },
top: { ...contentDefaults, opener: false },
right: { ...contentDefaults, opener: false },
bottom: { ...contentDefaults, opener: false }
Expand Down
3 changes: 0 additions & 3 deletions extras/css/core.variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ $warning: #d09931 !default;
$tooltip-fontsize: 12px !default;
$tooltip-background: $accent !default;

// Pane
$left-pane-width: 320px !default;

// Window
$window-min-width: 300px !default;
$window-min-height: 300px !default;
Expand Down

0 comments on commit 0b57392

Please sign in to comment.