From 9c1db9dc5bef1cbc15fd04d69406e1d5ebe2415a Mon Sep 17 00:00:00 2001 From: Denis Bykhov <bykhov.denis@gmail.com> Date: Wed, 12 Apr 2023 14:21:49 +0600 Subject: [PATCH] Activity icons (#2955) Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com> --- models/tracker/src/index.ts | 9 ++- models/tracker/src/plugin.ts | 4 +- .../src/components/TxView.svelte | 7 +- plugins/activity-resources/src/utils.ts | 14 ++-- .../components/activity/PriorityIcon.svelte | 31 +++++++++ .../src/components/activity/StatusIcon.svelte | 31 +++++++++ .../issues/PriorityRefPresenter.svelte | 65 ++++--------------- .../components/issues/StatusPresenter.svelte | 2 +- plugins/tracker-resources/src/index.ts | 6 +- 9 files changed, 107 insertions(+), 62 deletions(-) create mode 100644 plugins/tracker-resources/src/components/activity/PriorityIcon.svelte create mode 100644 plugins/tracker-resources/src/components/activity/StatusIcon.svelte diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index da9b04001b..83e3768585 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -181,11 +181,16 @@ export class TIssue extends TAttachedDoc implements Issue { @Index(IndexKind.FullText) description!: Markup - @Prop(TypeRef(tracker.class.IssueStatus), tracker.string.Status, { _id: tracker.attribute.IssueStatus }) + @Prop(TypeRef(tracker.class.IssueStatus), tracker.string.Status, { + _id: tracker.attribute.IssueStatus, + iconComponent: tracker.activity.StatusIcon + }) @Index(IndexKind.Indexed) status!: Ref<IssueStatus> - @Prop(TypeIssuePriority(), tracker.string.Priority) + @Prop(TypeIssuePriority(), tracker.string.Priority, { + iconComponent: tracker.activity.PriorityIcon + }) @Index(IndexKind.Indexed) priority!: IssuePriority diff --git a/models/tracker/src/plugin.ts b/models/tracker/src/plugin.ts index b2a497a52a..c10b96b072 100644 --- a/models/tracker/src/plugin.ts +++ b/models/tracker/src/plugin.ts @@ -39,7 +39,9 @@ export default mergeIds(trackerId, tracker, { CreatedOn: '' as IntlString }, activity: { - TxIssueCreated: '' as AnyComponent + TxIssueCreated: '' as AnyComponent, + StatusIcon: '' as AnyComponent, + PriorityIcon: '' as AnyComponent }, component: { SprintSelector: '' as AnyComponent, diff --git a/plugins/activity-resources/src/components/TxView.svelte b/plugins/activity-resources/src/components/TxView.svelte index 49441d9c3a..338a4ddd43 100644 --- a/plugins/activity-resources/src/components/TxView.svelte +++ b/plugins/activity-resources/src/components/TxView.svelte @@ -21,6 +21,7 @@ import { createQuery, getClient } from '@hcengineering/presentation' import { ActionIcon, + AnyComponent, Component, Icon, IconEdit, @@ -56,6 +57,7 @@ let employee: Employee | undefined let model: AttributeModel[] = [] let modelIcon: Asset | undefined = undefined + let iconComponent: AnyComponent | undefined = undefined let edit = false @@ -83,6 +85,7 @@ viewlet = result.viewlet model = result.model modelIcon = result.modelIcon + iconComponent = result.iconComponent props = getProps(result.props, edit) } }) @@ -172,7 +175,9 @@ </div> {:else} <div class="msgactivity-icon"> - {#if viewlet} + {#if iconComponent} + <Component is={iconComponent} {props} /> + {:else if viewlet} <Icon icon={viewlet.icon} size="small" /> {:else if viewlet === undefined && model.length > 0} <Icon icon={modelIcon !== undefined ? modelIcon : Edit} size="small" /> diff --git a/plugins/activity-resources/src/utils.ts b/plugins/activity-resources/src/utils.ts index bf0552a760..de44544add 100644 --- a/plugins/activity-resources/src/utils.ts +++ b/plugins/activity-resources/src/utils.ts @@ -99,17 +99,17 @@ export async function updateViewlet ( model: AttributeModel[] props: any modelIcon: Asset | undefined + iconComponent: AnyComponent | undefined }> { let viewlet = getViewlet(viewlets, dtx) - let props = getDTxProps(dtx) + const props = getDTxProps(dtx) let model: AttributeModel[] = [] let modelIcon: Asset | undefined + let iconComponent: AnyComponent | undefined if (viewlet === undefined) { ;({ viewlet, model } = await checkInlineViewlets(dtx, viewlet, client, model)) - // Only value is necessary for inline viewlets - props = { value: dtx.doc } if (model !== undefined) { // Check for State attribute for (const a of model) { @@ -118,9 +118,15 @@ export async function updateViewlet ( break } } + for (const a of model) { + if (a.attribute?.iconComponent !== undefined) { + iconComponent = a.attribute?.iconComponent + break + } + } } } - return { viewlet, id: dtx.tx._id, model, props, modelIcon } + return { viewlet, id: dtx.tx._id, model, props, modelIcon, iconComponent } } async function checkInlineViewlets ( diff --git a/plugins/tracker-resources/src/components/activity/PriorityIcon.svelte b/plugins/tracker-resources/src/components/activity/PriorityIcon.svelte new file mode 100644 index 0000000000..97fad4f956 --- /dev/null +++ b/plugins/tracker-resources/src/components/activity/PriorityIcon.svelte @@ -0,0 +1,31 @@ +<!-- +// 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 { TxUpdateDoc } from '@hcengineering/core' + import { Asset } from '@hcengineering/platform' + import { Issue } from '@hcengineering/tracker' + import { Icon } from '@hcengineering/ui' + import { issuePriorities } from '../../utils' + + export let tx: TxUpdateDoc<Issue> + $: value = tx.operations.priority + + let icon: Asset + $: if (value !== undefined) ({ icon } = issuePriorities[value]) +</script> + +<div class="icon"> + <Icon {icon} size={'small'} /> +</div> diff --git a/plugins/tracker-resources/src/components/activity/StatusIcon.svelte b/plugins/tracker-resources/src/components/activity/StatusIcon.svelte new file mode 100644 index 0000000000..3a227d61e8 --- /dev/null +++ b/plugins/tracker-resources/src/components/activity/StatusIcon.svelte @@ -0,0 +1,31 @@ +<!-- +// 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 { TxUpdateDoc } from '@hcengineering/core' + import { statusStore } from '@hcengineering/presentation' + import { Issue } from '@hcengineering/tracker' + import IssueStatusIcon from '../issues/IssueStatusIcon.svelte' + + export let tx: TxUpdateDoc<Issue> + $: value = tx.operations.status + + $: status = value && $statusStore.byId.get(value) +</script> + +<div class="icon"> + {#if status} + <IssueStatusIcon value={status} size="small" /> + {/if} +</div> diff --git a/plugins/tracker-resources/src/components/issues/PriorityRefPresenter.svelte b/plugins/tracker-resources/src/components/issues/PriorityRefPresenter.svelte index 72ed7e7e8d..d3cbc2b07e 100644 --- a/plugins/tracker-resources/src/components/issues/PriorityRefPresenter.svelte +++ b/plugins/tracker-resources/src/components/issues/PriorityRefPresenter.svelte @@ -14,61 +14,22 @@ --> <script lang="ts"> import { IssuePriority } from '@hcengineering/tracker' - import { Button, ButtonKind, ButtonSize, Icon, Label } from '@hcengineering/ui' + import { Icon, Label } from '@hcengineering/ui' import { issuePriorities } from '../../utils' export let value: IssuePriority + export let size: 'small' | 'medium' = 'small' + export let inline: boolean = false - export let kind: ButtonKind = 'link' - export let size: ButtonSize = 'large' - export let justify: 'left' | 'center' = 'left' - export let width: string | undefined = undefined + $: icon = issuePriorities[value]?.icon + $: label = issuePriorities[value]?.label </script> -{#if kind === 'list' || kind === 'list-header'} - <div class="priority-container"> - <div class="icon"> - {#if issuePriorities[value]?.icon}<Icon icon={issuePriorities[value]?.icon} {size} />{/if} - </div> - <span - class="{kind === 'list' ? 'ml-2 text-md' : 'ml-3 text-base'} overflow-label disabled fs-bold content-accent-color" - > - <Label label={issuePriorities[value]?.label} /> - </span> - </div> -{:else} - <Button - label={issuePriorities[value]?.label} - icon={issuePriorities[value]?.icon} - {justify} - {width} - {size} - {kind} - disabled - /> -{/if} - -<style lang="scss"> - .priority-container { - display: flex; - align-items: center; - flex-shrink: 0; - min-width: 0; - cursor: pointer; - - .icon { - display: flex; - justify-content: center; - align-items: center; - flex-shrink: 0; - width: 1rem; - height: 1rem; - color: var(--content-color); - } - &:hover { - .icon { - color: var(--caption-color) !important; - } - } - } -</style> +<div class="flex-presenter cursor-default"> + {#if !inline && icon} + <Icon {icon} {size} /> + {/if} + <span class="overflow-label" class:ml-2={!inline && icon}> + <Label {label} /> + </span> +</div> diff --git a/plugins/tracker-resources/src/components/issues/StatusPresenter.svelte b/plugins/tracker-resources/src/components/issues/StatusPresenter.svelte index 4c96461e35..40927657f8 100644 --- a/plugins/tracker-resources/src/components/issues/StatusPresenter.svelte +++ b/plugins/tracker-resources/src/components/issues/StatusPresenter.svelte @@ -22,7 +22,7 @@ </script> {#if value} - <div class="flex-presenter"> + <div class="flex-presenter cursor-default"> {#if !inline} <IssueStatusIcon {value} {size} /> {/if} diff --git a/plugins/tracker-resources/src/index.ts b/plugins/tracker-resources/src/index.ts index 413b980ed4..a8523cc887 100644 --- a/plugins/tracker-resources/src/index.ts +++ b/plugins/tracker-resources/src/index.ts @@ -134,6 +134,8 @@ import MoveIssues from './components/issues/Move.svelte' import IssueStatistics from './components/sprints/IssueStatistics.svelte' import SprintRefPresenter from './components/sprints/SprintRefPresenter.svelte' import TxIssueCreated from './components/activity/TxIssueCreated.svelte' +import PriorityIcon from './components/activity/PriorityIcon.svelte' +import StatusIcon from './components/activity/StatusIcon.svelte' export { default as SubIssueList } from './components/issues/edit/SubIssueList.svelte' @@ -352,7 +354,9 @@ export async function handleRecordingScrum ( export default async (): Promise<Resources> => ({ activity: { - TxIssueCreated + TxIssueCreated, + PriorityIcon, + StatusIcon }, component: { NopeComponent,