mirror of
https://github.com/clearml/clearml-web
synced 2025-03-13 15:20:35 +00:00
Added pipeline parameters component and integrated with pipeline dialog.
This commit is contained in:
parent
6f37b4ee0d
commit
ca102ecd2c
@ -1,6 +1,7 @@
|
||||
import {ProjectsGetAllResponseSingleSubProjects} from '~/business-logic/model/projects/projectsGetAllResponseSingleSubProjects';
|
||||
import {Stats} from '~/business-logic/model/projects/stats';
|
||||
import {ProjectsGetAllResponseSingleDatasetStats} from '~/business-logic/model/projects/projectsGetAllResponseSingleDatasetStats';
|
||||
import { PipelinesParameter } from './pipelinesParameter';
|
||||
|
||||
/**
|
||||
* pipelines
|
||||
@ -69,5 +70,5 @@ export interface Pipeline {
|
||||
own_models?: number;
|
||||
hidden?: boolean;
|
||||
|
||||
parameters?: Array<object>
|
||||
parameters?: Array<PipelinesParameter>
|
||||
}
|
||||
|
21
src/app/business-logic/model/pipelines/pipelinesParameter.ts
Normal file
21
src/app/business-logic/model/pipelines/pipelinesParameter.ts
Normal file
@ -0,0 +1,21 @@
|
||||
export interface PipelinesParameter {
|
||||
id?: string;
|
||||
/**
|
||||
* Name of the parameter. The combination of section and name should be unique
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Value of the parameter
|
||||
*/
|
||||
value?: string;
|
||||
/**
|
||||
* Type of the parameter. Optional
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* The parameter description. Optional
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
default?:string;
|
||||
}
|
@ -52,6 +52,34 @@
|
||||
<textarea class="pipeline-description" name="description" matInput [(ngModel)]="pipeline.description"
|
||||
#description="ngModel"></textarea>
|
||||
</mat-form-field>
|
||||
<div class="parameters">
|
||||
<div class="search">
|
||||
<mat-label>Parameters</mat-label>
|
||||
<sm-search search-button
|
||||
#search
|
||||
class="table-search"
|
||||
[value]="searchedText"
|
||||
[enableNavigation]="true"
|
||||
[minimumChars]="1"
|
||||
[debounceTime]="0"
|
||||
[expandOnHover]="true"
|
||||
[searchResultsCount]="searchResultsCount"
|
||||
[searchCounterIndex]="pipelineParamsForm.matchIndex"
|
||||
(valueChanged)="searchTable($event)"
|
||||
></sm-search>
|
||||
</div>
|
||||
<sm-pipeline-parameters
|
||||
#pipelineParamsForm
|
||||
class="form-section"
|
||||
[section]=""
|
||||
[formData]="pipeline?.parameters"
|
||||
(formDataChanged)="onFormValuesChanged($event)"
|
||||
(searchCounterChanged)="searchCounterChanged($event)"
|
||||
(resetSearch)="search.clear(false)"
|
||||
(scrollToResultCounterReset)="scrollIndexCounterReset()"
|
||||
></sm-pipeline-parameters>
|
||||
</div>
|
||||
|
||||
<div class="w-100 create-pipeline-button">
|
||||
<button class="btn btn-dark-fill center" data-id="Create Pipeline" [disabled]="pipelineForm.invalid"
|
||||
(click)="send()">CREATE PIPELINE
|
||||
|
@ -1,7 +1,37 @@
|
||||
@import "variables";
|
||||
|
||||
:host {
|
||||
.create-report-button {
|
||||
padding: 32px 12px 0;
|
||||
}
|
||||
|
||||
.parameters {
|
||||
display: block;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
margin-bottom: 50px;
|
||||
|
||||
sm-pipeline-parameters {
|
||||
display: block;
|
||||
height: 124px;
|
||||
}
|
||||
|
||||
div.search {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 8px;
|
||||
// padding-right: 4px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
sm-search.table-search {
|
||||
border-radius: 4px;
|
||||
color: $blue-280 !important;
|
||||
background-color: $blue-600 !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
width: 100%;
|
||||
|
||||
@ -9,4 +39,4 @@
|
||||
min-height: 68px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
@ -16,6 +17,9 @@ import {rootProjectsPageSize} from '@common/constants';
|
||||
import {
|
||||
IOption
|
||||
} from '@common/shared/ui-components/inputs/select-autocomplete-with-chips/select-autocomplete-with-chips.component';
|
||||
import { PipelinesParameter } from '~/business-logic/model/pipelines/pipelinesParameter';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { PipelineParametersComponent } from '@common/pipelines/pipeline-parameters/pipeline-parameters.component';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -37,16 +41,29 @@ export class CreateNewPipelineFormComponent implements OnChanges, OnDestroy {
|
||||
|
||||
public pipelinesNames: Array<string>;
|
||||
public projectsNames: Array<string>;
|
||||
public pipeline: { name: string; description: string; project: { label: string; value: string }, parameters: Array<object>, tags: Array<string> } = {
|
||||
public pipeline: { name: string; description: string; project: { label: string; value: string }, parameters: Array<PipelinesParameter>, tags: Array<string> } = {
|
||||
name: null,
|
||||
description: '',
|
||||
project: null,
|
||||
parameters: [],
|
||||
parameters: [{
|
||||
name: "Paramter1",
|
||||
value: ""
|
||||
}, {
|
||||
name: "Parameter2",
|
||||
value: ""
|
||||
}],
|
||||
tags: [],
|
||||
};
|
||||
filterText: string = '';
|
||||
isAutoCompleteOpen: boolean;
|
||||
|
||||
// for parameters
|
||||
@ViewChild('pipelineParamsForm', {static: false}) pipelineParamsForm: PipelineParametersComponent;
|
||||
public searchedText: string;
|
||||
public searchResultsCount: number;
|
||||
public scrollIndexCounter: number;
|
||||
public size$: Observable<number>;
|
||||
|
||||
@Input() readOnlyProjectsNames: string[];
|
||||
@Input() defaultProjectId: string;
|
||||
public loading: boolean;
|
||||
@ -66,6 +83,24 @@ export class CreateNewPipelineFormComponent implements OnChanges, OnDestroy {
|
||||
this.projectsNames = this.projectsOptions.map(project => project.label);
|
||||
}
|
||||
|
||||
constructor(/* private store: Store, protected router: Router, */ private cdr: ChangeDetectorRef) {
|
||||
// this.selectedSectionHyperParams$ = this.store.select(selectExperimentHyperParamsSelectedSectionParams);
|
||||
// this.editable$ = this.store.select(selectIsExperimentEditable);
|
||||
// this.selectedSection$ = this.store.select(selectExperimentHyperParamsSelectedSectionFromRoute);
|
||||
// this.isInDev$ = this.store.select(selectIsSelectedExperimentInDev);
|
||||
// this.saving$ = this.store.select(selectIsExperimentSaving);
|
||||
// this.backdropActive$ = this.store.select(selectBackdropActive);
|
||||
// this.routerConfig$ = this.store.select(selectRouterConfig);
|
||||
// this.selectedExperiment$ = this.store.select(selectSelectedExperiment);
|
||||
// this.size$ = this.store.select(selectSplitSize);
|
||||
|
||||
// this.store.dispatch(setExperimentFormErrors({errors: null}));
|
||||
// this.selectedSectionSubscription = this.selectedSection$.subscribe(section => {
|
||||
// this.selectedSection = section;
|
||||
// this.propSection = section === 'properties';
|
||||
// });
|
||||
}
|
||||
|
||||
get projects() {
|
||||
return this._projects;
|
||||
}
|
||||
@ -116,6 +151,9 @@ export class CreateNewPipelineFormComponent implements OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
send() {
|
||||
if (this.pipelineParamsForm.formData.length > 0) {
|
||||
this.pipeline.parameters = cloneDeep(this.pipelineParamsForm.formData);
|
||||
}
|
||||
this.pipelineCreated.emit(this.pipeline);
|
||||
}
|
||||
|
||||
@ -134,5 +172,35 @@ export class CreateNewPipelineFormComponent implements OnChanges, OnDestroy {
|
||||
isFocused(locationRef: HTMLInputElement) {
|
||||
return document.activeElement === locationRef;
|
||||
}
|
||||
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
searchTable(value: string) {
|
||||
// const searchBackward = value === null;
|
||||
// if (this.searchedText !== value && !searchBackward) {
|
||||
// this.searchedText = value;
|
||||
// this.scrollIndexCounter = -1;
|
||||
// this.searchResultsCount = 0;
|
||||
// // this.executionParamsForm.resetIndex();
|
||||
// this.cdr.detectChanges();
|
||||
// }
|
||||
// // this.executionParamsForm.jumpToNextResult(!searchBackward);
|
||||
}
|
||||
|
||||
searchCounterChanged(count: number) {
|
||||
this.searchResultsCount = count;
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
||||
scrollIndexCounterReset() {
|
||||
this.scrollIndexCounter = -1;
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
||||
onFormValuesChanged(event: { field: string; value: any }) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(event);
|
||||
// this.store.dispatch(updateExperimentAtPath({path: ('hyperparams.' + event.field), value: event.value}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
:host{
|
||||
width: 640px;
|
||||
width: 690px;
|
||||
display: block;
|
||||
}
|
||||
|
@ -0,0 +1,115 @@
|
||||
<form [class.editable]="editable" #hyperParameters="ngForm">
|
||||
<cdk-virtual-scroll-viewport #formContainer class="form-container" itemSize="58" minBufferPx="280" >
|
||||
<ng-container *ngIf="editable">
|
||||
<div *ngFor="let parameter of formData; let index= index" class="w-100 d-flex">
|
||||
<mat-form-field
|
||||
[hintLabel]="parameterKey.invalid && parameterKey?.errors?.required? '*Required': ''"
|
||||
appearance="outline"
|
||||
class="strength"
|
||||
>
|
||||
<input
|
||||
#parameterKey="ngModel"
|
||||
#row="matInput"
|
||||
[(ngModel)]="parameter['name']"
|
||||
(keydown.enter)="nextRow($event, index)"
|
||||
placeholder="Parameter"
|
||||
name="parameterKey-{{parameter.name}}-{{index}}"
|
||||
matInput
|
||||
smUniqueNameValidator
|
||||
[class.highlight-text]="(searchedText?.length > 0) && parameter['name'].includes(searchedText)"
|
||||
[class.current-match]="searchIndexList[matchIndex]?.index===index && searchIndexList[matchIndex]?.col==='name'"
|
||||
[existingNames]="formNames(parameter.name)"
|
||||
required/>
|
||||
<mat-error *ngIf="parameterKey.invalid && parameterKey?.errors?.required">
|
||||
Required
|
||||
</mat-error>
|
||||
<mat-error *ngIf="parameterKey.invalid && parameterKey?.errors?.smNotAllowedStringsValidator">
|
||||
.(dot) $(dollar) and space are not allowed in parameter key.
|
||||
</mat-error>
|
||||
<mat-error *ngIf="!parameterKey?.errors?.required && parameterKey.invalid && parameterKey?.errors?.uniqueName">
|
||||
key already exists
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline"
|
||||
class="strength">
|
||||
<input
|
||||
#parameterValue="ngModel"
|
||||
[(ngModel)]="parameter['value']"
|
||||
(keydown.enter)="nextRow($event, index)"
|
||||
name="parameterValue-{{parameter.name}}-{{index}}"
|
||||
placeholder="Value"
|
||||
[class.highlight-text]="(searchedText?.length > 0) && parameter['value'].includes(searchedText)"
|
||||
[class.current-match]="searchIndexList[matchIndex]?.index===index && searchIndexList[matchIndex]?.col==='value'"
|
||||
matInput/>
|
||||
</mat-form-field>
|
||||
<button class="remove-button btn" (click)="removeRow(index)">
|
||||
<i class="al-icon al-ico-trash al-color blue-400 sm-md pointer flashing-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
<button *ngIf="editable" class="btn btn-dark-fill add-parameter" (click)="addRow()"><i class="fas fa-plus" data-id="AddParamterButton"></i> ADD PARAMETER</button>
|
||||
</form>
|
||||
|
||||
<!-- <div class="table-container" *ngIf="!editable">
|
||||
<sm-table
|
||||
[columns]="cols"
|
||||
columnResizeMode="fit"
|
||||
[tableData]="formData"
|
||||
[enableTableSearch]="true"
|
||||
[globalFilterFields]="['name', 'value','description']"
|
||||
[noHeader]="true"
|
||||
[simple]="true"
|
||||
[scrollable]="true"
|
||||
[virtualScrollOptions]="{ trackBy: trackByIndex, appendOnly: true, delay: 0, orientation: 'vertical', items: formData, itemSize: 32}"
|
||||
[virtualScroll]="true"
|
||||
[rowHeight]="32"
|
||||
(rowClicked)="rowActivated($event)"
|
||||
>
|
||||
<ng-template pTemplate="body"
|
||||
let-col
|
||||
let-i="rowIndex"
|
||||
let-row="rowData">
|
||||
<ng-container [ngSwitch]="col.id">
|
||||
<ng-container *ngSwitchCase="'description'">
|
||||
<span *ngIf="row.type!=='legacy' && (row.description || row.type)"
|
||||
class="allow-multi-space pointer"
|
||||
customClass="hyper-parameters-tooltip parameter-tooltip"
|
||||
smTooltip="{{(row.type ? ('Type: '+ row.type+'\n') : '') + (row?.description|| '')}}"
|
||||
matTooltipPosition="before"
|
||||
><i class="al-icon al-ico-description"></i></span>
|
||||
</ng-container>
|
||||
<span
|
||||
*ngSwitchCase="'name'"
|
||||
class="ellipsis name"
|
||||
smShowTooltipIfEllipsis
|
||||
matTooltipPosition="before"
|
||||
[matTooltipShowDelay]="250"
|
||||
[smTooltip]="row.name"
|
||||
[smSearchText]="searchedText"
|
||||
highlightClass="highlight-text"
|
||||
[class.current-match]="searchIndexList[matchIndex]?.index===i && searchIndexList[matchIndex]?.col==='name'"
|
||||
>{{row.name}}</span>
|
||||
<ng-container *ngSwitchCase="'value'">
|
||||
<a *ngIf="row.section === 'Datasets' && row.value.length === 32; else: noLink"
|
||||
(click)="$event.preventDefault(); navigateToDataset(row.value)"
|
||||
href="" target="_blank"
|
||||
>{{row.value}}</a>
|
||||
<ng-template #noLink>
|
||||
<span
|
||||
class="ellipsis"
|
||||
smShowTooltipIfEllipsis
|
||||
matTooltipPosition="before"
|
||||
[matTooltipShowDelay]="250"
|
||||
[smTooltip]="row.value"
|
||||
[smSearchText]="searchedText"
|
||||
highlightClass="highlight-text"
|
||||
[class.current-match]="searchIndexList[matchIndex]?.index===i && searchIndexList[matchIndex]?.col==='value'"
|
||||
>{{row.value}}</span>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
</sm-table>
|
||||
</div> -->
|
||||
|
@ -0,0 +1,80 @@
|
||||
@import "variables";
|
||||
@import "mixins/link";
|
||||
|
||||
:host {
|
||||
@include link();
|
||||
form.editable, .table-container {
|
||||
height: 100%;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
form.editable {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
||||
input.highlight-text {
|
||||
background: $neon-yellow;
|
||||
&.current-match {
|
||||
background: #f5d655;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.param-row {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
flex: 1;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
::ng-deep tr:hover {
|
||||
cursor: auto !important;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.separator {
|
||||
width: 100%;
|
||||
//border-bottom: solid 1px #dee1e9;
|
||||
}
|
||||
|
||||
.remove-button {
|
||||
margin-bottom: 22px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.param-row {
|
||||
font-weight: 500;
|
||||
|
||||
& > div {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.current-match .highlight-text{
|
||||
background-color: #f5d655;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.allow-multi-space {
|
||||
white-space: pre;
|
||||
|
||||
}
|
||||
|
||||
.add-parameter {
|
||||
border: 1px solid $grey-purple;
|
||||
background-color: #ffffff;
|
||||
color: $grey-purple;
|
||||
transition: all ease-in-out 0.15s, border ease-in-out 0.15s;
|
||||
}
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input, OnChanges,
|
||||
OnDestroy,
|
||||
Output,
|
||||
QueryList, SimpleChanges,
|
||||
ViewChild,
|
||||
ViewChildren
|
||||
} from '@angular/core';
|
||||
import {IExperimentInfoFormComponent} from '~/features/experiments/shared/experiment-info.model';
|
||||
import {cloneDeep} from 'lodash-es';
|
||||
import {v4 as uuidV4} from 'uuid';
|
||||
import {NgForm} from '@angular/forms';
|
||||
import {ParamsItem} from '~/business-logic/model/tasks/paramsItem';
|
||||
import {ISmCol} from '@common/shared/ui-components/data/table/table.consts';
|
||||
import {CdkVirtualScrollViewport} from '@angular/cdk/scrolling';
|
||||
import {Subscription} from 'rxjs';
|
||||
// import {TableComponent} from '@common/shared/ui-components/data/table/table.component';
|
||||
import {isEqual} from 'lodash-es';
|
||||
import {MatInput} from '@angular/material/input';
|
||||
import {Store} from '@ngrx/store';
|
||||
import { navigateToDataset } from '@common/experiments/actions/common-experiments-info.actions';
|
||||
import {trackByIndex} from '@common/shared/utils/forms-track-by';
|
||||
import { PipelinesParameter } from '~/business-logic/model/pipelines/pipelinesParameter';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'sm-pipeline-parameters',
|
||||
templateUrl: './pipeline-parameters.component.html',
|
||||
styleUrls: ['./pipeline-parameters.component.scss']
|
||||
})
|
||||
export class PipelineParametersComponent implements IExperimentInfoFormComponent, OnDestroy, AfterViewInit, OnChanges {
|
||||
private _formData = [] as PipelinesParameter[];
|
||||
private formContainersSub: Subscription;
|
||||
private _editable: boolean = true;
|
||||
private formContainer: CdkVirtualScrollViewport;
|
||||
private clickedRow: number;
|
||||
|
||||
public search = '';
|
||||
public searchIndexList: {index: number; col: string}[] = [];
|
||||
public matchIndex = -1;
|
||||
public cols = [
|
||||
{id: 'name', style: {width: '300px'}},
|
||||
{id: 'value', style: {width: '300px'}},
|
||||
{id: 'description', style: {width: '48px'}}
|
||||
] as ISmCol[];
|
||||
|
||||
|
||||
@ViewChild('hyperParameters') hyperParameters: NgForm;
|
||||
// @ViewChild(TableComponent) executionParametersTable: TableComponent<PipelinesParameter>;
|
||||
|
||||
@ViewChildren('formContainer') formContainers: QueryList<CdkVirtualScrollViewport>;
|
||||
@ViewChildren('row') rows: QueryList<MatInput>;
|
||||
@ViewChild(CdkVirtualScrollViewport) viewPort: CdkVirtualScrollViewport;
|
||||
@Output() formDataChanged = new EventEmitter<{ field: string; value: ParamsItem[] }>();
|
||||
@Output() searchCounterChanged = new EventEmitter<number>();
|
||||
@Output() resetSearch = new EventEmitter();
|
||||
@Output() scrollToResultCounterReset = new EventEmitter();
|
||||
@Input() section;
|
||||
private _originalData: PipelineParametersComponent['formData'];
|
||||
|
||||
// @Input() set size(size: number) {
|
||||
// this.executionParametersTable?.resize();
|
||||
// }
|
||||
|
||||
@Input() set formData(formData) {
|
||||
this._originalData = formData;
|
||||
this._formData = cloneDeep(formData).map((row: ParamsItem) => ({...row, id: uuidV4()}));
|
||||
// console.log(this._formData);
|
||||
}
|
||||
|
||||
get formData() {
|
||||
return this._formData;
|
||||
}
|
||||
|
||||
|
||||
// @Input() set editable(editable: boolean) {
|
||||
// this._editable = editable;
|
||||
// this.executionParametersTable?.resize();
|
||||
// editable && window.setTimeout(() => this.rows.first?.focus());
|
||||
// }
|
||||
get editable() {
|
||||
return this._editable;
|
||||
}
|
||||
|
||||
@Input() searchedText: string;
|
||||
|
||||
constructor(private store: Store) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.formContainersSub = this.formContainers.changes
|
||||
.subscribe((list: QueryList<CdkVirtualScrollViewport>) => {
|
||||
this.formContainer = list.first;
|
||||
if (this.formContainer && this.clickedRow !== null) {
|
||||
this.formContainer.scrollToIndex(this.clickedRow, 'smooth');
|
||||
this.clickedRow = null;
|
||||
}
|
||||
});
|
||||
//this.executionParametersTable.resize();
|
||||
}
|
||||
|
||||
formNames(name) {
|
||||
return this.formData.filter(parameter => parameter.name !== name).map(parameter => parameter.name);
|
||||
}
|
||||
|
||||
addRow() {
|
||||
this.formData.push({
|
||||
id: uuidV4(),
|
||||
name: '',
|
||||
value: '',
|
||||
description: '',
|
||||
type: ''
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
const height = this.viewPort.elementRef.nativeElement.scrollHeight;
|
||||
this.viewPort.scrollToIndex(height, 'smooth');
|
||||
}, 50);
|
||||
}
|
||||
|
||||
removeRow(index) {
|
||||
this.formData.splice(index, 1);
|
||||
}
|
||||
|
||||
rowActivated({data}: { data: PipelinesParameter; e: MouseEvent }) {
|
||||
this.clickedRow = this.formData.findIndex(row => row.name === data.name);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.formContainersSub?.unsubscribe();
|
||||
}
|
||||
|
||||
resetIndex() {
|
||||
this.matchIndex = -1;
|
||||
}
|
||||
|
||||
jumpToNextResult(forward: boolean) {
|
||||
this.matchIndex = forward ? this.matchIndex + 1 : this.matchIndex - 1;
|
||||
if (this.editable) {
|
||||
this.viewPort.scrollToIndex(this.searchIndexList[this.matchIndex]?.index, 'smooth');
|
||||
} else {
|
||||
// this.executionParametersTable.scrollToIndex(this.searchIndexList[this.matchIndex]?.index);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes?.formData && (!changes.formData?.firstChange) && !isEqual(changes.formData.currentValue, changes.formData.previousValue)) {
|
||||
this.matchIndex = -1;
|
||||
this.searchIndexList = [];
|
||||
this.resetSearch.emit();
|
||||
}
|
||||
if (changes?.searchedText) {
|
||||
let searchResultsCounter = 0;
|
||||
const searchedIndexList = [];
|
||||
if (changes?.searchedText?.currentValue) {
|
||||
this.formData.forEach((parameter, index) => {
|
||||
if (parameter?.name.includes(changes.searchedText.currentValue)) {
|
||||
searchResultsCounter++;
|
||||
searchedIndexList.push({index, col: 'name'});
|
||||
}
|
||||
if (parameter?.value.includes(changes.searchedText.currentValue)) {
|
||||
searchResultsCounter++;
|
||||
searchedIndexList.push({index, col: 'value'});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.searchCounterChanged.emit(searchResultsCounter);
|
||||
this.scrollToResultCounterReset.emit();
|
||||
this.searchIndexList = searchedIndexList;
|
||||
}
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this._formData = cloneDeep(this._originalData).map((row: ParamsItem) => ({...row, id: uuidV4()}));
|
||||
}
|
||||
|
||||
nextRow(event: Event, index: number) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
if (this.formData.length === index + 1) {
|
||||
this.addRow();
|
||||
}
|
||||
window.setTimeout(()=> this.rows.get(index + 1)?.focus());
|
||||
}
|
||||
|
||||
navigateToDataset(datasetId: string) {
|
||||
this.store.dispatch(navigateToDataset({datasetId}));
|
||||
}
|
||||
|
||||
protected readonly trackByIndex = trackByIndex;
|
||||
}
|
@ -138,7 +138,7 @@ if __name__ == '__main__':
|
||||
this.dialog.open(PipelineDialogComponent, {
|
||||
data: {defaultProjectId: this.projectId},
|
||||
panelClass: 'light-theme',
|
||||
width: '640px'
|
||||
width: '690px'
|
||||
})
|
||||
.afterClosed()
|
||||
.subscribe(pipeline => {
|
||||
|
@ -53,6 +53,8 @@ import { createUserPrefFeatureReducer } from "@common/core/meta-reducers/user-pr
|
||||
import { PIPELINES_PREFIX } from "./pipelines.actions";
|
||||
import { PipelineAddStepDialogComponent } from "./pipeline-add-step-dialog/pipeline-add-step-dialog.component";
|
||||
import { PipelineAddStepFormComponent } from "./pipeline-add-step-dialog/pipeline-add-step-form/pipeline-add-step-form.component";
|
||||
import {SortPipe} from '@common/shared/pipes/sort.pipe';
|
||||
import { PipelineParametersComponent } from "./pipeline-parameters/pipeline-parameters.component";
|
||||
|
||||
export const pipelinesSyncedKeys = ["projects.showPipelineExamples"];
|
||||
const pipelinesSyncedKeys2 = ['orderBy', 'sortOrder'];
|
||||
@ -103,6 +105,7 @@ const getInitState = (userPreferences: UserPreferences) => ({
|
||||
PipelineAddStepFormComponent,
|
||||
EditPipelinePageComponent,
|
||||
EditPipelineHeaderComponent,
|
||||
PipelineParametersComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
@ -145,6 +148,7 @@ const getInitState = (userPreferences: UserPreferences) => ({
|
||||
ExperimentSharedModule,
|
||||
RefreshButtonComponent,
|
||||
LabeledFormFieldDirective,
|
||||
SortPipe,
|
||||
],
|
||||
exports: [PipelinesPageComponent, EditPipelinePageComponent],
|
||||
providers: [
|
||||
|
Loading…
Reference in New Issue
Block a user