mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-15 12:55:59 +00:00
Merge pull request #1444 from hcengineering/ano/update-date-presenter
Board: Update Date Presenter to reuse as presenter
This commit is contained in:
commit
582fb4dad0
@ -44,10 +44,11 @@
|
||||
let handleMove: () => void
|
||||
|
||||
$: cardQuery.query(_class, { _id }, async (result) => {
|
||||
object = result[0]
|
||||
})
|
||||
object = result[0]
|
||||
})
|
||||
|
||||
$: object?.state && stateQuery.query(task.class.State, { _id: object.state }, async (result) => {
|
||||
$: object?.state &&
|
||||
stateQuery.query(task.class.State, { _id: object.state }, async (result) => {
|
||||
state = result[0]
|
||||
})
|
||||
|
||||
@ -62,7 +63,7 @@
|
||||
}
|
||||
})
|
||||
|
||||
function change(field: string, value: any) {
|
||||
function change (field: string, value: any) {
|
||||
if (object) {
|
||||
updateCard(client, object, field, value)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
}
|
||||
|
||||
function canDropAttachment (e: DragEvent): boolean {
|
||||
return !!e.dataTransfer?.items && e.dataTransfer?.items.length > 0;
|
||||
return !!e.dataTransfer?.items && e.dataTransfer?.items.length > 0
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -1,67 +1,68 @@
|
||||
<script lang="ts">
|
||||
import { ActionIcon, Button, EditBox, IconAdd, IconClose } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import board from '../plugin'
|
||||
import { ActionIcon, Button, EditBox, IconAdd, IconClose } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import board from '../plugin'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let isAdding = false
|
||||
let newPanelTitle = ''
|
||||
let isAdding = false
|
||||
let newPanelTitle = ''
|
||||
|
||||
async function onAdd () {
|
||||
if (!newPanelTitle) return
|
||||
dispatch('add', newPanelTitle)
|
||||
newPanelTitle = ''
|
||||
isAdding = false
|
||||
}
|
||||
async function onAdd () {
|
||||
if (!newPanelTitle) return
|
||||
dispatch('add', newPanelTitle)
|
||||
newPanelTitle = ''
|
||||
isAdding = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="panel-container step-lr75">
|
||||
{#if isAdding}
|
||||
<EditBox
|
||||
bind:value={newPanelTitle}
|
||||
maxWidth={'19rem'}
|
||||
placeholder={board.string.NewListPlaceholder}
|
||||
focus={true}
|
||||
/>
|
||||
<div class="list-add-controls">
|
||||
<Button
|
||||
icon={IconAdd}
|
||||
label={board.string.AddList}
|
||||
justify={'left'}
|
||||
on:click={() => { onAdd() }}
|
||||
/>
|
||||
<ActionIcon
|
||||
icon={IconClose}
|
||||
size={'large'}
|
||||
action={() => { isAdding = false }}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<Button
|
||||
<div class="panel-container step-lr75">
|
||||
{#if isAdding}
|
||||
<EditBox bind:value={newPanelTitle} maxWidth={'19rem'} placeholder={board.string.NewListPlaceholder} focus={true} />
|
||||
<div class="list-add-controls">
|
||||
<Button
|
||||
icon={IconAdd}
|
||||
label={board.string.NewList}
|
||||
label={board.string.AddList}
|
||||
justify={'left'}
|
||||
on:click={() => { isAdding = true }}
|
||||
/>
|
||||
{/if}
|
||||
on:click={() => {
|
||||
onAdd()
|
||||
}}
|
||||
/>
|
||||
<ActionIcon
|
||||
icon={IconClose}
|
||||
size={'large'}
|
||||
action={() => {
|
||||
isAdding = false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<Button
|
||||
icon={IconAdd}
|
||||
label={board.string.NewList}
|
||||
justify={'left'}
|
||||
on:click={() => {
|
||||
isAdding = true
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.panel-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
width: 20rem;
|
||||
height: fit-content;
|
||||
background-color: transparent;
|
||||
border: .125rem solid transparent;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
.list-add-controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin: 0.5rem 0 0 0;
|
||||
}
|
||||
.panel-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
width: 20rem;
|
||||
height: fit-content;
|
||||
background-color: transparent;
|
||||
border: 0.125rem solid transparent;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
.list-add-controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin: 0.5rem 0 0 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -23,7 +23,7 @@
|
||||
import KanbanCard from './KanbanCard.svelte'
|
||||
import KanbanPanelEmpty from './KanbanPanelEmpty.svelte'
|
||||
import AddCard from './add-card/AddCard.svelte'
|
||||
|
||||
|
||||
export let _class: Ref<Class<Card>>
|
||||
export let space: Ref<SpaceWithStates>
|
||||
export let search: string
|
||||
@ -59,11 +59,7 @@
|
||||
const client = getClient()
|
||||
|
||||
async function addItem (title: any) {
|
||||
const lastOne = await client.findOne(
|
||||
task.class.State,
|
||||
{ space },
|
||||
{ sort: { rank: SortingOrder.Descending } }
|
||||
)
|
||||
const lastOne = await client.findOne(task.class.State, { space }, { sort: { rank: SortingOrder.Descending } })
|
||||
await client.createDoc(task.class.State, space, {
|
||||
title,
|
||||
color: 9,
|
||||
@ -73,17 +69,29 @@
|
||||
/* eslint-disable no-undef */
|
||||
</script>
|
||||
|
||||
<KanbanUI {_class} {space} {search} {options} query={{ doneState: null }} states={states}
|
||||
fieldName={'state'} rankFieldName={'rank'}>
|
||||
<svelte:fragment slot='card' let:object let:dragged>
|
||||
<KanbanUI
|
||||
{_class}
|
||||
{space}
|
||||
{search}
|
||||
{options}
|
||||
query={{ doneState: null }}
|
||||
{states}
|
||||
fieldName={'state'}
|
||||
rankFieldName={'rank'}
|
||||
>
|
||||
<svelte:fragment slot="card" let:object let:dragged>
|
||||
<KanbanCard object={castObject(object)} {dragged} />
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot='additionalPanel'>
|
||||
<KanbanPanelEmpty on:add={(e) => { addItem(e.detail) }} />
|
||||
<svelte:fragment slot="additionalPanel">
|
||||
<KanbanPanelEmpty
|
||||
on:add={(e) => {
|
||||
addItem(e.detail)
|
||||
}}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="afterCard" let:space={targetSpace} let:state={targetState}>
|
||||
<AddCard space={targetSpace} state={targetState}/>
|
||||
<AddCard space={targetSpace} state={targetState} />
|
||||
</svelte:fragment>
|
||||
</KanbanUI>
|
||||
|
@ -28,7 +28,7 @@
|
||||
let anchorRef: HTMLDivElement
|
||||
const client = getClient()
|
||||
|
||||
async function addCard(title: string) {
|
||||
async function addCard (title: string) {
|
||||
const newCardId = generateId() as Ref<BoardCard>
|
||||
|
||||
const sequence = await client.findOne(task.class.Sequence, { attachedTo: board.class.Card })
|
||||
@ -58,7 +58,7 @@
|
||||
return client.addCollection(board.class.Card, space, space, board.class.Board, 'cards', value, newCardId)
|
||||
}
|
||||
|
||||
async function addCards(title: string, checkNewLine: boolean = false) {
|
||||
async function addCards (title: string, checkNewLine: boolean = false) {
|
||||
if (!checkNewLine) {
|
||||
return addCard(title.replace('\n', ' '))
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script lang='ts'>
|
||||
<script lang="ts">
|
||||
import { Button, TextArea, ActionIcon, IconClose } from '@anticrm/ui'
|
||||
import board from '../../plugin'
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
let inputRef: TextArea
|
||||
let openedContainerRef: HTMLDivElement
|
||||
|
||||
async function addCard() {
|
||||
async function addCard () {
|
||||
if (!title) {
|
||||
inputRef.focus()
|
||||
return
|
||||
@ -21,7 +21,7 @@
|
||||
title = ''
|
||||
}
|
||||
|
||||
async function onClickOutside(e: any) {
|
||||
async function onClickOutside (e: any) {
|
||||
if (openedContainerRef && !openedContainerRef.contains(e.target) && !e.defaultPrevented && isEditing) {
|
||||
if (title) {
|
||||
await onAdd(title)
|
||||
@ -33,12 +33,12 @@
|
||||
|
||||
const onKeydown = (e: any) => {
|
||||
if (e.detail.key !== 'Enter') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
e.detail.preventDefault()
|
||||
addCard()
|
||||
};
|
||||
}
|
||||
|
||||
$: if (inputRef && !title) {
|
||||
isEditing = true
|
||||
@ -46,23 +46,23 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:click={onClickOutside}/>
|
||||
<svelte:window on:click={onClickOutside} />
|
||||
<div bind:this={openedContainerRef}>
|
||||
<div class="card-container">
|
||||
<div class="card-container">
|
||||
<TextArea
|
||||
placeholder={board.string.CardTitlePlaceholder}
|
||||
bind:this={inputRef}
|
||||
bind:value={title}
|
||||
on:keydown={onKeydown}
|
||||
noFocusBorder={true}
|
||||
placeholder={board.string.CardTitlePlaceholder}
|
||||
bind:this={inputRef}
|
||||
bind:value={title}
|
||||
on:keydown={onKeydown}
|
||||
noFocusBorder={true}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex-row-center mt-3">
|
||||
</div>
|
||||
<div class="flex-row-center mt-3">
|
||||
<Button label={board.string.AddCard} kind="no-border" on:click={addCard} />
|
||||
<div class="ml-2" on:click={onClose}>
|
||||
<ActionIcon icon={IconClose} size={'large'} action={onClose} />
|
||||
</div>
|
||||
<ActionIcon icon={IconClose} size={'large'} action={onClose} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@ -75,4 +75,4 @@
|
||||
border-radius: 0.25rem;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -41,12 +41,12 @@
|
||||
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: .75rem;
|
||||
right: .75rem;
|
||||
top: 0.75rem;
|
||||
right: 0.75rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding-bottom: .5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
</style>
|
||||
|
@ -28,12 +28,11 @@
|
||||
|
||||
let inputFile: HTMLInputElement
|
||||
|
||||
async function fetch() {
|
||||
async function fetch () {
|
||||
attachments = await client.findAll(attachment.class.Attachment, { space: value.space, attachedTo: value._id })
|
||||
}
|
||||
|
||||
$: value?.attachments && value.attachments > 0 && fetch()
|
||||
|
||||
</script>
|
||||
|
||||
{#if value !== undefined && value.attachments !== undefined && value.attachments > 0}
|
||||
@ -55,7 +54,7 @@
|
||||
<div class="mt-2">
|
||||
<AddAttachment bind:inputFile objectClass={value._class} objectId={value._id} space={value.space}>
|
||||
<svelte:fragment slot="control" let:click>
|
||||
<Button label={board.string.AddAttachment} kind="no-border" on:click={click}/>
|
||||
<Button label={board.string.AddAttachment} kind="no-border" on:click={click} />
|
||||
</svelte:fragment>
|
||||
</AddAttachment>
|
||||
</div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Card, CardLabel } from '@anticrm/board'
|
||||
import type { Card, CardDate, CardLabel } from '@anticrm/board'
|
||||
|
||||
import contact, { Employee } from '@anticrm/contact'
|
||||
import { getResource } from '@anticrm/platform'
|
||||
@ -71,6 +71,10 @@
|
||||
labels = []
|
||||
}
|
||||
|
||||
function updateDate (e: CustomEvent<CardDate>) {
|
||||
client.update(value, { date: e.detail })
|
||||
}
|
||||
|
||||
getCardActions(client, {
|
||||
_id: { $in: [board.cardAction.Dates, board.cardAction.Labels, board.cardAction.Members] }
|
||||
}).then(async (result) => {
|
||||
@ -87,7 +91,6 @@
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
@ -123,7 +126,7 @@
|
||||
<Label label={board.string.Dates} />
|
||||
</div>
|
||||
{#key value.date}
|
||||
<DatePresenter {value} on:click={dateHandler} />
|
||||
<DatePresenter value={value.date} on:click={dateHandler} on:update={updateDate} />
|
||||
{/key}
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -17,7 +17,7 @@
|
||||
let filteredLabels: CardLabel[] = []
|
||||
let hovered: Ref<CardLabel> | undefined = undefined
|
||||
|
||||
function applySearch() {
|
||||
function applySearch () {
|
||||
if (!search || search.trim().length <= 0) {
|
||||
filteredLabels = boardCardLabels
|
||||
return
|
||||
@ -27,14 +27,14 @@
|
||||
filteredLabels = boardCardLabels.filter((l) => l.title?.toUpperCase().includes(text) ?? false)
|
||||
}
|
||||
|
||||
async function fetchBoardLabels() {
|
||||
async function fetchBoardLabels () {
|
||||
if (object.space) {
|
||||
boardCardLabels = await getBoardLabels(client, object.space)
|
||||
applySearch()
|
||||
}
|
||||
}
|
||||
|
||||
function toggle(label: CardLabel) {
|
||||
function toggle (label: CardLabel) {
|
||||
if (!object) {
|
||||
return
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { Card, CardDate } from '@anticrm/board'
|
||||
import calendar from '@anticrm/calendar'
|
||||
import board from '../../plugin'
|
||||
import { getClient } from '@anticrm/presentation';
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
|
||||
export let object: Card
|
||||
|
||||
@ -24,36 +24,46 @@
|
||||
const date: CardDate = {}
|
||||
if (startDate !== undefined) date.startDate = startDate
|
||||
if (dueDate !== undefined) date.dueDate = dueDate
|
||||
client.update(object, {date})
|
||||
client.update(object, { date })
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiPopup antiPopup-withHeader antiPopup-withTitle antiPopup-withCategory w-85">
|
||||
<div class="ap-space"/>
|
||||
<div class="ap-space" />
|
||||
<div class="fs-title ap-header flex-row-center">
|
||||
<Label label={board.string.Dates}/>
|
||||
<Label label={board.string.Dates} />
|
||||
</div>
|
||||
<div class="ap-space bottom-divider"/>
|
||||
<div class="ap-category">
|
||||
<div class="categoryItem flex-center whitespace-nowrap">
|
||||
<Label label={board.string.StartDate}/>
|
||||
</div>
|
||||
<div class="ap-space bottom-divider" />
|
||||
<div class="ap-category">
|
||||
<div class="categoryItem flex-center whitespace-nowrap">
|
||||
<Label label={board.string.StartDate} />
|
||||
</div>
|
||||
<div class="categoryItem p-2 flex-center">
|
||||
<CheckBox bind:checked={startDateEnabled} on:value={() => {startDate = startDateEnabled ? savedStartDate : undefined}}/>
|
||||
<CheckBox
|
||||
bind:checked={startDateEnabled}
|
||||
on:value={() => {
|
||||
startDate = startDateEnabled ? savedStartDate : undefined
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="categoryItem w-full p-2">
|
||||
<DateRangePresenter bind:value={startDate} editable={startDateEnabled} labelNull={board.string.NullDate}/>
|
||||
<DateRangePresenter bind:value={startDate} editable={startDateEnabled} labelNull={board.string.NullDate} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ap-category">
|
||||
<div class="categoryItem flex-center whitespace-nowrap">
|
||||
<Label label={board.string.DueDate}/>
|
||||
<Label label={board.string.DueDate} />
|
||||
</div>
|
||||
<div class="categoryItem p-2 flex-center">
|
||||
<CheckBox bind:checked={dueDateEnabled} on:value={() => {dueDate = dueDateEnabled ? savedDueDate : undefined}}/>
|
||||
<CheckBox
|
||||
bind:checked={dueDateEnabled}
|
||||
on:value={() => {
|
||||
dueDate = dueDateEnabled ? savedDueDate : undefined
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="categoryItem w-full p-2">
|
||||
<DateRangePresenter bind:value={dueDate} editable={dueDateEnabled} labelNull={board.string.NullDate}/>
|
||||
<DateRangePresenter bind:value={dueDate} editable={dueDateEnabled} labelNull={board.string.NullDate} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ap-footer">
|
||||
@ -68,7 +78,7 @@
|
||||
label={board.string.Remove}
|
||||
size={'small'}
|
||||
on:click={() => {
|
||||
client.update(object, {date: {}})
|
||||
client.update(object, { date: {} })
|
||||
dispatch('close')
|
||||
}}
|
||||
/>
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { Class, Client, Doc, DocumentUpdate, Ref } from '@anticrm/core'
|
||||
import { getResource, OK, Resource, Status } from '@anticrm/platform'
|
||||
import { Card } from '@anticrm/board';
|
||||
import { Card } from '@anticrm/board'
|
||||
import view from '@anticrm/view'
|
||||
import board from '../../plugin'
|
||||
import SpaceSelect from '../selectors/SpaceSelect.svelte'
|
||||
@ -51,15 +51,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: validate({...object, ...selected}, object._class)
|
||||
$: validate({ ...object, ...selected }, object._class)
|
||||
</script>
|
||||
|
||||
<div class="antiPopup antiPopup-withHeader antiPopup-withTitle antiPopup-withCategory w-85">
|
||||
<div class="ap-space"/>
|
||||
<div class="ap-space" />
|
||||
<div class="fs-title ap-header flex-row-center">
|
||||
<Label label={board.string.MoveCard}/>
|
||||
<Label label={board.string.MoveCard} />
|
||||
</div>
|
||||
<div class="ap-space bottom-divider"/>
|
||||
<div class="ap-space bottom-divider" />
|
||||
<StatusControl {status} />
|
||||
<div class="ap-title">
|
||||
<Label label={board.string.SelectDestination} />
|
||||
@ -92,7 +92,7 @@
|
||||
<Button
|
||||
label={board.string.Move}
|
||||
size={'small'}
|
||||
disabled={status !== OK || object.state === selected.state && object.rank === selected.rank}
|
||||
disabled={status !== OK || (object.state === selected.state && object.rank === selected.rank)}
|
||||
kind={'primary'}
|
||||
on:click={move}
|
||||
/>
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
export let value: Attachment
|
||||
// TODO: implement
|
||||
|
||||
</script>
|
||||
|
||||
<div>
|
||||
|
@ -1,31 +1,31 @@
|
||||
<script lang="ts">
|
||||
import type { Card } from '@anticrm/board'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import type { CardDate } from '@anticrm/board'
|
||||
import { CheckBox, DatePresenter } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let value: Card
|
||||
export let value: CardDate
|
||||
export let isInline: boolean = false
|
||||
|
||||
const client = getClient()
|
||||
const {date} = value
|
||||
let isChecked = date?.isChecked
|
||||
let isChecked = value?.isChecked
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function update(){
|
||||
if (isChecked === undefined) return
|
||||
client.update(value, {date: {...date, isChecked}})
|
||||
function check () {
|
||||
if (isInline || isChecked === undefined) return
|
||||
dispatch('update', { ...value, isChecked })
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if date}
|
||||
{#if value}
|
||||
<div class="flex-presenter flex-gap-1 h-full">
|
||||
<CheckBox bind:checked={isChecked} on:value={update}/>
|
||||
<CheckBox bind:checked={isChecked} on:value={check} />
|
||||
<div class="flex-center h-full" on:click>
|
||||
<div class="flex-row-center background-button-bg-color border-radius-1 w-full">
|
||||
{#if date.startDate}
|
||||
<DatePresenter bind:value={date.startDate} />
|
||||
{#if value.startDate}
|
||||
<DatePresenter bind:value={value.startDate} />
|
||||
{/if}
|
||||
{#if date.startDate && date.dueDate}-{/if}
|
||||
{#if date.dueDate}
|
||||
<DatePresenter bind:value={date.dueDate} withTime={true} showIcon={false} />
|
||||
{#if value.startDate && value.dueDate}-{/if}
|
||||
{#if value.dueDate}
|
||||
<DatePresenter bind:value={value.dueDate} withTime={true} showIcon={false} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,41 +1,43 @@
|
||||
<script lang="ts">
|
||||
import { IntlString, translate } from '@anticrm/platform'
|
||||
import { createQuery } from '@anticrm/presentation';
|
||||
import { DropdownLabels } from '@anticrm/ui'
|
||||
import { Ref, SortingOrder } from '@anticrm/core'
|
||||
import { DropdownTextItem } from '@anticrm/ui/src/types';
|
||||
import { calcRank, State } from '@anticrm/task';
|
||||
import { Card } from '@anticrm/board'
|
||||
import board from '../../plugin'
|
||||
import { IntlString, translate } from '@anticrm/platform'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { DropdownLabels } from '@anticrm/ui'
|
||||
import { Ref, SortingOrder } from '@anticrm/core'
|
||||
import { DropdownTextItem } from '@anticrm/ui/src/types'
|
||||
import { calcRank, State } from '@anticrm/task'
|
||||
import { Card } from '@anticrm/board'
|
||||
import board from '../../plugin'
|
||||
|
||||
export let object: Card
|
||||
export let label: IntlString
|
||||
export let state: Ref<State>
|
||||
export let selected: string
|
||||
export let object: Card
|
||||
export let label: IntlString
|
||||
export let state: Ref<State>
|
||||
export let selected: string
|
||||
|
||||
let ranks: DropdownTextItem[] = []
|
||||
const tasksQuery = createQuery()
|
||||
tasksQuery.query(
|
||||
board.class.Card, { state },
|
||||
async result => {
|
||||
[ranks] = [...result.filter(t => t._id !== object._id), undefined]
|
||||
.reduce<[DropdownTextItem[], Card | undefined]>(
|
||||
([arr, prev], next) => [[...arr, {id: calcRank(prev, next), label:`${arr.length+1}`}], next],
|
||||
[[], undefined]
|
||||
);
|
||||
[{ id: selected = object.rank }] = ranks.slice(-1)
|
||||
let ranks: DropdownTextItem[] = []
|
||||
const tasksQuery = createQuery()
|
||||
tasksQuery.query(
|
||||
board.class.Card,
|
||||
{ state },
|
||||
async (result) => {
|
||||
;[ranks] = [...result.filter((t) => t._id !== object._id), undefined].reduce<
|
||||
[DropdownTextItem[], Card | undefined]
|
||||
>(
|
||||
([arr, prev], next) => [[...arr, { id: calcRank(prev, next), label: `${arr.length + 1}` }], next],
|
||||
[[], undefined]
|
||||
)
|
||||
;[{ id: selected = object.rank }] = ranks.slice(-1)
|
||||
|
||||
if (object.state === state){
|
||||
const index = result.findIndex(t => t._id === object._id)
|
||||
ranks[index] = {
|
||||
id: object.rank,
|
||||
label: await translate(board.string.Current, {label: ranks[index].label})
|
||||
}
|
||||
selected = object.rank
|
||||
}
|
||||
},
|
||||
{ sort: { rank: SortingOrder.Ascending } }
|
||||
)
|
||||
if (object.state === state) {
|
||||
const index = result.findIndex((t) => t._id === object._id)
|
||||
ranks[index] = {
|
||||
id: object.rank,
|
||||
label: await translate(board.string.Current, { label: ranks[index].label })
|
||||
}
|
||||
selected = object.rank
|
||||
}
|
||||
},
|
||||
{ sort: { rank: SortingOrder.Ascending } }
|
||||
)
|
||||
</script>
|
||||
|
||||
<DropdownLabels items={ranks} label={label} bind:selected={selected}/>
|
||||
<DropdownLabels items={ranks} {label} bind:selected />
|
||||
|
@ -1,26 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { IntlString, translate } from '@anticrm/platform'
|
||||
import { createQuery } from '@anticrm/presentation';
|
||||
import { DropdownLabels } from '@anticrm/ui'
|
||||
import { Ref } from '@anticrm/core'
|
||||
import { DropdownTextItem } from '@anticrm/ui/src/types';
|
||||
import { Board, Card } from '@anticrm/board'
|
||||
import board from '../../plugin'
|
||||
import { IntlString, translate } from '@anticrm/platform'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { DropdownLabels } from '@anticrm/ui'
|
||||
import { Ref } from '@anticrm/core'
|
||||
import { DropdownTextItem } from '@anticrm/ui/src/types'
|
||||
import { Board, Card } from '@anticrm/board'
|
||||
import board from '../../plugin'
|
||||
|
||||
export let object: Card
|
||||
export let label: IntlString
|
||||
export let selected: Ref<Board>
|
||||
export let object: Card
|
||||
export let label: IntlString
|
||||
export let selected: Ref<Board>
|
||||
|
||||
let spaces: DropdownTextItem[] = []
|
||||
const spacesQuery = createQuery()
|
||||
spacesQuery.query(
|
||||
board.class.Board, {},
|
||||
async result => {
|
||||
spaces = result.map(({_id, name}) => ({id: _id, label: name}))
|
||||
const index = spaces.findIndex(({id}) => id === object.space)
|
||||
spaces[index].label = await translate(board.string.Current, {label: spaces[index].label})
|
||||
}
|
||||
)
|
||||
let spaces: DropdownTextItem[] = []
|
||||
const spacesQuery = createQuery()
|
||||
spacesQuery.query(board.class.Board, {}, async (result) => {
|
||||
spaces = result.map(({ _id, name }) => ({ id: _id, label: name }))
|
||||
const index = spaces.findIndex(({ id }) => id === object.space)
|
||||
spaces[index].label = await translate(board.string.Current, { label: spaces[index].label })
|
||||
})
|
||||
</script>
|
||||
|
||||
<DropdownLabels items={spaces} label={label} bind:selected/>
|
||||
<DropdownLabels items={spaces} {label} bind:selected />
|
||||
|
@ -1,34 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { IntlString, translate } from '@anticrm/platform'
|
||||
import { createQuery } from '@anticrm/presentation';
|
||||
import { DropdownLabels } from '@anticrm/ui'
|
||||
import { Ref, SortingOrder, Space } from '@anticrm/core'
|
||||
import { DropdownTextItem } from '@anticrm/ui/src/types';
|
||||
import task, { State } from '@anticrm/task';
|
||||
import { Card } from '@anticrm/board'
|
||||
import board from '../../plugin'
|
||||
import { IntlString, translate } from '@anticrm/platform'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { DropdownLabels } from '@anticrm/ui'
|
||||
import { Ref, SortingOrder, Space } from '@anticrm/core'
|
||||
import { DropdownTextItem } from '@anticrm/ui/src/types'
|
||||
import task, { State } from '@anticrm/task'
|
||||
import { Card } from '@anticrm/board'
|
||||
import board from '../../plugin'
|
||||
|
||||
export let object: Card
|
||||
export let label: IntlString
|
||||
export let selected: Ref<State>
|
||||
export let space: Ref<Space>
|
||||
export let object: Card
|
||||
export let label: IntlString
|
||||
export let selected: Ref<State>
|
||||
export let space: Ref<Space>
|
||||
|
||||
let states: DropdownTextItem[] = []
|
||||
const statesQuery = createQuery()
|
||||
statesQuery.query(
|
||||
task.class.State, { space },
|
||||
async result => {
|
||||
if(!result) return
|
||||
states = result.map(({_id, title }) => ({id: _id, label: title}));
|
||||
[{ _id: selected }] = result
|
||||
if (object.space === space) {
|
||||
const index = states.findIndex(({id}) => id === object.state)
|
||||
states[index].label = await translate(board.string.Current, {label: states[index].label})
|
||||
selected = object.state
|
||||
}
|
||||
},
|
||||
{ sort: { rank: SortingOrder.Ascending } }
|
||||
)
|
||||
let states: DropdownTextItem[] = []
|
||||
const statesQuery = createQuery()
|
||||
statesQuery.query(
|
||||
task.class.State,
|
||||
{ space },
|
||||
async (result) => {
|
||||
if (!result) return
|
||||
states = result.map(({ _id, title }) => ({ id: _id, label: title }))
|
||||
;[{ _id: selected }] = result
|
||||
if (object.space === space) {
|
||||
const index = states.findIndex(({ id }) => id === object.state)
|
||||
states[index].label = await translate(board.string.Current, { label: states[index].label })
|
||||
selected = object.state
|
||||
}
|
||||
},
|
||||
{ sort: { rank: SortingOrder.Ascending } }
|
||||
)
|
||||
</script>
|
||||
|
||||
<DropdownLabels items={states} label={label} bind:selected/>
|
||||
<DropdownLabels items={states} {label} bind:selected />
|
||||
|
@ -36,7 +36,12 @@ export async function createBoardLabels (client: TxOperations, boardRef: Ref<Boa
|
||||
])
|
||||
}
|
||||
|
||||
export async function createCardLabel (client: TxOperations, boardRef: Ref<Board>, color: string, title?: string): Promise<void> {
|
||||
export async function createCardLabel (
|
||||
client: TxOperations,
|
||||
boardRef: Ref<Board>,
|
||||
color: string,
|
||||
title?: string
|
||||
): Promise<void> {
|
||||
await client.createDoc(board.class.CardLabel, core.space.Model, {
|
||||
attachedTo: boardRef,
|
||||
attachedToClass: board.class.Board,
|
||||
|
Loading…
Reference in New Issue
Block a user