Add CardCover (#1652)

Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com>
This commit is contained in:
Alex 2022-05-06 13:43:44 +07:00 committed by GitHub
parent 472ee0537b
commit 612f36c079
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 131 additions and 7 deletions

View File

@ -97,6 +97,8 @@
"NoResults": "No results",
"SwitchToLists": "Switch to lists",
"SwitchToCards": "Switch to cards",
"SearchArchive": "Search archive..."
"SearchArchive": "Search archive...",
"Size": "Size",
"RemoveCover": "Remove cover"
}
}

View File

@ -97,6 +97,8 @@
"NoResults": "Нет результатов",
"SwitchToLists": "К спискам",
"SwitchToCards": "К карточкам",
"SearchArchive": "Поиск в архиве..."
"SearchArchive": "Поиск в архиве...",
"Size": "Размер",
"RemoveCover": "Удалить обложку"
}
}

View File

@ -0,0 +1,104 @@
<script lang="ts">
import { Card, CardCover } from '@anticrm/board'
import { getClient } from '@anticrm/presentation'
import { Button, hexColorToNumber, Icon, Label, IconCheck, IconClose } from '@anticrm/ui'
import { createEventDispatcher } from 'svelte'
import board from '../../plugin'
import { getBoardAvailableColors } from '../../utils/BoardUtils'
import ColorPresenter from '../presenters/ColorPresenter.svelte'
export let object: Card
let cover = object.cover
const dispatch = createEventDispatcher()
const client = getClient()
const colorGroups = (function chunk (colors: number[]): number[][] {
return colors.length ? [colors.slice(0, 5), ...chunk(colors.slice(5))] : []
})(getBoardAvailableColors().map(hexColorToNumber))
function updateCover (newCover?: Partial<CardCover>) {
cover = newCover ? { size: 'small', ...cover, ...newCover } : null
client.update(object, { cover })
}
</script>
<div class="antiPopup w-85">
<div class="ap-space" />
<div class="flex-center flex-grow fs-title mt-1 mb-1">
<Label label={board.string.Cover} />
</div>
<div class="absolute mr-1 mt-1 mb-1" style:top="0" style:right="0">
<Button
icon={IconClose}
kind="transparent"
size="small"
on:click={() => {
dispatch('close')
}}
/>
</div>
<div class="ap-space bottom-divider" />
<div class="flex" />
<div class="flex-col ml-4 mt-4 mb-4 mr-4 flex-gap-1">
<div class="text-md font-medium">
<Label label={board.string.Size} />
</div>
<div class="flex-center mt-1 mb-1 flex-gap-2">
<!-- TODO: replace with actual buttons -->
<Button
icon={board.icon.Card}
width="40%"
disabled={!cover || cover.size === 'small'}
on:click={() => {
updateCover({ size: 'small' })
}}
/>
<Button
icon={board.icon.Board}
width="40%"
disabled={!cover || cover.size === 'large'}
on:click={() => {
updateCover({ size: 'large' })
}}
/>
</div>
<div class="flex-center">
<Button
label={board.string.RemoveCover}
width="80%"
on:click={() => {
updateCover()
}}
/>
</div>
</div>
<div class="flex-col ml-4 mt-4 mb-4 mr-4 flex-gap-1">
<div class="text-md font-medium">
<Label label={board.string.SelectColor} />
</div>
<div class="flex-col mt-1 mb-1 flex-gap-2">
{#each colorGroups as colorGroup}
<div class="flex-row-stretch flex-gap-2">
{#each colorGroup as color}
<div class="w-14">
<ColorPresenter
value={color}
size="large"
on:click={() => {
updateCover({ color })
}}
>
{#if cover && cover.color === color}
<div class="flex-center flex-grow fs-title h-full">
<Icon icon={IconCheck} size="small" />
</div>
{/if}
</ColorPresenter>
</div>
{/each}
</div>
{/each}
</div>
</div>
</div>

View File

@ -51,6 +51,7 @@ import {
updateCardMembers
} from './utils/CardUtils'
import { getPopupAlignment } from './utils/PopupUtils'
import CardCoverEditor from './components/popups/CardCoverEditor.svelte'
async function showMoveCardPopup (object: Card, client: Client, e?: Event): Promise<void> {
showPopup(MoveCard, { object }, getPopupAlignment(e))
@ -94,6 +95,10 @@ async function showAttachmentsPopup (object: Card, client: Client, e?: Event): P
showPopup(AttachmentPicker, { object }, getPopupAlignment(e))
}
async function showCoverPopup (object: Card, client: Client, e?: Event): Promise<void> {
showPopup(CardCoverEditor, { object }, getPopupAlignment(e))
}
export default async (): Promise<Resources> => ({
component: {
CreateBoard,
@ -121,7 +126,8 @@ export default async (): Promise<Resources> => ({
SendToBoard: unarchiveCard,
Delete: showDeleteCardPopup,
Members: showEditMembersPopup,
Copy: showCopyCardPopup
Copy: showCopyCardPopup,
Cover: showCoverPopup
},
cardActionSupportedHandler: {
Join: canAddCurrentUser,

View File

@ -118,7 +118,9 @@ export default mergeIds(boardId, board, {
NoResults: '' as IntlString,
SwitchToLists: '' as IntlString,
SwitchToCards: '' as IntlString,
SearchArchive: '' as IntlString
SearchArchive: '' as IntlString,
Size: '' as IntlString,
RemoveCover: '' as IntlString
},
component: {
EditCard: '' as AnyComponent,

View File

@ -43,7 +43,7 @@ export function canAddCurrentUser (card: Card): boolean {
}
export function hasCover (card: Card): boolean {
return card.coverColor !== undefined || card.coverImage !== undefined
return card.cover != null
}
export function hasDate (card: Card): boolean {

View File

@ -56,6 +56,15 @@ export interface CardDate extends Obj {
startDate?: Timestamp
}
/**
* @public
*/
export interface CardCover {
color?: number
image?: string
size: 'large' | 'small'
}
/**
* @public
*/
@ -73,8 +82,7 @@ export interface Card extends Task {
location?: string
coverColor?: number
coverImage?: string
cover?: CardCover | null
comments?: number
attachments?: number