diff --git a/changelog.md b/changelog.md
index 665748398f..748487f1be 100644
--- a/changelog.md
+++ b/changelog.md
@@ -15,6 +15,7 @@ HR:
Tracker:
- Manual issues ordering
+- Issue relations
Workbench
- Use application aliases in URL
diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts
index 7dca28a859..4b796185da 100644
--- a/models/tracker/src/index.ts
+++ b/models/tracker/src/index.ts
@@ -853,7 +853,7 @@ export function createModel (builder: Builder): void {
builder,
{
action: view.actionImpl.Move,
- label: view.string.Move,
+ label: tracker.string.MoveToTeam,
icon: view.icon.Move,
keyBinding: [],
input: 'none',
@@ -862,9 +862,32 @@ export function createModel (builder: Builder): void {
context: {
mode: ['context', 'browser'],
application: tracker.app.Tracker,
- group: 'edit'
+ group: 'associate'
}
},
- tracker.action.CopyIssueLink
+ tracker.action.MoveToTeam
+ )
+ // TODO: fix icon
+ createAction(
+ builder,
+ {
+ action: view.actionImpl.ValueSelector,
+ actionPopup: tracker.component.RelationsPopup,
+ actionProps: {
+ attribute: ''
+ },
+ label: tracker.string.Relations,
+ icon: tracker.icon.Document,
+ keyBinding: [],
+ input: 'focus',
+ category: tracker.category.Tracker,
+ target: tracker.class.Issue,
+ context: {
+ mode: ['context', 'browser'],
+ application: tracker.app.Tracker,
+ group: 'associate'
+ }
+ },
+ tracker.action.Relations
)
}
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 366314db8e..4471c94d71 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -34,6 +34,7 @@
"dependencies": {
"@anticrm/platform": "~0.6.6",
"@anticrm/theme": "~0.6.0",
+ "@anticrm/core": "~0.6.16",
"svelte": "^3.47",
"@types/jest": "~28.1.0"
}
diff --git a/packages/ui/src/components/Menu.svelte b/packages/ui/src/components/Menu.svelte
index 63ba26ee4b..888fac62b5 100644
--- a/packages/ui/src/components/Menu.svelte
+++ b/packages/ui/src/components/Menu.svelte
@@ -14,6 +14,7 @@
-->
+
+
diff --git a/plugins/tracker-resources/src/components/SelectIssuePopup.svelte b/plugins/tracker-resources/src/components/SelectIssuePopup.svelte
new file mode 100644
index 0000000000..bdbfd396a9
--- /dev/null
+++ b/plugins/tracker-resources/src/components/SelectIssuePopup.svelte
@@ -0,0 +1,49 @@
+
+
+
+
+ {@const { icon } = issue.$lookup?.status.$lookup?.category ?? {}}
+ {@const issueId = getIssueId(issue.$lookup.space, issue)}
+ {#if issueId && icon}
+
+
+
+
+
{issueId}
+
{issue.title}
+
+ {/if}
+
+
diff --git a/plugins/tracker-resources/src/components/SelectRelationPopup.svelte b/plugins/tracker-resources/src/components/SelectRelationPopup.svelte
new file mode 100644
index 0000000000..c2ce98c9e8
--- /dev/null
+++ b/plugins/tracker-resources/src/components/SelectRelationPopup.svelte
@@ -0,0 +1,70 @@
+
+
+{#await getValue()}
+
+{:then value}
+ {
+ if (e.detail === undefined) dispatch('close')
+ else dispatch('close', value[e.detail])
+ }}
+ />
+{/await}
diff --git a/plugins/tracker-resources/src/components/issues/RelationEditor.svelte b/plugins/tracker-resources/src/components/issues/RelationEditor.svelte
new file mode 100644
index 0000000000..531ba84ccc
--- /dev/null
+++ b/plugins/tracker-resources/src/components/issues/RelationEditor.svelte
@@ -0,0 +1,83 @@
+
+
+
+ {#each issues as issue}
+ {#if issue.$lookup?.space}
+
+
+ {getIssueId(issue.$lookup.space, issue)}
+
+
+ {/if}
+ {/each}
+
+
+
diff --git a/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte b/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte
index 6ff36cac79..65b714e4fa 100644
--- a/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte
+++ b/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte
@@ -15,6 +15,7 @@
@@ -34,6 +42,25 @@
+ {#if issue.blockedBy?.length}
+
+
+
+
+ {/if}
+ {#if showIsBlocking}
+
+
+
+
+ {/if}
+ {#if issue.relatedIssue?.length}
+
+
+
+
+ {/if}
+
diff --git a/plugins/tracker-resources/src/index.ts b/plugins/tracker-resources/src/index.ts
index 97d6f7fc51..914fd32b75 100644
--- a/plugins/tracker-resources/src/index.ts
+++ b/plugins/tracker-resources/src/index.ts
@@ -59,6 +59,7 @@ import KanbanView from './components/issues/KanbanView.svelte'
import tracker from './plugin'
import { copyToClipboard, getIssueId, getIssueTitle, resolveLocation } from './issues'
import CreateIssue from './components/CreateIssue.svelte'
+import RelationsPopup from './components/RelationsPopup.svelte'
export async function queryIssue
(
_class: Ref>,
@@ -149,6 +150,7 @@ export default async (): Promise => ({
TeamProjects,
Roadmap,
IssuePreview,
+ RelationsPopup,
CreateIssue
},
completion: {
diff --git a/plugins/tracker-resources/src/issues.ts b/plugins/tracker-resources/src/issues.ts
index e5761a23ff..82588863dd 100644
--- a/plugins/tracker-resources/src/issues.ts
+++ b/plugins/tracker-resources/src/issues.ts
@@ -95,3 +95,16 @@ export async function resolveLocation (loc: Location): Promise,
+ prop: 'blockedBy' | 'relatedIssue',
+ operation: '$push' | '$pull'
+): Promise {
+ const update = Array.isArray(value[prop])
+ ? { [operation]: { [prop]: id } }
+ : { [prop]: operation === '$push' ? [id] : [] }
+ await client.update(value, update)
+}
diff --git a/plugins/tracker-resources/src/plugin.ts b/plugins/tracker-resources/src/plugin.ts
index 508ac29f2e..d76f965a07 100644
--- a/plugins/tracker-resources/src/plugin.ts
+++ b/plugins/tracker-resources/src/plugin.ts
@@ -140,6 +140,7 @@ export default mergeIds(trackerId, tracker, {
List: '' as IntlString,
NumberLabels: '' as IntlString,
Roadmap: '' as IntlString,
+ MoveToTeam: '' as IntlString,
IssueTitlePlaceholder: '' as IntlString,
IssueDescriptionPlaceholder: '' as IntlString,
@@ -168,6 +169,20 @@ export default mergeIds(trackerId, tracker, {
Created: '' as IntlString,
Subscribed: '' as IntlString,
+ Relations: '' as IntlString,
+ RemoveRelation: '' as IntlString,
+ AddBlockedBy: '' as IntlString,
+ AddIsBlocking: '' as IntlString,
+ AddRelatedIssue: '' as IntlString,
+ RelatedIssue: '' as IntlString,
+ BlockedIssue: '' as IntlString,
+ BlockingIssue: '' as IntlString,
+ BlockedBySearchPlaceholder: '' as IntlString,
+ IsBlockingSearchPlaceholder: '' as IntlString,
+ RelatedIssueSearchPlaceholder: '' as IntlString,
+ Blocks: '' as IntlString,
+ Related: '' as IntlString,
+
DurMinutes: '' as IntlString,
DurHours: '' as IntlString,
DurDays: '' as IntlString,
@@ -215,6 +230,7 @@ export default mergeIds(trackerId, tracker, {
Roadmap: '' as AnyComponent,
TeamProjects: '' as AnyComponent,
IssuePreview: '' as AnyComponent,
+ RelationsPopup: '' as AnyComponent,
CreateIssue: '' as AnyComponent
},
function: {
diff --git a/plugins/tracker/src/index.ts b/plugins/tracker/src/index.ts
index de2afbc6c3..743dd595f9 100644
--- a/plugins/tracker/src/index.ts
+++ b/plugins/tracker/src/index.ts
@@ -284,6 +284,8 @@ export default plugin(trackerId, {
SetProject: '' as Ref,
CopyIssueId: '' as Ref,
CopyIssueTitle: '' as Ref,
+ MoveToTeam: '' as Ref,
+ Relations: '' as Ref,
CopyIssueLink: '' as Ref
},
team: {