From fff4debc49760b490be9c734ee2338ee7e67178d Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Wed, 15 Mar 2023 21:26:33 +0600 Subject: [PATCH] =?UTF-8?q?TSK-806=20=D0=9F=D1=80=D0=BE=D0=BF=D0=B0=D0=B4?= =?UTF-8?q?=D0=B0=D1=8E=D1=82=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B5=20View=20(#2738)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Denis Bykhov --- models/board/src/index.ts | 30 +- models/board/src/plugin.ts | 4 +- models/lead/src/index.ts | 44 ++- models/lead/src/plugin.ts | 4 +- models/recruit/src/index.ts | 40 ++- models/recruit/src/plugin.ts | 4 +- models/task/src/index.ts | 31 +- models/task/src/plugin.ts | 3 +- models/tracker/src/index.ts | 318 ++++++++++-------- models/tracker/src/plugin.ts | 6 +- models/view/src/index.ts | 1 + .../src/components/Events.svelte | 10 +- .../src/components/Contacts.svelte | 5 +- .../src/components/Members.svelte | 10 +- .../src/components/Documents.svelte | 3 +- .../src/components/DepartmentStaff.svelte | 10 +- .../components/schedule/MonthTableView.svelte | 10 +- .../src/components/Organizations.svelte | 3 +- .../src/components/Vacancies.svelte | 3 +- plugins/recruit/src/index.ts | 1 + .../src/components/issues/IssuesView.svelte | 10 +- .../components/issues/edit/SubIssues.svelte | 10 +- .../related/RelatedIssuesSection.svelte | 9 +- .../components/sprints/SprintBrowser.svelte | 3 +- .../templates/IssueTemplatesView.svelte | 10 +- .../src/components/filter/FilterBar.svelte | 19 +- .../src/components/filter/FilterSave.svelte | 3 +- plugins/view-resources/src/filter.ts | 9 +- plugins/view-resources/src/viewOptions.ts | 30 +- plugins/view/src/index.ts | 1 + .../src/components/SavedView.svelte | 14 +- .../src/components/SpaceView.svelte | 4 +- .../src/components/SpecialView.svelte | 3 +- 33 files changed, 412 insertions(+), 253 deletions(-) diff --git a/models/board/src/index.ts b/models/board/src/index.ts index 640c2fc096..c27486fbac 100644 --- a/models/board/src/index.ts +++ b/models/board/src/index.ts @@ -192,17 +192,27 @@ export function createModel (builder: Builder): void { // ] // }) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: board.class.Card, - descriptor: board.viewlet.Kanban, - config: [] - }) + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: board.class.Card, + descriptor: board.viewlet.Kanban, + config: [] + }, + board.viewlet.KanbanCard + ) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: board.class.Card, - descriptor: board.viewlet.Table, - config: [] - }) + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: board.class.Card, + descriptor: board.viewlet.Table, + config: [] + }, + board.viewlet.TableCard + ) builder.mixin(board.class.Card, core.class.Class, task.mixin.KanbanCard, { card: board.component.KanbanCard diff --git a/models/board/src/plugin.ts b/models/board/src/plugin.ts index d9048c7a0f..650af33cb9 100644 --- a/models/board/src/plugin.ts +++ b/models/board/src/plugin.ts @@ -20,7 +20,7 @@ import type { Ref, Space } from '@hcengineering/core' import { IntlString, mergeIds } from '@hcengineering/platform' import { KanbanTemplate, Sequence } from '@hcengineering/task' import type { AnyComponent } from '@hcengineering/ui' -import { Action, ViewAction, ViewletDescriptor } from '@hcengineering/view' +import { Action, ViewAction, Viewlet, ViewletDescriptor } from '@hcengineering/view' export default mergeIds(boardId, board, { component: { @@ -51,6 +51,8 @@ export default mergeIds(boardId, board, { Sequence: '' as Ref }, viewlet: { + KanbanCard: '' as Ref, + TableCard: '' as Ref, Kanban: '' as Ref, Table: '' as Ref }, diff --git a/models/lead/src/index.ts b/models/lead/src/index.ts index ea5370d9fc..faa32e3870 100644 --- a/models/lead/src/index.ts +++ b/models/lead/src/index.ts @@ -257,24 +257,34 @@ export function createModel (builder: Builder): void { lead.viewlet.ListLead ) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: lead.class.Lead, - descriptor: task.viewlet.Kanban, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - options: { - lookup: { - attachedTo: lead.mixin.Customer - } - } as FindOptions, // TODO: fix - config: [] - }) + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: lead.class.Lead, + descriptor: task.viewlet.Kanban, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + options: { + lookup: { + attachedTo: lead.mixin.Customer + } + } as FindOptions, // TODO: fix + config: [] + }, + lead.viewlet.KanbanLead + ) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: lead.class.Lead, - descriptor: task.viewlet.Dashboard, - options: {}, - config: [] - }) + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: lead.class.Lead, + descriptor: task.viewlet.Dashboard, + options: {}, + config: [] + }, + lead.viewlet.DashboardLead + ) builder.mixin(lead.class.Lead, core.class.Class, task.mixin.KanbanCard, { card: lead.component.KanbanCard diff --git a/models/lead/src/plugin.ts b/models/lead/src/plugin.ts index 77b1e4a7be..ab237623c5 100644 --- a/models/lead/src/plugin.ts +++ b/models/lead/src/plugin.ts @@ -52,7 +52,9 @@ export default mergeIds(leadId, lead, { viewlet: { TableCustomer: '' as Ref, TableLead: '' as Ref, - ListLead: '' as Ref + ListLead: '' as Ref, + DashboardLead: '' as Ref, + KanbanLead: '' as Ref }, category: { Lead: '' as Ref diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 2532e888cc..00594917e2 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -565,22 +565,32 @@ export function createModel (builder: Builder): void { } } - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: recruit.class.Applicant, - descriptor: task.viewlet.Kanban, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - options: { - lookup: applicantKanbanLookup - } as FindOptions, // TODO: fix - config: [] - }) + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: recruit.class.Applicant, + descriptor: task.viewlet.Kanban, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + options: { + lookup: applicantKanbanLookup + } as FindOptions, // TODO: fix + config: [] + }, + recruit.viewlet.ApplicantKanban + ) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: recruit.class.Applicant, - descriptor: task.viewlet.Dashboard, - options: {}, - config: [] - }) + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: recruit.class.Applicant, + descriptor: task.viewlet.Dashboard, + options: {}, + config: [] + }, + recruit.viewlet.ApplicantDashboard + ) builder.mixin(recruit.class.Applicant, core.class.Class, task.mixin.KanbanCard, { card: recruit.component.KanbanCard diff --git a/models/recruit/src/plugin.ts b/models/recruit/src/plugin.ts index 7a6555451e..62445984a3 100644 --- a/models/recruit/src/plugin.ts +++ b/models/recruit/src/plugin.ts @@ -100,10 +100,12 @@ export default mergeIds(recruitId, recruit, { TableCandidate: '' as Ref, TableVacancy: '' as Ref, ApplicantTable: '' as Ref, + ApplicantKanban: '' as Ref, TableApplicant: '' as Ref, TableApplicantMatch: '' as Ref, CalendarReview: '' as Ref, TableReview: '' as Ref, - TableVacancyList: '' as Ref + TableVacancyList: '' as Ref, + ApplicantDashboard: '' as Ref } }) diff --git a/models/task/src/index.ts b/models/task/src/index.ts index ece159d044..b6cd5bbe14 100644 --- a/models/task/src/index.ts +++ b/models/task/src/index.ts @@ -387,20 +387,25 @@ export function createModel (builder: Builder): void { fields: ['assignee'] }) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: task.class.Issue, - descriptor: task.viewlet.Kanban, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - options: { - lookup: { - assignee: contact.class.Employee, - _id: { - todoItems: task.class.TodoItem + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: task.class.Issue, + descriptor: task.viewlet.Kanban, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + options: { + lookup: { + assignee: contact.class.Employee, + _id: { + todoItems: task.class.TodoItem + } } - } - } as FindOptions, - config: [] - }) + } as FindOptions, + config: [] + }, + task.viewlet.KanbanIssue + ) builder.mixin(task.class.Issue, core.class.Class, task.mixin.KanbanCard, { card: task.component.KanbanCard diff --git a/models/task/src/plugin.ts b/models/task/src/plugin.ts index 671b7ac249..6460749ab8 100644 --- a/models/task/src/plugin.ts +++ b/models/task/src/plugin.ts @@ -69,6 +69,7 @@ export default mergeIds(taskId, task, { DefaultProject: '' as Ref }, viewlet: { - TableIssue: '' as Ref + TableIssue: '' as Ref, + KanbanIssue: '' as Ref } }) diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index 87f19297fc..7372dcf283 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -540,71 +540,80 @@ export function createModel (builder: Builder): void { ] } - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: tracker.class.Issue, - descriptor: view.viewlet.List, - viewOptions: issuesOptions, - config: [ - { - key: '', - presenter: tracker.component.PriorityEditor, - props: { type: 'priority', kind: 'list', size: 'small' } - }, - { key: '', presenter: tracker.component.IssuePresenter, props: { type: 'issue', listProps: { fixed: 'left' } } }, - { - key: '', - presenter: tracker.component.StatusEditor, - props: { kind: 'list', size: 'small', justify: 'center' } - }, - { key: '', presenter: tracker.component.TitlePresenter, props: { shouldUseMargin: true } }, - { key: '', presenter: tracker.component.SubIssuesSelector, props: {} }, - { key: '', presenter: view.component.GrowPresenter, props: { type: 'grow' } }, - { key: '', presenter: tracker.component.DueDatePresenter, props: { kind: 'list' } }, - { - key: '', - presenter: tracker.component.ProjectEditor, - props: { - kind: 'list', - size: 'small', - shape: 'round', - shouldShowPlaceholder: false, - listProps: { - excludeByKey: 'project', - optional: true + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: tracker.class.Issue, + descriptor: view.viewlet.List, + viewOptions: issuesOptions, + config: [ + { + key: '', + presenter: tracker.component.PriorityEditor, + props: { type: 'priority', kind: 'list', size: 'small' } + }, + { + key: '', + presenter: tracker.component.IssuePresenter, + props: { type: 'issue', listProps: { fixed: 'left' } } + }, + { + key: '', + presenter: tracker.component.StatusEditor, + props: { kind: 'list', size: 'small', justify: 'center' } + }, + { key: '', presenter: tracker.component.TitlePresenter, props: { shouldUseMargin: true } }, + { key: '', presenter: tracker.component.SubIssuesSelector, props: {} }, + { key: '', presenter: view.component.GrowPresenter, props: { type: 'grow' } }, + { key: '', presenter: tracker.component.DueDatePresenter, props: { kind: 'list' } }, + { + key: '', + presenter: tracker.component.ProjectEditor, + props: { + kind: 'list', + size: 'small', + shape: 'round', + shouldShowPlaceholder: false, + listProps: { + excludeByKey: 'project', + optional: true + } } - } - }, - { - key: '', - presenter: tracker.component.SprintEditor, - props: { - kind: 'list', - size: 'small', - shape: 'round', - shouldShowPlaceholder: false, - listProps: { - excludeByKey: 'sprint', - optional: true + }, + { + key: '', + presenter: tracker.component.SprintEditor, + props: { + kind: 'list', + size: 'small', + shape: 'round', + shouldShowPlaceholder: false, + listProps: { + excludeByKey: 'sprint', + optional: true + } } + }, + { + key: '', + presenter: tracker.component.EstimationEditor, + props: { kind: 'list', size: 'small', listProps: { optional: true } } + }, + { + key: 'modifiedOn', + presenter: tracker.component.ModificationDatePresenter, + props: { listProps: { fixed: 'right', optional: true } } + }, + { + key: '$lookup.assignee', + presenter: tracker.component.AssigneePresenter, + props: { defaultClass: contact.class.Employee, shouldShowLabel: false } } - }, - { - key: '', - presenter: tracker.component.EstimationEditor, - props: { kind: 'list', size: 'small', listProps: { optional: true } } - }, - { - key: 'modifiedOn', - presenter: tracker.component.ModificationDatePresenter, - props: { listProps: { fixed: 'right', optional: true } } - }, - { - key: '$lookup.assignee', - presenter: tracker.component.AssigneePresenter, - props: { defaultClass: contact.class.Employee, shouldShowLabel: false } - } - ] - }) + ] + }, + tracker.viewlet.IssueList + ) const subIssuesOptions: ViewOptionsModel = { groupBy: ['status', 'assignee', 'priority', 'sprint'], @@ -681,57 +690,71 @@ export function createModel (builder: Builder): void { tracker.viewlet.SubIssues ) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: tracker.class.IssueTemplate, - descriptor: view.viewlet.List, - viewOptions: { - groupBy: ['assignee', 'priority', 'project', 'sprint'], - orderBy: [ - ['priority', SortingOrder.Ascending], - ['modifiedOn', SortingOrder.Descending], - ['dueDate', SortingOrder.Descending], - ['rank', SortingOrder.Ascending] - ], - other: [] + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: tracker.class.IssueTemplate, + descriptor: view.viewlet.List, + viewOptions: { + groupBy: ['assignee', 'priority', 'project', 'sprint'], + orderBy: [ + ['priority', SortingOrder.Ascending], + ['modifiedOn', SortingOrder.Descending], + ['dueDate', SortingOrder.Descending], + ['rank', SortingOrder.Ascending] + ], + other: [] + }, + config: [ + // { key: '', presenter: tracker.component.PriorityEditor, props: { kind: 'list', size: 'small' } }, + { + key: '', + presenter: tracker.component.IssueTemplatePresenter, + props: { type: 'issue', shouldUseMargin: true } + }, + { key: '', presenter: view.component.GrowPresenter, props: { type: 'grow' } }, + // { key: '', presenter: tracker.component.DueDatePresenter, props: { kind: 'list' } }, + { + key: '', + presenter: tracker.component.ProjectEditor, + props: { kind: 'list', size: 'small', shape: 'round', shouldShowPlaceholder: false } + }, + { + key: '', + presenter: tracker.component.SprintEditor, + props: { kind: 'list', size: 'small', shape: 'round', shouldShowPlaceholder: false } + }, + { key: '', presenter: tracker.component.TemplateEstimationEditor, props: { kind: 'list', size: 'small' } }, + { + key: 'modifiedOn', + presenter: tracker.component.ModificationDatePresenter, + props: { listProps: { fixed: 'right' } } + }, + { + key: '$lookup.assignee', + presenter: tracker.component.AssigneePresenter, + props: { defaultClass: contact.class.Employee, shouldShowLabel: false } + } + ] }, - config: [ - // { key: '', presenter: tracker.component.PriorityEditor, props: { kind: 'list', size: 'small' } }, - { key: '', presenter: tracker.component.IssueTemplatePresenter, props: { type: 'issue', shouldUseMargin: true } }, - { key: '', presenter: view.component.GrowPresenter, props: { type: 'grow' } }, - // { key: '', presenter: tracker.component.DueDatePresenter, props: { kind: 'list' } }, - { - key: '', - presenter: tracker.component.ProjectEditor, - props: { kind: 'list', size: 'small', shape: 'round', shouldShowPlaceholder: false } - }, - { - key: '', - presenter: tracker.component.SprintEditor, - props: { kind: 'list', size: 'small', shape: 'round', shouldShowPlaceholder: false } - }, - { key: '', presenter: tracker.component.TemplateEstimationEditor, props: { kind: 'list', size: 'small' } }, - { - key: 'modifiedOn', - presenter: tracker.component.ModificationDatePresenter, - props: { listProps: { fixed: 'right' } } - }, - { - key: '$lookup.assignee', - presenter: tracker.component.AssigneePresenter, - props: { defaultClass: contact.class.Employee, shouldShowLabel: false } - } - ] - }) + tracker.viewlet.IssueTemplateList + ) - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: tracker.class.Issue, - descriptor: tracker.viewlet.Kanban, - viewOptions: { - ...issuesOptions, - groupDepth: 1 + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: tracker.class.Issue, + descriptor: tracker.viewlet.Kanban, + viewOptions: { + ...issuesOptions, + groupDepth: 1 + }, + config: [] }, - config: [] - }) + tracker.viewlet.IssueKanban + ) builder.createDoc( view.class.ViewletDescriptor, @@ -1669,42 +1692,47 @@ export function createModel (builder: Builder): void { other: [] } - builder.createDoc(view.class.Viewlet, core.space.Model, { - attachTo: tracker.class.Sprint, - descriptor: view.viewlet.List, - viewOptions: sprintOptions, - config: [ - { - key: '', - presenter: tracker.component.SprintStatusPresenter, - props: { width: '1rem', kind: 'list', size: 'small', justify: 'center' } - }, - { key: '', presenter: tracker.component.SprintPresenter, props: { shouldUseMargin: true } }, - { key: '', presenter: view.component.GrowPresenter, props: { type: 'grow' } }, - { key: '', presenter: tracker.component.SprintProjectEditor, props: { kind: 'list' } }, - { - key: '', - presenter: contact.component.MembersPresenter, - props: { - kind: 'link', - intlTitle: tracker.string.SprintMembersTitle, - intlSearchPh: tracker.string.SprintMembersSearchPlaceholder + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: tracker.class.Sprint, + descriptor: view.viewlet.List, + viewOptions: sprintOptions, + config: [ + { + key: '', + presenter: tracker.component.SprintStatusPresenter, + props: { width: '1rem', kind: 'list', size: 'small', justify: 'center' } + }, + { key: '', presenter: tracker.component.SprintPresenter, props: { shouldUseMargin: true } }, + { key: '', presenter: view.component.GrowPresenter, props: { type: 'grow' } }, + { key: '', presenter: tracker.component.SprintProjectEditor, props: { kind: 'list' } }, + { + key: '', + presenter: contact.component.MembersPresenter, + props: { + kind: 'link', + intlTitle: tracker.string.SprintMembersTitle, + intlSearchPh: tracker.string.SprintMembersSearchPlaceholder + } + }, + { key: '', presenter: tracker.component.SprintDatePresenter, props: { field: 'startDate' } }, + { key: '', presenter: tracker.component.SprintDatePresenter, props: { field: 'targetDate' } }, + { + key: '$lookup.lead', + presenter: tracker.component.SprintLeadPresenter, + props: { + _class: tracker.class.Sprint, + defaultClass: contact.class.Employee, + shouldShowLabel: false, + size: 'x-small' + } } - }, - { key: '', presenter: tracker.component.SprintDatePresenter, props: { field: 'startDate' } }, - { key: '', presenter: tracker.component.SprintDatePresenter, props: { field: 'targetDate' } }, - { - key: '$lookup.lead', - presenter: tracker.component.SprintLeadPresenter, - props: { - _class: tracker.class.Sprint, - defaultClass: contact.class.Employee, - shouldShowLabel: false, - size: 'x-small' - } - } - ] - }) + ] + }, + tracker.viewlet.SprintList + ) createAction( builder, diff --git a/models/tracker/src/plugin.ts b/models/tracker/src/plugin.ts index b4bc971da1..36f2fbc95f 100644 --- a/models/tracker/src/plugin.ts +++ b/models/tracker/src/plugin.ts @@ -20,7 +20,7 @@ import { IntlString, mergeIds, Resource } from '@hcengineering/platform' import { trackerId } from '@hcengineering/tracker' import tracker from '@hcengineering/tracker-resources/src/plugin' import type { AnyComponent } from '@hcengineering/ui/src/types' -import { Action, ViewAction, ViewletDescriptor } from '@hcengineering/view' +import { Action, ViewAction, Viewlet, ViewletDescriptor } from '@hcengineering/view' import { Application } from '@hcengineering/workbench' export default mergeIds(trackerId, tracker, { @@ -47,6 +47,10 @@ export default mergeIds(trackerId, tracker, { Tracker: '' as Ref }, viewlet: { + IssueList: '' as Ref, + IssueTemplateList: '' as Ref, + IssueKanban: '' as Ref, + SprintList: '' as Ref, List: '' as Ref, Kanban: '' as Ref }, diff --git a/models/view/src/index.ts b/models/view/src/index.ts index aa80abef1f..3248cc2489 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -105,6 +105,7 @@ export class TFilteredView extends TPreference implements FilteredView { location!: Location filters!: string viewOptions?: ViewOptions + filterClass?: Ref> viewletId?: Ref | null } diff --git a/plugins/calendar-resources/src/components/Events.svelte b/plugins/calendar-resources/src/components/Events.svelte index c9bfc1e191..4931adeb17 100644 --- a/plugins/calendar-resources/src/components/Events.svelte +++ b/plugins/calendar-resources/src/components/Events.svelte @@ -30,7 +30,13 @@ TabList } from '@hcengineering/ui' import view, { Viewlet, ViewletPreference } from '@hcengineering/view' - import { FilterButton, getViewOptions, setActiveViewletId, ViewletSettingButton } from '@hcengineering/view-resources' + import { + FilterButton, + getViewOptions, + setActiveViewletId, + ViewletSettingButton, + viewOptionStore + } from '@hcengineering/view-resources' import calendar from '../plugin' import { deviceOptionsStore as deviceInfo } from '@hcengineering/ui' @@ -103,7 +109,7 @@ $: twoRows = $deviceInfo.twoRows - $: viewOptions = getViewOptions(selectedViewlet) + $: viewOptions = getViewOptions(selectedViewlet, $viewOptionStore)
diff --git a/plugins/contact-resources/src/components/Contacts.svelte b/plugins/contact-resources/src/components/Contacts.svelte index 47c90244f0..beb3bc5cc2 100644 --- a/plugins/contact-resources/src/components/Contacts.svelte +++ b/plugins/contact-resources/src/components/Contacts.svelte @@ -25,7 +25,8 @@ getViewOptions, setActiveViewletId, TableBrowser, - ViewletSettingButton + ViewletSettingButton, + viewOptionStore } from '@hcengineering/view-resources' import contact from '../plugin' import CreateContact from './CreateContact.svelte' @@ -75,7 +76,7 @@ $: twoRows = $deviceInfo.twoRows - $: viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore) @@ -91,7 +97,7 @@ } }) } - $: viewOptions = getViewOptions(descr) + $: viewOptions = getViewOptions(descr, $viewOptionStore)
diff --git a/plugins/document-resources/src/components/Documents.svelte b/plugins/document-resources/src/components/Documents.svelte index f45ed23466..01312f4fc6 100644 --- a/plugins/document-resources/src/components/Documents.svelte +++ b/plugins/document-resources/src/components/Documents.svelte @@ -25,6 +25,7 @@ FilterButton, getViewOptions, setActiveViewletId, + viewOptionStore, TableBrowser, ViewletSettingButton } from '@hcengineering/view-resources' @@ -72,7 +73,7 @@ let twoRows: boolean $: twoRows = $deviceInfo.docWidth <= 680 - $: viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore)
diff --git a/plugins/hr-resources/src/components/schedule/MonthTableView.svelte b/plugins/hr-resources/src/components/schedule/MonthTableView.svelte index 3a74d311dc..9b667221ae 100644 --- a/plugins/hr-resources/src/components/schedule/MonthTableView.svelte +++ b/plugins/hr-resources/src/components/schedule/MonthTableView.svelte @@ -20,7 +20,13 @@ import { createQuery, getClient } from '@hcengineering/presentation' import { Button, Label, Loading, Scroller, tableSP } from '@hcengineering/ui' import view, { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view' - import { getViewOptions, setActiveViewletId, Table, ViewletSettingButton } from '@hcengineering/view-resources' + import { + getViewOptions, + setActiveViewletId, + Table, + viewOptionStore, + ViewletSettingButton + } from '@hcengineering/view-resources' import hr from '../../plugin' import { EmployeeReports, @@ -258,7 +264,7 @@ return result } - $: viewOptions = getViewOptions(descr) + $: viewOptions = getViewOptions(descr, $viewOptionStore) {#if departmentStaff.length} diff --git a/plugins/recruit-resources/src/components/Organizations.svelte b/plugins/recruit-resources/src/components/Organizations.svelte index 9e3b77cf18..d94ff3d15f 100644 --- a/plugins/recruit-resources/src/components/Organizations.svelte +++ b/plugins/recruit-resources/src/components/Organizations.svelte @@ -32,6 +32,7 @@ FilterBar, FilterButton, getViewOptions, + viewOptionStore, setActiveViewletId, TableBrowser, ViewletSettingButton @@ -231,7 +232,7 @@ $: twoRows = $deviceInfo.twoRows - $: viewOptions = getViewOptions(descr) + $: viewOptions = getViewOptions(descr, $viewOptionStore)
diff --git a/plugins/recruit-resources/src/components/Vacancies.svelte b/plugins/recruit-resources/src/components/Vacancies.svelte index 19529fc07a..afeb5ac5b6 100644 --- a/plugins/recruit-resources/src/components/Vacancies.svelte +++ b/plugins/recruit-resources/src/components/Vacancies.svelte @@ -24,6 +24,7 @@ getViewOptions, setActiveViewletId, TableBrowser, + viewOptionStore, ViewletSettingButton } from '@hcengineering/view-resources' import recruit from '../plugin' @@ -142,7 +143,7 @@ $: twoRows = $deviceInfo.twoRows - $: viewOptions = getViewOptions(descr) + $: viewOptions = getViewOptions(descr, $viewOptionStore)
diff --git a/plugins/recruit/src/index.ts b/plugins/recruit/src/index.ts index ca60b37a1b..40f9e90996 100644 --- a/plugins/recruit/src/index.ts +++ b/plugins/recruit/src/index.ts @@ -85,6 +85,7 @@ export interface CandidateDraft extends Doc { * @public */ export interface Applicant extends Task { + space: Ref attachedTo: Ref attachments?: number comments?: number diff --git a/plugins/tracker-resources/src/components/issues/IssuesView.svelte b/plugins/tracker-resources/src/components/issues/IssuesView.svelte index 5847d6ed76..3c0ac21b81 100644 --- a/plugins/tracker-resources/src/components/issues/IssuesView.svelte +++ b/plugins/tracker-resources/src/components/issues/IssuesView.svelte @@ -5,7 +5,13 @@ import { Issue } from '@hcengineering/tracker' import { Button, IconDetails, IconDetailsFilled } from '@hcengineering/ui' import view, { Viewlet } from '@hcengineering/view' - import { FilterBar, getActiveViewletId, getViewOptions, setActiveViewletId } from '@hcengineering/view-resources' + import { + FilterBar, + getActiveViewletId, + getViewOptions, + viewOptionStore, + setActiveViewletId + } from '@hcengineering/view-resources' import ViewletSettingButton from '@hcengineering/view-resources/src/components/ViewletSettingButton.svelte' import tracker from '../../plugin' import IssuesContent from './IssuesContent.svelte' @@ -65,7 +71,7 @@ $: if (docWidth <= 900 && !docSize) docSize = true $: if (docWidth > 900 && docSize) docSize = false - $: viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore) diff --git a/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte b/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte index ded1e73586..13109fb2e9 100644 --- a/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/SubIssues.svelte @@ -29,7 +29,13 @@ navigate } from '@hcengineering/ui' import view, { Viewlet } from '@hcengineering/view' - import { createFilter, filterStore, getViewOptions, ViewletSettingButton } from '@hcengineering/view-resources' + import { + createFilter, + filterStore, + getViewOptions, + viewOptionStore, + ViewletSettingButton + } from '@hcengineering/view-resources' import tracker from '../../../plugin' import CreateSubIssue from './CreateSubIssue.svelte' import SubIssueList from './SubIssueList.svelte' @@ -86,7 +92,7 @@ statusesQuery.unsubscribe() } - $: viewOptions = viewlet !== undefined ? getViewOptions(viewlet) : undefined + $: viewOptions = viewlet !== undefined ? getViewOptions(viewlet, $viewOptionStore) : undefined
diff --git a/plugins/tracker-resources/src/components/issues/related/RelatedIssuesSection.svelte b/plugins/tracker-resources/src/components/issues/related/RelatedIssuesSection.svelte index a72e10eae0..c94c67b2b1 100644 --- a/plugins/tracker-resources/src/components/issues/related/RelatedIssuesSection.svelte +++ b/plugins/tracker-resources/src/components/issues/related/RelatedIssuesSection.svelte @@ -4,7 +4,12 @@ import { createQuery, getClient } from '@hcengineering/presentation' import { Button, Icon, IconAdd, Label, showPopup, Component } from '@hcengineering/ui' import view, { Viewlet } from '@hcengineering/view' - import { getViewOptions, ViewletSettingButton, getAdditionalHeader } from '@hcengineering/view-resources' + import { + getViewOptions, + ViewletSettingButton, + viewOptionStore, + getAdditionalHeader + } from '@hcengineering/view-resources' import viewplg from '@hcengineering/view-resources/src/plugin' import tracker from '../../../plugin' import RelatedIssues from './RelatedIssues.svelte' @@ -22,7 +27,7 @@ ;[viewlet] = res }) - let viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore) const createIssue = () => showPopup(tracker.component.CreateIssue, { relatedTo: object, space: object.space }, 'top') let query: DocumentQuery diff --git a/plugins/tracker-resources/src/components/sprints/SprintBrowser.svelte b/plugins/tracker-resources/src/components/sprints/SprintBrowser.svelte index 8c1834bb13..07a97b4e0d 100644 --- a/plugins/tracker-resources/src/components/sprints/SprintBrowser.svelte +++ b/plugins/tracker-resources/src/components/sprints/SprintBrowser.svelte @@ -24,6 +24,7 @@ FilterButton, getActiveViewletId, getViewOptions, + viewOptionStore, setActiveViewletId, ViewletSettingButton } from '@hcengineering/view-resources' @@ -90,7 +91,7 @@ $: if (docWidth <= 900 && !docSize) docSize = true $: if (docWidth > 900 && docSize) docSize = false - $: viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore) const handleViewModeChanged = (newMode: SprintViewMode) => { if (newMode === undefined || newMode === mode) { diff --git a/plugins/tracker-resources/src/components/templates/IssueTemplatesView.svelte b/plugins/tracker-resources/src/components/templates/IssueTemplatesView.svelte index 68f5d24e6e..0334175f98 100644 --- a/plugins/tracker-resources/src/components/templates/IssueTemplatesView.svelte +++ b/plugins/tracker-resources/src/components/templates/IssueTemplatesView.svelte @@ -5,7 +5,13 @@ import { IssueTemplate } from '@hcengineering/tracker' import { Button, IconAdd, IconDetails, IconDetailsFilled, showPopup } from '@hcengineering/ui' import view, { Viewlet } from '@hcengineering/view' - import { FilterBar, getActiveViewletId, getViewOptions, setActiveViewletId } from '@hcengineering/view-resources' + import { + FilterBar, + getActiveViewletId, + getViewOptions, + viewOptionStore, + setActiveViewletId + } from '@hcengineering/view-resources' import ViewletSettingButton from '@hcengineering/view-resources/src/components/ViewletSettingButton.svelte' import tracker from '../../plugin' import IssuesHeader from '../issues/IssuesHeader.svelte' @@ -71,7 +77,7 @@ showPopup(CreateIssueTemplate, { targetElement: null, space }, 'top') } - $: viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore) diff --git a/plugins/view-resources/src/components/filter/FilterBar.svelte b/plugins/view-resources/src/components/filter/FilterBar.svelte index 0bff4eb126..7af7dc12e6 100644 --- a/plugins/view-resources/src/components/filter/FilterBar.svelte +++ b/plugins/view-resources/src/components/filter/FilterBar.svelte @@ -16,14 +16,14 @@ import { Class, Doc, DocumentQuery, Ref } from '@hcengineering/core' import { getResource } from '@hcengineering/platform' import { getClient } from '@hcengineering/presentation' - import { Button, eventToHTMLElement, getCurrentLocation, IconAdd, locationToUrl, showPopup } from '@hcengineering/ui' + import { Button, eventToHTMLElement, IconAdd, showPopup } from '@hcengineering/ui' import { Filter, ViewOptions } from '@hcengineering/view' import { createEventDispatcher } from 'svelte' - import { filterStore } from '../../filter' + import { filterStore, getFilterKey } from '../../filter' import view from '../../plugin' + import FilterSave from './FilterSave.svelte' import FilterSection from './FilterSection.svelte' import FilterTypePopup from './FilterTypePopup.svelte' - import FilterSave from './FilterSave.svelte' export let _class: Ref> export let query: DocumentQuery @@ -71,7 +71,7 @@ $: saveFilters($filterStore) function saveFilters (filters: Filter[]) { - const key = makeKey(_class) + const key = getFilterKey(_class) if (filters.length > 0) { localStorage.setItem(key, JSON.stringify(filters)) } else { @@ -80,7 +80,7 @@ } async function saveFilteredView () { - showPopup(FilterSave, { viewOptions }) + showPopup(FilterSave, { viewOptions, _class }) } let loading = false @@ -88,7 +88,7 @@ function load (_class: Ref>) { loading = true const oldFilters = $filterStore - const key = makeKey(_class) + const key = getFilterKey(_class) const saved = localStorage.getItem(key) if (saved !== null) { $filterStore = JSON.parse(saved) @@ -99,13 +99,6 @@ oldFilters.forEach((p) => p.onRemove?.()) } - function makeKey (_class: Ref>): string { - const loc = getCurrentLocation() - loc.fragment = undefined - loc.query = undefined - return 'filter' + locationToUrl(loc) + _class - } - async function makeQuery (query: DocumentQuery, filters: Filter[]): Promise { const newQuery = hierarchy.clone(query) for (let i = 0; i < filters.length; i++) { diff --git a/plugins/view-resources/src/components/filter/FilterSave.svelte b/plugins/view-resources/src/components/filter/FilterSave.svelte index c17f29fac2..febfd92557 100644 --- a/plugins/view-resources/src/components/filter/FilterSave.svelte +++ b/plugins/view-resources/src/components/filter/FilterSave.svelte @@ -6,10 +6,11 @@ import { createEventDispatcher } from 'svelte' import { filterStore } from '../../filter' import { ViewOptions } from '@hcengineering/view' - import { Doc, Ref } from '@hcengineering/core' + import { Class, Doc, Ref } from '@hcengineering/core' import { getActiveViewletId } from '../../utils' export let viewOptions: ViewOptions | undefined = undefined + export let _class: Ref> let filterName = '' const client = getClient() diff --git a/plugins/view-resources/src/filter.ts b/plugins/view-resources/src/filter.ts index 9308b0d0c4..9895f8b08f 100644 --- a/plugins/view-resources/src/filter.ts +++ b/plugins/view-resources/src/filter.ts @@ -11,7 +11,7 @@ import core, { } from '@hcengineering/core' import { getResource } from '@hcengineering/platform' import { createQuery, getClient, LiveQuery } from '@hcengineering/presentation' -import { AnyComponent } from '@hcengineering/ui' +import { AnyComponent, getCurrentLocation, locationToUrl } from '@hcengineering/ui' import { Filter, FilterMode, KeyFilter } from '@hcengineering/view' import { writable } from 'svelte/store' import view from './plugin' @@ -172,3 +172,10 @@ export function createFilter (_class: Ref>, key: string, value: any[] mode: modes.mode } } + +export function getFilterKey (_class: Ref>): string { + const loc = getCurrentLocation() + loc.fragment = undefined + loc.query = undefined + return 'filter' + locationToUrl(loc) + _class +} diff --git a/plugins/view-resources/src/viewOptions.ts b/plugins/view-resources/src/viewOptions.ts index c32a1a81af..f208156147 100644 --- a/plugins/view-resources/src/viewOptions.ts +++ b/plugins/view-resources/src/viewOptions.ts @@ -10,6 +10,7 @@ import { ViewOptions, ViewOptionsModel } from '@hcengineering/view' +import { get, writable } from 'svelte/store' import view from './plugin' export const noCategory = '#no_category' @@ -35,20 +36,29 @@ function makeViewOptionsKey (viewlet: Viewlet): string { return `viewOptions:${prefix}:${locationToUrl(loc)}` } -function _setViewOptions (viewlet: Viewlet, options: ViewOptions): void { +export function setViewOptions (viewlet: Viewlet, options: ViewOptions): void { const key = makeViewOptionsKey(viewlet) localStorage.setItem(key, JSON.stringify(options)) + setStore(key, options) } -export function setViewOptions (viewlet: Viewlet, options: ViewOptions): void { - _setViewOptions(viewlet, options) +function setStore (key: string, options: ViewOptions): void { + const map = get(viewOptionStore) + map.set(key, options) + viewOptionStore.set(map) } -function _getViewOptions (viewlet: Viewlet): ViewOptions | null { +function _getViewOptions (viewlet: Viewlet, viewOptionStore: Map): ViewOptions | null { const key = makeViewOptionsKey(viewlet) + const store = viewOptionStore.get(key) + if (store !== undefined) { + return store + } const options = localStorage.getItem(key) if (options === null) return null - return JSON.parse(options) + const res = JSON.parse(options) + setStore(key, res) + return res } function getDefaults (viewOptions: ViewOptionsModel): ViewOptions { @@ -62,11 +72,15 @@ function getDefaults (viewOptions: ViewOptionsModel): ViewOptions { return res } -export function getViewOptions (viewlet: Viewlet | undefined, defaults = defaulOptions): ViewOptions { +export function getViewOptions ( + viewlet: Viewlet | undefined, + viewOptionStore: Map, + defaults = defaulOptions +): ViewOptions { if (viewlet === undefined) { return { ...defaults } } - const res = _getViewOptions(viewlet) + const res = _getViewOptions(viewlet, viewOptionStore) if (res !== null) return res return viewlet.viewOptions != null ? getDefaults(viewlet.viewOptions) : defaults } @@ -132,3 +146,5 @@ export const CategoryQuery = { this.results.delete(index) } } + +export const viewOptionStore = writable(new Map()) diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts index 123f8c257f..e3e41d28b2 100644 --- a/plugins/view/src/index.ts +++ b/plugins/view/src/index.ts @@ -89,6 +89,7 @@ export interface FilteredView extends Preference { location: PlatformLocation filters: string viewOptions?: ViewOptions + filterClass?: Ref> viewletId?: Ref | null } diff --git a/plugins/workbench-resources/src/components/SavedView.svelte b/plugins/workbench-resources/src/components/SavedView.svelte index 0329fee35a..1a1d23666d 100644 --- a/plugins/workbench-resources/src/components/SavedView.svelte +++ b/plugins/workbench-resources/src/components/SavedView.svelte @@ -4,7 +4,14 @@ import setting from '@hcengineering/setting' import { Action, navigate } from '@hcengineering/ui' import view, { FilteredView } from '@hcengineering/view' - import { filterStore, setActiveViewletId, setViewOptions, TreeNode, TreeItem } from '@hcengineering/view-resources' + import { + filterStore, + getFilterKey, + setActiveViewletId, + setViewOptions, + TreeItem, + TreeNode + } from '@hcengineering/view-resources' import { Application } from '@hcengineering/workbench' export let currentApplication: Application | undefined @@ -41,6 +48,11 @@ setViewOptions(viewlet, fv.viewOptions) } } + if (fv.filterClass !== undefined) { + const key = getFilterKey(fv.filterClass) + const filters = JSON.parse(fv.filters) + localStorage.setItem(key, JSON.stringify(filters)) + } navigate(fv.location) $filterStore = JSON.parse(fv.filters) } diff --git a/plugins/workbench-resources/src/components/SpaceView.svelte b/plugins/workbench-resources/src/components/SpaceView.svelte index c446f933ec..e2c0778540 100644 --- a/plugins/workbench-resources/src/components/SpaceView.svelte +++ b/plugins/workbench-resources/src/components/SpaceView.svelte @@ -18,7 +18,7 @@ import { getClient } from '@hcengineering/presentation' import { AnyComponent, Component } from '@hcengineering/ui' import view, { Viewlet } from '@hcengineering/view' - import { getActiveViewletId, getViewOptions } from '@hcengineering/view-resources' + import { getActiveViewletId, getViewOptions, viewOptionStore } from '@hcengineering/view-resources' import type { ViewConfiguration } from '@hcengineering/workbench' import SpaceContent from './SpaceContent.svelte' import SpaceHeader from './SpaceHeader.svelte' @@ -80,7 +80,7 @@ viewlet = e.detail } - $: viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore) {#if _class && space} diff --git a/plugins/workbench-resources/src/components/SpecialView.svelte b/plugins/workbench-resources/src/components/SpecialView.svelte index 1ed93846cd..5082329203 100644 --- a/plugins/workbench-resources/src/components/SpecialView.svelte +++ b/plugins/workbench-resources/src/components/SpecialView.svelte @@ -34,6 +34,7 @@ FilterButton, getViewOptions, setActiveViewletId, + viewOptionStore, ViewletSettingButton } from '@hcengineering/view-resources' @@ -100,7 +101,7 @@ $: twoRows = $deviceInfo.twoRows - $: viewOptions = getViewOptions(viewlet) + $: viewOptions = getViewOptions(viewlet, $viewOptionStore)