mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03:00
Fixed Planner layout and Separator (#5410)
Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com>
This commit is contained in:
parent
d1c4e35eda
commit
128f5f55ff
@ -152,6 +152,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
.hulyHeader-titleGroup {
|
||||
flex-grow: 1;
|
||||
|
@ -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 />
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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">
|
||||
|
@ -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 }
|
||||
]
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user