mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-16 13:21:57 +00:00
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:
parent
96dc2f9847
commit
2265d6f8d0
98
packages/ui/src/components/ButtonWithDropdown.svelte
Normal file
98
packages/ui/src/components/ButtonWithDropdown.svelte
Normal 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>
|
@ -52,6 +52,7 @@ export { getCurrentLocation, locationToUrl, navigate, location, setLocationStora
|
|||||||
export { default as EditBox } from './components/EditBox.svelte'
|
export { default as EditBox } from './components/EditBox.svelte'
|
||||||
export { default as Label } from './components/Label.svelte'
|
export { default as Label } from './components/Label.svelte'
|
||||||
export { default as Button } from './components/Button.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 ButtonGroup } from './components/ButtonGroup.svelte'
|
||||||
export { default as Status } from './components/Status.svelte'
|
export { default as Status } from './components/Status.svelte'
|
||||||
export { default as Component } from './components/Component.svelte'
|
export { default as Component } from './components/Component.svelte'
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Ref, Space } from '@hcengineering/core'
|
import { Ref, Space } from '@hcengineering/core'
|
||||||
import { MultipleDraftController, getClient } from '@hcengineering/presentation'
|
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 view from '@hcengineering/view'
|
||||||
import { onDestroy } from 'svelte'
|
import { onDestroy } from 'svelte'
|
||||||
import tracker from '../plugin'
|
import tracker from '../plugin'
|
||||||
@ -41,25 +41,49 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: label = draftExists || !closed ? tracker.string.ResumeDraft : tracker.string.NewIssue
|
$: 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()
|
const client = getClient()
|
||||||
|
|
||||||
let keys: string[] | undefined = undefined
|
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))
|
client.findOne(view.class.Action, { _id: tracker.action.NewIssue }).then((p) => (keys = p?.keyBinding))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiNav-subheader">
|
<div class="antiNav-subheader">
|
||||||
<Button
|
<ButtonWithDropdown
|
||||||
icon={IconAdd}
|
icon={IconAdd}
|
||||||
{label}
|
|
||||||
justify={'left'}
|
justify={'left'}
|
||||||
kind={'primary'}
|
kind={'primary'}
|
||||||
width={'100%'}
|
{label}
|
||||||
gap={'large'}
|
|
||||||
on:click={newIssue}
|
on:click={newIssue}
|
||||||
id={'new-issue'}
|
{dropdownItems}
|
||||||
showTooltip={{
|
dropdownIcon={IconDropdown}
|
||||||
|
on:dropdown-selected={(ev) => {
|
||||||
|
dropdownItemSelected(ev.detail)
|
||||||
|
}}
|
||||||
|
mainButtonId={'new-issue'}
|
||||||
|
showTooltipMain={{
|
||||||
direction: 'bottom',
|
direction: 'bottom',
|
||||||
label,
|
label,
|
||||||
keys
|
keys
|
||||||
@ -70,12 +94,13 @@
|
|||||||
<div class="draft-circle" />
|
<div class="draft-circle" />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</ButtonWithDropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.draft-circle-container {
|
.draft-circle-container {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
padding-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.draft-circle {
|
.draft-circle {
|
||||||
|
@ -39,7 +39,7 @@ export class IssuesPage extends CommonTrackerPage {
|
|||||||
this.modelSelectorAll = page.locator('div[data-id="tab-all"]')
|
this.modelSelectorAll = page.locator('div[data-id="tab-all"]')
|
||||||
this.modelSelectorActive = page.locator('div[data-id="tab-active"]')
|
this.modelSelectorActive = page.locator('div[data-id="tab-active"]')
|
||||||
this.modelSelectorBacklog = page.locator('div[data-id="tab-backlog"]')
|
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.inputPopupCreateNewIssueTitle = page.locator('form[id="tracker:string:NewIssue"] input[type="text"]')
|
||||||
this.inputPopupCreateNewIssueDescription = page.locator('form[id="tracker:string:NewIssue"] div.tiptap')
|
this.inputPopupCreateNewIssueDescription = page.locator('form[id="tracker:string:NewIssue"] div.tiptap')
|
||||||
this.buttonPopupCreateNewIssueStatus = page.locator('form[id="tracker:string:NewIssue"] div#status-editor button')
|
this.buttonPopupCreateNewIssueStatus = page.locator('form[id="tracker:string:NewIssue"] div#status-editor button')
|
||||||
|
Loading…
Reference in New Issue
Block a user