From 9290942a5628999a9b05f2cdff3805c879a3f290 Mon Sep 17 00:00:00 2001
From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
Date: Tue, 4 Oct 2022 21:48:14 +0600
Subject: [PATCH] Empty title subissue, backreferences fix (#2280)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
---
 plugins/chunter-resources/src/index.ts        |  7 +-
 plugins/chunter/src/index.ts                  |  2 +-
 .../src/components/CreateIssue.svelte         |  6 +-
 .../src/components/RelationsPopup.svelte      |  8 +-
 .../issues/RelationEditorPart.svelte          |  4 +-
 .../issues/edit/CreateSubIssue.svelte         | 81 ++++++++++---------
 .../issues/related/CreateRelatedIssue.svelte  | 77 ++++++++++--------
 7 files changed, 101 insertions(+), 84 deletions(-)

diff --git a/plugins/chunter-resources/src/index.ts b/plugins/chunter-resources/src/index.ts
index a18b7d44b7..dc94b15e71 100644
--- a/plugins/chunter-resources/src/index.ts
+++ b/plugins/chunter-resources/src/index.ts
@@ -24,7 +24,7 @@ import chunter, {
   Backlink
 } from '@hcengineering/chunter'
 import { NotificationClientImpl } from '@hcengineering/notification-resources'
-import { Resources } from '@hcengineering/platform'
+import { IntlString, Resources, translate } from '@hcengineering/platform'
 import preference from '@hcengineering/preference'
 import { getClient, MessageBox } from '@hcengineering/presentation'
 import { getCurrentLocation, navigate, showPopup } from '@hcengineering/ui'
@@ -190,13 +190,14 @@ export function chunterBrowserVisible (spaces: Space[]): boolean {
   return false
 }
 
-async function update (source: Doc, key: string, target: RelatedDocument[], msg: string): Promise<void> {
+async function update (source: Doc, key: string, target: RelatedDocument[], msg: IntlString): Promise<void> {
+  const message = await translate(msg, {})
   const backlinks: Array<Data<Backlink>> = target.map((it) => ({
     backlinkId: source._id,
     backlinkClass: source._class,
     attachedTo: it._id,
     attachedToClass: it._class,
-    message: msg,
+    message,
     collection: key
   }))
 
diff --git a/plugins/chunter/src/index.ts b/plugins/chunter/src/index.ts
index dfe0b6ed33..252afd8a9c 100644
--- a/plugins/chunter/src/index.ts
+++ b/plugins/chunter/src/index.ts
@@ -161,6 +161,6 @@ export default plugin(chunterId, {
   },
   backreference: {
     // Update list of back references
-    Update: '' as Resource<(source: Doc, key: string, target: RelatedDocument[], label: IntlString) => void>
+    Update: '' as Resource<(source: Doc, key: string, target: RelatedDocument[], label: IntlString) => Promise<void>>
   }
 })
diff --git a/plugins/tracker-resources/src/components/CreateIssue.svelte b/plugins/tracker-resources/src/components/CreateIssue.svelte
index b1b383c972..ac334a75eb 100644
--- a/plugins/tracker-resources/src/components/CreateIssue.svelte
+++ b/plugins/tracker-resources/src/components/CreateIssue.svelte
@@ -17,7 +17,7 @@
   import chunter from '@hcengineering/chunter'
   import { Employee } from '@hcengineering/contact'
   import core, { Account, AttachedData, Doc, generateId, Ref, SortingOrder, WithLookup } from '@hcengineering/core'
-  import { getResource, translate } from '@hcengineering/platform'
+  import { getResource } from '@hcengineering/platform'
   import { Card, createQuery, getClient, KeyedAttribute, SpaceSelector } from '@hcengineering/presentation'
   import tags, { TagElement, TagReference } from '@hcengineering/tags'
   import { calcRank, Issue, IssuePriority, IssueStatus, Project, Sprint, Team } from '@hcengineering/tracker'
@@ -190,7 +190,9 @@
     const update = await getResource(chunter.backreference.Update)
     if (relatedTo !== undefined) {
       const doc = await client.findOne(tracker.class.Issue, { _id: objectId })
-      await update(doc, 'relations', [relatedTo], await translate(tracker.string.AddedReference, {}))
+      if (doc !== undefined) {
+        await update(doc, 'relations', [relatedTo], tracker.string.AddedReference)
+      }
     }
 
     objectId = generateId()
diff --git a/plugins/tracker-resources/src/components/RelationsPopup.svelte b/plugins/tracker-resources/src/components/RelationsPopup.svelte
index 1e9e1bcf98..9ce77abc98 100644
--- a/plugins/tracker-resources/src/components/RelationsPopup.svelte
+++ b/plugins/tracker-resources/src/components/RelationsPopup.svelte
@@ -1,13 +1,13 @@
 <script lang="ts">
-  import { createEventDispatcher, afterUpdate } from 'svelte'
+  import chunter from '@hcengineering/chunter'
   import { Class, Doc, Ref, RelatedDocument } from '@hcengineering/core'
-  import { getResource, IntlString, translate } from '@hcengineering/platform'
+  import { getResource, IntlString } from '@hcengineering/platform'
   import { createQuery, getClient, ObjectSearchPopup, ObjectSearchResult } from '@hcengineering/presentation'
   import { Issue } from '@hcengineering/tracker'
   import { Action, closePopup, Menu, showPopup } from '@hcengineering/ui'
+  import { afterUpdate, createEventDispatcher } from 'svelte'
   import { updateIssueRelation } from '../issues'
   import tracker from '../plugin'
-  import chunter from '@hcengineering/chunter'
 
   export let value: Issue
 
@@ -65,7 +65,7 @@
     if (operation === '$pull' && pos !== -1) {
       docs.splice(pos, 1)
     }
-    await update(value, type, docs, await translate(label, {}))
+    await update(value, type, docs, label)
   }
 
   const makeAddAction = (type: keyof typeof relations, placeholder: IntlString) => async (props: any, evt: Event) => {
diff --git a/plugins/tracker-resources/src/components/issues/RelationEditorPart.svelte b/plugins/tracker-resources/src/components/issues/RelationEditorPart.svelte
index 8431a3dcb2..ef8f514b9b 100644
--- a/plugins/tracker-resources/src/components/issues/RelationEditorPart.svelte
+++ b/plugins/tracker-resources/src/components/issues/RelationEditorPart.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
   import chunter from '@hcengineering/chunter'
   import { Class, Doc, Ref, RelatedDocument, WithLookup } from '@hcengineering/core'
-  import { getResource, IntlString, translate } from '@hcengineering/platform'
+  import { getResource, IntlString } from '@hcengineering/platform'
   import { createQuery, getClient } from '@hcengineering/presentation'
   import { Issue } from '@hcengineering/tracker'
   import { Component, Icon, IconClose } from '@hcengineering/ui'
@@ -68,7 +68,7 @@
     if (pos !== -1) {
       docs.splice(pos, 1)
     }
-    await update(value, type, docs, await translate(label, {}))
+    await update(value, type, docs, label)
   }
   const asIssue = (x: Doc) => x as WithLookup<Issue>
 </script>
diff --git a/plugins/tracker-resources/src/components/issues/edit/CreateSubIssue.svelte b/plugins/tracker-resources/src/components/issues/edit/CreateSubIssue.svelte
index abeba758fa..cb50728ad9 100644
--- a/plugins/tracker-resources/src/components/issues/edit/CreateSubIssue.svelte
+++ b/plugins/tracker-resources/src/components/issues/edit/CreateSubIssue.svelte
@@ -82,46 +82,50 @@
     if (!canSave) {
       return
     }
+    loading = true
+    try {
+      const space = currentTeam._id
+      const lastOne = await client.findOne<Issue>(
+        tracker.class.Issue,
+        { space },
+        { sort: { rank: SortingOrder.Descending } }
+      )
+      const incResult = await client.updateDoc(
+        tracker.class.Team,
+        core.space.Space,
+        space,
+        { $inc: { sequence: 1 } },
+        true
+      )
 
-    const space = currentTeam._id
-    const lastOne = await client.findOne<Issue>(
-      tracker.class.Issue,
-      { space },
-      { sort: { rank: SortingOrder.Descending } }
-    )
-    const incResult = await client.updateDoc(
-      tracker.class.Team,
-      core.space.Space,
-      space,
-      { $inc: { sequence: 1 } },
-      true
-    )
+      const value: AttachedData<Issue> = {
+        ...newIssue,
+        title: getTitle(newIssue.title),
+        number: (incResult as any).object.sequence,
+        rank: calcRank(lastOne, undefined),
+        project: parentIssue.project,
+        parents: [{ parentId: parentIssue._id, parentTitle: parentIssue.title }, ...parentIssue.parents]
+      }
 
-    const value: AttachedData<Issue> = {
-      ...newIssue,
-      title: getTitle(newIssue.title),
-      number: (incResult as any).object.sequence,
-      rank: calcRank(lastOne, undefined),
-      project: parentIssue.project,
-      parents: [{ parentId: parentIssue._id, parentTitle: parentIssue.title }, ...parentIssue.parents]
+      const objectId = await client.addCollection(
+        tracker.class.Issue,
+        space,
+        parentIssue._id,
+        parentIssue._class,
+        'subIssues',
+        value
+      )
+      for (const label of labels) {
+        await client.addCollection(label._class, label.space, objectId, tracker.class.Issue, 'labels', {
+          title: label.title,
+          color: label.color,
+          tag: label.tag
+        })
+      }
+    } finally {
+      resetToDefaults()
+      loading = false
     }
-
-    const objectId = await client.addCollection(
-      tracker.class.Issue,
-      space,
-      parentIssue._id,
-      parentIssue._class,
-      'subIssues',
-      value
-    )
-    for (const label of labels) {
-      await client.addCollection(label._class, label.space, objectId, tracker.class.Issue, 'labels', {
-        title: label.title,
-        color: label.color,
-        tag: label.tag
-      })
-    }
-    resetToDefaults()
   }
 
   function addTagRef (tag: TagElement): void {
@@ -143,6 +147,8 @@
     ]
   }
 
