Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UBERF-5348: Fix new status creation #4567

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/ui/src/components/ButtonMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher, ComponentType } from 'svelte'
import type { Asset, IntlString } from '@hcengineering/platform'
import { deepEqual } from 'fast-equals'
import { ComponentType, createEventDispatcher } from 'svelte'
import { closePopup, showPopup } from '..'
import { AnySvelteComponent, DropdownIntlItem } from '../types'
import ButtonBase from './ButtonBase.svelte'
import { showPopup, closePopup, eventToHTMLElement } from '..'
import ModernPopup from './ModernPopup.svelte'

export let title: string | undefined = undefined
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/src/components/EmojiPopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import plugin from '../plugin'

export let embedded = false
export let selected: string | undefined

interface Category {
id: string
Expand Down Expand Up @@ -179,7 +180,9 @@
{#if emoji !== undefined}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- 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}
{/each}
</div>
Expand Down Expand Up @@ -250,6 +253,7 @@

&.selected {
background-color: var(--theme-popup-header);
border: 1px solid var(--theme-popup-divider);
}
}
</style>
143 changes: 87 additions & 56 deletions plugins/task-resources/src/components/CreateStatePopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,30 @@
// limitations under the License.
-->
<script lang="ts">
import { Asset, Metadata, getEmbeddedLabel } from '@hcengineering/platform'
import { Attribute, Class, Ref, Status, StatusCategory } from '@hcengineering/core'
import core, { Attribute, Class, Ref, Status, StatusCategory } from '@hcengineering/core'
import { Asset, getEmbeddedLabel } from '@hcengineering/platform'
import presentation, { getClient } from '@hcengineering/presentation'
import { clearSettingsStore } from '@hcengineering/setting-resources'
import { ProjectType, TaskType, calculateStatuses, createState } from '@hcengineering/task'
import {
ModernEditbox,
getColorNumberByText,
Modal,
Label,
ButtonIcon,
ButtonMenu,
EmojiPopup,
IconCopy,
IconDelete,
IconSettings,
IconWithEmoji,
Label,
Modal,
ModernEditbox,
TextArea,
getPlatformColorDef,
themeStore,
EmojiPopup,
ButtonIcon,
IconDelete,
IconCopy
themeStore
} 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 { clearSettingsStore } from '@hcengineering/setting-resources'
import task from '../plugin'
import { taskTypeStore } from '..'
import IconLink from './icons/Link.svelte'
import task from '../plugin'

export let status: Status | undefined = undefined
export let _class: Ref<Class<Status>> | undefined = status?._class
Expand All @@ -49,13 +48,19 @@
export let color: number | undefined = undefined
export let icons: Asset[]
export let iconWithEmoji: Asset = view.ids.IconWithEmoji
export let icon: Asset | undefined

const client = getClient()

let description: string | undefined = status?.description

$: allowEditCategory = status === undefined

$: 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() !== ''

async function save (): Promise<void> {
Expand All @@ -73,6 +78,13 @@
const lastIndex = states.findLastIndex((p) => p.category === category)
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, {
statuses: calculateStatuses(type, $taskTypeStore, [{ taskTypeId: taskType._id, statuses }])
})
Expand All @@ -89,35 +101,42 @@
})
const index = taskType.statuses.indexOf(status._id)
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, {
statuses: calculateStatuses(type, $taskTypeStore, [{ taskTypeId: taskType._id, statuses }])
})
await client.update(taskType, {
statuses
})
const projects = await client.findAll(task.class.Project, { type: type._id })
while (true) {
const docs = await client.findAll(
task.class.Task,
{
status: status._id,
space: { $in: projects.map((p) => p._id) }
},
{ limit: 1000 }
)
if (docs.length === 0) {
break
}
if (status._id !== _id) {
const projects = await client.findAll(task.class.Project, { type: type._id })
while (true) {
const docs = await client.findAll(
task.class.Task,
{
status: status._id,
space: { $in: projects.map((p) => p._id) }
},
{ limit: 1000 }
)
if (docs.length === 0) {
break
}

const op = client.apply(_id)
docs.map((p) => op.update(p, { status: _id }))
await op.commit()
const op = client.apply(_id)
docs.map((p) => op.update(p, { status: _id }))
await op.commit()
}
}
}
clearSettingsStore()
}

