diff --git a/.github/workflows/continuum.yaml b/.github/workflows/continuum.yaml index b0f9971555..cda1549ec2 100644 --- a/.github/workflows/continuum.yaml +++ b/.github/workflows/continuum.yaml @@ -84,7 +84,18 @@ jobs: -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer ${{ secrets.ROBBY_SMEUP_PAT }}" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/smeup/webup-project/dispatches \ - -d '{"event_type": "ketchup-continuum-rebuild"}' + https://api.github.com/repos/smeup/webup-project/actions/workflows/continuum.yaml/dispatches \ + -d '{"ref": "develop"}' - # TODO: add webup.js triggers \ No newline at end of file + trigger-webupjs-develop: + needs: ketchup-release + runs-on: ubuntu-latest + steps: + - run: | + curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.ROBBY_SMEUP_PAT }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/smeup/webup.js/actions/workflows/develop-release.yaml/dispatches \ + -d '{"ref": "develop"}' \ No newline at end of file diff --git a/packages/ketchup-showcase/src/App.vue b/packages/ketchup-showcase/src/App.vue index 69389a7b4c..3349b9813e 100644 --- a/packages/ketchup-showcase/src/App.vue +++ b/packages/ketchup-showcase/src/App.vue @@ -80,7 +80,7 @@ size-y="24px" > - © Copyright 2022 - Sme.UP Spa + © Copyright 2024 - Sme.UP Spa { console.log(e); }); + +document.addEventListener('kup-imagelist-contextmenu', (e) => { + console.log(e); +}); + +document.addEventListener('kup-imagelist-dblclick', (e) => { + console.log(e); +}); diff --git a/packages/ketchup/src/assets/input-panel.js b/packages/ketchup/src/assets/input-panel.js index bfdc90753a..458ffd66f6 100644 --- a/packages/ketchup/src/assets/input-panel.js +++ b/packages/ketchup/src/assets/input-panel.js @@ -108,13 +108,9 @@ const data = { }, CHK: { value: 'on', - obj: { - t: 'V2', - p: 'SI/NO', - k: '', - }, editable: true, mandatory: true, + shape: 'CHK', }, RAD: { value: '1', diff --git a/packages/ketchup/src/components.d.ts b/packages/ketchup/src/components.d.ts index 0cf63ba20f..661a905889 100644 --- a/packages/ketchup/src/components.d.ts +++ b/packages/ketchup/src/components.d.ts @@ -11,7 +11,7 @@ import { ItemsDisplayMode, KupListEventPayload, KupListNode, KupListRole } from import { KupAutocompleteEventPayload, KupAutocompleteIconClickEventPayload } from "./components/kup-autocomplete/kup-autocomplete-declarations"; import { KupBoxAutoSelectEventPayload, KupBoxClickEventPayload, KupBoxContextMenuEventPayload, KupBoxData, KupBoxKanban, KupBoxLayout, KupBoxLoadMoreClickEventPayload, KupBoxRow, KupBoxRowActionClickEventPayload, KupBoxSelectedEventPayload, LoadMoreMode } from "./components/kup-box/kup-box-declarations"; import { KupStore } from "./components/kup-state/kup-store"; -import { KupDataCell, KupDataColumn, KupDataDataset, KupDataNewColumnOptions, KupDataNewColumnTypes, KupDataNode, KupDataRowAction } from "./managers/kup-data/kup-data-declarations"; +import { KupDataCell, KupDataColumn, KupDataDataset, KupDataNewColumnOptions, KupDataNewColumnTypes, KupDataRowAction } from "./managers/kup-data/kup-data-declarations"; import { FButtonProps, FButtonStyling } from "./f-components/f-button/f-button-declarations"; import { KupButtonClickEventPayload } from "./components/kup-button/kup-button-declarations"; import { KupButtonListClickEventPayload, KupButtonListNode } from "./components/kup-button-list/kup-button-list-declarations"; @@ -41,8 +41,8 @@ import { KupFormData, KupFormLabelPlacement, KupFormLayout } from "./components/ import { KupBadge } from "./components/kup-badge/kup-badge"; import { FImageData } from "./f-components/f-image/f-image-declarations"; import { KupImageClickEventPayload } from "./components/kup-image/kup-image-declarations"; +import { KupImageListDataNode, KupImageListEventPayload } from "./components/kup-image-list/kup-image-list-declarations"; import { KupTreeColumnMenuEventPayload, KupTreeColumnRemoveEventPayload, KupTreeContextMenuEventPayload, KupTreeDynamicMassExpansionEventPayload, KupTreeExpansionMode, KupTreeNode, KupTreeNodeButtonClickEventPayload, KupTreeNodeCollapseEventPayload, KupTreeNodeExpandEventPayload, KupTreeNodeSelectedEventPayload, TreeNodePath } from "./components/kup-tree/kup-tree-declarations"; -import { KupImageListEventPayload } from "./components/kup-image-list/kup-image-list-declarations"; import { KupInputPanelData } from "./components/kup-input-panel/kup-input-panel-declarations"; import { KupLazyRender } from "./components/kup-lazy/kup-lazy-declarations"; import { KupNavBarStyling } from "./components/kup-nav-bar/kup-nav-bar-declarations"; @@ -62,7 +62,7 @@ export { ItemsDisplayMode, KupListEventPayload, KupListNode, KupListRole } from export { KupAutocompleteEventPayload, KupAutocompleteIconClickEventPayload } from "./components/kup-autocomplete/kup-autocomplete-declarations"; export { KupBoxAutoSelectEventPayload, KupBoxClickEventPayload, KupBoxContextMenuEventPayload, KupBoxData, KupBoxKanban, KupBoxLayout, KupBoxLoadMoreClickEventPayload, KupBoxRow, KupBoxRowActionClickEventPayload, KupBoxSelectedEventPayload, LoadMoreMode } from "./components/kup-box/kup-box-declarations"; export { KupStore } from "./components/kup-state/kup-store"; -export { KupDataCell, KupDataColumn, KupDataDataset, KupDataNewColumnOptions, KupDataNewColumnTypes, KupDataNode, KupDataRowAction } from "./managers/kup-data/kup-data-declarations"; +export { KupDataCell, KupDataColumn, KupDataDataset, KupDataNewColumnOptions, KupDataNewColumnTypes, KupDataRowAction } from "./managers/kup-data/kup-data-declarations"; export { FButtonProps, FButtonStyling } from "./f-components/f-button/f-button-declarations"; export { KupButtonClickEventPayload } from "./components/kup-button/kup-button-declarations"; export { KupButtonListClickEventPayload, KupButtonListNode } from "./components/kup-button-list/kup-button-list-declarations"; @@ -92,8 +92,8 @@ export { KupFormData, KupFormLabelPlacement, KupFormLayout } from "./components/ export { KupBadge } from "./components/kup-badge/kup-badge"; export { FImageData } from "./f-components/f-image/f-image-declarations"; export { KupImageClickEventPayload } from "./components/kup-image/kup-image-declarations"; +export { KupImageListDataNode, KupImageListEventPayload } from "./components/kup-image-list/kup-image-list-declarations"; export { KupTreeColumnMenuEventPayload, KupTreeColumnRemoveEventPayload, KupTreeContextMenuEventPayload, KupTreeDynamicMassExpansionEventPayload, KupTreeExpansionMode, KupTreeNode, KupTreeNodeButtonClickEventPayload, KupTreeNodeCollapseEventPayload, KupTreeNodeExpandEventPayload, KupTreeNodeSelectedEventPayload, TreeNodePath } from "./components/kup-tree/kup-tree-declarations"; -export { KupImageListEventPayload } from "./components/kup-image-list/kup-image-list-declarations"; export { KupInputPanelData } from "./components/kup-input-panel/kup-input-panel-declarations"; export { KupLazyRender } from "./components/kup-lazy/kup-lazy-declarations"; export { KupNavBarStyling } from "./components/kup-nav-bar/kup-nav-bar-declarations"; @@ -2542,7 +2542,7 @@ export namespace Components { * Actual data of the component. * @default [] */ - "data": KupDataNode[]; + "data": KupImageListDataNode[]; /** * Used to retrieve component's props values. * @param descriptions - When provided and true, the result will be the list of props with their description. @@ -2592,6 +2592,10 @@ export namespace Components { * @default false */ "hiddenSubmitButton": boolean; + /** + * This method is used to trigger a new render of the component. + */ + "refresh": () => Promise; /** * Sets the callback function on submit form * @default null @@ -7343,7 +7347,7 @@ declare namespace LocalJSX { * Actual data of the component. * @default [] */ - "data"?: KupDataNode[]; + "data"?: KupImageListDataNode[]; "onKup-imagelist-click"?: (event: KupImageListCustomEvent) => void; "onKup-imagelist-contextmenu"?: (event: KupImageListCustomEvent) => void; "onKup-imagelist-dblclick"?: (event: KupImageListCustomEvent) => void; diff --git a/packages/ketchup/src/components/kup-image-list/kup-image-list-declarations.ts b/packages/ketchup/src/components/kup-image-list/kup-image-list-declarations.ts index 341c48eda7..2721d4a8d7 100644 --- a/packages/ketchup/src/components/kup-image-list/kup-image-list-declarations.ts +++ b/packages/ketchup/src/components/kup-image-list/kup-image-list-declarations.ts @@ -1,11 +1,17 @@ -import { KupDataNode } from '../../managers/kup-data/kup-data-declarations'; -import { KupEventPayload } from '../../types/GenericTypes'; +import { + KupDataCell, + KupDataColumn, + KupDataNode, + KupDataRow, +} from '../../managers/kup-data/kup-data-declarations'; +import { GenericObject, KupEventPayload } from '../../types/GenericTypes'; /** * Props of the kup-image-list component. * Used to export every prop in an object. */ export enum KupImageListProps { + columns = 'Can set a specific number of columns', customStyle = 'Custom style of the component.', data = 'Actual data of the component', ripple = "When enabled displays Material's ripple effect on clicked items.", @@ -13,5 +19,19 @@ export enum KupImageListProps { } export interface KupImageListEventPayload extends KupEventPayload { - node: KupDataNode; + details: KupImageListEventHandlerDetails; +} +/** + * Contains all the data of an event. + */ +export interface KupImageListEventHandlerDetails { + cell: KupDataCell; + column: KupDataColumn; + originalEvent: PointerEvent; + row: KupDataRow; +} + +export interface KupImageListDataNode extends KupDataNode { + badgeData: GenericObject[]; + children?: KupImageListDataNode[]; } diff --git a/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx b/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx index d89ad313d2..1c9b2d431d 100644 --- a/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx +++ b/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx @@ -19,12 +19,13 @@ import { } from '../../managers/kup-manager/kup-manager'; import { GenericObject, KupComponent } from '../../types/GenericTypes'; import { + KupImageListDataNode, + KupImageListEventHandlerDetails, KupImageListEventPayload, KupImageListProps, } from './kup-image-list-declarations'; import { getProps, setProps } from '../../utils/utils'; import { componentWrapperId } from '../../variables/GenericVariables'; -import { KupDataNode } from '../../managers/kup-data/kup-data-declarations'; import { FImage } from '../../f-components/f-image/f-image'; import { FImageProps } from '../../f-components/f-image/f-image-declarations'; import { FButton } from '../../f-components/f-button/f-button'; @@ -34,11 +35,15 @@ import { } from '../../f-components/f-button/f-button-declarations'; import { KupLanguageGeneric } from '../../managers/kup-language/kup-language-declarations'; import { FCell } from '../../f-components/f-cell/f-cell'; -import { FCellPadding } from '../../f-components/f-cell/f-cell-declarations'; +import { + FCellPadding, + FCellProps, +} from '../../f-components/f-cell/f-cell-declarations'; import { KupStore } from '../kup-state/kup-store'; import { KupImageListState } from './kup-image-list-state'; import { TreeNodePath } from '../kup-tree/kup-tree-declarations'; import { KupBadge } from '../kup-badge/kup-badge'; +import { KupPointerEventTypes } from '../../managers/kup-interact/kup-interact-declarations'; @Component({ tag: 'kup-image-list', @@ -57,7 +62,7 @@ export class KupImageList { state: KupImageListState = new KupImageListState(); - @State() currentNode: KupDataNode = null; + @State() currentNode: KupImageListDataNode = null; @State() navigationBarToggled: boolean = false; initWithPersistedState(): void { @@ -65,10 +70,10 @@ export class KupImageList { const state = this.store.getState(this.stateId); if (state != null) { this.currentNode = - this.kupManager.data.node.findByStrTreeNodePath( + this.#kupManager.data.node.findByStrTreeNodePath( this.data, state.selectedTreeNodePath - ); + ) as KupImageListDataNode; } } } @@ -79,7 +84,7 @@ export class KupImageList { let cNodeRowId = this.currentNode ? this.currentNode.id : ''; if ( - !this.kupManager.objects.deepEqual( + !this.#kupManager.objects.deepEqual( this.state.selectedTreeNodePath, cNodeRowId ) @@ -116,7 +121,7 @@ export class KupImageList { * Actual data of the component. * @default [] */ - @Prop() data: KupDataNode[] = []; + @Prop() data: KupImageListDataNode[] = []; /** * When enabled displays Material's ripple effect on clicked items. * @default true @@ -140,7 +145,6 @@ export class KupImageList { /** * Instance of the KupManager class. */ - private kupManager: KupManager = kupManagerInstance(); #clickTimeout: ReturnType[] = []; #kupManager: KupManager = kupManagerInstance(); @@ -150,7 +154,7 @@ export class KupImageList { this.currentNode = this.#kupManager.data.node.getParent( this.data, this.currentNode - ); + ) as KupImageListDataNode; if (!this.currentNode) { this.navigationBarToggled = false; } @@ -167,6 +171,9 @@ export class KupImageList { styling: FButtonStyling.FLAT, wrapperClass: 'navigation-bar__top', }; + #el: HTMLElement; + #hold: boolean = false; + #interactableTouch: HTMLElement[] = []; /*-------------------------------------------------*/ /* E v e n t s */ @@ -180,17 +187,6 @@ export class KupImageList { }) kupClick: EventEmitter; - onKupClick(node: KupDataNode) { - if (node.children && node.children.length > 0) { - this.currentNode = node; - } - this.kupClick.emit({ - comp: this, - id: this.rootElement.id, - node: node, - }); - } - @Event({ eventName: 'kup-imagelist-contextmenu', composed: true, @@ -199,15 +195,6 @@ export class KupImageList { }) kupContextMenu: EventEmitter; - onKupContextMenu(e: MouseEvent, node: KupDataNode) { - e.preventDefault(); - this.kupContextMenu.emit({ - comp: this, - id: this.rootElement.id, - node: node, - }); - } - @Event({ eventName: 'kup-imagelist-dblclick', composed: true, @@ -216,18 +203,6 @@ export class KupImageList { }) kupDblClick: EventEmitter; - onKupDblClick(node: KupDataNode) { - for (let index = 0; index < this.#clickTimeout.length; index++) { - clearTimeout(this.#clickTimeout[index]); - } - this.#clickTimeout = []; - this.kupDblClick.emit({ - comp: this, - id: this.rootElement.id, - node: node, - }); - } - /*-------------------------------------------------*/ /* W a t c h e r s */ /*-------------------------------------------------*/ @@ -237,7 +212,10 @@ export class KupImageList { if (!newData || newData.length == 0) { return; } - this.currentNode = this.kupManager.data.node.find(this.data, newData); + this.currentNode = this.#kupManager.data.node.find( + this.data, + newData + ) as KupImageListDataNode; } /*-------------------------------------------------*/ @@ -273,12 +251,13 @@ export class KupImageList { /* P r i v a t e M e t h o d s */ /*-------------------------------------------------*/ - #createItem(node: KupDataNode): VNode { + #createItem(node: KupImageListDataNode): VNode { const props: FImageProps = { - fit: false, + fit: true, resource: node.icon, title: node.title, wrapperClass: 'image-list__image', + badgeData: node.badgeData, }; const image = ; const label =
{node.value}
; @@ -309,13 +288,9 @@ export class KupImageList { }; const item: VNode = (
{ - this.#clickTimeout.push( - setTimeout(() => this.onKupClick(node), 300) - ); + onContextMenu={(e) => { + e.preventDefault(); }} - onContextMenu={(e) => this.onKupContextMenu(e, node)} - onDblClick={() => this.onKupDblClick(node)} class={classObj} > {this.#createItem(node)} @@ -326,6 +301,151 @@ export class KupImageList { return nodes; } + #getEventDetails( + path: HTMLElement[], + e?: PointerEvent + ): KupImageListEventHandlerDetails { + let cellProps: FCellProps; + + if (path) { + for (let i = path.length - 1; i >= 0; i--) { + let p = path[i]; + if (!p.tagName) { + continue; + } + if (p.classList.contains('f-cell')) { + cellProps = p['kup-get-cell-props'](); + } + } + } + + return { + cell: cellProps?.cell, + column: cellProps?.column, + originalEvent: e, + row: cellProps?.row, + }; + } + + #clickHandler(e: PointerEvent): KupImageListEventHandlerDetails { + const details: KupImageListEventHandlerDetails = this.#getEventDetails( + this.#kupManager.getEventPath(e.target, this.rootElement), + e + ); + + return details; + } + + #contextMenuHandler(e: PointerEvent): KupImageListEventHandlerDetails { + const details: KupImageListEventHandlerDetails = this.#getEventDetails( + this.#kupManager.getEventPath(e.target, this.rootElement), + e + ); + + return details; + } + + #dblClickHandler(e: PointerEvent): KupImageListEventHandlerDetails { + const details: KupImageListEventHandlerDetails = this.#getEventDetails( + this.#kupManager.getEventPath(e.target, this.rootElement), + e + ); + + return details; + } + + #didLoadInteractables() { + this.#interactableTouch.push(this.#el); + const tapCb = (e: PointerEvent) => { + if (this.#hold) { + this.#hold = false; + return; + } + switch (e.button) { + // left click + case 0: + // Note: event must be cloned + // otherwise inside setTimeout will be exiting the Shadow DOM scope(causing loss of information, including target). + const clone: GenericObject = {}; + for (const key in e) { + clone[key] = e[key]; + } + this.#clickTimeout.push( + setTimeout(() => { + const details = this.#clickHandler( + clone as PointerEvent + ); + const node = details.row as KupImageListDataNode; + if (node.children && node.children.length > 0) { + this.currentNode = node; + } + this.kupClick.emit({ + comp: this, + id: this.rootElement.id, + details, + }); + }, 300) + ); + break; + // right click + case 2: + this.kupContextMenu.emit({ + comp: this, + id: this.rootElement.id, + details: this.#contextMenuHandler(e), + }); + break; + } + }; + const doubletapCb = (e: PointerEvent) => { + switch (e.button) { + // left click + case 0: + for ( + let index = 0; + index < this.#clickTimeout.length; + index++ + ) { + clearTimeout(this.#clickTimeout[index]); + this.#kupManager.debug.logMessage( + this, + 'Cleared clickHandler timeout(' + + this.#clickTimeout[index] + + ').' + ); + } + this.#clickTimeout = []; + this.kupDblClick.emit({ + comp: this, + id: this.rootElement.id, + details: this.#dblClickHandler(e), + }); + break; + } + }; + const holdCb = (e: PointerEvent) => { + if (e.pointerType === 'pen' || e.pointerType === 'touch') { + this.#hold = true; + } + }; + this.#kupManager.interact.on( + this.#el, + KupPointerEventTypes.HOLD, + holdCb + ); + this.#kupManager.interact.on(this.#el, KupPointerEventTypes.TAP, tapCb); + this.#kupManager.interact.on( + this.#el, + KupPointerEventTypes.DOUBLETAP, + doubletapCb + ); + this.#kupManager.interact.on( + this.#el, + KupPointerEventTypes.HOLD, + holdCb + ); + } + /*-------------------------------------------------*/ /* L i f e c y c l e H o o k s */ /*-------------------------------------------------*/ @@ -337,6 +457,7 @@ export class KupImageList { } componentDidLoad() { + this.#didLoadInteractables(); this.#kupManager.debug.logLoad(this, true); } @@ -371,7 +492,7 @@ export class KupImageList { ...gridColumnsStyle, }; - if (this.rows !== null) { + if (this.rows != null && this.rows > 0) { const gridRowsStyle = { 'grid-template-rows': `repeat(${this.rows}, minmax(0px, 1fr))`, 'grid-auto-flow': `column`, @@ -386,7 +507,12 @@ export class KupImageList { this.rootElement as KupComponent )} -
+
{ + this.#el = el; + }} + >