Fix UI. Update Scroller. (#2270)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2022-09-16 05:59:16 +03:00 committed by GitHub
parent 13b6459c95
commit 719da02f7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 157 additions and 78 deletions

View File

@ -15,6 +15,7 @@
<script lang="ts"> <script lang="ts">
import { setContext, onMount } from 'svelte' import { setContext, onMount } from 'svelte'
import platform, { loadPluginStrings, setMetadata } from '@anticrm/platform' import platform, { loadPluginStrings, setMetadata } from '@anticrm/platform'
import { themeStore as themeOptions } from './'
const getCurrentTheme = (): string => localStorage.getItem('theme') ?? 'theme-dark' const getCurrentTheme = (): string => localStorage.getItem('theme') ?? 'theme-dark'
const getCurrnetFontSize = (): string => localStorage.getItem('fontsize') ?? 'normal-font' const getCurrnetFontSize = (): string => localStorage.getItem('fontsize') ?? 'normal-font'
@ -28,6 +29,9 @@
} }
const setRootFontSize = (fontsize: string) => { const setRootFontSize = (fontsize: string) => {
document.documentElement.setAttribute('class', `${getCurrentTheme()} ${fontsize}`) document.documentElement.setAttribute('class', `${getCurrentTheme()} ${fontsize}`)
themeOptions.update((opt) => {
return { ...opt, fontSize: fontsize === 'normal-font' ? 16 : 14 }
})
} }
setContext('theme', { setContext('theme', {

View File

@ -14,5 +14,11 @@
// //
import '@anticrm/platform-rig/profiles/ui/svelte' import '@anticrm/platform-rig/profiles/ui/svelte'
import { writable } from 'svelte/store'
export { default as Theme } from './Theme.svelte' export { default as Theme } from './Theme.svelte'
export interface ThemeOptions {
fontSize: number
}
export const themeStore = writable<ThemeOptions>()

View File

@ -202,14 +202,6 @@
flex-shrink: 0; flex-shrink: 0;
height: 1rem; height: 1rem;
} }
.antiNav-topFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 2rem, rgba(0, 0, 0, 1) calc(100% - 1px), rgba(0, 0, 0, 0) 100%); }
.antiNav-bottomFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - 2rem), rgba(0, 0, 0, 0) 100%); }
.antiNav-bothFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 2rem, rgba(0, 0, 0, 1) calc(100% - 2rem), rgba(0, 0, 0, 0) 100%); }
.antiNav-noneFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - 1px), rgba(0, 0, 0, 0) 100%); }
.tableFade.antiNav-topFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 2rem, rgba(0, 0, 0, 1) calc(100% - 1px), rgba(0, 0, 0, 0) 100%); }
.tableFade.antiNav-bottomFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - var(--scroller-header-height, 2.5rem) - 2rem - 1px), rgba(0, 0, 0, 0) calc(100% - var(--scroller-header-height, 2.5rem)), rgba(0, 0, 0, 1) calc(100% - var(--scroller-header-height, 2.5rem) + .5px)); }
.tableFade.antiNav-bothFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 2rem, rgba(0, 0, 0, 1) calc(100% - var(--scroller-header-height, 2.5rem) - 2rem - 1px), rgba(0, 0, 0, 0) calc(100% - var(--scroller-header-height, 2.5rem)), rgba(0, 0, 0, 1) calc(100% - var(--scroller-header-height, 2.5rem) + .5px)); }
.tableFade.antiNav-noneFade { mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 1) 1px, rgba(0, 0, 0, 1) calc(100% - 1px), rgba(0, 0, 0, 0) 100%); }
/* Basic */ /* Basic */
.antiTitle { .antiTitle {

View File

@ -81,7 +81,6 @@
function showActionPopup (action: Action, target: HTMLElement): void { function showActionPopup (action: Action, target: HTMLElement): void {
closePopup(category) closePopup(category)
if (action.component !== undefined) { if (action.component !== undefined) {
console.log(action.props)
showPopup( showPopup(
action.component, action.component,
action.props, action.props,

View File

@ -146,7 +146,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
max-height: calc(100vh - 2rem); max-height: calc(100vh - 32px);
background-color: transparent; background-color: transparent;
&.anim { &.anim {

View File

@ -15,13 +15,17 @@
<script lang="ts"> <script lang="ts">
import { onDestroy, onMount } from 'svelte' import { onDestroy, onMount } from 'svelte'
import { resizeObserver } from '../resize' import { resizeObserver } from '../resize'
import { themeStore as themeOptions } from '@anticrm/theme'
import type { FadeOptions } from '../types'
import { defaultSP } from '../types'
export let padding: string | undefined = undefined export let padding: string | undefined = undefined
export let autoscroll: boolean = false export let autoscroll: boolean = false
// export let correctPadding: number = 0 // export let correctPadding: number = 0
export let bottomStart: boolean = false export let bottomStart: boolean = false
export let tableFade: boolean = false export let fade: FadeOptions = defaultSP
export let fadeTopOffset: number = 40 // export let verticalFade: boolean = false
export let invertScroll: boolean = false
let mask: 'top' | 'bottom' | 'both' | 'none' = 'none' let mask: 'top' | 'bottom' | 'both' | 'none' = 'none'
@ -38,15 +42,16 @@
let timer: number let timer: number
$: shift = tableFade ? fadeTopOffset : 0 $: shiftTop = fade.offset?.top ? (fade.multipler?.top ?? 0) * $themeOptions.fontSize : 0
$: shiftBottom = fade.offset?.bottom ? fade.multipler?.bottom! * $themeOptions.fontSize : 0
const checkBar = (): void => { const checkBar = (): void => {
if (divBar && divScroll) { if (divBar && divScroll) {
const trackH = divScroll.clientHeight - shift - 4 const trackH = divScroll.clientHeight - shiftTop - shiftBottom - 4
const scrollH = divScroll.scrollHeight const scrollH = divScroll.scrollHeight
const proc = scrollH / trackH const proc = scrollH / trackH
divBar.style.height = divScroll.clientHeight / proc + 'px' divBar.style.height = divScroll.clientHeight / proc + 'px'
divBar.style.top = divScroll.scrollTop / proc + shift + 2 + 'px' divBar.style.top = divScroll.scrollTop / proc + shiftTop + shiftBottom + 2 + 'px'
if (mask === 'none') divBar.style.visibility = 'hidden' if (mask === 'none') divBar.style.visibility = 'hidden'
else { else {
divBar.style.visibility = 'visible' divBar.style.visibility = 'visible'
@ -57,7 +62,7 @@
} }
timer = setTimeout(() => { timer = setTimeout(() => {
if (divBar) divBar.style.opacity = '0' if (divBar) divBar.style.opacity = '0'
}, 2000) }, 1500)
} }
} }
if (divScroll.clientHeight >= divScroll.scrollHeight) divBar.style.visibility = 'hidden' if (divScroll.clientHeight >= divScroll.scrollHeight) divBar.style.visibility = 'hidden'
@ -69,11 +74,13 @@
if (isScrolling && divBar && divScroll) { if (isScrolling && divBar && divScroll) {
const rectScroll = divScroll.getBoundingClientRect() const rectScroll = divScroll.getBoundingClientRect()
let Y = event.clientY - dY let Y = event.clientY - dY
if (Y < rectScroll.top + shift + 2) Y = rectScroll.top + shift + 2 if (Y < rectScroll.top + shiftTop + 2) Y = rectScroll.top + shiftTop + 2
if (Y > rectScroll.bottom - divBar.clientHeight - 2) Y = rectScroll.bottom - divBar.clientHeight - 2 if (Y > rectScroll.bottom - divBar.clientHeight - shiftBottom - 2) {
Y = rectScroll.bottom - divBar.clientHeight - shiftBottom - 2
}
divBar.style.top = Y - rectScroll.y + 'px' divBar.style.top = Y - rectScroll.y + 'px'
const topBar = Y - rectScroll.y - shift - 2 const topBar = Y - rectScroll.y - shiftTop - 2
const heightScroll = rectScroll.height - 4 - divBar.clientHeight - shift const heightScroll = rectScroll.height - 4 - divBar.clientHeight - shiftTop - shiftBottom
const procBar = topBar / heightScroll const procBar = topBar / heightScroll
divScroll.scrollTop = (divScroll.scrollHeight - divScroll.clientHeight) * procBar divScroll.scrollTop = (divScroll.scrollHeight - divScroll.clientHeight) * procBar
} }
@ -146,21 +153,28 @@
let boxHeight: number let boxHeight: number
$: if (boxHeight) checkFade() $: if (boxHeight) checkFade()
$: scrollerVars = `
--scroller-header-height: ${
(fade.multipler && fade.multipler.top ? fade.multipler.top : 0) * $themeOptions.fontSize
}px;
--scroller-footer-height: ${
(fade.multipler && fade.multipler.bottom ? fade.multipler.bottom : 0) * $themeOptions.fontSize
}px;
--scroller-header-fade: ${mask === 'none' || mask === 'top' ? '0px' : '2rem'};
--scroller-footer-fade: ${mask === 'none' || mask === 'bottom' ? '0px' : '2rem'};
`
</script> </script>
<svelte:window on:resize={_resize} /> <svelte:window on:resize={_resize} />
<div class="scroller-container" class:bottomStart style="--scroller-header-height: {shift}px;">
<div class="scroller-container {invertScroll ? 'invert' : 'normal'}" class:bottomStart style={scrollerVars}>
<div <div
bind:this={divScroll} bind:this={divScroll}
use:resizeObserver={(element) => { use:resizeObserver={(element) => {
divHeight = element.clientHeight divHeight = element.clientHeight
}} }}
class="scroll relative" class="scroll relative verticalFade"
class:tableFade
class:antiNav-topFade={mask === 'top'}
class:antiNav-bottomFade={mask === 'bottom'}
class:antiNav-bothFade={mask === 'both'}
class:antiNav-noneFade={mask === 'none'}
> >
<div <div
bind:this={divBox} bind:this={divBox}
@ -182,7 +196,13 @@
on:mousedown={onScrollStart} on:mousedown={onScrollStart}
on:mouseleave={checkFade} on:mouseleave={checkFade}
/> />
<div class="track" class:hovered={isScrolling} class:tableFade bind:this={divTrack} /> <div
class="track"
class:hovered={isScrolling}
class:fadeTopOffset={fade.offset?.top}
class:fadeBottomOffset={fade.offset?.bottom}
bind:this={divTrack}
/>
</div> </div>
<style lang="scss"> <style lang="scss">
@ -193,6 +213,15 @@
height: 100%; height: 100%;
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
&.normal .track,
&.normal .bar {
right: 2px;
}
&.invert .track,
&.invert .bar {
left: 2px;
}
} }
.scroll { .scroll {
flex-grow: 1; flex-grow: 1;
@ -204,6 +233,17 @@
&::-webkit-scrollbar:vertical { &::-webkit-scrollbar:vertical {
width: 0; width: 0;
} }
&.verticalFade {
mask-image: linear-gradient(
0deg,
rgba(0, 0, 0, 1) calc(var(--scroller-footer-height, 2.5rem)),
rgba(0, 0, 0, 0) calc(var(--scroller-footer-height, 2.5rem)),
rgba(0, 0, 0, 1) calc(var(--scroller-footer-height, 2.5rem) + var(--scroller-footer-fade, 0) + 1px),
rgba(0, 0, 0, 1) calc(100% - var(--scroller-header-height, 0) - var(--scroller-header-fade, 0) - 1px),
rgba(0, 0, 0, 0) calc(100% - var(--scroller-header-height, 0)),
rgba(0, 0, 0, 1) calc(100% - var(--scroller-header-height, 0))
);
}
} }
.box { .box {
display: flex; display: flex;
@ -227,7 +267,6 @@
position: absolute; position: absolute;
top: 2px; top: 2px;
bottom: 2px; bottom: 2px;
right: 2px;
width: 8px; width: 8px;
transform-origin: center; transform-origin: center;
transform: scaleX(0); transform: scaleX(0);
@ -235,8 +274,11 @@
background-color: var(--scrollbar-track-color); background-color: var(--scrollbar-track-color);
border-radius: 0.5rem; border-radius: 0.5rem;
&.tableFade { &.fadeTopOffset {
top: 42px; top: var(--scroller-header-height);
}
&.fadeBottomOffset {
top: var(--scroller-footer-height);
} }
} }
.bar { .bar {
@ -267,7 +309,6 @@
& + .track { & + .track {
visibility: visible; visibility: visible;
right: 2px;
transform: scaleX(1); transform: scaleX(1);
} }
} }

View File

@ -156,17 +156,18 @@ export function fitPopupPositionedElement (
newProps.maxWidth = newProps.width = '' newProps.maxWidth = newProps.width = ''
if (alignment?.kind === 'submenu') { if (alignment?.kind === 'submenu') {
const dirH = const dirH =
docWidth - rect.right - rectPopup.width - 16 > 0 ? 'right' : rect.left > docWidth - rect.right ? 'left' : 'right' docWidth - rect.right - rectPopup.width - 12 > 0 ? 'right' : rect.left > docWidth - rect.left ? 'left' : 'right'
const dirV = const dirV =
docHeight - rect.top - rectPopup.height - 16 > 0 docHeight - rect.top - rectPopup.height - 20 > 0
? 'bottom' ? 'bottom'
: rect.bottom > docHeight - rect.top : rect.bottom > rectPopup.height + 20
? 'top' ? 'top'
: 'bottom' : 'bottom'
if (dirH === 'right') newProps.left = `${rect.right - 4}px` if (dirH === 'right') newProps.left = `${rect.right - 4}px`
else newProps.right = `${docWidth - rect.left - 4}px` else newProps.right = `${docWidth - rect.left - 4}px`
if (dirV === 'bottom') newProps.top = `${rect.top - 4}px` if (dirV === 'bottom') newProps.top = `${rect.top - 4}px`
else newProps.bottom = `${docHeight - rect.bottom - 4}px` else newProps.bottom = `${docHeight - rect.bottom - 4}px`
direction = `${dirV}|${dirH}`
} else if (alignment.position !== undefined) { } else if (alignment.position !== undefined) {
if (alignment.position.v === 'top') { if (alignment.position.v === 'top') {
newProps.top = `${rect.top}px` newProps.top = `${rect.top}px`
@ -175,9 +176,9 @@ export function fitPopupPositionedElement (
} }
if (alignment.position.h === 'right') { if (alignment.position.h === 'right') {
newProps.left = `calc(${rect.right}px + .125rem)` newProps.left = `${rect.right + 4}px`
} else if (alignment.position.h === 'left') { } else if (alignment.position.h === 'left') {
newProps.left = `calc(${rect.left - rectPopup.width}px - .125rem)` newProps.left = `${rect.left - rectPopup.width - 4}px`
} }
direction = alignment.position.v + '|' + alignment.position.h direction = alignment.position.v + '|' + alignment.position.h
} else { } else {
@ -189,7 +190,7 @@ export function fitPopupPositionedElement (
newProps.bottom = `${document.body.clientHeight - rect.top + 1}px` newProps.bottom = `${document.body.clientHeight - rect.top + 1}px`
direction = 'top' direction = 'top'
} else { } else {
newProps.top = modalHTML.style.bottom = '1rem' newProps.top = modalHTML.style.bottom = '16px'
direction = 'top' direction = 'top'
} }
@ -201,7 +202,7 @@ export function fitPopupPositionedElement (
newProps.right = `${docWidth - rect.right}px` newProps.right = `${docWidth - rect.right}px`
direction += '|left' direction += '|left'
} else { } else {
newProps.left = '1rem' newProps.left = '16px'
direction += '|center' direction += '|center'
} }
} }
@ -233,7 +234,7 @@ export function fitPopupElement (
return result return result
} else if (element === 'right' && contentPanel !== undefined) { } else if (element === 'right' && contentPanel !== undefined) {
const rect = contentPanel.getBoundingClientRect() const rect = contentPanel.getBoundingClientRect()
newProps.top = `calc(${rect.top}px + 0.5rem)` newProps.top = `calc(${rect.top}px + 8px)`
newProps.bottom = '0.75rem' newProps.bottom = '0.75rem'
newProps.right = '0.75rem' newProps.right = '0.75rem'
newProps.maxWidth = '50%' newProps.maxWidth = '50%'
@ -244,10 +245,10 @@ export function fitPopupElement (
newProps.transform = 'translateX(-50%)' newProps.transform = 'translateX(-50%)'
show = true show = true
} else if (element === 'float') { } else if (element === 'float') {
newProps.top = 'calc(var(--status-bar-height) + .25rem)' newProps.top = 'calc(var(--status-bar-height) + 4px)'
newProps.bottom = '.25rem' newProps.bottom = '4px'
newProps.left = '60%' newProps.left = '60%'
newProps.right = '.25rem' newProps.right = '4px'
show = true show = true
} else if (element === 'account') { } else if (element === 'account') {
newProps.bottom = '2.75rem' newProps.bottom = '2.75rem'
@ -263,9 +264,9 @@ export function fitPopupElement (
} else if (element === 'full' && contentPanel !== undefined) { } else if (element === 'full' && contentPanel !== undefined) {
const rect = contentPanel.getBoundingClientRect() const rect = contentPanel.getBoundingClientRect()
newProps.top = `${rect.top + 1}px` newProps.top = `${rect.top + 1}px`
newProps.bottom = '.25rem' newProps.bottom = '4px'
newProps.left = '.25rem' newProps.left = '4px'
newProps.right = '.25rem' newProps.right = '4px'
show = true show = true
} else if (element === 'content' && contentPanel !== undefined) { } else if (element === 'content' && contentPanel !== undefined) {
const rect = contentPanel.getBoundingClientRect() const rect = contentPanel.getBoundingClientRect()
@ -282,7 +283,7 @@ export function fitPopupElement (
} else { } else {
newProps.top = '15%' newProps.top = '15%'
} }
newProps.bottom = '0.75rem' newProps.bottom = '12px'
newProps.left = '50%' newProps.left = '50%'
newProps.transform = 'translateX(-50%)' newProps.transform = 'translateX(-50%)'
} }

View File

@ -200,3 +200,17 @@ export interface DashboardGroup {
value: number value: number
color: number color: number
} }
interface Sides<T> {
top?: T
bottom?: T
left?: T
right?: T
}
export interface FadeOptions {
offset?: Sides<boolean>
multipler?: Sides<number>
}
export const defaultSP: FadeOptions = { multipler: { top: 0, bottom: 0 } }
export const tableSP: FadeOptions = { offset: { top: true }, multipler: { top: 2.5, bottom: 0 } }
export const issueSP: FadeOptions = { offset: { top: true }, multipler: { top: 3, bottom: 0 } }

View File

@ -325,11 +325,12 @@
.comment, .comment,
.mention { .mention {
position: relative; position: relative;
margin-top: 0.25rem;
&::after { &::after {
content: ''; content: '';
position: absolute; position: absolute;
bottom: -0.5rem; bottom: -0.75rem;
left: -0.625rem; left: -0.625rem;
right: -0.625rem; right: -0.625rem;
background-color: var(--accent-bg-color); background-color: var(--accent-bg-color);
@ -339,10 +340,10 @@
} }
} }
.comment::after { .comment::after {
top: -0.25rem; top: -0.375rem;
} }
.mention::after { .mention::after {
top: -0.625rem; top: -0.5rem;
} }
.msgactivity-container { .msgactivity-container {
@ -351,7 +352,7 @@
} }
.isNew { .isNew {
padding-bottom: 0.25rem; padding-bottom: 0.5rem;
border-bottom: 1px solid var(--highlight-red); border-bottom: 1px solid var(--highlight-red);
} }

View File

@ -17,7 +17,7 @@
import type { Request, RequestType, Staff } from '@anticrm/hr' import type { Request, RequestType, Staff } from '@anticrm/hr'
import { getEmbeddedLabel } from '@anticrm/platform' import { getEmbeddedLabel } from '@anticrm/platform'
import { createQuery, getClient } from '@anticrm/presentation' import { createQuery, getClient } from '@anticrm/presentation'
import { Button, Label, Loading, Scroller } from '@anticrm/ui' import { Button, Label, Loading, Scroller, tableSP } from '@anticrm/ui'
import view, { BuildModelKey, Viewlet, ViewletPreference } from '@anticrm/view' import view, { BuildModelKey, Viewlet, ViewletPreference } from '@anticrm/view'
import { Table, ViewletSettingButton } from '@anticrm/view-resources' import { Table, ViewletSettingButton } from '@anticrm/view-resources'
import hr from '../../plugin' import hr from '../../plugin'
@ -196,7 +196,7 @@
</script> </script>
{#if departmentStaff.length} {#if departmentStaff.length}
<Scroller tableFade> <Scroller fade={tableSP}>
<div class="p-2"> <div class="p-2">
{#if descr} {#if descr}
{#if loading} {#if loading}

View File

@ -28,6 +28,7 @@
Label, Label,
LabelAndProps, LabelAndProps,
Scroller, Scroller,
tableSP,
showPopup, showPopup,
tooltip tooltip
} from '@anticrm/ui' } from '@anticrm/ui'
@ -103,7 +104,7 @@
</script> </script>
{#if departmentStaff.length} {#if departmentStaff.length}
<Scroller tableFade> <Scroller fade={tableSP}>
<table> <table>
<thead class="scroller-thead"> <thead class="scroller-thead">
<tr class="scroller-thead__tr"> <tr class="scroller-thead__tr">

View File

@ -17,7 +17,7 @@
import contact from '@anticrm/contact-resources/src/plugin' import contact from '@anticrm/contact-resources/src/plugin'
import { Ref } from '@anticrm/core' import { Ref } from '@anticrm/core'
import type { Request, RequestType, Staff } from '@anticrm/hr' import type { Request, RequestType, Staff } from '@anticrm/hr'
import { Label, LabelAndProps, Scroller, tooltip } from '@anticrm/ui' import { Label, LabelAndProps, Scroller, tableSP, tooltip } from '@anticrm/ui'
import hr from '../../plugin' import hr from '../../plugin'
import { fromTzDate, getMonth, getTotal, weekDays } from '../../utils' import { fromTzDate, getMonth, getTotal, weekDays } from '../../utils'
import RequestsPopup from '../RequestsPopup.svelte' import RequestsPopup from '../RequestsPopup.svelte'
@ -67,7 +67,7 @@
</script> </script>
{#if departmentStaff.length} {#if departmentStaff.length}
<Scroller tableFade> <Scroller fade={tableSP}>
<table> <table>
<thead class="scroller-thead"> <thead class="scroller-thead">
<tr class="scroller-thead__tr"> <tr class="scroller-thead__tr">

View File

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher, afterUpdate } from 'svelte'
import { Class, Doc, Ref, RelatedDocument } from '@anticrm/core' import { Class, Doc, Ref, RelatedDocument } from '@anticrm/core'
import { getResource, IntlString, translate } from '@anticrm/platform' import { getResource, IntlString, translate } from '@anticrm/platform'
import { createQuery, getClient, ObjectSearchPopup, ObjectSearchResult } from '@anticrm/presentation' import { createQuery, getClient, ObjectSearchPopup, ObjectSearchResult } from '@anticrm/presentation'
@ -10,6 +11,8 @@
export let value: Issue export let value: Issue
const dispatch = createEventDispatcher()
const client = getClient() const client = getClient()
const query = createQuery() const query = createQuery()
$: relations = { $: relations = {
@ -119,6 +122,10 @@
}, },
...(hasRelation ? removeRelationAction : []) ...(hasRelation ? removeRelationAction : [])
] ]
afterUpdate(() => dispatch('changeContent', true))
</script> </script>
<Menu {actions} /> {#if actions}
<Menu {actions} on:changeContent={() => dispatch('changeContent', true)} />
{/if}

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { Scroller } from '@anticrm/ui' import { Scroller, issueSP, defaultSP } from '@anticrm/ui'
import IssuesListBrowser from './IssuesListBrowser.svelte' import IssuesListBrowser from './IssuesListBrowser.svelte'
import tracker from '../../plugin' import tracker from '../../plugin'
import { Issue, IssueStatus, ViewOptions } from '@anticrm/tracker' import { Issue, IssueStatus, ViewOptions } from '@anticrm/tracker'
@ -68,7 +68,7 @@
</script> </script>
<div class="w-full h-full clear-mins"> <div class="w-full h-full clear-mins">
<Scroller tableFade={categories[0] !== undefined} fadeTopOffset={48}> <Scroller fade={categories[0] !== undefined ? issueSP : defaultSP}>
<IssuesListBrowser <IssuesListBrowser
{_class} {_class}
{currentSpace} {currentSpace}

View File

@ -18,7 +18,17 @@
import { FindOptions } from '@anticrm/core' import { FindOptions } from '@anticrm/core'
import presentation, { Card } from '@anticrm/presentation' import presentation, { Card } from '@anticrm/presentation'
import { Issue, TimeSpendReport } from '@anticrm/tracker' import { Issue, TimeSpendReport } from '@anticrm/tracker'
import { Button, EditBox, EditStyle, eventToHTMLElement, IconAdd, Label, Scroller, showPopup } from '@anticrm/ui' import {
Button,
EditBox,
EditStyle,
eventToHTMLElement,
IconAdd,
Label,
Scroller,
tableSP,
showPopup
} from '@anticrm/ui'
import { TableBrowser } from '@anticrm/view-resources' import { TableBrowser } from '@anticrm/view-resources'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import tracker from '../../../plugin' import tracker from '../../../plugin'
@ -75,7 +85,7 @@
</div> </div>
<Label label={tracker.string.ChildEstimation} />: <Label label={tracker.string.ChildEstimation} />:
<div class="h-50"> <div class="h-50">
<Scroller tableFade> <Scroller fade={tableSP}>
<TableBrowser <TableBrowser
showFilterBar={false} showFilterBar={false}
_class={tracker.class.Issue} _class={tracker.class.Issue}
@ -91,7 +101,7 @@
</div> </div>
<Label label={tracker.string.ReportedTime} />: <Label label={tracker.string.ReportedTime} />:
<div class="h-50"> <div class="h-50">
<Scroller tableFade> <Scroller fade={tableSP}>
<TableBrowser <TableBrowser
_class={tracker.class.TimeSpendReport} _class={tracker.class.TimeSpendReport}
query={{ attachedTo: { $in: [object._id, ...childIds] } }} query={{ attachedTo: { $in: [object._id, ...childIds] } }}

View File

@ -17,7 +17,7 @@
import { FindOptions } from '@anticrm/core' import { FindOptions } from '@anticrm/core'
import presentation, { Card } from '@anticrm/presentation' import presentation, { Card } from '@anticrm/presentation'
import { Issue, TimeSpendReport } from '@anticrm/tracker' import { Issue, TimeSpendReport } from '@anticrm/tracker'
import { Button, eventToHTMLElement, IconAdd, Scroller, showPopup } from '@anticrm/ui' import { Button, eventToHTMLElement, IconAdd, Scroller, tableSP, showPopup } from '@anticrm/ui'
import { TableBrowser } from '@anticrm/view-resources' import { TableBrowser } from '@anticrm/view-resources'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import IssuePresenter from '../IssuePresenter.svelte' import IssuePresenter from '../IssuePresenter.svelte'
@ -54,7 +54,7 @@
<IssuePresenter value={issue} disableClick /> <IssuePresenter value={issue} disableClick />
</svelte:fragment> </svelte:fragment>
<div class="h-50"> <div class="h-50">
<Scroller tableFade> <Scroller fade={tableSP}>
<TableBrowser <TableBrowser
showFilterBar={false} showFilterBar={false}
_class={tracker.class.TimeSpendReport} _class={tracker.class.TimeSpendReport}

View File

@ -14,7 +14,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import type { Class, Doc, DocumentQuery, FindOptions, Ref } from '@anticrm/core' import type { Class, Doc, DocumentQuery, FindOptions, Ref } from '@anticrm/core'
import { Scroller } from '@anticrm/ui' import { Scroller, tableSP } from '@anticrm/ui'
import { BuildModelKey } from '@anticrm/view' import { BuildModelKey } from '@anticrm/view'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { ActionContext } from '..' import { ActionContext } from '..'
@ -57,7 +57,7 @@
{#if showFilterBar} {#if showFilterBar}
<FilterBar {_class} {query} on:change={(e) => (resultQuery = e.detail)} /> <FilterBar {_class} {query} on:change={(e) => (resultQuery = e.detail)} />
{/if} {/if}
<Scroller tableFade> <Scroller fade={tableSP}>
<Table <Table
bind:this={table} bind:this={table}
{_class} {_class}

View File

@ -17,6 +17,7 @@
import type { Application } from '@anticrm/workbench' import type { Application } from '@anticrm/workbench'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import AppItem from './AppItem.svelte' import AppItem from './AppItem.svelte'
import { Scroller } from '@anticrm/ui'
export let active: Ref<Application> | undefined export let active: Ref<Application> | undefined
export let apps: Application[] = [] export let apps: Application[] = []
@ -24,16 +25,18 @@
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
</script> </script>
<div class="flex-col"> <div class="flex-col align-center py-1">
{#each apps as app} <Scroller invertScroll padding={'.5rem .5rem'}>
<AppItem {#each apps as app}
selected={app._id === active} <AppItem
icon={app.icon} selected={app._id === active}
label={app.label} icon={app.icon}
action={async () => { label={app.label}
dispatch('active', app) action={async () => {
}} dispatch('active', app)
notify={false} }}
/> notify={false}
{/each} />
{/each}
</Scroller>
</div> </div>