Customize board header (#1492)

Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com>
This commit is contained in:
Alex 2022-04-24 12:06:20 +07:00 committed by GitHub
parent d663e383e6
commit 34ddd0cb6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 147 additions and 12 deletions

View File

@ -131,6 +131,9 @@ export function createModel (builder: Builder): void {
// createItemLabel: board.string.CardCreateLabel // createItemLabel: board.string.CardCreateLabel
} }
}) })
builder.mixin(board.class.Board, core.class.Class, view.mixin.SpaceHeader, {
header: board.component.BoardHeader
})
builder.createDoc( builder.createDoc(
workbench.class.Application, workbench.class.Application,
@ -435,7 +438,7 @@ export function createModel (builder: Builder): void {
{ {
icon: board.icon.Card, icon: board.icon.Card,
isInline: true, isInline: true,
label: board.string.Archive, label: board.string.ToArchive,
position: 140, position: 140,
type: board.cardActionType.Action, type: board.cardActionType.Action,
handler: board.cardActionHandler.Archive, handler: board.cardActionHandler.Archive,

View File

@ -87,6 +87,9 @@
"Edit": "Edit", "Edit": "Edit",
"Update": "Update", "Update": "Update",
"DeleteAttachment": "Deleting an attachment is permanent. There is no undo.", "DeleteAttachment": "Deleting an attachment is permanent. There is no undo.",
"SearchMembers": "Search members" "DeleteCard": "All actions will be removed from the activity feed and you wont be able to re-open the card. There is no undo.",
"SearchMembers": "Search members",
"Menu": "Menu",
"ToArchive": "Archive"
} }
} }

View File

@ -55,7 +55,7 @@
"MakeTemplate": "Шаблон", "MakeTemplate": "Шаблон",
"Watch": "Отслеживать", "Watch": "Отслеживать",
"Unwatch": "Не отслеживать", "Unwatch": "Не отслеживать",
"Archive": "Архивировать", "Archive": "Архив",
"SendToBoard": "Вернуть", "SendToBoard": "Вернуть",
"Delete": "Удалить", "Delete": "Удалить",
"HideDetails": "Спрятать", "HideDetails": "Спрятать",
@ -87,6 +87,9 @@
"Edit": "Изменить", "Edit": "Изменить",
"Update": "Обновить", "Update": "Обновить",
"DeleteAttachment": "Удаление вложения необратимо. Отмена невозможна.", "DeleteAttachment": "Удаление вложения необратимо. Отмена невозможна.",
"SearchMembers": "Поиск участников" "DeleteCard": "Все действия будут удалены из ленты, и вы не сможете повторно открыть карточку. Отмена невозможна.",
"SearchMembers": "Поиск участников",
"Menu": "Меню",
"ToArchive": "Архивировать"
} }
} }

View File

