UBER-853 Wiki application navigation ()

Signed-off-by: Alexander Onnikov <alexander.onnikov@xored.com>
This commit is contained in:
Alexander Onnikov 2023-09-22 13:56:33 +07:00 committed by GitHub
parent cec2cc4f37
commit e32f41767f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 114 additions and 35 deletions
packages
panel/src/components
presentation/src/components
theme/styles
ui/src/components
plugins
tracker-resources/src/components/projects
view-resources/src/components
workbench-resources/src/components

View File

@ -1,6 +1,6 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
// Copyright © 2021, 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
@ -45,6 +45,7 @@
export let isUtils: boolean = true
export let isCustomAttr: boolean = true
export let floatAside = false
export let allowBack = true
export let allowClose = true
export let useMaxWidth: boolean | undefined = undefined
export let isFullSize = false
@ -96,6 +97,7 @@
bind:withoutTitle
on:open
on:close
{allowBack}
{allowClose}
{floatAside}
{embedded}

View File

@ -1,5 +1,6 @@
<!--
// Copyright © 2020 Anticrm Platform Contributors.
// 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
@ -13,18 +14,42 @@
// limitations under the License.
-->
<script lang="ts">
import { IconFolder, IconSize, Label } from '@hcengineering/ui'
import { Space } from '@hcengineering/core'
import presentation from '..'
import { Asset } from '@hcengineering/platform'
import {
AnySvelteComponent,
Icon,
IconFolder,
IconSize,
IconWithEmoji,
Label,
getPlatformColorDef,
themeStore
} from '@hcengineering/ui'
import view, { IconProps } from '@hcengineering/view'
export let value: Space
import presentation from '..'
import { ComponentType } from 'svelte'
export let value: Space & IconProps
export let subtitle: string | undefined = undefined
export let size: IconSize
export let iconWithEmoji: AnySvelteComponent | Asset | ComponentType | undefined = view.ids.IconWithEmoji
export let defaultIcon: AnySvelteComponent | Asset | ComponentType | undefined = undefined
</script>
<div class="flex-presenter">
<div class="icon medium-gap"><IconFolder {size} /></div>
<div class="icon medium-gap">
<Icon
{size}
icon={value.icon === iconWithEmoji && iconWithEmoji ? IconWithEmoji : value.icon ?? defaultIcon ?? IconFolder}
iconProps={value.icon === iconWithEmoji && iconWithEmoji
? { icon: value.color }
: {
fill: value.color !== undefined ? getPlatformColorDef(value.color, $themeStore.dark).icon : 'currentColor'
}}
/>
</div>
<div class="flex-col">
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
<div class="label no-underline nowrap">

View File

