From 128f5f55ff353494dad281ad4508d3eb53f21a7f Mon Sep 17 00:00:00 2001 From: Alexander Platov Date: Wed, 24 Apr 2024 09:59:32 +0300 Subject: [PATCH] Fixed Planner layout and Separator (#5410) Signed-off-by: Alexander Platov --- packages/theme/styles/components.scss | 1 + packages/ui/src/components/Header.svelte | 4 +- packages/ui/src/components/Separator.svelte | 111 +++++++++++++++--- .../src/components/PlanView.svelte | 50 ++++---- .../src/components/PlanningCalendar.svelte | 7 +- .../src/components/ToDos.svelte | 8 +- plugins/time-resources/src/utils.ts | 4 +- 7 files changed, 133 insertions(+), 52 deletions(-) diff --git a/packages/theme/styles/components.scss b/packages/theme/styles/components.scss index f6e7135397..2ddc75130e 100644 --- a/packages/theme/styles/components.scss +++ b/packages/theme/styles/components.scss @@ -152,6 +152,7 @@ display: flex; align-items: center; min-width: 0; + min-height: 0; } .hulyHeader-titleGroup { flex-grow: 1; diff --git a/packages/ui/src/components/Header.svelte b/packages/ui/src/components/Header.svelte index bd64f533e6..dd3934b714 100644 --- a/packages/ui/src/components/Header.svelte +++ b/packages/ui/src/components/Header.svelte @@ -36,7 +36,9 @@ {/if} -
+ {#if !noResize || $$slots.beforeTitle} +
+ {/if} {/if}
diff --git a/packages/ui/src/components/Separator.svelte b/packages/ui/src/components/Separator.svelte index 59131a6298..8b090774ef 100644 --- a/packages/ui/src/components/Separator.svelte +++ b/packages/ui/src/components/Separator.svelte @@ -54,7 +54,7 @@ let correctedIndex: number = index let offset: number = 0 let separatorsSizes: number[] | null = null - const separatorsWide: { start: number, end: number, total: number } = { start: 0, end: 0, total: 0 } + const separatorsWide: { before: number, after: number, total: number } = { before: 0, after: 0, total: 0 } const containers: { minStart: number, minEnd: number, maxStart: number, maxEnd: number } = { minStart: -1, minEnd: -1, @@ -105,7 +105,8 @@ element.style.maxHeight = s element.style.height = s } - const sizePx = direction === 'horizontal' ? element.clientWidth : element.clientHeight + const rect = element.getBoundingClientRect() + const sizePx = direction === 'horizontal' ? rect.width : rect.height element.setAttribute('data-size', `${sizePx}`) if (sState === SeparatorState.NORMAL) { if (separators) separators[index + (next ? 1 : 0)].size = pxToRem(sizePx) @@ -146,7 +147,8 @@ .forEach((st) => styles.set(st.split(':')[0], st.split(':')[1])) dropStyles.forEach((key) => styles.delete(key)) } - const size = direction === 'horizontal' ? elements[i].clientWidth : elements[i].clientHeight + const rect = element.getBoundingClientRect() + const size = direction === 'horizontal' ? rect.width : rect.height if (separators) { sm.push({ id: ind, @@ -190,16 +192,17 @@ setSize(element, remToPx(props.size), next) return } + const rect = element.getBoundingClientRect() if (direction === 'horizontal') { element.style.minWidth = minSizePx element.style.maxWidth = maxSizePx element.style.width = sizePx - element.setAttribute('data-auto', `${element.clientWidth}`) + element.setAttribute('data-auto', `${rect.width}`) } else { element.style.minHeight = minSizePx element.style.maxHeight = maxSizePx element.style.height = sizePx - element.setAttribute('data-auto', `${element.clientHeight}`) + element.setAttribute('data-auto', `${rect.height}`) } } @@ -233,6 +236,13 @@ } if (isSeparate) style += 'pointer-events:none;' item.element.setAttribute('style', style) + if (final) { + const rect = item.element.getBoundingClientRect() + item.element.setAttribute( + item.maxSize === -1 ? 'data-auto' : 'data-size', + `${direction === 'horizontal' ? rect.width : rect.height}` + ) + } item.resize = false } }) @@ -306,15 +316,19 @@ .filter((f) => f.begin) .map((m) => m.size) .reduce((prev, a) => prev + a, 0) - for (let i = 0; i < correctedIndex; i++) prevCoord += separatorsSizes[i] - const startSizeMin = containers.minStart + separatorsWide.start - const startSizeMax = containers.maxStart === -1 ? -1 : containers.maxStart + separatorsWide.start + prevCoord += separatorsWide.before + const startSizeMin = containers.minStart + separatorsWide.before + const startSizeMax = containers.maxStart === -1 ? -1 : containers.maxStart + separatorsWide.before if (parentCoord <= startSizeMin) parentCoord = startSizeMin + 1 if (startSizeMax !== -1 && parentCoord > startSizeMax) parentCoord = startSizeMax - const endSizeMin = containers.minEnd + separatorsWide.end - const endSizeMax = containers.maxEnd === -1 ? -1 : containers.maxEnd + separatorsWide.end - if (parentCoord > parentSize.size - endSizeMin) parentCoord = parentSize.size - endSizeMin - 1 - if (endSizeMax !== -1 && parentCoord < parentSize.size - endSizeMax) parentCoord = parentSize.size - endSizeMax - 1 + const endSizeMin = containers.minEnd + separatorsWide.after + const endSizeMax = containers.maxEnd === -1 ? -1 : containers.maxEnd + separatorsWide.after + if (parentCoord > parentSize.size - endSizeMin - separatorSize) { + parentCoord = parentSize.size - endSizeMin - separatorSize + } + if (endSizeMax !== -1 && parentCoord < parentSize.size - endSizeMax - separatorSize) { + parentCoord = parentSize.size - endSizeMax - separatorSize + } const diff = prevCoord - parentCoord // + <- - -> let remains = diff if (remains !== 0) { @@ -427,6 +441,7 @@ ? { start: p.left, end: p.right, size: p.width } : { start: p.top, end: p.bottom, size: p.height } if (sState === SeparatorState.NORMAL) { + calculateSeparators() generateMap() applyStyles(true) } else if (sState === SeparatorState.FLOAT) preparePanel() @@ -462,11 +477,75 @@ .filter((el) => el.classList.contains('antiSeparator')) .map((el) => parseInt(el.getAttribute('data-size') ?? '0', 10)) separatorsWide.total = separatorsSizes.reduce((prev, a) => prev + a, 0) - separatorsWide.start = separatorsSizes.slice(0, index).reduce((prev, a) => prev + a, 0) - separatorsWide.end = separatorsSizes.slice(index + 1, separatorsSizes.length).reduce((prev, a) => prev + a, 0) + separatorsWide.before = separatorsSizes.slice(0, index).reduce((prev, a) => prev + a, 0) + separatorsWide.after = separatorsSizes.slice(index + 1, separatorsSizes.length).reduce((prev, a) => prev + a, 0) } } + let checkElements: boolean = false + const resizeDocument = (): void => { + if (parentElement == null || checkElements || sState !== SeparatorState.NORMAL) return + checkElements = true + setTimeout(() => { + if (parentElement != null && separators) { + const children: Element[] = Array.from(parentElement.children) + let totalSize: number = 0 + let ind: number = 0 + const rects = new Map() + const hasSep: string[] = [] + children.forEach((ch) => { + const rect = ch.getBoundingClientRect() + if ( + !ch.classList.contains('antiSeparator') && + (ch.hasAttribute('data-size') || ch.hasAttribute('data-auto')) + ) { + rects.set(ind++, { + size: direction === 'horizontal' ? rect.width : rect.height, + element: ch as HTMLElement + }) + } + if (ch.hasAttribute('data-float')) hasSep.push(ch.getAttribute('data-float') ?? '') + totalSize += direction === 'horizontal' ? rect.width : rect.height + }) + const parentRect = parentElement.getBoundingClientRect() + let diff = totalSize - (direction === 'horizontal' ? parentRect.width : parentRect.height) + if (diff > 0) { + const excluded = separators + .filter((separ) => separ.float !== undefined && !hasSep.includes(separ.float)) + .map((separ) => separ.float) + const reverseSep = [...separators].reverse() + let ind: number = 0 + reverseSep.forEach((separ, i) => { + const pass = excluded.includes(separ.float) + if (diff > 0 && !pass && separators) { + const box = rects.get(reverseSep.length - ind - 1) + if (box) { + const minSize: number = remToPx(separ.minSize === 'auto' ? 20 : separ.minSize) + const forCrop = box.size - minSize + if (forCrop > 0) { + const newSize = forCrop - diff < 0 ? minSize : box.size - diff + diff -= forCrop + if (direction === 'horizontal') { + box.element.style.width = `${newSize}px` + box.element.style.minWidth = `${newSize}px` + box.element.style.maxWidth = `${newSize}px` + } else { + box.element.style.height = `${newSize}px` + box.element.style.minHeight = `${newSize}px` + box.element.style.maxHeight = `${newSize}px` + } + separators[separators.length - i - 1].size = newSize + } + } + ind++ + } + }) + } + } + checkElements = false + }, 100) + } + onMount(() => { if (separator) { parentElement = separator.parentElement as HTMLElement @@ -478,13 +557,13 @@ checkSizes() mounted = true } - document.addEventListener('resize', checkSizes) + window.addEventListener('resize', resizeDocument) if (sState !== SeparatorState.FLOAT && $separatorsStore.filter((f) => f === name).length === 0) { $separatorsStore = [...$separatorsStore, name] } }) onDestroy(() => { - document.removeEventListener('resize', checkSizes) + window.removeEventListener('resize', resizeDocument) if (sState !== SeparatorState.FLOAT && $separatorsStore.filter((f) => f === name).length > 0) { $separatorsStore = $separatorsStore.filter((f) => f !== name) } diff --git a/plugins/time-resources/src/components/PlanView.svelte b/plugins/time-resources/src/components/PlanView.svelte index 1bc360a8a8..18cba95f20 100644 --- a/plugins/time-resources/src/components/PlanView.svelte +++ b/plugins/time-resources/src/components/PlanView.svelte @@ -36,12 +36,13 @@ const dispatch = createEventDispatcher() const defaultDuration = 30 * 60 * 1000 + let mainPanel: HTMLElement let replacedPanel: HTMLElement - let isVisiblePlannerNav: boolean = true let currentDate: Date = new Date() $: dragItem = $dragging.item + $: visibleCalendar = $deviceInfo.docWidth > 800 const client = getClient() @@ -78,33 +79,32 @@ dispatch('change', true) afterUpdate(() => { - $deviceInfo.replacedPanel = replacedPanel + $deviceInfo.replacedPanel = replacedPanel ?? mainPanel }) {#if visibleNav} - {#if isVisiblePlannerNav} - - - {/if} -
- -
- -{/if} -
- (visibleNav = event.detail)} + + +{/if} +
+
+{#if visibleCalendar} + +
+ (visibleNav = event.detail)} + /> +
+{/if} diff --git a/plugins/time-resources/src/components/PlanningCalendar.svelte b/plugins/time-resources/src/components/PlanningCalendar.svelte index 2e3feb98b7..20bd21f1ae 100644 --- a/plugins/time-resources/src/components/PlanningCalendar.svelte +++ b/plugins/time-resources/src/components/PlanningCalendar.svelte @@ -29,7 +29,6 @@ export let currentDate: Date = new Date() export let displayedDaysCount = 1 export let createComponent: AnyComponent | undefined = calendar.component.CreateEvent - export let visibleNav: boolean = true const dispatch = createEventDispatcher() const q = createQuery() @@ -174,10 +173,10 @@ showLabel = showLabel ? element.clientWidth > rem(3.5) + 399 : element.clientWidth > rem(3.5) + 400 }} > -
dispatch('change', event.detail)}> - +
+
| undefined export let currentDate: Date - export let isVisiblePlannerNav: boolean = true + export let visibleNav: boolean = true const acc = getCurrentAccount() as PersonAccount const user = acc.person @@ -59,7 +59,7 @@ $: updateTags(mode, tag) function togglePlannerNav (): void { - isVisiblePlannerNav = !isVisiblePlannerNav + visibleNav = !visibleNav } function updateTags (mode: ToDosMode, tag: Ref | undefined): void { @@ -279,10 +279,10 @@
diff --git a/plugins/time-resources/src/utils.ts b/plugins/time-resources/src/utils.ts index 499e80ae22..489e4386c0 100644 --- a/plugins/time-resources/src/utils.ts +++ b/plugins/time-resources/src/utils.ts @@ -23,8 +23,8 @@ export function getNearest (events: WorkSlot[]): WorkSlot | undefined { */ export const timeSeparators: DefSeparators = [ { minSize: 18, size: 18, maxSize: 22.5, float: 'navigator' }, - { minSize: 15, size: 35, maxSize: 45, float: 'planner' }, - null + null, + { minSize: 20, size: 41.25, maxSize: 50 } ] /**