Fixed Planner layout and Separator (#5410)

Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com>
This commit is contained in:
Alexander Platov 2024-04-24 09:59:32 +03:00 committed by GitHub
parent d1c4e35eda
commit 128f5f55ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 133 additions and 52 deletions

View File

@ -152,6 +152,7 @@
display: flex;
align-items: center;
min-width: 0;
min-height: 0;
}
.hulyHeader-titleGroup {
flex-grow: 1;

View File

@ -36,7 +36,9 @@
</button>
{/if}
<slot name="beforeTitle" />
<div class="hulyHeader-divider" />
{#if !noResize || $$slots.beforeTitle}
<div class="hulyHeader-divider" />
{/if}
{/if}
<div class="hulyHeader-titleGroup">
<slot />

View File

@ -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<number, { size: number, element: HTMLElement }>()
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)
}

View File

@ -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
})
</script>
{#if visibleNav}
{#if isVisiblePlannerNav}
<ToDosNavigator bind:mode bind:tag bind:currentDate {navFloat} {appsDirection} />
<Separator
name={'time'}
float={navFloat}
index={0}
disabledWhen={['panel-aside']}
color={'var(--theme-navpanel-border)'}
/>
{/if}
<div class="flex-col clear-mins">
<ToDos {mode} {tag} bind:isVisiblePlannerNav bind:currentDate />
</div>
<Separator name={'time'} float={navFloat} index={1} color={'transparent'} separatorSize={0} short />
{/if}
<div class="w-full clear-mins" bind:this={replacedPanel}>
<PlanningCalendar
{dragItem}
{visibleNav}
bind:currentDate
displayedDaysCount={3}
on:dragDrop={drop}
on:change={(event) => (visibleNav = event.detail)}
<ToDosNavigator bind:mode bind:tag bind:currentDate {navFloat} {appsDirection} />
<Separator
name={'time'}
float={navFloat}
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>
{#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={3}
on:dragDrop={drop}
on:change={(event) => (visibleNav = event.detail)}
/>
</div>
{/if}

View File

@ -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
}}
>
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
<span class="heading-medium-20 overflow-label">
<Header noResize>
<div class="heading-medium-20 line-height-auto overflow-label">
<Label label={time.string.Schedule} />: <Label label={getTitle(currentDate, $ticker)} />
</span>
</div>
<svelte:fragment slot="actions">
<ButtonIcon
icon={IconChevronLeft}

View File

@ -38,7 +38,7 @@
export let mode: ToDosMode
export let tag: Ref<TagElement> | 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<TagElement> | undefined): void {
@ -279,10 +279,10 @@
<div class="toDos-container">
<Header type={'type-panel'} hideSeparator>
<ButtonIcon
icon={isVisiblePlannerNav ? MenuClose : MenuOpen}
icon={visibleNav ? MenuClose : MenuOpen}
kind={'tertiary'}
size={'small'}
pressed={!isVisiblePlannerNav}
pressed={!visibleNav}
on:click={togglePlannerNav}
/>
<div class="heading-bold-20 ml-4">

View File

@ -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 }
]
/**