Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update dashboard events #7827

Merged
merged 3 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 4 additions & 24 deletions dev/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,12 @@
`;
};

dashboard.addEventListener('dashboard-item-reorder-start', (e) => {
console.log('dashboard-item-reorder-start');
dashboard.addEventListener('dashboard-item-moved', (e) => {
console.log('dashboard-item-moved', e.detail);
});

dashboard.addEventListener('dashboard-item-drag-reorder', (e) => {
console.log('dashboard-item-drag-reorder', e.detail);
// e.preventDefault();
});

dashboard.addEventListener('dashboard-item-reorder-end', (e) => {
console.log('dashboard-item-reorder-end');
console.log('items after reorder', e.target.items);
});

dashboard.addEventListener('dashboard-item-resize-start', (e) => {
console.log('dashboard-item-resize-start', e.detail);
});

dashboard.addEventListener('dashboard-item-drag-resize', (e) => {
console.log('dashboard-item-drag-resize', e.detail);
// e.preventDefault();
});

dashboard.addEventListener('dashboard-item-resize-end', (e) => {
console.log('dashboard-item-resize-end');
console.log('item after resize', e.detail);
dashboard.addEventListener('dashboard-item-resized', (e) => {
console.log('dashboard-item-resized', e.detail);
});

dashboard.addEventListener('dashboard-item-removed', (e) => {
Expand Down
55 changes: 13 additions & 42 deletions packages/dashboard/src/vaadin-dashboard.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,69 +48,40 @@ export type DashboardRenderer<TItem extends DashboardItem> = (
) => void;

/**
* Fired when item reordering starts
* Fired when an item was moved
*/
export type DashboardItemReorderStartEvent = CustomEvent;
export type DashboardItemMovedEvent<TItem extends DashboardItem> = CustomEvent<{
item: TItem;

/**
* Fired when item reordering ends
*/
export type DashboardItemReorderEndEvent = CustomEvent;
items: Array<TItem | DashboardSectionItem<TItem>>;

/**
* Fired when an items will be reordered by dragging
*/
export type DashboardItemDragReorderEvent<TItem extends DashboardItem> = CustomEvent<{
item: TItem | DashboardSectionItem<TItem>;
targetIndex: number;
section: DashboardSectionItem<TItem> | undefined;
}>;

/**
* Fired when item resizing starts
* Fired when an item was resized
*/
export type DashboardItemResizeStartEvent<TItem extends DashboardItem> = CustomEvent<{
export type DashboardItemResizedEvent<TItem extends DashboardItem> = CustomEvent<{
item: TItem;
}>;

/**
* Fired when item resizing ends
*/
export type DashboardItemResizeEndEvent<TItem extends DashboardItem> = CustomEvent<{
item: TItem;
}>;

/**
* Fired when an item will be resized by dragging
*/
export type DashboardItemDragResizeEvent<TItem extends DashboardItem> = CustomEvent<{
item: TItem;
colspan: number;
rowspan: number;
items: Array<TItem | DashboardSectionItem<TItem>>;
}>;

/**
* Fired when an item is removed
* Fired when an item was removed
*/
export type DashboardItemRemoveEvent<TItem extends DashboardItem> = CustomEvent<{
export type DashboardItemRemovedEvent<TItem extends DashboardItem> = CustomEvent<{
item: TItem | DashboardSectionItem<TItem>;

items: Array<TItem | DashboardSectionItem<TItem>>;
}>;

export interface DashboardCustomEventMap<TItem extends DashboardItem> {
'dashboard-item-reorder-start': DashboardItemReorderStartEvent;

'dashboard-item-reorder-end': DashboardItemReorderEndEvent;

'dashboard-item-drag-reorder': DashboardItemDragReorderEvent<TItem>;

'dashboard-item-resize-start': DashboardItemResizeStartEvent<TItem>;

'dashboard-item-resize-end': DashboardItemResizeEndEvent<TItem>;
'dashboard-item-moved': DashboardItemMovedEvent<TItem>;

'dashboard-item-drag-resize': DashboardItemDragResizeEvent<TItem>;
'dashboard-item-resized': DashboardItemResizedEvent<TItem>;

'dashboard-item-removed': DashboardItemRemoveEvent<TItem>;
'dashboard-item-removed': DashboardItemRemovedEvent<TItem>;
}

export type DashboardEventMap<TItem extends DashboardItem> = DashboardCustomEventMap<TItem> & HTMLElementEventMap;
Expand Down
44 changes: 8 additions & 36 deletions packages/dashboard/src/vaadin-dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,9 @@ import { WidgetResizeController } from './widget-resize-controller.js';
/**
* A responsive, grid-based dashboard layout component
*
* @fires {CustomEvent} dashboard-item-drag-reorder - Fired when an items will be reordered by dragging
* @fires {CustomEvent} dashboard-item-reorder-start - Fired when item reordering starts
* @fires {CustomEvent} dashboard-item-reorder-end - Fired when item reordering ends
* @fires {CustomEvent} dashboard-item-drag-resize - Fired when an item will be resized by dragging
* @fires {CustomEvent} dashboard-item-resize-start - Fired when item resizing starts
* @fires {CustomEvent} dashboard-item-resize-end - Fired when item resizing ends
* @fires {CustomEvent} dashboard-item-removed - Fired when an item is removed
* @fires {CustomEvent} dashboard-item-moved - Fired when an item was moved
* @fires {CustomEvent} dashboard-item-resized - Fired when an item was resized
* @fires {CustomEvent} dashboard-item-removed - Fired when an item was removed
*
* @customElement
* @extends HTMLElement
Expand Down Expand Up @@ -232,43 +228,19 @@ class Dashboard extends ControllerMixin(DashboardLayoutMixin(ElementMixin(Themab
}

/**
* Fired when item reordering starts
* Fired when an item was moved
*
* @event dashboard-item-reorder-start
* @event dashboard-item-moved
*/

/**
* Fired when item reordering ends
* Fired when an item was resized
*
* @event dashboard-item-reorder-end
* @event dashboard-item-resized
*/

/**
* Fired when an items will be reordered by dragging
*
* @event dashboard-item-drag-reorder
*/

/**
* Fired when item resizing starts
*
* @event dashboard-item-resize-start
*/

/**
* Fired when item resizing ends
*
* @event dashboard-item-resize-end
*/

/**
* Fired when an item will be resized by dragging
*
* @event dashboard-item-drag-resize
*/

/**
* Fired when an item is removed
* Fired when an item was removed
*
* @event dashboard-item-removed
*/
Expand Down
27 changes: 14 additions & 13 deletions packages/dashboard/src/widget-reorder-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ export class WidgetReorderController {
// Observe the removal of the dragged element from the DOM
this.draggedElementRemoveObserver.observe(this.host, { childList: true, subtree: true });

this.host.dispatchEvent(new CustomEvent('dashboard-item-reorder-start'));

requestAnimationFrame(() => {
// Re-render to have the dragged element turn into a placeholder
this.host.items = [...this.host.items];
Expand Down Expand Up @@ -87,15 +85,7 @@ export class WidgetReorderController {
const targetItems = getItemsArrayOfItem(targetItem, this.host.items);
const targetIndex = targetItems.indexOf(targetItem);

const reorderEvent = new CustomEvent('dashboard-item-drag-reorder', {
detail: { item: this.draggedItem, targetIndex },
cancelable: true,
});

// Dispatch the reorder event and reorder items if the event is not canceled
if (this.host.dispatchEvent(reorderEvent)) {
this.__reorderItems(this.draggedItem, targetIndex);
}
this.__reorderItems(this.draggedItem, targetIndex);
}
}

Expand All @@ -111,16 +101,26 @@ export class WidgetReorderController {
this.__draggedElement.remove();
}

// Dispatch the moved event
this.__fireItemMovedEvent(this.draggedItem);

// Reset the dragged element and item, and re-render to remove the placeholder
this.__draggedElement = null;
this.draggedItem = null;
this.host.items = [...this.host.items];

// Disconnect the observer for the dragged element removal
this.draggedElementRemoveObserver.disconnect();
}

// Dispatch the reorder end event
this.host.dispatchEvent(new CustomEvent('dashboard-item-reorder-end'));
/** @private */
__fireItemMovedEvent(item) {
const section = this.host.items.find((hostItem) => hostItem.items && hostItem.items.includes(item));
this.host.dispatchEvent(
new CustomEvent('dashboard-item-moved', {
detail: { item, items: this.host.items, section },
}),
);
}

/** @private */
Expand Down Expand Up @@ -228,5 +228,6 @@ export class WidgetReorderController {
const item = getElementItem(e.target);
const items = getItemsArrayOfItem(item, this.host.items);
this.__reorderItems(item, items.indexOf(item) + e.detail.delta);
this.__fireItemMovedEvent(item);
}
}
26 changes: 9 additions & 17 deletions packages/dashboard/src/widget-resize-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ export class WidgetResizeController {
this.__resizeHeight = this.__resizeStartHeight + e.detail.dy;
this.__updateWidgetStyles();

this.host.dispatchEvent(new CustomEvent('dashboard-item-resize-start', { detail: { item: this.resizedItem } }));

this.__resizedElement = e.target;
// Observe the removal of the resized element from the DOM
this.__resizedElementRemoveObserver.observe(this.host, { childList: true, subtree: true });
Expand Down Expand Up @@ -120,13 +118,17 @@ export class WidgetResizeController {
document.removeEventListener('touchmove', this.__touchMoveCancelListener);

// Dispatch the resize end event
this.__fireItemResizedEvent(this.resizedItem);
this.resizedItem = null;
}

/** @private */
__fireItemResizedEvent(item) {
this.host.dispatchEvent(
new CustomEvent('dashboard-item-resize-end', {
detail: { item: this.resizedItem },
cancelable: true,
new CustomEvent('dashboard-item-resized', {
detail: { item, items: this.host.items },
}),
);
this.resizedItem = null;
}

/** @private */
Expand Down Expand Up @@ -165,17 +167,6 @@ export class WidgetResizeController {
return;
}

// TODO: Event to be removed
const resizeEvent = new CustomEvent('dashboard-item-drag-resize', {
detail: { item: this.resizedItem, colspan: newColspan, rowspan: newRowspan },
cancelable: true,
});

// Dispatch the resize event and resize items if the event is not canceled
if (!this.host.dispatchEvent(resizeEvent)) {
return;
}

item.colspan = newColspan;
item.rowspan = newRowspan;
this.host.items = [...this.host.items];
Expand Down Expand Up @@ -204,6 +195,7 @@ export class WidgetResizeController {
e.stopImmediatePropagation();
const item = getElementItem(e.target);
this.__resizeItem(item, e.detail.colspanDelta, e.detail.rowspanDelta);
this.__fireItemResizedEvent(item);
}

hostDisconnected() {
Expand Down
55 changes: 55 additions & 0 deletions packages/dashboard/test/dashboard-keyboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ describe('dashboard - keyboard interaction', () => {
expect(dashboard.items).to.eql([{ id: 1 }, { items: [{ id: 2 }, { id: 3 }] }]);
});

it('should dispatch an item removed event on backspace', async () => {
const spy = sinon.spy();
dashboard.addEventListener('dashboard-item-removed', spy);
await sendKeys({ press: 'Backspace' });
expect(spy.calledOnce).to.be.true;
expect(spy.firstCall.args[0].detail.item).to.eql({ id: 0 });
expect(spy.firstCall.args[0].detail.items).to.eql(dashboard.items);
});

it('should move the widget forwards on arrow down', async () => {
await sendKeys({ press: 'ArrowDown' });
expect(dashboard.items).to.eql([{ id: 1 }, { id: 0 }, { items: [{ id: 2 }, { id: 3 }] }]);
Expand All @@ -165,6 +174,16 @@ describe('dashboard - keyboard interaction', () => {
expect(dashboard.items).to.eql([{ id: 0 }, { id: 1 }, { items: [{ id: 2 }, { id: 3 }] }]);
});

it('should dispatch an item moved event arrow down', async () => {
const spy = sinon.spy();
dashboard.addEventListener('dashboard-item-moved', spy);
await sendKeys({ press: 'ArrowDown' });
expect(spy.calledOnce).to.be.true;
expect(spy.firstCall.args[0].detail.item).to.eql({ id: 0 });
expect(spy.firstCall.args[0].detail.items).to.eql(dashboard.items);
expect(spy.firstCall.args[0].detail.section).to.be.undefined;
});

it('should increase the widget row span on shift + arrow down', async () => {
// Set minimum row height to enable vertical resizing
setMinimumRowHeight(dashboard, 100);
Expand All @@ -184,6 +203,18 @@ describe('dashboard - keyboard interaction', () => {
expect((dashboard.items[0] as DashboardItem).rowspan).to.equal(1);
});

it('should dispatch an item resized event shift + arrow down', async () => {
const spy = sinon.spy();
dashboard.addEventListener('dashboard-item-resized', spy);
await sendKeys({ down: 'Shift' });
await sendKeys({ press: 'ArrowDown' });
await sendKeys({ up: 'Shift' });
expect(spy.calledOnce).to.be.true;
expect(spy.firstCall.args[0].detail.item).to.eql({ id: 0 });
expect(spy.firstCall.args[0].detail.items).to.eql(dashboard.items);
expect(spy.firstCall.args[0].detail.section).to.be.undefined;
});

it('should not increase the widget row span on shift + arrow down if row min height is not defined', async () => {
await sendKeys({ down: 'Shift' });
await sendKeys({ press: 'ArrowDown' });
Expand Down Expand Up @@ -448,6 +479,18 @@ describe('dashboard - keyboard interaction', () => {
expect(dashboard.items).to.eql([{ id: 0 }, { id: 1 }, { items: [{ id: 2 }, { id: 3 }] }]);
});

it('should dispatch an item moved event on forward button click', async () => {
const spy = sinon.spy();
dashboard.addEventListener('dashboard-item-moved', spy);
// Focus forward button, click it
await sendKeys({ press: 'Tab' });
await sendKeys({ press: 'Space' });
expect(spy.calledOnce).to.be.true;
expect(spy.firstCall.args[0].detail.item).to.eql({ id: 0 });
expect(spy.firstCall.args[0].detail.items).to.eql(dashboard.items);
expect(spy.firstCall.args[0].detail.section).to.be.undefined;
});

it('should not lose move mode when the focused backward button is hidden', async () => {
const widget = getElementFromCell(dashboard, 0, 0)!;

Expand Down Expand Up @@ -663,6 +706,18 @@ describe('dashboard - keyboard interaction', () => {
expect((dashboard.items[0] as DashboardItem).rowspan).to.equal(1);
});

it('should dispatch an item resized event on on grow width button click', async () => {
const spy = sinon.spy();
dashboard.addEventListener('dashboard-item-resized', spy);
// Focus forward button, click it
const widget = getElementFromCell(dashboard, 0, 0)!;
getResizeGrowWidthButton(widget).focus();
await sendKeys({ press: 'Space' });
expect(spy.calledOnce).to.be.true;
expect(spy.firstCall.args[0].detail.item).to.eql(dashboard.items[0]);
expect(spy.firstCall.args[0].detail.items).to.eql(dashboard.items);
});

it('should deselect the widget on blur', async () => {
const widget = getElementFromCell(dashboard, 0, 0)!;
const anotherWidget = getElementFromCell(dashboard, 0, 1)!;
Expand Down
Loading
Loading