diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index 7bbee0e2f6..5be2437f07 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -301,7 +301,7 @@ export function createModel (builder: Builder): void { view.class.ViewletDescriptor, core.space.Model, { - label: view.string.Table, + label: tracker.string.List, icon: view.icon.Table, component: tracker.component.ListView }, diff --git a/plugins/tracker-assets/lang/en.json b/plugins/tracker-assets/lang/en.json index 304f89523b..ad7dfbdcee 100644 --- a/plugins/tracker-assets/lang/en.json +++ b/plugins/tracker-assets/lang/en.json @@ -50,6 +50,7 @@ "Low": "Low", "Unassigned": "Unassigned", "Back": "Back", + "List": "List", "CategoryBacklog": "Backlog", "CategoryUnstarted": "Unstarted", diff --git a/plugins/tracker-assets/lang/ru.json b/plugins/tracker-assets/lang/ru.json index 1dd545496c..8e97d3b145 100644 --- a/plugins/tracker-assets/lang/ru.json +++ b/plugins/tracker-assets/lang/ru.json @@ -50,6 +50,7 @@ "Low": "Низкий", "Unassigned": "Не назначен", "Back": "Назад", + "List": "Список", "CategoryBacklog": "Пул", "CategoryUnstarted": "Не запущенные", diff --git a/plugins/tracker-resources/src/components/issues/IssuesHeader.svelte b/plugins/tracker-resources/src/components/issues/IssuesHeader.svelte index 5d75b09328..aff38e507b 100644 --- a/plugins/tracker-resources/src/components/issues/IssuesHeader.svelte +++ b/plugins/tracker-resources/src/components/issues/IssuesHeader.svelte @@ -3,7 +3,7 @@ import { Team, ViewOptions } from '@anticrm/tracker' import { Button, Icon, Tooltip, IconOptions, showPopup, eventToHTMLElement } from '@anticrm/ui' import { Filter, Viewlet } from '@anticrm/view' - import { FilterButton } from '@anticrm/view-resources' + import { FilterButton, setActiveViewletId } from '@anticrm/view-resources' import tracker from '../../plugin' import ViewOptionsPopup from './ViewOptionsPopup.svelte' @@ -39,6 +39,7 @@ class="ac-header__icon-button" class:selected={viewlet?._id === v._id} on:click={() => { + setActiveViewletId(v._id) viewlet = v }} > diff --git a/plugins/tracker-resources/src/components/issues/IssuesView.svelte b/plugins/tracker-resources/src/components/issues/IssuesView.svelte index a905b88af2..1145c0be63 100644 --- a/plugins/tracker-resources/src/components/issues/IssuesView.svelte +++ b/plugins/tracker-resources/src/components/issues/IssuesView.svelte @@ -13,6 +13,7 @@ import { Button, IconDetails } from '@anticrm/ui' import view, { Filter, Viewlet } from '@anticrm/view' import { FilterBar } from '@anticrm/view-resources' + import { getActiveViewletId } from '@anticrm/view-resources/src/utils' import tracker from '../../plugin' import IssuesContent from './IssuesContent.svelte' import IssuesHeader from './IssuesHeader.svelte' @@ -53,7 +54,8 @@ } } ) - ;[viewlet] = viewlets + const _id = getActiveViewletId() + viewlet = viewlets.find((viewlet) => viewlet._id === _id) || viewlets[0] } } $: if (!label && title) { diff --git a/plugins/tracker-resources/src/plugin.ts b/plugins/tracker-resources/src/plugin.ts index 338ec96b97..ace7572db1 100644 --- a/plugins/tracker-resources/src/plugin.ts +++ b/plugins/tracker-resources/src/plugin.ts @@ -135,6 +135,7 @@ export default mergeIds(trackerId, tracker, { ProjectMembersTitle: '' as IntlString, ProjectLeadSearchPlaceholder: '' as IntlString, ProjectMembersSearchPlaceholder: '' as IntlString, + List: '' as IntlString, IssueTitlePlaceholder: '' as IntlString, IssueDescriptionPlaceholder: '' as IntlString, diff --git a/plugins/view-resources/src/index.ts b/plugins/view-resources/src/index.ts index 23efeeaee1..e3eba9de9c 100644 --- a/plugins/view-resources/src/index.ts +++ b/plugins/view-resources/src/index.ts @@ -65,7 +65,14 @@ export { default as ContextMenu } from './components/Menu.svelte' export { default as TableBrowser } from './components/TableBrowser.svelte' export * from './context' export * from './selection' -export { buildModel, getCollectionCounter, getObjectPresenter, LoadingProps } from './utils' +export { + buildModel, + getCollectionCounter, + getObjectPresenter, + LoadingProps, + setActiveViewletId, + getActiveViewletId +} from './utils' export { HTMLPresenter, Table, diff --git a/plugins/view-resources/src/utils.ts b/plugins/view-resources/src/utils.ts index 9dd60f47ed..6cd3eb822b 100644 --- a/plugins/view-resources/src/utils.ts +++ b/plugins/view-resources/src/utils.ts @@ -30,8 +30,8 @@ import core, { import type { IntlString } from '@anticrm/platform' import { getResource } from '@anticrm/platform' import { getAttributePresenterClass, KeyedAttribute } from '@anticrm/presentation' -import { AnyComponent, ErrorPresenter, getPlatformColorForText } from '@anticrm/ui' -import type { BuildModelOptions } from '@anticrm/view' +import { AnyComponent, ErrorPresenter, getCurrentLocation, getPlatformColorForText, locationToUrl } from '@anticrm/ui' +import type { BuildModelOptions, Viewlet } from '@anticrm/view' import view, { AttributeModel, BuildModelKey } from '@anticrm/view' import plugin from './plugin' @@ -392,3 +392,24 @@ export function collectionsFilter (hierarchy: Hierarchy, keys: KeyedAttribute[], export function isCollectionAttr (hierarchy: Hierarchy, key: KeyedAttribute): boolean { return hierarchy.isDerived(key.attr.type._class, core.class.Collection) } + +function makeViewletKey (): string { + const loc = getCurrentLocation() + loc.fragment = undefined + loc.query = undefined + return 'viewlet' + locationToUrl(loc) +} + +export function setActiveViewletId (viewletId: Ref | null): void { + const key = makeViewletKey() + if (viewletId !== null) { + localStorage.setItem(key, viewletId) + } else { + localStorage.removeItem(key) + } +} + +export function getActiveViewletId (): Ref | null { + const key = makeViewletKey() + return localStorage.getItem(key) as Ref | null +} diff --git a/tests/sanity/tests/tracker.spec.ts b/tests/sanity/tests/tracker.spec.ts index 07528b69c4..ba51d90b5f 100644 --- a/tests/sanity/tests/tracker.spec.ts +++ b/tests/sanity/tests/tracker.spec.ts @@ -82,7 +82,7 @@ test.describe('issues-status-display', () => { test(`${panel}-panel`, async ({ page }) => { const locator = page.locator('.antiPanel-component >> .antiPanel-component') await page.locator(`text="${panel}"`).click() - await page.click('[name="tooltip-view:string:Table"]') + await page.click('[name="tooltip-tracker:string:List"]') await expect(locator).toContainText(statuses) if (excluded.length > 0) await expect(locator).not.toContainText(excluded) await page.click('[name="tooltip-tracker:string:Board"]') @@ -93,3 +93,19 @@ test.describe('issues-status-display', () => { }) } }) + +test('save-active-viewlet', async ({ page }) => { + const panels = ['Issues', 'Active', 'Backlog'] + const viewletTooltips = ['Board', 'List'] + await navigate(page) + for (const viewletTooltip of viewletTooltips) { + for (const panel of panels) { + await page.click(`text="${panel}"`) + await page.click(`[name="tooltip-tracker:string:${viewletTooltip}"]`) + } + for (const panel of panels) { + await page.click(`text="${panel}"`) + await expect(page.locator(`[name="tooltip-tracker:string:${viewletTooltip}"] >> button`)).toHaveClass(/selected/) + } + } +})