mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-21 07:46:24 +00:00
kanban take cards implementation from extensions
Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
parent
951fd2ae10
commit
a26c10ad8c
File diff suppressed because it is too large
Load Diff
@ -138,6 +138,10 @@ export function createModel (builder: Builder): void {
|
|||||||
} as FindOptions<Doc>, // TODO: fix
|
} as FindOptions<Doc>, // TODO: fix
|
||||||
config: ['$lookup.candidate', '$lookup.state', '$lookup.candidate.city', '$lookup.candidate.channels']
|
config: ['$lookup.candidate', '$lookup.state', '$lookup.candidate.city', '$lookup.candidate.channels']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.KanbanCard, {
|
||||||
|
card: recruit.component.KanbanCard
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export { default } from './plugin'
|
export { default } from './plugin'
|
||||||
|
@ -32,7 +32,8 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
CreateCandidates: '' as AnyComponent,
|
CreateCandidates: '' as AnyComponent,
|
||||||
CreateCandidate: '' as AnyComponent,
|
CreateCandidate: '' as AnyComponent,
|
||||||
CreateApplication: '' as AnyComponent,
|
CreateApplication: '' as AnyComponent,
|
||||||
EditCandidate: '' as AnyComponent
|
EditCandidate: '' as AnyComponent,
|
||||||
|
KanbanCard: '' as AnyComponent
|
||||||
},
|
},
|
||||||
space: {
|
space: {
|
||||||
CandidatesPublic: '' as Ref<Space>
|
CandidatesPublic: '' as Ref<Space>
|
||||||
|
@ -18,7 +18,7 @@ import type { Ref, Class, Space } from '@anticrm/core'
|
|||||||
import { DOMAIN_MODEL } from '@anticrm/core'
|
import { DOMAIN_MODEL } from '@anticrm/core'
|
||||||
import { Model, Mixin, Builder } from '@anticrm/model'
|
import { Model, Mixin, Builder } from '@anticrm/model'
|
||||||
import type { AnyComponent } from '@anticrm/ui'
|
import type { AnyComponent } from '@anticrm/ui'
|
||||||
import type { ViewletDescriptor, Viewlet, AttributeEditor, AttributePresenter } from '@anticrm/view'
|
import type { ViewletDescriptor, Viewlet, AttributeEditor, AttributePresenter, KanbanCard } from '@anticrm/view'
|
||||||
|
|
||||||
import core, { TDoc, TClass } from '@anticrm/model-core'
|
import core, { TDoc, TClass } from '@anticrm/model-core'
|
||||||
|
|
||||||
@ -34,6 +34,11 @@ export class TAttributePresenter extends TClass implements AttributePresenter {
|
|||||||
presenter!: AnyComponent
|
presenter!: AnyComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mixin(view.mixin.KanbanCard, core.class.Class)
|
||||||
|
export class TKanbanCard extends TClass implements KanbanCard {
|
||||||
|
card!: AnyComponent
|
||||||
|
}
|
||||||
|
|
||||||
@Model(view.class.ViewletDescriptor, core.class.Doc, DOMAIN_MODEL)
|
@Model(view.class.ViewletDescriptor, core.class.Doc, DOMAIN_MODEL)
|
||||||
export class TViewletDescriptor extends TDoc implements ViewletDescriptor {
|
export class TViewletDescriptor extends TDoc implements ViewletDescriptor {
|
||||||
component!: AnyComponent
|
component!: AnyComponent
|
||||||
@ -48,7 +53,7 @@ export class TViewlet extends TDoc implements Viewlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function createModel (builder: Builder): void {
|
export function createModel (builder: Builder): void {
|
||||||
builder.createModel(TAttributeEditor, TAttributePresenter, TViewletDescriptor, TViewlet)
|
builder.createModel(TAttributeEditor, TAttributePresenter, TKanbanCard, TViewletDescriptor, TViewlet)
|
||||||
|
|
||||||
builder.mixin(core.class.TypeString, core.class.Class, view.mixin.AttributeEditor, {
|
builder.mixin(core.class.TypeString, core.class.Class, view.mixin.AttributeEditor, {
|
||||||
editor: view.component.StringEditor
|
editor: view.component.StringEditor
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { UserInfo } from '@anticrm/presentation'
|
import { UserInfo, Avatar } from '@anticrm/presentation'
|
||||||
import { ActionIcon, IconMoreH, IconFile } from '@anticrm/ui'
|
import { Icon, Label, IconThread, IconAttachment } from '@anticrm/ui'
|
||||||
import IconWithLabel from './IconWithLabel.svelte'
|
import type { WithLookup } from '@anticrm/core'
|
||||||
import Tag from './Tag.svelte'
|
import type { Applicant } from '@anticrm/recruit'
|
||||||
|
|
||||||
interface ICard {
|
interface ICard {
|
||||||
_id: number
|
_id: number
|
||||||
@ -27,63 +27,139 @@
|
|||||||
state: number
|
state: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export let card: ICard
|
export let object: WithLookup<Applicant>
|
||||||
export let draggable: boolean
|
export let draggable: boolean
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
|
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
|
||||||
<div class="header">
|
<div class="card-bg" />
|
||||||
<UserInfo value={{firstName: card.firstName, lastName: card.lastName }} subtitle={'Candidate'} size={'small'} />
|
|
||||||
<ActionIcon icon={IconMoreH} label={'More..'} direction={'left'} />
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<IconWithLabel icon={IconFile} label={'Team Interview'} />
|
<div class="flex-center">
|
||||||
<div class="description">{card.description}</div>
|
<div class="avatar">
|
||||||
<div class="tags">
|
<Avatar size={'large'} />
|
||||||
<Tag icon={IconFile} label={'Application'} />
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-col">
|
||||||
|
<div class="name">{object.$lookup?.candidate?.firstName} {object.$lookup?.candidate?.lastName}</div>
|
||||||
|
<div class="city">{object.$lookup?.candidate?.city}</div>
|
||||||
|
<div class="tags">
|
||||||
|
<div class="tag"><Label label={'Application'} /></div>
|
||||||
|
<div class="tag"><Label label={'Resume'} /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<Avatar size={'small'} />
|
||||||
|
<div class="flex-row-center">
|
||||||
|
<div class="flex-row-center caption-color tool">
|
||||||
|
<span class="icon"><IconAttachment size={'small'} /></span>
|
||||||
|
4
|
||||||
|
</div>
|
||||||
|
<div class="flex-row-center caption-color tool">
|
||||||
|
<span class="icon"><IconThread size={'small'} /></span>
|
||||||
|
5
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@import '../../../../packages/theme/styles/mixins.scss';
|
||||||
|
|
||||||
.card-container {
|
.card-container {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
background-color: var(--theme-button-bg-hovered);
|
|
||||||
border: 1px solid var(--theme-bg-accent-color);
|
|
||||||
border-radius: .75rem;
|
border-radius: .75rem;
|
||||||
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 14px 16px;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 60px;
|
|
||||||
background-color: var(--theme-button-bg-focused);
|
|
||||||
border-radius: 11px 11px 0 0;
|
|
||||||
}
|
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
align-items: center;
|
||||||
align-items: stretch;
|
padding: 1.25rem;
|
||||||
padding: 16px;
|
|
||||||
|
|
||||||
.description {
|
.avatar {
|
||||||
margin-top: 8px;
|
position: relative;
|
||||||
|
margin-right: 1rem;
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: drop-shadow(0px 24px 94px rgba(50, 53, 47, 1));
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
@include bg-layer(transparent, .1);
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
margin: .25rem 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
}
|
||||||
|
.city {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: .75rem;
|
||||||
}
|
}
|
||||||
.tags {
|
.tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
margin-top: .5rem;
|
||||||
margin-top: 16px;
|
|
||||||
|
.tag {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: .375rem .5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: .625rem;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
@include bg-layer(#fff, .04);
|
||||||
|
border-radius: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tag + .tag { margin-left: .5rem; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: .75rem 1.25rem;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 3rem;
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
@include bg-layer(#fff, .04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool .icon {
|
||||||
|
margin-right: .25rem;
|
||||||
|
opacity: .4;
|
||||||
|
}
|
||||||
|
.tool + .tool {
|
||||||
|
margin-left: .75rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.draggable {
|
&.draggable {
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-bg {
|
||||||
|
@include bg-layer(var(--theme-card-bg), .06);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.card-container + .card-container) { margin-top: .75rem; }
|
||||||
</style>
|
</style>
|
||||||
|
@ -20,6 +20,7 @@ import CreateApplication from './components/CreateApplication.svelte'
|
|||||||
import EditCandidate from './components/EditCandidate.svelte'
|
import EditCandidate from './components/EditCandidate.svelte'
|
||||||
import CandidateGeneral from './components/CandidateGeneral.svelte'
|
import CandidateGeneral from './components/CandidateGeneral.svelte'
|
||||||
import Attachments from './components/Attachments.svelte'
|
import Attachments from './components/Attachments.svelte'
|
||||||
|
import KanbanCard from './components/KanbanCard.svelte'
|
||||||
|
|
||||||
export default async () => ({
|
export default async () => ({
|
||||||
component: {
|
component: {
|
||||||
@ -29,6 +30,7 @@ export default async () => ({
|
|||||||
CreateApplication,
|
CreateApplication,
|
||||||
EditCandidate,
|
EditCandidate,
|
||||||
CandidateGeneral,
|
CandidateGeneral,
|
||||||
Attachments
|
Attachments,
|
||||||
|
KanbanCard
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -1,163 +0,0 @@
|
|||||||
<!--
|
|
||||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
|
||||||
//
|
|
||||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License. You may
|
|
||||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
//
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { UserInfo, Avatar } from '@anticrm/presentation'
|
|
||||||
import { Icon, Label, IconThread, IconAttachment } from '@anticrm/ui'
|
|
||||||
|
|
||||||
interface ICard {
|
|
||||||
_id: number
|
|
||||||
firstName: string
|
|
||||||
lastName: string
|
|
||||||
description: string
|
|
||||||
state: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export let card: ICard
|
|
||||||
export let draggable: boolean
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
|
|
||||||
<div class="card-bg" />
|
|
||||||
<div class="content">
|
|
||||||
<div class="flex-center">
|
|
||||||
<div class="avatar">
|
|
||||||
<Avatar size={'large'} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-col">
|
|
||||||
<div class="name">{card.firstName} {card.lastName}</div>
|
|
||||||
<div class="city">{card.description}</div>
|
|
||||||
<div class="tags">
|
|
||||||
<div class="tag"><Label label={'Application'} /></div>
|
|
||||||
<div class="tag"><Label label={'Resume'} /></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<Avatar size={'small'} />
|
|
||||||
<div class="flex-row-center">
|
|
||||||
<div class="flex-row-center caption-color tool">
|
|
||||||
<span class="icon"><IconAttachment size={'small'} /></span>
|
|
||||||
4
|
|
||||||
</div>
|
|
||||||
<div class="flex-row-center caption-color tool">
|
|
||||||
<span class="icon"><IconThread size={'small'} /></span>
|
|
||||||
5
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import '../../../../packages/theme/styles/mixins.scss';
|
|
||||||
|
|
||||||
.card-container {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
border-radius: .75rem;
|
|
||||||
overflow: hidden;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1.25rem;
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 1rem;
|
|
||||||
width: 5rem;
|
|
||||||
height: 5rem;
|
|
||||||
border-radius: 50%;
|
|
||||||
filter: drop-shadow(0px 24px 94px rgba(50, 53, 47, 1));
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
@include bg-layer(transparent, .1);
|
|
||||||
border: 2px solid #fff;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
margin: .25rem 0;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 1rem;
|
|
||||||
color: var(--theme-caption-color);
|
|
||||||
}
|
|
||||||
.city {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: .75rem;
|
|
||||||
}
|
|
||||||
.tags {
|
|
||||||
display: flex;
|
|
||||||
margin-top: .5rem;
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: .375rem .5rem;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: .625rem;
|
|
||||||
text-align: center;
|
|
||||||
color: var(--theme-caption-color);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
@include bg-layer(#fff, .04);
|
|
||||||
border-radius: .5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tag + .tag { margin-left: .5rem; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: .75rem 1.25rem;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 3rem;
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
@include bg-layer(#fff, .04);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool .icon {
|
|
||||||
margin-right: .25rem;
|
|
||||||
opacity: .4;
|
|
||||||
}
|
|
||||||
.tool + .tool {
|
|
||||||
margin-left: .75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.draggable {
|
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-bg {
|
|
||||||
@include bg-layer(var(--theme-card-bg), .06);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.card-container + .card-container) { margin-top: .75rem; }
|
|
||||||
</style>
|
|
@ -17,20 +17,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import type { Ref, Class, Doc, Space, FindOptions, State } from '@anticrm/core'
|
import type { Ref, Class, Doc, Space, FindOptions, State } from '@anticrm/core'
|
||||||
|
import { getResource } from '@anticrm/platform'
|
||||||
import { buildModel } from '../utils'
|
import { buildModel } from '../utils'
|
||||||
import { getClient } from '@anticrm/presentation'
|
import { getClient } from '@anticrm/presentation'
|
||||||
import { Label, showPopup, Loading, ScrollBox } from '@anticrm/ui'
|
import { Label, showPopup, Loading, ScrollBox, AnyComponent } from '@anticrm/ui'
|
||||||
import type { AnyComponent } from '@anticrm/ui'
|
import type { AnySvelteComponent } from '@anticrm/ui'
|
||||||
|
|
||||||
import { createQuery } from '@anticrm/presentation'
|
import { createQuery } from '@anticrm/presentation'
|
||||||
|
|
||||||
import KanbanPanel from './KanbanPanel.svelte'
|
import KanbanPanel from './KanbanPanel.svelte'
|
||||||
import KanbanPanelEmpty from './KanbanPanelEmpty.svelte'
|
import KanbanPanelEmpty from './KanbanPanelEmpty.svelte'
|
||||||
import KanbanCard from './KanbanCard.svelte'
|
|
||||||
import KanbanCardEmpty from './KanbanCardEmpty.svelte'
|
import KanbanCardEmpty from './KanbanCardEmpty.svelte'
|
||||||
|
|
||||||
import core from '@anticrm/core'
|
import core from '@anticrm/core'
|
||||||
import { _ID_SEPARATOR } from '@anticrm/platform';
|
import view from '@anticrm/view'
|
||||||
|
|
||||||
export let _class: Ref<Class<(Doc & { state: Ref<State> })>>
|
export let _class: Ref<Class<(Doc & { state: Ref<State> })>>
|
||||||
export let space: Ref<Space>
|
export let space: Ref<Space>
|
||||||
@ -75,11 +75,17 @@ import { _ID_SEPARATOR } from '@anticrm/platform';
|
|||||||
|
|
||||||
let dragCard: (Doc & { state: Ref<State>}) | undefined
|
let dragCard: (Doc & { state: Ref<State>}) | undefined
|
||||||
|
|
||||||
|
async function cardPresenter(_class: Ref<Class<Doc>>): Promise<AnySvelteComponent> {
|
||||||
|
const clazz = client.getHierarchy().getClass(_class)
|
||||||
|
const presenterMixin = client.getHierarchy().as(clazz, view.mixin.KanbanCard)
|
||||||
|
return await getResource(presenterMixin.card)
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#await buildModel(client, _class, config, options)}
|
{#await cardPresenter(_class)}
|
||||||
<Loading/>
|
<Loading/>
|
||||||
{:then model}
|
{:then presenter}
|
||||||
<div class="kanban-container">
|
<div class="kanban-container">
|
||||||
<ScrollBox>
|
<ScrollBox>
|
||||||
<div class="kanban-content">
|
<div class="kanban-content">
|
||||||
@ -97,15 +103,14 @@ import { _ID_SEPARATOR } from '@anticrm/platform';
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<KanbanCardEmpty label={'Create new application'} />
|
<KanbanCardEmpty label={'Create new application'} />
|
||||||
{#each objects.filter((c) => c.state === state._id) as card}
|
{#each objects.filter((c) => c.state === state._id) as object}
|
||||||
<KanbanCard {card} draggable={true}
|
<svelte:component this={presenter} {object} draggable={true}
|
||||||
on:dragstart={() => {
|
on:dragstart={() => {
|
||||||
dragCard = card
|
dragCard = object
|
||||||
}}
|
}}
|
||||||
on:dragend={() => {
|
on:dragend={() => {
|
||||||
dragCard = undefined
|
dragCard = undefined
|
||||||
}}
|
}}/>
|
||||||
/>
|
|
||||||
{/each}
|
{/each}
|
||||||
</KanbanPanel>
|
</KanbanPanel>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -34,6 +34,13 @@ export interface AttributePresenter extends Class<Doc> {
|
|||||||
presenter: AnyComponent
|
presenter: AnyComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface KanbanCard extends Class<Doc> {
|
||||||
|
card: AnyComponent
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -60,7 +67,8 @@ export const viewId = 'view' as Plugin
|
|||||||
export default plugin(viewId, {
|
export default plugin(viewId, {
|
||||||
mixin: {
|
mixin: {
|
||||||
AttributeEditor: '' as Ref<Mixin<AttributeEditor>>,
|
AttributeEditor: '' as Ref<Mixin<AttributeEditor>>,
|
||||||
AttributePresenter: '' as Ref<Mixin<AttributePresenter>>
|
AttributePresenter: '' as Ref<Mixin<AttributePresenter>>,
|
||||||
|
KanbanCard: '' as Ref<Mixin<KanbanCard>>
|
||||||
},
|
},
|
||||||
class: {
|
class: {
|
||||||
ViewletDescriptor: '' as Ref<Class<ViewletDescriptor>>,
|
ViewletDescriptor: '' as Ref<Class<ViewletDescriptor>>,
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user