+  let loading = false
+
   $: thisRef && thisRef.scrollIntoView({ behavior: 'smooth' })
   $: canSave = getTitle(newIssue.title ?? '').length > 0
   $: if (!newIssue.status && currentTeam?.defaultIssueStatus) {
@@ -222,6 +228,7 @@
     <div class="buttons-group small-gap">
       <Button label={presentation.string.Cancel} size="small" kind="transparent" on:click={close} />
       <Button
+        {loading}
         disabled={!canSave}
         label={presentation.string.Save}
         size="small"
diff --git a/plugins/tracker-resources/src/components/issues/related/CreateRelatedIssue.svelte b/plugins/tracker-resources/src/components/issues/related/CreateRelatedIssue.svelte
index 9d70f9c912..3eb62a0c3e 100644
--- a/plugins/tracker-resources/src/components/issues/related/CreateRelatedIssue.svelte
+++ b/plugins/tracker-resources/src/components/issues/related/CreateRelatedIssue.svelte
@@ -89,44 +89,49 @@
     if (!canSave) {
       return
     }
+    loading = true
 
-    const lastOne = await client.findOne<Issue>(
-      tracker.class.Issue,
-      { space: currentTeam },
-      { sort: { rank: SortingOrder.Descending } }
-    )
-    const incResult = await client.updateDoc(
-      tracker.class.Team,
-      core.space.Space,
-      currentTeam,
-      { $inc: { sequence: 1 } },
-      true
-    )
+    try {
+      const lastOne = await client.findOne<Issue>(
+        tracker.class.Issue,
+        { space: currentTeam },
+        { sort: { rank: SortingOrder.Descending } }
+      )
+      const incResult = await client.updateDoc(
+        tracker.class.Team,
+        core.space.Space,
+        currentTeam,
+        { $inc: { sequence: 1 } },
+        true
+      )
 
-    const value: AttachedData<Issue> = {
-      ...newIssue,
-      title: getTitle(newIssue.title),
-      number: (incResult as any).object.sequence,
-      rank: calcRank(lastOne, undefined),
-      parents: [{ parentId: tracker.ids.NoParent, parentTitle: '' }]
+      const value: AttachedData<Issue> = {
+        ...newIssue,
+        title: getTitle(newIssue.title),
+        number: (incResult as any).object.sequence,
+        rank: calcRank(lastOne, undefined),
+        parents: [{ parentId: tracker.ids.NoParent, parentTitle: '' }]
+      }
+
+      const objectId = await client.addCollection(
+        tracker.class.Issue,
+        currentTeam,
+        tracker.ids.NoParent,
+        tracker.class.Issue,
+        'subIssues',
+        value
+      )
+      for (const label of labels) {
+        await client.addCollection(label._class, label.space, objectId, tracker.class.Issue, 'labels', {
+          title: label.title,
+          color: label.color,
+          tag: label.tag
+        })
+      }
+    } finally {
+      resetToDefaults()
+      loading = false
     }
-
-    const objectId = await client.addCollection(
-      tracker.class.Issue,
-      currentTeam,
-      tracker.ids.NoParent,
-      tracker.class.Issue,
-      'subIssues',
-      value
-    )
-    for (const label of labels) {
-      await client.addCollection(label._class, label.space, objectId, tracker.class.Issue, 'labels', {
-        title: label.title,
-        color: label.color,
-        tag: label.tag
-      })
-    }
-    resetToDefaults()
   }
 
   function addTagRef (tag: TagElement): void {
@@ -148,6 +153,7 @@
     ]
   }
 
+  let loading = false
   $: thisRef && thisRef.scrollIntoView({ behavior: 'smooth' })
   $: canSave = getTitle(newIssue.title ?? '').length > 0
   $: if (!newIssue.status) {
@@ -230,6 +236,7 @@
     <div class="buttons-group small-gap">
       <Button label={presentation.string.Cancel} size="small" kind="transparent" on:click={close} />
       <Button
+        {loading}
         disabled={!canSave}
         label={presentation.string.Save}
         size="small"