@ -0,0 +1,24 @@
<script lang="ts">
import core, { Ref, Space } from "@anticrm/core";
import { Button, showPopup } from "@anticrm/ui";
import { createQuery, getClient } from "@anticrm/presentation";
import { Header, classIcon } from '@anticrm/chunter-resources'
import Menu from './popups/Menu.svelte'
import { getPopupAlignment } from "../utils/PopupUtils";
import border from '../plugin'
export let spaceId: Ref<Space> | undefined
let space: Space
const query = createQuery()
$: query.query(core.class.Space, { _id: spaceId }, result => { space = result[0] })
const client = getClient()
</script>
<div class="ac-header divide full">
{#if space}
<Header icon={classIcon(client, space._class)} label={space.name} description={space.description}/>
<Button label={border.string.Menu} on:click={(e) => { showPopup(Menu, {}, getPopupAlignment(e))}}/>
{/if}
</div>

View File

@ -0,0 +1,50 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Label, Button, ActionIcon, IconClose, Icon } from '@anticrm/ui'
import { createQuery, getClient } from '@anticrm/presentation'
import { Card } from '@anticrm/board'
import board from '../../plugin'
import KanbanCard from '../KanbanCard.svelte'
import { SortingOrder } from '@anticrm/core'
import { getResource } from '@anticrm/platform'
let archivedCards: Card[]
const client = getClient()
const dispatch = createEventDispatcher()
const cardQuery = createQuery()
$: cardQuery.query(board.class.Card, {isArchived: true},
result => { archivedCards = result },
{ sort: { rank: SortingOrder.Descending } }
)
</script>
<div class="antiPopup antiPopup-withHeader antiPopup-withCategory w-60">
<div class="ap-space"/>
<div class="flex-row-center header">
<div class="flex-center flex-grow">
<Label label={board.string.Archive}/>
</div>
<div class="close-icon mr-1">
<ActionIcon icon={IconClose} size={'small'} action={() => { dispatch('close') }} />
</div>
</div>
<div class="ap-space bottom-divider"/>
{#if archivedCards}
{#each archivedCards as card}
<KanbanCard object={card} dragged={false}/>
<div class="flex-center flex-gap-2 w-full">
<Button label={board.string.SendToBoard}
on:click={async (e) => {
const deleteAction = await getResource(board.cardActionHandler.SendToBoard)
deleteAction(card, client, e)
}}/>
<Button label={board.string.Delete}
on:click={async (e) => {
const deleteAction = await getResource(board.cardActionHandler.Delete)
deleteAction(card, client, e)
}}/>
</div>
{/each}
{/if}
<div class="ap-space"/>
</div>

View File

@ -0,0 +1,40 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Label, Button, ActionIcon, IconClose } from '@anticrm/ui'
import board from '../../plugin'
import { getClient } from '@anticrm/presentation'
import { Card } from '@anticrm/board';
export let object: Card
const client = getClient()
const dispatch = createEventDispatcher()
</script>
<div class="antiPopup antiPopup-withHeader antiPopup-withTitle antiPopup-withCategory w-85">
<div class="ap-space"/>
<div class="flex-row-center header">
<div class="flex-center flex-grow">
<Label label={board.string.Delete} />
</div>
<div class="close-icon mr-1">
<ActionIcon icon={IconClose} size={'small'} action={() => { dispatch('close') }} />
</div>
</div>
<div class="ap-space bottom-divider"/>
<div class="ap-box ml-4 mr-4 mt-4">
<Label label={board.string.DeleteCard}/>
</div>
<div class="ap-footer">
<Button
size={'small'}
width="100%"
label={board.string.Delete}
kind={'dangerous'}
on:click={() => {
client.remove(object)
dispatch('close')
}}
/>
</div>
</div>

View File

@ -32,24 +32,29 @@ import TemplatesIcon from './components/TemplatesIcon.svelte'
import KanbanView from './components/KanbanView.svelte' import KanbanView from './components/KanbanView.svelte'
import AttachmentPicker from './components/popups/AttachmentPicker.svelte' import AttachmentPicker from './components/popups/AttachmentPicker.svelte'
import CardLabelsPopup from './components/popups/CardLabelsPopup.svelte' import CardLabelsPopup from './components/popups/CardLabelsPopup.svelte'
import MoveView from './components/popups/MoveCard.svelte' import MoveCard from './components/popups/MoveCard.svelte'
import DeleteCard from './components/popups/RemoveCard.svelte'
import DateRangePicker from './components/popups/DateRangePicker.svelte' import DateRangePicker from './components/popups/DateRangePicker.svelte'
import CardLabelPresenter from './components/presenters/LabelPresenter.svelte' import CardLabelPresenter from './components/presenters/LabelPresenter.svelte'
import CardDatePresenter from './components/presenters/DatePresenter.svelte' import CardDatePresenter from './components/presenters/DatePresenter.svelte'
import WatchCard from './components/WatchCard.svelte' import WatchCard from './components/WatchCard.svelte'
import BoardHeader from './components/BoardHeader.svelte'
import { import {
addCurrentUser, addCurrentUser,
canAddCurrentUser, canAddCurrentUser,
isArchived, isArchived,
isUnarchived, isUnarchived,
archiveCard, archiveCard,
unarchiveCard, unarchiveCard
deleteCard
} from './utils/CardUtils' } from './utils/CardUtils'
import { getPopupAlignment } from './utils/PopupUtils' import { getPopupAlignment } from './utils/PopupUtils'
async function showMoveCardPopup (object: Card, client: Client, e?: Event): Promise<void> { async function showMoveCardPopup (object: Card, client: Client, e?: Event): Promise<void> {
showPopup(MoveView, { object }, getPopupAlignment(e)) showPopup(MoveCard, { object }, getPopupAlignment(e))
}
async function showDeleteCardPopup (object: Card, client: Client, e?: Event): Promise<void> {
showPopup(DeleteCard, { object }, getPopupAlignment(e))
} }
async function showDatePickerPopup (object: Card, client: Client, e?: Event): Promise<void> { async function showDatePickerPopup (object: Card, client: Client, e?: Event): Promise<void> {
@ -94,7 +99,8 @@ export default async (): Promise<Resources> => ({
TemplatesIcon, TemplatesIcon,
KanbanView, KanbanView,
BoardPresenter, BoardPresenter,
WatchCard WatchCard,
BoardHeader
}, },
cardActionHandler: { cardActionHandler: {
Join: addCurrentUser, Join: addCurrentUser,
@ -104,7 +110,7 @@ export default async (): Promise<Resources> => ({
Attachments: showAttachmentsPopup, Attachments: showAttachmentsPopup,
Archive: archiveCard, Archive: archiveCard,
SendToBoard: unarchiveCard, SendToBoard: unarchiveCard,
Delete: deleteCard, Delete: showDeleteCardPopup,
Members: showEditMembersPopup Members: showEditMembersPopup
}, },
cardActionSupportedHandler: { cardActionSupportedHandler: {

View File

@ -108,12 +108,16 @@ export default mergeIds(boardId, board, {
Edit: '' as IntlString, Edit: '' as IntlString,
Update: '' as IntlString, Update: '' as IntlString,
DeleteAttachment: '' as IntlString, DeleteAttachment: '' as IntlString,
SearchMembers: '' as IntlString SearchMembers: '' as IntlString,
DeleteCard: '' as IntlString,
Menu: '' as IntlString,
ToArchive: '' as IntlString
}, },
component: { component: {
Boards: '' as AnyComponent, Boards: '' as AnyComponent,
EditCard: '' as AnyComponent, EditCard: '' as AnyComponent,
Members: '' as AnyComponent, Members: '' as AnyComponent,
Settings: '' as AnyComponent Settings: '' as AnyComponent,
BoardHeader: '' as AnyComponent
} }
}) })

View File

@ -40,6 +40,8 @@ import preference from '@anticrm/preference'
import { getDmName } from './utils' import { getDmName } from './utils'
export { default as Header } from './components/Header.svelte'
export { classIcon } from './utils'
export { CommentsPresenter } export { CommentsPresenter }
async function MarkUnread (object: Message): Promise<void> { async function MarkUnread (object: Message): Promise<void> {