UBERF-5348: Fix new status creation (#4567)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-02-07 22:08:15 +07:00 committed by GitHub
parent 0d884fa93d
commit 6e67c57035
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 144 additions and 198 deletions

View File

@ -13,12 +13,12 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { createEventDispatcher, ComponentType } from 'svelte'
import type { Asset, IntlString } from '@hcengineering/platform' import type { Asset, IntlString } from '@hcengineering/platform'
import { deepEqual } from 'fast-equals' import { deepEqual } from 'fast-equals'
import { ComponentType, createEventDispatcher } from 'svelte'
import { closePopup, showPopup } from '..'
import { AnySvelteComponent, DropdownIntlItem } from '../types' import { AnySvelteComponent, DropdownIntlItem } from '../types'
import ButtonBase from './ButtonBase.svelte' import ButtonBase from './ButtonBase.svelte'
import { showPopup, closePopup, eventToHTMLElement } from '..'
import ModernPopup from './ModernPopup.svelte' import ModernPopup from './ModernPopup.svelte'
export let title: string | undefined = undefined export let title: string | undefined = undefined

View File

@ -18,6 +18,7 @@
import plugin from '../plugin' import plugin from '../plugin'
export let embedded = false export let embedded = false
export let selected: string | undefined
interface Category { interface Category {
id: string id: string
@ -179,7 +180,9 @@
{#if emoji !== undefined} {#if emoji !== undefined}
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div class="element" on:click={() => dispatch('close', emoji)}>{emoji}</div> <div class="element" class:selected={emoji === selected} on:click={() => dispatch('close', emoji)}>
{emoji}
</div>
{/if} {/if}
{/each} {/each}
</div> </div>
@ -250,6 +253,7 @@
&.selected { &.selected {
background-color: var(--theme-popup-header); background-color: var(--theme-popup-header);
border: 1px solid var(--theme-popup-divider);
} }
} }
</style> </style>

View File

@ -13,31 +13,30 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { Asset, Metadata, getEmbeddedLabel } from '@hcengineering/platform' import core, { Attribute, Class, Ref, Status, StatusCategory } from '@hcengineering/core'
import { Attribute, Class, Ref, Status, StatusCategory } from '@hcengineering/core' import { Asset, getEmbeddedLabel } from '@hcengineering/platform'
import presentation, { getClient } from '@hcengineering/presentation' import presentation, { getClient } from '@hcengineering/presentation'
import { clearSettingsStore } from '@hcengineering/setting-resources'
import { ProjectType, TaskType, calculateStatuses, createState } from '@hcengineering/task' import { ProjectType, TaskType, calculateStatuses, createState } from '@hcengineering/task'
import { import {
ModernEditbox, ButtonIcon,
getColorNumberByText,
Modal,
Label,
ButtonMenu, ButtonMenu,
EmojiPopup,
IconCopy,
IconDelete,
IconSettings, IconSettings,
IconWithEmoji,
Label,
Modal,
ModernEditbox,
TextArea, TextArea,
getPlatformColorDef, getPlatformColorDef,
themeStore, themeStore
EmojiPopup,
ButtonIcon,
IconDelete,
IconCopy
} from '@hcengineering/ui' } from '@hcengineering/ui'
import { statusStore, ColorsPopup } from '@hcengineering/view-resources' import { ColorsPopup, statusStore } from '@hcengineering/view-resources'
import view from '@hcengineering/view-resources/src/plugin' import view from '@hcengineering/view-resources/src/plugin'
import { clearSettingsStore } from '@hcengineering/setting-resources'
import task from '../plugin'
import { taskTypeStore } from '..' import { taskTypeStore } from '..'
import IconLink from './icons/Link.svelte' import task from '../plugin'
export let status: Status | undefined = undefined export let status: Status | undefined = undefined
export let _class: Ref<Class<Status>> | undefined = status?._class export let _class: Ref<Class<Status>> | undefined = status?._class
@ -49,13 +48,19 @@
export let color: number | undefined = undefined export let color: number | undefined = undefined
export let icons: Asset[] export let icons: Asset[]
export let iconWithEmoji: Asset = view.ids.IconWithEmoji export let iconWithEmoji: Asset = view.ids.IconWithEmoji
export let icon: Asset | undefined
const client = getClient() const client = getClient()
let description: string | undefined = status?.description let description: string | undefined = status?.description
$: allowEditCategory = status === undefined
$: needUpdate = $: needUpdate =
(status?.name.trim() !== value.trim() || description !== status?.description || color !== status?.color) && (status === undefined ||
status.name.trim() !== value.trim() ||
description !== status?.description ||
color !== status.color) &&
value.trim() !== '' value.trim() !== ''
async function save (): Promise<void> { async function save (): Promise<void> {
@ -73,6 +78,13 @@
const lastIndex = states.findLastIndex((p) => p.category === category) const lastIndex = states.findLastIndex((p) => p.category === category)
const statuses = [...taskType.statuses.slice(0, lastIndex + 1), _id, ...taskType.statuses.slice(lastIndex + 1)] const statuses = [...taskType.statuses.slice(0, lastIndex + 1), _id, ...taskType.statuses.slice(lastIndex + 1)]
type.statuses.push({
_id,
color,
icon,
taskType: taskType._id
})
await client.update(type, { await client.update(type, {
statuses: calculateStatuses(type, $taskTypeStore, [{ taskTypeId: taskType._id, statuses }]) statuses: calculateStatuses(type, $taskTypeStore, [{ taskTypeId: taskType._id, statuses }])
}) })
@ -89,35 +101,42 @@
}) })
const index = taskType.statuses.indexOf(status._id) const index = taskType.statuses.indexOf(status._id)
const statuses = [...taskType.statuses.slice(0, index), _id, ...taskType.statuses.slice(index + 1)] const statuses = [...taskType.statuses.slice(0, index), _id, ...taskType.statuses.slice(index + 1)]
for (const status of type.statuses) {
if (status._id === _id) {
status.color = color
status.icon = icon as any // Fix me
}
}
await client.update(type, { await client.update(type, {
statuses: calculateStatuses(type, $taskTypeStore, [{ taskTypeId: taskType._id, statuses }]) statuses: calculateStatuses(type, $taskTypeStore, [{ taskTypeId: taskType._id, statuses }])
}) })
await client.update(taskType, { await client.update(taskType, {
statuses statuses
}) })
const projects = await client.findAll(task.class.Project, { type: type._id }) if (status._id !== _id) {
while (true) { const projects = await client.findAll(task.class.Project, { type: type._id })
const docs = await client.findAll( while (true) {
task.class.Task, const docs = await client.findAll(
{ task.class.Task,
status: status._id, {
space: { $in: projects.map((p) => p._id) } status: status._id,
}, space: { $in: projects.map((p) => p._id) }
{ limit: 1000 } },
) { limit: 1000 }
if (docs.length === 0) { )
break if (docs.length === 0) {
} break
}
const op = client.apply(_id) const op = client.apply(_id)
docs.map((p) => op.update(p, { status: _id })) docs.map((p) => op.update(p, { status: _id }))
await op.commit() await op.commit()
}
} }
} }
clearSettingsStore()
} }
let selected: number = 0 let selected: number = icon === iconWithEmoji ? 1 : 0
const items = [ const items = [
{ {
id: 'color', id: 'color',
@ -128,12 +147,22 @@
label: view.string.EmojiCategory label: view.string.EmojiCategory
} }
] ]
$: allCategories = getClient()
.getModel()
.findAllSync(core.class.StatusCategory, { _id: { $in: taskType.statusCategories } })
$: categories = allCategories.map((it) => ({
id: it._id,
label: it.label,
icon: it.icon
}))
</script> </script>
<Modal <Modal
label={task.string.StatusPopupTitle} label={task.string.StatusPopupTitle}
type={'type-aside'} type={'type-aside'}
okLabel={presentation.string.Save} okLabel={status === undefined ? presentation.string.Create : presentation.string.Save}
okAction={save} okAction={save}
canSave={needUpdate} canSave={needUpdate}
onCancel={() => { onCancel={() => {
@ -157,28 +186,19 @@
</div> </div>
<div class="hulyModal-content__settingsSet"> <div class="hulyModal-content__settingsSet">
<div class="hulyModal-content__settingsSet-line"> <div class="hulyModal-content__settingsSet-line">
<span class="label"><Label label={task.string.Group} /></span> <span class="label"><Label label={getEmbeddedLabel('Status Category')} /></span>
<!-- <ButtonMenu <ButtonMenu
{items} items={categories}
{selected} selected={category}
icon={IconLink} disabled={!allowEditCategory}
label={getEmbeddedLabel('Compeletd')} icon={categories.find((it) => it.id === category)?.icon}
label={categories.find((it) => it.id === category)?.label}
kind={'secondary'} kind={'secondary'}
size={'medium'} size={'medium'}
on:selected={() => {}} on:selected={(it) => {
/> --> category = it.detail
</div> }}
<div class="hulyModal-content__settingsSet-line"> />
<span class="label"><Label label={task.string.Type} /></span>
<!-- <ButtonMenu
{items}
{selected}
icon={IconLink}
label={getEmbeddedLabel('Success')}
kind={'secondary'}
size={'medium'}
on:selected={() => {}}
/> -->
</div> </div>
</div> </div>
<div class="hulyModal-content__settingsSet table"> <div class="hulyModal-content__settingsSet table">
@ -192,9 +212,17 @@
kind={'secondary'} kind={'secondary'}
size={'small'} size={'small'}
on:selected={(event) => { on:selected={(event) => {
if (event.detail) selected = items.findIndex((it) => it.id === event.detail) if (event.detail) {
selected = items.findIndex((it) => it.id === event.detail)
if (selected === 1) {
icon = undefined
}
}
}} }}
/> />
{#if icon === iconWithEmoji}
<IconWithEmoji icon={color ?? 0} size={'medium'} />
{/if}
</div> </div>
<div class="hulyTableAttr-content" class:mb-2={selected === 1}> <div class="hulyTableAttr-content" class:mb-2={selected === 1}>
{#if selected === 0} {#if selected === 0}
@ -204,13 +232,16 @@
columns={'auto'} columns={'auto'}
on:close={(evt) => { on:close={(evt) => {
color = evt.detail color = evt.detail
icon = undefined
}} }}
/> />
{:else} {:else}
<EmojiPopup <EmojiPopup
embedded embedded
selected={String.fromCodePoint(color ?? 0)}
on:close={(evt) => { on:close={(evt) => {
color = evt.detail.codePointAt(0) color = evt.detail.codePointAt(0)
icon = iconWithEmoji
}} }}
/> />
{/if} {/if}

View File

@ -15,6 +15,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import core, { IdMap, Ref, Status, StatusCategory } from '@hcengineering/core' import core, { IdMap, Ref, Status, StatusCategory } from '@hcengineering/core'
import { Asset } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import task, { Project, ProjectType, TaskType } from '@hcengineering/task' import task, { Project, ProjectType, TaskType } from '@hcengineering/task'
import { import {
@ -31,10 +32,10 @@
import { createEventDispatcher, onMount } from 'svelte' import { createEventDispatcher, onMount } from 'svelte'
import { typeStore } from '../..' import { typeStore } from '../..'
import IconBacklog from '../icons/IconBacklog.svelte' import IconBacklog from '../icons/IconBacklog.svelte'
import IconUnstarted from '../icons/IconUnstarted.svelte'
import IconCanceled from '../icons/IconCanceled.svelte' import IconCanceled from '../icons/IconCanceled.svelte'
import IconCompleted from '../icons/IconCompleted.svelte' import IconCompleted from '../icons/IconCompleted.svelte'
import IconStarted from '../icons/IconStarted.svelte' import IconStarted from '../icons/IconStarted.svelte'
import IconUnstarted from '../icons/IconUnstarted.svelte'
export let value: Status | undefined export let value: Status | undefined
export let shouldShowAvatar = true export let shouldShowAvatar = true
@ -80,20 +81,10 @@
$: projectState = type?.statuses.find((p) => p._id === value?._id) $: projectState = type?.statuses.find((p) => p._id === value?._id)
const dispatchAccentColor = (color?: ColorDefinition): void => {
dispatch('accent-color', color)
}
$: color = getPlatformColorDef( $: color = getPlatformColorDef(
projectState?.color ?? category?.color ?? getColorNumberByText(value?.name ?? ''), projectState?.color ?? category?.color ?? getColorNumberByText(value?.name ?? ''),
$themeStore.dark $themeStore.dark
) )
$: dispatchAccentColor(color)
onMount(() => {
dispatchAccentColor(color)
})
$: void updateCategory(value) $: void updateCategory(value)
async function updateCategory (value: Status | undefined): Promise<void> { async function updateCategory (value: Status | undefined): Promise<void> {
@ -119,8 +110,21 @@
) )
$: index = sameCategory.findIndex((it) => it._id === value?._id) + 1 $: index = sameCategory.findIndex((it) => it._id === value?._id) + 1
$: icon = projectState?.icon === view.ids.IconWithEmoji ? IconWithEmoji : projectState?.icon $: icon = projectState?.icon === view.ids.IconWithEmoji ? IconWithEmoji : projectState?.icon
const dispatchAccentColor = (color?: ColorDefinition, icon?: Asset | typeof IconWithEmoji): void => {
if (icon === undefined) {
dispatch('accent-color', color)
} else {
dispatch('accent-color', null)
}
}
$: dispatchAccentColor(color, icon)
onMount(() => {
dispatchAccentColor(color, icon)
})
</script> </script>
{#if value} {#if value}

View File

@ -13,36 +13,21 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import core, { Attribute, IdMap, Ref, Status, StatusCategory, toIdMap } from '@hcengineering/core' import core, { IdMap, Ref, Status, StatusCategory, toIdMap } from '@hcengineering/core'
import { Asset } from '@hcengineering/platform' import { Asset } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation' import { createQuery } from '@hcengineering/presentation'
import { ProjectStatus, ProjectType, TaskType, findStatusAttr } from '@hcengineering/task' import { settingsStore } from '@hcengineering/setting-resources'
import { import { ProjectStatus, ProjectType, TaskType } from '@hcengineering/task'
CircleButton, import { IconMoreV2, IconOpenedArrow, Label } from '@hcengineering/ui'
ColorDefinition, import { ObjectPresenter } from '@hcengineering/view-resources'
IconOpenedArrow,
IconMoreV2,
IconMoreH,
Label,
defaultBackground,
eventToHTMLElement,
getColorNumberByText,
getPlatformColorDef,
showPopup,
themeStore
} from '@hcengineering/ui'
import { ColorsPopup, IconPicker, ObjectPresenter, statusStore } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import task from '../../plugin' import task from '../../plugin'
import StatusesPopup from './StatusesPopup.svelte'
import { settingsStore, clearSettingsStore } from '@hcengineering/setting-resources'
export let taskType: TaskType export let taskType: TaskType
export let type: ProjectType export let type: ProjectType
export let states: Status[] = [] export let states: Status[] = []
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const client = getClient()
const elements: HTMLElement[] = [] const elements: HTMLElement[] = []
let selected: number | undefined let selected: number | undefined
@ -74,42 +59,6 @@
}) })
} }
function onColor (state: Status, color: ColorDefinition, el: HTMLElement): void {
showPopup(ColorsPopup, { selected: color.name }, el, async (res) => {
if (res == null) {
return
}
const targetColors = type.statuses.filter((p) => p._id === state._id)
for (const targetColor of targetColors) {
targetColor.color = res
}
await client.update(type, { statuses: type.statuses })
type = type
})
}
function add (ofAttribute: Ref<Attribute<Status>> | undefined, cat: Ref<StatusCategory>): void {
if (ofAttribute === undefined) {
return
}
showPopup(task.component.CreateStatePopup, {
ofAttribute,
_class: taskType.statusClass,
category: cat,
taskType,
type
})
}
function edit (status: Status): void {
showPopup(task.component.CreateStatePopup, {
status,
taskType,
type,
ofAttribute: status.ofAttribute
})
}
let categories: StatusCategory[] = [] let categories: StatusCategory[] = []
let categoriesMap: IdMap<StatusCategory> = new Map() let categoriesMap: IdMap<StatusCategory> = new Map()
let groups = new Map<Ref<StatusCategory>, Status[]>() let groups = new Map<Ref<StatusCategory>, Status[]>()
@ -119,35 +68,10 @@
categoriesMap = toIdMap(res) categoriesMap = toIdMap(res)
}) })
function click (ev: MouseEvent, state: Status): void { function getProjectStatus (type: ProjectType, state: Status): ProjectStatus | undefined {
showPopup(
StatusesPopup,
{
onDelete: () => dispatch('delete', { state }),
showDelete: states.filter((it) => it.category === state.category).length > 1,
onUpdate: () => {
edit(state)
}
},
eventToHTMLElement(ev),
() => {}
)
}
function getProjectStatus (
type: ProjectType,
state: Status,
categoriesMap: IdMap<StatusCategory>
): ProjectStatus | undefined {
return type.statuses.find((p) => p._id === state._id) return type.statuses.find((p) => p._id === state._id)
} }
function getColor (type: ProjectType, state: Status, categoriesMap: IdMap<StatusCategory>): ColorDefinition {
const category = state.category !== undefined ? categoriesMap.get(state.category) : undefined
const targetColor = getProjectStatus(type, state, categoriesMap)?.color ?? state.color ?? category?.color
return getPlatformColorDef(targetColor ?? getColorNumberByText(state.name), $themeStore.dark)
}
function group (categories: StatusCategory[], states: Status[]): Map<Ref<StatusCategory>, Status[]> { function group (categories: StatusCategory[], states: Status[]): Map<Ref<StatusCategory>, Status[]> {
const map = new Map<Ref<StatusCategory>, Status[]>(categories.map((p) => [p._id, []])) const map = new Map<Ref<StatusCategory>, Status[]>(categories.map((p) => [p._id, []]))
for (const state of states) { for (const state of states) {
@ -171,23 +95,6 @@
} }
return index return index
} }
function selectIcon (el: HTMLElement, state: Status): void {
const icons: Asset[] = []
const projectStatus = getProjectStatus(type, state, categoriesMap)
showPopup(IconPicker, { icon: projectStatus?.icon, color: projectStatus?.color, icons }, el, async (result) => {
if (result !== undefined && result !== null) {
const targetColors = type.statuses.filter((p) => p._id === state._id)
for (const targetColor of targetColors) {
targetColor.color = result.color
targetColor.icon = result.icon
}
if (targetColors.length > 0) {
await client.update(type, { statuses: type.statuses })
type = type
}
}
})
}
settingsStore.subscribe((value) => { settingsStore.subscribe((value) => {
if ((value.id === undefined && opened !== undefined) || (value.id !== undefined && value.id !== opened)) { if ((value.id === undefined && opened !== undefined) || (value.id !== undefined && value.id !== opened)) {
opened = undefined opened = undefined
@ -197,7 +104,9 @@
if (opened === undefined || opened !== _status._id) { if (opened === undefined || opened !== _status._id) {
opened = _status._id opened = _status._id
const icons: Asset[] = [] const icons: Asset[] = []
const projectStatus = getProjectStatus(type, _status, categoriesMap) const category = _status.category !== undefined ? categoriesMap.get(_status.category) : undefined
const projectStatus = getProjectStatus(type, _status)
const color = getProjectStatus(type, _status)?.color ?? _status.color ?? category?.color
$settingsStore = { $settingsStore = {
id: opened, id: opened,
component: task.component.CreateStatePopup, component: task.component.CreateStatePopup,
@ -207,13 +116,10 @@
type, type,
ofAttribute: _status.ofAttribute, ofAttribute: _status.ofAttribute,
icon: projectStatus?.icon, icon: projectStatus?.icon,
color: projectStatus?.color, color,
icons icons
} }
} }
} else if (opened === _status._id) {
clearSettingsStore()
opened = undefined
} }
} }
</script> </script>
@ -224,27 +130,15 @@
<div class="hulyTableAttr-content class withTitle"> <div class="hulyTableAttr-content class withTitle">
<div class="hulyTableAttr-content__title"> <div class="hulyTableAttr-content__title">
<Label label={cat.label} /> <Label label={cat.label} />
<!-- <CircleButton
icon={IconAdd}
size={'medium'}
on:click={() => {
add(findStatusAttr(getClient().getHierarchy(), taskType.ofClass)?._id, cat._id)
}}
/> -->
</div> </div>
<div class="hulyTableAttr-content__wrapper"> <div class="hulyTableAttr-content__wrapper">
{#each states as state, i} {#each states as state, i}
{@const color = getColor(type, state, categoriesMap)}
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- style:background={color.background ?? defaultBackground($themeStore.dark)} -->
<button <button
bind:this={elements[prevIndex + i]} bind:this={elements[prevIndex + i]}
class="hulyTableAttr-content__row" class="hulyTableAttr-content__row"
class:selected={state._id === opened} class:selected={state._id === opened}
draggable={true} draggable={true}
on:contextmenu|preventDefault={(e) => {
click(e, state)
}}
on:click={() => { on:click={() => {
handleSelect(state) handleSelect(state)
}} }}
@ -270,13 +164,6 @@
objectId={state._id} objectId={state._id}
value={state} value={state}
props={{ projectType: type._id, taskType: taskType._id, kind: 'table-attrs' }} props={{ projectType: type._id, taskType: taskType._id, kind: 'table-attrs' }}
on:click={(ev) => {
if (state.category !== undefined) {
selectIcon(elements[i + prevIndex], state)
} else {
onColor(state, color, elements[i + prevIndex])
}
}}
/> />
<div class="hulyTableAttr-content__row-arrow"> <div class="hulyTableAttr-content__row-arrow">
<IconOpenedArrow size={'small'} /> <IconOpenedArrow size={'small'} />

View File

@ -15,12 +15,12 @@
--> -->
<script lang="ts"> <script lang="ts">
import { AttributeEditor, getClient } from '@hcengineering/presentation' import { AttributeEditor, getClient } from '@hcengineering/presentation'
import task, { ProjectType, TaskType, calculateStatuses } from '@hcengineering/task' import task, { ProjectType, TaskType, calculateStatuses, findStatusAttr } from '@hcengineering/task'
import { Ref, Status } from '@hcengineering/core' import { Ref, Status } from '@hcengineering/core'
import { Asset, getEmbeddedLabel } from '@hcengineering/platform' import { Asset, getEmbeddedLabel } from '@hcengineering/platform'
import { Label, showPopup, ButtonIcon, ModernButton, IconSquareExpand, IconAdd, Icon } from '@hcengineering/ui' import { Label, showPopup, ButtonIcon, ModernButton, IconSquareExpand, IconAdd, Icon } from '@hcengineering/ui'
import { IconPicker, statusStore } from '@hcengineering/view-resources' import { IconPicker, statusStore } from '@hcengineering/view-resources'
import { ClassAttributes } from '@hcengineering/setting-resources' import { ClassAttributes, settingsStore } from '@hcengineering/setting-resources'
import { taskTypeStore } from '../..' import { taskTypeStore } from '../..'
import StatesProjectEditor from '../state/StatesProjectEditor.svelte' import StatesProjectEditor from '../state/StatesProjectEditor.svelte'
import TaskTypeKindEditor from '../taskTypes/TaskTypeKindEditor.svelte' import TaskTypeKindEditor from '../taskTypes/TaskTypeKindEditor.svelte'
@ -52,6 +52,25 @@
} }
) )
} }
function handleAddStatus (el: MouseEvent): void {
const icons: Asset[] = []
const attr = findStatusAttr(getClient().getHierarchy(), taskType.ofClass)
$settingsStore = {
id: '#',
component: task.component.CreateStatePopup,
props: {
status: undefined,
taskType,
_class: taskType.statusClass,
category: task.statusCategory.Active,
type: projectType,
ofAttribute: attr,
icon: undefined,
color: 0,
icons
}
}
}
</script> </script>
<div class="hulyComponent-content__column-group mt-4"> <div class="hulyComponent-content__column-group mt-4">
@ -105,7 +124,7 @@
<div class="hulyTableAttr-header font-medium-12"> <div class="hulyTableAttr-header font-medium-12">
<Icon icon={task.icon.ManageTemplates} size={'small'} /> <Icon icon={task.icon.ManageTemplates} size={'small'} />
<span><Label label={plugin.string.ProcessStates} /></span> <span><Label label={plugin.string.ProcessStates} /></span>
<ButtonIcon kind={'primary'} icon={IconAdd} size={'small'} on:click={(ev) => {}} /> <ButtonIcon kind={'primary'} icon={IconAdd} size={'small'} on:click={handleAddStatus} />
</div> </div>
<StatesProjectEditor <StatesProjectEditor
{taskType} {taskType}

View File

@ -75,6 +75,7 @@
{:else} {:else}
<EmojiPopup <EmojiPopup
embedded embedded
selected={String.fromCodePoint(color ?? 0)}
on:close={(evt) => { on:close={(evt) => {
dispatch('close', { icon: iconWithEmoji, color: evt.detail.codePointAt(0) }) dispatch('close', { icon: iconWithEmoji, color: evt.detail.codePointAt(0) })
}} }}