mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-13 11:50:56 +00:00
Board: Extend popup positioning for Kanban card (#1483)
Signed-off-by: Anna No <anna.no@xored.com>
This commit is contained in:
parent
588dd22f95
commit
70579c2f47
@ -1,4 +1,4 @@
|
||||
import { AnySvelteComponent, AnyComponent, PopupAlignment } from './types'
|
||||
import { AnySvelteComponent, AnyComponent, PopupAlignment, PopupPositionElement } from './types'
|
||||
import { getResource } from '@anticrm/platform'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
@ -30,7 +30,7 @@ export function showPopup (
|
||||
const id = `${popupId++}`
|
||||
const closePopupOp = (): void => {
|
||||
popupstore.update((popups) => {
|
||||
const pos = popups.findIndex(p => p.id === id)
|
||||
const pos = popups.findIndex((p) => p.id === id)
|
||||
if (pos !== -1) {
|
||||
popups.splice(pos, 1)
|
||||
}
|
||||
@ -38,7 +38,9 @@ export function showPopup (
|
||||
})
|
||||
}
|
||||
if (typeof component === 'string') {
|
||||
getResource(component).then((resolved) => addPopup({ id, is: resolved, props, element, onClose, onUpdate, close: closePopupOp })).catch((err) => console.log(err))
|
||||
getResource(component)
|
||||
.then((resolved) => addPopup({ id, is: resolved, props, element, onClose, onUpdate, close: closePopupOp }))
|
||||
.catch((err) => console.log(err))
|
||||
} else {
|
||||
addPopup({ id, is: component, props, element, onClose, onUpdate, close: closePopupOp })
|
||||
}
|
||||
@ -104,6 +106,50 @@ export function closeDatePopup (): void {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
* Place element based on position and element.
|
||||
*
|
||||
* return boolean to show or not modal overlay.
|
||||
*/
|
||||
export function fitPopupPositionedElement (modalHTML: HTMLElement, alignment: PopupPositionElement): boolean {
|
||||
const rect = alignment.getBoundingClientRect()
|
||||
const rectPopup = modalHTML.getBoundingClientRect()
|
||||
modalHTML.style.left = modalHTML.style.right = modalHTML.style.top = modalHTML.style.bottom = ''
|
||||
modalHTML.style.maxHeight = modalHTML.style.height = ''
|
||||
if (alignment.position) {
|
||||
if (alignment.position.v === 'top') {
|
||||
modalHTML.style.top = `${rect.top}px`
|
||||
} else if (alignment.position.v === 'bottom') {
|
||||
modalHTML.style.top = `${rect.bottom - rectPopup.height}px`
|
||||
}
|
||||
|
||||
if (alignment.position.h === 'right') {
|
||||
modalHTML.style.left = `calc(${rect.right}px + .125rem)`
|
||||
} else if (alignment.position.h === 'left') {
|
||||
modalHTML.style.left = `calc(${rect.left - rectPopup.width}px - .125rem)`
|
||||
}
|
||||
} else {
|
||||
// Vertical
|
||||
if (rect.bottom + rectPopup.height + 28 <= document.body.clientHeight) {
|
||||
modalHTML.style.top = `calc(${rect.bottom}px + .125rem)`
|
||||
} else if (rectPopup.height + 28 < rect.top) {
|
||||
modalHTML.style.bottom = `calc(${document.body.clientHeight - rect.y}px + .125rem)`
|
||||
} else {
|
||||
modalHTML.style.top = modalHTML.style.bottom = '1rem'
|
||||
}
|
||||
|
||||
// Horizontal
|
||||
if (rect.left + rectPopup.width + 16 > document.body.clientWidth) {
|
||||
modalHTML.style.right = `${document.body.clientWidth - rect.right}px`
|
||||
} else {
|
||||
modalHTML.style.left = `${rect.left}px`
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
@ -118,24 +164,7 @@ export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignmen
|
||||
modalHTML.style.left = modalHTML.style.right = modalHTML.style.top = modalHTML.style.bottom = ''
|
||||
modalHTML.style.maxHeight = modalHTML.style.height = ''
|
||||
if (typeof element !== 'string') {
|
||||
const el = element as HTMLElement
|
||||
const rect = el.getBoundingClientRect()
|
||||
const rectPopup = modalHTML.getBoundingClientRect()
|
||||
// Vertical
|
||||
if (rect.bottom + rectPopup.height + 28 <= document.body.clientHeight) {
|
||||
modalHTML.style.top = `calc(${rect.bottom}px + .125rem)`
|
||||
} else if (rectPopup.height + 28 < rect.top) {
|
||||
modalHTML.style.bottom = `calc(${document.body.clientHeight - rect.y}px + .125rem)`
|
||||
} else {
|
||||
modalHTML.style.top = modalHTML.style.bottom = '1rem'
|
||||
}
|
||||
|
||||
// Horizontal
|
||||
if (rect.left + rectPopup.width + 16 > document.body.clientWidth) {
|
||||
modalHTML.style.right = `${document.body.clientWidth - rect.right}px`
|
||||
} else {
|
||||
modalHTML.style.left = `${rect.left}px`
|
||||
}
|
||||
return fitPopupPositionedElement(modalHTML, element)
|
||||
} else if (element === 'right' && contentPanel !== undefined) {
|
||||
const rect = contentPanel.getBoundingClientRect()
|
||||
modalHTML.style.top = `calc(${rect.top}px + 0.5rem)`
|
||||
|
@ -67,9 +67,15 @@ export type ButtonKind = 'primary' | 'secondary' | 'no-border' | 'transparent' |
|
||||
export type ButtonSize = 'small' | 'medium' | 'large' | 'x-large'
|
||||
export interface PopupPositionElement {
|
||||
getBoundingClientRect: () => DOMRect
|
||||
position?: {
|
||||
v: VerticalAlignment
|
||||
h: HorizontalAlignment
|
||||
}
|
||||
}
|
||||
export type PopupAlignment = PopupPositionElement | null | 'right' | 'top' | 'account' | 'full' | 'content' | 'middle'
|
||||
export type TooltipAlignment = 'top' | 'bottom' | 'left' | 'right'
|
||||
export type VerticalAlignment = 'top' | 'bottom'
|
||||
export type HorizontalAlignment = 'left' | 'right'
|
||||
|
||||
export interface LabelAndProps {
|
||||
label: IntlString | undefined
|
||||
|
@ -21,10 +21,11 @@
|
||||
import type { Ref, WithLookup } from '@anticrm/core'
|
||||
import notification from '@anticrm/notification'
|
||||
import { getClient, UserBoxList } from '@anticrm/presentation'
|
||||
import { Button, Component, IconEdit, IconMoreH, Label, showPanel, showPopup } from '@anticrm/ui'
|
||||
import { Button, Component, IconEdit, Label, showPanel, showPopup } from '@anticrm/ui'
|
||||
import { ContextMenu } from '@anticrm/view-resources'
|
||||
import board from '../plugin'
|
||||
import { hasDate } from '../utils/CardUtils'
|
||||
import { getElementPopupAlignment } from '../utils/PopupUtils'
|
||||
import CardLabels from './editor/CardLabels.svelte'
|
||||
import DatePresenter from './presenters/DatePresenter.svelte'
|
||||
|
||||
@ -33,11 +34,12 @@
|
||||
|
||||
let loadingAttachment = 0
|
||||
let dragoverAttachment = false
|
||||
let ref: HTMLElement
|
||||
|
||||
const client = getClient()
|
||||
|
||||
function showMenu (ev?: Event): void {
|
||||
showPopup(ContextMenu, { object }, (ev as MouseEvent).target as HTMLElement)
|
||||
function showMenu (): void {
|
||||
showPopup(ContextMenu, { object }, getElementPopupAlignment(ref, { h: 'right', v: 'top' }))
|
||||
}
|
||||
|
||||
function showCard () {
|
||||
@ -65,7 +67,7 @@
|
||||
objectId={object._id}
|
||||
space={object.space}
|
||||
canDrop={canDropAttachment}>
|
||||
<div class="relative flex-col pt-2 pb-1 pr-2 pl-2">
|
||||
<div class="relative flex-col pt-2 pb-1 pr-2 pl-2" bind:this={ref}>
|
||||
{#if dragoverAttachment}
|
||||
<div style:pointer-events="none" class="abs-full-content h-full w-full flex-center fs-title">
|
||||
<Label label={board.string.DropFileToUpload} />
|
||||
|
@ -116,7 +116,7 @@
|
||||
{space}
|
||||
{search}
|
||||
{options}
|
||||
query={{ doneState: null, isArchived: {$nin: [true]} }}
|
||||
query={{ doneState: null, isArchived: { $nin: [true] } }}
|
||||
{states}
|
||||
fieldName={'state'}
|
||||
rankFieldName={'rank'}
|
||||
|
@ -1,14 +1,20 @@
|
||||
import { PopupAlignment } from '@anticrm/ui'
|
||||
import { HorizontalAlignment, VerticalAlignment } from '@anticrm/ui/src/types'
|
||||
|
||||
export function getPopupAlignment (e?: Event): PopupAlignment | undefined {
|
||||
export function getPopupAlignment (e?: Event, position?: {v: VerticalAlignment, h: HorizontalAlignment}): PopupAlignment | undefined {
|
||||
if (!e || !e.target) {
|
||||
return undefined
|
||||
}
|
||||
const target = e.target as HTMLElement
|
||||
if (target.getBoundingClientRect) {
|
||||
const result = target.getBoundingClientRect()
|
||||
return getElementPopupAlignment(target, position)
|
||||
}
|
||||
|
||||
export function getElementPopupAlignment (el: HTMLElement, position?: {v: VerticalAlignment, h: HorizontalAlignment}): PopupAlignment | undefined {
|
||||
if (el?.getBoundingClientRect) {
|
||||
const result = el.getBoundingClientRect()
|
||||
return {
|
||||
getBoundingClientRect: () => result
|
||||
getBoundingClientRect: () => result,
|
||||
position
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user