UBER-1116: saving sidebar changes (#3919)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2023-10-31 12:21:29 +03:00 committed by GitHub
parent f4a5c6de1b
commit 7382bf8ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 44 additions and 112 deletions

View File

@ -186,3 +186,16 @@ export function navigate (location: PlatformLocation, store = true): boolean {
}
return false
}
const COLLAPSED = 'COLLAPSED'
export const getCollapsedKey = (_id: string): string => `${getCurrentLocation().path[1]}_${_id}_collapsed`
export const getTreeCollapsed = (_id: any): boolean => {
if (_id === undefined || _id === 'undefined') return false
return localStorage.getItem(getCollapsedKey(_id as string)) === COLLAPSED
}
export const setTreeCollapsed = (_id: any, collapsed: boolean): void => {
if (_id === undefined || _id === 'undefined') return
localStorage.setItem(getCollapsedKey(_id), collapsed ? COLLAPSED : '')
}

View File

@ -20,11 +20,8 @@
import { getClient } from '@hcengineering/presentation'
import { Action, IconEdit } from '@hcengineering/ui'
import { getActions as getContributedActions, TreeElement } from '@hcengineering/view-resources'
import hr from '../../plugin'
// import TreeElement from './TreeElement.svelte'
export let departments: Ref<Department>[]
export let descendants: Map<Ref<Department>, Department[]>
export let departmentById: Map<Ref<Department>, Department>

View File

@ -37,7 +37,7 @@
<NavHeader label={hr.string.HRApplication} />
<Scroller shrink>
<TreeNode label={hr.string.Departments} node>
<TreeNode _id={'tree-hr'} label={hr.string.Departments} node>
<DepartmentsHierarchy {departments} {descendants} {departmentById} selected={department} on:selected />
</TreeNode>
<div class="antiNav-space" />

View File

