From 1db0417e8584d2165d21b267372225a9a2a7327c Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Tue, 22 Mar 2022 16:09:58 +0700 Subject: [PATCH] My assigned issues/applications (#1184) Signed-off-by: Andrey Sobolev --- models/recruit/src/index.ts | 38 +++++- models/task/src/index.ts | 14 ++ models/task/src/plugin.ts | 1 - plugins/task-assets/lang/en.json | 4 +- plugins/task-assets/lang/ru.json | 4 +- plugins/task-resources/package.json | 3 +- .../src/components/AssignedTasks.svelte | 129 ++++++++++++++++++ plugins/task-resources/src/index.ts | 4 +- plugins/task-resources/src/plugin.ts | 9 +- .../src/components/Table.svelte | 5 + .../src/components/Workbench.svelte | 11 +- plugins/workbench/src/index.ts | 1 + 12 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 plugins/task-resources/src/components/AssignedTasks.svelte diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index ed3ccae000..b87603a794 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -183,6 +183,17 @@ export function createModel (builder: Builder): void { label: recruit.string.SkillsLabel, createItemLabel: recruit.string.SkillCreateLabel, position: 'bottom' + }, + { + id: 'assigned', + label: task.string.Assigned, + icon: task.icon.Task, + component: task.component.AssignedTasks, + componentProps: { + labelTasks: recruit.string.Applications, + _class: recruit.class.Applicant + }, + position: 'top' } ] } @@ -206,8 +217,16 @@ export function createModel (builder: Builder): void { '', 'title', 'city', - { presenter: recruit.component.ApplicationsPresenter, label: recruit.string.ApplicationsShort, sortingKey: 'applications' }, - { presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' }, + { + presenter: recruit.component.ApplicationsPresenter, + label: recruit.string.ApplicationsShort, + sortingKey: 'applications' + }, + { + presenter: attachment.component.AttachmentsPresenter, + label: attachment.string.Files, + sortingKey: 'attachments' + }, { presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' }, { // key: '$lookup.skills', // Required, since presenter require list of tag references or '' and TagsPopupPresenter @@ -244,7 +263,11 @@ export function createModel (builder: Builder): void { '$lookup.assignee', '$lookup.state', '$lookup.doneState', - { presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' }, + { + presenter: attachment.component.AttachmentsPresenter, + label: attachment.string.Files, + sortingKey: 'attachments' + }, { presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' }, 'modifiedOn', '$lookup.attachedTo.$lookup.channels' @@ -279,7 +302,11 @@ export function createModel (builder: Builder): void { '$lookup.assignee', '$lookup.state', '$lookup.doneState', - { presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' }, + { + presenter: attachment.component.AttachmentsPresenter, + label: attachment.string.Files, + sortingKey: 'attachments' + }, { presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' }, 'modifiedOn', '$lookup.attachedTo.$lookup.channels' @@ -399,8 +426,7 @@ export function createModel (builder: Builder): void { builder.createDoc(view.class.ActionTarget, core.space.Model, { target: recruit.class.Vacancy, action: recruit.action.EditVacancy, - query: { - } + query: {} }) builder.mixin(recruit.class.Vacancy, core.class.Class, view.mixin.IgnoreActions, { diff --git a/models/task/src/index.ts b/models/task/src/index.ts index 4f1253d25a..66fb59ffcf 100644 --- a/models/task/src/index.ts +++ b/models/task/src/index.ts @@ -84,6 +84,7 @@ export class TLostState extends TDoneState implements LostState {} * No domain is specified, since pure Tasks could not exists */ @Model(task.class.Task, core.class.AttachedDoc, DOMAIN_TASK, [task.interface.DocWithRank]) +@UX(task.string.Task, task.icon.Task, task.string.Task) export class TTask extends TAttachedDoc implements Task { @Prop(TypeRef(task.class.State), task.string.TaskState) state!: Ref @@ -279,6 +280,15 @@ export function createModel (builder: Builder): void { addSpaceLabel: task.string.CreateProject, createComponent: task.component.CreateProject } + ], + specials: [ + { + id: 'assigned', + label: task.string.Assigned, + icon: task.icon.Task, + component: task.component.AssignedTasks, + position: 'top' + } ] } }, @@ -302,6 +312,10 @@ export function createModel (builder: Builder): void { ] }) + builder.mixin(task.class.Task, core.class.Class, view.mixin.AttributePresenter, { + presenter: view.component.ObjectPresenter + }) + builder.mixin(task.class.Issue, core.class.Class, view.mixin.AttributePresenter, { presenter: task.component.TaskPresenter }) diff --git a/models/task/src/plugin.ts b/models/task/src/plugin.ts index d403dfc432..134f463a49 100644 --- a/models/task/src/plugin.ts +++ b/models/task/src/plugin.ts @@ -66,7 +66,6 @@ export default mergeIds(taskId, task, { Todo: '' as IntlString, TaskDone: '' as IntlString, TaskDueTo: '' as IntlString, - Task: '' as IntlString, TaskParent: '' as IntlString, IssueName: '' as IntlString, TaskComments: '' as IntlString, diff --git a/plugins/task-assets/lang/en.json b/plugins/task-assets/lang/en.json index 822ad93cd6..490c67f189 100644 --- a/plugins/task-assets/lang/en.json +++ b/plugins/task-assets/lang/en.json @@ -72,6 +72,8 @@ "StatusDelete": "Delete status", "StatusDeleteConfirm": "Do you want to delete this status?", "CantStatusDelete": "Can't delete status", - "CantStatusDeleteError": "There are objects in the given state. Move or delete them first." + "CantStatusDeleteError": "There are objects in the given state. Move or delete them first.", + "Tasks": "Tasks", + "Assigned": "Assigned to me" } } \ No newline at end of file diff --git a/plugins/task-assets/lang/ru.json b/plugins/task-assets/lang/ru.json index bc08f9a00b..a30d022099 100644 --- a/plugins/task-assets/lang/ru.json +++ b/plugins/task-assets/lang/ru.json @@ -72,6 +72,8 @@ "StatusDelete": "Удалить статус", "StatusDeleteConfirm": "Вы действительно хотите удалить этот статус?", "CantStatusDelete": "Невозможно удалить статус", - "CantStatusDeleteError": "Есть объекты с данным статусом. Сначала переместите или удалите их. " + "CantStatusDeleteError": "Есть объекты с данным статусом. Сначала переместите или удалите их. ", + "Tasks": "Задачи", + "Assigned": "Назначения" } } \ No newline at end of file diff --git a/plugins/task-resources/package.json b/plugins/task-resources/package.json index 614f38b049..b0f93c323a 100644 --- a/plugins/task-resources/package.json +++ b/plugins/task-resources/package.json @@ -47,6 +47,7 @@ "@anticrm/attachment-resources": "~0.6.0", "@anticrm/chunter-resources": "~0.6.0", "@anticrm/workbench": "~0.6.1", - "@anticrm/notification": "~0.6.0" + "@anticrm/notification": "~0.6.0", + "@anticrm/tags": "~0.6.1" } } diff --git a/plugins/task-resources/src/components/AssignedTasks.svelte b/plugins/task-resources/src/components/AssignedTasks.svelte new file mode 100644 index 0000000000..74e27640fb --- /dev/null +++ b/plugins/task-resources/src/components/AssignedTasks.svelte @@ -0,0 +1,129 @@ + + + +
+
+
+ +
+ + { + updateResultQuery(search, documentIds, doneStates) + }} + /> +
+ + updateCategory(evt.detail)} +/> + + + + diff --git a/plugins/task-resources/src/index.ts b/plugins/task-resources/src/index.ts index 8dd2c57aac..e5becc1953 100644 --- a/plugins/task-resources/src/index.ts +++ b/plugins/task-resources/src/index.ts @@ -39,6 +39,7 @@ import TemplatesIcon from './components/TemplatesIcon.svelte' import TodoItemPresenter from './components/todos/TodoItemPresenter.svelte' import Todos from './components/todos/Todos.svelte' import TodoStatePresenter from './components/todos/TodoStatePresenter.svelte' +import AssignedTasks from './components/AssignedTasks.svelte' import task from './plugin' async function createTask (object: Doc): Promise { @@ -145,7 +146,8 @@ export default async (): Promise => ({ TaskHeader, DoneStateEditor, KanbanTemplateEditor, - KanbanTemplateSelector + KanbanTemplateSelector, + AssignedTasks }, actionImpl: { CreateTask: createTask, diff --git a/plugins/task-resources/src/plugin.ts b/plugins/task-resources/src/plugin.ts index 7d748cafe4..1dc2d423f8 100644 --- a/plugins/task-resources/src/plugin.ts +++ b/plugins/task-resources/src/plugin.ts @@ -68,12 +68,17 @@ export default mergeIds(taskId, task, { CantStatusDelete: '' as IntlString, CantStatusDeleteError: '' as IntlString, Archive: '' as IntlString, - Unarchive: '' as IntlString + Unarchive: '' as IntlString, + + Tasks: '' as IntlString, + Assigned: '' as IntlString, + Task: '' as IntlString }, status: { AssigneeRequired: '' as IntlString }, component: { - TodoStatePresenter: '' as AnyComponent + TodoStatePresenter: '' as AnyComponent, + AssignedTasks: '' as AnyComponent } }) diff --git a/plugins/view-resources/src/components/Table.svelte b/plugins/view-resources/src/components/Table.svelte index a27ad69e76..0e7474189e 100644 --- a/plugins/view-resources/src/components/Table.svelte +++ b/plugins/view-resources/src/components/Table.svelte @@ -47,6 +47,7 @@ $: sortingFunction = (config.find(it => (typeof it !== 'string') && it.sortingKey === sortKey) as BuildModelKey)?.sortingFunction + let qindex = 0 async function update ( _class: Ref>, query: DocumentQuery, @@ -54,11 +55,15 @@ sortOrder: SortingOrder, options?: FindOptions ) { + const c = ++qindex loading = true q.query( _class, query, (result) => { + if (c !== qindex) { + return // our data is invalid. + } objects = result if (sortingFunction !== undefined) { const sf = sortingFunction diff --git a/plugins/workbench-resources/src/components/Workbench.svelte b/plugins/workbench-resources/src/components/Workbench.svelte index 230cb63edd..999e5495a8 100644 --- a/plugins/workbench-resources/src/components/Workbench.svelte +++ b/plugins/workbench-resources/src/components/Workbench.svelte @@ -31,7 +31,7 @@ showPopup, TooltipInstance } from '@anticrm/ui' - import type { Application, NavigatorModel, ViewConfiguration } from '@anticrm/workbench' + import type { Application, NavigatorModel, SpecialNavModel, ViewConfiguration } from '@anticrm/workbench' import { onDestroy } from 'svelte' import workbench from '../plugin' import AccountPopup from './AccountPopup.svelte' @@ -51,7 +51,7 @@ let currentApp: Ref | undefined let currentSpace: Ref | undefined let currentSpecial: string | undefined - let specialComponent: AnyComponent | undefined + let specialComponent: SpecialNavModel | undefined let currentApplication: Application | undefined let currentView: ViewConfiguration | undefined @@ -134,9 +134,8 @@ navigate(loc) } - function getSpecialComponent (id: string): AnyComponent | undefined { - const special = navigatorModel?.specials?.find((x) => x.id === id) - return special?.component + function getSpecialComponent (id: string): SpecialNavModel | undefined { + return navigatorModel?.specials?.find((x) => x.id === id) } let apps: Application[] = [] @@ -295,7 +294,7 @@ {#if currentApplication && currentApplication.component} {:else if specialComponent} - + {:else} {/if} diff --git a/plugins/workbench/src/index.ts b/plugins/workbench/src/index.ts index 117d598c71..e1294bbebd 100644 --- a/plugins/workbench/src/index.ts +++ b/plugins/workbench/src/index.ts @@ -57,6 +57,7 @@ export interface SpecialNavModel { label: IntlString icon: Asset component: AnyComponent + componentProps?: Record position?: 'top'|'bottom' // undefined == 'top visibleIf?: Resource<(spaces: Space[]) => boolean> // If defined, will be used to find spaces for visibleIf