Add dropdown with creating project button for "New issue" button in tracker (#4612)

Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
Vyacheslav Tumanov 2024-02-13 20:11:38 +05:00 committed by GitHub
parent 96dc2f9847
commit 2265d6f8d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 134 additions and 10 deletions

View File

@ -0,0 +1,98 @@
<!--
// Copyright © 2023 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 { Asset, IntlString } from '@hcengineering/platform'
import {
AnySvelteComponent,
Button,
ButtonKind,
Icon,
Label,
SelectPopup,
SelectPopupValueType,
eventToHTMLElement,
showPopup,
LabelAndProps
} from '../index'
import { createEventDispatcher } from 'svelte'
export let dropdownItems: SelectPopupValueType[]
export let label: IntlString | undefined = undefined
export let kind: ButtonKind = 'primary'
export let justify: 'left' | 'center' = 'center'
export let icon: Asset | AnySvelteComponent | undefined = undefined
export let dropdownIcon: Asset | AnySvelteComponent | undefined = undefined
export let showTooltipMain: LabelAndProps | undefined = undefined
export let mainButtonId: string | undefined = undefined
const dispatch = createEventDispatcher()
function openDropdown (ev: MouseEvent): void {
showPopup(SelectPopup, { value: dropdownItems }, eventToHTMLElement(ev), (res) => {
dispatch('dropdown-selected', res)
})
}
</script>
<div class="w-full flex-row-center">
<div class="flex-grow">
<Button
width="100%"
{icon}
{kind}
shape="rectangle-right"
{justify}
borderStyle="none"
on:click
showTooltip={showTooltipMain}
id={mainButtonId}
>
<div class="flex w-full" slot="content">
<div class="flex-row-center w-full flex-between">
{#if label}
<Label {label} />
<slot name="content" />
<div class="{kind} vertical-divider max-h-5 h-5" />
{/if}
</div>
</div>
</Button>
</div>
<Button width="1.75rem" {kind} shape="rectangle-left" justify="center" borderStyle="none" on:click={openDropdown}>
<div slot="icon">
{#if dropdownIcon}
<Icon icon={dropdownIcon} size="small" />
{/if}
</div>
</Button>
</div>
<style lang="scss">
.vertical-divider {
background-color: var(--theme-content-color);
min-width: 1px;
opacity: 0.25;
margin-right: -0.75rem;
&.primary,
&.secondary,
&.positive,
&.negative,
&.dangerous,
&.contrast {
background-color: var(--primary-button-content-color);
}
}
</style>

View File

@ -52,6 +52,7 @@ export { getCurrentLocation, locationToUrl, navigate, location, setLocationStora
export { default as EditBox } from './components/EditBox.svelte'
export { default as Label } from './components/Label.svelte'
export { default as Button } from './components/Button.svelte'
export { default as ButtonWithDropdown } from './components/ButtonWithDropdown.svelte'
export { default as ButtonGroup } from './components/ButtonGroup.svelte'
export { default as Status } from './components/Status.svelte'
export { default as Component } from './components/Component.svelte'

View File

@ -15,7 +15,7 @@
<script lang="ts">
import { Ref, Space } from '@hcengineering/core'
import { MultipleDraftController, getClient } from '@hcengineering/presentation'
import { Button, IconAdd, showPopup } from '@hcengineering/ui'
import { ButtonWithDropdown, IconAdd, IconDropdown, SelectPopupValueType, showPopup } from '@hcengineering/ui'
import view from '@hcengineering/view'
import { onDestroy } from 'svelte'
import tracker from '../plugin'
@ -41,25 +41,49 @@
}
$: label = draftExists || !closed ? tracker.string.ResumeDraft : tracker.string.NewIssue
$: dropdownItems = [
{
id: tracker.string.CreateProject,
label: tracker.string.CreateProject
},
{
id: tracker.string.NewIssue,
label
}
]
const client = getClient()
let keys: string[] | undefined = undefined
async function dropdownItemSelected (res?: SelectPopupValueType['id']): Promise<void> {
if (res == null) return
if (res === tracker.string.CreateProject) {
closed = false
showPopup(tracker.component.CreateProject, {}, 'top', () => {
closed = true
})
} else {
await newIssue()
}
}
client.findOne(view.class.Action, { _id: tracker.action.NewIssue }).then((p) => (keys = p?.keyBinding))
</script>
<div class="antiNav-subheader">
<Button
<ButtonWithDropdown
icon={IconAdd}
{label}
justify={'left'}
kind={'primary'}
width={'100%'}
gap={'large'}
{label}
on:click={newIssue}
id={'new-issue'}
showTooltip={{
{dropdownItems}
dropdownIcon={IconDropdown}
on:dropdown-selected={(ev) => {
dropdownItemSelected(ev.detail)
}}
mainButtonId={'new-issue'}
showTooltipMain={{
direction: 'bottom',
label,
keys
@ -70,12 +94,13 @@
<div class="draft-circle" />
{/if}
</div>
</Button>
</ButtonWithDropdown>
</div>
<style lang="scss">
.draft-circle-container {
margin-left: auto;
padding-right: 12px;
}
.draft-circle {

View File

@ -39,7 +39,7 @@ export class IssuesPage extends CommonTrackerPage {
this.modelSelectorAll = page.locator('div[data-id="tab-all"]')
this.modelSelectorActive = page.locator('div[data-id="tab-active"]')
this.modelSelectorBacklog = page.locator('div[data-id="tab-backlog"]')
this.buttonCreateNewIssue = page.locator('button > span', { hasText: 'New issue' })
this.buttonCreateNewIssue = page.locator('button > div', { hasText: 'New issue' })
this.inputPopupCreateNewIssueTitle = page.locator('form[id="tracker:string:NewIssue"] input[type="text"]')
this.inputPopupCreateNewIssueDescription = page.locator('form[id="tracker:string:NewIssue"] div.tiptap')
this.buttonPopupCreateNewIssueStatus = page.locator('form[id="tracker:string:NewIssue"] div#status-editor button')