Tracker: fix colors for issue status icons (#2203)

Signed-off-by: Sergei Ogorelkov <sergei.ogorelkov@xored.com>
This commit is contained in:
Sergei Ogorelkov 2022-07-05 12:00:54 +07:00 committed by GitHub
parent 26d998a2dd
commit e052aa5e41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 147 additions and 84 deletions

View File

@ -26,6 +26,7 @@
interface ValueType {
id: number | string
icon?: Asset
iconColor?: string
label?: IntlString
text?: string
isSelected?: boolean
@ -118,7 +119,7 @@
{/if}
{#if item.icon}
<div class="mr-2">
<Icon icon={item.icon} {size} />
<Icon icon={item.icon} fill={item.iconColor} {size} />
</div>
{/if}
<span class="label" class:text-base={huge}>

View File

@ -52,21 +52,21 @@
</symbol>
<symbol id="status-backlog" viewBox="0 0 14 14">
<path fill="#bec2c8" d="M13.9408 7.91426L11.9576 7.65557C11.9855 7.4419 12 7.22314 12 7C12 6.77686 11.9855 6.5581 11.9576 6.34443L13.9408 6.08573C13.9799 6.38496 14 6.69013 14 7C14 7.30987 13.9799 7.61504 13.9408 7.91426ZM13.4688 4.32049C13.2328 3.7514 12.9239 3.22019 12.5538 2.73851L10.968 3.95716C11.2328 4.30185 11.4533 4.68119 11.6214 5.08659L13.4688 4.32049ZM11.2615 1.4462L10.0428 3.03204C9.69815 2.76716 9.31881 2.54673 8.91341 2.37862L9.67951 0.531163C10.2486 0.767153 10.7798 1.07605 11.2615 1.4462ZM7.91426 0.0591659L7.65557 2.04237C7.4419 2.01449 7.22314 2 7 2C6.77686 2 6.5581 2.01449 6.34443 2.04237L6.08574 0.059166C6.38496 0.0201343 6.69013 0 7 0C7.30987 0 7.61504 0.0201343 7.91426 0.0591659ZM4.32049 0.531164L5.08659 2.37862C4.68119 2.54673 4.30185 2.76716 3.95716 3.03204L2.73851 1.4462C3.22019 1.07605 3.7514 0.767153 4.32049 0.531164ZM1.4462 2.73851L3.03204 3.95716C2.76716 4.30185 2.54673 4.68119 2.37862 5.08659L0.531164 4.32049C0.767153 3.7514 1.07605 3.22019 1.4462 2.73851ZM0.0591659 6.08574C0.0201343 6.38496 0 6.69013 0 7C0 7.30987 0.0201343 7.61504 0.059166 7.91426L2.04237 7.65557C2.01449 7.4419 2 7.22314 2 7C2 6.77686 2.01449 6.5581 2.04237 6.34443L0.0591659 6.08574ZM0.531164 9.67951L2.37862 8.91341C2.54673 9.31881 2.76716 9.69815 3.03204 10.0428L1.4462 11.2615C1.07605 10.7798 0.767153 10.2486 0.531164 9.67951ZM2.73851 12.5538L3.95716 10.968C4.30185 11.2328 4.68119 11.4533 5.08659 11.6214L4.32049 13.4688C3.7514 13.2328 3.22019 12.9239 2.73851 12.5538ZM6.08574 13.9408L6.34443 11.9576C6.5581 11.9855 6.77686 12 7 12C7.22314 12 7.4419 11.9855 7.65557 11.9576L7.91427 13.9408C7.61504 13.9799 7.30987 14 7 14C6.69013 14 6.38496 13.9799 6.08574 13.9408ZM9.67951 13.4688L8.91341 11.6214C9.31881 11.4533 9.69815 11.2328 10.0428 10.968L11.2615 12.5538C10.7798 12.9239 10.2486 13.2328 9.67951 13.4688ZM12.5538 11.2615L10.968 10.0428C11.2328 9.69815 11.4533 9.31881 11.6214 8.91341L13.4688 9.67951C13.2328 10.2486 12.924 10.7798 12.5538 11.2615Z" />
<path d="M13.9408 7.91426L11.9576 7.65557C11.9855 7.4419 12 7.22314 12 7C12 6.77686 11.9855 6.5581 11.9576 6.34443L13.9408 6.08573C13.9799 6.38496 14 6.69013 14 7C14 7.30987 13.9799 7.61504 13.9408 7.91426ZM13.4688 4.32049C13.2328 3.7514 12.9239 3.22019 12.5538 2.73851L10.968 3.95716C11.2328 4.30185 11.4533 4.68119 11.6214 5.08659L13.4688 4.32049ZM11.2615 1.4462L10.0428 3.03204C9.69815 2.76716 9.31881 2.54673 8.91341 2.37862L9.67951 0.531163C10.2486 0.767153 10.7798 1.07605 11.2615 1.4462ZM7.91426 0.0591659L7.65557 2.04237C7.4419 2.01449 7.22314 2 7 2C6.77686 2 6.5581 2.01449 6.34443 2.04237L6.08574 0.059166C6.38496 0.0201343 6.69013 0 7 0C7.30987 0 7.61504 0.0201343 7.91426 0.0591659ZM4.32049 0.531164L5.08659 2.37862C4.68119 2.54673 4.30185 2.76716 3.95716 3.03204L2.73851 1.4462C3.22019 1.07605 3.7514 0.767153 4.32049 0.531164ZM1.4462 2.73851L3.03204 3.95716C2.76716 4.30185 2.54673 4.68119 2.37862 5.08659L0.531164 4.32049C0.767153 3.7514 1.07605 3.22019 1.4462 2.73851ZM0.0591659 6.08574C0.0201343 6.38496 0 6.69013 0 7C0 7.30987 0.0201343 7.61504 0.059166 7.91426L2.04237 7.65557C2.01449 7.4419 2 7.22314 2 7C2 6.77686 2.01449 6.5581 2.04237 6.34443L0.0591659 6.08574ZM0.531164 9.67951L2.37862 8.91341C2.54673 9.31881 2.76716 9.69815 3.03204 10.0428L1.4462 11.2615C1.07605 10.7798 0.767153 10.2486 0.531164 9.67951ZM2.73851 12.5538L3.95716 10.968C4.30185 11.2328 4.68119 11.4533 5.08659 11.6214L4.32049 13.4688C3.7514 13.2328 3.22019 12.9239 2.73851 12.5538ZM6.08574 13.9408L6.34443 11.9576C6.5581 11.9855 6.77686 12 7 12C7.22314 12 7.4419 11.9855 7.65557 11.9576L7.91427 13.9408C7.61504 13.9799 7.30987 14 7 14C6.69013 14 6.38496 13.9799 6.08574 13.9408ZM9.67951 13.4688L8.91341 11.6214C9.31881 11.4533 9.69815 11.2328 10.0428 10.968L11.2615 12.5538C10.7798 12.9239 10.2486 13.2328 9.67951 13.4688ZM12.5538 11.2615L10.968 10.0428C11.2328 9.69815 11.4533 9.31881 11.6214 8.91341L13.4688 9.67951C13.2328 10.2486 12.924 10.7798 12.5538 11.2615Z" />
</symbol>
<symbol id="status-todo" viewBox="0 0 14 14">
<rect x="1" y="1" width="12" height="12" rx="6" stroke="#e2e2e2" stroke-width="2" fill="none" />
<path fill="#e2e2e2" stroke="none" d="M 3.5,3.5 L3.5,0 A3.5,3.5 0 0,1 3.5, 0 z" transform="translate(3.5,3.5)" />
<path stroke="none" d="M 3.5,3.5 L3.5,0 A3.5,3.5 0 0,1 3.5, 0 z" transform="translate(3.5,3.5)" />
</symbol>
<symbol id="status-inprogress" viewBox="0 0 14 14">
<rect x="1" y="1" width="12" height="12" rx="6" stroke="#f2c94c" stroke-width="2" fill="none" />
<path fill="#f2c94c" stroke="none" d="M 3.5,3.5 L3.5,0 A3.5,3.5 0 0,1 3.5, 7 z" transform="translate(3.5,3.5)" />
<path stroke="none" d="M 3.5,3.5 L3.5,0 A3.5,3.5 0 0,1 3.5, 7 z" transform="translate(3.5,3.5)" />
</symbol>
<symbol id="status-done" viewBox="0 0 14 14">
<path fill="#5e6ad2" stroke="#5e6ad2" d="M9.54541 3.54541L9.89896 3.89896L9.54541 3.54541L5.5 7.59081L4.45459 6.54541C3.92739 6.0182 3.07261 6.0182 2.54541 6.54541C2.0182 7.07261 2.0182 7.92739 2.54541 8.45459L4.54541 10.4546C5.07261 10.9818 5.92739 10.9818 6.45459 10.4546L11.4546 5.45459C11.9818 4.92739 11.9818 4.07261 11.4546 3.54541L11.101 3.89896L11.4546 3.54541C10.9274 3.0182 10.0726 3.0182 9.54541 3.54541ZM0.5 7C0.5 3.41015 3.41015 0.5 7 0.5C10.5899 0.5 13.5 3.41015 13.5 7C13.5 10.5899 10.5899 13.5 7 13.5C3.41015 13.5 0.5 10.5899 0.5 7Z" />
<path stroke="#5e6ad2" d="M9.54541 3.54541L9.89896 3.89896L9.54541 3.54541L5.5 7.59081L4.45459 6.54541C3.92739 6.0182 3.07261 6.0182 2.54541 6.54541C2.0182 7.07261 2.0182 7.92739 2.54541 8.45459L4.54541 10.4546C5.07261 10.9818 5.92739 10.9818 6.45459 10.4546L11.4546 5.45459C11.9818 4.92739 11.9818 4.07261 11.4546 3.54541L11.101 3.89896L11.4546 3.54541C10.9274 3.0182 10.0726 3.0182 9.54541 3.54541ZM0.5 7C0.5 3.41015 3.41015 0.5 7 0.5C10.5899 0.5 13.5 3.41015 13.5 7C13.5 10.5899 10.5899 13.5 7 13.5C3.41015 13.5 0.5 10.5899 0.5 7Z" />
</symbol>
<symbol id="status-canceled" viewBox="0 0 14 14">
<path fill="#95a2b3" fill-rule="evenodd" d="M7 14C10.866 14 14 10.866 14 7C14 3.13401 10.866 0 7 0C3.13401 0 0 3.13401 0 7C0 10.866 3.13401 14 7 14ZM5.03033 3.96967C4.73744 3.67678 4.26256 3.67678 3.96967 3.96967C3.67678 4.26256 3.67678 4.73744 3.96967 5.03033L5.93934 7L3.96967 8.96967C3.67678 9.26256 3.67678 9.73744 3.96967 10.0303C4.26256 10.3232 4.73744 10.3232 5.03033 10.0303L7 8.06066L8.96967 10.0303C9.26256 10.3232 9.73744 10.3232 10.0303 10.0303C10.3232 9.73744 10.3232 9.26256 10.0303 8.96967L8.06066 7L10.0303 5.03033C10.3232 4.73744 10.3232 4.26256 10.0303 3.96967C9.73744 3.67678 9.26256 3.67678 8.96967 3.96967L7 5.93934L5.03033 3.96967Z" />
<path fill-rule="evenodd" d="M7 14C10.866 14 14 10.866 14 7C14 3.13401 10.866 0 7 0C3.13401 0 0 3.13401 0 7C0 10.866 3.13401 14 7 14ZM5.03033 3.96967C4.73744 3.67678 4.26256 3.67678 3.96967 3.96967C3.67678 4.26256 3.67678 4.73744 3.96967 5.03033L5.93934 7L3.96967 8.96967C3.67678 9.26256 3.67678 9.73744 3.96967 10.0303C4.26256 10.3232 4.73744 10.3232 5.03033 10.0303L7 8.06066L8.96967 10.0303C9.26256 10.3232 9.73744 10.3232 10.0303 10.0303C10.3232 9.73744 10.3232 9.26256 10.0303 8.96967L8.06066 7L10.0303 5.03033C10.3232 4.73744 10.3232 4.26256 10.0303 3.96967C9.73744 3.67678 9.26256 3.67678 8.96967 3.96967L7 5.93934L5.03033 3.96967Z" />
</symbol>
<symbol id="priority-nopriority" viewBox="0 0 14 14">

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -3,9 +3,9 @@
import { IntlString } from '@anticrm/platform'
import { ObjectPopup } from '@anticrm/presentation'
import { Issue } from '@anticrm/tracker'
import { Icon } from '@anticrm/ui'
import { getIssueId } from '../issues'
import tracker from '../plugin'
import IssueStatusIcon from './issues/IssueStatusIcon.svelte'
export let docQuery: DocumentQuery<Issue> | undefined = undefined
export let ignoreObjects: Ref<Issue>[] | undefined = undefined
@ -34,13 +34,14 @@
on:close
>
<svelte:fragment slot="item" let:item={issue}>
{@const { icon } = issue.$lookup?.status.$lookup?.category ?? {}}
{@const issueId = getIssueId(issue.$lookup.space, issue)}
{#if issueId && icon}
{#if issueId}
<div class="flex-center clear-mins w-full h-9">
<div class="icon mr-4 h-8">
<Icon {icon} size="small" />
</div>
{#if issue?.$lookup?.status}
<div class="icon mr-4 h-8">
<IssueStatusIcon value={issue.$lookup.status} size="small" />
</div>
{/if}
<span class="overflow-label flex-no-shrink mr-3">{issueId}</span>
<span class="overflow-label w-full issue-title">{issue.title}</span>
</div>

View File

@ -15,11 +15,11 @@
<script lang="ts">
import { AttachedData, FindOptions, Ref, SortingOrder } from '@anticrm/core'
import { getClient, ObjectPopup } from '@anticrm/presentation'
import { calcRank, Issue, IssueStatusCategory } from '@anticrm/tracker'
import { Icon } from '@anticrm/ui'
import { calcRank, Issue } from '@anticrm/tracker'
import { createEventDispatcher } from 'svelte'
import tracker from '../plugin'
import { getIssueId } from '../issues'
import IssueStatusIcon from './issues/IssueStatusIcon.svelte'
export let value: Issue | AttachedData<Issue> | Issue[]
export let width: 'medium' | 'large' | 'full' = 'large'
@ -27,18 +27,13 @@
const client = getClient()
const dispatch = createEventDispatcher()
const options: FindOptions<Issue> = {
lookup: { status: tracker.class.IssueStatus, space: tracker.class.Team },
lookup: {
space: tracker.class.Team,
status: [tracker.class.IssueStatus, { category: tracker.class.IssueStatusCategory }]
},
sort: { modifiedOn: SortingOrder.Descending }
}
let statusCategoryById: Map<string, IssueStatusCategory> | undefined
async function updateIssueStatusCategories () {
const categories = await client.findAll(tracker.class.IssueStatusCategory, {})
statusCategoryById = new Map(categories.map((c) => [c._id, c]))
}
async function onClose ({ detail: parentIssue }: CustomEvent<Issue | undefined | null>) {
const vv = Array.isArray(value) ? value : [value]
for (const docValue of vv) {
@ -83,7 +78,6 @@
]
}
}
$: updateIssueStatusCategories()
</script>
<ObjectPopup
@ -103,13 +97,14 @@
on:close={onClose}
>
<svelte:fragment slot="item" let:item={issue}>
{@const { icon } = statusCategoryById?.get(issue.$lookup?.status.category) ?? {}}
{@const issueId = getIssueId(issue.$lookup.space, issue)}
{#if issueId && icon}
{#if issueId}
<div class="flex-center clear-mins w-full h-9">
<div class="icon mr-4 h-8">
<Icon {icon} size="small" />
</div>
{#if issue?.$lookup?.status}
<div class="icon mr-4 h-8">
<IssueStatusIcon value={issue.$lookup.status} size="small" />
</div>
{/if}
<span class="overflow-label flex-no-shrink mr-3">{issueId}</span>
<span class="overflow-label w-full issue-title">{issue.title}</span>
</div>

View File

@ -18,7 +18,7 @@
import { Kanban, TypeState } from '@anticrm/kanban'
import { createQuery } from '@anticrm/presentation'
import type { Issue, IssueStatus, Team } from '@anticrm/tracker'
import { Button, Icon, IconAdd, showPopup, showPanel, Component } from '@anticrm/ui'
import { Button, Icon, IconAdd, showPopup, showPanel, Component, getPlatformColor } from '@anticrm/ui'
import { focusStore, ListSelectionProvider, SelectDirection, selectionStore } from '@anticrm/view-resources'
import ActionContext from '@anticrm/view-resources/src/components/ActionContext.svelte'
import Menu from '@anticrm/view-resources/src/components/Menu.svelte'
@ -110,7 +110,6 @@
<Kanban
bind:this={kanbanUI}
_class={tracker.class.Issue}
space={currentSpace}
search=""
{states}
{options}
@ -134,7 +133,7 @@
<div class="header flex-col">
<div class="flex-between label font-medium w-full h-full">
<div class="flex-row-center gap-2">
<Icon icon={state.icon} size={'small'} />
<Icon icon={state.icon} fill={getPlatformColor(state.color)} size={'small'} />
<span class="lines-limit-2 ml-2">{state.title}</span>
<span class="counter ml-2 text-md">{count}</span>
</div>

View File

@ -0,0 +1,48 @@
<!--
// Copyright © 2022 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 { WithLookup } from '@anticrm/core'
import { getClient } from '@anticrm/presentation'
import { IssueStatus, IssueStatusCategory } from '@anticrm/tracker'
import { getPlatformColor, Icon, IconSize } from '@anticrm/ui'
import tracker from '../../plugin'
export let value: WithLookup<IssueStatus>
export let size: IconSize
export let fill: string | undefined = undefined
const client = getClient()
let category: IssueStatusCategory | undefined
async function updateCategory (status: WithLookup<IssueStatus>) {
if (status.$lookup?.category) {
category = status.$lookup.category
}
category = await client.findOne(tracker.class.IssueStatusCategory, { _id: value.category })
}
$: updateCategory(value)
$: icon = category?.icon
$: color =
fill ??
(value.color !== undefined ? getPlatformColor(value.color) : undefined) ??
(category !== undefined ? getPlatformColor(category.color) : undefined)
</script>
{#if icon !== undefined && color !== undefined}
<Icon {icon} fill={color} {size} />
{/if}

View File

@ -19,7 +19,7 @@
import notification from '@anticrm/notification'
import { createQuery, getClient } from '@anticrm/presentation'
import { Issue, IssuesGrouping, IssuesOrdering, IssueStatus, Team, ViewOptions } from '@anticrm/tracker'
import { Button, Component, Icon, IconAdd, showPanel, showPopup } from '@anticrm/ui'
import { Button, Component, Icon, IconAdd, showPanel, showPopup, getPlatformColor } from '@anticrm/ui'
import { focusStore, ListSelectionProvider, SelectDirection, selectionStore } from '@anticrm/view-resources'
import ActionContext from '@anticrm/view-resources/src/components/ActionContext.svelte'
import Menu from '@anticrm/view-resources/src/components/Menu.svelte'
@ -139,7 +139,7 @@
<div class="header flex-col">
<div class="flex-between label font-medium w-full h-full">
<div class="flex-row-center gap-2">
<Icon icon={state.icon} size={'small'} />
<Icon icon={state.icon} fill={getPlatformColor(state.color)} size={'small'} />
<span class="lines-limit-2 ml-2">{state.title}</span>
<span class="counter ml-2 text-md">{count}</span>
</div>

View File

@ -17,9 +17,10 @@
import { AttachedData, Ref, SortingOrder, WithLookup } from '@anticrm/core'
import { Issue, IssueStatus } from '@anticrm/tracker'
import { createQuery, getClient } from '@anticrm/presentation'
import { Button, showPopup, SelectPopup, TooltipAlignment, eventToHTMLElement, Icon } from '@anticrm/ui'
import { Button, showPopup, SelectPopup, TooltipAlignment, eventToHTMLElement, getPlatformColor } from '@anticrm/ui'
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
import tracker from '../../plugin'
import IssueStatusIcon from './IssueStatusIcon.svelte'
export let value: Issue | AttachedData<Issue>
export let statuses: WithLookup<IssueStatus>[] | undefined = undefined
@ -62,9 +63,17 @@
}
$: selectedStatus = statuses?.find((status) => status._id === value.status) ?? statuses?.[0]
$: selectedStatusIcon = selectedStatus?.$lookup?.category?.icon
$: selectedStatusLabel = shouldShowLabel ? selectedStatus?.name : undefined
$: statusesInfo = statuses?.map((s) => ({ id: s._id, text: s.name, color: s.color, icon: s.$lookup?.category?.icon }))
$: statusesInfo = statuses?.map((s) => {
const color = s.color ?? s.$lookup?.category?.color
return {
id: s._id,
text: s.name,
icon: s.$lookup?.category?.icon,
...(color !== undefined ? { iconColor: getPlatformColor(color) } : undefined)
}
})
$: if (!statuses) {
const query = '_id' in value ? { attachedTo: value.space } : {}
statusesQuery.query(
@ -85,7 +94,7 @@
{#if kind === 'list'}
<div class="flex-row-center flex-no-shrink" class:cursor-pointer={isEditable} on:click={handleStatusEditorOpened}>
<div class="flex-center flex-no-shrink square-4">
{#if selectedStatusIcon}<Icon icon={selectedStatusIcon} size={'inline'} />{/if}
{#if selectedStatus}<IssueStatusIcon value={selectedStatus} size="inline" />{/if}
</div>
{#if selectedStatusLabel}
<span class="ml-2 overflow-label disabled text-md fs-bold content-accent-color">
@ -93,10 +102,9 @@
</span>
{/if}
</div>
{:else if selectedStatusLabel}
{:else}
<Button
showTooltip={isEditable ? { label: tracker.string.SetStatus, direction: tooltipAlignment } : undefined}
icon={selectedStatusIcon}
disabled={!isEditable}
{justify}
{size}
@ -104,18 +112,14 @@
{width}
on:click={handleStatusEditorOpened}
>
<span slot="content" class="overflow-label disabled">{selectedStatusLabel}</span>
<span slot="content" class="inline-flex">
{#if selectedStatus}
<IssueStatusIcon value={selectedStatus} size="inline" />
{/if}
{#if selectedStatusLabel}
<span class="overflow-label disabled" class:ml-1={selectedStatus}>{selectedStatusLabel}</span>
{/if}
</span>
</Button>
{:else}
<Button
showTooltip={isEditable ? { label: tracker.string.SetStatus, direction: tooltipAlignment } : undefined}
icon={selectedStatusIcon}
disabled={!isEditable}
{justify}
{size}
{kind}
{width}
on:click={handleStatusEditorOpened}
/>
{/if}
{/if}

View File

@ -15,7 +15,7 @@
<script lang="ts">
import { WithLookup } from '@anticrm/core'
import { IssueStatus } from '@anticrm/tracker'
import { Icon } from '@anticrm/ui'
import IssueStatusIcon from './IssueStatusIcon.svelte'
export let value: WithLookup<IssueStatus> | undefined
</script>
@ -23,7 +23,7 @@
{#if value}
<div class="flex-presenter">
{#if value.$lookup?.category?.icon}
<Icon icon={value.$lookup?.category?.icon} size={'medium'} />
<IssueStatusIcon {value} size="medium" />
{/if}
<span class="overflow-label" class:ml-2={value.$lookup?.category?.icon !== undefined}>
{value.name}

View File

@ -212,7 +212,7 @@
{#if parentIssue}
<div class="mb-6">
{#if currentTeam && issueStatuses}
<SubIssueSelector {issue} {issueStatuses} team={currentTeam} />
<SubIssueSelector {issue} />
{:else}
<Spinner />
{/if}
@ -255,7 +255,7 @@
{#if parentIssue}
<div class="mb-6">
{#if currentTeam && issueStatuses}
<SubIssueSelector {issue} {issueStatuses} team={currentTeam} />
<SubIssueSelector {issue} />
{:else}
<Spinner />
{/if}

View File

@ -15,7 +15,7 @@
<script lang="ts">
import { Ref, SortingOrder, WithLookup } from '@anticrm/core'
import { createQuery } from '@anticrm/presentation'
import { Team, Issue, IssueStatus } from '@anticrm/tracker'
import { Issue, IssueStatus } from '@anticrm/tracker'
import {
Icon,
tooltip,
@ -25,24 +25,20 @@
showPopup,
SelectPopup,
closeTooltip,
Spinner
Spinner,
getPlatformColor
} from '@anticrm/ui'
import tracker from '../../../plugin'
import { getIssueId } from '../../../issues'
import IssueStatusIcon from '../IssueStatusIcon.svelte'
export let issue: WithLookup<Issue>
export let team: Team
export let issueStatuses: WithLookup<IssueStatus>[]
const subIssuesQeury = createQuery()
let subIssues: Issue[] | undefined
let subIssues: WithLookup<Issue>[] | undefined
let subIssuesElement: Element
function getIssueStatusIcon (issue: Issue) {
return issueStatuses.find((s) => issue.status === s._id)?.$lookup?.category?.icon ?? null
}
function openIssue (target: Ref<Issue>) {
if (target !== issue._id) {
showPanel(tracker.component.EditIssue, target, issue._class, 'content')
@ -62,12 +58,20 @@
showPopup(
SelectPopup,
{
value: subIssues.map((iss) => ({
id: iss._id,
icon: getIssueStatusIcon(iss),
text: `${getIssueId(team, iss)} ${iss.title}`,
isSelected: iss._id === issue._id
})),
value: subIssues.map((iss) => {
const team = iss.$lookup?.space
const status = iss.$lookup?.status as WithLookup<IssueStatus>
const icon = status.$lookup?.category?.icon
const color = status.color ?? status.$lookup?.category?.color
return {
id: iss._id,
icon,
isSelected: iss._id === issue._id,
...(team !== undefined ? { text: `${getIssueId(team, iss)} ${iss.title}` } : undefined),
...(color !== undefined ? { iconColor: getPlatformColor(color) } : undefined)
}
}),
width: 'large'
},
{
@ -91,7 +95,13 @@
tracker.class.Issue,
{ space: issue.space, attachedTo: parentIssue._id },
(res) => (subIssues = res),
{ sort: { modifiedOn: SortingOrder.Descending } }
{
sort: { modifiedOn: SortingOrder.Descending },
lookup: {
space: tracker.class.Team,
status: [tracker.class.IssueStatus, { category: tracker.class.IssueStatusCategory }]
}
}
)
} else {
subIssuesQeury.unsubscribe()
@ -99,7 +109,6 @@
</script>
{#if parentIssue}
{@const icon = getIssueStatusIcon(issue)}
<div class="flex root">
<div class="item clear-mins">
<div
@ -107,12 +116,14 @@
use:tooltip={{ label: tracker.string.OpenParent, direction: 'bottom' }}
on:click={openParentIssue}
>
{#if icon}
{#if issue?.$lookup?.status}
<div class="pr-2">
<Icon {icon} size="small" />
<IssueStatusIcon value={issue.$lookup.status} size="small" />
</div>
{/if}
<span class="overflow-label flex-no-shrink mr-2">{getIssueId(team, parentIssue)}</span>
{#if issue.$lookup?.space}
<span class="overflow-label flex-no-shrink mr-2">{getIssueId(issue.$lookup.space, parentIssue)}</span>
{/if}
<span class="overflow-label issue-title">{parentIssue.title}</span>
</div>
</div>

View File

@ -15,7 +15,7 @@
<script lang="ts">
import { Doc, Ref, WithLookup } from '@anticrm/core'
import { Issue, IssueStatus, Team } from '@anticrm/tracker'
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
import { ButtonKind, ButtonSize, getPlatformColor } from '@anticrm/ui'
import { Button, closeTooltip, ProgressCircle, SelectPopup, showPanel, showPopup } from '@anticrm/ui'
import { updateFocus } from '@anticrm/view-resources'
import tracker from '../../../plugin'
@ -47,7 +47,14 @@
$: hasSubIssues = (subIssues?.length ?? 0) > 0
function getIssueStatusIcon (issue: Issue) {
return issueStatuses?.find((s) => issue.status === s._id)?.$lookup?.category?.icon ?? null
const status = issueStatuses?.find((s) => issue.status === s._id)
const category = status?.$lookup?.category
const color = status?.color ?? category?.color
return {
...(category?.icon !== undefined ? { icon: category.icon } : {}),
...(color !== undefined ? { iconColor: getPlatformColor(color) } : {})
}
}
function openIssue (target: Ref<Issue>) {
@ -64,7 +71,7 @@
value: subIssues.map((iss) => {
const text = currentTeam ? `${getIssueId(currentTeam, iss)} ${iss.title}` : iss.title
return { id: iss._id, icon: getIssueStatusIcon(iss), text, isSelected: iss._id === issue._id }
return { id: iss._id, text, isSelected: iss._id === issue._id, ...getIssueStatusIcon(iss) }
}),
width: 'large'
},
@ -83,7 +90,6 @@
(selectedIssue) => {
const focus = subIssues?.find((it) => it._id === selectedIssue.id)
if (focus !== undefined) {
console.log('ISE', selectedIssue, focus)
updateFocus({ focus })
}
}

View File

@ -14,14 +14,13 @@
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Asset } from '@anticrm/platform'
import { IssueStatus } from '@anticrm/tracker'
import { Icon, Label, IconEdit, IconClose, tooltip } from '@anticrm/ui'
import tracker from '../../plugin'
import Circles from '../icons/Circles.svelte'
import IssueStatusIcon from '../issues/IssueStatusIcon.svelte'
export let value: IssueStatus
export let icon: Asset
export let isDefault = false
export let isSingle = true
@ -38,7 +37,7 @@
<Circles />
</div>
<div class="flex-no-shrink ml-2">
<Icon {icon} size="small" />
<IssueStatusIcon {value} size="small" />
</div>
<span class="content-accent-color ml-2">{value.name}</span>
{#if value.description}

View File

@ -287,7 +287,6 @@
{:else}
<StatusPresenter
value={status}
icon={category.icon}
isDefault={status._id === team.defaultIssueStatus}
{isSingle}
on:default-update={({ detail }) => updateTeamDefaultStatus(detail)}