Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist state of right sidebar #10612

Merged
merged 13 commits into from
Mar 15, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Remember right side bar state

We've implemented a feature to remember the state of the right side bar. Now, when the user reopens the web application,
the right side bar will remain in its last state, either open or closed, based on the user's previous interaction with it.

https://github.com/owncloud/web/pull/10612
https://github.com/owncloud/web/issues/9613
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<div id="oc-trash-no-selection" class="oc-text-center oc-mt-xl">
<oc-icon size="xxlarge" name="settings-4" fill-type="fill" />
<p v-text="$gettext('Select a resource from the left sidebar to manage it')" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
name: 'DetailsPanel'
})
</script>
28 changes: 26 additions & 2 deletions packages/web-app-admin-settings/src/views/General.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
<template>
<div>
<app-template ref="template" :breadcrumbs="breadcrumbs" :show-app-bar="false">
<app-template
ref="template"
:breadcrumbs="breadcrumbs"
:show-app-bar="false"
:is-side-bar-open="isSideBarOpen"
:side-bar-active-panel="sideBarActivePanel"
:side-bar-available-panels="sideBarAvailablePanels"
>
<template #mainContent>
<div class="oc-px-m">
<InfoSection />
Expand All @@ -16,6 +23,9 @@ import { defineComponent, ref } from 'vue'
import AppTemplate from '../components/AppTemplate.vue'
import InfoSection from '../components/General/InfoSection.vue'
import AppearanceSection from '../components/General/AppearanceSection.vue'
import DetailsPanel from '../components/General/SideBar/DetailsPanel.vue'
import { useGettext } from 'vue3-gettext'
import { useSideBar } from '@ownclouders/web-pkg'

