Fix test management header button (#7172)

Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
Artyom Savchenko 2024-11-14 20:23:45 +07:00 committed by GitHub
parent 503ceeeab6
commit 5ea7ff2667
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 165 additions and 52 deletions

View File

@ -119,7 +119,7 @@ function defineApplication (builder: Builder): void {
} }
] ]
}, },
navHeaderComponent: testManagement.component.NewTestCaseHeader navHeaderComponent: testManagement.component.TestManagementSpaceHeader
}, },
testManagement.app.TestManagement testManagement.app.TestManagement
) )

View File

@ -49,4 +49,7 @@
<path d="M18.5,9.8c0.4,0,0.8-0.3,0.8-0.8V7.5c0-0.4-0.3-0.8-0.8-0.8s-0.8,0.3-0.8,0.8V9C17.8,9.4,18.1,9.8,18.5,9.8z"/> <path d="M18.5,9.8c0.4,0,0.8-0.3,0.8-0.8V7.5c0-0.4-0.3-0.8-0.8-0.8s-0.8,0.3-0.8,0.8V9C17.8,9.4,18.1,9.8,18.5,9.8z"/>
<path d="M13.5,6.8c-0.4,0-0.8,0.3-0.8,0.8V9c0,0.4,0.3,0.8,0.8,0.8s0.8-0.3,0.8-0.8V7.5C14.2,7.1,13.9,6.8,13.5,6.8z"/> <path d="M13.5,6.8c-0.4,0-0.8,0.3-0.8,0.8V9c0,0.4,0.3,0.8,0.8,0.8s0.8-0.3,0.8-0.8V7.5C14.2,7.1,13.9,6.8,13.5,6.8z"/>
</symbol> </symbol>
<symbol id="project" viewBox="0 0 32 32">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 6C13.4477 6 13 6.44772 13 7V8H19V7C19 6.44772 18.5523 6 18 6H14ZM21 8V7C21 5.34315 19.6569 4 18 4H14C12.3431 4 11 5.34315 11 7V8H6C3.79086 8 2 9.79086 2 12V24C2 26.2091 3.79086 28 6 28H26C28.2091 28 30 26.2091 30 24V12C30 9.79086 28.2091 8 26 8H21ZM6 10C4.89543 10 4 10.8954 4 12V16H28V12C28 10.8954 27.1046 10 26 10H6ZM28 18H17V19C17 19.5523 16.5523 20 16 20C15.4477 20 15 19.5523 15 19V18H4V24C4 25.1046 4.89543 26 6 26H26C27.1046 26 28 25.1046 28 24V18Z" />
</symbol>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -26,7 +26,7 @@ loadMetadata(testManagement.icon, {
Home: `${icons}#home`, Home: `${icons}#home`,
Estimation: `${icons}#testCase`, Estimation: `${icons}#testCase`,
TestSuite: `${icons}#testSuite`, TestSuite: `${icons}#testSuite`,
TestProject: `${icons}#testCase`, TestProject: `${icons}#project`,
TestSuites: `${icons}#testSuite`, TestSuites: `${icons}#testSuite`,
TestRuns: `${icons}#testRun`, TestRuns: `${icons}#testRun`,
RedCircle: `${icons}#red-circle`, RedCircle: `${icons}#red-circle`,

View File

@ -0,0 +1,132 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { AccountRole, Ref, getCurrentAccount, hasAccountRole } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { Button, ButtonWithDropdown, IconAdd, IconDropdown, Loading, SelectPopupValueType } from '@hcengineering/ui'
import { TestProject } from '@hcengineering/test-management'
import { showCreateTestCasePopup, showCreateTestSuitePopup, showCreateProjectPopup } from '../utils'
import { getTestSuiteIdFromLocation } from '../navigation'
import testManagement from '../plugin'
export let currentSpace: Ref<TestProject> | undefined
const me = getCurrentAccount()
const query = createQuery()
let hasProject = currentSpace !== undefined
let loading = !hasProject
if (!hasProject) {
query.query(
testManagement.class.TestProject,
{ archived: false, members: me._id },
(res) => {
hasProject = res.length > 0
loading = false
},
{ limit: 1, projection: { _id: 1 } }
)
}
async function handleCreateProject (): Promise<void> {
await showCreateProjectPopup()
}
async function handleCreateTestSuite (): Promise<void> {
await showCreateTestSuitePopup(currentSpace, testManagement.ids.NoParent)
}
async function handleCreateTestCase (): Promise<void> {
if (currentSpace !== undefined) {
await showCreateTestCasePopup(currentSpace, getTestSuiteIdFromLocation())
} else {
console.warn('Project is not defined')
}
}
async function handleDropdownItemSelected (res?: SelectPopupValueType['id']): Promise<void> {
switch (res) {
case testManagement.string.CreateProject: {
await handleCreateProject()
return
}
case testManagement.string.CreateTestSuite: {
await handleCreateTestSuite()
return
}
case testManagement.string.CreateTestCase: {
await handleCreateTestCase()
}
}
}
const commonDropdownItems = [
{
id: testManagement.string.CreateTestSuite,
label: testManagement.string.CreateTestSuite,
icon: testManagement.icon.TestSuite
},
{
id: testManagement.string.CreateTestCase,
label: testManagement.string.CreateTestCase,
icon: testManagement.icon.TestCase
}
]
const dropdownItems = hasAccountRole(me, AccountRole.User)
? [
{
id: testManagement.string.CreateProject,
label: testManagement.string.CreateProject,
icon: testManagement.icon.TestProject
},
...commonDropdownItems
]
: commonDropdownItems
</script>
{#if loading}
<Loading shrink />
{:else}
<div class="antiNav-subheader">
{#if hasProject}
<ButtonWithDropdown
icon={IconAdd}
justify={'left'}
kind={'primary'}
label={testManagement.string.CreateTestCase}
dropdownIcon={IconDropdown}
{dropdownItems}
disabled={currentSpace === undefined}
on:click={handleCreateTestCase}
on:dropdown-selected={(ev) => {
void handleDropdownItemSelected(ev.detail)
}}
/>
{:else}
<Button
icon={IconAdd}
label={testManagement.string.CreateProject}
justify={'left'}
width={'100%'}
kind={'primary'}
gap={'large'}
on:click={showCreateProjectPopup}
/>
{/if}
</div>
{/if}

View File

@ -1,45 +0,0 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { getClient } from '@hcengineering/presentation'
import { Button, IconAdd, showPopup } from '@hcengineering/ui'
import testManagement from '../../plugin'
import CreateTestCase from './CreateTestCase.svelte'
import { openDoc } from '@hcengineering/view-resources'
const client = getClient()
async function newTestCase (): Promise<void> {
showPopup(CreateTestCase, {}, 'top', async (id) => {
if (id != null) {
const doc = await client.findOne(testManagement.class.TestCase, { _id: id })
if (doc !== undefined) {
void openDoc(client.getHierarchy(), doc)
}
}
})
}
</script>
<div class="antiNav-subheader">
<Button
icon={IconAdd}
label={testManagement.string.CreateTestCase}
kind={'primary'}
justify={'left'}
width="100%"
on:click={newTestCase}
/>
</div>

View File

@ -14,7 +14,7 @@
// //
import { type Resources } from '@hcengineering/platform' import { type Resources } from '@hcengineering/platform'
import NewTestCaseHeader from './components/test-case/NewTestCaseHeader.svelte' import TestManagementSpaceHeader from './components/TestManagementSpaceHeader.svelte'
import CreateProject from './components/project/CreateProject.svelte' import CreateProject from './components/project/CreateProject.svelte'
import ProjectSpacePresenter from './components/project/ProjectSpacePresenter.svelte' import ProjectSpacePresenter from './components/project/ProjectSpacePresenter.svelte'
import CreateTestSuite from './components/test-suite/CreateTestSuite.svelte' import CreateTestSuite from './components/test-suite/CreateTestSuite.svelte'
@ -34,7 +34,7 @@ import { resolveLocation, getTestSuiteLink } from './navigation'
export default async (): Promise<Resources> => ({ export default async (): Promise<Resources> => ({
component: { component: {
NewTestCaseHeader, TestManagementSpaceHeader,
CreateProject, CreateProject,
ProjectSpacePresenter, ProjectSpacePresenter,
CreateTestSuite, CreateTestSuite,

View File

@ -14,10 +14,18 @@
import testManagement, { testManagementId, type TestSuite, type TestProject } from '@hcengineering/test-management' import testManagement, { testManagementId, type TestSuite, type TestProject } from '@hcengineering/test-management'
import { type Doc, type Ref } from '@hcengineering/core' import { type Doc, type Ref } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import { getCurrentResolvedLocation, getPanelURI, type Location, type ResolvedLocation } from '@hcengineering/ui' import {
getCurrentResolvedLocation,
getLocation,
getPanelURI,
type Location,
type ResolvedLocation
} from '@hcengineering/ui'
import view, { type ObjectPanel } from '@hcengineering/view' import view, { type ObjectPanel } from '@hcengineering/view'
import { accessDeniedStore } from '@hcengineering/view-resources' import { accessDeniedStore } from '@hcengineering/view-resources'
const SUITE_KEY = 'attachedTo'
export function getPanelFragment<T extends Doc> (object: Pick<T, '_class' | '_id'>): string { export function getPanelFragment<T extends Doc> (object: Pick<T, '_class' | '_id'>): string {
const hierarchy = getClient().getHierarchy() const hierarchy = getClient().getHierarchy()
const objectPanelMixin = hierarchy.classHierarchyMixin<Doc, ObjectPanel>(object._class, view.mixin.ObjectPanel) const objectPanelMixin = hierarchy.classHierarchyMixin<Doc, ObjectPanel>(object._class, view.mixin.ObjectPanel)
@ -59,7 +67,7 @@ export function getTestSuiteLink (testSuite: Ref<TestSuite>): Location {
testSuite === undefined testSuite === undefined
? undefined ? undefined
: { : {
attachedTo: testSuite [SUITE_KEY]: testSuite
} }
return loc return loc
@ -71,6 +79,11 @@ export function getTestSuiteIdFromFragment (fragment: string): Ref<TestSuite> |
return props[6] != null ? (props[6] as Ref<TestSuite>) : undefined return props[6] != null ? (props[6] as Ref<TestSuite>) : undefined
} }
export function getTestSuiteIdFromLocation (): Ref<TestSuite> {
const location = getLocation()
return (location?.query?.[SUITE_KEY] as Ref<TestSuite>) ?? testManagement.ids.NoParent
}
export async function resolveLocation (loc: Location): Promise<ResolvedLocation | undefined> { export async function resolveLocation (loc: Location): Promise<ResolvedLocation | undefined> {
if (loc.path[2] !== testManagementId) { if (loc.path[2] !== testManagementId) {
return undefined return undefined

View File

@ -21,6 +21,8 @@ import { type TestProject, type TestCase, type TestSuite } from '@hcengineering/
import CreateTestSuiteComponent from './components/test-suite/CreateTestSuite.svelte' import CreateTestSuiteComponent from './components/test-suite/CreateTestSuite.svelte'
import EditTestSuiteComponent from './components/test-suite/EditTestSuite.svelte' import EditTestSuiteComponent from './components/test-suite/EditTestSuite.svelte'
import CreateTestCase from './components/test-case/CreateTestCase.svelte'
import CreateProject from './components/project/CreateProject.svelte'
export async function getPreviousAssignees (objectId: Ref<Doc> | undefined): Promise<Array<Ref<Contact>>> { export async function getPreviousAssignees (objectId: Ref<Doc> | undefined): Promise<Array<Ref<Contact>>> {
if (objectId === undefined) { if (objectId === undefined) {
@ -62,6 +64,14 @@ export async function showEditTestSuitePopup (suite: Ref<TestSuite>): Promise<vo
showPopup(EditTestSuiteComponent, { _id: suite }, 'top') showPopup(EditTestSuiteComponent, { _id: suite }, 'top')
} }
export async function showCreateTestCasePopup (space: Ref<TestProject>, testSuiteId: Ref<TestSuite>): Promise<void> {
showPopup(CreateTestCase, { space, testSuiteId }, 'top')
}
export async function showCreateProjectPopup (): Promise<void> {
showPopup(CreateProject, {}, 'top')
}
export async function CreateChildTestSuiteAction (doc: TestSuite): Promise<void> { export async function CreateChildTestSuiteAction (doc: TestSuite): Promise<void> {
await showCreateTestSuitePopup(doc.space, doc._id) await showCreateTestSuitePopup(doc.space, doc._id)
} }

View File

@ -166,7 +166,7 @@ export const testManagementPlugin = plugin(testManagementId, {
TestCaseSearchIcon: '' as AnyComponent, TestCaseSearchIcon: '' as AnyComponent,
TestCases: '' as AnyComponent, TestCases: '' as AnyComponent,
CreateProject: '' as AnyComponent, CreateProject: '' as AnyComponent,
NewTestCaseHeader: '' as AnyComponent, TestManagementSpaceHeader: '' as AnyComponent,
TestCaseStatusIcon: '' as AnyComponent, TestCaseStatusIcon: '' as AnyComponent,
PriorityIconPresenter: '' as AnyComponent, PriorityIconPresenter: '' as AnyComponent,
TestCaseStatusPresenter: '' as AnyComponent, TestCaseStatusPresenter: '' as AnyComponent,