mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-22 16:27:22 +00:00
UBER-538: fixed ListView and KanbanView. (#3475)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
6100c73ae4
commit
9f81007d8e
@ -302,11 +302,14 @@ export function createModel (builder: Builder): void {
|
|||||||
},
|
},
|
||||||
config: [
|
config: [
|
||||||
{ key: '', displayProps: { fixed: 'left', key: 'lead' } },
|
{ key: '', displayProps: { fixed: 'left', key: 'lead' } },
|
||||||
|
{
|
||||||
|
key: 'state',
|
||||||
|
props: { kind: 'list', size: 'small', shouldShowName: false }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
presenter: lead.component.TitlePresenter,
|
presenter: lead.component.TitlePresenter,
|
||||||
label: lead.string.Title,
|
label: lead.string.Title,
|
||||||
displayProps: { fixed: 'left', key: 'title' },
|
|
||||||
props: { maxWidth: '10rem' }
|
props: { maxWidth: '10rem' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -314,35 +317,38 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: contact.component.PersonPresenter,
|
presenter: contact.component.PersonPresenter,
|
||||||
label: lead.string.Customer,
|
label: lead.string.Customer,
|
||||||
sortingKey: '$lookup.attachedTo.name',
|
sortingKey: '$lookup.attachedTo.name',
|
||||||
displayProps: { fixed: 'left', key: 'talent' },
|
|
||||||
props: {
|
props: {
|
||||||
_class: lead.mixin.Customer,
|
_class: lead.mixin.Customer,
|
||||||
inline: true,
|
inline: true,
|
||||||
maxWidth: '10rem'
|
maxWidth: '10rem'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ key: 'state', displayProps: { fixed: 'left', key: 'state' } },
|
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
presenter: tracker.component.RelatedIssueSelector,
|
presenter: tracker.component.RelatedIssueSelector,
|
||||||
label: tracker.string.Relations,
|
label: tracker.string.Relations,
|
||||||
displayProps: { fixed: 'left', key: 'issues', optional: true }
|
props: { size: 'small' }
|
||||||
},
|
},
|
||||||
{ key: 'attachments', displayProps: { key: 'attachments', optional: true } },
|
{ key: 'attachments', displayProps: { key: 'attachments', suffix: true } },
|
||||||
{ key: 'comments', displayProps: { key: 'comments', optional: true } },
|
{ key: 'comments', displayProps: { key: 'comments', suffix: true } },
|
||||||
{ key: '', displayProps: { grow: true } },
|
{ key: '', displayProps: { grow: true } },
|
||||||
{
|
{
|
||||||
key: '$lookup.attachedTo.$lookup.channels',
|
key: '$lookup.attachedTo.$lookup.channels',
|
||||||
label: contact.string.ContactInfo,
|
label: contact.string.ContactInfo,
|
||||||
sortingKey: ['$lookup.attachedTo.$lookup.channels.lastMessage', '$lookup.attachedTo.channels'],
|
sortingKey: ['$lookup.attachedTo.$lookup.channels.lastMessage', '$lookup.attachedTo.channels'],
|
||||||
displayProps: {
|
props: {
|
||||||
fixed: 'left',
|
length: 'full',
|
||||||
key: 'channels',
|
size: 'small',
|
||||||
dividerBefore: true
|
kind: 'list'
|
||||||
}
|
},
|
||||||
|
displayProps: { optional: true }
|
||||||
},
|
},
|
||||||
{ key: 'modifiedOn', displayProps: { key: 'modified', fixed: 'left', dividerBefore: true } },
|
{ key: 'modifiedOn', displayProps: { key: 'modified', fixed: 'right', dividerBefore: true } },
|
||||||
{ key: 'assignee', displayProps: { key: 'assignee', fixed: 'right' }, props: { shouldShowLabel: false } }
|
{
|
||||||
|
key: 'assignee',
|
||||||
|
props: { kind: 'list', shouldShowName: false, avatarSize: 'x-small' },
|
||||||
|
displayProps: { key: 'assignee', fixed: 'right' }
|
||||||
|
}
|
||||||
],
|
],
|
||||||
viewOptions: leadViewOptions
|
viewOptions: leadViewOptions
|
||||||
},
|
},
|
||||||
|
@ -685,8 +685,7 @@ export function createModel (builder: Builder): void {
|
|||||||
{ key: '', displayProps: { fixed: 'left', key: 'app' } },
|
{ key: '', displayProps: { fixed: 'left', key: 'app' } },
|
||||||
{
|
{
|
||||||
key: 'state',
|
key: 'state',
|
||||||
props: { kind: 'list', size: 'small', shouldShowName: false },
|
props: { kind: 'list', size: 'small', shouldShowName: false }
|
||||||
displayProps: { excludeByKey: 'state' }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '$lookup.attachedTo',
|
key: '$lookup.attachedTo',
|
||||||
@ -721,14 +720,16 @@ export function createModel (builder: Builder): void {
|
|||||||
sortingKey: ['$lookup.attachedTo.$lookup.channels.lastMessage', '$lookup.attachedTo.channels'],
|
sortingKey: ['$lookup.attachedTo.$lookup.channels.lastMessage', '$lookup.attachedTo.channels'],
|
||||||
props: {
|
props: {
|
||||||
length: 'full',
|
length: 'full',
|
||||||
size: 'inline'
|
size: 'small',
|
||||||
}
|
kind: 'list'
|
||||||
|
},
|
||||||
|
displayProps: { optional: true }
|
||||||
},
|
},
|
||||||
{ key: 'modifiedOn', displayProps: { key: 'modified', fixed: 'right', dividerBefore: true } },
|
{ key: 'modifiedOn', displayProps: { key: 'modified', fixed: 'right', dividerBefore: true } },
|
||||||
{
|
{
|
||||||
key: 'assignee',
|
key: 'assignee',
|
||||||
props: { kind: 'list', shouldShowName: false, avatarSize: 'x-small' },
|
props: { kind: 'list', shouldShowName: false, avatarSize: 'x-small' },
|
||||||
displayProps: { key: 'assignee', fixed: 'right', excludeByKey: 'assignee' }
|
displayProps: { key: 'assignee', fixed: 'right' }
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
|
@ -366,7 +366,7 @@
|
|||||||
}
|
}
|
||||||
.kanban-content {
|
.kanban-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem 1.5rem 0.5rem;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,11 +901,6 @@
|
|||||||
flex-shrink: .5;
|
flex-shrink: .5;
|
||||||
min-width: initial;
|
min-width: initial;
|
||||||
}
|
}
|
||||||
.label-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
& > *:last-child {
|
& > *:last-child {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
@ -936,8 +931,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Kanban - global style */
|
/* Kanban - global style */
|
||||||
.kanban-container .card-container .card-labels > * { margin: .25rem .25rem 0 0; }
|
.kanban-container .card-container .card-labels > *:not(.labels-container),
|
||||||
.kanban-container .card-container .card-labels.labels > *:last-child {
|
.kanban-container .card-container .card-labels.labels .labels-container > * {
|
||||||
flex-shrink: 0;
|
margin: .25rem .25rem 0 0;
|
||||||
margin-right: 0;
|
|
||||||
|
&:last-child {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.kanban-container .card-container .card-labels .datetime-button {
|
||||||
|
padding: 0 0.25rem !important;
|
||||||
|
height: 1.75rem !important;
|
||||||
|
font-size: .8125rem !important;
|
||||||
|
}
|
||||||
|
.kanban-container .card-container .card-labels .label { font-size: .8125rem !important; }
|
||||||
|
|
||||||
|
/* ListView & Kanban */
|
||||||
|
.list-container .optional-bar .label-wrapper,
|
||||||
|
.kanban-container .card-container .card-labels .label-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { afterUpdate } from 'svelte'
|
import { afterUpdate } from 'svelte'
|
||||||
|
import { closeTooltip } from '..'
|
||||||
|
|
||||||
export let vertical: boolean = false
|
export let vertical: boolean = false
|
||||||
export let stretch: boolean = false
|
export let stretch: boolean = false
|
||||||
@ -29,6 +30,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
function setAutoscroll () {
|
function setAutoscroll () {
|
||||||
|
closeTooltip()
|
||||||
autoscroll = div.scrollTop > div.scrollHeight - div.clientHeight - 50
|
autoscroll = div.scrollTop > div.scrollHeight - div.clientHeight - 50
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -474,7 +474,7 @@
|
|||||||
class="scroll relative flex-shrink"
|
class="scroll relative flex-shrink"
|
||||||
style:overflow-x={horizontal ? 'auto' : 'hidden'}
|
style:overflow-x={horizontal ? 'auto' : 'hidden'}
|
||||||
on:scroll={() => {
|
on:scroll={() => {
|
||||||
if ($tooltipstore.label !== undefined) closeTooltip()
|
if ($tooltipstore.label !== undefined || $tooltipstore.component !== undefined) closeTooltip()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
export let editable: boolean = true
|
export let editable: boolean = true
|
||||||
export let shouldIgnoreOverdue: boolean = false
|
export let shouldIgnoreOverdue: boolean = false
|
||||||
export let size: ButtonSize = 'medium'
|
export let size: ButtonSize = 'medium'
|
||||||
export let width: string | undefined = undefined
|
export let width: string | undefined = 'auto'
|
||||||
|
|
||||||
const today = new Date(new Date(Date.now()).setHours(0, 0, 0, 0))
|
const today = new Date(new Date(Date.now()).setHours(0, 0, 0, 0))
|
||||||
$: isOverdue = value !== null && value < today.getTime()
|
$: isOverdue = value !== null && value < today.getTime()
|
||||||
|
@ -261,7 +261,7 @@
|
|||||||
id={item.label}
|
id={item.label}
|
||||||
bind:input={btns[i]}
|
bind:input={btns[i]}
|
||||||
icon={item.icon}
|
icon={item.icon}
|
||||||
kind={highlighted.includes(item.provider) ? 'dangerous' : kind}
|
kind={'link-bordered'}
|
||||||
{size}
|
{size}
|
||||||
{shape}
|
{shape}
|
||||||
highlight={item.integration || item.notification}
|
highlight={item.integration || item.notification}
|
||||||
|
@ -21,12 +21,14 @@
|
|||||||
|
|
||||||
import OrganizationPresenter from './OrganizationPresenter.svelte'
|
import OrganizationPresenter from './OrganizationPresenter.svelte'
|
||||||
import PersonPresenter from './PersonPresenter.svelte'
|
import PersonPresenter from './PersonPresenter.svelte'
|
||||||
|
import { IconSize } from '@hcengineering/ui'
|
||||||
|
|
||||||
export let value: Contact
|
export let value: Contact
|
||||||
export let inline: boolean = false
|
export let inline: boolean = false
|
||||||
export let disabled: boolean = false
|
export let disabled: boolean = false
|
||||||
export let accent: boolean = false
|
export let accent: boolean = false
|
||||||
export let maxWidth = ''
|
export let maxWidth = ''
|
||||||
|
export let avatarSize: IconSize = 'x-small'
|
||||||
|
|
||||||
function isPerson (value: Contact): boolean {
|
function isPerson (value: Contact): boolean {
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
@ -43,9 +45,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isEmployee(value)}
|
{#if isEmployee(value)}
|
||||||
<EmployeePresenter {disabled} value={toEmployee(value)} {inline} {accent} />
|
<EmployeePresenter {disabled} value={toEmployee(value)} {inline} {accent} {avatarSize} />
|
||||||
{:else if isPerson(value)}
|
{:else if isPerson(value)}
|
||||||
<PersonPresenter {disabled} {value} {inline} {accent} />
|
<PersonPresenter {disabled} {value} {inline} {accent} {avatarSize} />
|
||||||
{:else}
|
{:else}
|
||||||
<OrganizationPresenter value={toOrg(value)} {inline} {accent} {maxWidth} />
|
<OrganizationPresenter value={toOrg(value)} {inline} {accent} {maxWidth} />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -44,11 +44,10 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex-col pt-2 pb-2 pr-4 pl-4">
|
<div class="flex-col pt-3 pb-3 pr-4 pl-4">
|
||||||
<div class="flex-between mb-4">
|
<div class="flex-between mb-3">
|
||||||
<div class="flex-col">
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div class="fs-title cursor-pointer" on:click={showLead}>{object.title}</div>
|
<div class="fs-title cursor-pointer" on:click={showLead}>{object.title}</div>
|
||||||
</div>
|
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
<div class="mr-2">
|
<div class="mr-2">
|
||||||
<Component is={notification.component.NotificationPresenter} props={{ value: object }} />
|
<Component is={notification.component.NotificationPresenter} props={{ value: object }} />
|
||||||
@ -63,42 +62,44 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-col">
|
<div class="flex-between mb-2">
|
||||||
<div class="flex-between">
|
{#if enabledConfig(config, 'attachedTo') && object.$lookup?.attachedTo}
|
||||||
{#if enabledConfig(config, 'attachedTo') && object.$lookup?.attachedTo}
|
<ContactPresenter value={object.$lookup.attachedTo} avatarSize={'small'} />
|
||||||
<ContactPresenter value={object.$lookup.attachedTo} />
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
<div class="flex-row-center gap-3">
|
{#if enabledConfig(config, 'dueDate')}
|
||||||
{#if enabledConfig(config, 'attachments') && (object.attachments ?? 0) > 0}
|
<div class="card-labels labels mb-2">
|
||||||
<AttachmentsPresenter value={object.attachments} {object} />
|
<DueDatePresenter
|
||||||
{/if}
|
size={'small'}
|
||||||
{#if enabledConfig(config, 'comments') && (object.comments ?? 0) > 0}
|
kind={'link-bordered'}
|
||||||
<CommentsPresenter value={object.comments} {object} />
|
width={'fit-content'}
|
||||||
{/if}
|
value={object.dueDate}
|
||||||
</div>
|
shouldRender={object.dueDate !== null && object.dueDate !== undefined}
|
||||||
|
shouldIgnoreOverdue={object.doneState !== null}
|
||||||
|
onChange={async (e) => {
|
||||||
|
await client.update(object, { dueDate: e })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-row-center flex-between mt-2">
|
{/if}
|
||||||
|
<div class="flex-between">
|
||||||
|
<div class="flex-row-center gap-3 reverse mr-4">
|
||||||
<LeadPresenter value={object} />
|
<LeadPresenter value={object} />
|
||||||
{#if enabledConfig(config, 'dueDate')}
|
{#if enabledConfig(config, 'attachments') && (object.attachments ?? 0) > 0}
|
||||||
<DueDatePresenter
|
<AttachmentsPresenter value={object.attachments} {object} />
|
||||||
size={'small'}
|
|
||||||
value={object.dueDate}
|
|
||||||
shouldRender={object.dueDate !== null && object.dueDate !== undefined}
|
|
||||||
shouldIgnoreOverdue={object.doneState !== null}
|
|
||||||
onChange={async (e) => {
|
|
||||||
await client.update(object, { dueDate: e })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
{#if enabledConfig(config, 'assignee')}
|
{#if enabledConfig(config, 'comments') && (object.comments ?? 0) > 0}
|
||||||
<AssigneePresenter
|
<CommentsPresenter value={object.comments} {object} />
|
||||||
value={object.assignee}
|
|
||||||
issueId={object._id}
|
|
||||||
defaultClass={contact.class.Employee}
|
|
||||||
currentSpace={object.space}
|
|
||||||
placeholderLabel={assigneeAttribute.label}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{#if enabledConfig(config, 'assignee')}
|
||||||
|
<AssigneePresenter
|
||||||
|
value={object.assignee}
|
||||||
|
issueId={object._id}
|
||||||
|
defaultClass={contact.class.Employee}
|
||||||
|
currentSpace={object.space}
|
||||||
|
placeholderLabel={assigneeAttribute.label}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,9 +48,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div class="flex-col pt-2 pb-2 pr-4 pl-4 cursor-pointer" on:click={showCandidate}>
|
<div class="flex-col pt-3 pb-3 pr-4 pl-4" on:click={showCandidate}>
|
||||||
{#if enabledConfig(config, 'space') || enabledConfig(config, 'company')}
|
{#if enabledConfig(config, 'space') || enabledConfig(config, 'company')}
|
||||||
<div class="p-1 flex-between gap-2">
|
<div class="flex-between mb-3">
|
||||||
{#if enabledConfig(config, 'space')}
|
{#if enabledConfig(config, 'space')}
|
||||||
<ObjectPresenter _class={recruit.class.Vacancy} objectId={object.space} value={object.$lookup?.space} />
|
<ObjectPresenter _class={recruit.class.Vacancy} objectId={object.space} value={object.$lookup?.space} />
|
||||||
{/if}
|
{/if}
|
||||||
@ -59,7 +59,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex-between mb-3">
|
<div class="flex-between mb-1">
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
<Avatar avatar={object.$lookup?.attachedTo?.avatar} size={'medium'} />
|
<Avatar avatar={object.$lookup?.attachedTo?.avatar} size={'medium'} />
|
||||||
<div class="flex-grow flex-col min-w-0 ml-2">
|
<div class="flex-grow flex-col min-w-0 ml-2">
|
||||||
@ -71,63 +71,69 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool mr-1 flex-row-center">
|
<div class="tool flex-row-center">
|
||||||
{#if !dragged}
|
{#if !dragged}
|
||||||
<div class="mr-2">
|
<div class="mr-2">
|
||||||
<Component showLoading={false} is={notification.component.NotificationPresenter} props={{ value: object }} />
|
<Component showLoading={false} is={notification.component.NotificationPresenter} props={{ value: object }} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if channels && channels.length > 0 && enabledConfig(config, 'channels')}
|
</div>
|
||||||
<div class="tool mr-1 flex-row-center">
|
{#if channels && channels.length > 0 && enabledConfig(config, 'channels')}
|
||||||
<div class="step-lr75">
|
<div class="card-labels labels mb-2">
|
||||||
<Component
|
<Component
|
||||||
showLoading={false}
|
showLoading={false}
|
||||||
is={contact.component.ChannelsPresenter}
|
is={contact.component.ChannelsPresenter}
|
||||||
props={{ value: channels, object: object.$lookup?.attachedTo, length: 'tiny', size: 'inline' }}
|
props={{ value: channels, object: object.$lookup?.attachedTo, length: 'full', size: 'inline', kind: 'list' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
|
<div class="card-labels mb-2">
|
||||||
|
{#if groupByKey !== 'state' && enabledConfig(config, 'state')}
|
||||||
|
<StateRefPresenter
|
||||||
|
size={'small'}
|
||||||
|
kind={'link-bordered'}
|
||||||
|
shrink={1}
|
||||||
|
value={object.state}
|
||||||
|
onChange={(state) => {
|
||||||
|
client.update(object, { state })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
<Component showLoading={false} is={tracker.component.RelatedIssueSelector} props={{ object, size: 'small' }} />
|
||||||
|
{#if enabledConfig(config, 'dueDate')}
|
||||||
|
<DueDatePresenter
|
||||||
|
size={'small'}
|
||||||
|
kind={'link-bordered'}
|
||||||
|
value={object.dueDate}
|
||||||
|
shouldRender={object.dueDate !== null && object.dueDate !== undefined}
|
||||||
|
shouldIgnoreOverdue={object.doneState !== null}
|
||||||
|
onChange={async (e) => {
|
||||||
|
await client.update(object, { dueDate: e })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center gap-3 reverse mr-4">
|
||||||
<div class="sm-tool-icon step-lr75">
|
{#if enabledConfig(config, '')}
|
||||||
{#if enabledConfig(config, '')}
|
<ApplicationPresenter value={object} inline />
|
||||||
<div class="mr-2">
|
|
||||||
<ApplicationPresenter value={object} inline />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<Component showLoading={false} is={tracker.component.RelatedIssueSelector} props={{ object }} />
|
|
||||||
</div>
|
|
||||||
{#if enabledConfig(config, 'dueDate')}
|
|
||||||
<DueDatePresenter
|
|
||||||
size={'small'}
|
|
||||||
value={object.dueDate}
|
|
||||||
shouldRender={object.dueDate !== null && object.dueDate !== undefined}
|
|
||||||
shouldIgnoreOverdue={object.doneState !== null}
|
|
||||||
onChange={async (e) => {
|
|
||||||
await client.update(object, { dueDate: e })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex-row-center gap-3">
|
{#if (object.attachments ?? 0) > 0 && enabledConfig(config, 'attachments')}
|
||||||
{#if (object.attachments ?? 0) > 0 && enabledConfig(config, 'attachments')}
|
<AttachmentsPresenter value={object.attachments} {object} />
|
||||||
<AttachmentsPresenter value={object.attachments} {object} />
|
{/if}
|
||||||
|
{#if enabledConfig(config, 'comments')}
|
||||||
|
{#if (object.comments ?? 0) > 0}
|
||||||
|
<CommentsPresenter value={object.comments} {object} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if enabledConfig(config, 'comments')}
|
{#if object.$lookup?.attachedTo !== undefined && (object.$lookup.attachedTo.comments ?? 0) > 0}
|
||||||
{#if (object.comments ?? 0) > 0}
|
<CommentsPresenter
|
||||||
<CommentsPresenter value={object.comments} {object} />
|
value={object.$lookup?.attachedTo?.comments}
|
||||||
{/if}
|
object={object.$lookup?.attachedTo}
|
||||||
{#if object.$lookup?.attachedTo !== undefined && (object.$lookup.attachedTo.comments ?? 0) > 0}
|
withInput={false}
|
||||||
<CommentsPresenter
|
/>
|
||||||
value={object.$lookup?.attachedTo?.comments}
|
|
||||||
object={object.$lookup?.attachedTo}
|
|
||||||
withInput={false}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if enabledConfig(config, 'assignee')}
|
{#if enabledConfig(config, 'assignee')}
|
||||||
<AssigneePresenter
|
<AssigneePresenter
|
||||||
@ -139,13 +145,18 @@
|
|||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if groupByKey !== 'state' && enabledConfig(config, 'state')}
|
|
||||||
<StateRefPresenter
|
|
||||||
size={'small'}
|
|
||||||
value={object.state}
|
|
||||||
onChange={(state) => {
|
|
||||||
client.update(object, { state })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.card-labels {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
&.labels {
|
||||||
|
overflow: hidden;
|
||||||
|
flex-shrink: 1;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
class="label-box no-shrink"
|
class="label-box no-shrink"
|
||||||
use:tooltip={{
|
use:tooltip={{
|
||||||
component: TagsItemPresenter,
|
component: TagsItemPresenter,
|
||||||
props: { value: items, kind: 'list' }
|
props: { value: items, kind: 'link' }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TagsReferencePresenter {items} {kind} />
|
<TagsReferencePresenter {items} {kind} />
|
||||||
@ -99,7 +99,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
// flex-shrink: 0;
|
flex-shrink: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
@ -107,15 +107,10 @@
|
|||||||
.label-box {
|
.label-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
// 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 {
|
|
||||||
// flex-shrink: 0;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
.wrap-short:not(:last-child) {
|
.wrap-short:not(:last-child) {
|
||||||
margin-right: 0.375rem;
|
margin-right: 0.375rem;
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
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'
|
export let kind: 'tag' | 'list' | 'link' = 'tag'
|
||||||
|
|
||||||
$: values = Array.isArray(value) ? value : [value]
|
$: values = Array.isArray(value) ? value : [value]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if kind === 'list'}
|
{#if kind === 'list' || kind === 'link'}
|
||||||
<div class="flex-center flex-wrap">
|
<div class="flex-center flex-wrap">
|
||||||
{#each values as v}
|
{#each values as v}
|
||||||
<div class="m-0-5">
|
<div class="m-0-5">
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
export let width: string = 'min-content'
|
export let width: string = 'min-content'
|
||||||
export let justify: 'left' | 'center' = 'center'
|
export let justify: 'left' | 'center' = 'center'
|
||||||
export let shouldShowName: boolean = true
|
export let shouldShowName: boolean = true
|
||||||
|
export let shrink: number = 0
|
||||||
|
|
||||||
let state: State
|
let state: State
|
||||||
let opened: boolean = false
|
let opened: boolean = false
|
||||||
@ -60,7 +61,7 @@
|
|||||||
{#if kind === 'list' || kind === 'list-header'}
|
{#if kind === 'list' || kind === 'list-header'}
|
||||||
<StatePresenter value={state} {shouldShowName} shouldShowTooltip on:click={handleClick} />
|
<StatePresenter value={state} {shouldShowName} shouldShowTooltip on:click={handleClick} />
|
||||||
{:else}
|
{:else}
|
||||||
<Button {kind} {size} {width} {justify} on:click={handleClick}>
|
<Button {kind} {size} {width} {justify} {shrink} on:click={handleClick}>
|
||||||
<svelte:fragment slot="content">
|
<svelte:fragment slot="content">
|
||||||
{#if state}
|
{#if state}
|
||||||
<div class="pointer-events-none clear-mins">
|
<div class="pointer-events-none clear-mins">
|
||||||
|
@ -26,13 +26,14 @@
|
|||||||
export let kind: ButtonKind = 'link'
|
export let kind: ButtonKind = 'link'
|
||||||
export let size: ButtonSize = 'medium'
|
export let size: ButtonSize = 'medium'
|
||||||
export let shouldShowName: boolean = true
|
export let shouldShowName: boolean = true
|
||||||
|
export let shrink: number = 0
|
||||||
|
|
||||||
$: state = $statusStore.get(typeof value === 'string' ? value : (value?.values?.[0]?._id as Ref<Status>))
|
$: state = $statusStore.get(typeof value === 'string' ? value : (value?.values?.[0]?._id as Ref<Status>))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
{#if onChange !== undefined && state !== undefined}
|
{#if onChange !== undefined && state !== undefined}
|
||||||
<StateEditor value={state._id} space={state.space} {onChange} {kind} {size} {shouldShowName} />
|
<StateEditor value={state._id} space={state.space} {onChange} {kind} {size} {shouldShowName} {shrink} />
|
||||||
{:else}
|
{:else}
|
||||||
<StatePresenter value={state} {shouldShowName} on:accent-color />
|
<StatePresenter value={state} {shouldShowName} on:accent-color />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
export let onlyIcon: boolean = false
|
export let onlyIcon: boolean = false
|
||||||
export let enlargedText: boolean = false
|
export let enlargedText: boolean = false
|
||||||
export let short: boolean = false
|
export let short: boolean = false
|
||||||
|
export let shrink: number = 0
|
||||||
export let focusIndex: number | undefined = undefined
|
export let focusIndex: number | undefined = undefined
|
||||||
export let space: Ref<Project> | undefined = undefined
|
export let space: Ref<Project> | undefined = undefined
|
||||||
|
|
||||||
@ -110,6 +111,7 @@
|
|||||||
disabled={!isEditable}
|
disabled={!isEditable}
|
||||||
{loading}
|
{loading}
|
||||||
{short}
|
{short}
|
||||||
|
{shrink}
|
||||||
on:click={handleComponentEditorOpened}
|
on:click={handleComponentEditorOpened}
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
@ -125,6 +127,7 @@
|
|||||||
{loading}
|
{loading}
|
||||||
notSelected={!value}
|
notSelected={!value}
|
||||||
{short}
|
{short}
|
||||||
|
{shrink}
|
||||||
on:click={handleComponentEditorOpened}
|
on:click={handleComponentEditorOpened}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="content">
|
<svelte:fragment slot="content">
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
export let groupBy: string | undefined = undefined
|
export let groupBy: string | undefined = undefined
|
||||||
export let enlargedText = false
|
export let enlargedText = false
|
||||||
export let compression: boolean = false
|
export let compression: boolean = false
|
||||||
|
export let shrink: number = 0
|
||||||
export let space: Ref<Project> | undefined = undefined
|
export let space: Ref<Project> | undefined = undefined
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
@ -72,6 +73,7 @@
|
|||||||
{popupPlaceholder}
|
{popupPlaceholder}
|
||||||
{onlyIcon}
|
{onlyIcon}
|
||||||
{enlargedText}
|
{enlargedText}
|
||||||
|
{shrink}
|
||||||
value={value.component}
|
value={value.component}
|
||||||
short
|
short
|
||||||
onChange={handleComponentIdChanged}
|
onChange={handleComponentIdChanged}
|
||||||
|
@ -47,7 +47,15 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<DocNavLink object={value} {onClick} {disabled} {noUnderline} {inline} component={tracker.component.EditIssue}>
|
<DocNavLink
|
||||||
|
object={value}
|
||||||
|
{onClick}
|
||||||
|
{disabled}
|
||||||
|
{noUnderline}
|
||||||
|
{inline}
|
||||||
|
component={tracker.component.EditIssue}
|
||||||
|
shrink={0}
|
||||||
|
>
|
||||||
<span class="issuePresenterRoot" class:inline class:list={kind === 'list'}>
|
<span class="issuePresenterRoot" class:inline class:list={kind === 'list'}>
|
||||||
{#if !inline && shouldShowAvatar}
|
{#if !inline && shouldShowAvatar}
|
||||||
<div class="icon" use:tooltip={{ label: tracker.string.Issue }}>
|
<div class="icon" use:tooltip={{ label: tracker.string.Issue }}>
|
||||||
|
@ -43,8 +43,7 @@
|
|||||||
Loading,
|
Loading,
|
||||||
showPanel,
|
showPanel,
|
||||||
showPopup,
|
showPopup,
|
||||||
themeStore,
|
themeStore
|
||||||
tooltip
|
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import {
|
import {
|
||||||
AttributeModel,
|
AttributeModel,
|
||||||
@ -389,7 +388,7 @@
|
|||||||
kind={'link-bordered'}
|
kind={'link-bordered'}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
justify={'center'}
|
justify={'center'}
|
||||||
width={''}
|
shrink={1}
|
||||||
bind:onlyIcon={fullFilled[issueId]}
|
bind:onlyIcon={fullFilled[issueId]}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
@ -398,16 +397,16 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if enabledConfig(config, 'labels')}
|
{#if enabledConfig(config, 'labels')}
|
||||||
<div
|
<div class="card-labels labels">
|
||||||
class="card-labels labels"
|
|
||||||
use:tooltip={{
|
|
||||||
component: fullFilled[issueId] ? tags.component.LabelsPresenter : undefined,
|
|
||||||
props: { object: issue, kind: 'full' }
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Component
|
<Component
|
||||||
is={tags.component.LabelsPresenter}
|
is={tags.component.LabelsPresenter}
|
||||||
props={{ value: issue.labels, object: issue, ckeckFilled: fullFilled[issueId], kind: 'kanban' }}
|
props={{
|
||||||
|
value: issue.labels,
|
||||||
|
object: issue,
|
||||||
|
ckeckFilled: fullFilled[issueId],
|
||||||
|
kind: 'link',
|
||||||
|
compression: true
|
||||||
|
}}
|
||||||
on:change={(res) => {
|
on:change={(res) => {
|
||||||
if (res.detail.full) fullFilled[issueId] = true
|
if (res.detail.full) fullFilled[issueId] = true
|
||||||
}}
|
}}
|
||||||
@ -487,6 +486,7 @@
|
|||||||
|
|
||||||
&.labels {
|
&.labels {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
flex-shrink: 1;
|
||||||
margin: 0 1rem;
|
margin: 0 1rem;
|
||||||
width: calc(100% - 2rem);
|
width: calc(100% - 2rem);
|
||||||
border-radius: 0 0.24rem 0.24rem 0;
|
border-radius: 0 0.24rem 0.24rem 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user