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 @@ -46,7 +46,7 @@ export class AttachmentPreviewComponent {
readonly showDownload = input(true);
readonly withBorder = input(true);

private streamingStatus = computed(() => this._streamingStatus.status());
private readonly streamingStatus = computed(() => this._streamingStatus.status());

protected readonly isStreamingInProgress = computed(() => {
const status = this.streamingStatus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export class UndraggedClickDirective {

private bindWindowListeners(): void {
this.removeWindowListeners?.();
const move = (event: MouseEvent) => this.guard.pointerMove(event);
const up = () => {
const move = (event: MouseEvent): void => this.guard.pointerMove(event);
const up = (): void => {
this.guard.pointerUp();
this.removeWindowListeners?.();
this.removeWindowListeners = undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export * from './services/wizard-registry.service';
export * from './services/execution-custom-panel-registry.service';
export * from './services/entity-menu-items-registry.service';
export * from './services/automation-package-entity-table-registry.service';
export * from './services/grid-settings-registry.service';
export { ItemInfo } from './services/base-registry.service';
export * from './shared/custom-registry-item';
export * from './shared/custom-registry-type.enum';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { BaseRegistryService } from './base-registry.service';
import { Injectable, Type } from '@angular/core';
import { inject, Injectable, Type } from '@angular/core';
import { CustomComponent } from '../shared/custom-component';
import { CustomRegistryItem } from '../shared/custom-registry-item';
import { CustomRegistryType } from '../shared/custom-registry-type.enum';
import { GridElementInfo, GridSettingsRegistryService } from './grid-settings-registry.service';
import { EXECUTION_REPORT_GRID } from '../../execution-common/types/execution-report-grid';

export interface ExecutionCustomPanelMetadata {
export interface ExecutionCustomPanelMetadata extends Omit<GridElementInfo, 'id' | 'title'> {
cssClassName?: string;
colSpan?: number;
}

export interface ExecutionCustomPanelRegistryItem extends CustomRegistryItem {
Expand All @@ -19,6 +20,8 @@ export type ExecutionCustomPanelItemInfo = Pick<ExecutionCustomPanelRegistryItem
providedIn: 'root',
})
export class ExecutionCustomPanelRegistryService extends BaseRegistryService {
private _gridSettingsRegistry = inject(GridSettingsRegistryService);

protected override readonly registryType = CustomRegistryType.EXECUTION_CUSTOM_PANEL;

override register(
Expand All @@ -29,6 +32,16 @@ export class ExecutionCustomPanelRegistryService extends BaseRegistryService {
): void {
const item: ExecutionCustomPanelRegistryItem = { type, label, component, metadata };
this._customRegistry.register(this.registryType, type, item);
if (metadata) {
const { weight, widthInCells, heightInCells } = metadata;
this._gridSettingsRegistry.register(EXECUTION_REPORT_GRID, {
id: type,
title: label,
weight,
widthInCells,
heightInCells,
});
}
}

override getItemInfos(): ReadonlyArray<ExecutionCustomPanelItemInfo> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';

export interface GridElementInfo {
id: string;
title: string;
weight: number;
widthInCells: number;
heightInCells: number;
minWidthInCells?: number;
minHeightInCells?: number;
}

@Injectable({
providedIn: 'root',
})
export class GridSettingsRegistryService {
private girdSettings: Map<string, GridElementInfo[]> = new Map();

register(gridId: string, gridElement: GridElementInfo): void {
if (!this.girdSettings.has(gridId)) {
this.girdSettings.set(gridId, []);
}
this.girdSettings.get(gridId)!.push(gridElement);
}

getSettings(gridId: string): ReadonlyArray<GridElementInfo> {
return (this.girdSettings.get(gridId) ?? []).map((item) => ({ ...item }));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ng-content />
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from '@angular/core';
import { GridDragHandleDirective } from '../../directives/grid-drag-handle.directive';

@Component({
selector: 'step-grid-drag-handle',
imports: [],
templateUrl: './grid-drag-handle.component.html',
styleUrl: './grid-drag-handle.component.scss',
hostDirectives: [GridDragHandleDirective],
})
export class GridDragHandleComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ displayTitle() }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Component, computed, inject } from '@angular/core';
import { GRID_LAYOUT_CONFIG } from '../../injectables/grid-layout-config.token';
import { GridElementDirective } from '../../directives/grid-element.directive';

@Component({
selector: 'step-grid-element-title',
imports: [],
templateUrl: './grid-element-title.component.html',
styleUrl: './grid-element-title.component.scss',
})
export class GridElementTitleComponent {
private _gridConfig = inject(GRID_LAYOUT_CONFIG);
private _gridElement = inject(GridElementDirective);

protected readonly displayTitle = computed(() => {
const id = this._gridElement.elementId();
const title = this._gridConfig.defaultElementParamsMap[id]?.title;
return title ?? id;
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<ng-content />
@if (_gridEditable.editMode()) {
@for (hiddenWidget of hiddenWidgets(); track hiddenWidget) {
<section class="hidden-placeholder" [stepGridElement]="hiddenWidget">
<step-grid-drag-handle />
<step-grid-element-title />
<step-grid-resizer />
</section>
}
}
<div #preview class="preview" [class.preview-invalid]="invalidPreview()"></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
@use 'projects/step-core/styles/core-variables' as var;

step-grid-layout {
$cols-count: var(--style__cols-count);

display: grid;
grid-template-columns: repeat($cols-count, calc((100% / $cols-count) - 1.5rem));
grid-auto-rows: 13rem;
row-gap: 2.4rem;
column-gap: 1.5rem;
position: relative;

&.hidden {
visibility: hidden;
}

.step-grid-element {
position: relative;

step-grid-drag-handle {
display: none;
position: absolute;
background: var.$gray-400;
opacity: 0.1;
min-height: 3rem;
top: 0;
left: 0;
width: 100%;
z-index: 5;
}

step-grid-resizer {
display: none;
position: absolute;
bottom: 0.2rem;
right: 0.2rem;
}
}

.preview {
border-style: solid;
border-width: 0.1rem;
background: var.$blue-50;
border-color: var.$blue-600;
opacity: 0.5;
border-radius: 0.5rem;
position: absolute;
display: none;

$animation-duration: 0.2s;
transition:
top $animation-duration ease,
left $animation-duration ease,
width $animation-duration ease,
height $animation-duration ease;

&.preview-invalid {
background: var.$red-50;
border-color: var.$red-650;
}
}

&.show-preview {
.preview {
display: block;
}
}

&.is-resize {
cursor: nwse-resize;
}

&.edit-mode .step-grid-element {
step-grid-drag-handle,
step-grid-resizer {
display: block;
}
.step-grid-drag-handle {
cursor: grab;
}
}

.hidden-placeholder {
border: dashed 0.1rem var.$black;
display: flex;
flex-direction: column;
align-items: center;

step-grid-element-title {
$size: 1.6rem;
font-size: $size;
position: absolute;
top: calc(50% - ($size / 2));
}

/*
.drag-handle {
background: var.$gray-50;
min-height: 3rem;
width: 100%;
}
*/
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {
afterNextRender,
AfterViewInit,
Component,
computed,
contentChildren,
effect,
ElementRef,
inject,
signal,
untracked,
viewChild,
ViewEncapsulation,
} from '@angular/core';
import { StepBasicsModule } from '../../../basics/step-basics.module';
import { WidgetsPositionsStateService } from '../../injectables/widgets-positions-state.service';
import { GridDimensionsDirective } from '../../directives/grid-dimensions.directive';
import { GridElementResizerService } from '../../injectables/grid-element-resizer.service';
import { GridElementDragService } from '../../injectables/grid-element-drag.service';
import { GRID_COLUMN_COUNT } from '../../injectables/grid-column-count.token';
import { GridEditableDirective } from '../../directives/grid-editable.directive';
import { GridEditableService } from '../../injectables/grid-editable.service';
import { GRID_LAYOUT_CONFIG } from '../../injectables/grid-layout-config.token';
import { GridElementDirective } from '../../directives/grid-element.directive';
import { GridResizerComponent } from '../grid-resizer/grid-resizer.component';
import { GridElementTitleComponent } from '../grid-element-title/grid-element-title.component';
import { GridDragHandleComponent } from '../grid-drag-handle/grid-drag-handle.component';

@Component({
selector: 'step-grid-layout',
imports: [
StepBasicsModule,
GridElementDirective,
GridResizerComponent,
GridElementTitleComponent,
GridDragHandleComponent,
],
templateUrl: './grid-layout.component.html',
styleUrl: './grid-layout.component.scss',
encapsulation: ViewEncapsulation.None,
host: {
'[class.show-preview]': 'showPreview()',
'[class.is-resize]': 'isResize()',
'[class.edit-mode]': '_gridEditable.editMode()',
'[class.hidden]': '!isInitialised()',
'[style.--style__cols-count]': '_colCount',
},
hostDirectives: [
GridDimensionsDirective,
{
directive: GridEditableDirective,
inputs: ['editMode'],
},
],
providers: [WidgetsPositionsStateService, GridElementResizerService, GridElementDragService],
})
export class GridLayoutComponent implements AfterViewInit {
protected readonly _colCount = inject(GRID_COLUMN_COUNT);
protected readonly _gridEditable = inject(GridEditableService);
private _gridLayoutConfig = inject(GRID_LAYOUT_CONFIG);
private _gridElementResizer = inject(GridElementResizerService);
private _gridElementDragService = inject(GridElementDragService);
private _widgetPositions = inject(WidgetsPositionsStateService);

private readonly isRenderComplete = signal(false);
private readonly preview = viewChild<ElementRef<HTMLDivElement>>('preview');
protected readonly isInitialised = computed(() => this._widgetPositions.isInitialized());

protected readonly isResize = computed(() => this._gridElementResizer.resizeInProgress());

protected readonly showPreview = computed(() => {
const isResize = this.isResize();
const isDrag = this._gridElementDragService.dragInProgress();
return !!isResize || !!isDrag;
});

protected readonly invalidPreview = computed(() => this._gridElementDragService.dragNotApplied());

private allWidgets = this._gridLayoutConfig.defaultElementParams.map((item) => item.id);
private readonly renderedWidgets = contentChildren(GridElementDirective);
private readonly renderedWidgetsIds = computed(() => {
const renderedWidgets = this.renderedWidgets();
const ids = renderedWidgets.map((item) => untracked(() => item.elementId()));
return new Set(ids);
});

protected readonly hiddenWidgets = computed(() => {
const renderedWidgetsIds = this.renderedWidgetsIds();
return this.allWidgets.filter((id) => !renderedWidgetsIds.has(id));
});

private effectHiddenWidgetsChange = effect(() => {
const hiddenWidgets = this.hiddenWidgets();
const isRenderComplete = this.isRenderComplete();
if (isRenderComplete) {
this._widgetPositions.setHiddenWidgets(hiddenWidgets);
}
});

constructor() {
afterNextRender(() => this.isRenderComplete.set(true));
}

ngAfterViewInit(): void {
const previewElement = untracked(() => this.preview())!.nativeElement;
this._gridElementResizer.setupPreviewElement(previewElement);
this._gridElementDragService.setupPreviewElement(previewElement);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<step-icon name="maximize-2" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
step-icon {
transform: rotateX(180deg);
&:hover {
cursor: nwse-resize;
}
}
Loading