From ab479a93a0472e6f85564d436cfe6b032fc50e8d Mon Sep 17 00:00:00 2001 From: Denis Bykhov <bykhov.denis@gmail.com> Date: Fri, 21 Apr 2023 08:52:37 +0600 Subject: [PATCH] Remove status (#3031) Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com> --- plugins/tracker-assets/lang/en.json | 3 +- plugins/tracker-assets/lang/ru.json | 3 +- .../components/workflow/RemoveStatus.svelte | 130 ++++++++++++++++++ .../workflow/StatusPresenter.svelte | 2 +- .../src/components/workflow/Statuses.svelte | 16 +-- plugins/tracker-resources/src/plugin.ts | 1 - 6 files changed, 139 insertions(+), 16 deletions(-) create mode 100644 plugins/tracker-resources/src/components/workflow/RemoveStatus.svelte diff --git a/plugins/tracker-assets/lang/en.json b/plugins/tracker-assets/lang/en.json index e3d36b0fd2..07b3ae3bd5 100644 --- a/plugins/tracker-assets/lang/en.json +++ b/plugins/tracker-assets/lang/en.json @@ -188,8 +188,7 @@ "EditWorkflowStatus": "Edit issue status", "DeleteWorkflowStatus": "Delete issue status", "DeleteWorkflowStatusConfirm": "Do you want to delete the \"{status}\" status?", - "DeleteWorkflowStatusError": "Can't delete the issue status", - "DeleteWorkflowStatusErrorDescription": "The \"{status}\" status has {count, plural, =1 {1 issue} other {# issues}} assigned. Please archive or move {count, plural, =1 {it} other {them}} before deleting this status.", + "DeleteWorkflowStatusErrorDescription": "The \"{status}\" status has {count, plural, =1 {1 issue} other {# issues}} assigned. Please select a status to move", "Save": "Save", "IncludeItemsThatMatch": "Include items that match", diff --git a/plugins/tracker-assets/lang/ru.json b/plugins/tracker-assets/lang/ru.json index a4ff6ed4a8..d6366ee1c2 100644 --- a/plugins/tracker-assets/lang/ru.json +++ b/plugins/tracker-assets/lang/ru.json @@ -188,8 +188,7 @@ "EditWorkflowStatus": "Редактировать статус задачи", "DeleteWorkflowStatus": "Удалить статус задачи", "DeleteWorkflowStatusConfirm": "Вы действительно хотите удалить \"{status}\" статус?", - "DeleteWorkflowStatusError": "Невозможно удалить статус задачи", - "DeleteWorkflowStatusErrorDescription": "Статус \"{status}\" {count, plural, =1 {имеет 1 задача} other {имеют # задачи}}. Пожалуйста, архивируйте или переместите {count, plural, =1 {ее} other {их}} перед удалением этого статуса.", + "DeleteWorkflowStatusErrorDescription": "Статус \"{status}\" {count, plural, =1 {имеет 1 задача} other {имеют # задачи}}. Пожалуйста, выберите статус для перемещения.", "Save": "Сохранить", "IncludeItemsThatMatch": "Включить элементы, которые соответствуют", diff --git a/plugins/tracker-resources/src/components/workflow/RemoveStatus.svelte b/plugins/tracker-resources/src/components/workflow/RemoveStatus.svelte new file mode 100644 index 0000000000..827d69269f --- /dev/null +++ b/plugins/tracker-resources/src/components/workflow/RemoveStatus.svelte @@ -0,0 +1,130 @@ +<script lang="ts"> + import { Ref } from '@hcengineering/core' + import { Issue, IssueStatus, Project } from '@hcengineering/tracker' + import { Button, Label, SelectPopup, eventToHTMLElement, showPopup } from '@hcengineering/ui' + import presentation, { getClient, statusStore } from '@hcengineering/presentation' + import tracker from '../../plugin' + import { createEventDispatcher } from 'svelte' + import IssueStatusIcon from '../issues/IssueStatusIcon.svelte' + import { StatusPresenter } from '@hcengineering/view-resources' + + export let projectId: Ref<Project> + export let issues: Issue[] + export let status: IssueStatus + + let processing = false + + const client = getClient() + + let newStatus: IssueStatus = + $statusStore.statuses.find( + (s) => s._id !== status._id && s.category === status.category && s.space === projectId + ) ?? + $statusStore.statuses.find((s) => s._id !== status._id && s.space === projectId) ?? + status + + async function remove () { + processing = true + await Promise.all( + issues.map(async (p) => { + await client.update(p, { + status: newStatus._id + }) + }) + ) + await client.remove(status) + processing = false + dispatch('close') + } + + $: statuses = $statusStore.filter((it) => it.space === projectId && it._id !== status._id) + $: statusesInfo = statuses?.map((s) => { + return { + id: s._id, + component: StatusPresenter, + props: { value: s, size: 'small' }, + isSelected: newStatus._id === s._id ?? false + } + }) + + const dispatch = createEventDispatcher() + + const handleStatusEditorOpened = (event: MouseEvent) => { + showPopup( + SelectPopup, + { value: statusesInfo, placeholder: tracker.string.SetStatus, searchable: true }, + eventToHTMLElement(event), + (val) => (newStatus = $statusStore.byId.get(val) ?? newStatus) + ) + } +</script> + +<div class="msgbox-container"> + <div class="overflow-label fs-title mb-4"><Label label={tracker.string.DeleteWorkflowStatus} /></div> + <div class="message"> + <Label label={tracker.string.DeleteWorkflowStatusConfirm} params={{ status: status.name }} /> + <Label + label={tracker.string.DeleteWorkflowStatusErrorDescription} + params={{ status: status.name, count: issues.length }} + /> + </div> + <div class="mt-2 mb-2"> + <Button kind={'link'} justify={'left'} width={'10rem'} on:click={handleStatusEditorOpened}> + <span slot="content" class="flex-row-center pointer-events-none"> + {#if newStatus} + <IssueStatusIcon value={newStatus} size="inline" /> + {/if} + {#if newStatus} + <span class="overflow-label disabled ml-1"> + {newStatus.name} + </span> + {/if} + </span> + </Button> + </div> + <div class="footer"> + <Button + focus + label={presentation.string.Ok} + size={'small'} + kind={'primary'} + loading={processing} + on:click={remove} + /> + <Button + label={presentation.string.Cancel} + size={'small'} + on:click={() => { + dispatch('close', false) + }} + /> + </div> +</div> + +<style lang="scss"> + .msgbox-container { + display: flex; + flex-direction: column; + padding: 2rem 1.75rem 1.75rem; + width: 30rem; + max-width: 40rem; + background: var(--popup-bg-color); + border-radius: 1.25rem; + user-select: none; + box-shadow: var(--popup-shadow); + + .message { + margin-bottom: 1.75rem; + color: var(--accent-color); + } + .footer { + flex-shrink: 0; + display: grid; + grid-auto-flow: column; + direction: rtl; + justify-content: flex-start; + align-items: center; + column-gap: 0.5rem; + } + } +</style> diff --git a/plugins/tracker-resources/src/components/workflow/StatusPresenter.svelte b/plugins/tracker-resources/src/components/workflow/StatusPresenter.svelte index 80871fca40..f590e6acfb 100644 --- a/plugins/tracker-resources/src/components/workflow/StatusPresenter.svelte +++ b/plugins/tracker-resources/src/components/workflow/StatusPresenter.svelte @@ -60,7 +60,7 @@ > <Icon icon={IconEdit} size="small" /> </div> - {#if !isSingle} + {#if !isDefault} <!-- svelte-ignore a11y-click-events-have-key-events --> <div class="btn" diff --git a/plugins/tracker-resources/src/components/workflow/Statuses.svelte b/plugins/tracker-resources/src/components/workflow/Statuses.svelte index 62340f7403..d8b87c87ab 100644 --- a/plugins/tracker-resources/src/components/workflow/Statuses.svelte +++ b/plugins/tracker-resources/src/components/workflow/Statuses.svelte @@ -34,6 +34,7 @@ import tracker from '../../plugin' import StatusEditor from './StatusEditor.svelte' import StatusPresenter from './StatusPresenter.svelte' + import RemoveStatus from './RemoveStatus.svelte' export let projectId: Ref<Project> export let projectClass: Ref<Class<Project>> @@ -128,18 +129,13 @@ closeTooltip() const { detail: status } = event - const issuesWithDeletingStatus = await client.findAll( - tracker.class.Issue, - { status: status._id }, - { projection: { _id: 1 } } - ) + const issuesWithDeletingStatus = await client.findAll(tracker.class.Issue, { status: status._id }) if (issuesWithDeletingStatus.length > 0) { - showPopup(MessageBox, { - label: tracker.string.DeleteWorkflowStatusError, - message: tracker.string.DeleteWorkflowStatusErrorDescription, - params: { status: status.name, count: issuesWithDeletingStatus.length }, - canSubmit: false + showPopup(RemoveStatus, { + issues: issuesWithDeletingStatus, + projectId, + status }) } else { showPopup( diff --git a/plugins/tracker-resources/src/plugin.ts b/plugins/tracker-resources/src/plugin.ts index b50b32cbf8..92bcba9840 100644 --- a/plugins/tracker-resources/src/plugin.ts +++ b/plugins/tracker-resources/src/plugin.ts @@ -106,7 +106,6 @@ export default mergeIds(trackerId, tracker, { EditWorkflowStatus: '' as IntlString, DeleteWorkflowStatus: '' as IntlString, DeleteWorkflowStatusConfirm: '' as IntlString, - DeleteWorkflowStatusError: '' as IntlString, DeleteWorkflowStatusErrorDescription: '' as IntlString, Name: '' as IntlString, StatusCategory: '' as IntlString,