@ -1,94 +0,0 @@
<!--
// Copyright © 2023 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Doc, Ref } from '@hcengineering/core'
import type { Asset, IntlString } from '@hcengineering/platform'
import type { AnySvelteComponent, Action } from '@hcengineering/ui'
import { Icon, IconChevronDown, IconMoreH, Label, Menu, showPopup } from '@hcengineering/ui'
export let _id: Ref<Doc> | undefined = undefined
export let icon: Asset | AnySvelteComponent | undefined = undefined
export let iconProps: Record<string, any> | undefined = undefined
export let label: IntlString | undefined = undefined
export let title: string | undefined = undefined
export let node = false
export let parent = false
export let collapsed = false
export let selected = false
export let level = 0
export let actions: (originalEvent?: MouseEvent) => Promise<Action[]> = async () => []
let hovered = false
async function onMenuClick (ev: MouseEvent) {
showPopup(Menu, { actions: await actions(ev), ctx: _id }, ev.target as HTMLElement, () => {
hovered = false
})
hovered = true
}
$: style = `padding-left: calc(${level} * 1.25rem);`
const dispatch = createEventDispatcher()
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="antiNav-element"
class:hovered
class:selected
class:parent
class:collapsed
{style}
on:click={() => {
if (selected) {
collapsed = !collapsed
}
dispatch('click')
}}
>
<span class="an-element__label" class:title={node}>
{#if icon && !parent}
<div class="an-element__icon">
<Icon {icon} {iconProps} size={'small'} />
</div>
{/if}
<span class="overflow-label">
{#if label}<Label {label} />{:else}{title}{/if}
</span>
{#if node}
<div
class="an-element__icon-arrow"
class:collapsed
on:click={(e) => {
e.stopPropagation()
e.preventDefault()
collapsed = !collapsed
}}
>
<IconChevronDown size={'small'} />
</div>
{/if}
</span>
<div class="an-element__tool" on:click|preventDefault|stopPropagation={onMenuClick}>
<IconMoreH size={'small'} />
</div>
</div>
{#if node && !collapsed}
<div class="antiNav-element__dropbox"><slot /></div>
{/if}

View File

@ -18,10 +18,11 @@
import { Project } from '@hcengineering/tracker'
import {
IconWithEmoji,
getCurrentLocation,
getPlatformColorDef,
getPlatformColorForTextDef,
themeStore
themeStore,
getTreeCollapsed,
setTreeCollapsed
} from '@hcengineering/ui'
import view from '@hcengineering/view'
import { NavLink, TreeNode } from '@hcengineering/view-resources'
@ -35,10 +36,8 @@
export let getActions: Function
export let deselect: boolean = false
const COLLAPSED = 'COLLAPSED'
const getSpaceCollapsedKey = () => `${getCurrentLocation().path[1]}_${space._id}_collapsed`
$: collapsed = localStorage.getItem(getSpaceCollapsedKey()) === COLLAPSED
let collapsed: boolean = getTreeCollapsed(space._id)
$: setTreeCollapsed(space._id, collapsed)
let specials: SpecialNavModel[] = []
@ -78,7 +77,7 @@
title={space.name}
folder
actions={() => getActions(space)}
on:click={() => localStorage.setItem(getSpaceCollapsedKey(), collapsed ? '' : COLLAPSED)}
on:click={() => (collapsed = !collapsed)}
>
{#each specials as special}
<NavLink space={space._id} special={special.id}>

View File

@ -17,10 +17,20 @@
import type { Doc, Ref } from '@hcengineering/core'
import type { Asset, IntlString } from '@hcengineering/platform'
import type { Action, AnySvelteComponent } from '@hcengineering/ui'
import { ActionIcon, Icon, IconChevronDown, IconMoreH, Label, Menu, showPopup } from '@hcengineering/ui'
import {
ActionIcon,
Icon,
IconChevronDown,
IconMoreH,
Label,
Menu,
showPopup,
getTreeCollapsed,
setTreeCollapsed
} from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
export let _id: Ref<Doc> | undefined = undefined
export let _id: Ref<Doc> | string | undefined = undefined
export let icon: Asset | AnySvelteComponent | undefined = undefined
export let iconProps: Record<string, any> | undefined = undefined
export let label: IntlString | undefined = undefined
@ -31,7 +41,7 @@
export let indent: boolean = false
export let folder: boolean = false
export let level: number = 0
export let collapsed: boolean = false
export let collapsed: boolean = getTreeCollapsed(_id)
export let selected: boolean = false
export let bold: boolean = false
export let actions: (originalEvent?: MouseEvent) => Promise<Action[]> = async () => []
@ -45,6 +55,8 @@
}
const dispatch = createEventDispatcher()
$: if (_id) collapsed = getTreeCollapsed(_id)
$: setTreeCollapsed(_id, collapsed)
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->

View File

@ -18,7 +18,7 @@
import type { Action, AnySvelteComponent } from '@hcengineering/ui'
import TreeElement from './TreeElement.svelte'
export let _id: Ref<Doc> | undefined = undefined
export let _id: Ref<Doc> | string | undefined = undefined
export let title: string | undefined = undefined
export let label: IntlString | undefined = undefined
export let icon: Asset | AnySvelteComponent | undefined = undefined

View File

@ -203,7 +203,12 @@
</script>
{#if shown}
<TreeNode label={view.string.FilteredViews} node actions={async () => getActions(availableFilteredViews)}>
<TreeNode
_id={'tree-saved'}
label={view.string.FilteredViews}
node
actions={async () => getActions(availableFilteredViews)}
>
{#each myFilteredViews as fv}
<TreeItem
_id={fv._id}

View File

@ -142,7 +142,7 @@
}
</script>
<TreeNode label={model.label} node actions={async () => getParentActions()}>
<TreeNode _id={'tree-' + model.id} label={model.label} node actions={async () => getParentActions()}>
{#each filteredSpaces as space, i (space._id)}
{#await getSpacePresenter(client, space._class) then presenter}
{#if separate && model.specials && i !== 0}<TreeSeparator line />{/if}

View File

@ -89,7 +89,7 @@
}
</script>
<TreeNode {label} node actions={async () => [unStarAll]}>
<TreeNode _id={'tree-stared'} {label} node actions={async () => [unStarAll]}>
{#each spaces as space (space._id)}
{@const model = models.find((p) => p.spaceClass === space._class)}
{#await getSpacePresenter(client, space._class) then presenter}