let selected: number = 0
let selected: number = icon === iconWithEmoji ? 1 : 0
const items = [
{
id: 'color',
Expand All @@ -128,12 +147,22 @@
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>

<Modal
label={task.string.StatusPopupTitle}
type={'type-aside'}
okLabel={presentation.string.Save}
okLabel={status === undefined ? presentation.string.Create : presentation.string.Save}
okAction={save}
canSave={needUpdate}
onCancel={() => {
Expand All @@ -157,28 +186,19 @@
</div>
<div class="hulyModal-content__settingsSet">
<div class="hulyModal-content__settingsSet-line">
<span class="label"><Label label={task.string.Group} /></span>
<!-- <ButtonMenu
{items}
{selected}
icon={IconLink}
label={getEmbeddedLabel('Compeletd')}
kind={'secondary'}
size={'medium'}
on:selected={() => {}}
/> -->
</div>
<div class="hulyModal-content__settingsSet-line">
<span class="label"><Label label={task.string.Type} /></span>
<!-- <ButtonMenu
{items}
{selected}
icon={IconLink}
label={getEmbeddedLabel('Success')}
<span class="label"><Label label={getEmbeddedLabel('Status Category')} /></span>
<ButtonMenu
items={categories}
selected={category}
disabled={!allowEditCategory}
icon={categories.find((it) => it.id === category)?.icon}
label={categories.find((it) => it.id === category)?.label}
kind={'secondary'}
size={'medium'}
on:selected={() => {}}
/> -->
on:selected={(it) => {
category = it.detail
}}
/>
</div>
</div>
<div class="hulyModal-content__settingsSet table">
Expand All @@ -192,9 +212,17 @@
kind={'secondary'}
size={'small'}
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 class="hulyTableAttr-content" class:mb-2={selected === 1}>
{#if selected === 0}
Expand All @@ -204,13 +232,16 @@
columns={'auto'}
on:close={(evt) => {
color = evt.detail
icon = undefined
}}
/>
{:else}
<EmojiPopup
embedded
selected={String.fromCodePoint(color ?? 0)}
on:close={(evt) => {
color = evt.detail.codePointAt(0)
icon = iconWithEmoji
}}
/>
{/if}
Expand Down
28 changes: 16 additions & 12 deletions plugins/task-resources/src/components/state/StatePresenter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
-->
<script lang="ts">
import core, { IdMap, Ref, Status, StatusCategory } from '@hcengineering/core'
import { Asset } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
import task, { Project, ProjectType, TaskType } from '@hcengineering/task'
import {
Expand All @@ -31,10 +32,10 @@
import { createEventDispatcher, onMount } from 'svelte'
import { typeStore } from '../..'
import IconBacklog from '../icons/IconBacklog.svelte'
import IconUnstarted from '../icons/IconUnstarted.svelte'
import IconCanceled from '../icons/IconCanceled.svelte'
import IconCompleted from '../icons/IconCompleted.svelte'
import IconStarted from '../icons/IconStarted.svelte'
import IconUnstarted from '../icons/IconUnstarted.svelte'

export let value: Status | undefined
export let shouldShowAvatar = true
Expand Down Expand Up @@ -80,20 +81,10 @@

$: projectState = type?.statuses.find((p) => p._id === value?._id)

const dispatchAccentColor = (color?: ColorDefinition): void => {
dispatch('accent-color', color)
}

$: color = getPlatformColorDef(
projectState?.color ?? category?.color ?? getColorNumberByText(value?.name ?? ''),
$themeStore.dark
)
$: dispatchAccentColor(color)

onMount(() => {
dispatchAccentColor(color)
})

$: void updateCategory(value)

async function updateCategory (value: Status | undefined): Promise<void> {
Expand All @@ -119,8 +110,21 @@
)

$: index = sameCategory.findIndex((it) => it._id === value?._id) + 1

$: 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>

{#if value}
Expand Down
Loading
Loading