mirror of
https://github.com/hcengineering/platform.git
synced 2025-01-03 08:57:14 +03: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(
|
||||
builder,
|
||||
{
|
||||
action: view.actionImpl.ValueSelector,
|
||||
actionPopup: view.component.ValueSelector,
|
||||
action: view.actionImpl.AttributeSelector,
|
||||
actionPopup: tracker.component.SprintEditor,
|
||||
actionProps: {
|
||||
attribute: 'sprint',
|
||||
_class: tracker.class.Sprint,
|
||||
queryOptions: {
|
||||
sort: {
|
||||
startDate: -1,
|
||||
targetDate: -1
|
||||
}
|
||||
},
|
||||
query: {},
|
||||
searchField: 'label',
|
||||
placeholder: tracker.string.Sprint
|
||||
isAction: true
|
||||
},
|
||||
label: tracker.string.Sprint,
|
||||
icon: tracker.icon.Sprint,
|
||||
|
@ -29,6 +29,7 @@
|
||||
import { getDayOfSprint } from '../../utils'
|
||||
import TimePresenter from '../issues/timereport/TimePresenter.svelte'
|
||||
import SprintSelector from './SprintSelector.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let value: Issue | IssueTemplate
|
||||
export let isEditable: boolean = true
|
||||
@ -41,19 +42,29 @@
|
||||
export let justify: 'left' | 'center' = 'left'
|
||||
export let width: string | undefined = '100%'
|
||||
export let onlyIcon: boolean = false
|
||||
export let isAction: boolean = false
|
||||
|
||||
export let groupBy: string | undefined = undefined
|
||||
export let enlargedText: boolean = false
|
||||
export let compression: boolean = false
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const handleSprintIdChanged = async (newSprintId: Ref<Sprint> | null | undefined) => {
|
||||
if (!isEditable || newSprintId === undefined || value.sprint === newSprintId) {
|
||||
return
|
||||
}
|
||||
|
||||
await client.update(value, { sprint: newSprintId })
|
||||
if (Array.isArray(value)) {
|
||||
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()
|
||||
@ -85,6 +96,7 @@
|
||||
showTooltip={{ label: value.sprint ? tracker.string.MoveToSprint : tracker.string.AddToSprint }}
|
||||
value={value.sprint}
|
||||
onChange={handleSprintIdChanged}
|
||||
{isAction}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
@ -111,6 +123,7 @@
|
||||
showTooltip={{ label: value.sprint ? tracker.string.MoveToSprint : tracker.string.AddToSprint }}
|
||||
value={value.sprint}
|
||||
onChange={handleSprintIdChanged}
|
||||
{isAction}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -36,6 +36,7 @@
|
||||
export let enlargedText: boolean = false
|
||||
export let short: boolean = false
|
||||
export let focusIndex: number | undefined = undefined
|
||||
export let isAction: boolean = false
|
||||
|
||||
export let useComponent: Ref<Component> | undefined = undefined
|
||||
export let showTooltip: LabelAndProps | undefined = undefined
|
||||
@ -72,13 +73,8 @@
|
||||
selectedSprint = sprints.find((it) => it._id === newSprintId)
|
||||
}
|
||||
|
||||
const handleSprintEditorOpened = async (event: MouseEvent): Promise<void> => {
|
||||
event.stopPropagation()
|
||||
if (!isEditable) {
|
||||
return
|
||||
}
|
||||
|
||||
const sprintInfo = [
|
||||
const getSprintInfo = (rawSprints: Sprint[]) => {
|
||||
return [
|
||||
{ id: null, icon: tracker.icon.Sprint, label: tracker.string.NoSprint },
|
||||
...rawSprints.map((p) => ({
|
||||
id: p._id,
|
||||
@ -87,6 +83,17 @@
|
||||
category: sprintStatusAssets[p.status]
|
||||
}))
|
||||
]
|
||||
}
|
||||
|
||||
$: sprints = getSprintInfo(rawSprints)
|
||||
|
||||
const handleSprintEditorOpened = async (event: MouseEvent): Promise<void> => {
|
||||
event.stopPropagation()
|
||||
if (!isEditable) {
|
||||
return
|
||||
}
|
||||
|
||||
const sprintInfo = sprints
|
||||
|
||||
showPopup(
|
||||
SelectPopup,
|
||||
@ -97,7 +104,16 @@
|
||||
}
|
||||
</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
|
||||
{focusIndex}
|
||||
{kind}
|
||||
|
@ -359,6 +359,33 @@ function ValueSelector (
|
||||
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 (
|
||||
element?: PopupPosAlignment | Resource<(e?: Event) => PopupAlignment | undefined>,
|
||||
evt?: Event
|
||||
@ -398,5 +425,6 @@ export const actionImpl = {
|
||||
ShowPanel,
|
||||
ShowPopup,
|
||||
ShowEditor,
|
||||
ValueSelector
|
||||
ValueSelector,
|
||||
AttributeSelector
|
||||
}
|
||||
|
@ -64,7 +64,11 @@
|
||||
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> = {}
|
||||
|
||||
|
@ -790,6 +790,13 @@ const view = plugin(viewId, {
|
||||
values?: { icon?: Asset, label: IntlString, id: number | string }[]
|
||||
|
||||
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