mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03:00
Tracker: fix status editor (#2097)
Signed-off-by: Sergei Ogorelkov <sergei.ogorelkov@xored.com>
This commit is contained in:
parent
6af76d678e
commit
5b534391b9
@ -250,7 +250,6 @@
|
||||
value={object}
|
||||
statuses={issueStatuses}
|
||||
kind="no-border"
|
||||
width="min-content"
|
||||
size="small"
|
||||
shouldShowLabel={true}
|
||||
on:change={({ detail }) => (object.status = detail)}
|
||||
@ -262,7 +261,6 @@
|
||||
kind="no-border"
|
||||
size="small"
|
||||
justify="center"
|
||||
width=""
|
||||
on:change={({ detail }) => (object.priority = detail)}
|
||||
/>
|
||||
<AssigneeEditor
|
||||
|
@ -1,57 +0,0 @@
|
||||
<!--
|
||||
// Copyright © 2022 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 { IssuePriority } from '@anticrm/tracker'
|
||||
import { Button, showPopup, SelectPopup, eventToHTMLElement } from '@anticrm/ui'
|
||||
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
|
||||
import { defaultPriorities, issuePriorities } from '../utils'
|
||||
import tracker from '../plugin'
|
||||
|
||||
export let priority: IssuePriority
|
||||
export let shouldShowLabel: boolean = true
|
||||
export let onPriorityChange: ((newPriority: IssuePriority | undefined) => void) | undefined = undefined
|
||||
export let isEditable: boolean = true
|
||||
|
||||
export let kind: ButtonKind = 'no-border'
|
||||
export let size: ButtonSize = 'small'
|
||||
export let justify: 'left' | 'center' = 'center'
|
||||
export let width: string | undefined = 'min-content'
|
||||
|
||||
const prioritiesInfo = defaultPriorities.map((p) => ({ id: p, ...issuePriorities[p] }))
|
||||
|
||||
const handlePriorityEditorOpened = (event: MouseEvent) => {
|
||||
event.stopPropagation()
|
||||
if (!isEditable) {
|
||||
return
|
||||
}
|
||||
showPopup(
|
||||
SelectPopup,
|
||||
{ value: prioritiesInfo, placeholder: tracker.string.SetPriority, searchable: true },
|
||||
eventToHTMLElement(event),
|
||||
onPriorityChange
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Button
|
||||
label={shouldShowLabel ? issuePriorities[priority].label : undefined}
|
||||
icon={issuePriorities[priority].icon}
|
||||
{justify}
|
||||
{width}
|
||||
{size}
|
||||
{kind}
|
||||
disabled={!isEditable}
|
||||
on:click={handlePriorityEditorOpened}
|
||||
/>
|
@ -1,65 +0,0 @@
|
||||
<!--
|
||||
// Copyright © 2022 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 { Ref, WithLookup } from '@anticrm/core'
|
||||
import { IssueStatus } from '@anticrm/tracker'
|
||||
import { Button, showPopup, SelectPopup, eventToHTMLElement } from '@anticrm/ui'
|
||||
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
|
||||
import tracker from '../plugin'
|
||||
|
||||
export let selectedStatusId: Ref<IssueStatus>
|
||||
export let statuses: WithLookup<IssueStatus>[]
|
||||
export let shouldShowLabel: boolean = true
|
||||
export let onStatusChange: ((newStatus: Ref<IssueStatus> | undefined) => void) | undefined = undefined
|
||||
export let isEditable: boolean = true
|
||||
|
||||
export let kind: ButtonKind = 'no-border'
|
||||
export let size: ButtonSize = 'small'
|
||||
export let justify: 'left' | 'center' = 'center'
|
||||
export let width: string | undefined = 'min-content'
|
||||
|
||||
$: selectedStatus = statuses.find((status) => status._id === selectedStatusId) ?? statuses[0]
|
||||
$: selectedStatusIcon = selectedStatus?.$lookup?.category?.icon
|
||||
$: selectedStatusLabel = shouldShowLabel ? selectedStatus?.name : undefined
|
||||
$: statusesInfo = statuses.map((s) => ({ id: s._id, text: s.name, color: s.color, icon: s.$lookup?.category?.icon }))
|
||||
|
||||
const handleStatusEditorOpened = (event: MouseEvent) => {
|
||||
if (!isEditable) {
|
||||
return
|
||||
}
|
||||
showPopup(
|
||||
SelectPopup,
|
||||
{ value: statusesInfo, placeholder: tracker.string.SetStatus, searchable: true },
|
||||
eventToHTMLElement(event),
|
||||
onStatusChange
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Button
|
||||
icon={selectedStatusIcon}
|
||||
{justify}
|
||||
{width}
|
||||
{size}
|
||||
{kind}
|
||||
disabled={!isEditable}
|
||||
on:click={handleStatusEditorOpened}
|
||||
>
|
||||
<svelte:fragment slot="content">
|
||||
{#if selectedStatusLabel}
|
||||
<span class="overflow-label disabled">{selectedStatusLabel}</span>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Button>
|
@ -182,14 +182,7 @@
|
||||
{#if issue && issueStatuses && issue.subIssues > 0}
|
||||
<SubIssuesSelector {issue} {currentTeam} {issueStatuses} />
|
||||
{/if}
|
||||
<PriorityEditor
|
||||
value={issue}
|
||||
isEditable={true}
|
||||
kind={'link-bordered'}
|
||||
size={'inline'}
|
||||
justify={'center'}
|
||||
width={''}
|
||||
/>
|
||||
<PriorityEditor value={issue} isEditable={true} kind={'link-bordered'} size={'inline'} justify={'center'} />
|
||||
<ProjectEditor
|
||||
value={issue}
|
||||
isEditable={true}
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
const replacedKeys: Map<string, BuildModelKey> = new Map<string, BuildModelKey>([
|
||||
['@currentTeam', { key: '', presenter: tracker.component.IssuePresenter, props: { currentTeam } }],
|
||||
['@statuses', { key: '', presenter: tracker.component.StatusEditor, props: { statuses } }]
|
||||
['@statuses', { key: '', presenter: tracker.component.StatusEditor, props: { statuses, justify: 'center' } }]
|
||||
])
|
||||
|
||||
function createConfig (descr: Viewlet, preference: ViewletPreference | undefined): (string | BuildModelKey)[] {
|
||||
|
@ -232,6 +232,7 @@
|
||||
<svelte:component
|
||||
this={attributeModel.presenter}
|
||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||
width="100%"
|
||||
{...attributeModel.props}
|
||||
/>
|
||||
</div>
|
||||
@ -256,6 +257,7 @@
|
||||
this={attributeModel.presenter}
|
||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||
issueId={docObject._id}
|
||||
width="100%"
|
||||
{...attributeModel.props}
|
||||
/>
|
||||
</div>
|
||||
|
@ -194,14 +194,7 @@
|
||||
{#if issue && issueStatuses && issue.subIssues > 0}
|
||||
<SubIssuesSelector {issue} {currentTeam} {issueStatuses} />
|
||||
{/if}
|
||||
<PriorityEditor
|
||||
value={issue}
|
||||
isEditable={true}
|
||||
kind={'link-bordered'}
|
||||
size={'inline'}
|
||||
justify={'center'}
|
||||
width={''}
|
||||
/>
|
||||
<PriorityEditor value={issue} isEditable={true} kind={'link-bordered'} size={'inline'} justify={'center'} />
|
||||
<ProjectEditor
|
||||
value={issue}
|
||||
isEditable={true}
|
||||
|
@ -17,10 +17,10 @@
|
||||
import { AttachedData } from '@anticrm/core'
|
||||
import { Issue, IssuePriority } from '@anticrm/tracker'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { tooltip } from '@anticrm/ui'
|
||||
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
|
||||
import { Button, eventToHTMLElement } from '@anticrm/ui'
|
||||
import { ButtonKind, ButtonSize, showPopup, SelectPopup } from '@anticrm/ui'
|
||||
import tracker from '../../plugin'
|
||||
import PrioritySelector from '../PrioritySelector.svelte'
|
||||
import { defaultPriorities, issuePriorities } from '../../utils'
|
||||
|
||||
export let value: Issue | AttachedData<Issue>
|
||||
export let isEditable: boolean = true
|
||||
@ -29,12 +29,28 @@
|
||||
export let kind: ButtonKind = 'link'
|
||||
export let size: ButtonSize = 'large'
|
||||
export let justify: 'left' | 'center' = 'left'
|
||||
export let width: string | undefined = '100%'
|
||||
export let width: string | undefined = undefined
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
const prioritiesInfo = defaultPriorities.map((p) => ({ id: p, ...issuePriorities[p] }))
|
||||
|
||||
const handlePriorityChanged = async (newPriority: IssuePriority | undefined) => {
|
||||
const handlePriorityEditorOpened = (event: MouseEvent) => {
|
||||
event.stopPropagation()
|
||||
|
||||
if (!isEditable) {
|
||||
return
|
||||
}
|
||||
|
||||
showPopup(
|
||||
SelectPopup,
|
||||
{ value: prioritiesInfo, placeholder: tracker.string.SetPriority, searchable: true },
|
||||
eventToHTMLElement(event),
|
||||
changePriority
|
||||
)
|
||||
}
|
||||
|
||||
const changePriority = async (newPriority: IssuePriority | undefined) => {
|
||||
if (!isEditable || newPriority === undefined || value.priority === newPriority) {
|
||||
return
|
||||
}
|
||||
@ -48,16 +64,15 @@
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
<div class="clear-mins" use:tooltip={isEditable ? { label: tracker.string.SetPriority } : undefined}>
|
||||
<PrioritySelector
|
||||
{kind}
|
||||
{size}
|
||||
{width}
|
||||
{justify}
|
||||
{isEditable}
|
||||
{shouldShowLabel}
|
||||
bind:priority={value.priority}
|
||||
onPriorityChange={handlePriorityChanged}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
showTooltip={isEditable ? { label: tracker.string.SetPriority } : undefined}
|
||||
label={shouldShowLabel ? issuePriorities[value.priority].label : undefined}
|
||||
icon={issuePriorities[value.priority].icon}
|
||||
{justify}
|
||||
{width}
|
||||
{size}
|
||||
{kind}
|
||||
disabled={!isEditable}
|
||||
on:click={handlePriorityEditorOpened}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -17,13 +17,12 @@
|
||||
import { AttachedData, Ref, SortingOrder, WithLookup } from '@anticrm/core'
|
||||
import { Issue, IssueStatus } from '@anticrm/tracker'
|
||||
import { createQuery, getClient } from '@anticrm/presentation'
|
||||
import { tooltip, TooltipAlignment } from '@anticrm/ui'
|
||||
import { Button, showPopup, SelectPopup, TooltipAlignment, eventToHTMLElement } from '@anticrm/ui'
|
||||
import type { ButtonKind, ButtonSize } from '@anticrm/ui'
|
||||
import tracker from '../../plugin'
|
||||
import StatusSelector from '../StatusSelector.svelte'
|
||||
|
||||
export let value: Issue | AttachedData<Issue>
|
||||
export let statuses: WithLookup<IssueStatus>[]
|
||||
export let statuses: WithLookup<IssueStatus>[] | undefined = undefined
|
||||
export let isEditable: boolean = true
|
||||
export let shouldShowLabel: boolean = false
|
||||
export let tooltipAlignment: TooltipAlignment | undefined = undefined
|
||||
@ -31,13 +30,13 @@
|
||||
export let kind: ButtonKind = 'link'
|
||||
export let size: ButtonSize = 'large'
|
||||
export let justify: 'left' | 'center' = 'left'
|
||||
export let width: string | undefined = '100%'
|
||||
export let width: string | undefined = undefined
|
||||
|
||||
const client = getClient()
|
||||
const statusesQuery = createQuery()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const handleStatusChanged = async (newStatus: Ref<IssueStatus> | undefined) => {
|
||||
const changeStatus = async (newStatus: Ref<IssueStatus> | undefined) => {
|
||||
if (!isEditable || newStatus === undefined || value.status === newStatus) {
|
||||
return
|
||||
}
|
||||
@ -48,6 +47,24 @@
|
||||
await client.update(value, { status: newStatus })
|
||||
}
|
||||
}
|
||||
|
||||
const handleStatusEditorOpened = (event: MouseEvent) => {
|
||||
if (!isEditable) {
|
||||
return
|
||||
}
|
||||
|
||||
showPopup(
|
||||
SelectPopup,
|
||||
{ value: statusesInfo, placeholder: tracker.string.SetStatus, searchable: true },
|
||||
eventToHTMLElement(event),
|
||||
changeStatus
|
||||
)
|
||||
}
|
||||
|
||||
$: selectedStatus = statuses?.find((status) => status._id === value.status) ?? statuses?.[0]
|
||||
$: selectedStatusIcon = selectedStatus?.$lookup?.category?.icon
|
||||
$: selectedStatusLabel = shouldShowLabel ? selectedStatus?.name : undefined
|
||||
$: statusesInfo = statuses?.map((s) => ({ id: s._id, text: s.name, color: s.color, icon: s.$lookup?.category?.icon }))
|
||||
$: if (!statuses) {
|
||||
const query = '_id' in value ? { attachedTo: value.space } : {}
|
||||
statusesQuery.query(
|
||||
@ -65,20 +82,29 @@
|
||||
</script>
|
||||
|
||||
{#if value && statuses}
|
||||
<div
|
||||
class="clear-mins"
|
||||
use:tooltip={isEditable ? { label: tracker.string.SetStatus, direction: tooltipAlignment } : undefined}
|
||||
>
|
||||
<StatusSelector
|
||||
{kind}
|
||||
{size}
|
||||
{width}
|
||||
{#if selectedStatusLabel}
|
||||
<Button
|
||||
showTooltip={isEditable ? { label: tracker.string.SetStatus, direction: tooltipAlignment } : undefined}
|
||||
icon={selectedStatusIcon}
|
||||
disabled={!isEditable}
|
||||
{justify}
|
||||
{isEditable}
|
||||
{shouldShowLabel}
|
||||
{statuses}
|
||||
bind:selectedStatusId={value.status}
|
||||
onStatusChange={handleStatusChanged}
|
||||
{size}
|
||||
{kind}
|
||||
{width}
|
||||
on:click={handleStatusEditorOpened}
|
||||
>
|
||||
<span slot="content" class="overflow-label disabled">{selectedStatusLabel}</span>
|
||||
</Button>
|
||||
{:else}
|
||||
<Button
|
||||
showTooltip={isEditable ? { label: tracker.string.SetStatus, direction: tooltipAlignment } : undefined}
|
||||
icon={selectedStatusIcon}
|
||||
disabled={!isEditable}
|
||||
{justify}
|
||||
{size}
|
||||
{kind}
|
||||
{width}
|
||||
on:click={handleStatusEditorOpened}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
@ -103,13 +103,13 @@
|
||||
|
||||
<div bind:this={thisRef} class="flex-col root">
|
||||
<div class="flex-row-top">
|
||||
<div id="status-editor">
|
||||
<div id="status-editor" class="mr-1">
|
||||
<StatusEditor
|
||||
value={newIssue}
|
||||
statuses={issueStatuses}
|
||||
kind="transparent"
|
||||
width="min-content"
|
||||
size="medium"
|
||||
justify="center"
|
||||
tooltipAlignment="bottom"
|
||||
on:change={({ detail }) => (newIssue.status = detail)}
|
||||
/>
|
||||
@ -141,7 +141,6 @@
|
||||
kind="no-border"
|
||||
size="small"
|
||||
justify="center"
|
||||
width=""
|
||||
on:change={({ detail }) => (newIssue.priority = detail)}
|
||||
/>
|
||||
<AssigneeEditor
|
||||
|
@ -93,13 +93,21 @@
|
||||
<div class="draggable-mark"><Circles /></div>
|
||||
</div>
|
||||
<div class="flex-center ml-6 clear-mins">
|
||||
<div class="mr-2">
|
||||
<PriorityEditor value={issue} isEditable kind="transparent" justify="center" width="" />
|
||||
<div class="mr-1">
|
||||
<PriorityEditor value={issue} isEditable kind="transparent" justify="center" />
|
||||
</div>
|
||||
<span class="flex-no-shrink text" on:click={() => openIssue(issue)}>
|
||||
{getIssueId(currentTeam, issue)}
|
||||
</span>
|
||||
<StatusEditor value={issue} statuses={issueStatuses} kind="transparent" tooltipAlignment="bottom" />
|
||||
<div class="mx-1">
|
||||
<StatusEditor
|
||||
value={issue}
|
||||
statuses={issueStatuses}
|
||||
justify="center"
|
||||
kind="transparent"
|
||||
tooltipAlignment="bottom"
|
||||
/>
|
||||
</div>
|
||||
<span class="text name" title={issue.title} on:click={() => openIssue(issue)}>
|
||||
{issue.title}
|
||||
</span>
|
||||
|
Loading…
Reference in New Issue
Block a user