diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts index 1e6d23f4c7..7b85638526 100644 --- a/models/contact/src/index.ts +++ b/models/contact/src/index.ts @@ -286,7 +286,8 @@ export function createModel (builder: Builder): void { } ], configOptions: { - hiddenKeys: ['name'] + hiddenKeys: ['name'], + sortable: true } }, contact.viewlet.TableContact diff --git a/models/inventory/src/index.ts b/models/inventory/src/index.ts index 9cae385fa3..2889c0ead7 100644 --- a/models/inventory/src/index.ts +++ b/models/inventory/src/index.ts @@ -111,7 +111,10 @@ export function createModel (builder: Builder): void { { attachTo: inventory.class.Product, descriptor: view.viewlet.Table, - config: ['', 'attachedTo', 'modifiedOn'] + config: ['', 'attachedTo', 'modifiedOn'], + configOptions: { + sortable: true + } }, inventory.viewlet.TableProduct ) diff --git a/models/lead/src/index.ts b/models/lead/src/index.ts index 8129f35b87..d451181794 100644 --- a/models/lead/src/index.ts +++ b/models/lead/src/index.ts @@ -209,7 +209,8 @@ export function createModel (builder: Builder): void { } ], configOptions: { - hiddenKeys: ['name'] + hiddenKeys: ['name'], + sortable: true }, options: { lookup: { @@ -241,11 +242,6 @@ export function createModel (builder: Builder): void { 'state', 'doneState', 'attachments', - { - key: '', - presenter: tracker.component.RelatedIssueSelector, - label: tracker.string.Relations - }, 'comments', 'modifiedOn', { @@ -253,6 +249,9 @@ export function createModel (builder: Builder): void { sortingKey: ['$lookup.attachedTo.$lookup.channels.lastMessage', '$lookup.attachedTo.channels'] } ], + configOptions: { + sortable: true + }, options: { lookup: { _id: { @@ -292,6 +291,7 @@ export function createModel (builder: Builder): void { descriptor: view.viewlet.List, configOptions: { hiddenKeys: ['title'], + sortable: true, extraProps: { displayProps: { optional: true diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 518b9df861..87ef2d7160 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -400,7 +400,8 @@ export function createModel (builder: Builder): void { } ], configOptions: { - hiddenKeys: ['name'] + hiddenKeys: ['name'], + sortable: true }, options: { lookup: { @@ -420,6 +421,9 @@ export function createModel (builder: Builder): void { attachTo: recruit.class.Applicant, descriptor: view.viewlet.Table, config: ['', '$lookup.attachedTo', 'state', 'doneState', 'modifiedOn'], + configOptions: { + sortable: true + }, variant: 'short' }, recruit.viewlet.VacancyApplicationsShort @@ -432,6 +436,9 @@ export function createModel (builder: Builder): void { attachTo: recruit.class.Applicant, descriptor: view.viewlet.Table, config: ['', '$lookup.space.name', '$lookup.space.$lookup.company', 'state', 'comments', 'doneState'], + configOptions: { + sortable: true + }, variant: 'embedded' }, recruit.viewlet.VacancyApplicationsEmbeddeed @@ -460,7 +467,8 @@ export function createModel (builder: Builder): void { } ], configOptions: { - hiddenKeys: ['name', 'space', 'modifiedOn'] + hiddenKeys: ['name', 'space', 'modifiedOn'], + sortable: true } }, recruit.viewlet.TableVacancy @@ -492,7 +500,8 @@ export function createModel (builder: Builder): void { } ], configOptions: { - hiddenKeys: ['name', 'space', 'modifiedOn'] + hiddenKeys: ['name', 'space', 'modifiedOn'], + sortable: true } }, recruit.viewlet.TableVacancyList @@ -533,7 +542,8 @@ export function createModel (builder: Builder): void { } ], configOptions: { - hiddenKeys: ['name', 'attachedTo'] + hiddenKeys: ['name', 'attachedTo'], + sortable: true }, options: { lookup: { @@ -588,7 +598,8 @@ export function createModel (builder: Builder): void { } }, configOptions: { - hiddenKeys: ['name', 'attachedTo'] + hiddenKeys: ['name', 'attachedTo'], + sortable: true }, baseQuery: { doneState: null, @@ -722,6 +733,7 @@ export function createModel (builder: Builder): void { }, configOptions: { hiddenKeys: ['name', 'attachedTo'], + sortable: true, extraProps: { displayProps: { optional: true diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index f181497933..49b0b1348c 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -505,6 +505,7 @@ export function createModel (builder: Builder): void { 'dueDate', 'attachedTo' ], + sortable: true, extraProps: { displayProps: { optional: true @@ -643,32 +644,51 @@ export function createModel (builder: Builder): void { descriptor: view.viewlet.List, viewOptions: subIssuesOptions, variant: 'subissue', + configOptions: { + sortable: true, + hiddenKeys: ['priority', 'number', 'status', 'title', 'dueDate', 'milestone', 'estimation'], + extraProps: { + displayProps: { + optional: true + } + } + }, config: [ { key: '', + label: tracker.string.Priority, presenter: tracker.component.PriorityEditor, props: { type: 'priority', kind: 'list', size: 'small' } }, { key: '', + label: tracker.string.Issue, presenter: tracker.component.IssuePresenter, props: { type: 'issue' }, displayProps: { fixed: 'left' } }, { key: '', + label: tracker.string.Status, presenter: tracker.component.StatusEditor, props: { kind: 'list', size: 'small', justify: 'center' } }, - { key: '', presenter: tracker.component.TitlePresenter, props: { shouldUseMargin: true, showParent: false } }, - { key: '', presenter: tracker.component.SubIssuesSelector, props: {} }, { key: '', + label: tracker.string.Title, + presenter: tracker.component.TitlePresenter, + props: { shouldUseMargin: true, showParent: false } + }, + { key: '', label: tracker.string.SubIssues, presenter: tracker.component.SubIssuesSelector, props: {} }, + { + key: '', + label: tracker.string.DueDate, presenter: tracker.component.DueDatePresenter, props: { kind: 'list' } }, { key: '', + label: tracker.string.Milestone, presenter: tracker.component.MilestoneEditor, props: { kind: 'list', @@ -683,6 +703,7 @@ export function createModel (builder: Builder): void { }, { key: '', + label: tracker.string.Estimation, presenter: tracker.component.EstimationEditor, props: { kind: 'list', size: 'small' }, displayProps: { optional: true } @@ -720,7 +741,8 @@ export function createModel (builder: Builder): void { }, configOptions: { hiddenKeys: ['milestone', 'estimation', 'component', 'title', 'description'], - extraProps: { displayProps: { optional: true } } + extraProps: { displayProps: { optional: true } }, + sortable: true }, config: [ // { key: '', presenter: tracker.component.PriorityEditor, props: { kind: 'list', size: 'small' } }, @@ -1861,7 +1883,8 @@ export function createModel (builder: Builder): void { viewOptions: milestoneOptions, configOptions: { hiddenKeys: ['targetDate', 'label', 'description'], - extraProps: { displayProps: { optional: true } } + extraProps: { displayProps: { optional: true } }, + sortable: true }, config: [ { @@ -1941,7 +1964,8 @@ export function createModel (builder: Builder): void { viewOptions: componentListViewOptions, configOptions: { hiddenKeys: ['label', 'description'], - extraProps: { displayProps: { optional: true } } + extraProps: { displayProps: { optional: true } }, + sortable: true }, config: [ { diff --git a/plugins/tracker-resources/src/components/views/Views.svelte b/plugins/tracker-resources/src/components/views/Views.svelte deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/tracker-resources/src/index.ts b/plugins/tracker-resources/src/index.ts index 929b53be2b..27583e70db 100644 --- a/plugins/tracker-resources/src/index.ts +++ b/plugins/tracker-resources/src/index.ts @@ -67,7 +67,6 @@ import SetParentIssueActionPopup from './components/SetParentIssueActionPopup.sv import MilestoneDatePresenter from './components/milestones/MilestoneDatePresenter.svelte' import EditMilestone from './components/milestones/EditMilestone.svelte' import CreateIssueTemplate from './components/templates/CreateIssueTemplate.svelte' -import Views from './components/views/Views.svelte' import Statuses from './components/workflow/Statuses.svelte' import { @@ -384,7 +383,6 @@ export default async (): Promise => ({ Inbox, MyIssues, Components, - Views, IssuePresenter, ComponentPresenter, ComponentTitlePresenter, diff --git a/plugins/view-resources/src/components/ViewletSetting.svelte b/plugins/view-resources/src/components/ViewletSetting.svelte index a6730f6648..24ed4e39fb 100644 --- a/plugins/view-resources/src/components/ViewletSetting.svelte +++ b/plugins/view-resources/src/components/ViewletSetting.svelte @@ -17,7 +17,7 @@ import { Asset, IntlString } from '@hcengineering/platform' import preferencePlugin from '@hcengineering/preference' import { createQuery, getAttributePresenterClass, getClient, hasResource } from '@hcengineering/presentation' - import { Loading, ToggleWithLabel } from '@hcengineering/ui' + import { Button, Loading, ToggleWithLabel } from '@hcengineering/ui' import { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view' import { deepEqual } from 'fast-equals' import view from '../plugin' @@ -36,8 +36,7 @@ }, (res) => { preference = res[0] - attributes = getConfig(viewlet, preference) - classes = groupByClasses(attributes) + items = getConfig(viewlet, preference) loading = false }, { limit: 1 } @@ -48,7 +47,7 @@ const client = getClient() const hierarchy = client.getHierarchy() - let attributes: AttributeConfig[] = [] + let items: AttributeConfig[] = [] let loading = true interface AttributeConfig { @@ -57,6 +56,7 @@ value: string | BuildModelKey _class: Ref> icon: Asset | undefined + order?: number } function getObjectConfig (_class: Ref>, param: string): AttributeConfig { @@ -201,10 +201,7 @@ } async function save (): Promise { - const config = Array.from(classes.values()) - .flat() - .filter((p) => p.enabled) - .map((p) => p.value) + const config = items.filter((p) => p.enabled).map((p) => p.value) if (preference !== undefined) { await client.update(preference, { config @@ -217,29 +214,51 @@ } } - // function restoreDefault (): void { - // attributes = getConfig(viewlet, undefined) - // classes = groupByClasses(attributes) - // } + function restoreDefault (): void { + items = getConfig(viewlet, undefined) + save() + } function setStatus (result: AttributeConfig[], preference: ViewletPreference): AttributeConfig[] { for (const key of result) { - key.enabled = preference.config.findIndex((p) => deepEqual(p, key.value)) !== -1 + const index = preference.config.findIndex((p) => deepEqual(p, key.value)) + key.enabled = index !== -1 + key.order = index !== -1 ? index : undefined } + result.sort((a, b) => { + if (a.order === undefined && b.order === undefined) return 0 + if (a.order === undefined) return 1 + if (b.order === undefined) return -1 + return a.order - b.order + }) return result } - function groupByClasses (attributes: AttributeConfig[]): Map>, AttributeConfig[]> { - const res = new Map() - for (const attribute of attributes) { - const arr = res.get(attribute._class) ?? [] - arr.push(attribute) - res.set(attribute._class, arr) - } - return res + function dragEnd () { + selected = undefined + save() } - let classes: Map>, AttributeConfig[]> = new Map() + function dragOver (e: DragEvent, i: number) { + const s = selected as number + if (dragswap(e, i, s)) { + ;[items[i], items[s]] = [items[s], items[i]] + selected = i + } + } + + const elements: HTMLElement[] = [] + + function dragswap (ev: MouseEvent, i: number, s: number): boolean { + if (i < s) { + return ev.offsetY < elements[i].offsetHeight / 2 + } else if (i > s) { + return ev.offsetY > elements[i].offsetHeight / 2 + } + return false + } + + let selected: number | undefined
@@ -247,23 +266,29 @@ {#if loading} {:else} - {#each Array.from(classes.keys()) as _class, i} - {@const items = classes.get(_class) ?? []} - {#if i !== 0} - diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts index 2a3cccaf49..3f15992e90 100644 --- a/plugins/view/src/index.ts +++ b/plugins/view/src/index.ts @@ -329,6 +329,7 @@ export interface ViewletConfigOptions { hiddenKeys?: string[] strict?: boolean extraProps?: Omit + sortable?: boolean } /**