Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/>
}
<div
class="component-host"
[class]="componentHostClasses"
[style.pointer-events]="editMode() ? 'none' : 'auto'"
>
<div #elementHost></div>
Expand All @@ -32,7 +32,7 @@
} @else {
<div class="card" [attr.data-testid]="'dashboard-card-' + card().id">
<div
class="card__body"
[class]="cardBodyClasses"
[style.pointer-events]="editMode() ? 'none' : 'auto'"
>
<ng-content />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DashboardCard } from './dashboard-card.component';
import { DASHBOARD_CARD_DRAG_ORIGIN_CLASS } from '../constants';
import { DashboardI18nService } from '../i18n';
import { ComponentFixture, TestBed } from '@angular/core/testing';

Expand Down Expand Up @@ -129,6 +130,38 @@ describe('DashboardCard', () => {
expect(root(fixture).querySelector('.component-card')).toBeNull();
});

it('marks the dynamic component host as the drag origin surface', () => {
const { fixture } = setup();

fixture.componentRef.setInput('card', {
id: 'card-1',
component: 'demo-widget',
});
fixture.detectChanges();

expect(
root(fixture).querySelector(
`.component-host.${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`,
),
).not.toBeNull();
});

it('marks the fallback card body as the drag origin surface', () => {
const { fixture } = setup();

fixture.componentRef.setInput('card', {
id: 'card-1',
component: '',
});
fixture.detectChanges();

expect(
root(fixture).querySelector(
`.card__body.${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`,
),
).not.toBeNull();
});

describe('data-testid attributes', () => {
it('sets data-testid on the component-card wrapper when card has a component', () => {
const { fixture } = setup();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DASHBOARD_CARD_DRAG_ORIGIN_CLASS } from '../constants';
import { DASHBOARD_I18N_KEYS, DashboardI18nService } from '../i18n';
import { CARD_TYPES, CardConfig } from '../models';
import { mountAngularCard, mountSapCard, mountWcCard } from './utils';
Expand Down Expand Up @@ -34,6 +35,8 @@ export class DashboardCard {
readonly removeCard = output<void>();
protected readonly i18n = inject(DashboardI18nService);
protected readonly i18nKeys = DASHBOARD_I18N_KEYS;
protected readonly componentHostClasses = `component-host ${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`;
protected readonly cardBodyClasses = `card__body ${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`;
protected readonly gridColumn = computed(() => {
const width = this.card().w ?? 12;
return this.createGridTrack(this.card().x, width);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,16 @@
// Keep these values identical to DASHBOARD_BREAKPOINTS in breakpoints.ts.
// ─────────────────────────────────────────────────────────────────────────────

// Each breakpoint's max-width (in px) and the corresponding column count
// applied at that breakpoint. Ordered ascending by `w` so it's easy to read
// off as a series of (max-width, columns) pairs.
$dashboard-breakpoints: (
(599, 1),
(1023, 8),
(1439, 12),
// Above 1439: 14 columns. Implemented as the default (no @container rule);
// the 4000 ceiling exists in the TS table for Gridstack's benefit only.
);

/// Convenience accessors for the four breakpoint widths used by the grid.
$dashboard-bp-sm: 599px;
$dashboard-bp-md: 1023px;
$dashboard-bp-lg: 1439px;

/// Column counts at each breakpoint.
$dashboard-cols-sm: 1;
$dashboard-cols-md: 8;
$dashboard-cols-lg: 12;
$dashboard-cols-xl: 14;
$dashboard-cols-md: 4;
$dashboard-cols-lg: 4;
$dashboard-cols-xl: 4;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/// Emit `grid-template-columns: repeat(N, 1fr)` rules wrapped in @container
/// queries against the `mfp-dashboard` named container. Every dashboard grid
Expand Down
78 changes: 74 additions & 4 deletions projects/ngx/declarative-ui/dashboard/constants/breakpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,86 @@
// ─────────────────────────────────────────────────────────────────────────────
import type { Breakpoint } from 'gridstack';


Comment thread
Sobyt483 marked this conversation as resolved.

































































/**
* Layout strategy applied at each breakpoint when Gridstack changes column
* count. See ColumnOptions in gridstack/dist/types.d.ts:27 for the full set.
*/
type LayoutStrategy = 'compact' | 'list' | 'none';

/** Single source of truth for grid + section breakpoints (TypeScript half). */
export const DASHBOARD_BREAKPOINTS: readonly Readonly<Required<Pick<Breakpoint, 'w' | 'c'>> & { layout: LayoutStrategy }>[] = [
{ w: 4000, c: 14, layout: 'compact' },
{ w: 1439, c: 12, layout: 'compact' },
{ w: 1023, c: 8, layout: 'compact' },
export const DASHBOARD_BREAKPOINTS: readonly Readonly<
Required<Pick<Breakpoint, 'w' | 'c'>> & { layout: LayoutStrategy }
>[] = [
{ w: 4000, c: 4, layout: 'compact' },

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why all are 4 columns, it should stay how it was by default and if anything is to be different the should be overwritten by configuration

{ w: 1439, c: 4, layout: 'compact' },
{ w: 1023, c: 4, layout: 'compact' },
{ w: 599, c: 1, layout: 'list' },
] as const;

export const XL_PAGE = 1440;
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export const COMPACT_BREAKPOINT = 726;
export const CELL_HEIGHT = 10;
export const DASHBOARD_CARD_DRAG_ORIGIN_CLASS =
'mfp-dashboard-card-drag-origin';
export const DASHBOARD_CARD_DRAG_ORIGIN_SELECTOR =
`.${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`;
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,12 @@
(addedCB)="onGridChange()"
(changeCB)="onGridChange()"
(removedCB)="onGridChange()"
(dragStartCB)="onDragStart($event)"
(dragStopCB)="onDragStop()"
>
@if (dragOriginStyle()) {
<div class="mfp-dashboard__drag-origin-placeholder" [style]="dragOriginStyle()"></div>
}
@for (card of looseCards(); track card.id) {
<gridstack-item [options]="card">
<mfp-dashboard-card
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
@import 'gridstack/dist/gridstack.min.css';

.grid-stack-placeholder {
z-index: 2;
pointer-events: none;

.placeholder-content {
border-radius: 16px;
height: calc(100% - 30px);
top: calc(var(--gs-item-margin-top) * 2) !important;
width: calc(100% - 20px);
left: 10px !important;
background: var(--sapInformationColor, #0070f2);
opacity: 0.25;
z-index: 2 !important;
}
}

Expand Down Expand Up @@ -171,6 +177,27 @@ mfp-wc-dashboard {
cursor: grabbing !important;
}

.mfp-dashboard__drag-origin-placeholder {
position: absolute;
pointer-events: none;
z-index: 1;

&::before {
content: '';
position: absolute;
top: -5px;
width: calc(100% - 10px);
height: 100%;
background: var(--sapNeutralColor, #6a6d75);
border-radius: 16px;
opacity: 0.3;
}
}

gridstack {
position: relative;
}
Comment thread
Sobyt483 marked this conversation as resolved.

.grid-stack:has(.ui-resizable-resizing),
.grid-stack:has(.ui-resizable-resizing) * {
cursor: nwse-resize !important;
Expand Down
Loading