export default defineComponent({
components: {
Expand All @@ -25,9 +35,23 @@ export default defineComponent({
},
setup() {
const template = ref()
const { $gettext } = useGettext()

const sideBarAvailablePanels = [
{
name: 'DetailsPanel',
icon: 'settings-4',
title: () => $gettext('Details'),
component: DetailsPanel,
isRoot: () => true,
isVisible: () => true
}
]

return {
template
template,
sideBarAvailablePanels,
...useSideBar()
}
},
computed: {
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-admin-settings/src/views/Groups.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export default defineComponent({
{
name: 'DetailsPanel',
icon: 'group-2',
title: () => $gettext('Group details'),
title: () => $gettext('Details'),
component: DetailsPanel,
componentAttrs: () => ({ groups: unref(selectedGroups) }),
isRoot: () => true,
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-admin-settings/src/views/Users.vue
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ export default defineComponent({
{
name: 'DetailsPanel',
icon: 'user',
title: () => $gettext('User details'),
title: () => $gettext('Details'),
component: DetailsPanel,
componentAttrs: ({ items }) => ({
user: items.length === 1 ? items[0] : null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

exports[`General view > renders component 1`] = `
"<div>
<app-template-stub breadcrumbs="[object Object],[object Object]" issidebaropen="false" sidebaravailablepanels="" sidebarpanelcontext="[object Object]" loading="false" sidebarloading="false" showviewoptions="false" showbatchactions="false" batchactionitems="" batchactions="" showappbar="false"></app-template-stub>
<app-template-stub breadcrumbs="[object Object],[object Object]" issidebaropen="false" sidebaravailablepanels="[object Object]" sidebarpanelcontext="[object Object]" loading="false" sidebarloading="false" showviewoptions="false" showbatchactions="false" batchactionitems="" batchactions="" showappbar="false"></app-template-stub>
</div>"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default defineComponent({
name: 'NoSelection',
computed: {
selectedFilesString() {
return this.$gettext('Select a file or folder to view details.')
return this.$gettext('Select a file or folder to view details')
}
}
})
Expand Down
13 changes: 13 additions & 0 deletions packages/web-app-files/src/components/SideBar/TrashNoSelection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<div id="oc-trash-no-selection" class="oc-text-center oc-mt-xl">
<oc-icon size="xxlarge" name="delete-bin" fill-type="line" />
<p data-testid="selectTrashText" v-text="$gettext('Select a trash to view details')" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
name: 'TrashNoSelection'
})
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import FileActions from '../../components/SideBar/Actions/FileActions.vue'
import FileVersions from '../../components/SideBar/Versions/FileVersions.vue'
import SharesPanel from '../../components/SideBar/Shares/SharesPanel.vue'
import NoSelection from '../../components/SideBar/NoSelection.vue'
import TrashNoSelection from '../../components/SideBar/TrashNoSelection.vue'
import SpaceActions from '../../components/SideBar/Actions/SpaceActions.vue'
import {
SpaceDetails,
Expand Down Expand Up @@ -52,6 +53,10 @@ export const useSideBarPanels = () => {
component: NoSelection,
isRoot: () => true,
isVisible: ({ parent, items }) => {
if (isLocationTrashActive(router, 'files-trash-overview')) {
// trash overview has its own "no selection" panel
return false
}
if (isLocationSpacesActive(router, 'files-spaces-projects')) {
// project spaces overview has its own "no selection" panel
return false
Expand All @@ -64,6 +69,21 @@ export const useSideBarPanels = () => {
}
}
},
{
id: 'com.github.owncloud.web.files.sidebar-panel.trash-no-selection',
type: 'sidebarPanel',
scopes: ['resource'],
panel: {
name: 'no-selection',
icon: 'questionnaire-line',
title: () => $gettext('Details'),
component: TrashNoSelection,
isRoot: () => true,
isVisible: () => {
return isLocationTrashActive(router, 'files-trash-overview')
}
}
},
{
id: 'com.github.owncloud.web.files.sidebar-panel.details-single-selection',
type: 'sidebarPanel',
Expand Down
8 changes: 6 additions & 2 deletions packages/web-app-files/src/views/trash/Overview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
</template>
</template>
</files-view-wrapper>
<file-side-bar :is-open="isSideBarOpen" :active-panel="sideBarActivePanel" />
</div>
</template>

Expand All @@ -72,9 +73,11 @@ import { useGettext } from 'vue3-gettext'
import { useTask } from 'vue-concurrency'
import {
defaultFuseOptions,
FileSideBar,
useClientService,
useResourcesStore,
useRouter,
useSideBar,
useSpacesStore,
useUserStore
} from '@ownclouders/web-pkg'
Expand All @@ -94,7 +97,7 @@ import { useFileListHeaderPosition } from '@ownclouders/web-pkg'

export default defineComponent({
name: 'TrashOverview',
components: { FilesViewWrapper, AppBar, AppLoadingSpinner, NoContentMessage },
components: { FileSideBar, FilesViewWrapper, AppBar, AppLoadingSpinner, NoContentMessage },
setup() {
const userStore = useUserStore()
const spacesStore = useSpacesStore()
Expand Down Expand Up @@ -259,7 +262,8 @@ export default defineComponent({
loadResourcesTask,
areResourcesLoading,
isPersonalSpaceResource,
fileListHeaderY
fileListHeaderY,
...useSideBar()
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ exports[`TrashOverview > view states > should render spaces list 1`] = `
</div>
</div>
<!--v-if-->
<file-side-bar-stub isopen="false"></file-side-bar-stub>
</div>"
`;
5 changes: 5 additions & 0 deletions packages/web-app-text-editor/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ export default defineComponent({
overflow: auto;
}

// Adjustments to match our theming
.toastui-editor-defaultUI {
border: none;
}
.toastui-editor-defaultUI-toolbar,
.toastui-editor-md-tab-container {
background-color: var(--oc-color-background-default) !important;
}
</style>
2 changes: 1 addition & 1 deletion packages/web-pkg/src/components/SideBar/FileSideBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export default defineComponent({
}
isLoading.value = false
},
{ deep: true }
{ deep: true, immediate: true }
)

provide('resource', readonly(loadedResource))
Expand Down
8 changes: 1 addition & 7 deletions packages/web-pkg/src/components/SideBar/SideBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,8 @@

<script lang="ts">
import { VisibilityObserver } from '../../observer'
import { computed, defineComponent, PropType, onBeforeUnmount, unref } from 'vue'
import { computed, defineComponent, PropType, unref } from 'vue'
import { SideBarPanel, SideBarPanelContext } from './types'
import { SideBarEventTopics, useEventBus } from '../../composables'

let visibilityObserver: VisibilityObserver
let hiddenObserver: VisibilityObserver
Expand Down Expand Up @@ -127,16 +126,11 @@ export default defineComponent({
},
emits: ['close', 'selectPanel'],
setup(props) {
const eventBus = useEventBus()
const panels = computed(() =>
props.availablePanels.filter((p) => p.isVisible(props.panelContext))
)
const subPanels = computed(() => unref(panels).filter((p) => !p.isRoot?.(props.panelContext)))

onBeforeUnmount(() => {
eventBus.publish(SideBarEventTopics.close)
})

return {
panels,
subPanels
Expand Down
4 changes: 3 additions & 1 deletion packages/web-pkg/src/composables/sideBar/useSideBar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { onBeforeUnmount, readonly, ref, Ref, unref } from 'vue'
import { EventBus, eventBus as defaultEventBus } from '../../services/eventBus'
import { SideBarEventTopics } from './eventTopics'
import { useLocalStorage } from '../localStorage'

interface SideBarResult {
isSideBarOpen: Ref<boolean>
Expand All @@ -14,7 +15,8 @@ interface SideBarOptions {

export const useSideBar = (options?: SideBarOptions): SideBarResult => {
const eventBus = options?.bus || defaultEventBus
const isSideBarOpen = ref(false)
const isSideBarOpen = useLocalStorage(`oc_sideBarOpen`, false)

const sideBarActivePanel = ref(null)
const toggleSideBarToken = eventBus.subscribe(SideBarEventTopics.toggle, () => {
isSideBarOpen.value = !unref(isSideBarOpen)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { EventBus } from '../../../../src/services/eventBus'
import { SideBarEventTopics, useSideBar } from '../../../../src/composables/sideBar'
import { unref } from 'vue'
import { unref, ref } from 'vue'
import { getComposableWrapper } from 'web-test-helpers'

vi.mock('../../../../src/composables/localStorage', async (importOriginal) => ({
useLocalStorage: () => ref(false)
}))

describe('useSideBar', () => {
let eventBus
beforeEach(() => {
Expand Down Expand Up @@ -97,7 +101,6 @@ describe('useSideBar', () => {
it('should not influence "isSideBarOpen"', () => {
getComposableWrapper(() => {
const { isSideBarOpen } = useSideBar({ bus: eventBus })
eventBus.publish(SideBarEventTopics.setActivePanel)
expect(unref(isSideBarOpen)).toBe(false)
})
})
Expand Down