@ -15,6 +15,7 @@
<script lang="ts">
import { createEventDispatcher, ComponentType } from 'svelte'
import { Class, DocumentQuery, FindOptions, Ref, Space } from '@hcengineering/core'
import { Asset, IntlString } from '@hcengineering/platform'
import { getPlatformColorDef, getPlatformColorForTextDef, IconWithEmoji, themeStore } from '@hcengineering/ui'
import {
@ -31,8 +32,7 @@
showPopup,
TooltipAlignment
} from '@hcengineering/ui'
import { Class, DocumentQuery, FindOptions, Ref, Space } from '@hcengineering/core'
import { IconProps } from '@hcengineering/view'
import view, { IconProps } from '@hcengineering/view'
import SpacesPopup from './SpacesPopup.svelte'
import { ObjectCreate } from '../types'
@ -58,7 +58,7 @@
export let componentProps: any | undefined = undefined
export let autoSelect = true
export let readonly = false
export let iconWithEmoji: AnySvelteComponent | Asset | ComponentType | undefined = undefined
export let iconWithEmoji: AnySvelteComponent | Asset | ComponentType | undefined = view.ids.IconWithEmoji
export let defaultIcon: AnySvelteComponent | Asset | ComponentType = IconFolder
let selected: (Space & IconProps) | undefined
@ -98,7 +98,9 @@
spaceQuery,
create,
component,
componentProps
componentProps,
iconWithEmoji,
defaultIcon
},
!$$slots.content ? eventToHTMLElement(ev) : getEventPositionElement(ev),
(result) => {

View File

@ -1,5 +1,6 @@
<!--
// Copyright © 2020 Anticrm Platform Contributors.
// 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
@ -14,9 +15,17 @@
-->
<script lang="ts">
import core, { Class, Ref, Space } from '@hcengineering/core'
import type { IntlString } from '@hcengineering/platform'
import { CheckBox, deviceOptionsStore, resizeObserver, tooltip, EditWithIcon, IconSearch } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import type { Asset, IntlString } from '@hcengineering/platform'
import {
AnySvelteComponent,
CheckBox,
deviceOptionsStore,
resizeObserver,
tooltip,
EditWithIcon,
IconSearch
} from '@hcengineering/ui'
import { ComponentType, createEventDispatcher } from 'svelte'
import presentation from '..'
import { createQuery } from '../utils'
import SpaceInfo from './SpaceInfo.svelte'
@ -28,6 +37,8 @@
export let placeholderParam: any | undefined = undefined
export let selected: Ref<Space> | undefined
export let selectedSpaces: Ref<Space>[] = []
export let iconWithEmoji: AnySvelteComponent | Asset | ComponentType | undefined = undefined
export let defaultIcon: AnySvelteComponent | Asset | ComponentType | undefined = undefined
let searchQuery: string = ''
let spaces: Space[] = []
@ -97,7 +108,7 @@
<div class="check pointer-events-none">
<CheckBox checked={isSelected(space)} accented />
</div>
<SpaceInfo size={'medium'} value={space} />
<SpaceInfo size={'medium'} value={space} {iconWithEmoji} {defaultIcon} />
{#if allowDeselect && space._id === selected}
<div class="check pointer-events-none">
{#if titleDeselect}

View File

@ -1,5 +1,6 @@
<!--
// Copyright © 2020 Anticrm Platform Contributors.
// 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
@ -14,11 +15,13 @@
-->
<script lang="ts">
import { Class, Doc, DocumentQuery, FindOptions, Ref, Space, getCurrentAccount } from '@hcengineering/core'
import { Asset } from '@hcengineering/platform'
import { AnySvelteComponent, ButtonSize } from '@hcengineering/ui'
import { ObjectCreate } from '../types'
import { createQuery } from '../utils'
import DocPopup from './DocPopup.svelte'
import SpaceInfo from './SpaceInfo.svelte'
import { ComponentType } from 'svelte'
export let _class: Ref<Class<Space>>
export let selected: Ref<Space> | undefined
@ -29,6 +32,8 @@
export let allowDeselect = false
export let component: AnySvelteComponent | undefined = undefined
export let componentProps: any | undefined = undefined
export let iconWithEmoji: AnySvelteComponent | Asset | ComponentType | undefined = undefined
export let defaultIcon: AnySvelteComponent | Asset | ComponentType | undefined = undefined
let search: string | undefined = undefined
@ -78,7 +83,7 @@
{#if component}
<svelte:component this={component} {...componentProps} {size} value={space} />
{:else}
<SpaceInfo {size} value={space} />
<SpaceInfo {size} value={space} {iconWithEmoji} {defaultIcon} />
{/if}
</svelte:fragment>
</DocPopup>

View File

@ -176,6 +176,7 @@
}
}
.an-element__icon-arrow {
flex-shrink: 0;
margin-left: .25rem;
width: 1rem;
height: 1rem;

View File

@ -1,5 +1,5 @@
<!--
// Copyright © 2022 Hardcore Engineering Inc.
// Copyright © 2022, 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
@ -32,6 +32,7 @@
export let isFullSize: boolean = false
export let withoutTitle: boolean = false
export let floatAside = false
export let allowBack = true
export let allowClose = true
export let useMaxWidth: boolean | undefined = undefined
export let embedded = false
@ -96,15 +97,17 @@
class:embedded
>
<div class="popupPanel-title {twoRows && !withoutTitle ? 'row-top' : 'row'}">
<Button
focusIndex={10000}
icon={IconBack}
kind={'ghost'}
size={'medium'}
on:click={() => {
history.back()
}}
/>
{#if allowBack}
<Button
focusIndex={10000}
icon={IconBack}
kind={'ghost'}
size={'medium'}
on:click={() => {
history.back()
}}
/>
{/if}
{#if allowClose}
<div class="antiHSpacer" />
<Button

View File

@ -184,7 +184,7 @@
function chooseIcon (ev: MouseEvent) {
const icons = [tracker.icon.Home, tracker.icon.RedCircle]
showPopup(IconPicker, { icon, color, icons, emoji: tracker.component.IconWithEmoji }, 'top', (result) => {
showPopup(IconPicker, { icon, color, icons, iconWithEmoji: tracker.component.IconWithEmoji }, 'top', (result) => {
if (result !== undefined && result !== null) {
icon = result.icon
color = result.color

View File

@ -32,7 +32,7 @@
export let icon: Metadata<string> | undefined = undefined
export let icons: Asset[]
export let emoji: Asset = view.ids.IconWithEmoji
export let iconWithEmoji: Asset = view.ids.IconWithEmoji
export let color: number = 0
const dispatch = createEventDispatcher()
@ -95,7 +95,7 @@
<EmojiPopup
embedded
on:close={(evt) => {
dispatch('close', { icon: emoji, color: evt.detail.codePointAt(0) })
dispatch('close', { icon: iconWithEmoji, color: evt.detail.codePointAt(0) })
}}
/>
{/if}

View File

@ -30,6 +30,7 @@
export let model: NavigatorModel | undefined
export let currentSpace: Ref<Space> | undefined
export let currentSpecial: string | undefined
export let currentFragment: string | undefined
export let currentApplication: Application | undefined
const client = getClient()
@ -169,6 +170,7 @@
on:space
{currentSpace}
{currentSpecial}
{currentFragment}
deselect={menuSelection}
/>
{/if}
@ -182,6 +184,7 @@
model={m}
on:open
{currentSpecial}
{currentFragment}
deselect={menuSelection}
separate
/>

View File

@ -707,10 +707,7 @@
class="cursor-pointer"
on:click|stopPropagation={() => showPopup(AccountPopup, {}, popupPosition)}
>
<Component
is={contact.component.Avatar}
props={{ avatar: employee?.avatar, size: 'small', name: employee?.name }}
/>
<Component is={contact.component.Avatar} props={{ avatar: employee?.avatar, size: 'small' }} />
</div>
</div>
</div>
@ -732,7 +729,16 @@
{#await checkIsHeaderHidden(currentApplication) then isHidden}
{#if !isHidden}
{#await checkIsHeaderDisabled(currentApplication) then disabled}
<Component is={currentApplication.navHeaderComponent} props={{ currentSpace, disabled }} shrink />
<Component
is={currentApplication.navHeaderComponent}
props={{
currentSpace,
currentSpecial,
currentFragment,
disabled
}}
shrink
/>
{/await}
{/if}
{/await}
@ -741,6 +747,7 @@
<Navigator
{currentSpace}
{currentSpecial}
{currentFragment}
model={navigatorModel}
{currentApplication}
on:open={checkOnHide}

View File

@ -42,6 +42,7 @@
export let currentSpace: Ref<Space> | undefined
export let spaces: Space[]
export let currentSpecial: string | undefined
export let currentFragment: string | undefined
export let hasSpaceBrowser: boolean = false
export let deselect: boolean = false
export let separate: boolean = false
@ -151,7 +152,16 @@
{#await getSpacePresenter(client, space._class) then presenter}
{#if separate && model.specials && i !== 0}<TreeSeparator line />{/if}
{#if model.specials && presenter}
<svelte:component this={presenter} {space} {model} {currentSpace} {currentSpecial} {getActions} {deselect} />
<svelte:component
this={presenter}
{space}
{model}
{currentSpace}
{currentSpecial}
{currentFragment}
{getActions}
{deselect}
/>
{:else}
<NavLink space={space._id}>
{#await getSpaceName(client, space) then name}

View File

@ -31,6 +31,7 @@
export let models: SpacesNavModel[]
export let currentSpace: Ref<Space> | undefined
export let currentSpecial: string | undefined
export let currentFragment: string | undefined
export let deselect: boolean = false
const client = getClient()
@ -93,7 +94,16 @@
{@const model = models.find((p) => p.spaceClass === space._class)}
{#await getSpacePresenter(client, space._class) then presenter}
{#if presenter && model}
<svelte:component this={presenter} {space} {model} {currentSpace} {currentSpecial} {getActions} {deselect} />
<svelte:component
this={presenter}
{space}
{model}
{currentSpace}
{currentSpecial}
{currentFragment}
{getActions}
{deselect}
/>
{:else}
{#await getSpaceName(client, space) then name}
<NavLink space={space._id}>