mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 08:48:01 +00:00
Add board to Active/Backlog (#2084)
Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com>
This commit is contained in:
parent
f4ff886ce1
commit
04a32872a3
@ -11,9 +11,9 @@
|
|||||||
"Issues": "Issues",
|
"Issues": "Issues",
|
||||||
"Views": "Views",
|
"Views": "Views",
|
||||||
"Active": "Active",
|
"Active": "Active",
|
||||||
"AllIssues": "All issues {value}",
|
"AllIssues": "All issues",
|
||||||
"ActiveIssues": "Active issues {value}",
|
"ActiveIssues": "Active issues",
|
||||||
"BacklogIssues": "Backlog {value}",
|
"BacklogIssues": "Backlog",
|
||||||
"Backlog": "Backlog",
|
"Backlog": "Backlog",
|
||||||
"Board": "Board",
|
"Board": "Board",
|
||||||
"Projects": "Projects",
|
"Projects": "Projects",
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
"Issues": "Задачи",
|
"Issues": "Задачи",
|
||||||
"Views": "Отображения",
|
"Views": "Отображения",
|
||||||
"Active": "Активные",
|
"Active": "Активные",
|
||||||
"ActiveIssues": "Активные задачи {value}",
|
"AllIssues": "Все задачи",
|
||||||
"BacklogIssues": "Пул задач {value}",
|
"ActiveIssues": "Активные задачи",
|
||||||
|
"BacklogIssues": "Пул задач",
|
||||||
"Backlog": "Пул задач",
|
"Backlog": "Пул задач",
|
||||||
"Board": "Канбан",
|
"Board": "Канбан",
|
||||||
"Projects": "Проекты",
|
"Projects": "Проекты",
|
||||||
|
@ -13,19 +13,23 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Ref } from '@anticrm/core'
|
import { DocumentQuery, Ref } from '@anticrm/core'
|
||||||
import { Team, IssuesDateModificationPeriod } from '@anticrm/tracker'
|
import { createQuery } from '@anticrm/presentation'
|
||||||
|
import { Issue, Team } from '@anticrm/tracker'
|
||||||
import tracker from '../../plugin'
|
import tracker from '../../plugin'
|
||||||
import Issues from './Issues.svelte'
|
import IssuesView from './IssuesView.svelte'
|
||||||
|
|
||||||
export let currentSpace: Ref<Team>
|
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>
|
</script>
|
||||||
|
|
||||||
<Issues
|
<IssuesView {currentSpace} {query} title={tracker.string.ActiveIssues} />
|
||||||
{currentSpace}
|
|
||||||
{completedIssuesPeriod}
|
|
||||||
includedGroups={{ status: [tracker.issueStatusCategory.Unstarted, tracker.issueStatusCategory.Started] }}
|
|
||||||
title={tracker.string.ActiveIssues}
|
|
||||||
/>
|
|
||||||
|
@ -13,19 +13,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Ref } from '@anticrm/core'
|
import { DocumentQuery, Ref } from '@anticrm/core'
|
||||||
import { Team, IssuesDateModificationPeriod } from '@anticrm/tracker'
|
import { createQuery } from '@anticrm/presentation'
|
||||||
|
import { Issue, Team } from '@anticrm/tracker'
|
||||||
import tracker from '../../plugin'
|
import tracker from '../../plugin'
|
||||||
import Issues from './Issues.svelte'
|
import IssuesView from './IssuesView.svelte'
|
||||||
|
|
||||||
export let currentSpace: Ref<Team>
|
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>
|
</script>
|
||||||
|
|
||||||
<Issues
|
<IssuesView {currentSpace} {query} title={tracker.string.BacklogIssues} />
|
||||||
title={tracker.string.BacklogIssues}
|
|
||||||
{currentSpace}
|
|
||||||
{completedIssuesPeriod}
|
|
||||||
includedGroups={{ status: [tracker.issueStatusCategory.Backlog] }}
|
|
||||||
/>
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Ref, WithLookup } from '@anticrm/core'
|
import type { DocumentQuery, Ref, WithLookup } from '@anticrm/core'
|
||||||
import { Component } from '@anticrm/ui'
|
import { Component } from '@anticrm/ui'
|
||||||
import { BuildModelKey, Viewlet } from '@anticrm/view'
|
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 currentSpace: Ref<Team>
|
||||||
export let viewlet: WithLookup<Viewlet> | undefined
|
export let viewlet: WithLookup<Viewlet> | undefined
|
||||||
export let config: (string | BuildModelKey)[] | undefined = undefined
|
export let config: (string | BuildModelKey)[] | undefined = undefined
|
||||||
export let query = {}
|
export let query: DocumentQuery<Issue> = {}
|
||||||
export let viewOptions: ViewOptions
|
export let viewOptions: ViewOptions
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
<script lang="ts">
|
<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 { IntlString, translate } from '@anticrm/platform'
|
||||||
import { getClient } from '@anticrm/presentation'
|
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 { Button, IconDetails } from '@anticrm/ui'
|
||||||
import view, { Filter, Viewlet } from '@anticrm/view'
|
import view, { Filter, Viewlet } from '@anticrm/view'
|
||||||
import { FilterBar } from '@anticrm/view-resources'
|
import { FilterBar } from '@anticrm/view-resources'
|
||||||
@ -11,7 +18,7 @@
|
|||||||
import IssuesHeader from './IssuesHeader.svelte'
|
import IssuesHeader from './IssuesHeader.svelte'
|
||||||
|
|
||||||
export let currentSpace: Ref<Team> | undefined
|
export let currentSpace: Ref<Team> | undefined
|
||||||
export let query = {}
|
export let query: DocumentQuery<Issue> = {}
|
||||||
export let title: IntlString | undefined = undefined
|
export let title: IntlString | undefined = undefined
|
||||||
export let label: string = ''
|
export let label: string = ''
|
||||||
|
|
||||||
@ -26,7 +33,7 @@
|
|||||||
shouldShowEmptyGroups: false,
|
shouldShowEmptyGroups: false,
|
||||||
shouldShowSubIssues: false
|
shouldShowSubIssues: false
|
||||||
}
|
}
|
||||||
let resultQuery = {}
|
let resultQuery: DocumentQuery<Issue> = {}
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
|
@ -400,6 +400,9 @@ export async function getKanbanStatuses (
|
|||||||
issueQuery: DocumentQuery<Issue>,
|
issueQuery: DocumentQuery<Issue>,
|
||||||
shouldShowEmptyGroups: boolean
|
shouldShowEmptyGroups: boolean
|
||||||
): Promise<TypeState[]> {
|
): Promise<TypeState[]> {
|
||||||
|
if (groupBy === IssuesGrouping.NoGrouping) {
|
||||||
|
return [{ _id: undefined, color: 0, title: await translate(tracker.string.NoGrouping, {}) }]
|
||||||
|
}
|
||||||
if (groupBy === IssuesGrouping.Status && shouldShowEmptyGroups) {
|
if (groupBy === IssuesGrouping.Status && shouldShowEmptyGroups) {
|
||||||
return (
|
return (
|
||||||
await client.findAll(
|
await client.findAll(
|
||||||
@ -417,7 +420,6 @@ export async function getKanbanStatuses (
|
|||||||
icon: status.$lookup?.category?.icon ?? undefined
|
icon: status.$lookup?.category?.icon ?? undefined
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
if (groupBy === IssuesGrouping.NoGrouping) return []
|
|
||||||
if (groupBy === IssuesGrouping.Priority) {
|
if (groupBy === IssuesGrouping.Priority) {
|
||||||
const issues = await client.findAll(tracker.class.Issue, issueQuery, {
|
const issues = await client.findAll(tracker.class.Issue, issueQuery, {
|
||||||
sort: { priority: SortingOrder.Ascending }
|
sort: { priority: SortingOrder.Ascending }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { test, expect } from '@playwright/test'
|
import { test, expect, Page } from '@playwright/test'
|
||||||
import { generateId, PlatformSetting, PlatformURI } from './utils'
|
import { generateId, PlatformSetting, PlatformURI } from './utils'
|
||||||
test.use({
|
test.use({
|
||||||
storageState: PlatformSetting
|
storageState: PlatformSetting
|
||||||
@ -33,20 +33,63 @@ test('create-issue-and-sub-issue', async ({ page }) => {
|
|||||||
await page.click('span.name:text("sub-issue")')
|
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.goto(`${PlatformURI}/workbench%3Acomponent%3AWorkbenchApp`)
|
||||||
await page.click('[id="app-tracker\\:string\\:TrackerApplication"]')
|
await page.click('[id="app-tracker\\:string\\:TrackerApplication"]')
|
||||||
await expect(page).toHaveURL(`${PlatformURI}/workbench%3Acomponent%3AWorkbenchApp/tracker%3Aapp%3ATracker`)
|
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('button:has-text("New issue")')
|
||||||
await page.click('[placeholder="Issue\\ title"]')
|
await page.click('[placeholder="Issue\\ title"]')
|
||||||
await page.fill('[placeholder="Issue\\ title"]', issueName)
|
await page.fill('[placeholder="Issue\\ title"]', props.name ?? '')
|
||||||
|
if (props.status !== undefined) {
|
||||||
await page.click('button:has-text("Backlog")')
|
await page.click('button:has-text("Backlog")')
|
||||||
await page.click('button:has-text("In Progress")')
|
await page.click(`.menu-item:has-text("${props.status}")`)
|
||||||
|
}
|
||||||
await page.click('button:has-text("Save issue")')
|
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.locator('text="Issues"').click()
|
||||||
await page.click('[name="tooltip-tracker:string:Board"]')
|
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))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user