Signed-off-by: Ilya Sumbatyants <ilya.sumb@gmail.com>
This commit is contained in:
Ilya Sumbatyants
2021-12-17 10:08:37 +01:00
committed by GitHub
parent 34b9495631
commit b0ffc0ed46
44 changed files with 482 additions and 705 deletions
@@ -14,7 +14,7 @@
-->
<script lang="ts">
import contact, { Employee } from '@anticrm/contact'
import type { AttachedData, Data, Doc, Ref, Space } from '@anticrm/core'
import { AttachedData, calcRank, Data, Doc, Ref, Space } from '@anticrm/core'
import { generateId } from '@anticrm/core'
import { OK, Status } from '@anticrm/platform'
import { Card, getClient, UserBox } from '@anticrm/presentation'
@@ -63,6 +63,11 @@
throw new Error('sequence object not found')
}
const lastOne = await client.findOne(
task.class.Task,
{ state: state._id },
{ sort: { rank: SortingOrder.Descending } }
)
const incResult = await client.updateDoc(
task.class.Sequence,
task.space.Sequence,
@@ -79,7 +84,8 @@
assignee,
number: (incResult as any).object.sequence,
doneState: null,
state: state._id
state: state._id,
rank: calcRank(lastOne, undefined)
}
await client.addCollection(task.class.Issue, _space, parent?._id ?? task.global.Task, parent?._class ?? task.class.Issue, 'tasks', value, taskId)
@@ -14,7 +14,7 @@
// limitations under the License.
-->
<script lang="ts">
import type { Ref, Doc } from '@anticrm/core'
import { Ref, Doc, SortingOrder, calcRank } from '@anticrm/core'
import { createQuery, getClient } from '@anticrm/presentation'
import type { Kanban, State, DoneState } from '@anticrm/task'
import task from '@anticrm/task'
@@ -33,45 +33,49 @@
const client = getClient()
function sort <T extends Doc> (order: Ref<T>[], items: T[]): T[] {
if (items.length === 0) {
return []
}
const itemMap = new Map(items.map(x => [x._id, x]))
const x = order
.map(id => itemMap.get(id))
.filter((x): x is T => x !== undefined)
return x
}
const statesQ = createQuery()
$: statesQ.query(task.class.State, { _id: { $in: kanban.states ?? [] } }, result => { states = sort(kanban.states, result) })
$: statesQ.query(task.class.State, { space: kanban.space }, result => { states = result}, {
sort: {
rank: SortingOrder.Ascending
}
})
const doneStatesQ = createQuery()
$: doneStatesQ.query(task.class.DoneState, { _id: { $in: kanban.doneStates } }, (result) => { doneStates = sort(kanban.doneStates, result) })
$: doneStatesQ.query(task.class.DoneState, { space: kanban.space }, (result) => { doneStates = result }, {
sort: {
rank: SortingOrder.Ascending
}
})
async function onMove ({ detail: { stateID, position } }: { detail: { stateID: Ref<State>, position: number } }) {
client.updateDoc(kanban._class, kanban.space, kanban._id, {
$move: {
states: {
$value: stateID,
$position: position
}
const [prev, next] = [states[position - 1], states[position + 1]]
const state = states.find((x) => x._id === stateID)
if (state === undefined) {
return
}
await client.updateDoc(
state._class,
state.space,
state._id,
{
rank: calcRank(prev, next)
}
})
)
}
async function onAdd () {
const state = await client.createDoc(task.class.State, kanban.space, {
const lastOne = await client.findOne(
task.class.State,
{ space: kanban.space },
{ sort: { rank: SortingOrder.Descending } }
)
await client.createDoc(task.class.State, kanban.space, {
title: 'New State',
color: '#7C6FCD'
})
await client.updateDoc(kanban._class, kanban.space, kanban._id, {
$push: {
states: state
}
color: '#7C6FCD',
rank: calcRank(lastOne, undefined)
})
}
</script>
@@ -15,7 +15,7 @@
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Ref, Space, Doc, generateId } from '@anticrm/core'
import { Ref, Space, SortingOrder, calcRank } from '@anticrm/core'
import core from '@anticrm/core'
import { createQuery, getClient } from '@anticrm/presentation'
import type { State, DoneStateTemplate, KanbanTemplate, StateTemplate } from '@anticrm/task'
@@ -35,42 +35,49 @@
const dispatch = createEventDispatcher()
const client = getClient()
function sort <T extends Doc>(order: Ref<T>[], items: T[]): T[] {
if (items.length === 0) {
return []
}
const itemMap = new Map(items.map(x => [x._id, x]))
const x = order
.map(id => itemMap.get(id))
.filter((x): x is T => x !== undefined)
return x
}
const statesQ = createQuery()
$: statesQ.query(task.class.StateTemplate, { attachedTo: kanban._id }, result => { states = sort(kanban.states, result) })
$: statesQ.query(task.class.StateTemplate, { attachedTo: kanban._id }, result => { states = result }, {
sort: {
rank: SortingOrder.Ascending
}
})
const doneStatesQ = createQuery()
$: doneStatesQ.query(task.class.DoneStateTemplate, { attachedTo: kanban._id }, (result) => { doneStates = sort(kanban.doneStates, result) })
$: doneStatesQ.query(task.class.DoneStateTemplate, { attachedTo: kanban._id }, (result) => { doneStates = result }, {
sort: {
rank: SortingOrder.Ascending
}
})
let space: Space | undefined
const spaceQ = createQuery()
$: spaceQ.query(core.class.Space, { _id: kanban.space }, (result) => { space = result[0] })
async function onMove ({ detail: { stateID, position } }: { detail: { stateID: Ref<StateTemplate>, position: number } }) {
client.updateDoc(kanban._class, kanban.space, kanban._id, {
$move: {
states: {
$value: stateID,
$position: position
}
const [prev, next] = [states[position - 1], states[position + 1]]
const state = states.find((x) => x._id === stateID)
if (state === undefined) {
return
}
await client.updateDoc(
state._class,
state.space,
state._id,
{
rank: calcRank(prev, next)
}
})
)
}
async function onAdd () {
const stateID = generateId<StateTemplate>()
const lastOne = await client.findOne(
task.class.StateTemplate,
{ attachedTo: kanban._id },
{ sort: { rank: SortingOrder.Descending } }
)
await client.addCollection(
task.class.StateTemplate,
kanban.space,
@@ -79,16 +86,10 @@
'statesC',
{
title: 'New State',
color: '#7C6FCD'
},
stateID
)
await client.updateDoc(kanban._class, kanban.space, kanban._id, {
$push: {
states: stateID
color: '#7C6FCD',
rank: calcRank(lastOne, undefined)
}
})
)
}
function onDelete ({ detail: { state } }: { detail: { state: State }}) {
@@ -15,7 +15,7 @@
-->
<script lang="ts">
import type { AttachedDoc, Class, Doc, FindOptions, Ref } from '@anticrm/core'
import { AttachedDoc, calcRank, Class, Doc, DocumentUpdate, DocWithRank, FindOptions, Ref, SortingOrder } from '@anticrm/core'
import core from '@anticrm/core'
import { getResource } from '@anticrm/platform'
import { createQuery, getClient } from '@anticrm/presentation'
@@ -26,7 +26,7 @@
import KanbanPanel from './KanbanPanel.svelte'
// import KanbanPanelEmpty from './KanbanPanelEmpty.svelte'
type Item = Doc & { state: Ref<State>, doneState: Ref<DoneState> | null }
type Item = DocWithRank & { state: Ref<State>, doneState: Ref<DoneState> | null }
export let _class: Ref<Class<Item>>
export let space: Ref<SpaceWithStates>
@@ -36,50 +36,38 @@
let kanban: Kanban
let states: State[] = []
let rawStates: State[] = []
let objects: (Item | undefined)[] = []
let rawObjects: Item[] = []
let kanbanStates: Ref<State>[] = []
let kanbanDoneStates: Ref<DoneState>[] = []
let objects: Item[] = []
let wonState: WonState | undefined
let lostState: LostState | undefined
const kanbanQuery = createQuery()
$: kanbanQuery.query(task.class.Kanban, { attachedTo: space }, result => { kanban = result[0] })
$: kanbanStates = kanban?.states ?? []
$: kanbanDoneStates = kanban?.doneStates ?? []
function sort (kanban: Kanban, states: State[]): State[] {
if (kanban === undefined || states.length === 0) { return [] }
const map = states.reduce((map, state) => { map.set(state._id, state); return map }, new Map<Ref<State>, State>())
return kanban.states.map(id => map.get(id) as State)
}
function sortObjects<T extends Doc> (kanban: Kanban, objects: T[]): (T | undefined)[] {
if (kanban === undefined || objects.length === 0) { return [] }
const map = objects.reduce((map, doc) => { map.set(doc._id, doc); return map }, new Map<Ref<T>, T>())
return kanban.order
.map(id => map.get(id as Ref<T>))
}
const statesQuery = createQuery()
$: if (kanbanStates.length > 0) statesQuery.query(task.class.State, { _id: { $in: kanbanStates } }, result => { rawStates = result })
$: states = sort(kanban, rawStates)
$: if (kanban !== undefined) {
statesQuery.query(task.class.State, { space: kanban.space }, result => { states = result }, {
sort: {
rank: SortingOrder.Ascending
}
})
}
const doneStatesQ = createQuery()
$: if (kanbanDoneStates.length > 0) {
doneStatesQ.query(task.class.DoneState, { _id: { $in: kanbanDoneStates } }, (result) => {
$: if (kanban !== undefined) {
doneStatesQ.query(task.class.DoneState, { space: kanban.space }, (result) => {
wonState = result.find((x) => x._class === task.class.WonState)
lostState = result.find((x) => x._class === task.class.LostState)
})
}
const query = createQuery()
$: query.query(_class, { space, doneState: null }, result => { rawObjects = result }, options)
$: objects = sortObjects(kanban, rawObjects)
$: query.query(_class, { space, doneState: null }, result => { objects = result }, {
...options,
sort: {
rank: SortingOrder.Ascending
},
})
function dragover (ev: MouseEvent, object: Item) {
if (dragCard !== object) {
@@ -89,28 +77,44 @@
}
}
async function updateItem (item: Item, update: DocumentUpdate<Item>) {
if (client.getHierarchy().isDerived(_class, core.class.AttachedDoc)) {
const adoc: AttachedDoc = item as Doc as AttachedDoc
await client.updateCollection(
_class,
space,
adoc._id as Ref<Doc> as Ref<AttachedDoc>,
adoc.attachedTo,
adoc.attachedToClass,
adoc.collection,
update
)
} else {
await client.updateDoc(item._class, item.space, item._id, update)
}
}
async function move (state: Ref<State>) {
const id = dragCard._id
let updates: DocumentUpdate<Item> = {}
if (dragCardInitialState !== state) {
if (client.getHierarchy().isDerived(_class, core.class.AttachedDoc)) {
const adoc: AttachedDoc = dragCard as Doc as AttachedDoc
// We need to update using updateCollection
client.updateCollection(_class, space, id as Ref<Doc> as Ref<AttachedDoc>, adoc.attachedTo, adoc.attachedToClass, adoc.collection, { state })
} else {
client.updateDoc<Task>(_class, space, id as Ref<Task>, { state })
updates = {
...updates,
state
}
}
if (dragCardInitialPosition !== dragCardEndPosition) {
client.updateDoc(task.class.Kanban, space, kanban._id, {
$move: {
order: {
$value: id,
$position: dragCardEndPosition
}
}
})
const [prev, next] = [objects[dragCardEndPosition - 1], objects[dragCardEndPosition + 1]]
updates = {
...updates,
rank: calcRank(prev, next)
}
}
if (Object.keys(updates).length > 0) {
await updateItem(dragCard, updates)
}
}
@@ -128,25 +132,9 @@
}
const onDone = (state: DoneState) => async () => {
if (client.getHierarchy().isDerived(_class, core.class.AttachedDoc)) {
const adoc: AttachedDoc = dragCard as Doc as AttachedDoc
await client.updateCollection<Doc, Task>(
_class,
space,
adoc._id as Ref<Task>,
adoc.attachedTo,
adoc.attachedToClass,
adoc.collection,
{ doneState: state._id }
)
} else {
await client.updateDoc(dragCard._class, dragCard.space, dragCard._id, {
doneState: state._id
})
}
isDragging = false
hoveredDoneState = undefined
await updateItem(dragCard, { doneState: state._id })
}
let isDragging = false
@@ -174,7 +162,7 @@
}}>
<!-- <KanbanCardEmpty label={'Create new application'} /> -->
{#each objects as object, j (object)}
{#if object !== undefined && object.state === state._id}
{#if object.state === state._id}
<div
class="step-tb75"
on:dragover|preventDefault={(ev) => {
@@ -226,11 +214,9 @@
class="flex-grow flex-center done-item"
class:hovered={hoveredDoneState === lostState._id}
on:dragenter={() => {
console.log('enter')
hoveredDoneState = lostState?._id
}}
on:dragleave={() => {
console.log('leave')
hoveredDoneState = undefined
}}
on:dragover|preventDefault={() => {}}