diff --git a/packages/presentation/src/components/InlineAttributeBarEditor.svelte b/packages/presentation/src/components/InlineAttributeBarEditor.svelte index b4b2cc0126..e727a08f5a 100644 --- a/packages/presentation/src/components/InlineAttributeBarEditor.svelte +++ b/packages/presentation/src/components/InlineAttributeBarEditor.svelte @@ -35,7 +35,12 @@ let editor: Promise | undefined - function onChange (value: any) { + $: attribute = typeof key === 'string' ? hierarchy.getAttribute(_class, key) : key.attr + $: attributeKey = typeof key === 'string' ? key : key.key + $: editor = getAttributeEditor(client, _class, key) + $: isReadonly = (attribute.readonly ?? false) || readonly + + function onChange (value: any): void { const doc = object as Doc if (draft) { ;(doc as any)[attributeKey] = value @@ -44,11 +49,6 @@ updateAttribute(client, doc, _class, { key: attributeKey, attr: attribute }, value) } } - - $: attribute = typeof key === 'string' ? hierarchy.getAttribute(_class, key) : key.attr - $: attributeKey = typeof key === 'string' ? key : key.key - $: editor = getAttributeEditor(client, _class, key) - $: isReadonly = (attribute.readonly ?? false) || readonly {#if editor} diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts index e9a27d3736..214962e94c 100644 --- a/plugins/view/src/index.ts +++ b/plugins/view/src/index.ts @@ -14,773 +14,60 @@ // limitations under the License. // +import { Class, Doc, DocumentQuery, FindOptions, Mixin, Ref } from '@hcengineering/core' +import { Asset, IntlString, Plugin, Resource, plugin } from '@hcengineering/platform' +import { AnyComponent, PopupAlignment, PopupPosAlignment } from '@hcengineering/ui' import { - Account, - AggregateValue, - AnyAttribute, - Attribute, - CategoryType, - Class, - Client, - Doc, - DocumentQuery, - FindOptions, - Hierarchy, - Lookup, - Mixin, - Obj, - ObjQueryType, - PrimitiveType, - Ref, - SortingOrder, - Space, - Tx, - TxOperations, - Type, - UXObject, - WithLookup -} from '@hcengineering/core' -import { Asset, IntlString, Plugin, Resource, Status, plugin } from '@hcengineering/platform' -import { Preference } from '@hcengineering/preference' -import { - AnyComponent, - AnySvelteComponent, - Location, - Location as PlatformLocation, - PopupAlignment, - PopupPosAlignment -} from '@hcengineering/ui' - -/** - * @public - */ -export interface KeyFilterPreset { - _class: Ref> - key: string - attribute?: AnyAttribute - component: AnyComponent - label?: IntlString - group?: 'top' | 'bottom' - showNested?: boolean -} - -/** - * @public - */ -export interface KeyFilter extends KeyFilterPreset { - attribute: AnyAttribute - component: AnyComponent - label: IntlString - group?: 'top' | 'bottom' -} - -/** - * @public - */ -export interface FilterMode extends Doc { - label: IntlString - selectedLabel?: IntlString - disableValueSelector?: boolean - result: FilterFunction -} - -/** - * @public - */ -export type FilterFunction = Resource<(filter: Filter, onUpdate: () => void) => Promise>> - -/** - * @public - */ -export interface Filter { - key: KeyFilter - nested?: Filter - mode: Ref - modes: Ref[] - value: any[] - props?: Record - index: number - onRemove?: () => void -} - -/** - * @public - */ -export interface FilteredView extends Doc { - name: string - location: PlatformLocation - filters: string - viewOptions?: ViewOptions - filterClass?: Ref> - viewletId?: Ref | null - sharable?: boolean - users: Ref[] - createdBy: Ref - attachedTo: string -} - -/** - * @public - */ -export interface ClassFilters extends Class { - filters: (KeyFilterPreset | string)[] - ignoreKeys?: string[] - - // Ignore attributes not specified in the "filters" array - strict?: boolean - // Allows to filter out the provided keys, leaving only the necessary ones - getVisibleFilters?: Resource<(filters: KeyFilter[], space?: Ref) => Promise> -} - -/** - * @public - */ -export interface AttributeFilter extends Class> { - component: AnyComponent - group?: 'top' | 'bottom' -} - -/** - * @public - */ -export interface AttributeEditor extends Class { - inlineEditor: AnyComponent - // If defined could be used for ShowEditor declarative actions. - popup?: AnyComponent -} - -/** - * @public - */ -export interface CollectionEditor extends Class { - editor: AnyComponent - inlineEditor?: AnyComponent -} - -/** - * @public - */ -export interface InlineAttributEditor extends Class { - editor: AnyComponent -} - -/** - * @public - */ -export interface ArrayEditor extends Class { - editor?: AnyComponent - inlineEditor?: AnyComponent -} - -/** - * @public - */ -export interface CollectionPresenter extends Class { - presenter: AnyComponent -} - -/** - * @public - */ -export interface AttributePresenter extends Class { - presenter: AnyComponent -} - -/** - * @public - */ -export interface AttributeFilterPresenter extends Class { - presenter: AnyComponent -} - -/** - * @public - */ -export interface ActivityAttributePresenter extends Class { - presenter: AnyComponent -} - -/** - * @public - */ -export interface SpacePresenter extends Class { - presenter: AnyComponent -} - -/** - * @public - */ -export interface ObjectPresenter extends Class { - presenter: AnyComponent -} - -/** - * @public - */ -export interface ListItemPresenter extends Class { - presenter: AnyComponent -} - -/** - * @public - */ -export interface ObjectEditor extends Class { - editor: AnyComponent - pinned?: boolean -} - -/** - * @public - */ -export interface ObjectEditorFooter extends Class { - editor: AnyComponent - props?: Record -} - -/** - * @public - */ -export interface SpaceHeader extends Class { - header: AnyComponent -} - -/** - * @public - */ -export interface SpaceName extends Class { - getName: Resource<(client: Client, space: Space) => Promise> -} - -/** - * @public - */ -export interface ObjectEditorHeader extends Class { - editor: AnyComponent -} - -/** - * @public - */ -export interface ObjectValidator extends Class { - validator: Resource<(doc: T, client: Client) => Promise> -} - -/** - * @public - */ -export interface ObjectTitle extends Class { - titleProvider: Resource<(client: Client, ref: Ref, doc?: T) => Promise> -} - -/** - * @public - */ -export interface ObjectIcon extends Class { - component: AnyComponent -} - -/** - * @public - */ -export interface ObjectIdentifier extends Class { - provider: Resource<(client: Client, ref: Ref, doc?: T) => Promise> -} - -/** - * @public - */ -export interface ViewletDescriptor extends Doc, UXObject { - component: AnyComponent -} - -/** - * @public - */ -export interface ListHeaderExtra extends Class { - presenters: AnyComponent[] -} - -/** - * @public - */ -export type SortFunc = Resource< -( - client: TxOperations, - values: PrimitiveType[], - space: Ref | undefined, - viewletDescriptorId?: Ref -) => Promise -> - -/** - * @public - */ -export interface ClassSortFuncs extends Class { - func: SortFunc -} - -/** - * @public - */ -export type GetAllValuesFunc = Resource< -( - query: DocumentQuery | undefined, - onUpdate: () => void, - queryId: Ref, - attr: AnyAttribute -) => Promise -> - -/** - * @public - */ -export interface AllValuesFunc extends Class { - func: GetAllValuesFunc -} - -/** - * @public - */ -export interface GrouppingManager { - groupByCategories: (categories: any[]) => AggregateValue[] - groupValues: (val: Doc[], targets: Set) => Doc[] - groupValuesWithEmpty: ( - hierarchy: Hierarchy, - _class: Ref>, - key: string, - query: DocumentQuery | undefined - ) => Array> - hasValue: (value: Doc | undefined | null, values: any[]) => boolean -} - -/** - * @public - */ -export type GrouppingManagerResource = Resource - -/** - * @public - */ -export interface Groupping extends Class { - grouppingManager: GrouppingManagerResource -} - -/** - * @public - */ -export interface AggregationManager { - close: () => void - notifyTx: (tx: Tx) => Promise - updateLookup: (resultDoc: WithLookup, attr: Attribute) => Promise - categorize: (target: Array>, attr: AnyAttribute) => Promise>> - getAttrClass: () => Ref> - updateSorting?: (finalOptions: FindOptions, attr: AnyAttribute) => Promise -} - -/** - * @public - */ -export type AggregationManagerResource = Resource - -/** - * @public - */ -export type CreateAggregationManagerFunc = Resource<(client: Client, lqCallback: () => void) => AggregationManager> - -/** - * @public - */ -export interface Aggregation extends Class { - createAggregationManager: CreateAggregationManagerFunc -} - -/** - * @public - */ -export interface Viewlet extends Doc { - attachTo: Ref> - baseQuery?: DocumentQuery - descriptor: Ref - options?: FindOptions - config: (BuildModelKey | string)[] - configOptions?: ViewletConfigOptions - viewOptions?: ViewOptionsModel - variant?: string -} - -/** - * @public - */ -export interface ViewletConfigOptions { - hiddenKeys?: string[] - strict?: boolean - extraProps?: Omit - sortable?: boolean -} - -/** - * @public - */ -export interface LinkPresenter extends Doc { - pattern: string - component: AnyComponent -} - -/** - * @public - * - * "Alt + K" =\> Alt and K should be pressed together - * "J T" - J and then T shold be pressed. - */ -export type KeyBinding = string - -/** - * @public - */ -export type ViewActionInput = 'focus' | 'selection' | 'any' | 'none' - -/** - * @public - */ - -export type ViewActionFunction> = ( - doc: T | T[] | undefined, - evt?: Event, - params?: P -) => Promise - -/** - * @public - */ -export type ViewActionAvailabilityFunction = (doc: T | T[] | undefined) => Promise - -/** - * @public - */ -export type ViewAction

> = Resource> - -/** - * @public - */ -export interface ActionCategory extends Doc, UXObject { - // Does category is visible for use in popup. - visible: boolean -} - -/** - * @public - */ -export type ActionGroup = 'create' | 'edit' | 'associate' | 'copy' | 'tools' | 'other' | 'remove' - -/** - * @public - */ -export interface Action> extends Doc, UXObject { - // Action implementation details - action: Resource> - // Action implementation parameters - actionProps?: P - - // If specified, will show sub menu based on actionPopup/actionProps - actionPopup?: AnyComponent - - // If specified, action could be used only with one item selected. - // single - one object is required - // any - one or multiple objects are required - // any - any input is suitable. - input: ViewActionInput - inline?: boolean - - // Focus and/or all selection document should match target class. - target: Ref> - // Action is applicable only for objects matching criteria - query?: DocumentQuery - - // Action is shown only if the check is passed - visibilityTester?: Resource> - - // If defined, types should be matched to proposed list - inputProps?: Record>> - - // Kayboard bindings - keyBinding?: KeyBinding[] - - // short description for action. - description?: IntlString - - // Action category, for UI. - category: Ref - - // Context action is defined for - context: ViewContext - - // A list of actions replaced by this one. - // For example, it could be global action and action for focus class, second one fill override first one. - override?: Ref[] - - // Avaible only for workspace owners - secured?: boolean - allowedForEditableContent?: boolean -} - -/** - * @public - * context - only for context menu actions. - * workbench - global actions per application or entire workbench. - * browser - actions for list/table/kanban browsing. - * editor - actions for selected editor context. - * panel - for panel based actions. - * popup - for popup based actions, like Close of Popup. - * input - for input based actions, some actions should be available for input controls. - */ -export type ViewContextType = 'context' | 'workbench' | 'browser' | 'editor' | 'panel' | 'popup' | 'input' | 'none' - -/** - * @public - */ -export interface ViewContext { - mode: ViewContextType | ViewContextType[] - // Active application - application?: Ref - - // Optional groupping - group?: ActionGroup -} - -/** - * @public - */ -export interface ActionIgnore { - _class: Ref> - // Action to be ignored - action: Ref - // Document match to ignore if matching at least one document. - query: DocumentQuery -} - -/** - * @public - */ -export interface IgnoreActions extends Class { - actions: (Ref | ActionIgnore)[] -} - -/** - * @public - */ -export interface PreviewPresenter extends Class { - presenter: AnyComponent -} + Action, + ActionCategory, + ActivityAttributePresenter, + Aggregation, + AllValuesFunc, + ArrayEditor, + AttributeEditor, + AttributeFilter, + AttributeFilterPresenter, + AttributePresenter, + ClassFilters, + ClassSortFuncs, + CollectionEditor, + CollectionPresenter, + FilteredView, + FilterMode, + Groupping, + IgnoreActions, + InlineAttributEditor, + LinkPresenter, + LinkProvider, + ListHeaderExtra, + ListItemPresenter, + ObjectEditor, + ObjectEditorFooter, + ObjectEditorHeader, + ObjectFactory, + ObjectIcon, + ObjectIdentifier, + ObjectPanel, + ObjectPresenter, + ObjectTitle, + ObjectValidator, + PreviewPresenter, + SpaceHeader, + SpaceName, + SpacePresenter, + ViewAction, + Viewlet, + ViewletDescriptor, + ViewletPreference +} from './types' + +export * from './types' /** * @public */ export const viewId = 'view' as Plugin -/** - * @public - */ -export interface DisplayProps { - key?: string - excludeByKey?: string - fixed?: 'left' | 'right' // using for align items in row - align?: 'left' | 'right' | 'center' - suffix?: boolean - optional?: boolean - compression?: boolean - grow?: boolean - dividerBefore?: boolean // should show divider before -} - -/** - * @public - */ -export interface BuildModelKey { - key: string - presenter?: AnyComponent | AnySvelteComponent - // A set of extra props passed to presenter. - props?: Record - // A set of extra props which using for display. - displayProps?: DisplayProps - - label?: IntlString - sortingKey?: string | string[] - - // On client sorting function - sortingFunction?: (a: Doc, b: Doc) => number -} - -/** - * @public - */ -export interface AttributeModel { - key: string - label: IntlString - _class: Ref> - presenter: AnySvelteComponent - // Extra properties for component - props?: Record - displayProps?: DisplayProps - sortingKey: string | string[] - // Extra icon if applicable - icon?: Asset - - attribute?: AnyAttribute - collectionAttr: boolean - isLookup: boolean - - castRequest?: Ref> -} - -/** - * @public - */ -export interface BuildModelOptions { - client: Client - _class: Ref> - keys: (BuildModelKey | string)[] - lookup?: Lookup - ignoreMissing?: boolean -} - -/** - * Define document create popup widget - * - * @public - * - */ -export interface ObjectFactory extends Class { - component?: AnyComponent - create?: Resource<(props?: Record) => Promise> -} - -/** - * @public - */ -export interface ViewletPreference extends Preference { - attachedTo: Ref - config: (BuildModelKey | string)[] -} - -/** - * @public - */ -export type ViewOptions = { - groupBy: string[] - orderBy: OrderOption -} & Record - -/** - * @public - */ -export interface ViewOption { - type: string - key: string - defaultValue: any - label: IntlString - hidden?: (viewOptions: ViewOptions) => boolean - actionTarget?: 'query' | 'category' | 'display' - action?: Resource<(value: any, ...params: any) => any> -} -/** - * @public - */ -export type ViewCategoryActionFunc = ( - _class: Ref>, - query: DocumentQuery | undefined, - space: Ref | undefined, - key: string, - onUpdate: () => void, - queryId: Ref, - viewletDescriptorId?: Ref -) => Promise -/** - * @public - */ -export type ViewCategoryAction = Resource - -/** - * @public - */ -export interface CategoryOption extends ViewOption { - actionTarget: 'category' - action: ViewCategoryAction -} - -/** - * @public - */ -export type ViewQueryAction = Resource< -(value: any, query: DocumentQuery) => DocumentQuery | Promise> -> - -/** - * @public - */ -export interface ViewQueryOption extends ViewOption { - actionTarget: 'query' - action: ViewQueryAction -} - -/** - * @public - */ -export interface ToggleViewOption extends ViewOption { - type: 'toggle' - defaultValue: boolean -} - -/** - * @public - */ -export interface DropdownViewOption extends ViewOption { - type: 'dropdown' - defaultValue: string - values: Array<{ label: IntlString, id: string, hidden?: (viewOptions: ViewOptions) => boolean }> -} - -/** - * @public - */ -export type ViewOptionModel = ToggleViewOption | DropdownViewOption - -/** - * @public - */ -export type OrderOption = [string, SortingOrder] - -/** - * @public - */ -export interface LinkProvider extends Class { - encode: Resource<(doc: Doc, props: Record) => Promise> -} - -/** - * @public - */ -export interface ObjectPanel extends Class { - component: AnyComponent -} - -/** - * @public - */ -export interface ViewOptionsModel { - groupBy: string[] - orderBy: OrderOption[] - other: ViewOptionModel[] - groupDepth?: number -} - -/** - * @public - */ -export interface IconProps { - icon?: Asset - color?: number -} - /** * @public */ diff --git a/plugins/view/src/types.ts b/plugins/view/src/types.ts new file mode 100644 index 0000000000..43a47f2ae4 --- /dev/null +++ b/plugins/view/src/types.ts @@ -0,0 +1,770 @@ +// +// Copyright © 2020, 2021 Anticrm Platform Contributors. +// Copyright © 2021, 2024 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 { + Account, + AggregateValue, + AnyAttribute, + Attribute, + CategoryType, + Class, + Client, + Doc, + DocumentQuery, + FindOptions, + Hierarchy, + Lookup, + Mixin, + Obj, + ObjQueryType, + PrimitiveType, + Ref, + SortingOrder, + Space, + Tx, + TxOperations, + Type, + UXObject, + WithLookup +} from '@hcengineering/core' +import { AnyComponent, AnySvelteComponent, Location, Location as PlatformLocation } from '@hcengineering/ui' +import { Asset, IntlString, Resource, Status } from '@hcengineering/platform' +import { Preference } from '@hcengineering/preference' + +/** + * @public + */ +export interface KeyFilterPreset { + _class: Ref> + key: string + attribute?: AnyAttribute + component: AnyComponent + label?: IntlString + group?: 'top' | 'bottom' + showNested?: boolean +} + +/** + * @public + */ +export interface KeyFilter extends KeyFilterPreset { + attribute: AnyAttribute + component: AnyComponent + label: IntlString + group?: 'top' | 'bottom' +} + +/** + * @public + */ +export interface FilterMode extends Doc { + label: IntlString + selectedLabel?: IntlString + disableValueSelector?: boolean + result: FilterFunction +} + +/** + * @public + */ +export type FilterFunction = Resource<(filter: Filter, onUpdate: () => void) => Promise>> + +/** + * @public + */ +export interface Filter { + key: KeyFilter + nested?: Filter + mode: Ref + modes: Ref[] + value: any[] + props?: Record + index: number + onRemove?: () => void +} + +/** + * @public + */ +export interface FilteredView extends Doc { + name: string + location: PlatformLocation + filters: string + viewOptions?: ViewOptions + filterClass?: Ref> + viewletId?: Ref | null + sharable?: boolean + users: Ref[] + createdBy: Ref + attachedTo: string +} + +/** + * @public + */ +export interface ClassFilters extends Class { + filters: (KeyFilterPreset | string)[] + ignoreKeys?: string[] + + // Ignore attributes not specified in the "filters" array + strict?: boolean + // Allows to filter out the provided keys, leaving only the necessary ones + getVisibleFilters?: Resource<(filters: KeyFilter[], space?: Ref) => Promise> +} + +/** + * @public + */ +export interface AttributeFilter extends Class> { + component: AnyComponent + group?: 'top' | 'bottom' +} + +/** + * @public + */ +export interface AttributeEditor extends Class { + inlineEditor: AnyComponent + // If defined could be used for ShowEditor declarative actions. + popup?: AnyComponent +} + +/** + * @public + */ +export interface CollectionEditor extends Class { + editor: AnyComponent + inlineEditor?: AnyComponent +} + +/** + * @public + */ +export interface InlineAttributEditor extends Class { + editor: AnyComponent +} + +/** + * @public + */ +export interface ArrayEditor extends Class { + editor?: AnyComponent + inlineEditor?: AnyComponent +} + +/** + * @public + */ +export interface CollectionPresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface AttributePresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface AttributeFilterPresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface ActivityAttributePresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface SpacePresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface ObjectPresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface ListItemPresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface ObjectEditor extends Class { + editor: AnyComponent + pinned?: boolean +} + +/** + * @public + */ +export interface ObjectEditorFooter extends Class { + editor: AnyComponent + props?: Record +} + +/** + * @public + */ +export interface SpaceHeader extends Class { + header: AnyComponent +} + +/** + * @public + */ +export interface SpaceName extends Class { + getName: Resource<(client: Client, space: Space) => Promise> +} + +/** + * @public + */ +export interface ObjectEditorHeader extends Class { + editor: AnyComponent +} + +/** + * @public + */ +export interface ObjectValidator extends Class { + validator: Resource<(doc: T, client: Client) => Promise> +} + +/** + * @public + */ +export interface ObjectTitle extends Class { + titleProvider: Resource<(client: Client, ref: Ref, doc?: T) => Promise> +} + +/** + * @public + */ +export interface ObjectIcon extends Class { + component: AnyComponent +} + +/** + * @public + */ +export interface ObjectIdentifier extends Class { + provider: Resource<(client: Client, ref: Ref, doc?: T) => Promise> +} + +/** + * @public + */ +export interface ViewletDescriptor extends Doc, UXObject { + component: AnyComponent +} + +/** + * @public + */ +export interface ListHeaderExtra extends Class { + presenters: AnyComponent[] +} + +/** + * @public + */ +export type SortFunc = Resource< +( + client: TxOperations, + values: PrimitiveType[], + space: Ref | undefined, + viewletDescriptorId?: Ref +) => Promise +> + +/** + * @public + */ +export interface ClassSortFuncs extends Class { + func: SortFunc +} + +/** + * @public + */ +export type GetAllValuesFunc = Resource< +( + query: DocumentQuery | undefined, + onUpdate: () => void, + queryId: Ref, + attr: AnyAttribute +) => Promise +> + +/** + * @public + */ +export interface AllValuesFunc extends Class { + func: GetAllValuesFunc +} + +/** + * @public + */ +export interface GrouppingManager { + groupByCategories: (categories: any[]) => AggregateValue[] + groupValues: (val: Doc[], targets: Set) => Doc[] + groupValuesWithEmpty: ( + hierarchy: Hierarchy, + _class: Ref>, + key: string, + query: DocumentQuery | undefined + ) => Array> + hasValue: (value: Doc | undefined | null, values: any[]) => boolean +} + +/** + * @public + */ +export type GrouppingManagerResource = Resource + +/** + * @public + */ +export interface Groupping extends Class { + grouppingManager: GrouppingManagerResource +} + +/** + * @public + */ +export interface AggregationManager { + close: () => void + notifyTx: (tx: Tx) => Promise + updateLookup: (resultDoc: WithLookup, attr: Attribute) => Promise + categorize: (target: Array>, attr: AnyAttribute) => Promise>> + getAttrClass: () => Ref> + updateSorting?: (finalOptions: FindOptions, attr: AnyAttribute) => Promise +} + +/** + * @public + */ +export type AggregationManagerResource = Resource + +/** + * @public + */ +export type CreateAggregationManagerFunc = Resource<(client: Client, lqCallback: () => void) => AggregationManager> + +/** + * @public + */ +export interface Aggregation extends Class { + createAggregationManager: CreateAggregationManagerFunc +} + +/** + * @public + */ +export interface Viewlet extends Doc { + attachTo: Ref> + baseQuery?: DocumentQuery + descriptor: Ref + options?: FindOptions + config: (BuildModelKey | string)[] + configOptions?: ViewletConfigOptions + viewOptions?: ViewOptionsModel + variant?: string +} + +/** + * @public + */ +export interface ViewletConfigOptions { + hiddenKeys?: string[] + strict?: boolean + extraProps?: Omit + sortable?: boolean +} + +/** + * @public + */ +export interface LinkPresenter extends Doc { + pattern: string + component: AnyComponent +} + +/** + * @public + * + * "Alt + K" =\> Alt and K should be pressed together + * "J T" - J and then T shold be pressed. + */ +export type KeyBinding = string + +/** + * @public + */ +export type ViewActionInput = 'focus' | 'selection' | 'any' | 'none' + +/** + * @public + */ + +export type ViewActionFunction> = ( + doc: T | T[] | undefined, + evt?: Event, + params?: P +) => Promise + +/** + * @public + */ +export type ViewActionAvailabilityFunction = (doc: T | T[] | undefined) => Promise + +/** + * @public + */ +export type ViewAction

> = Resource> + +/** + * @public + */ +export interface ActionCategory extends Doc, UXObject { + // Does category is visible for use in popup. + visible: boolean +} + +/** + * @public + */ +export type ActionGroup = 'create' | 'edit' | 'associate' | 'copy' | 'tools' | 'other' | 'remove' + +/** + * @public + */ +export interface Action> extends Doc, UXObject { + // Action implementation details + action: Resource> + // Action implementation parameters + actionProps?: P + + // If specified, will show sub menu based on actionPopup/actionProps + actionPopup?: AnyComponent + + // If specified, action could be used only with one item selected. + // single - one object is required + // any - one or multiple objects are required + // any - any input is suitable. + input: ViewActionInput + inline?: boolean + + // Focus and/or all selection document should match target class. + target: Ref> + // Action is applicable only for objects matching criteria + query?: DocumentQuery + + // Action is shown only if the check is passed + visibilityTester?: Resource> + + // If defined, types should be matched to proposed list + inputProps?: Record>> + + // Kayboard bindings + keyBinding?: KeyBinding[] + + // short description for action. + description?: IntlString + + // Action category, for UI. + category: Ref + + // Context action is defined for + context: ViewContext + + // A list of actions replaced by this one. + // For example, it could be global action and action for focus class, second one fill override first one. + override?: Ref[] + + // Avaible only for workspace owners + secured?: boolean + allowedForEditableContent?: boolean +} + +/** + * @public + * context - only for context menu actions. + * workbench - global actions per application or entire workbench. + * browser - actions for list/table/kanban browsing. + * editor - actions for selected editor context. + * panel - for panel based actions. + * popup - for popup based actions, like Close of Popup. + * input - for input based actions, some actions should be available for input controls. + */ +export type ViewContextType = 'context' | 'workbench' | 'browser' | 'editor' | 'panel' | 'popup' | 'input' | 'none' + +/** + * @public + */ +export interface ViewContext { + mode: ViewContextType | ViewContextType[] + // Active application + application?: Ref + + // Optional groupping + group?: ActionGroup +} + +/** + * @public + */ +export interface ActionIgnore { + _class: Ref> + // Action to be ignored + action: Ref + // Document match to ignore if matching at least one document. + query: DocumentQuery +} + +/** + * @public + */ +export interface IgnoreActions extends Class { + actions: (Ref | ActionIgnore)[] +} + +/** + * @public + */ +export interface PreviewPresenter extends Class { + presenter: AnyComponent +} + +/** + * @public + */ +export interface DisplayProps { + key?: string + excludeByKey?: string + fixed?: 'left' | 'right' // using for align items in row + align?: 'left' | 'right' | 'center' + suffix?: boolean + optional?: boolean + compression?: boolean + grow?: boolean + dividerBefore?: boolean // should show divider before +} + +/** + * @public + */ +export interface BuildModelKey { + key: string + presenter?: AnyComponent | AnySvelteComponent + // A set of extra props passed to presenter. + props?: Record + // A set of extra props which using for display. + displayProps?: DisplayProps + + label?: IntlString + sortingKey?: string | string[] + + // On client sorting function + sortingFunction?: (a: Doc, b: Doc) => number +} + +/** + * @public + */ +export interface AttributeModel { + key: string + label: IntlString + _class: Ref> + presenter: AnySvelteComponent + // Extra properties for component + props?: Record + displayProps?: DisplayProps + sortingKey: string | string[] + // Extra icon if applicable + icon?: Asset + + attribute?: AnyAttribute + collectionAttr: boolean + isLookup: boolean + + castRequest?: Ref> +} + +/** + * @public + */ +export interface BuildModelOptions { + client: Client + _class: Ref> + keys: (BuildModelKey | string)[] + lookup?: Lookup + ignoreMissing?: boolean +} + +/** + * Define document create popup widget + * + * @public + * + */ +export interface ObjectFactory extends Class { + component?: AnyComponent + create?: Resource<(props?: Record) => Promise> +} + +/** + * @public + */ +export interface ViewletPreference extends Preference { + attachedTo: Ref + config: (BuildModelKey | string)[] +} + +/** + * @public + */ +export type ViewOptions = { + groupBy: string[] + orderBy: OrderOption +} & Record + +/** + * @public + */ +export interface ViewOption { + type: string + key: string + defaultValue: any + label: IntlString + hidden?: (viewOptions: ViewOptions) => boolean + actionTarget?: 'query' | 'category' | 'display' + action?: Resource<(value: any, ...params: any) => any> +} +/** + * @public + */ +export type ViewCategoryActionFunc = ( + _class: Ref>, + query: DocumentQuery | undefined, + space: Ref | undefined, + key: string, + onUpdate: () => void, + queryId: Ref, + viewletDescriptorId?: Ref +) => Promise +/** + * @public + */ +export type ViewCategoryAction = Resource + +/** + * @public + */ +export interface CategoryOption extends ViewOption { + actionTarget: 'category' + action: ViewCategoryAction +} + +/** + * @public + */ +export type ViewQueryAction = Resource< +(value: any, query: DocumentQuery) => DocumentQuery | Promise> +> + +/** + * @public + */ +export interface ViewQueryOption extends ViewOption { + actionTarget: 'query' + action: ViewQueryAction +} + +/** + * @public + */ +export interface ToggleViewOption extends ViewOption { + type: 'toggle' + defaultValue: boolean +} + +/** + * @public + */ +export interface DropdownViewOption extends ViewOption { + type: 'dropdown' + defaultValue: string + values: Array<{ label: IntlString, id: string, hidden?: (viewOptions: ViewOptions) => boolean }> +} + +/** + * @public + */ +export type ViewOptionModel = ToggleViewOption | DropdownViewOption + +/** + * @public + */ +export type OrderOption = [string, SortingOrder] + +/** + * @public + */ +export interface LinkProvider extends Class { + encode: Resource<(doc: Doc, props: Record) => Promise> +} + +/** + * @public + */ +export interface ObjectPanel extends Class { + component: AnyComponent +} + +/** + * @public + */ +export interface ViewOptionsModel { + groupBy: string[] + orderBy: OrderOption[] + other: ViewOptionModel[] + groupDepth?: number +} + +/** + * @public + */ +export interface IconProps { + icon?: Asset + color?: number +}