From 11a62367123a4fe42cb7cb768b57120c0bba33e0 Mon Sep 17 00:00:00 2001 From: Alexander Platov Date: Wed, 30 Oct 2024 19:19:04 +0300 Subject: [PATCH] Updated mobile layout: collapsing WorkbenchTabs, floating aSide. UI fixes. (#7066) Signed-off-by: Alexander Platov --- packages/theme/styles/_layouts.scss | 2 + packages/theme/styles/common.scss | 33 +++++-- packages/theme/styles/global.scss | 5 ++ packages/ui/src/components/ModernTab.svelte | 7 +- packages/ui/src/components/Panel.svelte | 20 ++--- packages/ui/src/components/ScrollerBar.svelte | 64 +++++--------- .../ui/src/components/icons/Details.svelte | 2 +- .../src/components/icons/DetailsFilled.svelte | 2 +- packages/ui/src/components/icons/MoreH.svelte | 2 +- .../ui/src/components/internal/Root.svelte | 86 ++++++++++++++++-- .../internal/RootBarExtension.svelte | 2 +- packages/ui/src/index.ts | 1 + packages/ui/src/resize.ts | 2 +- packages/ui/src/types.ts | 1 + plugins/chunter-resources/src/navigation.ts | 7 +- .../components/MergeAttributeComparer.svelte | 2 +- .../src/components/MergeComparer.svelte | 67 +++++++------- .../src/components/MergePersons.svelte | 16 ++-- .../src/components/WorkbenchExtension.svelte | 2 +- .../src/components/FileUploadExt.svelte | 12 +-- .../src/components/WorkbenchExtension.svelte | 4 +- .../src/components/FixedColumn.svelte | 3 + .../src/components/AppItem.svelte | 4 +- .../src/components/Logo.svelte | 4 +- .../src/components/Workbench.svelte | 34 ++++++-- .../src/components/WorkbenchTabs.svelte | 87 +++++++++++++++---- .../src/components/sidebar/Sidebar.svelte | 23 ++++- .../sidebar/widgets/WidgetsBar.svelte | 6 +- plugins/workbench-resources/src/index.ts | 1 + .../model/recruiting/talent-details-page.ts | 29 ++----- 30 files changed, 349 insertions(+), 181 deletions(-) diff --git a/packages/theme/styles/_layouts.scss b/packages/theme/styles/_layouts.scss index b72c1face3..3247cfbf48 100644 --- a/packages/theme/styles/_layouts.scss +++ b/packages/theme/styles/_layouts.scss @@ -501,6 +501,7 @@ input.search { .ml-8 { margin-left: 2rem; } .ml-10 { margin-left: 2.5rem; } .ml-12 { margin-left: 3rem; } +.ml-14 { margin-left: 3.5rem; } .ml-22 { margin-left: 5.5rem; } .ml-auto { margin-left: auto; } .mr-0-5 { margin-right: .125rem; } @@ -744,6 +745,7 @@ input.search { .min-h-16 { min-height: 4rem; } .min-h-30 { min-height: 7.5rem; } .min-h-60 { min-height: 15rem; } +.max-w-0 { max-width: 0; } .max-w-2 { max-width: .5rem; } .max-w-4 { max-width: 1rem; } .max-w-9 { max-width: 2.25rem; } diff --git a/packages/theme/styles/common.scss b/packages/theme/styles/common.scss index 87c6982bc2..3509ad2b06 100644 --- a/packages/theme/styles/common.scss +++ b/packages/theme/styles/common.scss @@ -141,23 +141,40 @@ } .antiPanel-navigator { position: relative; - min-width: 12.5rem; - max-width: 22.5rem; - width: 17.5rem; background-color: var(--theme-navpanel-color); + + &:not(.right) { + min-width: 12.5rem; + max-width: 22.5rem; + width: 17.5rem; + } + &.right { + overflow: hidden; + border-radius: var(--medium-BorderRadius) 0 0 var(--medium-BorderRadius); + } } @media (max-width: 1024px) { .antiPanel-navigator { position: fixed; - 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; + + &:not(.right) { + top: calc(var(--status-bar-height) + 1px); + height: calc(100% - var(--status-bar-height) - 1px); + filter: drop-shadow(2px 0 5px rgba(0, 0, 0, .2)); - &.portrait { left: 0; } - &.landscape { left: var(--app-panel-width); } + &.portrait { left: 0; } + &.landscape { left: var(--app-panel-width); } + } + &.right { + top: var(--status-bar-height); + right: 0; + height: calc(100% - var(--status-bar-height) - 1px); + background-color: var(--theme-statusbar-color); + filter: drop-shadow(-2px 0 5px rgba(0, 0, 0, .2)); + } } } .antiPanel-component { diff --git a/packages/theme/styles/global.scss b/packages/theme/styles/global.scss index f3e054d191..a7f883a923 100644 --- a/packages/theme/styles/global.scss +++ b/packages/theme/styles/global.scss @@ -78,6 +78,7 @@ scrollbar-width: none; --body-font-size: .875rem; --status-bar-height: 36px; + --status-bar-normal-height: 36px; --panel-aside-width: 25rem; // 20rem; --font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto; --mono-font: 'IBM Plex Mono', monospace; @@ -89,6 +90,10 @@ &::after, &::before { box-sizing: border-box; } + + @media (max-width: 480px) { + --status-bar-height: 70px; + } } :root { --app-height: 100%; diff --git a/packages/ui/src/components/ModernTab.svelte b/packages/ui/src/components/ModernTab.svelte index 54054aafa3..24918a7bd7 100644 --- a/packages/ui/src/components/ModernTab.svelte +++ b/packages/ui/src/components/ModernTab.svelte @@ -36,7 +36,7 @@
{/if} - + {#if label} {label} {:else if labelIntl} @@ -100,11 +100,14 @@ &.horizontal { padding: 0.125rem 0.125rem 0.125rem 0.5rem; height: 1.625rem; + min-height: 1.625rem; + min-width: 6rem; } &.vertical { padding: 0.5rem 0.125rem 0.125rem 0.125rem; width: 1.625rem; + min-height: 6rem; writing-mode: vertical-rl; text-orientation: sideways; } diff --git a/packages/ui/src/components/Panel.svelte b/packages/ui/src/components/Panel.svelte index 7821e9832e..066d2bcd97 100644 --- a/packages/ui/src/components/Panel.svelte +++ b/packages/ui/src/components/Panel.svelte @@ -168,7 +168,7 @@
{#if $deviceInfo.isMobile} - -
{ - innerWidth = element.clientWidth - }} - > +
{ + innerWidth = element.clientWidth + }} + > + {#if $$slots.header && isHeader}
{/if} -
- + +
{:else}
- -
-
+
+
@@ -133,8 +117,8 @@ class="bar" class:hovered={isScrolling} bind:this={divBar} - on:mousedown={onScrollStart} - on:mouseleave={checkMask} + on:pointerdown={onScrollStart} + on:pointerleave={checkMask} />
diff --git a/packages/ui/src/components/icons/Details.svelte b/packages/ui/src/components/icons/Details.svelte index 26e6dd6629..82bd6fc69b 100644 --- a/packages/ui/src/components/icons/Details.svelte +++ b/packages/ui/src/components/icons/Details.svelte @@ -16,7 +16,7 @@ diff --git a/packages/ui/src/components/icons/DetailsFilled.svelte b/packages/ui/src/components/icons/DetailsFilled.svelte index 2da11f89d8..a223fbf9c7 100644 --- a/packages/ui/src/components/icons/DetailsFilled.svelte +++ b/packages/ui/src/components/icons/DetailsFilled.svelte @@ -15,7 +15,7 @@ --> diff --git a/packages/ui/src/components/icons/MoreH.svelte b/packages/ui/src/components/icons/MoreH.svelte index 98f32623c1..5b9ed2859a 100644 --- a/packages/ui/src/components/icons/MoreH.svelte +++ b/packages/ui/src/components/icons/MoreH.svelte @@ -1,6 +1,6 @@ diff --git a/packages/ui/src/components/internal/Root.svelte b/packages/ui/src/components/internal/Root.svelte index 443ae4b365..8356f9006f 100644 --- a/packages/ui/src/components/internal/Root.svelte +++ b/packages/ui/src/components/internal/Root.svelte @@ -5,7 +5,16 @@ import { deviceSizes, deviceWidths } from '../../types' // import { applicationShortcutKey } from '../../utils' import { Theme } from '@hcengineering/theme' - import { IconArrowLeft, IconArrowRight, checkMobile, deviceOptionsStore as deviceInfo } from '../../' + import { + IconArrowLeft, + IconArrowRight, + checkMobile, + deviceOptionsStore as deviceInfo, + checkAdaptiveMatching, + ButtonIcon, + IconDetailsFilled, + IconDetails + } from '../../' import { desktopPlatform, getCurrentLocation, location, locationStorageKeyId, navigate } from '../../location' import uiPlugin from '../../plugin' import Component from '../Component.svelte' @@ -129,6 +138,14 @@ } } updateDeviceSize() + + $: secondRow = checkAdaptiveMatching($deviceInfo.size, 'xs') + $: asideFloat = $deviceInfo.navigator.float + $: asideOpen = $deviceInfo.aside.visible + $: appsMini = + $deviceInfo.isMobile && + (($deviceInfo.isPortrait && $deviceInfo.docWidth <= 480) || + (!$deviceInfo.isPortrait && $deviceInfo.docHeight <= 480)) @@ -161,9 +178,15 @@
{/if} -
- -
+ {#if !secondRow} +
+ +
+ {/if}
+ {#if asideFloat && !secondRow} +
+ { + $deviceInfo.aside.visible = !$deviceInfo.aside.visible + }} + /> + {/if}
- + {#if !secondRow} + + {/if}
+ {#if secondRow} +
+
+ +
+
+ + { + $deviceInfo.aside.visible = !$deviceInfo.aside.visible + }} + /> +
+
+ {/if}
{#if application} @@ -213,6 +273,7 @@ .antiStatusBar { -webkit-app-region: drag; + min-width: 0; min-height: var(--status-bar-height); height: var(--status-bar-height); // min-width: 600px; @@ -248,6 +309,21 @@ margin: 0 12px 0 8px; } + .second-row { + display: none; + } + + @media (max-width: 480px) { + display: flex; + flex-direction: column; + gap: 2px; + padding: 2px 0; + width: 100%; + + .second-row { + display: flex; + } + } @media print { display: none; } diff --git a/packages/ui/src/components/internal/RootBarExtension.svelte b/packages/ui/src/components/internal/RootBarExtension.svelte index 5d33a0863e..6ce22ec56e 100644 --- a/packages/ui/src/components/internal/RootBarExtension.svelte +++ b/packages/ui/src/components/internal/RootBarExtension.svelte @@ -17,7 +17,7 @@ {#each sorted as ext (ext[1].id)} {#if ext[0] === position} -
+
({ isPortrait: false, isMobile: false, navigator: { visible: true, float: false, direction: 'vertical' }, + aside: { visible: true }, fontSize: 0, size: null, sizes: { xs: false, sm: false, md: false, lg: false, xl: false, xxl: false }, diff --git a/packages/ui/src/resize.ts b/packages/ui/src/resize.ts index aad3a64c4f..7ebae9e983 100644 --- a/packages/ui/src/resize.ts +++ b/packages/ui/src/resize.ts @@ -166,7 +166,7 @@ export const settingsSeparators: DefSeparators = [ export const mainSeparators: DefSeparators = [ { minSize: 30, size: 'auto', maxSize: 'auto' }, - { minSize: 20, size: 30, maxSize: 80, float: 'sidebar' } + { minSize: 25, size: 30, maxSize: 80, float: 'sidebar' } ] export const secondNavSeparators: DefSeparators = [{ minSize: 7, size: 7.5, maxSize: 15, float: 'navigator' }, null] diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index 33038525ad..f96794cdb3 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -378,6 +378,7 @@ export interface DeviceOptions { isPortrait: boolean isMobile: boolean navigator: { visible: boolean, float: boolean, direction: 'vertical' | 'horizontal' } + aside: { visible: boolean } fontSize: number size: WidthType | null sizes: Record diff --git a/plugins/chunter-resources/src/navigation.ts b/plugins/chunter-resources/src/navigation.ts index 8e13ecae37..6dc72ed16e 100644 --- a/plugins/chunter-resources/src/navigation.ts +++ b/plugins/chunter-resources/src/navigation.ts @@ -5,7 +5,8 @@ import { getLocation, type Location, navigate, - languageStore + languageStore, + deviceOptionsStore as deviceInfo } from '@hcengineering/ui' import { type Ref, type Doc, type Class, generateId } from '@hcengineering/core' import activity, { type ActivityMessage } from '@hcengineering/activity' @@ -179,6 +180,10 @@ export async function replyToThread (message: ActivityMessage, e: Event): Promis const fromSidebar = isElementFromSidebar(e.target as HTMLElement) const loc = getCurrentLocation() + const dev = get(deviceInfo) + dev.aside.visible = true + deviceInfo.set(dev) + threadMessagesStore.set(message) if (fromSidebar) { diff --git a/plugins/contact-resources/src/components/MergeAttributeComparer.svelte b/plugins/contact-resources/src/components/MergeAttributeComparer.svelte index b88c5b9882..b8f2f27988 100644 --- a/plugins/contact-resources/src/components/MergeAttributeComparer.svelte +++ b/plugins/contact-resources/src/components/MergeAttributeComparer.svelte @@ -23,7 +23,7 @@ export let targetEmp: Person export let key: string export let onChange: (key: string, value: boolean) => void - export let selected = false + export let selected: boolean = false const client = getClient() const hierarchy = client.getHierarchy() diff --git a/plugins/contact-resources/src/components/MergeComparer.svelte b/plugins/contact-resources/src/components/MergeComparer.svelte index 9417c0670f..d5ca6b4916 100644 --- a/plugins/contact-resources/src/components/MergeComparer.svelte +++ b/plugins/contact-resources/src/components/MergeComparer.svelte @@ -16,13 +16,14 @@ import { Person } from '@hcengineering/contact' import { Doc, Mixin, Ref } from '@hcengineering/core' import { getClient } from '@hcengineering/presentation' - import { CheckBox, Label } from '@hcengineering/ui' + import { Label, RadioButton } from '@hcengineering/ui' + import { FixedColumn } from '@hcengineering/view-resources' export let value: Person export let targetEmp: Person export let cast: Ref> | undefined = undefined export let key: string - export let selected = false + export let selected: boolean = false export let onChange: (key: string, value: boolean) => void const client = getClient() @@ -38,51 +39,51 @@ return (value as any)[key] === (targetEmp as any)[key] } $: attribute = hierarchy.findAttribute(cast ?? value._class, key) + const change = (sel: boolean): void => { + selected = sel + onChange(key, sel) + } {#if !isEqual(value, targetEmp, key)} -
-
+
+ {#if attribute?.label}
+ -
-
- { - selected = false - onChange(key, false) - }} - /> -
- -
-
-
-
- { - selected = true - onChange(key, true) - }} - /> -
- -
+ + { + if (selected) change(false) + }} + > + + + + + + { + if (!selected) change(true) + }} + > + + +
{/if} diff --git a/plugins/workbench-resources/src/components/sidebar/Sidebar.svelte b/plugins/workbench-resources/src/components/sidebar/Sidebar.svelte index c8422d2553..b761d46c4f 100644 --- a/plugins/workbench-resources/src/components/sidebar/Sidebar.svelte +++ b/plugins/workbench-resources/src/components/sidebar/Sidebar.svelte @@ -17,7 +17,7 @@ import { WidgetPreference, SidebarEvent, TxSidebarEvent, OpenSidebarWidgetParams } from '@hcengineering/workbench' import { Tx } from '@hcengineering/core' import { onMount } from 'svelte' - import { panelstore } from '@hcengineering/ui' + import { panelstore, deviceOptionsStore as deviceInfo } from '@hcengineering/ui' import workbench from '../../plugin' import { createWidgetTab, openWidget, sidebarStore, SidebarVariant } from '../../sidebar' @@ -61,7 +61,12 @@ }) -