mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-21 07:46:24 +00:00
initial kanban reordering
Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
parent
0d11546617
commit
d2262bbb16
@ -14,7 +14,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import type { IntlString } from '@anticrm/platform'
|
import type { IntlString } from '@anticrm/platform'
|
||||||
import type { Account, Arr, Ref, Space, Domain, State } from '@anticrm/core'
|
import type { Account, Arr, Ref, Space, Domain, State, Doc } from '@anticrm/core'
|
||||||
import { DOMAIN_MODEL } from '@anticrm/core'
|
import { DOMAIN_MODEL } from '@anticrm/core'
|
||||||
import { Model, Prop, TypeString } from '@anticrm/model'
|
import { Model, Prop, TypeString } from '@anticrm/model'
|
||||||
import core from './component'
|
import core from './component'
|
||||||
@ -48,4 +48,5 @@ export class TState extends TDoc implements State {
|
|||||||
@Model(core.class.SpaceWithStates, core.class.Space)
|
@Model(core.class.SpaceWithStates, core.class.Space)
|
||||||
export class TSpaceWithStates extends TSpace {
|
export class TSpaceWithStates extends TSpace {
|
||||||
states!: Arr<Ref<State>>
|
states!: Arr<Ref<State>>
|
||||||
|
order!: Arr<Ref<Doc>>
|
||||||
}
|
}
|
||||||
|
@ -209,4 +209,5 @@ export interface State extends Doc {
|
|||||||
*/
|
*/
|
||||||
export interface SpaceWithStates extends Space {
|
export interface SpaceWithStates extends Space {
|
||||||
states: Arr<Ref<State>>
|
states: Arr<Ref<State>>
|
||||||
|
order: Arr<Ref<Doc>>
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import type { Ref, Space } from '@anticrm/core'
|
import type { Ref, Space, SpaceWithStates } from '@anticrm/core'
|
||||||
import { Status, OK, Severity } from '@anticrm/platform'
|
import { Status, OK, Severity } from '@anticrm/platform'
|
||||||
import { DatePicker, EditBox, Tabs, Section, Grid, Status as StatusControl } from '@anticrm/ui'
|
import { DatePicker, EditBox, Tabs, Section, Grid, Status as StatusControl } from '@anticrm/ui'
|
||||||
import { UserBox, Card, UserInfo, Avatar } from '@anticrm/presentation'
|
import { UserBox, Card, UserInfo, Avatar } from '@anticrm/presentation'
|
||||||
@ -30,7 +30,7 @@
|
|||||||
import recruit from '../plugin'
|
import recruit from '../plugin'
|
||||||
import contact from '@anticrm/contact'
|
import contact from '@anticrm/contact'
|
||||||
|
|
||||||
export let space: Ref<Space>
|
export let space: Ref<SpaceWithStates>
|
||||||
export let candidate: Ref<Candidate> // | null = null
|
export let candidate: Ref<Candidate> // | null = null
|
||||||
export let employee: Ref<Employee> // | null = null
|
export let employee: Ref<Employee> // | null = null
|
||||||
|
|
||||||
@ -47,10 +47,16 @@
|
|||||||
if (state === undefined) {
|
if (state === undefined) {
|
||||||
throw new Error('create application: state not found')
|
throw new Error('create application: state not found')
|
||||||
}
|
}
|
||||||
await client.createDoc(recruit.class.Applicant, _space, {
|
const id = await client.createDoc(recruit.class.Applicant, _space, {
|
||||||
candidate,
|
candidate,
|
||||||
state: state._id
|
state: state._id
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await client.updateDoc(core.class.SpaceWithStates, core.space.Model, space, {
|
||||||
|
$push: {
|
||||||
|
order: id
|
||||||
|
}
|
||||||
|
})
|
||||||
dispatch('close')
|
dispatch('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
description,
|
description,
|
||||||
private: false,
|
private: false,
|
||||||
members: [],
|
members: [],
|
||||||
states: []
|
states: [],
|
||||||
|
order: []
|
||||||
})
|
})
|
||||||
const s1 = await client.createDoc(core.class.State, id, {
|
const s1 = await client.createDoc(core.class.State, id, {
|
||||||
title: 'Initial',
|
title: 'Initial',
|
||||||
|
@ -53,11 +53,46 @@
|
|||||||
return _space.states.map(id => map.get(id) as State )
|
return _space.states.map(id => map.get(id) as State )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sortObjects<T extends Doc> (objects: T[]): T[] {
|
||||||
|
if (_space === undefined) { return [] }
|
||||||
|
const map = objects.reduce((map, doc) => { map.set(doc._id, doc); return map }, new Map<Ref<Doc>, Doc>())
|
||||||
|
const x = _space.order.map(id => map.get(id) as T)
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const statesQuery = createQuery()
|
const statesQuery = createQuery()
|
||||||
$: statesQuery.query(core.class.State, { _id: { $in: _space?.states ?? [] } }, result => { states = sort(result) })
|
$: statesQuery.query(core.class.State, { _id: { $in: _space?.states ?? [] } }, result => { states = sort(result) })
|
||||||
|
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
$: query.query(_class, { space }, result => { objects = result }, options)
|
$: query.query(_class, { space }, result => { objects = sortObjects(result) }, options)
|
||||||
|
|
||||||
|
function dragover(ev: MouseEvent, object: Doc) {
|
||||||
|
// if (dragswap(ev, i)) {
|
||||||
|
if (dragCard !== object) {
|
||||||
|
const dragover = objects.indexOf(object)
|
||||||
|
const dragging = objects.indexOf(dragCard)
|
||||||
|
console.log('dragover', dragover, dragging)
|
||||||
|
objects[dragover] = dragCard
|
||||||
|
objects[dragging] = object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function move(to: number) {
|
||||||
|
client.updateDoc(core.class.SpaceWithStates, core.space.Model, space, {
|
||||||
|
$pull: {
|
||||||
|
order: dragCard._id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
client.updateDoc(core.class.SpaceWithStates, core.space.Model, space, {
|
||||||
|
$push: {
|
||||||
|
order: {
|
||||||
|
$each: [dragCard._id],
|
||||||
|
$position: to < dragCardInitialPosition ? to : to
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function getValue(doc: Doc, key: string): any {
|
function getValue(doc: Doc, key: string): any {
|
||||||
if (key.length === 0)
|
if (key.length === 0)
|
||||||
@ -77,7 +112,8 @@
|
|||||||
showPopup(open, { object, space }, 'float')
|
showPopup(open, { object, space }, 'float')
|
||||||
}
|
}
|
||||||
|
|
||||||
let dragCard: (Doc & { state: Ref<State>}) | undefined
|
let dragCard: Doc
|
||||||
|
let dragCardInitialPosition: number
|
||||||
|
|
||||||
async function cardPresenter(_class: Ref<Class<Doc>>): Promise<AnySvelteComponent> {
|
async function cardPresenter(_class: Ref<Class<Doc>>): Promise<AnySvelteComponent> {
|
||||||
const clazz = client.getHierarchy().getClass(_class)
|
const clazz = client.getHierarchy().getClass(_class)
|
||||||
@ -97,24 +133,39 @@
|
|||||||
<KanbanPanel label={state.title} color={state.color} counter={4}
|
<KanbanPanel label={state.title} color={state.color} counter={4}
|
||||||
on:dragover={(event) => {
|
on:dragover={(event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
if (dragCard.state !== state._id) {
|
||||||
|
client.updateDoc(_class, space, dragCard._id, { state: state._id })
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
on:drop={(event) => {
|
on:drop={(event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (dragCard) {
|
// if (selected !== -1) {
|
||||||
client.updateDoc(_class, space, dragCard._id, { state: state._id })
|
// client.updateDoc(_class, space, objects[selected]._id, { state: state._id })
|
||||||
dragCard = undefined
|
// selected = -1
|
||||||
}
|
// }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<KanbanCardEmpty label={'Create new application'} />
|
<KanbanCardEmpty label={'Create new application'} />
|
||||||
{#each objects.filter((c) => c.state === state._id) as object}
|
{#each objects as object, j}
|
||||||
|
{#if object.state === state._id}
|
||||||
|
<div
|
||||||
|
on:dragover|preventDefault={(ev) => {
|
||||||
|
dragover(ev, object)
|
||||||
|
}}
|
||||||
|
on:drop|preventDefault={() => {
|
||||||
|
move(j)
|
||||||
|
}}
|
||||||
|
> {j}
|
||||||
<svelte:component this={presenter} {object} draggable={true}
|
<svelte:component this={presenter} {object} draggable={true}
|
||||||
on:dragstart={() => {
|
on:dragstart={() => {
|
||||||
dragCard = object
|
dragCardInitialPosition = j
|
||||||
|
dragCard = objects[j]
|
||||||
}}
|
}}
|
||||||
on:dragend={() => {
|
on:dragend={() => {
|
||||||
dragCard = undefined
|
dragCard = undefined
|
||||||
}}/>
|
}}/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</KanbanPanel>
|
</KanbanPanel>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -129,7 +129,6 @@
|
|||||||
dragover(ev, i)
|
dragover(ev, i)
|
||||||
}}
|
}}
|
||||||
on:drop|preventDefault={() => {
|
on:drop|preventDefault={() => {
|
||||||
console.log('DROP')
|
|
||||||
move(i)
|
move(i)
|
||||||
}}
|
}}
|
||||||
on:dragstart={() => {
|
on:dragstart={() => {
|
||||||
@ -137,7 +136,6 @@
|
|||||||
dragState = states[i]._id
|
dragState = states[i]._id
|
||||||
}}
|
}}
|
||||||
on:dragend={() => {
|
on:dragend={() => {
|
||||||
console.log('DRAGEND')
|
|
||||||
selected = undefined
|
selected = undefined
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user