diff --git a/Makefile b/Makefile index bdfeceb4..c4421117 100644 --- a/Makefile +++ b/Makefile @@ -45,11 +45,12 @@ storybook.serve: .require-compose ## [Build][docker] Runs Storybook for v1-compo storybook.shot: .require-compose ## [Research][docker] Captures a Storybook screenshot for v1-components docs/story page $(TARGET_HEADER) @$(COMPOSE) up -d v1-components - @UID=$$(id -u) GID=$$(id -g) $(COMPOSE) run --rm playwright \ + @$(COMPOSE) run --rm --user "$$(id -u):$$(id -g)" playwright \ yarn workspace @retailcrm/embed-ui-v1-components run storybook:shot \ --base-url http://v1-components:6006 \ --path "$(if $(story_path),$(story_path),/iframe.html?viewMode=docs&id=components-uitable--docs)" \ --output "$(if $(output),$(output),artifacts/storybook/UiTable.docs.png)" \ + $(if $(selector),--selector "$(selector)",) \ --wait-for-selector "$(if $(wait_for),$(wait_for),#storybook-docs)" \ --settle-ms "$(if $(settle_ms),$(settle_ms),2500)" \ --timeout-ms "$(if $(timeout_ms),$(timeout_ms),60000)" \ @@ -83,6 +84,18 @@ else endif $(TARGET_OK) +.PHONY: tests-e2e +tests-e2e: .require-compose ## [Tests][docker] Runs v1-components browser e2e tests + $(TARGET_HEADER) +ifdef cli + @$(COMPOSE) run --rm --user "$$(id -u):$$(id -g)" playwright \ + yarn workspace @retailcrm/embed-ui-v1-components run test:e2e $(cli) +else + @$(COMPOSE) run --rm --user "$$(id -u):$$(id -g)" playwright \ + yarn workspace @retailcrm/embed-ui-v1-components run test:e2e +endif + $(TARGET_OK) + .PHONY: tests-coverage tests-coverage: .require-compose ## [Tests][docker][heavy] Runs autotests with coverage report $(TARGET_HEADER) diff --git a/packages/v1-components/assets/sprites/actions/add-square-outlined.svg b/packages/v1-components/assets/sprites/actions/add-square-outlined.svg new file mode 100644 index 00000000..01a7bc12 --- /dev/null +++ b/packages/v1-components/assets/sprites/actions/add-square-outlined.svg @@ -0,0 +1,8 @@ + + + diff --git a/packages/v1-components/assets/sprites/actions/drag.svg b/packages/v1-components/assets/sprites/actions/drag.svg new file mode 100644 index 00000000..4b96ef5a --- /dev/null +++ b/packages/v1-components/assets/sprites/actions/drag.svg @@ -0,0 +1,8 @@ + + + diff --git a/packages/v1-components/src/common/components/logic-tree.ts b/packages/v1-components/src/common/components/logic-tree.ts new file mode 100644 index 00000000..e6b093bf --- /dev/null +++ b/packages/v1-components/src/common/components/logic-tree.ts @@ -0,0 +1,139 @@ +export enum LogicTreeNodeKind { + BRANCH = 'branch', + CONDITION = 'condition', + GROUP = 'group', +} + +export enum LogicTreeChildrenView { + GROUPED = 'grouped', + PLAIN = 'plain', +} + +export enum LogicTreeConjunction { + AND = 'and', + OR = 'or', +} + +export enum LogicTreeNodeView { + ACTIONS = 'actions', + SUMMARY = 'summary', +} + +export enum LogicTreeTone { + BLUE = 'blue', + GREEN = 'green', + GREY = 'grey', + RED = 'red', + YELLOW = 'yellow', +} + +export type UiLogicTreeConnector = { + continues: boolean; + placeholder?: boolean; + tone: LogicTreeTone; + visible: boolean; +} + +export type UiLogicTreeNodeData> = { + view: LogicTreeNodeView; + editable: boolean; + disabled?: boolean; + draggable?: boolean; + selected?: boolean; + highlighted?: boolean; +} & TNodeData + +export type UiLogicTreeNode> = { + id: string; + kind: LogicTreeNodeKind; + tone?: LogicTreeTone; + conjunction?: LogicTreeConjunction | string; + collapsible?: boolean; + expanded?: boolean; + childrenView?: LogicTreeChildrenView; + children?: UiLogicTreeNode[]; + data: UiLogicTreeNodeData; +} + +export type UiLogicTreeProperties> = { + items?: UiLogicTreeNode[]; +} + +export type UiLogicTreeDropPayload = { + itemId: string; + sourceContainerId: string; + targetContainerId: string; + targetIndex: number | null; + targetItemId: string | null; + placement: 'after' | 'before'; + payload?: unknown; +} + +export type UiLogicTreeNodeAddPayload = { + actionId: string; + kind: Exclude; + parentNodeId: string | null; + parentPathKey: string | null; + triggerNodeId: string; +} + +export type UiLogicTreeNodeEditPayload = { + controlId: string; + nodeId: string; + pathKey: string; + value: string | number | null; +} + +export type UiLogicTreeNodeRemovePayload = { + index: number; + nodeId: string; + parentNodeId: string | null; + parentPathKey: string | null; + pathKey: string; +} + +export type UiLogicTreeNodeSlotProps> = { + editing: boolean; + expanded: boolean; + grouped: boolean; + groupedHeader: boolean; + groupedPosition?: UiLogicTreeNodeProperties['groupedPosition']; + hasChildren: boolean; + highlighted: boolean; + disabled: boolean; + node: UiLogicTreeNode; + path: number[]; + pathKey: string; + nodeView: LogicTreeNodeView; + selected: boolean; + onAction: (actionId: string, kind: Exclude['kind'], LogicTreeNodeKind.BRANCH>) => void; + onControlAction: (controlId: string) => void; + onControlUpdate: (controlId: string, value: string | number | null) => void; + onRemove: () => void; + onToggle: () => void; +} + +export type UiLogicTreeRootProperties = Record + +export type UiLogicTreeCaretProperties = { + active?: boolean; +} + +export type UiLogicTreeNodeProperties = { + pathKey?: string; + nodeView?: LogicTreeNodeView; + connectors?: UiLogicTreeConnector[]; + conjunction?: string; + conjunctionEndPathKey?: string; + conjunctionLabel?: string; + conjunctionOffset?: number; + conjunctionStartPathKey?: string; + conjunctionTone?: LogicTreeTone; + groupedHeader?: boolean; + grouped?: boolean; + groupedPosition?: 'end' | 'middle' | 'single' | 'start'; + editable?: boolean; + disabled?: boolean; + highlighted?: boolean; + selected?: boolean; +} diff --git a/packages/v1-components/src/common/components/popper.ts b/packages/v1-components/src/common/components/popper.ts index b11e5dd2..058f5cf2 100644 --- a/packages/v1-components/src/common/components/popper.ts +++ b/packages/v1-components/src/common/components/popper.ts @@ -34,6 +34,7 @@ export type FloatingOptions = { } export type ShowingOptions = { + visible?: boolean; shown?: boolean; targetTriggers?: Trigger[] | TriggerSchema; popperTriggers?: Trigger[] | TriggerSchema; diff --git a/packages/v1-components/src/host/components/index.ts b/packages/v1-components/src/host/components/index.ts index f777ec60..04d9182f 100644 --- a/packages/v1-components/src/host/components/index.ts +++ b/packages/v1-components/src/host/components/index.ts @@ -16,6 +16,11 @@ export { default as UiImage } from '@/host/components/image/UiImage.vue' export { default as UiInfobox } from '@/host/components/infobox/UiInfobox.vue' export { default as UiLink } from '@/host/components/link/UiLink.vue' export { default as UiLoader } from '@/host/components/loader/UiLoader.vue' +export { default as UiLogicTreeCaret } from '@/host/components/logic-tree/UiLogicTreeCaret.vue' +export { default as UiLogicTreeNode } from '@/host/components/logic-tree/UiLogicTreeNode.vue' +export { default as UiLogicTreeNodeIcon } from '@/host/components/logic-tree/UiLogicTreeNodeIcon.vue' +export { default as UiLogicTreeNodeItem } from '@/host/components/logic-tree/UiLogicTreeNodeItem.vue' +export { default as UiLogicTreeRoot } from '@/host/components/logic-tree/UiLogicTreeRoot.vue' export { default as UiMenuItem } from '@/host/components/menu/UiMenuItem.vue' export { default as UiMenuItemGroup } from '@/host/components/menu/UiMenuItemGroup.vue' export { default as UiModalSidebar } from '@/host/components/modal-sidebar/UiModalSidebar.vue' diff --git a/packages/v1-components/src/host/components/logic-tree/UiLogicTreeCaret.vue b/packages/v1-components/src/host/components/logic-tree/UiLogicTreeCaret.vue new file mode 100644 index 00000000..6b91c7bc --- /dev/null +++ b/packages/v1-components/src/host/components/logic-tree/UiLogicTreeCaret.vue @@ -0,0 +1,19 @@ + + + diff --git a/packages/v1-components/src/host/components/logic-tree/UiLogicTreeCaret.vue.d.ts b/packages/v1-components/src/host/components/logic-tree/UiLogicTreeCaret.vue.d.ts new file mode 100644 index 00000000..27832358 --- /dev/null +++ b/packages/v1-components/src/host/components/logic-tree/UiLogicTreeCaret.vue.d.ts @@ -0,0 +1,7 @@ +import type { DefineComponent } from '@/common/vue' + +import type { UiLogicTreeCaretProperties } from '@/common/components/logic-tree' + +declare const UiLogicTreeCaret: DefineComponent + +export default UiLogicTreeCaret diff --git a/packages/v1-components/src/host/components/logic-tree/UiLogicTreeNode.vue b/packages/v1-components/src/host/components/logic-tree/UiLogicTreeNode.vue new file mode 100644 index 00000000..62262cde --- /dev/null +++ b/packages/v1-components/src/host/components/logic-tree/UiLogicTreeNode.vue @@ -0,0 +1,388 @@ + + + + +