Add AddMultipleCardsPopup (#1374)

Signed-off-by: Sergey Semenov <lvfx@ya.ru>
This commit is contained in:
Sergey Semenov 2022-04-12 15:19:53 +07:00 committed by GitHub
parent fa2e1b3229
commit 13750963c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 126 additions and 12 deletions

View File

@ -21,6 +21,7 @@
import { onMount } from 'svelte'
export let label: IntlString | undefined = undefined
export let labelParams: Record<string, any> = {}
export let kind: 'primary' | 'secondary' | 'no-border' | 'transparent' | 'link' | 'dangerous' = 'secondary'
export let size: 'small' | 'medium' | 'large' | 'x-large' = 'medium'
export let icon: Asset | AnySvelteComponent | undefined = undefined
@ -67,7 +68,7 @@
<Spinner />
{:else}
{#if label}
<Label {label} />
<Label {label} params={labelParams}/>
{:else if $$slots.content}
<slot name="content" />
{/if}

View File

@ -53,6 +53,10 @@
"NewListPlaceholder": "Enter list title...",
"AddACard": "Add a card",
"AddCard": "Add card",
"CardTitlePlaceholder": "Enter a title for this card..."
"CardTitlePlaceholder": "Enter a title for this card...",
"Create": "Create",
"CreateDescription": "If you want, we can create a card for every new line ({number}). You can also create one card with a long title.",
"CreateSingle": "Just one card",
"CreateMultiple": "Create {number} cards"
}
}

View File

@ -53,6 +53,10 @@
"NewListPlaceholder": "Введите заголовок колонки...",
"AddACard": "Добавить карточку",
"AddCard": "Добавить карточку",
"CardTitlePlaceholder": "Введите заголовок для этой карточки..."
"CardTitlePlaceholder": "Введите заголовок для этой карточки...",
"Create": "Создать",
"CreateDescription": "Можно создать отдельные карточки для каждой строки ({number}) или одну с длинным названием.",
"CreateSingle": "Создать одну",
"CreateMultiple": "Создать несколько ({number})"
}
}

View File

@ -17,17 +17,20 @@
import board from '../../plugin'
import task, { calcRank } from '@anticrm/task'
import { AttachedData, generateId, Ref, SortingOrder, Space } from '@anticrm/core'
import { IconAdd, Button } from '@anticrm/ui'
import { IconAdd, Button, showPopup, AnySvelteComponent } from '@anticrm/ui'
import { getClient } from '@anticrm/presentation'
import AddCardEditor from './AddCardEditor.svelte'
import AddMultipleCardsPopup from './AddMultipleCardsPopup.svelte'
export let space: Ref<Space>
export let state: any
let anchorRef: HTMLDivElement
const client = getClient()
let newCardId = generateId() as Ref<BoardCard>
async function addCard(title: string) {
const newCardId = generateId() as Ref<BoardCard>
const sequence = await client.findOne(task.class.Sequence, { attachedTo: board.class.Card })
if (sequence === undefined) {
throw new Error('sequence object not found')
@ -52,9 +55,51 @@
location: ''
}
await client.addCollection(board.class.Card, space, space, board.class.Board, 'cards', value, newCardId)
return client.addCollection(board.class.Card, space, space, board.class.Board, 'cards', value, newCardId)
}
newCardId = generateId() as Ref<BoardCard>
async function addCards(title: string, checkNewLine: boolean = false) {
if (!checkNewLine) {
return addCard(title.replace('\n', ' '))
}
const splittedTitle = title.split('\n')
if (splittedTitle.length === 1) {
return addCard(splittedTitle[0])
}
return new Promise<'single' | 'multiple' | 'close'>((resolve) => {
const popupOpts = {
onAddSingle: () => {
closePopup()
resolve('single')
},
onAddMultiple: () => {
closePopup()
resolve('multiple')
},
onClose: () => {
closePopup()
resolve('close')
},
cardsNumber: splittedTitle.length
}
const closePopup = showPopup(AddMultipleCardsPopup, popupOpts, anchorRef, () => resolve('close'))
}).then((value) => {
if (value === 'single' || value === 'close') {
return addCard(title.replace('\n', ' ')).then((res) => {
if (value === 'close') {
onClose()
}
return [res]
})
}
return Promise.all(splittedTitle.map((titlePart) => addCard(titlePart)))
})
}
let isOpened = false
@ -70,8 +115,9 @@
</script>
<div class="flex-col step-tb75">
<div bind:this={anchorRef} style:position="absolute" />
{#if isOpened}
<AddCardEditor {onClose} onAdd={addCard} />
<AddCardEditor {onClose} onAdd={addCards} />
{:else}
<Button
icon={IconAdd}

View File

@ -3,8 +3,9 @@
import board from '../../plugin'
export let onClose: () => void
export let onAdd: (title: string) => Promise<void>
export let onAdd: (title: string, checkNewLine?: boolean) => Promise<any>
let isEditing = false
let title = ''
let inputRef: TextArea
let openedContainerRef: HTMLDivElement
@ -15,12 +16,13 @@
return
}
await onAdd(title)
isEditing = false
await onAdd(title, true)
title = ''
}
async function onClickOutside(e: any) {
if (openedContainerRef && !openedContainerRef.contains(e.target) && !e.defaultPrevented) {
if (openedContainerRef && !openedContainerRef.contains(e.target) && !e.defaultPrevented && isEditing) {
if (title) {
await onAdd(title)
}
@ -39,6 +41,7 @@
};
$: if (inputRef && !title) {
isEditing = true
inputRef.focus()
}
</script>

View File

@ -0,0 +1,52 @@
<script lang="ts">
import board from '../../plugin'
import { Button, ActionIcon, IconClose, Label } from '@anticrm/ui'
export let cardsNumber: number
export let onAddSingle: () => void
export let onAddMultiple: () => void
export let onClose: () => void
</script>
<div class="antiPopup container p-3">
<div class="flex-row-center header">
<div class="flex-center flex-grow">
<Label label={board.string.Create} />
</div>
<div class="close-icon">
<ActionIcon icon={IconClose} size={'small'} action={onClose} />
</div>
</div>
<div class="mt-2">
<Label label={board.string.CreateDescription} params={{ number: cardsNumber }} />
</div>
<div class="mt-4">
<Button
label={board.string.CreateMultiple}
labelParams={{ number: cardsNumber }}
kind="no-border"
width={'100%'}
on:click={onAddMultiple}
/>
</div>
<div class="mt-2">
<Button label={board.string.CreateSingle} kind="no-border" width={'100%'} on:click={onAddSingle} />
</div>
</div>
<style lang="scss">
.container {
max-width: 20rem;
}
.close-icon {
position: absolute;
top: .75rem;
right: .75rem;
}
.header {
padding-bottom: .5rem;
border-bottom: 1px solid var(--divider-color);
}
</style>

View File

@ -74,7 +74,11 @@ export default mergeIds(boardId, board, {
NewListPlaceholder: '' as IntlString,
AddACard: '' as IntlString,
AddCard: '' as IntlString,
CardTitlePlaceholder: '' as IntlString
CardTitlePlaceholder: '' as IntlString,
Create: '' as IntlString,
CreateDescription: '' as IntlString,
CreateSingle: '' as IntlString,
CreateMultiple: '' as IntlString
},
component: {
CreateCustomer: '' as AnyComponent,