Fixed Navigator visibility (#5842)

* Fixed Navigator visibility

Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com>

* Clean Workbench

Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com>

---------

Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com>
This commit is contained in:
Alexander Platov 2024-06-18 08:14:20 +03:00 committed by GitHub
parent 30fbac0d9e
commit d1f6a9de7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 197 additions and 301 deletions

View File

@ -137,8 +137,8 @@
@media (max-width: 1024px) {
.antiPanel-navigator {
position: fixed;
top: var(--status-bar-height);
height: calc(100% - var(--status-bar-height));
top: calc(var(--status-bar-height) + 1px);
height: calc(100% - var(--status-bar-height) - 1px);
background-color: var(--theme-navpanel-color);
filter: drop-shadow(2px 0 1px rgba(0, 0, 0, .2));
z-index: 450;
@ -147,7 +147,8 @@
left: 0;
}
&.landscape {
left: var(--app-panel-width);
.modern-app & { left: var(--app-panel-width); }
:not(.modern-app) & { left: calc(var(--app-panel-width) + 1px); }
}
}
}

View File

@ -14,10 +14,9 @@
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { IconMaximize, IconMinimize, IconClose, ButtonIcon } from '..'
import { IconMaximize, IconMinimize, IconClose, ButtonIcon, deviceOptionsStore as deviceInfo } from '..'
export let type: 'type-aside' | 'type-popup' | 'type-component' | 'type-panel' = 'type-component'
export let minimize: boolean = false
export let noResize: boolean = false
export let hideSeparator: boolean = false
@ -27,11 +26,14 @@
<div class="hulyHeader-container" class:topIndent={type === 'type-panel'} class:hideSeparator>
{#if type === 'type-component'}
{#if !noResize}
<button class="hulyHeader-button" on:click={() => dispatch('resize', minimize)}>
{#if minimize}
<IconMinimize size={'small'} />
{:else}
<button
class="hulyHeader-button"
on:click={() => ($deviceInfo.navigator.visible = !$deviceInfo.navigator.visible)}
>
{#if $deviceInfo.navigator.visible}
<IconMaximize size={'small'} />
{:else}
<IconMinimize size={'small'} />
{/if}
</button>
{/if}

View File

@ -299,6 +299,7 @@ export const deviceOptionsStore = writable<DeviceOptions>({
docHeight: 0,
isPortrait: false,
isMobile: false,
navigator: { visible: true, float: false, direction: 'vertical' },
fontSize: 0,
size: null,
sizes: { xs: false, sm: false, md: false, lg: false, xl: false, xxl: false },

View File

@ -364,6 +364,7 @@ export interface DeviceOptions {
docHeight: number
isPortrait: boolean
isMobile: boolean
navigator: { visible: boolean, float: boolean, direction: 'vertical' | 'horizontal' }
fontSize: number
size: WidthType | null
sizes: Record<WidthType, boolean>

View File

@ -23,7 +23,8 @@
navigate,
Separator,
Location,
restoreLocation
restoreLocation,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import { NavigatorModel, SpecialNavModel } from '@hcengineering/workbench'
@ -38,10 +39,6 @@
import { SelectChannelEvent } from './types'
import { decodeChannelURI, openChannel } from '../../navigation'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
const notificationsClient = InboxNotificationsClientImpl.getClient()
const contextByDocStore = notificationsClient.contextByDoc
const objectQuery = createQuery()
@ -134,14 +131,14 @@
</script>
<div class="flex-row-top h-full">
{#if visibleNav}
<div class="antiPanel-navigator {appsDirection === 'horizontal' ? 'portrait' : 'landscape'}">
{#if $deviceInfo.navigator.visible}
<div class="antiPanel-navigator {$deviceInfo.navigator.direction === 'horizontal' ? 'portrait' : 'landscape'}">
<div class="antiPanel-wrap__content hulyNavPanel-container">
<ChatNavigator objectId={selectedData?._id} {object} {currentSpecial} on:select={handleChannelSelected} />
</div>
<Separator name="chat" float={navFloat ? 'navigator' : true} index={0} />
<Separator name="chat" float={$deviceInfo.navigator.float ? 'navigator' : true} index={0} />
</div>
<Separator name="chat" float={navFloat} index={0} />
<Separator name="chat" float={$deviceInfo.navigator.float} index={0} />
{/if}
<div class="antiPanel-component filled w-full">
@ -150,10 +147,7 @@
is={currentSpecial.component}
props={{
model: navigatorModel,
...currentSpecial.componentProps,
visibleNav,
navFloat,
appsDirection
...currentSpecial.componentProps
}}
on:action={(e) => {
if (e?.detail) {

View File

@ -35,7 +35,8 @@
navigate,
openPanel,
defineSeparators,
setResolvedLocation
setResolvedLocation,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import view from '@hcengineering/view'
import { ListSelectionProvider, restrictionStore, updateFocus } from '@hcengineering/view-resources'
@ -46,6 +47,7 @@
import { workbenchGuestSeparators } from '..'
const excludedApps = getMetadata(workbench.metadata.ExcludedApplications) ?? []
$deviceInfo.navigator.visible = false
const client = getClient()
@ -277,22 +279,18 @@
<div class="workbench-container inner">
<div class="antiPanel-component antiComponent" bind:this={contentPanel}>
{#if currentApplication && currentApplication.component}
<Component is={currentApplication.component} props={{ currentSpace, visibleNav: false }} />
<Component is={currentApplication.component} props={{ currentSpace }} />
{:else if specialComponent}
<Component
is={specialComponent.component}
props={{
model: navigatorModel,
...specialComponent.componentProps,
currentSpace,
visibleNav: false
currentSpace
}}
/>
{:else if currentView?.component !== undefined}
<Component
is={currentView.component}
props={{ ...currentView.componentProps, currentView, visibleNav: false }}
/>
<Component is={currentView.component} props={{ ...currentView.componentProps, currentView }} />
{:else}
<SpaceView {currentSpace} {currentView} />
{/if}

View File

@ -30,7 +30,8 @@
Separator,
TabList,
defineSeparators,
workbenchSeparators
workbenchSeparators,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import view from '@hcengineering/view'
@ -39,10 +40,6 @@
import ScheduleView from './ScheduleView.svelte'
import Sidebar from './sidebar/Sidebar.svelte'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
const accountEmployee = $employeeByIdStore.get((getCurrentAccount() as PersonAccount).person as Ref<Employee>)
let accountStaff: Staff | undefined
@ -129,20 +126,18 @@
</script>
<div class="flex h-full clear-mins">
{#if visibleNav}
{#if $deviceInfo.navigator.visible}
<Sidebar
{department}
{descendants}
departmentById={departments}
{navFloat}
{appsDirection}
on:selected={(e) => {
departmentSelected(e.detail)
}}
/>
<Separator
name={'workbench'}
float={navFloat}
float={$deviceInfo.navigator.float}
disabledWhen={['panel-aside']}
index={0}
color={'var(--theme-navpanel-border)'}

View File

@ -26,7 +26,6 @@
export let rooms: Room[] = []
export let floor: Ref<Floor>
export let visibleNav: boolean
const dispatch = createEventDispatcher()
@ -45,7 +44,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb title={selectedFloor?.name ?? ''} size={'large'} isCurrent />
<svelte:fragment slot="actions">
{#if editable}

View File

@ -38,7 +38,6 @@
export let rooms: Room[] = []
export let floor: Ref<Floor>
export let visibleNav: boolean
export let excludedPersons: Ref<Contact>[] = []
const client = getClient()
@ -291,7 +290,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb title={selectedFloor?.name ?? ''} size={'large'} isCurrent />
<svelte:fragment slot="actions">
<ButtonIcon icon={IconAdd} size={'small'} on:click={addRoom} />

View File

@ -22,7 +22,8 @@
Separator,
defineSeparators,
eventToHTMLElement,
showPopup
showPopup,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import { Floor as FloorType, Room } from '@hcengineering/love'
import love from '../plugin'
@ -31,9 +32,6 @@
import EditFloorPopup from './EditFloorPopup.svelte'
import FloorPreview from './FloorPreview.svelte'
export let visibleNav: boolean
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
export let floor: Ref<FloorType>
export let configure: boolean
@ -53,9 +51,9 @@
defineSeparators('love', loveSeparators)
</script>
{#if visibleNav}
{#if $deviceInfo.navigator.visible}
<div
class="antiPanel-navigator {appsDirection === 'horizontal'
class="antiPanel-navigator {$deviceInfo.navigator.direction === 'horizontal'
? 'portrait'
: 'landscape'} border-left will-change-opacity"
>
@ -93,7 +91,14 @@
{/each}
</Scroller>
</div>
<Separator name={'love'} float={navFloat ? 'navigator' : true} index={0} color={'transparent'} />
<Separator name={'love'} float={$deviceInfo.navigator.float ? 'navigator' : true} index={0} color={'transparent'} />
</div>
<Separator name={'love'} float={navFloat} index={0} color={'transparent'} separatorSize={0} short />
<Separator
name={'love'}
float={$deviceInfo.navigator.float}
index={0}
color={'transparent'}
separatorSize={0}
short
/>
{/if}

View File

@ -14,6 +14,7 @@
-->
<script lang="ts">
import { Ref } from '@hcengineering/core'
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
import { Floor as FloorType, Office, Room, isOffice } from '@hcengineering/love'
import { activeFloor, floors, rooms } from '../stores'
import Floor from './Floor.svelte'
@ -21,42 +22,32 @@
import Floors from './Floors.svelte'
import { Contact, Person } from '@hcengineering/contact'
export let visibleNav: boolean
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
function getRooms (rooms: Room[], floor: Ref<FloorType>): Room[] {
return rooms.filter((p) => p.floor === floor)
}
let selectedFloor = $activeFloor === '' ? $floors[0]?._id : $activeFloor
let configure: boolean = false
let replacedPanel: HTMLElement
let excludedPersons: Ref<Contact>[] = []
$: excludedPersons = $rooms
.filter((p) => isOffice(p) && p.person !== null)
.map((p) => (p as Office).person) as Ref<Person>[]
$: $deviceInfo.replacedPanel = replacedPanel
</script>
<Floors bind:visibleNav {navFloat} {appsDirection} bind:floor={selectedFloor} bind:configure />
<div class="antiPanel-component filledNav">
<Floors bind:floor={selectedFloor} bind:configure />
<div class="antiPanel-component filledNav" bind:this={replacedPanel}>
{#if configure}
<FloorConfigure
rooms={getRooms($rooms, selectedFloor)}
floor={selectedFloor}
{visibleNav}
{excludedPersons}
on:change={(event) => (visibleNav = event.detail)}
on:configure={() => (configure = false)}
/>
{:else}
<Floor
rooms={getRooms($rooms, selectedFloor)}
floor={selectedFloor}
{visibleNav}
on:change={(event) => (visibleNav = event.detail)}
on:configure={() => (configure = true)}
/>
<Floor rooms={getRooms($rooms, selectedFloor)} floor={selectedFloor} on:configure={() => (configure = true)} />
{/if}
</div>

View File

@ -14,24 +14,27 @@
-->
<script lang="ts">
import { RoomType } from '@hcengineering/love'
import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
import { currentRoom } from '../stores'
import { screenSharing } from '../utils'
import Hall from './Hall.svelte'
import RoomComponent from './Room.svelte'
import { onMount, onDestroy } from 'svelte'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
const localNav: boolean = $deviceInfo.navigator.visible
const savedNav = localStorage.getItem('love-visibleNav')
if (savedNav !== undefined) $deviceInfo.navigator.visible = savedNav === 'true'
$: localStorage.setItem('love-visibleNav', JSON.stringify($deviceInfo.navigator.visible))
const saved = localStorage.getItem('love-visibleNav')
if (saved !== undefined) visibleNav = saved === 'true'
$: localStorage.setItem('love-visibleNav', JSON.stringify(visibleNav))
onDestroy(() => {
$deviceInfo.navigator.visible = localNav
})
</script>
<div class="hulyPanels-container" class:left-divider={$screenSharing || $currentRoom?.type === RoomType.Video}>
{#if ($currentRoom !== undefined && $screenSharing) || $currentRoom?.type === RoomType.Video}
<RoomComponent withVideo={$currentRoom.type === RoomType.Video} room={$currentRoom} />
{:else}
<Hall bind:visibleNav {navFloat} {appsDirection} />
<Hall />
{/if}
</div>

View File

@ -5,14 +5,9 @@
import { DevicesPreference } from '@hcengineering/love'
import love from '../plugin'
import { myPreferences } from '../stores'
import { createEventDispatcher } from 'svelte'
import { krispProcessor } from '../utils'
import { isKrispNoiseFilterSupported } from '@livekit/krisp-noise-filter'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
async function saveMicPreference (myPreferences: DevicesPreference | undefined, value: boolean): Promise<void> {
@ -66,7 +61,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={love.icon.Love} label={love.string.Settings} size={'large'} isCurrent />
</Header>
<div class="flex-row-stretch flex-grow p-10">

View File

@ -13,7 +13,7 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher, onDestroy } from 'svelte'
import { onDestroy } from 'svelte'
import { Ref } from '@hcengineering/core'
import type {
BaseNotificationType,
@ -40,10 +40,6 @@
import notification from '../plugin'
import NotificationGroupSetting from './NotificationGroupSetting.svelte'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
const groups: NotificationGroup[] = client.getModel().findAllSync(notification.class.NotificationGroup, {})
const preferencesGroups: NotificationPreferencesGroup[] = client
@ -90,7 +86,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb
icon={notification.icon.Notifications}
label={notification.string.Notifications}

View File

@ -33,7 +33,8 @@
Scroller,
Separator,
TabItem,
TabList
TabList,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import chunter, { ThreadMessage } from '@hcengineering/chunter'
import activity, { ActivityMessage } from '@hcengineering/activity'
@ -50,10 +51,6 @@
import notification from '../../plugin'
import InboxMenuButton from './InboxMenuButton.svelte'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
const client = getClient()
const hierarchy = client.getHierarchy()
const me = getCurrentAccount()
@ -407,9 +404,9 @@
/>
<div class="flex-row-top h-full">
{#if visibleNav}
{#if $deviceInfo.navigator.visible}
<div
class="antiPanel-navigator {appsDirection === 'horizontal'
class="antiPanel-navigator {$deviceInfo.navigator.direction === 'horizontal'
? 'portrait'
: 'landscape'} background-comp-header-color"
>
@ -437,9 +434,9 @@
/>
</Scroller>
</div>
<Separator name="inbox" float={navFloat ? 'navigator' : true} index={0} />
<Separator name="inbox" float={$deviceInfo.navigator.float ? 'navigator' : true} index={0} />
</div>
<Separator name="inbox" float={navFloat} index={0} />
<Separator name="inbox" float={$deviceInfo.navigator.float} index={0} />
{/if}
<div class="antiPanel-component filled w-full">
{#if selectedContext && selectedComponent}

View File

@ -13,7 +13,6 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import core, { Class, Doc, Obj, Ref, isOwnerOrMaintainer } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
@ -48,10 +47,8 @@
| undefined = undefined
export let withoutHeader = false
export let useOfClassAttributes = true
export let visibleNav: boolean = true
const canEdit = isOwnerOrMaintainer()
const dispatch = createEventDispatcher()
const loc = getLocation()
const client = getClient()
@ -105,7 +102,7 @@
<div class="hulyComponent">
{#if !withoutHeader}
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.Clazz} label={setting.string.ClassSetting} size={'large'} isCurrent />
</Header>
{/if}

View File

@ -13,16 +13,11 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { PluginConfiguration } from '@hcengineering/core'
import { configurationStore, getClient } from '@hcengineering/presentation'
import { Button, Icon, IconInfo, Label, Header, Breadcrumb, Scroller } from '@hcengineering/ui'
import setting from '../plugin'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
async function change (config: PluginConfiguration, value: boolean): Promise<void> {
@ -33,7 +28,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.Setting} label={setting.string.Configuration} size={'large'} isCurrent />
</Header>
<div class="hulyComponent-content__column content">

View File

@ -31,14 +31,9 @@
showPopup
} from '@hcengineering/ui'
import { showMenu } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import setting from '../plugin'
import EnumValues from './EnumValues.svelte'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const query = createQuery()
let enums: Enum[] = []
@ -60,7 +55,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.Enums} label={setting.string.Enums} size={'large'} isCurrent />
<svelte:fragment slot="actions">
<ModernButton

View File

@ -13,7 +13,6 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Ref, getCurrentAccount } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import type { Integration, IntegrationType } from '@hcengineering/setting'
@ -21,10 +20,6 @@
import { Header, Breadcrumb } from '@hcengineering/ui'
import PluginCard from './PluginCard.svelte'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const accountId = getCurrentAccount()._id
const typeQuery = createQuery()
const integrationQuery = createQuery()
@ -45,7 +40,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.Integrations} label={setting.string.Integrations} size={'large'} isCurrent />
</Header>
<div class="ac-body__cards-container">

View File

@ -13,16 +13,11 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import login from '@hcengineering/login'
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
import setting, { InviteSettings } from '@hcengineering/setting'
import { Button, EditBox, MiniToggle, Header, Breadcrumb } from '@hcengineering/ui'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
let expTime: number = 48
let mask: string = ''
@ -61,7 +56,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.InviteSettings} label={setting.string.InviteSettings} size={'large'} isCurrent />
</Header>
<div class="form">

View File

@ -18,12 +18,8 @@
import { AccountRole, getCurrentAccount, hasAccountRole } from '@hcengineering/core'
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
import { Breadcrumb, DropdownIntlItem, DropdownLabelsIntl, EditBox, Header, Scroller } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import setting from '../plugin'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
const query = createQuery()
const currentAccount = getCurrentAccount()
@ -50,7 +46,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.Owners} label={setting.string.Owners} size={'large'} isCurrent />
<EditBox kind={'search-style'} focusIndex={1} bind:value={search} placeholder={presentation.string.Search} />
</Header>

View File

@ -19,14 +19,9 @@
import presentation from '@hcengineering/presentation'
import setting from '@hcengineering/setting'
import { Breadcrumb, Button, EditBox, Header, Icon, Label } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import plugin from '../plugin'
import Error from './icons/Error.svelte'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
let oldPassword: string = ''
let password: string = ''
let password2: string = ''
@ -62,7 +57,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.Password} label={setting.string.ChangePassword} size={'large'} isCurrent />
</Header>
<div class="flex-row-stretch flex-grow p-10">

View File

@ -20,13 +20,9 @@
import { getResource } from '@hcengineering/platform'
import { AttributeEditor, MessageBox, getClient } from '@hcengineering/presentation'
import { Breadcrumb, Button, EditBox, FocusHandler, Header, createFocusManager, showPopup } from '@hcengineering/ui'
import { createEventDispatcher, onDestroy } from 'svelte'
import { onDestroy } from 'svelte'
import setting from '../plugin'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
let avatarEditor: EditableAvatar
@ -87,7 +83,7 @@
<FocusHandler {manager} />
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.AccountSettings} label={setting.string.AccountSettings} size={'large'} isCurrent />
</Header>
<div class="ac-body p-10">

View File

@ -34,16 +34,13 @@
setMetadataLocalStorage,
settingsSeparators,
showPopup,
type AnyComponent
type AnyComponent,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import { NavFooter } from '@hcengineering/workbench-resources'
import { ComponentType, onDestroy } from 'svelte'
import { clearSettingsStore, settingsStore, type SettingsStore } from '../store'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
let category: SettingsCategory | undefined
let categoryId: string = ''
@ -121,9 +118,11 @@
</script>
<div class="hulyPanels-container">
{#if visibleNav}
{#if $deviceInfo.navigator.visible}
<div
class="antiPanel-navigator {appsDirection === 'horizontal' ? 'portrait' : 'landscape'} border-left"
class="antiPanel-navigator {$deviceInfo.navigator.direction === 'horizontal'
? 'portrait'
: 'landscape'} border-left"
class:border-right={category?.component === undefined}
>
<div class="antiPanel-wrap__content hulyNavPanel-container">
@ -178,21 +177,26 @@
<NavItem icon={setting.icon.Signout} label={setting.string.Signout} on:click={signOut} />
</NavFooter>
</div>
<Separator name={'setting'} float={navFloat ? 'navigator' : true} index={0} color={'transparent'} />
<Separator
name={'setting'}
float={$deviceInfo.navigator.float ? 'navigator' : true}
index={0}
color={'transparent'}
/>
</div>
<Separator name={'setting'} float={navFloat} index={0} color={'transparent'} separatorSize={0} short />
<Separator
name={'setting'}
float={$deviceInfo.navigator.float}
index={0}
color={'transparent'}
separatorSize={0}
short
/>
{/if}
<div class="antiPanel-component filledNav" style:flex-direction={'row'}>
{#if category}
<Component
is={category.component}
props={{
kind: 'content',
visibleNav
}}
on:change={(event) => (visibleNav = event.detail)}
/>
<Component is={category.component} props={{ kind: 'content' }} />
{/if}
</div>
{#if asideComponent != null}

View File

@ -13,19 +13,15 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Header, Breadcrumb, Label } from '@hcengineering/ui'
import { Header, Breadcrumb } from '@hcengineering/ui'
import core, { Account, Ref, Role, RolesAssignment, SpaceType, TypedSpace, WithLookup } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { AccountArrayEditor } from '@hcengineering/contact-resources'
import setting from '../plugin'
export let visibleNav: boolean = true
const client = getClient()
const hierarchy = client.getHierarchy()
const dispatch = createEventDispatcher()
let space: TypedSpace
let spaceType: WithLookup<SpaceType>
@ -81,7 +77,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={setting.icon.Views} label={setting.string.Spaces} size="large" isCurrent />
</Header>
<div class="hulyComponent-content__column content">

View File

@ -19,12 +19,8 @@
import { getClient } from '@hcengineering/presentation'
import { WorkspaceSetting } from '@hcengineering/setting'
import { FocusHandler, Label, createFocusManager } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import setting from '../plugin'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
let workspaceSettings: WorkspaceSetting | undefined = undefined
const client = getClient()

View File

@ -30,7 +30,6 @@
export let kind: 'navigation' | 'content' | undefined
export let categoryName: string
export let visibleNav: boolean = true
let category: SettingsCategory | undefined
let categoryId: string = ''
@ -98,5 +97,5 @@
{:else if kind === 'content' && !category}
<div class="hulyComponent" />
{:else if category}
<Component is={category.component} props={{ kind: 'content', visibleNav }} on:change />
<Component is={category.component} props={{ kind: 'content' }} on:change />
{/if}

View File

@ -14,7 +14,7 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher, onDestroy } from 'svelte'
import { onDestroy } from 'svelte'
import core, {
Class,
Doc,
@ -47,9 +47,6 @@
import SpaceTypeEditorComponent from './editor/SpaceTypeEditor.svelte'
import { clearSettingsStore } from '../../store'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
const hierarchy = client.getHierarchy()
const canEdit = isOwnerOrMaintainer()
@ -143,7 +140,7 @@
}}
>
{#if type !== undefined && descriptor !== undefined}
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
{#if canEdit}
<ButtonIcon
icon={IconCopy}

View File

@ -1,5 +1,4 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import core, { Data, Ref } from '@hcengineering/core'
import { getEmbeddedLabel, getResource } from '@hcengineering/platform'
import { createQuery, getClient, MessageViewer, SpaceSelector } from '@hcengineering/presentation'
@ -26,10 +25,6 @@
import CreateTemplateCategory from './CreateTemplateCategory.svelte'
import FieldPopup from './FieldPopup.svelte'
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
const client = getClient()
const query = createQuery()
const spaceQ = createQuery()
@ -156,7 +151,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb
icon={templatesPlugin.icon.Templates}
label={templatesPlugin.string.Templates}

View File

@ -1,11 +1,7 @@
<script lang="ts">
import PlanView from './PlanView.svelte'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
</script>
<div class="hulyPanels-container">
<PlanView {visibleNav} {navFloat} {appsDirection} on:change />
<PlanView on:change />
</div>

View File

@ -29,10 +29,6 @@
import { dragging } from '../dragging'
import time from '../plugin'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
const dispatch = createEventDispatcher()
const defaultDuration = 30 * 60 * 1000
@ -84,28 +80,22 @@
})
</script>
{#if visibleNav}
<ToDosNavigator bind:mode bind:tag bind:currentDate {navFloat} {appsDirection} />
{#if $deviceInfo.navigator.visible}
<ToDosNavigator bind:mode bind:tag bind:currentDate />
<Separator
name={'time'}
float={navFloat}
float={$deviceInfo.navigator.float}
index={0}
disabledWhen={['panel-aside']}
color={'var(--theme-navpanel-border)'}
/>
{/if}
<div class="flex-col w-full clear-mins" class:left-divider={!visibleNav} bind:this={mainPanel}>
<ToDos {mode} {tag} bind:visibleNav bind:currentDate />
<div class="flex-col w-full clear-mins" class:left-divider={!$deviceInfo.navigator.visible} bind:this={mainPanel}>
<ToDos {mode} {tag} bind:currentDate />
</div>
{#if visibleCalendar}
<Separator name={'time'} index={1} color={'transparent'} separatorSize={0} short />
<div class="flex-col clear-mins" bind:this={replacedPanel}>
<PlanningCalendar
{dragItem}
bind:currentDate
displayedDaysCount={5}
on:dragDrop={drop}
on:change={(event) => (visibleNav = event.detail)}
/>
<PlanningCalendar {dragItem} bind:currentDate displayedDaysCount={5} on:dragDrop={drop} />
</div>
{/if}

View File

@ -21,7 +21,16 @@
import type { TagElement } from '@hcengineering/tags'
import type { Project } from '@hcengineering/tracker'
import type { ToDosMode } from '..'
import { Scroller, areDatesEqual, todosSP, defaultSP, Header, ButtonIcon, Label } from '@hcengineering/ui'
import {
Scroller,
areDatesEqual,
todosSP,
defaultSP,
Header,
ButtonIcon,
Label,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import { getCurrentAccount, toIdMap, SortingOrder } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import tracker from '@hcengineering/tracker'
@ -38,7 +47,6 @@
export let mode: ToDosMode
export let tag: Ref<TagElement> | undefined
export let currentDate: Date
export let visibleNav: boolean = true
const acc = getCurrentAccount() as PersonAccount
const user = acc.person
@ -59,7 +67,7 @@
$: updateTags(mode, tag)
function togglePlannerNav (): void {
visibleNav = !visibleNav
$deviceInfo.navigator.visible = !$deviceInfo.navigator.visible
}
function updateTags (mode: ToDosMode, tag: Ref<TagElement> | undefined): void {
@ -279,10 +287,10 @@
<div class="toDos-container">
<Header type={'type-panel'} hideSeparator>
<ButtonIcon
icon={visibleNav ? MenuClose : MenuOpen}
icon={$deviceInfo.navigator.visible ? MenuClose : MenuOpen}
kind={'tertiary'}
size={'small'}
pressed={!visibleNav}
pressed={!$deviceInfo.navigator.visible}
on:click={togglePlannerNav}
/>
<div class="heading-bold-20 ml-4">

View File

@ -13,15 +13,14 @@
Scroller,
Month,
getPlatformColorDef,
themeStore
themeStore,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import { ToDosMode } from '..'
import time from '../plugin'
export let mode: ToDosMode
export let tag: Ref<TagElementType> | undefined
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
export let currentDate: Date
const acc = getCurrentAccount() as PersonAccount
@ -104,7 +103,9 @@
const today: Date = new Date()
</script>
<div class="antiPanel-navigator {appsDirection === 'horizontal' ? 'portrait' : 'landscape'} border-left">
<div
class="antiPanel-navigator {$deviceInfo.navigator.direction === 'horizontal' ? 'portrait' : 'landscape'} border-left"
>
<div class="antiPanel-wrap__content hulyNavPanel-container">
<div class="hulyNavPanel-header">
<Label label={time.string.Planner} />
@ -203,7 +204,7 @@
</div>
<Separator
name={'time'}
float={navFloat ? 'navigator' : true}
float={$deviceInfo.navigator.float ? 'navigator' : true}
index={0}
disabledWhen={['panel-aside']}
color={'var(--theme-navpanel-border)'}

View File

@ -16,16 +16,13 @@
import { Ref } from '@hcengineering/core'
import { IntlString } from '@hcengineering/platform'
import { Project } from '@hcengineering/task'
import { Label, ModeSelector, Separator, defineSeparators } from '@hcengineering/ui'
import { Label, ModeSelector, Separator, defineSeparators, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
import time from '../../plugin'
import { teamSeparators } from '../../utils'
import TeamNavigator from './TeamNavigator.svelte'
import Agenda from './agenda/Agenda.svelte'
import Calendar from './calendar/Calendar.svelte'
export let visibleNav: boolean = true
export let navFloat: boolean = false
export let appsDirection: 'vertical' | 'horizontal' = 'horizontal'
let currentDate: Date = new Date()
let space: Ref<Project> | undefined = undefined
@ -45,11 +42,11 @@
</script>
<div class="background-comp-header-color w-full h-full flex-row-top">
{#if visibleNav}
<TeamNavigator {navFloat} {appsDirection} bind:selected={space} />
{#if $deviceInfo.navigator.visible}
<TeamNavigator bind:selected={space} />
<Separator
name={'team'}
float={navFloat}
float={$deviceInfo.navigator.float}
index={0}
disabledWhen={['panel-aside']}
color={'var(--theme-navpanel-border)'}

View File

@ -1,18 +1,14 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Space } from '@hcengineering/core'
import { Header, Breadcrumb } from '@hcengineering/ui'
import tracker from '../plugin'
import EditRelatedTargets from './EditRelatedTargets.svelte'
export let value: Space | undefined
export let visibleNav: boolean = true
const dispatch = createEventDispatcher()
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={tracker.icon.Relations} label={tracker.string.RelatedIssues} size={'large'} isCurrent />
</Header>
<EditRelatedTargets {value} />

View File

@ -16,7 +16,6 @@
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import contact from '@hcengineering/contact-resources/src/plugin'
import { AccountArrayEditor } from '@hcengineering/contact-resources'
import core, {
@ -33,12 +32,9 @@
import training from '../plugin'
export let visibleNav: boolean = true
const client = getClient()
const hierarchy = client.getHierarchy()
const query = createQuery()
const dispatch = createEventDispatcher()
let space: TypedSpace | null = null
let spaceType: SpaceType | null = null
let roles: Role[] | null = null
@ -87,7 +83,7 @@
</script>
<div class="hulyComponent">
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<Header>
<Breadcrumb icon={training.icon.Training} label={training.string.Trainings} size="large" isCurrent />
</Header>
<div class="hulyComponent-content__column content">

View File

@ -117,9 +117,9 @@
let panelInstance: PanelInstance
let popupInstance: Popup
let visibleNav: boolean = getMetadata(workbench.metadata.NavigationExpandedDefault) ?? true
$deviceInfo.navigator.visible = getMetadata(workbench.metadata.NavigationExpandedDefault) ?? true
async function toggleNav (): Promise<void> {
visibleNav = !visibleNav
$deviceInfo.navigator.visible = !$deviceInfo.navigator.visible
closeTooltip()
if (currentApplication && navigatorModel && navigator) {
await tick()
@ -499,21 +499,20 @@
let aside: HTMLElement
let cover: HTMLElement
let navFloat: boolean = !($deviceInfo.docWidth < 1024)
$: if ($deviceInfo.docWidth <= 1024 && !navFloat) {
visibleNav = false
navFloat = true
} else if ($deviceInfo.docWidth > 1024 && navFloat) {
$deviceInfo.navigator.float = !($deviceInfo.docWidth < 1024)
$: if ($deviceInfo.docWidth <= 1024 && !$deviceInfo.navigator.float) {
$deviceInfo.navigator.visible = false
$deviceInfo.navigator.float = true
} else if ($deviceInfo.docWidth > 1024 && $deviceInfo.navigator.float) {
if (getMetadata(workbench.metadata.NavigationExpandedDefault) === undefined) {
navFloat = false
visibleNav = true
$deviceInfo.navigator.float = false
$deviceInfo.navigator.visible = true
}
}
const checkOnHide = (): void => {
if (visibleNav && $deviceInfo.docWidth <= 1024) visibleNav = false
if ($deviceInfo.navigator.visible && $deviceInfo.docWidth <= 1024) $deviceInfo.navigator.visible = false
}
let appsDirection: 'vertical' | 'horizontal'
$: appsDirection = $deviceInfo.isMobile && $deviceInfo.isPortrait ? 'horizontal' : 'vertical'
$: $deviceInfo.navigator.direction = $deviceInfo.isMobile && $deviceInfo.isPortrait ? 'horizontal' : 'vertical'
let appsMini: boolean
$: appsMini =
$deviceInfo.isMobile &&
@ -521,13 +520,17 @@
(!$deviceInfo.isPortrait && $deviceInfo.docHeight <= 480))
let popupPosition: PopupPosAlignment
$: popupPosition =
appsDirection === 'horizontal'
$deviceInfo.navigator.direction === 'horizontal'
? 'account-portrait'
: appsDirection === 'vertical' && $deviceInfo.isMobile
: $deviceInfo.navigator.direction === 'vertical' && $deviceInfo.isMobile
? 'account-mobile'
: 'account'
let popupSpacePosition: PopupPosAlignment
$: popupSpacePosition = appsMini ? 'logo-mini' : appsDirection === 'horizontal' ? 'logo-portrait' : 'logo'
$: popupSpacePosition = appsMini
? 'logo-mini'
: $deviceInfo.navigator.direction === 'horizontal'
? 'logo-portrait'
: 'logo'
onMount(() => {
subscribeMobile(setTheme)
@ -627,13 +630,16 @@
<div
class="workbench-container"
class:modern-app={modern}
style:flex-direction={appsDirection === 'horizontal' ? 'column-reverse' : 'row'}
style:flex-direction={$deviceInfo.navigator.direction === 'horizontal' ? 'column-reverse' : 'row'}
>
<div class="antiPanel-application {appsDirection} no-print" class:lastDivider={!visibleNav}>
<div
class="antiPanel-application {$deviceInfo.navigator.direction} no-print"
class:lastDivider={!$deviceInfo.navigator.visible}
>
<div
class="hamburger-container clear-mins"
class:portrait={appsDirection === 'horizontal'}
class:landscape={appsDirection === 'vertical'}
class:portrait={$deviceInfo.navigator.direction === 'horizontal'}
class:landscape={$deviceInfo.navigator.direction === 'vertical'}
>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
@ -649,8 +655,8 @@
<div class="topmenu-container clear-mins flex-no-shrink" class:mini={appsMini}>
<AppItem
icon={TopMenu}
label={visibleNav ? workbench.string.HideMenu : workbench.string.ShowMenu}
selected={!visibleNav}
label={$deviceInfo.navigator.visible ? workbench.string.HideMenu : workbench.string.ShowMenu}
selected={!$deviceInfo.navigator.visible}
size={appsMini ? 'small' : 'medium'}
on:click={toggleNav}
/>
@ -675,9 +681,13 @@
notify={hasInboxNotifications}
/>
</NavLink>
<Applications {apps} active={currentApplication?._id} direction={appsDirection} />
<Applications {apps} active={currentApplication?._id} direction={$deviceInfo.navigator.direction} />
</div>
<div class="info-box {appsDirection}" class:vertical-mobile={appsDirection === 'vertical'} class:mini={appsMini}>
<div
class="info-box {$deviceInfo.navigator.direction}"
class:vertical-mobile={$deviceInfo.navigator.direction === 'vertical'}
class:mini={appsMini}
>
<AppItem
icon={IconSettings}
label={setting.string.Settings}
@ -709,7 +719,11 @@
/>
{/if}
{/await} -->
<div class="flex-center" class:mt-3={appsDirection === 'vertical'} class:ml-2={appsDirection === 'horizontal'}>
<div
class="flex-center"
class:mt-3={$deviceInfo.navigator.direction === 'vertical'}
class:ml-2={$deviceInfo.navigator.direction === 'horizontal'}
>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
@ -732,11 +746,17 @@
}}
/>
<div class="workbench-container inner">
{#if currentApplication && navigatorModel && navigator && visibleNav}
{#if currentApplication && navigatorModel && navigator && $deviceInfo.navigator.visible}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
{#if navFloat}<div class="cover shown" on:click={() => (visibleNav = false)} />{/if}
<div class="antiPanel-navigator no-print {appsDirection === 'horizontal' ? 'portrait' : 'landscape'}">
{#if $deviceInfo.navigator.float}
<div class="cover shown" on:click={() => ($deviceInfo.navigator.visible = false)} />
{/if}
<div
class="antiPanel-navigator no-print {$deviceInfo.navigator.direction === 'horizontal'
? 'portrait'
: 'landscape'}"
>
<div class="antiPanel-wrap__content hulyNavPanel-container">
{#if currentApplication}
<NavHeader label={currentApplication.label} />
@ -768,27 +788,25 @@
</div>
<Separator
name={'workbench'}
float={navFloat ? 'navigator' : true}
float={$deviceInfo.navigator.float ? 'navigator' : true}
index={0}
color={'var(--theme-navpanel-border)'}
/>
</div>
<Separator name={'workbench'} float={navFloat} index={0} color={'var(--theme-navpanel-border)'} />
<Separator
name={'workbench'}
float={$deviceInfo.navigator.float}
index={0}
color={'var(--theme-navpanel-border)'}
/>
{/if}
<div class="antiPanel-component antiComponent" bind:this={contentPanel}>
{#if currentApplication && currentApplication.component}
<Component is={currentApplication.component} props={{ currentSpace, visibleNav, navFloat, appsDirection }} />
<Component is={currentApplication.component} props={{ currentSpace }} />
{:else if specialComponent}
<Component
is={specialComponent.component}
props={{
model: navigatorModel,
...specialComponent.componentProps,
currentSpace,
visibleNav,
navFloat,
appsDirection
}}
props={{ model: navigatorModel, ...specialComponent.componentProps, currentSpace }}
on:action={(e) => {
if (e?.detail) {
const loc = getCurrentLocation()
@ -798,10 +816,7 @@
}}
/>
{:else if currentView?.component !== undefined}
<Component
is={currentView.component}
props={{ ...currentView.componentProps, currentView, visibleNav, navFloat, appsDirection }}
/>
<Component is={currentView.component} props={{ ...currentView.componentProps, currentView }} />
{:else if $accessDeniedStore}
<div class="flex-center h-full">
<h2><Label label={workbench.string.AccessDenied} /></h2>
@ -969,37 +984,6 @@
display: block;
}
}
.splitter {
position: relative;
width: 1px;
min-width: 1px;
max-width: 1px;
height: 100%;
background-color: var(--theme-divider-color);
transition: background-color 0.15s ease-in-out;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 0.5rem;
height: 100%;
border-left: 2px solid transparent;
cursor: col-resize;
z-index: 1;
transition: border-color 0.15s ease-in-out;
}
&:hover,
&.hovered {
transition-duration: 0;
background-color: var(--primary-bg-color);
&::before {
transition-duration: 0;
border-left: 2px solid var(--primary-bg-color);
}
}
}
@media print {
.workbench-container:has(~ .panel-instance) {