mirror of
https://github.com/hcengineering/platform.git
synced 2025-01-03 08:57:14 +03:00
UBER-504: fix presenters on ListItem. Add DeviceSizes. (#3463)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
dbfbcc12ee
commit
c7ade707c6
@ -474,14 +474,19 @@ export function createModel (builder: Builder): void {
|
|||||||
props: {},
|
props: {},
|
||||||
displayProps: { key: 'title' }
|
displayProps: { key: 'title' }
|
||||||
},
|
},
|
||||||
{ key: 'comments', displayProps: { key: 'comments' } },
|
{
|
||||||
{ key: 'attachments', displayProps: { key: 'attachments' } },
|
key: '',
|
||||||
{ key: '', label: tracker.string.SubIssues, presenter: tracker.component.SubIssuesSelector, props: {} },
|
label: tracker.string.SubIssues,
|
||||||
|
presenter: tracker.component.SubIssuesSelector,
|
||||||
|
props: {}
|
||||||
|
},
|
||||||
|
{ key: 'comments', displayProps: { key: 'comments', suffix: true } },
|
||||||
|
{ key: 'attachments', displayProps: { key: 'attachments', suffix: true } },
|
||||||
{ key: '', displayProps: { grow: true } },
|
{ key: '', displayProps: { grow: true } },
|
||||||
{
|
{
|
||||||
key: 'labels',
|
key: 'labels',
|
||||||
presenter: tags.component.LabelsPresenter,
|
presenter: tags.component.LabelsPresenter,
|
||||||
displayProps: { optional: true, compression: true },
|
displayProps: { optional: true },
|
||||||
props: { kind: 'list', full: false }
|
props: { kind: 'list', full: false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -497,7 +502,6 @@ export function createModel (builder: Builder): void {
|
|||||||
displayProps: {
|
displayProps: {
|
||||||
key: 'milestone',
|
key: 'milestone',
|
||||||
excludeByKey: 'milestone',
|
excludeByKey: 'milestone',
|
||||||
compression: true,
|
|
||||||
optional: true
|
optional: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -514,7 +518,6 @@ export function createModel (builder: Builder): void {
|
|||||||
displayProps: {
|
displayProps: {
|
||||||
key: 'component',
|
key: 'component',
|
||||||
excludeByKey: 'component',
|
excludeByKey: 'component',
|
||||||
compression: true,
|
|
||||||
optional: true
|
optional: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -522,7 +525,7 @@ export function createModel (builder: Builder): void {
|
|||||||
key: '',
|
key: '',
|
||||||
label: tracker.string.DueDate,
|
label: tracker.string.DueDate,
|
||||||
presenter: tracker.component.DueDatePresenter,
|
presenter: tracker.component.DueDatePresenter,
|
||||||
displayProps: { key: 'dueDate', optional: true, compression: true },
|
displayProps: { key: 'dueDate', optional: true },
|
||||||
props: { kind: 'list' }
|
props: { kind: 'list' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -530,7 +533,7 @@ export function createModel (builder: Builder): void {
|
|||||||
label: tracker.string.Estimation,
|
label: tracker.string.Estimation,
|
||||||
presenter: tracker.component.EstimationEditor,
|
presenter: tracker.component.EstimationEditor,
|
||||||
props: { kind: 'list', size: 'small' },
|
props: { kind: 'list', size: 'small' },
|
||||||
displayProps: { key: 'estimation', fixed: 'left', compression: true, dividerBefore: true }
|
displayProps: { key: 'estimation', fixed: 'left', dividerBefore: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'modifiedOn',
|
key: 'modifiedOn',
|
||||||
@ -697,7 +700,7 @@ export function createModel (builder: Builder): void {
|
|||||||
size: 'small',
|
size: 'small',
|
||||||
shouldShowPlaceholder: false
|
shouldShowPlaceholder: false
|
||||||
},
|
},
|
||||||
displayProps: { key: 'component', optional: true, compression: true }
|
displayProps: { key: 'component', optional: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
@ -708,7 +711,7 @@ export function createModel (builder: Builder): void {
|
|||||||
size: 'small',
|
size: 'small',
|
||||||
shouldShowPlaceholder: false
|
shouldShowPlaceholder: false
|
||||||
},
|
},
|
||||||
displayProps: { key: 'milestone', optional: true, compression: true }
|
displayProps: { key: 'milestone', optional: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
@ -718,7 +721,7 @@ export function createModel (builder: Builder): void {
|
|||||||
kind: 'list',
|
kind: 'list',
|
||||||
size: 'small'
|
size: 'small'
|
||||||
},
|
},
|
||||||
displayProps: { key: 'estimation', optional: true, compression: true }
|
displayProps: { key: 'estimation', optional: true }
|
||||||
},
|
},
|
||||||
{ key: '', displayProps: { grow: true } },
|
{ key: '', displayProps: { grow: true } },
|
||||||
{
|
{
|
||||||
|
@ -453,6 +453,7 @@ input.search {
|
|||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
}
|
}
|
||||||
|
&.halfcontent { color: var(--theme-halfcontent-color); }
|
||||||
}
|
}
|
||||||
&:hover .icon { color: var(--theme-caption-color); }
|
&:hover .icon { color: var(--theme-caption-color); }
|
||||||
}
|
}
|
||||||
@ -904,6 +905,7 @@ a.no-line {
|
|||||||
|
|
||||||
.content-trans-color { color: var(--theme-trans-color); }
|
.content-trans-color { color: var(--theme-trans-color); }
|
||||||
.content-darker-color { color: var(--theme-darker-color); }
|
.content-darker-color { color: var(--theme-darker-color); }
|
||||||
|
.content-halfcontent-color { color: var(--theme-halfcontent-color); }
|
||||||
.content-dark-color { color: var(--theme-dark-color); }
|
.content-dark-color { color: var(--theme-dark-color); }
|
||||||
.content-color { color: var(--theme-content-color); }
|
.content-color { color: var(--theme-content-color); }
|
||||||
.caption-color { color: var(--theme-caption-color); }
|
.caption-color { color: var(--theme-caption-color); }
|
||||||
|
@ -890,27 +890,28 @@
|
|||||||
.optional-bar {
|
.optional-bar {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-shrink: 1;
|
flex-grow: 1;
|
||||||
min-width: 0;
|
border-radius: 1.625rem;
|
||||||
border-radius: 0 1.49rem 1.49rem 0;
|
transition: flex-shrink 0.25s cubic-bezier(0.38, 0.01, 0.33, 1) 0s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
flex-shrink: .5;
|
||||||
|
min-width: initial;
|
||||||
|
}
|
||||||
.label-wrapper {
|
.label-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-shrink: 10;
|
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
& > *:not(:last-child) {
|
|
||||||
flex-shrink: 10;
|
|
||||||
width: min-content;
|
|
||||||
}
|
|
||||||
& > *:last-child {
|
& > *:last-child {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
}
|
}
|
||||||
& > * { margin-left: .375rem; }
|
& > *:not(:first-child) { margin-left: .25rem; }
|
||||||
|
& > * > * { min-width: fit-content; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Labels on the ListView
|
// Labels on the ListView
|
||||||
@ -920,10 +921,13 @@
|
|||||||
.list-container .antiButton.list:hover,
|
.list-container .antiButton.list:hover,
|
||||||
.list-container .datetime-button,
|
.list-container .datetime-button,
|
||||||
.list-container .datetime-button:hover {
|
.list-container .datetime-button:hover {
|
||||||
|
padding-left: .5rem !important;
|
||||||
|
padding-right: .5rem !important;
|
||||||
|
font-size: 0.8125rem !important;
|
||||||
background-color: var(--theme-list-button-color) !important;
|
background-color: var(--theme-list-button-color) !important;
|
||||||
|
|
||||||
&:not(.only-icon) .btn-icon,
|
&:not(.only-icon) .btn-icon,
|
||||||
&:not(.only-icon) .icon { margin-right: .5rem !important; }
|
&:not(.only-icon) .icon { margin-right: .375rem !important; }
|
||||||
.icon, .btn-icon { color: var(--theme-halfcontent-color) !important; }
|
.icon, .btn-icon { color: var(--theme-halfcontent-color) !important; }
|
||||||
.label {
|
.label {
|
||||||
font-size: 0.8125rem !important;
|
font-size: 0.8125rem !important;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import platform, { addEventListener, getMetadata, OK, PlatformEvent, Status } from '@hcengineering/platform'
|
import platform, { addEventListener, getMetadata, OK, PlatformEvent, Status } from '@hcengineering/platform'
|
||||||
import { onDestroy } from 'svelte'
|
import { onDestroy } from 'svelte'
|
||||||
import type { AnyComponent } from '../../types'
|
import type { AnyComponent, WidthType } from '../../types'
|
||||||
// import { applicationShortcutKey } from '../../utils'
|
// import { applicationShortcutKey } from '../../utils'
|
||||||
import { getCurrentLocation, location, navigate, locationStorageKeyId } from '../../location'
|
import { getCurrentLocation, location, navigate, locationStorageKeyId } from '../../location'
|
||||||
|
|
||||||
@ -100,6 +100,41 @@
|
|||||||
document.addEventListener('dblclick', (event) => {
|
document.addEventListener('dblclick', (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let remove: any = null
|
||||||
|
const sizes: Record<WidthType, boolean> = { xs: false, sm: false, md: false, lg: false, xl: false, xxl: false }
|
||||||
|
const css: Record<WidthType, string> = { xs: '', sm: '', md: '', lg: '', xl: '', xxl: '' }
|
||||||
|
const deviceSizes: WidthType[] = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl']
|
||||||
|
const deviceWidths = [480, 680, 760, 1024, 1208, -1]
|
||||||
|
deviceSizes.forEach((ds, i) => {
|
||||||
|
if (i === 0) css[ds] = `(max-width: ${deviceWidths[i]}px)`
|
||||||
|
else if (i === deviceSizes.length - 1) css[ds] = `(min-width: ${deviceWidths[i - 1]}.01px)`
|
||||||
|
else css[ds] = `(min-width: ${deviceWidths[i - 1]}.01px) and (max-width: ${deviceWidths[i]}px)`
|
||||||
|
})
|
||||||
|
const getSize = (width: number): WidthType => {
|
||||||
|
return deviceSizes[
|
||||||
|
deviceWidths.findIndex((it) => (it === -1 ? deviceWidths[deviceWidths.length - 2] < width : it > width))
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const updateDeviceSize = () => {
|
||||||
|
if (remove !== null) remove()
|
||||||
|
const size = getSize(docWidth)
|
||||||
|
const mqString = css[size]
|
||||||
|
const media = matchMedia(mqString)
|
||||||
|
|
||||||
|
deviceWidths.forEach((_, i) => (sizes[deviceSizes[i]] = false))
|
||||||
|
deviceWidths.forEach((dw, i) => {
|
||||||
|
sizes[deviceSizes[i]] =
|
||||||
|
dw === -1 ? deviceWidths[deviceWidths.length - 2] < docWidth : docWidth > dw || size === deviceSizes[i]
|
||||||
|
})
|
||||||
|
$deviceInfo.size = size
|
||||||
|
$deviceInfo.sizes = sizes
|
||||||
|
media.addEventListener('change', updateDeviceSize)
|
||||||
|
remove = () => {
|
||||||
|
media.removeEventListener('change', updateDeviceSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateDeviceSize()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window bind:innerWidth={docWidth} bind:innerHeight={docHeight} />
|
<svelte:window bind:innerWidth={docWidth} bind:innerHeight={docHeight} />
|
||||||
|
@ -220,6 +220,8 @@ export const deviceOptionsStore = writable<DeviceOptions>({
|
|||||||
isPortrait: false,
|
isPortrait: false,
|
||||||
isMobile: false,
|
isMobile: false,
|
||||||
fontSize: 0,
|
fontSize: 0,
|
||||||
|
size: null,
|
||||||
|
sizes: { xs: false, sm: false, md: false, lg: false, xl: false, xxl: false },
|
||||||
minWidth: false,
|
minWidth: false,
|
||||||
twoRows: false
|
twoRows: false
|
||||||
})
|
})
|
||||||
|
@ -295,12 +295,16 @@ export const tableHRscheduleY: FadeOptions = { multipler: { top: 5, bottom: 0 }
|
|||||||
export const issueSP: FadeOptions = { multipler: { top: 2.75, bottom: 0 } }
|
export const issueSP: FadeOptions = { multipler: { top: 2.75, bottom: 0 } }
|
||||||
export const emojiSP: FadeOptions = { multipler: { top: 1.5, bottom: 0 } }
|
export const emojiSP: FadeOptions = { multipler: { top: 1.5, bottom: 0 } }
|
||||||
|
|
||||||
|
export type WidthType = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'
|
||||||
|
|
||||||
export interface DeviceOptions {
|
export interface DeviceOptions {
|
||||||
docWidth: number
|
docWidth: number
|
||||||
docHeight: number
|
docHeight: number
|
||||||
isPortrait: boolean
|
isPortrait: boolean
|
||||||
isMobile: boolean
|
isMobile: boolean
|
||||||
fontSize: number
|
fontSize: number
|
||||||
|
size: WidthType | null
|
||||||
|
sizes: Record<WidthType, boolean>
|
||||||
minWidth: boolean
|
minWidth: boolean
|
||||||
twoRows: boolean
|
twoRows: boolean
|
||||||
theme?: any
|
theme?: any
|
||||||
|
@ -23,29 +23,40 @@
|
|||||||
export let object: Doc
|
export let object: Doc
|
||||||
export let size: ButtonSize = 'small'
|
export let size: ButtonSize = 'small'
|
||||||
export let kind: ButtonKind = 'link'
|
export let kind: ButtonKind = 'link'
|
||||||
export let showCounter = true
|
export let showCounter: boolean = true
|
||||||
|
export let compactMode: boolean = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value && value > 0}
|
{#if value && value > 0}
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<DocNavLink {object} inline noUnderline={true}>
|
<DocNavLink {object} inline noUnderline={true} shrink={0}>
|
||||||
{#if kind === 'list'}
|
{#if kind === 'list'}
|
||||||
<div
|
{#if compactMode}
|
||||||
use:tooltip={{
|
<div
|
||||||
component: AttachmentPopup,
|
use:tooltip={{
|
||||||
props: { objectId: object._id, attachments: value, object }
|
component: AttachmentPopup,
|
||||||
}}
|
props: { objectId: object._id, attachments: value, object }
|
||||||
class="sm-tool-icon"
|
}}
|
||||||
>
|
class="sm-tool-icon"
|
||||||
<Button {kind} {size}>
|
|
||||||
<div slot="content" class="flex-row-center">
|
|
||||||
<span class="icon"><IconAttachment {size} /></span>
|
|
||||||
{#if showCounter}
|
|
||||||
{value}
|
|
||||||
{/if}
|
|
||||||
</div></Button
|
|
||||||
>
|
>
|
||||||
</div>
|
<div class="icon halfcontent"><IconAttachment {size} /></div>
|
||||||
|
{#if showCounter}{value ?? 0}{/if}
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<Button
|
||||||
|
{kind}
|
||||||
|
{size}
|
||||||
|
showTooltip={{
|
||||||
|
component: AttachmentPopup,
|
||||||
|
props: { objectId: object._id, attachments: value, object }
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div slot="icon"><IconAttachment {size} /></div>
|
||||||
|
<div slot="content" style:margin-left={showCounter ? '.375rem' : '0'}>
|
||||||
|
{#if showCounter}{value ?? 0}{/if}
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
use:tooltip={{
|
use:tooltip={{
|
||||||
|
@ -23,30 +23,41 @@
|
|||||||
export let object: Doc
|
export let object: Doc
|
||||||
export let size: ButtonSize = 'small'
|
export let size: ButtonSize = 'small'
|
||||||
export let kind: ButtonKind = 'link'
|
export let kind: ButtonKind = 'link'
|
||||||
export let showCounter = true
|
export let showCounter: boolean = true
|
||||||
|
export let compactMode: boolean = false
|
||||||
export let withInput: boolean = true
|
export let withInput: boolean = true
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value && value > 0}
|
{#if value && value > 0}
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<DocNavLink {object} inline noUnderline={true}>
|
<DocNavLink {object} inline noUnderline={true} shrink={0}>
|
||||||
{#if kind === 'list'}
|
{#if kind === 'list'}
|
||||||
<div
|
{#if compactMode}
|
||||||
use:tooltip={{
|
<div
|
||||||
component: CommentPopup,
|
use:tooltip={{
|
||||||
props: { objectId: object._id, object, withInput }
|
component: CommentPopup,
|
||||||
}}
|
props: { objectId: object._id, object, withInput }
|
||||||
class="sm-tool-icon"
|
}}
|
||||||
>
|
class="sm-tool-icon"
|
||||||
<Button {kind} {size}>
|
>
|
||||||
<div slot="content" class="flex-row-center">
|
<div class="icon halfcontent"><IconThread {size} /></div>
|
||||||
<span class="icon"><IconThread size={'small'} /></span>
|
{#if showCounter}{value ?? 0}{/if}
|
||||||
{#if showCounter}
|
</div>
|
||||||
{value ?? 0}
|
{:else}
|
||||||
{/if}
|
<Button
|
||||||
|
{kind}
|
||||||
|
{size}
|
||||||
|
showTooltip={{
|
||||||
|
component: CommentPopup,
|
||||||
|
props: { objectId: object._id, object, withInput }
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div slot="icon"><IconThread {size} /></div>
|
||||||
|
<div slot="content" style:margin-left={showCounter ? '.375rem' : '0'}>
|
||||||
|
{#if showCounter}{value ?? 0}{/if}
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
use:tooltip={{
|
use:tooltip={{
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
"Weight": "Weight",
|
"Weight": "Weight",
|
||||||
"Expert": "Expert",
|
"Expert": "Expert",
|
||||||
"Meaningfull": "Meaningfull",
|
"Meaningfull": "Meaningfull",
|
||||||
"Initial": "Initial"
|
"Initial": "Initial",
|
||||||
|
"NumberLabels": "{count, plural, =0 {no labels} =1 {1 label} other {# labels}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,6 +37,7 @@
|
|||||||
"Weight": "Вес",
|
"Weight": "Вес",
|
||||||
"Expert": "Эксперт",
|
"Expert": "Эксперт",
|
||||||
"Meaningfull": "Значимый",
|
"Meaningfull": "Значимый",
|
||||||
"Initial": "Начальный"
|
"Initial": "Начальный",
|
||||||
|
"NumberLabels": "{count, plural, =0 {нет меток} one {# метка} few {# метки} other {# меток}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,10 +3,12 @@
|
|||||||
import { createQuery } from '@hcengineering/presentation'
|
import { createQuery } from '@hcengineering/presentation'
|
||||||
import type { TagReference } from '@hcengineering/tags'
|
import type { TagReference } from '@hcengineering/tags'
|
||||||
import tags from '@hcengineering/tags'
|
import tags from '@hcengineering/tags'
|
||||||
import { getEventPopupPositionElement, resizeObserver, showPopup } from '@hcengineering/ui'
|
import { getEventPopupPositionElement, resizeObserver, showPopup, tooltip } from '@hcengineering/ui'
|
||||||
import { afterUpdate, createEventDispatcher } from 'svelte'
|
import { afterUpdate, createEventDispatcher } from 'svelte'
|
||||||
import TagReferencePresenter from './TagReferencePresenter.svelte'
|
import TagReferencePresenter from './TagReferencePresenter.svelte'
|
||||||
|
import TagsReferencePresenter from './TagsReferencePresenter.svelte'
|
||||||
import TagsEditorPopup from './TagsEditorPopup.svelte'
|
import TagsEditorPopup from './TagsEditorPopup.svelte'
|
||||||
|
import TagsItemPresenter from './TagsItemPresenter.svelte'
|
||||||
|
|
||||||
export let value: number
|
export let value: number
|
||||||
export let object: WithLookup<Doc>
|
export let object: WithLookup<Doc>
|
||||||
@ -51,11 +53,23 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if kind === 'list' || kind === 'link'}
|
{#if kind === 'list' || kind === 'link'}
|
||||||
{#each items as value}
|
{#if items.length > 4}
|
||||||
<div class="label-box no-shrink" title={value.title}>
|
<div
|
||||||
<TagReferencePresenter attr={undefined} {value} {kind} />
|
class="label-box no-shrink"
|
||||||
|
use:tooltip={{
|
||||||
|
component: TagsItemPresenter,
|
||||||
|
props: { value: items, kind: 'list' }
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TagsReferencePresenter {items} {kind} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{:else}
|
||||||
|
{#each items as value}
|
||||||
|
<div class="label-box no-shrink" title={value.title}>
|
||||||
|
<TagReferencePresenter attr={undefined} {value} {kind} />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
@ -93,15 +107,15 @@
|
|||||||
.label-box {
|
.label-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-shrink: 10;
|
// flex-shrink: 10;
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
transition: box-shadow 0.15s ease-in-out;
|
transition: box-shadow 0.15s ease-in-out;
|
||||||
|
|
||||||
&:not(.no-shrink):last-child {
|
// &:not(.no-shrink):last-child {
|
||||||
flex-shrink: 0;
|
// flex-shrink: 0;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
.wrap-short:not(:last-child) {
|
.wrap-short:not(:last-child) {
|
||||||
margin-right: 0.375rem;
|
margin-right: 0.375rem;
|
||||||
|
@ -14,13 +14,25 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { TagReference } from '@hcengineering/tags'
|
import { TagReference } from '@hcengineering/tags'
|
||||||
|
import TagReferencePresenter from './TagReferencePresenter.svelte'
|
||||||
import TagItem from './TagItem.svelte'
|
import TagItem from './TagItem.svelte'
|
||||||
|
|
||||||
export let value: TagReference[] | TagReference
|
export let value: TagReference[] | TagReference
|
||||||
|
export let kind: 'tag' | 'list' = 'tag'
|
||||||
|
|
||||||
$: values = Array.isArray(value) ? value : [value]
|
$: values = Array.isArray(value) ? value : [value]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each values as v}
|
{#if kind === 'list'}
|
||||||
<TagItem tag={v} />
|
<div class="flex-center flex-wrap">
|
||||||
{/each}
|
{#each values as v}
|
||||||
|
<div class="m-0-5">
|
||||||
|
<TagReferencePresenter attr={undefined} value={v} {kind} />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
{#each values as v}
|
||||||
|
<TagItem tag={v} />
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
@ -0,0 +1,119 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2023 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License. You may
|
||||||
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
//
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
-->
|
||||||
|
<script lang="ts">
|
||||||
|
import type { TagReference } from '@hcengineering/tags'
|
||||||
|
import plugin from '../plugin'
|
||||||
|
import { getPlatformColorDef, themeStore, Label } from '@hcengineering/ui'
|
||||||
|
|
||||||
|
export let items: TagReference[]
|
||||||
|
export let kind: 'list' | 'link' = 'list'
|
||||||
|
|
||||||
|
$: colors = items.slice(0, 3).map((it) => {
|
||||||
|
return getPlatformColorDef(it.color ?? 0, $themeStore.dark)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if items}
|
||||||
|
{#if kind === 'link'}
|
||||||
|
<button class="link-container">
|
||||||
|
{#each colors as color}
|
||||||
|
<div class="color" style:background-color={color.color} />
|
||||||
|
{/each}
|
||||||
|
<span class="label overflow-label ml-1 text-sm caption-color max-w-40">
|
||||||
|
<Label label={plugin.string.NumberLabels} params={{ count: items.length }} />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{:else if kind === 'list'}
|
||||||
|
<div class="listitems-container">
|
||||||
|
{#each colors as color}
|
||||||
|
<div class="color" style:background-color={color.color} />
|
||||||
|
{/each}
|
||||||
|
<span class="label overflow-label ml-1-5 max-w-40">
|
||||||
|
<Label label={plugin.string.NumberLabels} params={{ count: items.length }} />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.listitems-container {
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
height: 1.75rem;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
background-color: var(--theme-button-enabled);
|
||||||
|
border: 1px solid var(--theme-button-border);
|
||||||
|
border-radius: 1.5rem;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--theme-button-hovered);
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 0 0.375rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
min-width: 1.5rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 0.75rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: var(--theme-content-color);
|
||||||
|
background-color: var(--theme-link-button-color);
|
||||||
|
border: 1px solid var(--theme-button-border);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
transition-property: border, background-color, color, box-shadow;
|
||||||
|
transition-duration: 0.15s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
background-color: var(--theme-link-button-hover);
|
||||||
|
border-color: var(--theme-list-divider-color);
|
||||||
|
transition-duration: 0;
|
||||||
|
}
|
||||||
|
&:focus {
|
||||||
|
border-color: var(--primary-edit-border-color) !important;
|
||||||
|
}
|
||||||
|
&:disabled {
|
||||||
|
color: rgb(var(--theme-caption-color) / 40%);
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.color {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
&:not(:nth-child(3)) {
|
||||||
|
mask: radial-gradient(circle at 100% 50%, rgba(0, 0, 0, 0) 48.5%, rgb(0, 0, 0) 50%);
|
||||||
|
}
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-left: calc(1px - 0.25rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -49,7 +49,8 @@ export default mergeIds(tagsId, tags, {
|
|||||||
Weight: '' as IntlString,
|
Weight: '' as IntlString,
|
||||||
Expert: '' as IntlString,
|
Expert: '' as IntlString,
|
||||||
Meaningfull: '' as IntlString,
|
Meaningfull: '' as IntlString,
|
||||||
Initial: '' as IntlString
|
Initial: '' as IntlString,
|
||||||
|
NumberLabels: '' as IntlString
|
||||||
},
|
},
|
||||||
function: {
|
function: {
|
||||||
FilterTagsInResult: '' as FilterFunction,
|
FilterTagsInResult: '' as FilterFunction,
|
||||||
|
@ -56,9 +56,8 @@
|
|||||||
|
|
||||||
{#if (value.component && value.component !== $activeComponent && groupBy !== 'component') || shouldShowPlaceholder}
|
{#if (value.component && value.component !== $activeComponent && groupBy !== 'component') || shouldShowPlaceholder}
|
||||||
<div
|
<div
|
||||||
class="clear-mins"
|
class="label-wrapper"
|
||||||
class:minus-margin={kind === 'list-header'}
|
class:minus-margin={kind === 'list-header'}
|
||||||
class:label-wrapper={compression}
|
|
||||||
use:tooltip={{ label: value.component ? tracker.string.MoveToComponent : tracker.string.AddToComponent }}
|
use:tooltip={{ label: value.component ? tracker.string.MoveToComponent : tracker.string.AddToComponent }}
|
||||||
>
|
>
|
||||||
<ComponentSelector
|
<ComponentSelector
|
||||||
@ -74,7 +73,7 @@
|
|||||||
{onlyIcon}
|
{onlyIcon}
|
||||||
{enlargedText}
|
{enlargedText}
|
||||||
value={value.component}
|
value={value.component}
|
||||||
short={compression}
|
short
|
||||||
onChange={handleComponentIdChanged}
|
onChange={handleComponentIdChanged}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
export let size: ButtonSize = 'small'
|
export let size: ButtonSize = 'small'
|
||||||
export let justify: 'left' | 'center' = 'left'
|
export let justify: 'left' | 'center' = 'left'
|
||||||
export let width: string | undefined = 'min-contet'
|
export let width: string | undefined = 'min-contet'
|
||||||
|
export let compactMode: boolean = false
|
||||||
|
|
||||||
let btn: HTMLElement
|
let btn: HTMLElement
|
||||||
|
|
||||||
@ -150,9 +151,11 @@
|
|||||||
<svelte:fragment slot="content">
|
<svelte:fragment slot="content">
|
||||||
{#if subIssues}
|
{#if subIssues}
|
||||||
<div class="flex-row-center content-color text-sm pointer-events-none">
|
<div class="flex-row-center content-color text-sm pointer-events-none">
|
||||||
<div class="mr-1-5">
|
{#if !compactMode}
|
||||||
<ProgressCircle bind:value={countComplete} bind:max={subIssues.length} size={'small'} primary />
|
<div class="mr-1-5">
|
||||||
</div>
|
<ProgressCircle bind:value={countComplete} bind:max={subIssues.length} size={'small'} primary />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{countComplete}/{subIssues.length}
|
{countComplete}/{subIssues.length}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
{#if kind === 'list'}
|
{#if kind === 'list'}
|
||||||
{#if value.milestone}
|
{#if value.milestone}
|
||||||
<div class="clear-mins" class:label-wrapper={compression}>
|
<div class="label-wrapper">
|
||||||
<MilestoneSelector
|
<MilestoneSelector
|
||||||
{kind}
|
{kind}
|
||||||
{size}
|
{size}
|
||||||
@ -90,7 +90,7 @@
|
|||||||
{popupPlaceholder}
|
{popupPlaceholder}
|
||||||
{onlyIcon}
|
{onlyIcon}
|
||||||
{enlargedText}
|
{enlargedText}
|
||||||
short={compression}
|
short
|
||||||
showTooltip={{ label: value.milestone ? tracker.string.MoveToMilestone : tracker.string.AddToMilestone }}
|
showTooltip={{ label: value.milestone ? tracker.string.MoveToMilestone : tracker.string.AddToMilestone }}
|
||||||
value={value.milestone}
|
value={value.milestone}
|
||||||
onChange={handleMilestoneIdChanged}
|
onChange={handleMilestoneIdChanged}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
export let disableHeader = false
|
export let disableHeader = false
|
||||||
export let props: Record<string, any> = {}
|
export let props: Record<string, any> = {}
|
||||||
export let selection: number | undefined = undefined
|
export let selection: number | undefined = undefined
|
||||||
|
export let compactMode: boolean = false
|
||||||
|
|
||||||
export let documents: Doc[] | undefined = undefined
|
export let documents: Doc[] | undefined = undefined
|
||||||
|
|
||||||
@ -138,6 +139,7 @@
|
|||||||
{disableHeader}
|
{disableHeader}
|
||||||
{props}
|
{props}
|
||||||
{listDiv}
|
{listDiv}
|
||||||
|
{compactMode}
|
||||||
bind:dragItem
|
bind:dragItem
|
||||||
on:select={(evt) => {
|
on:select={(evt) => {
|
||||||
select(0, evt.detail)
|
select(0, evt.detail)
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
export let listDiv: HTMLDivElement
|
export let listDiv: HTMLDivElement
|
||||||
export let selection: number | undefined = undefined
|
export let selection: number | undefined = undefined
|
||||||
export let groupPersistKey: string
|
export let groupPersistKey: string
|
||||||
|
export let compactMode: boolean = false
|
||||||
|
|
||||||
$: groupByKey = viewOptions.groupBy[level] ?? noCategory
|
$: groupByKey = viewOptions.groupBy[level] ?? noCategory
|
||||||
let categories: CategoryType[] = []
|
let categories: CategoryType[] = []
|
||||||
@ -310,6 +311,7 @@
|
|||||||
{createItemDialogProps}
|
{createItemDialogProps}
|
||||||
{createItemLabel}
|
{createItemLabel}
|
||||||
{viewOptionsConfig}
|
{viewOptionsConfig}
|
||||||
|
{compactMode}
|
||||||
on:check
|
on:check
|
||||||
on:uncheckAll
|
on:uncheckAll
|
||||||
on:row-focus
|
on:row-focus
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
export let listDiv: HTMLDivElement
|
export let listDiv: HTMLDivElement
|
||||||
export let index: number
|
export let index: number
|
||||||
export let groupPersistKey: string
|
export let groupPersistKey: string
|
||||||
|
export let compactMode: boolean = false
|
||||||
|
|
||||||
$: lastLevel = level + 1 >= viewOptions.groupBy.length
|
$: lastLevel = level + 1 >= viewOptions.groupBy.length
|
||||||
|
|
||||||
@ -448,6 +449,7 @@
|
|||||||
on:mouseover={mouseAttractor(() => handleRowFocused(docObject))}
|
on:mouseover={mouseAttractor(() => handleRowFocused(docObject))}
|
||||||
on:mouseenter={mouseAttractor(() => handleRowFocused(docObject))}
|
on:mouseenter={mouseAttractor(() => handleRowFocused(docObject))}
|
||||||
{props}
|
{props}
|
||||||
|
{compactMode}
|
||||||
on:on-mount={() => {
|
on:on-mount={() => {
|
||||||
wasLoaded = true
|
wasLoaded = true
|
||||||
}}
|
}}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
import { AnyAttribute, Doc, getObjectValue } from '@hcengineering/core'
|
import { AnyAttribute, Doc, getObjectValue } from '@hcengineering/core'
|
||||||
import notification from '@hcengineering/notification'
|
import notification from '@hcengineering/notification'
|
||||||
import { getClient, updateAttribute } from '@hcengineering/presentation'
|
import { getClient, updateAttribute } from '@hcengineering/presentation'
|
||||||
import { CheckBox, Component, deviceOptionsStore as deviceInfo, IconCircles, tooltip } from '@hcengineering/ui'
|
import { CheckBox, Component, IconCircles, tooltip } from '@hcengineering/ui'
|
||||||
import { AttributeModel } from '@hcengineering/view'
|
import { AttributeModel } from '@hcengineering/view'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import view from '../../plugin'
|
import view from '../../plugin'
|
||||||
@ -31,6 +31,7 @@
|
|||||||
export let last: boolean = false
|
export let last: boolean = false
|
||||||
export let lastCat: boolean = false
|
export let lastCat: boolean = false
|
||||||
export let props: Record<string, any> = {}
|
export let props: Record<string, any> = {}
|
||||||
|
export let compactMode: boolean = false
|
||||||
|
|
||||||
export function scroll () {
|
export function scroll () {
|
||||||
elem?.scrollIntoView({ behavior: 'auto', block: 'nearest' })
|
elem?.scrollIntoView({ behavior: 'auto', block: 'nearest' })
|
||||||
@ -48,8 +49,6 @@
|
|||||||
return elem
|
return elem
|
||||||
}
|
}
|
||||||
|
|
||||||
$: compactMode = $deviceInfo.twoRows
|
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
function onChange (value: any, doc: Doc, key: string, attribute: AnyAttribute) {
|
function onChange (value: any, doc: Doc, key: string, attribute: AnyAttribute) {
|
||||||
@ -64,13 +63,6 @@
|
|||||||
return (value: any) => onChange(value, docObject, attribute.key, attr)
|
return (value: any) => onChange(value, docObject, attribute.key, attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
let noCompressed: number
|
|
||||||
$: if (model) {
|
|
||||||
noCompressed = -1
|
|
||||||
model.forEach((m, i) => {
|
|
||||||
if (m.displayProps?.compression) noCompressed = i
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
dispatch('on-mount')
|
dispatch('on-mount')
|
||||||
})
|
})
|
||||||
@ -120,32 +112,55 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#each model.filter((p) => !(p.displayProps?.optional === true)) as attributeModel, i}
|
{#each model.filter((p) => !(p.displayProps?.optional === true || p.displayProps?.suffix === true)) as attributeModel, i}
|
||||||
{@const displayProps = attributeModel.displayProps}
|
{@const displayProps = attributeModel.displayProps}
|
||||||
{#if !groupByKey || displayProps?.excludeByKey !== groupByKey}
|
{#if !groupByKey || displayProps?.excludeByKey !== groupByKey}
|
||||||
{#if displayProps?.grow}
|
{#if displayProps?.grow}
|
||||||
<GrowPresenter />
|
|
||||||
{#if !compactMode}
|
{#if !compactMode}
|
||||||
{#each model.filter((p) => p.displayProps?.optional === true) as attrModel, j}
|
{#each model.filter((p) => p.displayProps?.suffix === true) as attrModel}
|
||||||
<ListPresenter
|
<ListPresenter
|
||||||
{docObject}
|
{docObject}
|
||||||
attributeModel={attrModel}
|
attributeModel={attrModel}
|
||||||
{props}
|
{props}
|
||||||
compression={j !== noCompressed}
|
|
||||||
value={getObjectValue(attrModel.key, docObject)}
|
value={getObjectValue(attrModel.key, docObject)}
|
||||||
onChange={getOnChange(docObject, attrModel)}
|
onChange={getOnChange(docObject, attrModel)}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
<GrowPresenter />
|
||||||
|
{#if !compactMode}
|
||||||
|
<div class="optional-bar">
|
||||||
|
{#each model.filter((p) => p.displayProps?.optional === true) as attrModel}
|
||||||
|
<ListPresenter
|
||||||
|
{docObject}
|
||||||
|
attributeModel={attrModel}
|
||||||
|
{props}
|
||||||
|
value={getObjectValue(attrModel.key, docObject)}
|
||||||
|
onChange={getOnChange(docObject, attrModel)}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
{#each model.filter((p) => p.displayProps?.suffix === true) as attrModel}
|
||||||
|
<ListPresenter
|
||||||
|
{docObject}
|
||||||
|
attributeModel={attrModel}
|
||||||
|
{props}
|
||||||
|
value={getObjectValue(attrModel.key, docObject)}
|
||||||
|
onChange={getOnChange(docObject, attrModel)}
|
||||||
|
compactMode
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<ListPresenter
|
<ListPresenter
|
||||||
{docObject}
|
{docObject}
|
||||||
{attributeModel}
|
{attributeModel}
|
||||||
{props}
|
{props}
|
||||||
compression={i !== noCompressed}
|
|
||||||
value={getObjectValue(attributeModel.key, docObject)}
|
value={getObjectValue(attributeModel.key, docObject)}
|
||||||
onChange={getOnChange(docObject, attributeModel)}
|
onChange={getOnChange(docObject, attributeModel)}
|
||||||
hideDivider={i === 0}
|
hideDivider={i === 0}
|
||||||
|
{compactMode}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
@ -164,7 +179,7 @@
|
|||||||
<IconCircles />
|
<IconCircles />
|
||||||
</div>
|
</div>
|
||||||
<div class="scroll-box gap-2">
|
<div class="scroll-box gap-2">
|
||||||
{#each model.filter((m) => m.displayProps?.optional || m.displayProps?.compression) as attributeModel, j}
|
{#each model.filter((m) => m.displayProps?.optional) as attributeModel, j}
|
||||||
{@const displayProps = attributeModel.displayProps}
|
{@const displayProps = attributeModel.displayProps}
|
||||||
{@const value = getObjectValue(attributeModel.key, docObject)}
|
{@const value = getObjectValue(attributeModel.key, docObject)}
|
||||||
{#if displayProps?.excludeByKey !== groupByKey && value !== undefined}
|
{#if displayProps?.excludeByKey !== groupByKey && value !== undefined}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
export let props: Record<string, any>
|
export let props: Record<string, any>
|
||||||
export let compression: boolean = false
|
export let compression: boolean = false
|
||||||
export let hideDivider: boolean = false
|
export let hideDivider: boolean = false
|
||||||
|
export let compactMode: boolean = false
|
||||||
|
|
||||||
$: dp = attributeModel?.displayProps
|
$: dp = attributeModel?.displayProps
|
||||||
|
|
||||||
@ -47,6 +48,7 @@
|
|||||||
{value}
|
{value}
|
||||||
{onChange}
|
{onChange}
|
||||||
kind={'list'}
|
kind={'list'}
|
||||||
|
{compactMode}
|
||||||
{...joinProps(attributeModel, docObject, props)}
|
{...joinProps(attributeModel, docObject, props)}
|
||||||
/>
|
/>
|
||||||
</FixedColumn>
|
</FixedColumn>
|
||||||
@ -56,7 +58,7 @@
|
|||||||
{value}
|
{value}
|
||||||
{onChange}
|
{onChange}
|
||||||
kind={'list'}
|
kind={'list'}
|
||||||
compression={dp?.compression && compression}
|
{compactMode}
|
||||||
{...joinProps(attributeModel, docObject, props)}
|
{...joinProps(attributeModel, docObject, props)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
let list: List
|
let list: List
|
||||||
let scroll: Scroller
|
let scroll: Scroller
|
||||||
let divScroll: HTMLDivElement
|
let divScroll: HTMLDivElement
|
||||||
|
let listWidth: number
|
||||||
|
|
||||||
const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
|
const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
|
||||||
if (dir === 'vertical') {
|
if (dir === 'vertical') {
|
||||||
@ -43,7 +44,7 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="w-full h-full py-4 clear-mins">
|
<div bind:clientWidth={listWidth} class="w-full h-full py-4 clear-mins">
|
||||||
<Scroller
|
<Scroller
|
||||||
bind:this={scroll}
|
bind:this={scroll}
|
||||||
bind:divScroll
|
bind:divScroll
|
||||||
@ -64,6 +65,7 @@
|
|||||||
{createItemLabel}
|
{createItemLabel}
|
||||||
{viewOptions}
|
{viewOptions}
|
||||||
{props}
|
{props}
|
||||||
|
compactMode={listWidth <= 800}
|
||||||
viewOptionsConfig={viewlet.viewOptions?.other}
|
viewOptionsConfig={viewlet.viewOptions?.other}
|
||||||
selectedObjectIds={$selectionStore ?? []}
|
selectedObjectIds={$selectionStore ?? []}
|
||||||
selection={listProvider.current($focusStore)}
|
selection={listProvider.current($focusStore)}
|
||||||
|
@ -535,8 +535,8 @@ export interface DisplayProps {
|
|||||||
key?: string
|
key?: string
|
||||||
excludeByKey?: string
|
excludeByKey?: string
|
||||||
fixed?: 'left' | 'right' // using for align items in row
|
fixed?: 'left' | 'right' // using for align items in row
|
||||||
|
suffix?: boolean
|
||||||
optional?: boolean
|
optional?: boolean
|
||||||
compression?: boolean
|
|
||||||
grow?: boolean
|
grow?: boolean
|
||||||
dividerBefore?: boolean // should show divider before
|
dividerBefore?: boolean // should show divider before
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user