From 04a32872a3e578a534fc82c172943ba9ae59e943 Mon Sep 17 00:00:00 2001 From: Alex <41288429+Dvinyanin@users.noreply.github.com> Date: Thu, 16 Jun 2022 01:04:37 +0700 Subject: [PATCH] Add board to Active/Backlog (#2084) Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com> --- plugins/tracker-assets/lang/en.json | 6 +- plugins/tracker-assets/lang/ru.json | 5 +- .../src/components/issues/Active.svelte | 24 ++++---- .../src/components/issues/Backlog.svelte | 20 +++---- .../components/issues/IssuesContent.svelte | 6 +- .../src/components/issues/IssuesView.svelte | 15 +++-- plugins/tracker-resources/src/utils.ts | 4 +- tests/sanity/tests/tracker.spec.ts | 57 ++++++++++++++++--- 8 files changed, 97 insertions(+), 40 deletions(-) diff --git a/plugins/tracker-assets/lang/en.json b/plugins/tracker-assets/lang/en.json index 52116da60d..304f89523b 100644 --- a/plugins/tracker-assets/lang/en.json +++ b/plugins/tracker-assets/lang/en.json @@ -11,9 +11,9 @@ "Issues": "Issues", "Views": "Views", "Active": "Active", - "AllIssues": "All issues {value}", - "ActiveIssues": "Active issues {value}", - "BacklogIssues": "Backlog {value}", + "AllIssues": "All issues", + "ActiveIssues": "Active issues", + "BacklogIssues": "Backlog", "Backlog": "Backlog", "Board": "Board", "Projects": "Projects", diff --git a/plugins/tracker-assets/lang/ru.json b/plugins/tracker-assets/lang/ru.json index 4d2764dd5d..f1b5ee5edb 100644 --- a/plugins/tracker-assets/lang/ru.json +++ b/plugins/tracker-assets/lang/ru.json @@ -11,8 +11,9 @@ "Issues": "Задачи", "Views": "Отображения", "Active": "Активные", - "ActiveIssues": "Активные задачи {value}", - "BacklogIssues": "Пул задач {value}", + "AllIssues": "Все задачи", + "ActiveIssues": "Активные задачи", + "BacklogIssues": "Пул задач", "Backlog": "Пул задач", "Board": "Канбан", "Projects": "Проекты", diff --git a/plugins/tracker-resources/src/components/issues/Active.svelte b/plugins/tracker-resources/src/components/issues/Active.svelte index 30aa36e195..55a2830fb2 100644 --- a/plugins/tracker-resources/src/components/issues/Active.svelte +++ b/plugins/tracker-resources/src/components/issues/Active.svelte @@ -13,19 +13,23 @@ // limitations under the License. --> <script lang="ts"> - import { Ref } from '@anticrm/core' - import { Team, IssuesDateModificationPeriod } from '@anticrm/tracker' + import { DocumentQuery, Ref } from '@anticrm/core' + import { createQuery } from '@anticrm/presentation' + import { Issue, Team } from '@anticrm/tracker' import tracker from '../../plugin' - import Issues from './Issues.svelte' + import IssuesView from './IssuesView.svelte' export let currentSpace: Ref<Team> - const completedIssuesPeriod: IssuesDateModificationPeriod | null = null + const statusQuery = createQuery() + let query: DocumentQuery<Issue> + $: statusQuery.query( + tracker.class.IssueStatus, + { category: { $in: [tracker.issueStatusCategory.Unstarted, tracker.issueStatusCategory.Started] } }, + (result) => { + query = { status: { $in: result.map(({ _id }) => _id) } } + } + ) </script> -<Issues - {currentSpace} - {completedIssuesPeriod} - includedGroups={{ status: [tracker.issueStatusCategory.Unstarted, tracker.issueStatusCategory.Started] }} - title={tracker.string.ActiveIssues} -/> +<IssuesView {currentSpace} {query} title={tracker.string.ActiveIssues} /> diff --git a/plugins/tracker-resources/src/components/issues/Backlog.svelte b/plugins/tracker-resources/src/components/issues/Backlog.svelte index 00df49d0e3..e67f50238a 100644 --- a/plugins/tracker-resources/src/components/issues/Backlog.svelte +++ b/plugins/tracker-resources/src/components/issues/Backlog.svelte @@ -13,19 +13,19 @@ // limitations under the License. --> <script lang="ts"> - import { Ref } from '@anticrm/core' - import { Team, IssuesDateModificationPeriod } from '@anticrm/tracker' + import { DocumentQuery, Ref } from '@anticrm/core' + import { createQuery } from '@anticrm/presentation' + import { Issue, Team } from '@anticrm/tracker' import tracker from '../../plugin' - import Issues from './Issues.svelte' + import IssuesView from './IssuesView.svelte' export let currentSpace: Ref<Team> - const completedIssuesPeriod: IssuesDateModificationPeriod | null = null + const statusQuery = createQuery() + let query: DocumentQuery<Issue> = {} + $: statusQuery.query(tracker.class.IssueStatus, { category: tracker.issueStatusCategory.Backlog }, (result) => { + query = { status: { $in: result.map(({ _id }) => _id) } } + }) </script> -<Issues - title={tracker.string.BacklogIssues} - {currentSpace} - {completedIssuesPeriod} - includedGroups={{ status: [tracker.issueStatusCategory.Backlog] }} -/> +<IssuesView {currentSpace} {query} title={tracker.string.BacklogIssues} /> diff --git a/plugins/tracker-resources/src/components/issues/IssuesContent.svelte b/plugins/tracker-resources/src/components/issues/IssuesContent.svelte index b9a21c1043..3966c3cb0d 100644 --- a/plugins/tracker-resources/src/components/issues/IssuesContent.svelte +++ b/plugins/tracker-resources/src/components/issues/IssuesContent.svelte @@ -1,13 +1,13 @@ <script lang="ts"> - import type { Ref, WithLookup } from '@anticrm/core' + import type { DocumentQuery, Ref, WithLookup } from '@anticrm/core' import { Component } from '@anticrm/ui' import { BuildModelKey, Viewlet } from '@anticrm/view' - import { Team, ViewOptions } from '@anticrm/tracker' + import { Issue, Team, ViewOptions } from '@anticrm/tracker' export let currentSpace: Ref<Team> export let viewlet: WithLookup<Viewlet> | undefined export let config: (string | BuildModelKey)[] | undefined = undefined - export let query = {} + export let query: DocumentQuery<Issue> = {} export let viewOptions: ViewOptions </script> diff --git a/plugins/tracker-resources/src/components/issues/IssuesView.svelte b/plugins/tracker-resources/src/components/issues/IssuesView.svelte index 0ad3657e05..a905b88af2 100644 --- a/plugins/tracker-resources/src/components/issues/IssuesView.svelte +++ b/plugins/tracker-resources/src/components/issues/IssuesView.svelte @@ -1,8 +1,15 @@ <script lang="ts"> - import core, { Ref, Space, WithLookup } from '@anticrm/core' + import core, { DocumentQuery, Ref, Space, WithLookup } from '@anticrm/core' import { IntlString, translate } from '@anticrm/platform' import { getClient } from '@anticrm/presentation' - import { IssuesDateModificationPeriod, IssuesGrouping, IssuesOrdering, Team, ViewOptions } from '@anticrm/tracker' + import { + Issue, + IssuesDateModificationPeriod, + IssuesGrouping, + IssuesOrdering, + Team, + ViewOptions + } from '@anticrm/tracker' import { Button, IconDetails } from '@anticrm/ui' import view, { Filter, Viewlet } from '@anticrm/view' import { FilterBar } from '@anticrm/view-resources' @@ -11,7 +18,7 @@ import IssuesHeader from './IssuesHeader.svelte' export let currentSpace: Ref<Team> | undefined - export let query = {} + export let query: DocumentQuery<Issue> = {} export let title: IntlString | undefined = undefined export let label: string = '' @@ -26,7 +33,7 @@ shouldShowEmptyGroups: false, shouldShowSubIssues: false } - let resultQuery = {} + let resultQuery: DocumentQuery<Issue> = {} const client = getClient() diff --git a/plugins/tracker-resources/src/utils.ts b/plugins/tracker-resources/src/utils.ts index 03b0fd04f7..210443d32e 100644 --- a/plugins/tracker-resources/src/utils.ts +++ b/plugins/tracker-resources/src/utils.ts @@ -400,6 +400,9 @@ export async function getKanbanStatuses ( issueQuery: DocumentQuery<Issue>, shouldShowEmptyGroups: boolean ): Promise<TypeState[]> { + if (groupBy === IssuesGrouping.NoGrouping) { + return [{ _id: undefined, color: 0, title: await translate(tracker.string.NoGrouping, {}) }] + } if (groupBy === IssuesGrouping.Status && shouldShowEmptyGroups) { return ( await client.findAll( @@ -417,7 +420,6 @@ export async function getKanbanStatuses ( icon: status.$lookup?.category?.icon ?? undefined })) } - if (groupBy === IssuesGrouping.NoGrouping) return [] if (groupBy === IssuesGrouping.Priority) { const issues = await client.findAll(tracker.class.Issue, issueQuery, { sort: { priority: SortingOrder.Ascending } diff --git a/tests/sanity/tests/tracker.spec.ts b/tests/sanity/tests/tracker.spec.ts index bb28bd2f0e..07528b69c4 100644 --- a/tests/sanity/tests/tracker.spec.ts +++ b/tests/sanity/tests/tracker.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from '@playwright/test' +import { test, expect, Page } from '@playwright/test' import { generateId, PlatformSetting, PlatformURI } from './utils' test.use({ storageState: PlatformSetting @@ -33,20 +33,63 @@ test('create-issue-and-sub-issue', async ({ page }) => { await page.click('span.name:text("sub-issue")') }) -test('use-kanban', async ({ page }) => { +async function navigate (page: Page): Promise<void> { await page.goto(`${PlatformURI}/workbench%3Acomponent%3AWorkbenchApp`) await page.click('[id="app-tracker\\:string\\:TrackerApplication"]') await expect(page).toHaveURL(`${PlatformURI}/workbench%3Acomponent%3AWorkbenchApp/tracker%3Aapp%3ATracker`) +} - const issueName = 'issue-' + generateId(5) +async function createIssue (page: Page, props: { [p: string]: string } = {}): Promise<void> { await page.click('button:has-text("New issue")') await page.click('[placeholder="Issue\\ title"]') - await page.fill('[placeholder="Issue\\ title"]', issueName) - await page.click('button:has-text("Backlog")') - await page.click('button:has-text("In Progress")') + await page.fill('[placeholder="Issue\\ title"]', props.name ?? '') + if (props.status !== undefined) { + await page.click('button:has-text("Backlog")') + await page.click(`.menu-item:has-text("${props.status}")`) + } await page.click('button:has-text("Save issue")') +} + +const getIssueName = (postfix: string = generateId(5)): string => `issue-${postfix}` + +test('use-kanban', async ({ page }) => { + await navigate(page) + const name = getIssueName() + const status = 'In Progress' + await createIssue(page, { name, status }) await page.locator('text="Issues"').click() await page.click('[name="tooltip-tracker:string:Board"]') - await expect(page.locator('.panel-container:has-text("In Progress")')).toContainText(issueName) + await expect(page.locator(`.panel-container:has-text("${status}")`)).toContainText(name) +}) + +const defaultStatuses = ['Backlog', 'Todo', 'In Progress', 'Done', 'Canceled'] + +test.describe('issues-status-display', () => { + const panelStatusMap = new Map([ + ['Issues', defaultStatuses], + ['Active', ['Todo', 'In Progress']], + ['Backlog', ['Backlog']] + ]) + test.beforeEach(async ({ page }) => { + await navigate(page) + for (const status of defaultStatuses) { + await createIssue(page, { name: getIssueName(status), status }) + } + }) + for (const [panel, statuses] of panelStatusMap) { + const excluded = defaultStatuses.filter((status) => !statuses.includes(status)) + 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 expect(locator).toContainText(statuses) + if (excluded.length > 0) await expect(locator).not.toContainText(excluded) + await page.click('[name="tooltip-tracker:string:Board"]') + if (excluded.length > 0) await expect(locator).not.toContainText(excluded) + for (const status of statuses) { + await expect(page.locator(`.panel-container:has-text("${status}")`)).toContainText(getIssueName(status)) + } + }) + } })