mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-29 03:21:13 +00:00
Add BoardMenu (#1592)
Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com>
This commit is contained in:
parent
a44fb47592
commit
67e6a7958f
@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
// To help typescript locate view plugin properly
|
||||
import type { Board, Card, CardAction, CardDate, CardLabel } from '@anticrm/board'
|
||||
import type { Board, Card, CardAction, CardDate, CardLabel, MenuPage } from '@anticrm/board'
|
||||
import type { Employee } from '@anticrm/contact'
|
||||
import { TxOperations as Client, Doc, DOMAIN_MODEL, FindOptions, IndexKind, Ref, Type, Timestamp } from '@anticrm/core'
|
||||
import {
|
||||
@ -122,8 +122,26 @@ export class TCardAction extends TDoc implements CardAction {
|
||||
supported?: Resource<(card: Card, client: Client) => boolean>
|
||||
}
|
||||
|
||||
@Model(board.class.MenuPage, core.class.Doc, DOMAIN_MODEL)
|
||||
export class TMenuPage extends TDoc implements MenuPage {
|
||||
component!: AnyComponent
|
||||
pageId!: string
|
||||
label!: IntlString
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(TBoard, TCard, TCardLabel, TCardDate, TCardAction)
|
||||
builder.createModel(TBoard, TCard, TCardLabel, TCardDate, TCardAction, TMenuPage)
|
||||
|
||||
builder.createDoc(board.class.MenuPage, core.space.Model, {
|
||||
component: board.component.Archive,
|
||||
pageId: board.menuPageId.Archive,
|
||||
label: board.string.Archive
|
||||
})
|
||||
builder.createDoc(board.class.MenuPage, core.space.Model, {
|
||||
component: board.component.MenuMainPage,
|
||||
pageId: board.menuPageId.Main,
|
||||
label: board.string.Menu
|
||||
})
|
||||
|
||||
builder.mixin(board.class.Board, core.class.Class, workbench.mixin.SpaceView, {
|
||||
view: {
|
||||
@ -151,7 +169,8 @@ export function createModel (builder: Builder): void {
|
||||
addSpaceLabel: board.string.BoardCreateLabel,
|
||||
createComponent: board.component.CreateBoard
|
||||
}
|
||||
]
|
||||
],
|
||||
aside: board.component.BoardMenu
|
||||
}
|
||||
},
|
||||
board.app.Board
|
||||
|
@ -91,6 +91,7 @@
|
||||
"DeleteCard": "All actions will be removed from the activity feed and you won’t be able to re-open the card. There is no undo.",
|
||||
"SearchMembers": "Search members",
|
||||
"Menu": "Menu",
|
||||
"ShowMenu": "Show menu",
|
||||
"ToArchive": "Archive",
|
||||
"CopyCard": "Copy card",
|
||||
"AlsoCopy": "Keep...",
|
||||
|
@ -91,6 +91,7 @@
|
||||
"DeleteCard": "Все действия будут удалены из ленты, и вы не сможете повторно открыть карточку. Отмена невозможна.",
|
||||
"SearchMembers": "Поиск участников",
|
||||
"Menu": "Меню",
|
||||
"ShowMenu": "Показать меню",
|
||||
"ToArchive": "Архивировать",
|
||||
"CopyCard": "Копировать карточку",
|
||||
"AlsoCopy": "Также копировать...",
|
||||
|
29
plugins/board-resources/src/components/Archive.svelte
Normal file
29
plugins/board-resources/src/components/Archive.svelte
Normal file
@ -0,0 +1,29 @@
|
||||
<script lang="ts">
|
||||
import { Ref, Space } from '@anticrm/core'
|
||||
import { Button } from '@anticrm/ui'
|
||||
import board from '../plugin'
|
||||
import CardsArchive from './CardArchive.svelte'
|
||||
import ListArchive from './ListArchive.svelte'
|
||||
import TextArea from '@anticrm/ui/src/components/TextArea.svelte'
|
||||
|
||||
export let space: Ref<Space>
|
||||
|
||||
let isCardArchive = true
|
||||
let search: string = ''
|
||||
$: query = { space, title: { $like: '%' + search + '%' } }
|
||||
$: label = isCardArchive
|
||||
? board.string.SwitchToLists
|
||||
: board.string.SwitchToCards
|
||||
</script>
|
||||
|
||||
<div class="p-4">
|
||||
<Button {label} width={'100%'} on:click={() => { isCardArchive = !isCardArchive }} />
|
||||
<div class="pt-4">
|
||||
<TextArea bind:value={search} placeholder={board.string.SearchArchive}/>
|
||||
</div>
|
||||
</div>
|
||||
{#if isCardArchive}
|
||||
<CardsArchive {query}/>
|
||||
{:else}
|
||||
<ListArchive {query}/>
|
||||
{/if}
|
@ -1,30 +1,28 @@
|
||||
<script lang="ts">
|
||||
import core, { Ref, Space } from '@anticrm/core'
|
||||
import { Button, showPopup } from '@anticrm/ui'
|
||||
import { Button, getCurrentLocation, navigate } 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]
|
||||
})
|
||||
$: query.query(core.class.Space, { _id: spaceId }, result => { space = result[0] })
|
||||
|
||||
const client = getClient()
|
||||
|
||||
function showMenu (e: MouseEvent) {
|
||||
showPopup(Menu, { space: space._id }, getPopupAlignment(e, { h: 'left', v: 'top' }))
|
||||
function showMenu () {
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[3] = space._id
|
||||
navigate(loc)
|
||||
}
|
||||
</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={showMenu} />
|
||||
<Header icon={classIcon(client, space._class)} label={space.name} description={space.description}/>
|
||||
<Button label={border.string.ShowMenu} on:click={showMenu}/>
|
||||
{/if}
|
||||
</div>
|
||||
|
52
plugins/board-resources/src/components/BoardMenu.svelte
Normal file
52
plugins/board-resources/src/components/BoardMenu.svelte
Normal file
@ -0,0 +1,52 @@
|
||||
<script lang="ts">
|
||||
import { Ref, Space } from '@anticrm/core'
|
||||
import Label from '@anticrm/ui/src/components/Label.svelte'
|
||||
import board from '../plugin'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { MenuPage } from '@anticrm/board'
|
||||
import { Button, Component, IconBack, IconClose } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let currentSpace: Ref<Space> | undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let currentPageId = board.menuPageId.Main
|
||||
let trace: string[] = []
|
||||
let page: MenuPage
|
||||
const query = createQuery()
|
||||
$: query.query(board.class.MenuPage, { pageId: currentPageId }, result => {
|
||||
;[page] = result
|
||||
})
|
||||
function setKey (e: CustomEvent) {
|
||||
trace = [currentPageId, ...trace]
|
||||
currentPageId = e.detail
|
||||
}
|
||||
function onBack () {
|
||||
[currentPageId = board.menuPageId.Main, ...trace] = trace
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if page}
|
||||
<div class="ac-header flex-between w-full divide">
|
||||
{#if trace.length}
|
||||
<Button icon={IconBack} kind="transparent" size="x-large" on:click={onBack} />
|
||||
{:else}
|
||||
<div class="ml-12"/>
|
||||
{/if}
|
||||
<div class="flex-center fs-title">
|
||||
<Label label={page.label} />
|
||||
</div>
|
||||
<Button
|
||||
icon={IconClose}
|
||||
kind="transparent"
|
||||
size="x-large"
|
||||
on:click={() => {
|
||||
dispatch('close')
|
||||
}} />
|
||||
</div>
|
||||
{#if currentSpace}
|
||||
<div class="vScroll mb-4">
|
||||
<Component is={page.component} props={{ space: currentSpace }} on:change={setKey}/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
12
plugins/board-resources/src/components/MenuMainPage.svelte
Normal file
12
plugins/board-resources/src/components/MenuMainPage.svelte
Normal file
@ -0,0 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import board from '@anticrm/board'
|
||||
import plugin from '../plugin'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<div class="p-4">
|
||||
<Button label={plugin.string.Archive} width={'100%'} on:click={() => { dispatch('change', board.menuPageId.Archive) }} />
|
||||
</div>
|
@ -1,55 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Ref, Space } from '@anticrm/core'
|
||||
import { ActionIcon, Button, IconClose, Label } from '@anticrm/ui'
|
||||
import TextArea from '@anticrm/ui/src/components/TextArea.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import board from '../../plugin'
|
||||
import CardsArchive from '../CardArchive.svelte'
|
||||
import ListArchive from '../ListArchive.svelte'
|
||||
|
||||
export let space: Ref<Space>
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let isCardArchive = true
|
||||
let search: string = ''
|
||||
$: query = { space, title: { $like: '%' + search + '%' } }
|
||||
$: label = isCardArchive ? board.string.SwitchToLists : board.string.SwitchToCards
|
||||
</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" />
|
||||
<div class="ap-scroll">
|
||||
<div class="p-4">
|
||||
<Button
|
||||
{label}
|
||||
width={'100%'}
|
||||
on:click={() => {
|
||||
isCardArchive = !isCardArchive
|
||||
}}
|
||||
/>
|
||||
<div class="pt-4">
|
||||
<TextArea bind:value={search} placeholder={board.string.SearchArchive} />
|
||||
</div>
|
||||
</div>
|
||||
{#if isCardArchive}
|
||||
<CardsArchive {query} />
|
||||
{:else}
|
||||
<ListArchive {query} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
@ -38,6 +38,9 @@ import CardLabelPresenter from './components/presenters/LabelPresenter.svelte'
|
||||
import TemplatesIcon from './components/TemplatesIcon.svelte'
|
||||
import WatchCard from './components/WatchCard.svelte'
|
||||
import BoardHeader from './components/BoardHeader.svelte'
|
||||
import BoardMenu from './components/BoardMenu.svelte'
|
||||
import MenuMainPage from './components/MenuMainPage.svelte'
|
||||
import Archive from './components/Archive.svelte'
|
||||
import board from './plugin'
|
||||
import {
|
||||
addCurrentUser,
|
||||
@ -104,7 +107,10 @@ export default async (): Promise<Resources> => ({
|
||||
KanbanView,
|
||||
BoardPresenter,
|
||||
WatchCard,
|
||||
BoardHeader
|
||||
BoardHeader,
|
||||
BoardMenu,
|
||||
Archive,
|
||||
MenuMainPage
|
||||
},
|
||||
cardActionHandler: {
|
||||
Join: addCurrentUser,
|
||||
|
@ -112,6 +112,7 @@ export default mergeIds(boardId, board, {
|
||||
SearchMembers: '' as IntlString,
|
||||
DeleteCard: '' as IntlString,
|
||||
Menu: '' as IntlString,
|
||||
ShowMenu: '' as IntlString,
|
||||
ToArchive: '' as IntlString,
|
||||
CopyCard: '' as IntlString,
|
||||
AlsoCopy: '' as IntlString,
|
||||
@ -123,6 +124,11 @@ export default mergeIds(boardId, board, {
|
||||
},
|
||||
component: {
|
||||
EditCard: '' as AnyComponent,
|
||||
BoardHeader: '' as AnyComponent
|
||||
Members: '' as AnyComponent,
|
||||
Settings: '' as AnyComponent,
|
||||
BoardHeader: '' as AnyComponent,
|
||||
BoardMenu: '' as AnyComponent,
|
||||
Archive: '' as AnyComponent,
|
||||
MenuMainPage: '' as AnyComponent
|
||||
}
|
||||
})
|
||||
|
@ -94,6 +94,14 @@ export interface CardAction extends Doc {
|
||||
handler?: Resource<(card: Card, client: Client, e?: Event) => void>
|
||||
supported?: Resource<(card: Card, client: Client) => boolean>
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface MenuPage extends Doc {
|
||||
component: AnyComponent
|
||||
pageId: string
|
||||
label: IntlString
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -112,7 +120,8 @@ const boards = plugin(boardId, {
|
||||
Card: '' as Ref<Class<Card>>,
|
||||
CardAction: '' as Ref<Class<CardAction>>,
|
||||
CardDate: '' as Ref<Class<CardDate>>,
|
||||
CardLabel: '' as Ref<Class<CardLabel>>
|
||||
CardLabel: '' as Ref<Class<CardLabel>>,
|
||||
MenuPage: '' as Ref<Class<MenuPage>>
|
||||
},
|
||||
icon: {
|
||||
Board: '' as Asset,
|
||||
@ -121,6 +130,10 @@ const boards = plugin(boardId, {
|
||||
space: {
|
||||
BoardTemplates: '' as Ref<KanbanTemplateSpace>
|
||||
},
|
||||
menuPageId: {
|
||||
Main: 'main',
|
||||
Archive: 'archive'
|
||||
},
|
||||
cardActionType: {
|
||||
Suggested: 'Suggested',
|
||||
Editor: 'Editor',
|
||||
|
Loading…
Reference in New Issue
Block a user