// @flow import { flattenDeep } from "lodash"; import * as React from "react"; import { v4 as uuidv4 } from "uuid"; import type { Action, ActionContext, CommandBarAction, MenuItemClickable, MenuItemWithChildren, } from "types"; export function createAction( definition: $Diff ): Action { return { id: uuidv4(), ...definition, }; } export function actionToMenuItem( action: Action, context: ActionContext ): MenuItemClickable | MenuItemWithChildren { function resolve(value: any): T { if (typeof value === "function") { return value(context); } return value; } const resolvedIcon = resolve>(action.icon); const resolvedChildren = resolve(action.children); const visible = action.visible ? action.visible(context) : true; const title = resolve(action.name); const icon = resolvedIcon && action.iconInContextMenu !== false ? React.cloneElement(resolvedIcon, { color: "currentColor" }) : undefined; if (resolvedChildren) { return { title, icon, items: resolvedChildren .map((a) => actionToMenuItem(a, context)) .filter((a) => !!a), visible, }; } return { title, icon, visible, onClick: () => action.perform && action.perform(context), selected: action.selected ? action.selected(context) : undefined, }; } export function actionToKBar( action: Action, context: ActionContext ): CommandBarAction[] { function resolve(value: any): T { if (typeof value === "function") { return value(context); } return value; } if (typeof action.visible === "function" && !action.visible(context)) { return []; } const resolvedIcon = resolve>(action.icon); const resolvedChildren = resolve(action.children); const resolvedSection = resolve(action.section); const resolvedName = resolve(action.name); const resolvedPlaceholder = resolve(action.placeholder); const children = resolvedChildren ? flattenDeep(resolvedChildren.map((a) => actionToKBar(a, context))).filter( (a) => !!a ) : []; return [ { id: action.id, name: resolvedName, section: resolvedSection, placeholder: resolvedPlaceholder, keywords: `${action.keywords || ""} ${children .filter((c) => !!c.keywords) .map((c) => c.keywords) .join(" ")}`, shortcut: action.shortcut, icon: resolvedIcon ? React.cloneElement(resolvedIcon, { color: "currentColor" }) : undefined, perform: action.perform ? () => action.perform && action.perform(context) : undefined, children: children.length ? children.map((a) => a.id) : undefined, }, ].concat( children.map((child) => ({ ...child, parent: action.id, })) ); }