mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-05 15:24:22 +00:00
TSK-1166: sprint editor action (#3110)
Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
parent
9412db643e
commit
9b04d366e3
@ -1511,20 +1511,11 @@ export function createModel (builder: Builder): void {
|
|||||||
createAction(
|
createAction(
|
||||||
builder,
|
builder,
|
||||||
{
|
{
|
||||||
action: view.actionImpl.ValueSelector,
|
action: view.actionImpl.AttributeSelector,
|
||||||
actionPopup: view.component.ValueSelector,
|
actionPopup: tracker.component.SprintEditor,
|
||||||
actionProps: {
|
actionProps: {
|
||||||
attribute: 'sprint',
|
attribute: 'sprint',
|
||||||
_class: tracker.class.Sprint,
|
isAction: true
|
||||||
queryOptions: {
|
|
||||||
sort: {
|
|
||||||
startDate: -1,
|
|
||||||
targetDate: -1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
query: {},
|
|
||||||
searchField: 'label',
|
|
||||||
placeholder: tracker.string.Sprint
|
|
||||||
},
|
},
|
||||||
label: tracker.string.Sprint,
|
label: tracker.string.Sprint,
|
||||||
icon: tracker.icon.Sprint,
|
icon: tracker.icon.Sprint,
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
import { getDayOfSprint } from '../../utils'
|
import { getDayOfSprint } from '../../utils'
|
||||||
import TimePresenter from '../issues/timereport/TimePresenter.svelte'
|
import TimePresenter from '../issues/timereport/TimePresenter.svelte'
|
||||||
import SprintSelector from './SprintSelector.svelte'
|
import SprintSelector from './SprintSelector.svelte'
|
||||||
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
|
||||||
export let value: Issue | IssueTemplate
|
export let value: Issue | IssueTemplate
|
||||||
export let isEditable: boolean = true
|
export let isEditable: boolean = true
|
||||||
@ -41,19 +42,29 @@
|
|||||||
export let justify: 'left' | 'center' = 'left'
|
export let justify: 'left' | 'center' = 'left'
|
||||||
export let width: string | undefined = '100%'
|
export let width: string | undefined = '100%'
|
||||||
export let onlyIcon: boolean = false
|
export let onlyIcon: boolean = false
|
||||||
|
export let isAction: boolean = false
|
||||||
|
|
||||||
export let groupBy: string | undefined = undefined
|
export let groupBy: string | undefined = undefined
|
||||||
export let enlargedText: boolean = false
|
export let enlargedText: boolean = false
|
||||||
export let compression: boolean = false
|
export let compression: boolean = false
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
const handleSprintIdChanged = async (newSprintId: Ref<Sprint> | null | undefined) => {
|
const handleSprintIdChanged = async (newSprintId: Ref<Sprint> | null | undefined) => {
|
||||||
if (!isEditable || newSprintId === undefined || value.sprint === newSprintId) {
|
if (!isEditable || newSprintId === undefined || value.sprint === newSprintId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (Array.isArray(value)) {
|
||||||
await client.update(value, { sprint: newSprintId })
|
await Promise.all(
|
||||||
|
value.map(async (p) => {
|
||||||
|
await client.update(p, { sprint: newSprintId })
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
await client.update(value, { sprint: newSprintId })
|
||||||
|
}
|
||||||
|
if (isAction) dispatch('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
const sprintQuery = createQuery()
|
const sprintQuery = createQuery()
|
||||||
@ -85,6 +96,7 @@
|
|||||||
showTooltip={{ label: value.sprint ? tracker.string.MoveToSprint : tracker.string.AddToSprint }}
|
showTooltip={{ label: value.sprint ? tracker.string.MoveToSprint : tracker.string.AddToSprint }}
|
||||||
value={value.sprint}
|
value={value.sprint}
|
||||||
onChange={handleSprintIdChanged}
|
onChange={handleSprintIdChanged}
|
||||||
|
{isAction}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@ -111,6 +123,7 @@
|
|||||||
showTooltip={{ label: value.sprint ? tracker.string.MoveToSprint : tracker.string.AddToSprint }}
|
showTooltip={{ label: value.sprint ? tracker.string.MoveToSprint : tracker.string.AddToSprint }}
|
||||||
value={value.sprint}
|
value={value.sprint}
|
||||||
onChange={handleSprintIdChanged}
|
onChange={handleSprintIdChanged}
|
||||||
|
{isAction}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
export let enlargedText: boolean = false
|
export let enlargedText: boolean = false
|
||||||
export let short: boolean = false
|
export let short: boolean = false
|
||||||
export let focusIndex: number | undefined = undefined
|
export let focusIndex: number | undefined = undefined
|
||||||
|
export let isAction: boolean = false
|
||||||
|
|
||||||
export let useComponent: Ref<Component> | undefined = undefined
|
export let useComponent: Ref<Component> | undefined = undefined
|
||||||
export let showTooltip: LabelAndProps | undefined = undefined
|
export let showTooltip: LabelAndProps | undefined = undefined
|
||||||
@ -72,13 +73,8 @@
|
|||||||
selectedSprint = sprints.find((it) => it._id === newSprintId)
|
selectedSprint = sprints.find((it) => it._id === newSprintId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSprintEditorOpened = async (event: MouseEvent): Promise<void> => {
|
const getSprintInfo = (rawSprints: Sprint[]) => {
|
||||||
event.stopPropagation()
|
return [
|
||||||
if (!isEditable) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const sprintInfo = [
|
|
||||||
{ id: null, icon: tracker.icon.Sprint, label: tracker.string.NoSprint },
|
{ id: null, icon: tracker.icon.Sprint, label: tracker.string.NoSprint },
|
||||||
...rawSprints.map((p) => ({
|
...rawSprints.map((p) => ({
|
||||||
id: p._id,
|
id: p._id,
|
||||||
@ -87,6 +83,17 @@
|
|||||||
category: sprintStatusAssets[p.status]
|
category: sprintStatusAssets[p.status]
|
||||||
}))
|
}))
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
$: sprints = getSprintInfo(rawSprints)
|
||||||
|
|
||||||
|
const handleSprintEditorOpened = async (event: MouseEvent): Promise<void> => {
|
||||||
|
event.stopPropagation()
|
||||||
|
if (!isEditable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const sprintInfo = sprints
|
||||||
|
|
||||||
showPopup(
|
showPopup(
|
||||||
SelectPopup,
|
SelectPopup,
|
||||||
@ -97,7 +104,16 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if onlyIcon || sprintText === undefined}
|
{#if isAction}
|
||||||
|
<SelectPopup
|
||||||
|
value={sprints}
|
||||||
|
placeholder={popupPlaceholder}
|
||||||
|
searchable
|
||||||
|
on:close={(evt) => {
|
||||||
|
if (onChange !== undefined) onChange(evt.detail)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{:else if onlyIcon || sprintText === undefined}
|
||||||
<Button
|
<Button
|
||||||
{focusIndex}
|
{focusIndex}
|
||||||
{kind}
|
{kind}
|
||||||
|
@ -359,6 +359,33 @@ function ValueSelector (
|
|||||||
showPopup(view.component.ValueSelector, { ...props, value: doc, width: 'large' }, 'top')
|
showPopup(view.component.ValueSelector, { ...props, value: doc, width: 'large' }, 'top')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AttributeSelector (
|
||||||
|
doc: Doc | Doc[],
|
||||||
|
evt: Event,
|
||||||
|
props: {
|
||||||
|
actionPopup: AnyComponent
|
||||||
|
|
||||||
|
attribute: string
|
||||||
|
|
||||||
|
values?: Array<{ icon?: Asset, label: IntlString, id: number | string }>
|
||||||
|
|
||||||
|
isAction?: boolean
|
||||||
|
}
|
||||||
|
): void {
|
||||||
|
const client = getClient()
|
||||||
|
const hierarchy = client.getHierarchy()
|
||||||
|
const docArray = Array.isArray(doc) ? doc : [doc]
|
||||||
|
const attribute = hierarchy.getAttribute(docArray[0]._class, props.attribute)
|
||||||
|
showPopup(props.actionPopup, { ...props, value: docArray, width: 'large' }, 'top', (result) => {
|
||||||
|
console.log(result)
|
||||||
|
if (result != null) {
|
||||||
|
for (const docEl of docArray) {
|
||||||
|
void updateAttribute(client, docEl, docEl._class, { key: props.attribute, attr: attribute }, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function getPopupAlignment (
|
async function getPopupAlignment (
|
||||||
element?: PopupPosAlignment | Resource<(e?: Event) => PopupAlignment | undefined>,
|
element?: PopupPosAlignment | Resource<(e?: Event) => PopupAlignment | undefined>,
|
||||||
evt?: Event
|
evt?: Event
|
||||||
@ -398,5 +425,6 @@ export const actionImpl = {
|
|||||||
ShowPanel,
|
ShowPanel,
|
||||||
ShowPopup,
|
ShowPopup,
|
||||||
ShowEditor,
|
ShowEditor,
|
||||||
ValueSelector
|
ValueSelector,
|
||||||
|
AttributeSelector
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,11 @@
|
|||||||
dispatch('close', newStatus)
|
dispatch('close', newStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
$: current = (value as any)[attribute]
|
$: current = Array.isArray(value)
|
||||||
|
? value.every((v) => (v as any)[attribute] === (value as Array<any>)[0][attribute])
|
||||||
|
? (value as Array<any>)[0][attribute]
|
||||||
|
: value
|
||||||
|
: (value as any)[attribute]
|
||||||
|
|
||||||
let finalQuery: DocumentQuery<Doc> = {}
|
let finalQuery: DocumentQuery<Doc> = {}
|
||||||
|
|
||||||
|
@ -790,6 +790,13 @@ const view = plugin(viewId, {
|
|||||||
values?: { icon?: Asset, label: IntlString, id: number | string }[]
|
values?: { icon?: Asset, label: IntlString, id: number | string }[]
|
||||||
|
|
||||||
placeholder?: IntlString
|
placeholder?: IntlString
|
||||||
|
}>,
|
||||||
|
AttributeSelector: '' as ViewAction<{
|
||||||
|
attribute: string
|
||||||
|
isAction?: boolean
|
||||||
|
|
||||||
|
// Or list of values to select from
|
||||||
|
values?: { icon?: Asset, label: IntlString, id: number | string }[]
|
||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user