Activity icons (#2955)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2023-04-12 14:21:49 +06:00 committed by GitHub
parent 981cbada6a
commit 9c1db9dc5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 107 additions and 62 deletions

View File

@ -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

View File

@ -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,

View File

@ -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" />

View File

@ -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 (

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -22,7 +22,7 @@
</script>
{#if value}
<div class="flex-presenter">
<div class="flex-presenter cursor-default">
{#if !inline}
<IssueStatusIcon {value} {size} />
{/if}

View File

@ -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,