mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-23 05:53:09 +03:00
Delete
action
Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
parent
55ceee2372
commit
048bb9c71f
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ import { Builder } from '@anticrm/model'
|
||||
import core from './component'
|
||||
import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString } from './core'
|
||||
import { TSpace, TAccount, TState, TSpaceWithStates } from './security'
|
||||
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD, TTxPutBag } from './tx'
|
||||
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD, TTxPutBag, TTxRemoveDoc } from './tx'
|
||||
|
||||
export * from './core'
|
||||
export * from './security'
|
||||
@ -36,6 +36,7 @@ export function createModel (builder: Builder): void {
|
||||
TTxPutBag,
|
||||
TTxMixin,
|
||||
TTxUpdateDoc,
|
||||
TTxRemoveDoc,
|
||||
TSpace,
|
||||
TSpaceWithStates,
|
||||
TAccount,
|
||||
|
@ -13,12 +13,12 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import type { Ref, Class, Space } from '@anticrm/core'
|
||||
import type { IntlString, Asset, Resource } from '@anticrm/platform'
|
||||
import type { Ref, Class, Space, Doc } from '@anticrm/core'
|
||||
import { DOMAIN_MODEL } from '@anticrm/core'
|
||||
import { Model, Mixin, Builder } from '@anticrm/model'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
import type { ViewletDescriptor, Viewlet, AttributeEditor, AttributePresenter, KanbanCard, ObjectEditor } from '@anticrm/view'
|
||||
import type { ViewletDescriptor, Viewlet, AttributeEditor, AttributePresenter, KanbanCard, ObjectEditor, Action, ActionTarget } from '@anticrm/view'
|
||||
|
||||
import core, { TDoc, TClass } from '@anticrm/model-core'
|
||||
|
||||
@ -57,8 +57,21 @@ export class TViewlet extends TDoc implements Viewlet {
|
||||
config: any
|
||||
}
|
||||
|
||||
@Model(view.class.Action, core.class.Doc, DOMAIN_MODEL)
|
||||
export class TAction extends TDoc implements Action {
|
||||
label!: IntlString
|
||||
icon?: Asset
|
||||
action!: Resource<(doc: Doc) => Promise<void>>
|
||||
}
|
||||
|
||||
@Model(view.class.ActionTarget, core.class.Doc, DOMAIN_MODEL)
|
||||
export class TActionTarget extends TDoc implements ActionTarget {
|
||||
target!: Ref<Class<Doc>>
|
||||
action!: Ref<Action>
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(TAttributeEditor, TAttributePresenter, TKanbanCard, TObjectEditor, TViewletDescriptor, TViewlet)
|
||||
builder.createModel(TAttributeEditor, TAttributePresenter, TKanbanCard, TObjectEditor, TViewletDescriptor, TViewlet, TAction, TActionTarget)
|
||||
|
||||
builder.mixin(core.class.TypeString, core.class.Class, view.mixin.AttributeEditor, {
|
||||
editor: view.component.StringEditor
|
||||
@ -83,6 +96,17 @@ export function createModel (builder: Builder): void {
|
||||
icon: view.icon.Kanban,
|
||||
component: view.component.KanbanView
|
||||
}, view.viewlet.Kanban)
|
||||
|
||||
builder.createDoc(view.class.Action, core.space.Model, {
|
||||
label: 'Delete' as IntlString,
|
||||
icon: view.icon.Kanban,
|
||||
action: view.actionImpl.Delete
|
||||
}, view.action.Delete)
|
||||
|
||||
builder.createDoc(view.class.ActionTarget, core.space.Model, {
|
||||
target: core.class.Doc,
|
||||
action: view.action.Delete
|
||||
})
|
||||
}
|
||||
|
||||
export default view
|
||||
|
@ -14,10 +14,18 @@
|
||||
//
|
||||
|
||||
import { mergeIds } from '@anticrm/platform'
|
||||
import type { Ref, Doc } from '@anticrm/core'
|
||||
import type { Resource } from '@anticrm/platform'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
import view, { viewId } from '@anticrm/view'
|
||||
import view, { viewId, Action } from '@anticrm/view'
|
||||
|
||||
export default mergeIds(viewId, view, {
|
||||
action: {
|
||||
Delete: '' as Ref<Action>
|
||||
},
|
||||
actionImpl: {
|
||||
Delete: '' as Resource<(doc: Doc) => Promise<void>>
|
||||
},
|
||||
component: {
|
||||
StringEditor: '' as AnyComponent,
|
||||
StringPresenter: '' as AnyComponent,
|
||||
|
@ -14,34 +14,39 @@
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { IntlString, Asset } from '@anticrm/platform'
|
||||
import type { AnySvelteComponent } from '@anticrm/ui'
|
||||
import type { IntlString, Asset, Resource } from '@anticrm/platform'
|
||||
import { getResource } from '@anticrm/platform'
|
||||
import { getClient, createQuery } from '@anticrm/presentation'
|
||||
import type { Ref, Class, Doc } from '@anticrm/core'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { Icon, Label, IconMoreH, IconFile } from '@anticrm/ui'
|
||||
import type { Action, ActionTarget } from '@anticrm/view'
|
||||
import { getActions } from '../utils'
|
||||
import view from '@anticrm/view'
|
||||
|
||||
export let title: IntlString
|
||||
export let caption: IntlString
|
||||
export let object: Doc
|
||||
|
||||
let actions: Action[] = []
|
||||
|
||||
interface PopupItem {
|
||||
icon: Asset | AnySvelteComponent
|
||||
label: IntlString
|
||||
action?: () => Promise<void>
|
||||
}
|
||||
const client = getClient()
|
||||
|
||||
getActions(client, object._class).then(result => { actions = result })
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const actions: Array<PopupItem> = [{ icon: IconFile, label: 'Application', action: async () => {} },
|
||||
{ icon: IconMoreH, label: 'Options', action: async () => {} }]
|
||||
|
||||
async function invokeAction(action: Resource<(object: Doc) => Promise<void>>) {
|
||||
dispatch('close')
|
||||
const impl = await getResource(action)
|
||||
await impl(object)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="flex-col popup">
|
||||
{#each actions as action}
|
||||
<div class="flex-row-center menu-item" on:click={() => { dispatch('close') }}>
|
||||
<div class="flex-row-center menu-item" on:click={() => { invokeAction(action.action) }}>
|
||||
<div class="icon">
|
||||
{#if typeof (action.icon) === 'string'}
|
||||
<Icon icon={action.icon} size={'large'} />
|
||||
{:else}
|
||||
<svelte:component this={action.icon} size={'large'} />
|
||||
{/if}
|
||||
<Icon icon={action.icon} size={'large'} />
|
||||
</div>
|
||||
<div class="label"><Label label={action.label} /></div>
|
||||
</div>
|
||||
|
@ -58,11 +58,12 @@
|
||||
}
|
||||
return false
|
||||
}
|
||||
const showMenu = (ev: MouseEvent): void => {
|
||||
|
||||
const showMenu = (ev: MouseEvent, object: Doc): void => {
|
||||
const elRow: HTMLElement = findNode(ev.target as HTMLElement, 'tr-body')
|
||||
const elBtn: HTMLElement = findNode(ev.target as HTMLElement, 'menuRow')
|
||||
elRow.classList.add('fixed')
|
||||
showPopup(Menu, {}, elBtn, (() => {
|
||||
showPopup(Menu, { object }, elBtn, (() => {
|
||||
elRow.classList.remove('fixed')
|
||||
}))
|
||||
}
|
||||
@ -100,7 +101,7 @@
|
||||
<div class="firstCell">
|
||||
<div class="control">
|
||||
<CheckBox bind:checked={checking} />
|
||||
<div class="menuRow" on:click={(ev) => showMenu(ev)}><MoreV size={'small'} /></div>
|
||||
<div class="menuRow" on:click={(ev) => showMenu(ev, object)}><MoreV size={'small'} /></div>
|
||||
</div>
|
||||
<svelte:component this={attribute.presenter} value={getValue(object, attribute.key)}/>
|
||||
</div>
|
||||
|
@ -13,13 +13,25 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Doc } from '@anticrm/core'
|
||||
|
||||
import StringEditor from './components/StringEditor.svelte'
|
||||
import StringPresenter from './components/StringPresenter.svelte'
|
||||
import StatePresenter from './components/StatePresenter.svelte'
|
||||
import TableView from './components/TableView.svelte'
|
||||
import KanbanView from './components/KanbanView.svelte'
|
||||
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
|
||||
async function Delete(object: Doc): Promise<void> {
|
||||
const client = getClient()
|
||||
await client.removeDoc(object._class, object.space, object._id)
|
||||
}
|
||||
|
||||
export default async () => ({
|
||||
actionImpl: {
|
||||
Delete
|
||||
},
|
||||
component: {
|
||||
StringEditor,
|
||||
StringPresenter,
|
||||
|
@ -18,6 +18,7 @@ import type { IntlString } from '@anticrm/platform'
|
||||
import { getResource } from '@anticrm/platform'
|
||||
import type { Ref, Class, Obj, FindOptions, Doc, Client } from '@anticrm/core'
|
||||
import type { AnyComponent, AnySvelteComponent } from '@anticrm/ui'
|
||||
import type { Action, ActionTarget } from '@anticrm/view'
|
||||
|
||||
import view from '@anticrm/view'
|
||||
|
||||
@ -98,4 +99,19 @@ export async function buildModel(client: Client, _class: Ref<Class<Obj>>, keys:
|
||||
const model = keys.map(key => getPresenter(client, _class, key, key, options))
|
||||
console.log(model)
|
||||
return await Promise.all(model)
|
||||
}
|
||||
}
|
||||
|
||||
function filterActions(client: Client, _class: Ref<Class<Obj>>, targets: ActionTarget[]): Ref<Action>[] {
|
||||
const result: Ref<Action>[] = []
|
||||
for (const target of targets) {
|
||||
if (client.getHierarchy().isDerived(_class, target.target)) {
|
||||
result.push(target.action)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export async function getActions(client: Client, _class: Ref<Class<Obj>>) {
|
||||
const targets = await client.findAll(view.class.ActionTarget, {})
|
||||
return await client.findAll(view.class.Action, { _id: { $in: filterActions(client, _class, targets) }})
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Plugin, Asset } from '@anticrm/platform'
|
||||
import type { Plugin, Asset, Resource } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import type { Ref, Mixin, UXObject, Space, FindOptions, Class, Doc } from '@anticrm/core'
|
||||
|
||||
@ -66,6 +66,21 @@ export interface Viewlet extends Doc {
|
||||
config: any
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Action extends Doc, UXObject {
|
||||
action: Resource<(doc: Doc) => Promise<void>>
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ActionTarget extends Doc {
|
||||
target: Ref<Class<Doc>>
|
||||
action: Ref<Action>
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -80,7 +95,9 @@ export default plugin(viewId, {
|
||||
},
|
||||
class: {
|
||||
ViewletDescriptor: '' as Ref<Class<ViewletDescriptor>>,
|
||||
Viewlet: '' as Ref<Class<Viewlet>>
|
||||
Viewlet: '' as Ref<Class<Viewlet>>,
|
||||
Action: '' as Ref<Class<Action>>,
|
||||
ActionTarget: '' as Ref<Class<ActionTarget>>
|
||||
},
|
||||
viewlet: {
|
||||
Table: '' as Ref<ViewletDescriptor>,
|
||||
|
@ -37,8 +37,8 @@ export class FullTextIndex extends TxProcessor implements Storage {
|
||||
console.log('FullTextIndex.txPutBag: Method not implemented.')
|
||||
}
|
||||
|
||||
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
throw new Error('Method not implemented.')
|
||||
protected override async txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
console.log('FullTextIndex.txRemoveDoc: Method not implemented.')
|
||||
}
|
||||
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user