TSK-831: Edit Title and Description inline (#2788)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2023-03-21 18:16:45 +06:00
committed by GitHub
parent d65cb70652
commit d770acb77a
10 changed files with 111 additions and 112 deletions
@@ -168,7 +168,7 @@
}
</script>
<div bind:this={thisRef} class="flex-col root">
<div id="sub-issue-child-editor" bind:this={thisRef} class="flex-col root">
<div class="flex-row-top">
<div id="status-editor" class="mr-1">
<StatusEditor
@@ -13,24 +13,22 @@
// limitations under the License.
-->
<script lang="ts">
import { AttachmentDocList, AttachmentStyledBox } from '@hcengineering/attachment-resources'
import { AttachmentStyledBox } from '@hcengineering/attachment-resources'
import { Class, Data, Doc, Ref, SortingOrder, WithLookup } from '@hcengineering/core'
import notification from '@hcengineering/notification'
import { Panel } from '@hcengineering/panel'
import { getResource } from '@hcengineering/platform'
import presentation, { createQuery, getClient, MessageViewer } from '@hcengineering/presentation'
import { createQuery, getClient } from '@hcengineering/presentation'
import setting, { settingId } from '@hcengineering/setting'
import type { Issue, IssueStatus, Project } from '@hcengineering/tracker'
import {
Button,
EditBox,
getCurrentLocation,
IconEdit,
IconMixin,
IconMoreH,
Label,
navigate,
Scroller,
showPopup,
Spinner
} from '@hcengineering/ui'
@@ -111,26 +109,8 @@
$: isDescriptionEmpty = !new DOMParser().parseFromString(description, 'text/html').documentElement.innerText?.trim()
$: parentIssue = issue?.$lookup?.attachedTo
function edit (ev: MouseEvent) {
ev.preventDefault()
isEditing = true
}
function cancelEditing (ev: MouseEvent) {
ev.preventDefault()
isEditing = false
if (issue) {
title = issue.title
description = issue.description
}
}
async function save (ev: MouseEvent) {
ev.preventDefault()
let saved = false
async function save () {
if (!issue || !canSave) {
return
}
@@ -156,11 +136,21 @@
issue.collection,
updates
)
saved = true
setTimeout(() => {
saved = false
}, 5000)
}
await descriptionBox.createAttachments()
isEditing = false
}
let saveTrigger: any
function triggerSave (): void {
clearTimeout(saveTrigger)
saveTrigger = setTimeout(save, 5000)
}
function showMenu (ev?: Event): void {
if (issue) {
showPopup(ContextMenu, { object: issue }, (ev as MouseEvent).target as HTMLElement)
@@ -178,7 +168,7 @@
isHeader
isAside={true}
isSub={false}
withoutActivity={isEditing}
withoutActivity={false}
withoutTitle
bind:innerWidth
on:close={() => dispatch('close')}
@@ -192,80 +182,54 @@
</span>
</svelte:fragment>
<svelte:fragment slot="tools">
{#if isEditing}
<Button kind={'transparent'} label={presentation.string.Cancel} on:click={cancelEditing} />
<Button disabled={!canSave} label={presentation.string.Save} on:click={save} />
{:else}
<Button icon={IconEdit} kind={'transparent'} size={'medium'} on:click={edit} />
<Button icon={IconMoreH} kind={'transparent'} size={'medium'} on:click={showMenu} />
{#if saved}
<Label label={tracker.string.Saved} />
{/if}
<Button icon={IconMoreH} kind={'transparent'} size={'medium'} on:click={showMenu} />
</svelte:fragment>
{#if isEditing}
<Scroller>
<div class="popupPanel-body__main-content py-10 clear-mins content">
{#if parentIssue}
<div class="mb-6">
{#if currentProject && issueStatuses}
<SubIssueSelector {issue} />
{:else}
<Spinner />
{/if}
</div>
{/if}
<EditBox bind:value={title} placeholder={tracker.string.IssueTitlePlaceholder} kind="large-style" />
<div class="w-full mt-6">
<AttachmentStyledBox
bind:this={descriptionBox}
objectId={_id}
_class={tracker.class.Issue}
space={issue.space}
alwaysEdit
showButtons
maxHeight={'card'}
focusable
bind:content={description}
placeholder={tracker.string.IssueDescriptionPlaceholder}
/>
</div>
</div>
</Scroller>
{:else}
{#if parentIssue}
<div class="mb-6">
{#if currentProject && issueStatuses}
<SubIssueSelector {issue} />
{:else}
<Spinner />
{/if}
</div>
{/if}
<span class="title select-text">{title}</span>
<div class="mt-6 description-preview select-text">
{#if isDescriptionEmpty}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="placeholder" on:click={edit}>
<Label label={tracker.string.IssueDescriptionPlaceholder} />
</div>
{#if parentIssue}
<div class="mb-6">
{#if currentProject && issueStatuses}
<SubIssueSelector {issue} />
{:else}
<MessageViewer message={description} />
<Spinner />
{/if}
</div>
<div class="mt-6">
{#key issue._id && currentProject !== undefined}
{#if currentProject !== undefined && issueStatuses !== undefined}
<SubIssues
{issue}
issueStatuses={new Map([[currentProject._id, issueStatuses]])}
projects={new Map([[currentProject?._id, currentProject]])}
/>
{/if}
{/key}
</div>
<div class="mt-6">
<AttachmentDocList value={issue} />
</div>
{/if}
<EditBox bind:value={title} placeholder={tracker.string.IssueTitlePlaceholder} kind="large-style" on:blur={save} />
<div class="w-full mt-6">
<AttachmentStyledBox
bind:this={descriptionBox}
useAttachmentPreview={true}
objectId={_id}
_class={tracker.class.Issue}
space={issue.space}
alwaysEdit
shouldSaveDraft={false}
on:attached={save}
on:detached={save}
showButtons
on:blur={save}
on:changeContent={triggerSave}
maxHeight={'card'}
focusable
bind:content={description}
placeholder={tracker.string.IssueDescriptionPlaceholder}
/>
</div>
<div class="mt-6">
{#key issue._id && currentProject !== undefined}
{#if currentProject !== undefined && issueStatuses !== undefined}
<SubIssues
{issue}
issueStatuses={new Map([[currentProject._id, issueStatuses]])}
projects={new Map([[currentProject?._id, currentProject]])}
/>
{/if}
{/key}
</div>
<span slot="actions-label" class="select-text">
{#if issueId}{issueId}{/if}