mirror of
https://github.com/hcengineering/platform.git
synced 2025-02-08 11:57:43 +00:00
![Anna No](/assets/img/avatar_default.png)
* Board: use standard actions Signed-off-by: Anna No <anna.no@xored.com> * Board: use standard actions Signed-off-by: Anna No <anna.no@xored.com> * fix lint issues Signed-off-by: Anna No <anna.no@xored.com> * fix lint issues Signed-off-by: Anna No <anna.no@xored.com> * fix merge conflicts Signed-off-by: Anna No <anna.no@xored.com> * fix merge conflicts Signed-off-by: Anna No <anna.no@xored.com>
143 lines
4.4 KiB
TypeScript
143 lines
4.4 KiB
TypeScript
//
|
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
|
// Copyright © 2022 Hardcore Engineering Inc.
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
import type { Doc, WithLookup } from '@anticrm/core'
|
|
import core, { Class, Client, matchQuery, Ref } from '@anticrm/core'
|
|
import { getResource } from '@anticrm/platform'
|
|
import type { Action, ViewAction, ViewActionInput, ViewContextType } from '@anticrm/view'
|
|
import view from './plugin'
|
|
import { FocusSelection } from './selection'
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export function getSelection (focusStore: FocusSelection, selectionStore: Doc[]): Doc[] {
|
|
let docs: Doc[] = []
|
|
if (selectionStore.find((it) => it._id === focusStore.focus?._id) === undefined && focusStore.focus !== undefined) {
|
|
docs = [focusStore.focus]
|
|
} else {
|
|
docs = selectionStore
|
|
}
|
|
return docs
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*
|
|
* Find all action contributions applicable for specified _class.
|
|
* If derivedFrom is specifie, only actions applicable to derivedFrom class will be used.
|
|
* So if we have contribution for Doc, Space and we ask for SpaceWithStates and derivedFrom=Space,
|
|
* we won't recieve Doc contribution but recieve Space ones.
|
|
*/
|
|
export async function getActions (
|
|
client: Client,
|
|
doc: Doc | Doc[],
|
|
derived: Ref<Class<Doc>> = core.class.Doc,
|
|
mode: ViewContextType = 'context'
|
|
): Promise<Action[]> {
|
|
const actions: Action[] = await client.findAll(view.class.Action, {
|
|
'context.mode': mode
|
|
})
|
|
|
|
const categories: Record<string, number> = { top: 1, filter: 50, tools: 100 }
|
|
|
|
let filteredActions = actions
|
|
|
|
if (Array.isArray(doc)) {
|
|
for (const d of doc) {
|
|
filteredActions = filterActions(client, d, filteredActions, derived)
|
|
}
|
|
} else {
|
|
filteredActions = filterActions(client, doc, filteredActions, derived)
|
|
}
|
|
const inputVal: ViewActionInput[] = ['none']
|
|
if (!Array.isArray(doc) || doc.length === 1) {
|
|
inputVal.push('focus')
|
|
inputVal.push('any')
|
|
}
|
|
if (Array.isArray(doc) && doc.length > 0) {
|
|
inputVal.push('selection')
|
|
inputVal.push('any')
|
|
}
|
|
filteredActions = filteredActions.filter((it) => inputVal.includes(it.input))
|
|
filteredActions.sort((a, b) => {
|
|
const aTarget = categories[a.context.group ?? 'top'] ?? 0
|
|
const bTarget = categories[b.context.group ?? 'top'] ?? 0
|
|
return aTarget - bTarget
|
|
})
|
|
return filteredActions
|
|
}
|
|
|
|
export async function invokeAction (
|
|
object: Doc | Doc[],
|
|
evt: Event,
|
|
action: ViewAction,
|
|
props?: Record<string, any>
|
|
): Promise<void> {
|
|
const impl = await getResource(action)
|
|
await impl(Array.isArray(object) && object.length === 1 ? object[0] : object, evt, props)
|
|
}
|
|
|
|
export async function getContextActions (
|
|
client: Client,
|
|
doc: Doc | Doc[],
|
|
context: {
|
|
mode: ViewContextType
|
|
application?: Ref<Doc>
|
|
}
|
|
): Promise<Action[]> {
|
|
const result = await getActions(client, doc, undefined, context.mode)
|
|
|
|
if (context.application !== undefined) {
|
|
return result.filter((it) => it.context.application === context.application || it.context.application === undefined)
|
|
}
|
|
return result
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export function filterActions (
|
|
client: Client,
|
|
doc: Doc,
|
|
actions: Array<WithLookup<Action>>,
|
|
derived: Ref<Class<Doc>> = core.class.Doc
|
|
): Array<WithLookup<Action>> {
|
|
const result: Array<WithLookup<Action>> = []
|
|
const hierarchy = client.getHierarchy()
|
|
const clazz = hierarchy.getClass(doc._class)
|
|
const ignoreActions = hierarchy.as(clazz, view.mixin.IgnoreActions)
|
|
const ignore = ignoreActions?.actions ?? []
|
|
for (const action of actions) {
|
|
if (ignore.includes(action._id)) {
|
|
continue
|
|
}
|
|
if (action.query !== undefined) {
|
|
const r = matchQuery([doc], action.query, doc._class, hierarchy)
|
|
if (r.length === 0) {
|
|
continue
|
|
}
|
|
}
|
|
if (
|
|
(hierarchy.isDerived(doc._class, action.target) && client.getHierarchy().isDerived(action.target, derived)) ||
|
|
(hierarchy.isMixin(action.target) && hierarchy.hasMixin(doc, action.target))
|
|
) {
|
|
result.push(action)
|
|
}
|
|
}
|
|
return result
|
|
}
|