Updated ListItem layout (#7008)

Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com>
This commit is contained in:
Alexander Platov 2024-10-22 10:46:39 +03:00 committed by GitHub
parent 385bd572a3
commit 15ce5442c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 77 additions and 26 deletions

View File

@ -14,7 +14,7 @@
-->
<script lang="ts">
import type { IntlString, Asset } from '@hcengineering/platform'
import { createEventDispatcher, ComponentType } from 'svelte'
import { createEventDispatcher, ComponentType, afterUpdate } from 'svelte'
import { DateRangeMode } from '@hcengineering/core'
import ui from '../../plugin'
@ -86,6 +86,7 @@
focusManager?.setFocus(idx)
})
}
afterUpdate(() => dispatch('resize', input?.clientWidth))
</script>
<button

View File

@ -75,6 +75,7 @@
{width}
{shouldIgnoreOverdue}
on:change={handleDueDateChanged}
on:resize
/>
</div>
{/if}

View File

@ -49,18 +49,32 @@
let allWidth: number
const widths: number[] = []
const elements: HTMLDivElement[] = []
afterUpdate(() => {
let count: number = 0
widths.forEach((i) => (count += i))
full = count > allWidth
dispatch('change', { full, ckeckFilled })
if (elements.length > 0) {
if (items.length > 4) dispatch('resize', elements[0]?.clientWidth)
else {
allWidth = 0
for (let i = 0; i < items.length; i++) {
if (elements[i].clientWidth !== undefined && allWidth < elements[i].clientWidth) {
allWidth = elements[i].clientWidth
}
}
dispatch('resize', allWidth + (items.length - 1) * 3)
}
}
})
</script>
{#if kind === 'list' || kind === 'link'}
{#if items.length > 4}
<div
bind:this={elements[0]}
class="label-box no-shrink"
use:tooltip={{
component: TagsItemPresenter,
@ -70,8 +84,8 @@
<TagsReferencePresenter {items} {kind} />
</div>
{:else}
{#each items as value}
<div class="label-box no-shrink" title={value.title}>
{#each items as value, i}
<div bind:this={elements[i]} class="label-box no-shrink" title={value.title}>
<TagReferencePresenter attr={undefined} {value} {kind} />
</div>
{/each}

View File

@ -18,7 +18,7 @@
import { RuleApplyResult, getClient, getDocRules } from '@hcengineering/presentation'
import { Component, Issue, IssueTemplate, Project, TrackerEvents } from '@hcengineering/tracker'
import { ButtonKind, ButtonShape, ButtonSize, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import { createEventDispatcher, afterUpdate } from 'svelte'
import { Analytics } from '@hcengineering/analytics'
import { activeComponent } from '../../issues'
@ -47,6 +47,8 @@
const dispatch = createEventDispatcher()
let element: HTMLDivElement
const handleComponentIdChanged = async (newComponentId: Ref<Component> | null | undefined) => {
if (!isEditable || newComponentId === undefined || (!Array.isArray(value) && value.component === newComponentId)) {
return
@ -101,11 +103,13 @@
}
}
}
afterUpdate(() => dispatch('resize', element?.clientWidth))
</script>
{#if kind === 'list'}
{#if !Array.isArray(value) && value.component}
<div class={compression ? 'label-wrapper' : 'clear-mins'}>
<div bind:this={element} class={compression ? 'label-wrapper' : 'clear-mins'}>
<ComponentSelector
{kind}
{size}
@ -127,6 +131,7 @@
{/if}
{:else}
<div
bind:this={element}
class="flex flex-wrap clear-mins"
class:minus-margin={kind === 'list-header'}
class:label-wrapper={compression}

View File

@ -55,4 +55,5 @@
{size}
{kind}
shouldIgnoreOverdue={ignoreOverDue}
on:resize
/>

View File

@ -13,6 +13,7 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher, afterUpdate } from 'svelte'
import { WithLookup } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import type { Issue } from '@hcengineering/tracker'
@ -26,13 +27,19 @@
export let disabled: boolean = false
export let maxWidth: string | undefined = undefined
let element: HTMLSpanElement
const dispatch = createEventDispatcher()
$: presenters =
value !== undefined ? getClient().getHierarchy().findMixinMixins(value, view.mixin.ObjectPresenter) : []
afterUpdate(() => dispatch('resize', element?.clientWidth))
</script>
{#if value}
{#if value && presenters.length > 0}
<span
class="presenter-label select-text p-1"
bind:this={element}
class="presenter-label select-text"
class:with-margin={shouldUseMargin}
class:list={kind === 'list'}
style:max-width={maxWidth}
@ -41,7 +48,7 @@
{#if presenters.length > 0}
<div class="flex-row-center">
{#each presenters as mixinPresenter}
<Component is={mixinPresenter.presenter} props={{ value }} />
<Component is={mixinPresenter.presenter} props={{ value, kind }} />
{/each}
</div>
{/if}
@ -50,7 +57,6 @@
<style lang="scss">
.presenter-label {
overflow: hidden;
display: inline-flex;
align-items: center;
flex-shrink: 1;

View File

@ -25,7 +25,7 @@
DatePresenter,
deviceOptionsStore as deviceInfo
} from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import { createEventDispatcher, afterUpdate } from 'svelte'
import { activeMilestone } from '../../issues'
import tracker from '../../plugin'
import MilestoneSelector from './MilestoneSelector.svelte'
@ -51,6 +51,8 @@
const client = getClient()
const dispatch = createEventDispatcher()
let element: HTMLDivElement
const handleMilestoneIdChanged = async (newMilestoneId: Ref<Milestone> | null | undefined) => {
if (!isEditable || newMilestoneId === undefined || (!Array.isArray(value) && value.milestone === newMilestoneId)) {
return
@ -86,11 +88,12 @@
$: _space = space ?? (!Array.isArray(value) ? value.space : { $in: Array.from(new Set(value.map((it) => it.space))) })
$: twoRows = $deviceInfo.twoRows
afterUpdate(() => dispatch('resize', element?.clientWidth))
</script>
{#if kind === 'list'}
{#if !Array.isArray(value) && value.milestone}
<div class={compression ? 'label-wrapper' : 'clear-mins'}>
<div bind:this={element} class={compression ? 'label-wrapper' : 'clear-mins'}>
<MilestoneSelector
{kind}
{size}
@ -112,6 +115,7 @@
{/if}
{:else}
<div
bind:this={element}
class="flex flex-wrap clear-mins"
class:minus-margin={kind === 'list-header'}
class:label-wrapper={compression}

View File

@ -60,11 +60,11 @@
>
<svelte:fragment slot="content">
{#if title}
<span class="caption-color overflow-label pointer-events-none">{title}</span>
<span class="label caption-color overflow-label pointer-events-none">{title}</span>
{:else if value}
<span class="caption-color overflow-label pointer-events-none">{value}</span>
<span class="label caption-color overflow-label pointer-events-none">{value}</span>
{:else}
<span class="content-dark-color pointer-events-none">
<span class="label content-dark-color pointer-events-none">
<Label label={placeholder} />
</span>
{/if}

View File

@ -84,6 +84,11 @@
onMount(() => {
dispatch('on-mount')
})
let minWidth: number | undefined = undefined
const sizes = new Map<number, number>()
const calcSizes = (): void => {
minWidth = sizes.size > 0 ? Array.from(sizes.values()).reduce((a, b) => a + b, 0) : undefined
}
</script>
<!-- svelte-ignore a11y-no-static-element-interactions -->
@ -147,14 +152,19 @@
{/if}
<GrowPresenter />
{#if !compactMode}
<div class="compression-bar">
{#each model.filter((p) => p.displayProps?.compression === true) as attrModel}
<div class="compression-bar" style:min-width={`${minWidth}px`}>
{#each model.filter((p) => p.displayProps?.compression === true) as attrModel, index}
<ListPresenter
{docObject}
attributeModel={attrModel}
props={getProps(props, $restrictionStore.readonly)}
value={getObjectValue(attrModel.key, docObject)}
onChange={getOnChange(docObject, attrModel)}
on:resize={(e) => {
if (e.detail == null) return
sizes.set(index, e.detail)
calcSizes()
}}
/>
{/each}
</div>

View File

@ -13,6 +13,7 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import core, { Doc } from '@hcengineering/core'
import { AttributeModel } from '@hcengineering/view'
import { FixedColumn } from '../..'
@ -26,6 +27,8 @@
export let hideDivider: boolean = false
export let compactMode: boolean = false
const dispatch = createEventDispatcher()
$: dp = attributeModel?.displayProps
function joinProps (attribute: AttributeModel, object: Doc, props: Record<string, any>) {
@ -35,6 +38,10 @@
}
return { object, ...clearAttributeProps, space: object.space, ...props }
}
const translateSize = (e: CustomEvent): void => {
if (e.detail === undefined) return
dispatch('resize', e.detail)
}
</script>
{#if dp?.dividerBefore === true && !hideDivider}
@ -49,6 +56,7 @@
kind={'list'}
{compactMode}
{...joinProps(attributeModel, docObject, props)}
on:resize={translateSize}
/>
</FixedColumn>
{:else}
@ -59,5 +67,6 @@
kind={'list'}
{compactMode}
{...joinProps(attributeModel, docObject, props)}
on:resize={translateSize}
/>
{/if}

View File

@ -2,11 +2,13 @@
import { Issue } from '@hcengineering/tracker'
import { getClient } from '@hcengineering/presentation'
import type { ButtonKind } from '@hcengineering/ui'
import { HyperlinkEditor } from '@hcengineering/view-resources'
import github from '../../plugin'
import { integrationRepositories } from '../utils'
export let value: Issue
export let kind: ButtonKind = 'ghost'
$: ghIssue = getClient().getHierarchy().asIf(value, github.mixin.GithubIssue)
@ -14,14 +16,12 @@
</script>
{#if ghIssue !== undefined && ghIssue.url !== '' && repository !== undefined}
<div class="flex flex-row-center">
<HyperlinkEditor
readonly
icon={github.icon.Github}
kind={'ghost'}
value={ghIssue.url}
placeholder={github.string.Issue}
title={`${repository.name}`}
/>
</div>
<HyperlinkEditor
readonly
icon={github.icon.Github}
{kind}
value={ghIssue.url}
placeholder={github.string.Issue}
title={`${repository.name}`}
/>
{/if}