mirror of
https://github.com/clearml/clearml-web
synced 2025-06-26 18:27:02 +00:00
11
angular.json
11
angular.json
@@ -60,15 +60,12 @@
|
||||
"@aws-crypto/crc32c",
|
||||
"filesize/lib/filesize.es6",
|
||||
"hex-rgb",
|
||||
"britecharts/dist/umd/donut.min",
|
||||
"britecharts/dist/umd/legend.min",
|
||||
"britecharts/dist/umd/line.min",
|
||||
"britecharts/dist/umd/tooltip.min",
|
||||
"britecharts/dist/umd/miniTooltip.min",
|
||||
"britecharts/dist/umd/scatterPlot.min",
|
||||
"britecharts",
|
||||
"localforage",
|
||||
"dom-to-image",
|
||||
"ace-builds"
|
||||
"ace-builds",
|
||||
"hocon-parser",
|
||||
"taira"
|
||||
],
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
|
||||
3421
package-lock.json
generated
3421
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clearml-webapp",
|
||||
"version": "1.11.0",
|
||||
"version": "1.12.0",
|
||||
"license": "",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
@@ -32,8 +32,8 @@
|
||||
"@angular/router": "^15.2.8",
|
||||
"@angular/service-worker": "^15.2.8",
|
||||
"@angular/youtube-player": "^15.2.8",
|
||||
"@aws-sdk/client-s3": "^3.317.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.317.0",
|
||||
"@aws-sdk/client-s3": "^3.360.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.360.0",
|
||||
"@ctrl/ngx-github-buttons": "^8.0.0",
|
||||
"@ngneat/dag": "^2.0.0",
|
||||
"@ngrx/effects": "^15.4.0",
|
||||
@@ -44,11 +44,14 @@
|
||||
"angular-google-tag-manager": "^1.7.0",
|
||||
"angular-resizable-element": "^7.0.2",
|
||||
"angular-split": "^15.0.0",
|
||||
"angular2-csv": "^0.2.9",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
"bootstrap": "^5.2.3",
|
||||
"britecharts": "^2.18.0",
|
||||
"britecharts": "^3.0.0-alpha-6.1.6",
|
||||
"curved-arrows": "^0.1.0",
|
||||
"d3-selection": "^3.0.0",
|
||||
"d3-transition": "^3.0.1",
|
||||
"d3-zoom": "^3.0.0",
|
||||
"diff": "^5.1.0",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"filesize": "^10.0.7",
|
||||
@@ -61,7 +64,7 @@
|
||||
"ngx-clipboard": "^16.0.0",
|
||||
"ngx-color-picker": "^14.0.0",
|
||||
"ngx-device-detector": "^5.0.1",
|
||||
"ngx-markdown-editor": "^5.3.0",
|
||||
"ngx-markdown-editor": "^5.3.1",
|
||||
"ngx-print": "^1.3.1",
|
||||
"ngx-window-token": "^7.0.0",
|
||||
"object-hash": "^3.0.0",
|
||||
@@ -70,6 +73,7 @@
|
||||
"process": "^0.11.10",
|
||||
"rxjs": "^7.8.0",
|
||||
"string-to-color": "^2.2.2",
|
||||
"taira": "^3.2.2",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"tslib": "^2.5.0",
|
||||
"url": "^0.11.0",
|
||||
@@ -96,7 +100,7 @@
|
||||
"@types/lodash-es": "^4.17.7",
|
||||
"@types/node": "^18.16.0",
|
||||
"@types/plotly.js": "^2.12.18",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.1",
|
||||
"@typescript-eslint/parser": "^5.59.1",
|
||||
"codelyzer": "^6.0.2",
|
||||
@@ -106,4 +110,4 @@
|
||||
"eslint-plugin-prefer-arrow": "1.2.3",
|
||||
"typescript": "~4.9.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const targets = [
|
||||
'https://demoapi.trains.allegro.ai', // 1
|
||||
'https://api.trains-master.hosted.allegro.ai', // 1
|
||||
];
|
||||
|
||||
const PROXY_CONFIG = {
|
||||
|
||||
@@ -135,7 +135,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
pageName: item.url
|
||||
};
|
||||
this.gtmService?.pushTag(gtmTag);
|
||||
this.store.dispatch(new routerActions.NavigationEnd());
|
||||
this.store.dispatch(routerActions.navigationEnd());
|
||||
});
|
||||
|
||||
this.selectedCurrentUserSubscription = this.selectedCurrentUser$.pipe(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Action} from '@ngrx/store';
|
||||
import {createAction} from '@ngrx/store';
|
||||
import {Environment} from '../environments/base';
|
||||
|
||||
export const NA = 'N/A';
|
||||
@@ -19,12 +19,14 @@ export const BASE_REGEX = {
|
||||
FOLDER : '\\/\\S*[^\\/ ]',
|
||||
S3_BUCKET_NAME : '(?!(xn--|.+-s3alias$|.*\\.{2}.*))[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]',
|
||||
GS_BUCKET_NAME : '(\\w[A-Za-z0-9\\-_]+\\w\\.)*\\w[A-Za-z0-9\\-_]+\\w',
|
||||
AZURE_BUCKET_NAME: '(\\w[A-Za-z0-9\\-_]+\\w\\.)*\\w[A-Za-z0-9\\-_]+\\w'
|
||||
AZURE_BUCKET_NAME: '(\\w[A-Za-z0-9\\-_]+\\w\\.)*\\w[A-Za-z0-9\\-_]+\\w',
|
||||
AZURE_CONTAINER: '\\/[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]'
|
||||
};
|
||||
|
||||
export const URI_REGEX = {
|
||||
S3_WITH_BUCKET : BASE_REGEX.S3_PROTOCOL + BASE_REGEX.S3_BUCKET_NAME + BASE_REGEX.PATH,
|
||||
GS_WITH_BUCKET : BASE_REGEX.GS_PROTOCOL + BASE_REGEX.GS_BUCKET_NAME + BASE_REGEX.PATH,
|
||||
AZURE_WITH_BUCKET: BASE_REGEX.AZURE_PROTOCOL + BASE_REGEX.AZURE_BUCKET_NAME + BASE_REGEX.AZURE_CONTAINER,
|
||||
S3_WITH_BUCKET_AND_HOST : BASE_REGEX.S3_PROTOCOL + BASE_REGEX.S3_BUCKET_NAME + BASE_REGEX.DOMAIN + BASE_REGEX.PATH,
|
||||
GS_WITH_BUCKET_AND_HOST : BASE_REGEX.GS_PROTOCOL + BASE_REGEX.GS_BUCKET_NAME + BASE_REGEX.DOMAIN + BASE_REGEX.PATH,
|
||||
AZURE_WITH_BUCKET_AND_HOST: BASE_REGEX.AZURE_PROTOCOL + BASE_REGEX.AZURE_BUCKET_NAME + BASE_REGEX.DOMAIN + BASE_REGEX.PATH,
|
||||
@@ -52,13 +54,6 @@ export const TASK_TYPES = {
|
||||
TESTING : 'testing',
|
||||
};
|
||||
|
||||
const recentTasksPrefix = 'RECENT_TASKS';
|
||||
|
||||
export const RECENT_TASKS_ACTIONS = {
|
||||
GET_RECENT_TASKS: recentTasksPrefix + 'GET_RECENT_TASKS',
|
||||
SET_RECENT_TASKS: recentTasksPrefix + 'SET_RECENT_TASKS'
|
||||
};
|
||||
|
||||
export const VIEW_PREFIX = 'VIEW_';
|
||||
|
||||
export type MediaContentTypeEnum = 'image/bmp' | 'image/jpeg' | 'image/png' | 'video/mp4';
|
||||
@@ -75,23 +70,8 @@ export const MESSAGES_SEVERITY = {
|
||||
};
|
||||
|
||||
export const USERS_PREFIX = 'USERS_';
|
||||
export const USERS_ACTIONS = {
|
||||
FETCH_CURRENT_USER: USERS_PREFIX + 'FETCH_USER',
|
||||
SET_CURRENT_USER : USERS_PREFIX + 'SET_CURRENT_USER',
|
||||
LOGOUT_SUCCESS : USERS_PREFIX + 'LOGOUT_SUCCESS',
|
||||
LOGOUT : USERS_PREFIX + 'LOGOUT',
|
||||
SET_PREF : USERS_PREFIX + 'SET_PREF'
|
||||
};
|
||||
|
||||
export const NAVIGATION_PREFIX = 'NAVIGATION_';
|
||||
export const NAVIGATION_ACTIONS = {
|
||||
NAVIGATE_TO : NAVIGATION_PREFIX + 'NAVIGATE_TO',
|
||||
NAVIGATION_END : NAVIGATION_PREFIX + 'NAVIGATION_END',
|
||||
SET_ROUTER_SEGMENT : NAVIGATION_PREFIX + 'SET_ROUTER_SEGMENT',
|
||||
UPDATATE_CURRENT_URL_WITHOUT_NAVIGATING: NAVIGATION_PREFIX + 'UPDATATE_CURRENT_URL_WITHOUT_NAVIGATING',
|
||||
NAVIGATION_SKIPPED : NAVIGATION_PREFIX + 'NAVIGATION_SKIPPED',
|
||||
};
|
||||
|
||||
|
||||
export const guessAPIServerURL = () => {
|
||||
const url = window.location.origin;
|
||||
@@ -145,8 +125,7 @@ export const updateHttpUrlBaseConstant = (_environment: Environment) => {
|
||||
|
||||
export const HTTP_PREFIX = 'HTTP_';
|
||||
|
||||
export class EmptyAction implements Action {
|
||||
readonly type = 'EMPTY_ACTION';
|
||||
}
|
||||
export const emptyAction = createAction('EMPTY_ACTION');
|
||||
|
||||
|
||||
export const AUTO_REFRESH_INTERVAL = 10 * 1000;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Routes} from '@angular/router';
|
||||
import {ProjectRedirectGuardGuard} from '@common/shared/guards/project-redirect.guard';
|
||||
import {projectRedirectGuardGuard} from '@common/shared/guards/project-redirect.guard';
|
||||
import {EntityTypeEnum} from '~/shared/constants/non-common-consts';
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export const routes: Routes = [
|
||||
path: ':projectId',
|
||||
data: {search: true},
|
||||
children: [
|
||||
{path: '', pathMatch: 'full', children: [], canActivate: [ProjectRedirectGuardGuard]},
|
||||
{path: '', pathMatch: 'full', children: [], canActivate: [projectRedirectGuardGuard]},
|
||||
{path: '', redirectTo: '*', pathMatch: 'full'},
|
||||
{path: 'overview', loadChildren: () => import('./webapp-common/project-info/project-info.module').then(m => m.ProjectInfoModule)},
|
||||
{path: 'projects', loadChildren: () => import('./features/projects/projects.module').then(m => m.ProjectsModule)},
|
||||
@@ -66,7 +66,8 @@ export const routes: Routes = [
|
||||
path: ':projectId',
|
||||
children: [
|
||||
{path: 'pipelines', loadChildren: () => import('@common/pipelines/pipelines.module').then(m => m.PipelinesModule)},
|
||||
{path: 'projects', loadChildren: () => import('@common/nested-project-view/nested-project-view.module').then(m => m.NestedProjectViewModule)},
|
||||
{path: 'projects', loadComponent: () => import('@common/pipelines/nested-pipeline-page/nested-pipeline-page.component')
|
||||
.then(m => m.NestedPipelinePageComponent)},
|
||||
{
|
||||
path: 'experiments', loadChildren: () => import('@common/pipelines-controller/pipelines-controller.module').then(m => m.PipelinesControllerModule)
|
||||
},
|
||||
|
||||
@@ -30,6 +30,7 @@ import { OrganizationGetEntitiesCountResponse } from '../model/organization/orga
|
||||
|
||||
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
||||
import { Configuration } from '../configuration';
|
||||
import {OrganizationPrepareDownloadForGetAllRequest} from '~/business-logic/model/organization/organizationPrepareDownloadForGetAllRequest';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@@ -65,7 +66,7 @@ export class ApiOrganizationService {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Get all the user and system tags used for the company tasks and models
|
||||
* @param request request body
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
@@ -110,7 +111,7 @@ export class ApiOrganizationService {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Get details for all companies associated with the current user
|
||||
* @param request request body
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
@@ -154,7 +155,51 @@ export class ApiOrganizationService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
*
|
||||
* Prepares download from get_all_ex parameters
|
||||
* @param request request body
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public organizationPrepareDownloadForGetAll(request: OrganizationPrepareDownloadForGetAllRequest, options?: any, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
|
||||
if (request === null || request === undefined) {
|
||||
throw new Error('Required parameter request was null or undefined when calling organizationPrepareDownloadForGetAll.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
if (options && options.async_enable) {
|
||||
headers = headers.set(this.configuration.asyncHeader, '1');
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = [
|
||||
];
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected != undefined) {
|
||||
headers = headers.set("Accept", httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = [
|
||||
];
|
||||
const httpContentTypeSelected:string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||
if (httpContentTypeSelected != undefined) {
|
||||
headers = headers.set("Content-Type", httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.apiRequest.post<any>(`${this.basePath}/organization.prepare_download_for_get_all`,
|
||||
request,
|
||||
{
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get counts for the company entities according to the passed search criteria
|
||||
* @param request request body
|
||||
|
||||
@@ -27,6 +27,8 @@ import { PipelinesStartPipelineResponse } from '../model/pipelines/pipelinesStar
|
||||
|
||||
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
||||
import { Configuration } from '../configuration';
|
||||
import {PipelinesDeleteRunsRequest} from '~/business-logic/model/pipelines/pipelinesDeleteRunsRequest';
|
||||
import {PipelinesDeleteRunsResponse} from '~/business-logic/model/pipelines/pipelinesDeleteRunsResponse';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@@ -60,6 +62,51 @@ export class ApiPipelinesService {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Delete pipeline runs
|
||||
* @param request request body
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public pipelinesDeleteRuns(request: PipelinesDeleteRunsRequest, options?: any, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
|
||||
if (request === null || request === undefined) {
|
||||
throw new Error('Required parameter request was null or undefined when calling pipelinesDeleteRuns.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
if (options && options.async_enable) {
|
||||
headers = headers.set(this.configuration.asyncHeader, '1');
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = [
|
||||
'application/json'
|
||||
];
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected != undefined) {
|
||||
headers = headers.set("Accept", httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = [
|
||||
];
|
||||
const httpContentTypeSelected:string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||
if (httpContentTypeSelected != undefined) {
|
||||
headers = headers.set("Content-Type", httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.apiRequest.post<PipelinesDeleteRunsResponse>(`${this.basePath}/pipelines.delete_runs`,
|
||||
request,
|
||||
{
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -65,6 +65,8 @@ import {ProjectsGetProjectTagsResponse} from '~/business-logic/model/projects/pr
|
||||
import {ProjectsGetProjectTagsRequest} from '~/business-logic/model/projects/projectsGetProjectTagsRequest';
|
||||
import {ProjectsGetModelMetadataValuesRequest} from '~/business-logic/model/projects/projectsGetModelMetadataValuesRequest';
|
||||
import {ProjectsGetModelMetadataValuesResponse} from '~/business-logic/model/projects/projectsGetModelMetadataValuesResponse';
|
||||
import {ProjectsGetUserNamesResponse} from '~/business-logic/model/projects/projectsGetUserNamesResponse';
|
||||
import {ProjectsGetUserNamesRequest} from '~/business-logic/model/projects/projectsGetUserNamesRequest';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@@ -821,6 +823,53 @@ export class ApiProjectsService {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Get names and ids of the users who created child entitites under the passed projects
|
||||
* @param request request body
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public projectsGetUserNames(request: ProjectsGetUserNamesRequest, options?: any, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
|
||||
if (request === null || request === undefined) {
|
||||
throw new Error('Required parameter request was null or undefined when calling projectsGetUserNames.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
if (options && options.async_enable) {
|
||||
headers = headers.set(this.configuration.asyncHeader, '1');
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = [
|
||||
'application/json'
|
||||
];
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected != undefined) {
|
||||
headers = headers.set("Accept", httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = [
|
||||
];
|
||||
const httpContentTypeSelected:string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||
if (httpContentTypeSelected != undefined) {
|
||||
headers = headers.set("Content-Type", httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.apiRequest.post<ProjectsGetUserNamesResponse>(`${this.basePath}/projects.get_user_names`,
|
||||
request,
|
||||
{
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Moves all the source project\'s contents to the destination project and remove the source project
|
||||
|
||||
28
src/app/business-logic/model/organization/fieldMapping.ts
Normal file
28
src/app/business-logic/model/organization/fieldMapping.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* organization
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface FieldMapping {
|
||||
/**
|
||||
* The source column name as specified in the only_fields
|
||||
*/
|
||||
field: string;
|
||||
/**
|
||||
* The column name in the exported csv file
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* The column values mapping
|
||||
*/
|
||||
values?: {key: any; value: any}[];
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* organization
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { FieldMapping } from '././fieldMapping';
|
||||
|
||||
|
||||
export interface OrganizationPrepareDownloadForGetAllRequest {
|
||||
/**
|
||||
* List of task field names (nesting is supported using \'.\', e.g. execution.model_labels). If provided, this list defines the query\'s projection (only these fields will be returned for each result entry)
|
||||
*/
|
||||
only_fields: Array<string>;
|
||||
/**
|
||||
* Download type. Determines the downloaded file\'s formatting and mime type.
|
||||
*/
|
||||
download_type?: OrganizationPrepareDownloadForGetAllRequest.DownloadTypeEnum;
|
||||
/**
|
||||
* Allow public entities to be returned in the results
|
||||
*/
|
||||
allow_public?: boolean;
|
||||
/**
|
||||
* If set to \'true\' then hidden entities are included in the search results
|
||||
*/
|
||||
search_hidden?: boolean;
|
||||
/**
|
||||
* The type of the entity to retrieve
|
||||
*/
|
||||
entity_type: OrganizationPrepareDownloadForGetAllRequest.EntityTypeEnum;
|
||||
/**
|
||||
* The name and value mappings for the exported fields. The fields that are not in the mappings will not be exported
|
||||
*/
|
||||
field_mappings?: Array<FieldMapping>;
|
||||
}
|
||||
export namespace OrganizationPrepareDownloadForGetAllRequest {
|
||||
export type DownloadTypeEnum = 'csv';
|
||||
export const DownloadTypeEnum = {
|
||||
Csv: 'csv' as DownloadTypeEnum
|
||||
}
|
||||
export type EntityTypeEnum = 'task' | 'model';
|
||||
export const EntityTypeEnum = {
|
||||
Task: 'task' as EntityTypeEnum,
|
||||
Model: 'model' as EntityTypeEnum
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* organization
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface OrganizationPrepareDownloadForGetAllResponse {
|
||||
/**
|
||||
* Prepare ID (use when calling \'download_for_get_all\')
|
||||
*/
|
||||
prepare_id?: string;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* pipelines
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface PipelinesDeleteRunsRequest {
|
||||
/**
|
||||
* IDs of the pipeline runs to delete. Should be the ids of pipeline controller tasks
|
||||
*/
|
||||
ids: Array<string>;
|
||||
/**
|
||||
* Pipeline project ids. When deleting at least one run should be left
|
||||
*/
|
||||
project: string;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* pipelines
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { PipelinesDeleteRunsResponseSucceeded } from '././pipelinesDeleteRunsResponseSucceeded';
|
||||
import { PipelinesDeleteRunsResponseFailed } from '././pipelinesDeleteRunsResponseFailed';
|
||||
|
||||
|
||||
export interface PipelinesDeleteRunsResponse {
|
||||
succeeded?: Array<PipelinesDeleteRunsResponseSucceeded>;
|
||||
failed?: Array<PipelinesDeleteRunsResponseFailed>;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* pipelines
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Error info
|
||||
*/
|
||||
export interface PipelinesDeleteRunsResponseError {
|
||||
codes?: Array<number>;
|
||||
msg?: string;
|
||||
data?: object;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* pipelines
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { PipelinesDeleteRunsResponseError } from '././pipelinesDeleteRunsResponseError';
|
||||
|
||||
|
||||
export interface PipelinesDeleteRunsResponseFailed {
|
||||
/**
|
||||
* ID of the failed entity
|
||||
*/
|
||||
id?: string;
|
||||
error?: PipelinesDeleteRunsResponseError;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* pipelines
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface PipelinesDeleteRunsResponseSucceeded {
|
||||
/**
|
||||
* ID of the succeeded entity
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* Indicates whether the task was deleted
|
||||
*/
|
||||
deleted?: boolean;
|
||||
/**
|
||||
* Number of child tasks whose parent property was updated
|
||||
*/
|
||||
updated_children?: number;
|
||||
/**
|
||||
* Number of models whose task property was updated
|
||||
*/
|
||||
updated_models?: number;
|
||||
/**
|
||||
* Number of deleted output models
|
||||
*/
|
||||
deleted_models?: number;
|
||||
/**
|
||||
* Number of deleted dataset versions
|
||||
*/
|
||||
deleted_versions?: number;
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { PipelinesStartPipelineRequestArgs } from '././pipelinesStartPipelineRequestArgs';
|
||||
|
||||
|
||||
export interface PipelinesStartPipelineRequest {
|
||||
@@ -22,7 +23,7 @@ export interface PipelinesStartPipelineRequest {
|
||||
*/
|
||||
queue?: string;
|
||||
/**
|
||||
* Task arguments, key/value to be placed in the hyperparameters Args section
|
||||
* Task arguments, name/value to be placed in the hyperparameters Args section
|
||||
*/
|
||||
args?: object;
|
||||
args?: Array<PipelinesStartPipelineRequestArgs>;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* pipelines
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface PipelinesStartPipelineRequestArgs {
|
||||
name?: string;
|
||||
}
|
||||
@@ -25,4 +25,8 @@ export interface ProjectsDeleteRequest {
|
||||
* If set to \'true\' then the project tasks and models will be deleted. Otherwise their project property will be unassigned. Default value is \'false\'
|
||||
*/
|
||||
delete_contents?: boolean;
|
||||
/**
|
||||
* If set to \'true\' then BE will try to delete the extenal artifacts associated with the project tasks and models from the fileserver (if configured to do so)
|
||||
*/
|
||||
delete_external_artifacts?: boolean;
|
||||
}
|
||||
|
||||
@@ -10,119 +10,135 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { MultiFieldPatternData } from '././multiFieldPatternData';
|
||||
import {MultiFieldPatternData} from '././multiFieldPatternData';
|
||||
|
||||
|
||||
export interface ProjectsGetAllExRequest {
|
||||
/**
|
||||
* List of IDs to filter by
|
||||
*/
|
||||
id?: Array<string>;
|
||||
/**
|
||||
* Get only projects whose name matches this pattern (python regular expression syntax)
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Project base name
|
||||
*/
|
||||
basename?: string;
|
||||
/**
|
||||
* Get only projects whose description matches this pattern (python regular expression syntax)
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* User-defined tags list used to filter results. Prepend \'-\' to tag name to indicate exclusion
|
||||
*/
|
||||
tags?: Array<string>;
|
||||
/**
|
||||
* System tags list used to filter results. Prepend \'-\' to system tag name to indicate exclusion
|
||||
*/
|
||||
system_tags?: Array<string>;
|
||||
/**
|
||||
* List of field names to order by. When search_text is used, \'@text_score\' can be used as a field representing the text score of returned documents. Use \'-\' prefix to specify descending order. Optional, recommended when using page
|
||||
*/
|
||||
order_by?: Array<string>;
|
||||
/**
|
||||
* Page number, returns a specific page out of the resulting list of dataviews
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* Page size, specifies the number of results returned in each page (last page may contain fewer results)
|
||||
*/
|
||||
page_size?: number;
|
||||
/**
|
||||
* Free text search query
|
||||
*/
|
||||
search_text?: string;
|
||||
/**
|
||||
* List of document\'s field names (nesting is supported using \'.\', e.g. execution.model_labels). If provided, this list defines the query\'s projection (only these fields will be returned for each result entry)
|
||||
*/
|
||||
only_fields?: Array<string>;
|
||||
_all_?: MultiFieldPatternData;
|
||||
_any_?: MultiFieldPatternData;
|
||||
/**
|
||||
* If true, include project statistic in response.
|
||||
*/
|
||||
include_stats?: boolean;
|
||||
/**
|
||||
* Report stats include only statistics for tasks in the specified state. If Null is provided, stats for all task states will be returned.
|
||||
*/
|
||||
stats_for_state?: ProjectsGetAllExRequest.StatsForStateEnum;
|
||||
/**
|
||||
* Return only non-public projects
|
||||
*/
|
||||
non_public?: boolean;
|
||||
active_users?: Array<string>;
|
||||
/**
|
||||
* If set to \'true\' then the search with the specified criteria is performed among top level projects only (or if parents specified, among the direct children of the these parents). Otherwise the search is performed among all the company projects (or among all of the descendants of the specified parents).
|
||||
*/
|
||||
shallow_search?: boolean;
|
||||
/**
|
||||
* If set to \'true\' and project ids are passed to the query then for these projects their own tasks, models and dataviews are counted
|
||||
*/
|
||||
check_own_contents?: boolean;
|
||||
/**
|
||||
* If set to \'true\' then hidden projects are included in the search results
|
||||
*/
|
||||
search_hidden?: boolean;
|
||||
/**
|
||||
* Scroll ID returned from the previos calls to get_all
|
||||
*/
|
||||
scroll_id?: string;
|
||||
/**
|
||||
* If set then all the data received with this scroll will be requeried
|
||||
*/
|
||||
refresh_scroll?: boolean;
|
||||
/**
|
||||
* The number of projects to retrieve
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* If include_stats flag is set then this flag contols whether the child projects tasks are taken into statistics or not
|
||||
*/
|
||||
stats_with_children?: boolean;
|
||||
/**
|
||||
* The filter for selecting entities that participate in statistics calculation. For each task field that you want to filter on pass the list of allowed values. Prepend the value with \'-\' to exclude
|
||||
*/
|
||||
include_stats_filter?: object;
|
||||
/**
|
||||
* If true, include project dataset statistic in response
|
||||
*/
|
||||
include_dataset_stats?: boolean;
|
||||
/**
|
||||
* If Truethen the shallow search is done among all the top projects that the user has access to beneath the requested parent. Even if these projects are not direct children of the parent
|
||||
*/
|
||||
permission_roots_only?: boolean;
|
||||
/**
|
||||
* Allow public projects to be returned in the results
|
||||
*/
|
||||
allow_public?: boolean;
|
||||
children_type?: string;
|
||||
/**
|
||||
* List of IDs to filter by
|
||||
*/
|
||||
id?: Array<string>;
|
||||
/**
|
||||
* Get only projects whose name matches this pattern (python regular expression syntax)
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Project base name
|
||||
*/
|
||||
basename?: string;
|
||||
/**
|
||||
* Get only projects whose description matches this pattern (python regular expression syntax)
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* User-defined tags list used to filter results. Prepend \'-\' to tag name to indicate exclusion
|
||||
*/
|
||||
tags?: Array<string>;
|
||||
/**
|
||||
* System tags list used to filter results. Prepend \'-\' to system tag name to indicate exclusion
|
||||
*/
|
||||
system_tags?: Array<string>;
|
||||
/**
|
||||
* List of field names to order by. When search_text is used, \'@text_score\' can be used as a field representing the text score of returned documents. Use \'-\' prefix to specify descending order. Optional, recommended when using page
|
||||
*/
|
||||
order_by?: Array<string>;
|
||||
/**
|
||||
* Page number, returns a specific page out of the resulting list of dataviews
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* Page size, specifies the number of results returned in each page (last page may contain fewer results)
|
||||
*/
|
||||
page_size?: number;
|
||||
/**
|
||||
* Free text search query
|
||||
*/
|
||||
search_text?: string;
|
||||
/**
|
||||
* List of document\'s field names (nesting is supported using \'.\', e.g. execution.model_labels). If provided, this list defines the query\'s projection (only these fields will be returned for each result entry)
|
||||
*/
|
||||
only_fields?: Array<string>;
|
||||
_all_?: MultiFieldPatternData;
|
||||
_any_?: MultiFieldPatternData;
|
||||
/**
|
||||
* If true, include project statistic in response.
|
||||
*/
|
||||
include_stats?: boolean;
|
||||
/**
|
||||
* Report stats include only statistics for tasks in the specified state. If Null is provided, stats for all task states will be returned.
|
||||
*/
|
||||
stats_for_state?: ProjectsGetAllExRequest.StatsForStateEnum;
|
||||
/**
|
||||
* Return only non-public projects
|
||||
*/
|
||||
non_public?: boolean;
|
||||
active_users?: Array<string>;
|
||||
/**
|
||||
* If set to \'true\' then the search with the specified criteria is performed among top level projects only (or if parents specified, among the direct children of the these parents). Otherwise the search is performed among all the company projects (or among all of the descendants of the specified parents).
|
||||
*/
|
||||
shallow_search?: boolean;
|
||||
/**
|
||||
* If set to \'true\' and project ids are passed to the query then for these projects their own tasks, models and dataviews are counted
|
||||
*/
|
||||
check_own_contents?: boolean;
|
||||
/**
|
||||
* If set to \'true\' then hidden projects are included in the search results
|
||||
*/
|
||||
search_hidden?: boolean;
|
||||
/**
|
||||
* Scroll ID returned from the previos calls to get_all
|
||||
*/
|
||||
scroll_id?: string;
|
||||
/**
|
||||
* If set then all the data received with this scroll will be requeried
|
||||
*/
|
||||
refresh_scroll?: boolean;
|
||||
/**
|
||||
* The number of projects to retrieve
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* If include_stats flag is set then this flag contols whether the child projects tasks are taken into statistics or not
|
||||
*/
|
||||
stats_with_children?: boolean;
|
||||
/**
|
||||
* The filter for selecting entities that participate in statistics calculation. For each task field that you want to filter on pass the list of allowed values. Prepend the value with \'-\' to exclude
|
||||
*/
|
||||
include_stats_filter?: object;
|
||||
/**
|
||||
* If true, include project dataset statistic in response
|
||||
*/
|
||||
include_dataset_stats?: boolean;
|
||||
/**
|
||||
* If Truethen the shallow search is done among all the top projects that the user has access to beneath the requested parent. Even if these projects are not direct children of the parent
|
||||
*/
|
||||
permission_roots_only?: boolean;
|
||||
/**
|
||||
* Allow public projects to be returned in the results
|
||||
*/
|
||||
allow_public?: boolean;
|
||||
/**
|
||||
* If specified that only the projects under which the entities of this type can be found will be returned
|
||||
*/
|
||||
children_type?: ProjectsGetAllExRequest.ChildrenTypeEnum;
|
||||
/**
|
||||
* The list of tag values to filter children by. Takes effect only if children_type is set. Use \'null\' value to specify empty tags. Use \'__Snot\' value to specify that the following value should be excluded
|
||||
*/
|
||||
children_tags?: Array<string>;
|
||||
}
|
||||
|
||||
|
||||
export namespace ProjectsGetAllExRequest {
|
||||
export type StatsForStateEnum = 'active' | 'archived';
|
||||
export const StatsForStateEnum = {
|
||||
Active: 'active' as StatsForStateEnum,
|
||||
Archived: 'archived' as StatsForStateEnum
|
||||
}
|
||||
export type ChildrenTypeEnum = 'pipeline' | 'report' | 'dataset';
|
||||
|
||||
export const ChildrenTypeEnum = {
|
||||
Pipeline: 'pipeline' as ChildrenTypeEnum,
|
||||
Report: 'report' as ChildrenTypeEnum,
|
||||
Dataset: 'dataset' as ChildrenTypeEnum
|
||||
};
|
||||
export type StatsForStateEnum = 'active' | 'archived';
|
||||
export const StatsForStateEnum = {
|
||||
Active: 'active' as StatsForStateEnum,
|
||||
Archived: 'archived' as StatsForStateEnum
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* projects
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface ProjectsGetUserNamesRequest {
|
||||
/**
|
||||
* The list of projects. If not passed or empty then all the projects are searched
|
||||
*/
|
||||
projects?: Array<string>;
|
||||
/**
|
||||
* If set to \'true\' and the projects field is not empty then the result includes user name from the subprojects children
|
||||
*/
|
||||
include_subprojects?: boolean;
|
||||
/**
|
||||
* The type of the child entity to look for
|
||||
*/
|
||||
entity?: ProjectsGetUserNamesRequest.EntityEnum;
|
||||
}
|
||||
export namespace ProjectsGetUserNamesRequest {
|
||||
export type EntityEnum = 'task' | 'model' | 'dataview';
|
||||
export const EntityEnum = {
|
||||
Task: 'task' as EntityEnum,
|
||||
Model: 'model' as EntityEnum,
|
||||
Dataview: 'dataview' as EntityEnum
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* projects
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { ProjectsGetUserNamesResponseUsers } from '././projectsGetUserNamesResponseUsers';
|
||||
|
||||
|
||||
export interface ProjectsGetUserNamesResponse {
|
||||
/**
|
||||
* The list of users sorted by their names
|
||||
*/
|
||||
users?: Array<ProjectsGetUserNamesResponseUsers>;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* projects
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 999.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface ProjectsGetUserNamesResponseUsers {
|
||||
/**
|
||||
* The ID of the user
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* The name of the user
|
||||
*/
|
||||
name?: string;
|
||||
}
|
||||
@@ -29,4 +29,20 @@ export interface ProjectsValidateDeleteResponse {
|
||||
* The total number of non-archived models under the project and all its children
|
||||
*/
|
||||
non_archived_models?: number;
|
||||
/**
|
||||
* The total number of non-empty datasets under the project and all its children
|
||||
*/
|
||||
datasets?: number;
|
||||
/**
|
||||
* The total number of reports under the project and all its children
|
||||
*/
|
||||
reports?: number;
|
||||
/**
|
||||
* The total number of non-archived reports under the project and all its children
|
||||
*/
|
||||
non_archived_reports?: number;
|
||||
/**
|
||||
* The total number of pipelines with active controllers under the project and all its children
|
||||
*/
|
||||
pipelines?: number;
|
||||
}
|
||||
|
||||
@@ -17,4 +17,8 @@ import { TasksResetManyResponseFailed } from '././tasksResetManyResponseFailed';
|
||||
export interface TasksEnqueueManyResponse {
|
||||
succeeded?: Array<TasksEnqueueManyResponseSucceeded>;
|
||||
failed?: Array<TasksResetManyResponseFailed>;
|
||||
/**
|
||||
* Returns Trueif there are workers or autscalers working with the queue
|
||||
*/
|
||||
queue_watched?: boolean;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { GetCurrentUserResponseUserObject } from '././getCurrentUserResponseUserObject';
|
||||
import {GetCurrentUserResponseUserObject} from '././getCurrentUserResponseUserObject';
|
||||
import {UsersGetCurrentUserResponseSettings} from "~/business-logic/model/users/usersGetCurrentUserResponseSettings";
|
||||
|
||||
|
||||
export interface UsersGetCurrentUserResponse {
|
||||
user?: GetCurrentUserResponseUserObject;
|
||||
getting_started?: object;
|
||||
user?: GetCurrentUserResponseUserObject;
|
||||
getting_started?: object;
|
||||
settings?: UsersGetCurrentUserResponseSettings;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* users
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 22.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export interface UsersGetCurrentUserResponseSettings {
|
||||
/**
|
||||
* The maximum items downloaded for this user in csv file downloads
|
||||
*/
|
||||
max_download_items?: string;
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import {createAction, props} from '@ngrx/store';
|
||||
import {USERS_PREFIX} from '~/app.constants';
|
||||
import {GetCurrentUserResponseUserObject} from '~/business-logic/model/users/getCurrentUserResponseUserObject';
|
||||
import {UsersGetCurrentUserResponseSettings} from "~/business-logic/model/users/usersGetCurrentUserResponseSettings";
|
||||
|
||||
export const setCurrentUser = createAction(USERS_PREFIX + 'SET_CURRENT_USER',
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
props<{user: GetCurrentUserResponseUserObject; terms_of_use?: any; getting_started?: any}>()
|
||||
props<{user: GetCurrentUserResponseUserObject; terms_of_use?: any; getting_started?: any; settings?: UsersGetCurrentUserResponseSettings;
|
||||
}>()
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {RouterEffects} from '@common/core/effects/router.effects';
|
||||
import {CommonUserEffects} from '@common/core/effects/users.effects';
|
||||
import {createUserPrefReducer} from '@common/core/meta-reducers/user-pref-reducer';
|
||||
import {messagesReducer} from '@common/core/reducers/messages-reducer';
|
||||
import {projectsReducer, RootProjects} from '@common/core/reducers/projects.reducer';
|
||||
import {projectsReducer} from '@common/core/reducers/projects.reducer';
|
||||
import {routerReducer} from '@common/core/reducers/router-reducer';
|
||||
import {SmSyncStateSelectorService} from '@common/core/services/sync-state-selector.service';
|
||||
import {
|
||||
@@ -30,7 +30,6 @@ import {projectSyncedKeys} from '~/features/projects/projects.module';
|
||||
import {authReducer} from '~/features/settings/containers/admin/auth.reducers';
|
||||
import {AdminService} from '~/shared/services/admin.service';
|
||||
import {UserEffects} from './effects/users.effects';
|
||||
import {recentTasksReducer} from './reducers/recent-tasks-reducer';
|
||||
import {sourcesReducer} from './reducers/sources-reducer';
|
||||
import {usageStatsReducer} from './reducers/usage-stats.reducer';
|
||||
import {usersReducer} from './reducers/users.reducer';
|
||||
@@ -38,6 +37,8 @@ import {viewReducer} from './reducers/view.reducer';
|
||||
import {UsageStatsService} from './services/usage-stats.service';
|
||||
import {extCoreModules} from '~/build-specifics';
|
||||
import {ReportCodeEmbedService} from '../shared/services/report-code-embed.service';
|
||||
import {recentTasksReducer} from '@common/core/reducers/recent-tasks-reducer';
|
||||
import {BreadcrumbsService} from '@common/shared/services/breadcrumbs.service';
|
||||
|
||||
export const reducers = {
|
||||
auth: authReducer,
|
||||
@@ -141,6 +142,7 @@ const userPrefMetaFactory = (userPreferences: UserPreferences): MetaReducer<any>
|
||||
useFactory: userPrefMetaFactory
|
||||
},
|
||||
{provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'},
|
||||
BreadcrumbsService,
|
||||
],
|
||||
declarations: [],
|
||||
exports: []
|
||||
|
||||
@@ -70,7 +70,6 @@ export class ProjectsEffects {
|
||||
actions.setSelectedProject({project: projects[0]}),
|
||||
actions.getProjectUsers(action),
|
||||
...(!customProjectType ? [actions.getTags()] : []),
|
||||
actions.getTags(),
|
||||
actions.getCompanyTags(),
|
||||
deactivateLoader(action.type),
|
||||
];
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import {RECENT_TASKS_ACTIONS} from '../../app.constants';
|
||||
import {SetRecentTasks} from '../../webapp-common/core/actions/recent-tasks.actions';
|
||||
import {Task} from '../../business-logic/model/tasks/task';
|
||||
|
||||
const initTasks = {
|
||||
data : <Array<Partial<Task>>>[],
|
||||
};
|
||||
|
||||
|
||||
export function recentTasksReducer(state = initTasks, action: SetRecentTasks) {
|
||||
switch (action.type) {
|
||||
case RECENT_TASKS_ACTIONS.SET_RECENT_TASKS:
|
||||
return {...state, data: action.payload.tasks};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ export const usersReducer = createReducer<UsersState>(initUsers,
|
||||
currentUser: action.user,
|
||||
gettingStarted: action.getting_started,
|
||||
activeWorkspace: action.user?.company,
|
||||
settings: action.settings,
|
||||
userWorkspaces: [action.user?.company],
|
||||
}))
|
||||
);
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
} from '@common/core/reducers/view.reducer';
|
||||
import {dismissSurvey} from '../actions/layout.actions';
|
||||
import {setServerUpdatesAvailable} from '@common/core/actions/layout.actions';
|
||||
import {selectRouterConfig} from '@common/core/reducers/router-reducer';
|
||||
import {routeConfToProjectType} from '~/features/projects/projects-page.utils';
|
||||
|
||||
interface ViewState extends CommonViewState {
|
||||
availableUpdates: string;
|
||||
@@ -22,6 +24,8 @@ export const selectAvailableUpdates = createSelector(views, state => state.ava
|
||||
export const selectShowSurvey = createSelector(views, state => state.showSurvey);
|
||||
export const selectUserSettingsNotificationPath = createSelector(views, (state) => '');
|
||||
export const selectActiveWorkspaceReady = createSelector(views, (state) => true);
|
||||
export const selectProjectType = createSelector(selectRouterConfig,
|
||||
config => (config && routeConfToProjectType(config)) ?? 'datasets');
|
||||
|
||||
export function viewReducer(viewState: ViewState = initViewState, action) {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="search-container">
|
||||
<div class="d-flex-center">
|
||||
<div class="pl-3 py-3">
|
||||
<div class="d-flex-center tabs">
|
||||
<div class="ps-3 py-3">
|
||||
<ng-container *ngFor="let searchTab of activeLinksList">
|
||||
<span [class.active]="activeLink === searchTab.name" class="pointer category-link"
|
||||
(click)="activeLinkChanged.emit(searchTab.name)">{{searchTab.label}} ({{resultsCount?.[searchTab.name]}}) </span>
|
||||
@@ -21,7 +21,8 @@
|
||||
[cardHeight]="getCardHeight()"
|
||||
[showLoadMoreButton]="getResults().length < resultsCount?.[activeLink]"
|
||||
(itemClicked)="projectClicked($event)"
|
||||
(loadMoreClicked)="loadMoreClicked.emit()">
|
||||
(loadMoreClicked)="loadMoreClicked.emit()"
|
||||
>
|
||||
</sm-virtual-grid>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,19 +3,22 @@
|
||||
|
||||
.category-link{
|
||||
padding-right: 24px;
|
||||
font-size: $font-size-lg;
|
||||
color: $blue-100;
|
||||
opacity: 0.3;
|
||||
&.active{
|
||||
opacity: 1;
|
||||
color: $blue-300;
|
||||
&:hover {
|
||||
color: $blue-200;
|
||||
}
|
||||
&.active {
|
||||
color: $neon-yellow;
|
||||
}
|
||||
}
|
||||
|
||||
.search-container{
|
||||
@include recent-title();
|
||||
height: calc(100% - 20px);
|
||||
height: calc(100% - 24px);
|
||||
.tabs {
|
||||
@include recent-title();
|
||||
}
|
||||
}
|
||||
|
||||
.page-container {
|
||||
height: calc(100% - 35px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@ import {NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {SimpleDatasetsComponent} from '@common/datasets/simple-datasets/simple-datasets.component';
|
||||
import {EntityTypeEnum} from '~/shared/constants/non-common-consts';
|
||||
import {
|
||||
NestedProjectViewPageComponent
|
||||
} from '@common/nested-project-view/nested-project-view-page/nested-project-view-page.component';
|
||||
import {CrumbTypeEnum} from '@common/layout/breadcrumbs/breadcrumbs.component';
|
||||
import {NestedSimpleDatasetsPageComponent} from '@common/datasets/nested-simple-datasets-page/nested-simple-datasets-page.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -27,7 +25,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'projects',
|
||||
component: NestedProjectViewPageComponent,
|
||||
component: NestedSimpleDatasetsPageComponent,
|
||||
data: {search: true}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -6,7 +6,8 @@ import {DatasetsRoutingModule} from '~/features/datasets/datasets-routing.module
|
||||
import {DatasetsSharedModule} from '~/features/datasets/shared/datasets-shared.module';
|
||||
import {SharedPipesModule} from '@common/shared/pipes/shared-pipes.module';
|
||||
import {SMSharedModule} from '@common/shared/shared.module';
|
||||
import {FeatureNestedProjectViewModule} from '~/features/nested-project-view/feature-nested-project-view.module';
|
||||
import {NestedDatasetsPageComponent} from '~/features/datasets/nested-datasets-page/nested-datasets-page.component';
|
||||
import {ProjectsSharedModule} from '~/features/projects/shared/projects-shared.module';
|
||||
import {LabeledFormFieldDirective} from '@common/shared/directive/labeled-form-field.directive';
|
||||
|
||||
|
||||
@@ -18,7 +19,8 @@ import {LabeledFormFieldDirective} from '@common/shared/directive/labeled-form-f
|
||||
DatasetsRoutingModule,
|
||||
DatasetsSharedModule,
|
||||
SharedPipesModule,
|
||||
FeatureNestedProjectViewModule,
|
||||
NestedDatasetsPageComponent,
|
||||
ProjectsSharedModule,
|
||||
LabeledFormFieldDirective,
|
||||
],
|
||||
declarations: [
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<sm-nested-project-view-page
|
||||
[projectsList]="projectsList$ | async"
|
||||
[projectsOrderBy]="projectsOrderBy$ | async"
|
||||
[projectsSortOrder]="projectsOrderBy$ | async"
|
||||
[noMoreProjects]="noMoreProjects$ | async"
|
||||
[allExamples]="allExamples"
|
||||
[cardContentTemplateRef]="cardContent"
|
||||
[entityType]="entityType"
|
||||
(cardClicked)="projectCardClicked($event)"
|
||||
(deleteProjectClicked)="deleteProject($event)"
|
||||
(projectNameChanged)="projectNameChanged($event)"
|
||||
(orderByChanged)="orderByChanged($event)"
|
||||
(loadMore)="loadMore()"
|
||||
(toggleNestedView)="toggleNestedView($event)"
|
||||
>
|
||||
|
||||
<button create-button
|
||||
class="btn btn-cml-primary d-flex align-items-center"
|
||||
(click)="createExamples()">
|
||||
<i class="al-icon al-ico-add sm me-2"></i>NEW DATASET
|
||||
</button>
|
||||
|
||||
<div empty-state class="empty-datasets">
|
||||
<div class="title-icon"><i class="al-icon al-ico-datasets xxl"></i></div>
|
||||
<div class="title">NO DATASETS TO SHOW</div>
|
||||
<div class="sub-title">Run your first dataset to see it displayed here
|
||||
<ng-container *ngIf="allExamples"> or <a href="" (click)="$event.preventDefault(); createExamples()" class="link">generate
|
||||
example
|
||||
</a></ng-container>
|
||||
</div>
|
||||
<sm-dataset-empty [showButton]="true"></sm-dataset-empty>
|
||||
</div>
|
||||
|
||||
</sm-nested-project-view-page>
|
||||
|
||||
<ng-template #cardContent let-project>
|
||||
<sm-circle-counter
|
||||
[counter]="project.id === '*' ? '∞' : project.stats?.datasets?.count ?? '0'"
|
||||
[label]="'DATASETS'"
|
||||
[type]="project.stats?.datasets?.count===0 ? circleTypeEnum.empty : circleTypeEnum.pending"></sm-circle-counter>
|
||||
<sm-circle-counter label="TAGS IN USE" [counter]="[]">
|
||||
<sm-tag-list
|
||||
*ngIf="!hideMenu; else: ReadOnlyTags"
|
||||
class="tags-list-counter"
|
||||
[readonly]="true"
|
||||
[class.empty-tags]="!(project.stats?.datasets?.tags.length > 0)"
|
||||
tagsList
|
||||
[tags]="project.stats?.datasets?.tags"
|
||||
smClickStopPropagation
|
||||
></sm-tag-list>
|
||||
</sm-circle-counter>
|
||||
<ng-template #ReadOnlyTags>
|
||||
<sm-tag-list [tags]="project.tags"></sm-tag-list>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {ProjectTypeEnum} from '@common/nested-project-view/nested-project-view-page/nested-project-view-page.component';
|
||||
import {CircleTypeEnum} from '~/shared/constants/non-common-consts';
|
||||
import {ProjectsSharedModule} from '~/features/projects/shared/projects-shared.module';
|
||||
import {SMSharedModule} from '@common/shared/shared.module';
|
||||
import {AsyncPipe, NgIf} from '@angular/common';
|
||||
import {CommonProjectsPageComponent} from '@common/projects/containers/projects-page/common-projects-page.component';
|
||||
import {DatasetEmptyComponent} from '@common/datasets/dataset-empty/dataset-empty.component';
|
||||
|
||||
@Component({
|
||||
selector: 'sm-nested-datasets-page',
|
||||
templateUrl: './nested-datasets-page.component.html',
|
||||
styleUrls: [
|
||||
'../../../webapp-common/nested-project-view/nested-project-view-page/nested-project-view-page.component.scss',
|
||||
'../../../webapp-common/datasets/simple-datasets/simple-datasets.component.scss'
|
||||
],
|
||||
imports: [
|
||||
ProjectsSharedModule,
|
||||
SMSharedModule,
|
||||
AsyncPipe,
|
||||
NgIf
|
||||
],
|
||||
standalone: true
|
||||
})
|
||||
export class NestedDatasetsPageComponent extends CommonProjectsPageComponent {
|
||||
entityTypeEnum = ProjectTypeEnum;
|
||||
circleTypeEnum = CircleTypeEnum;
|
||||
hideMenu = false;
|
||||
entityType = ProjectTypeEnum.datasets;
|
||||
|
||||
projectCardClicked(data: { hasSubProjects: boolean; id: string; name: string }) {
|
||||
if (data.hasSubProjects) {
|
||||
this.router.navigate(['simple', data.id, 'projects'], {relativeTo: this.route.parent?.parent});
|
||||
} else {
|
||||
this.router.navigate(['simple', data.id, ProjectTypeEnum.datasets], {relativeTo: this.route.parent?.parent});
|
||||
}
|
||||
}
|
||||
|
||||
createExamples() {
|
||||
this.dialog.open(DatasetEmptyComponent, {
|
||||
maxWidth: '95vw',
|
||||
width: '1248px'
|
||||
});
|
||||
}
|
||||
|
||||
toggleNestedView(nested: boolean) {
|
||||
if (!nested) {
|
||||
this.router.navigateByUrl(this.entityType);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
protected getExtraProjects(selectedProjectId, selectedProject) {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +1,12 @@
|
||||
import {Actions} from '@ngrx/effects';
|
||||
import {ApiProjectsService} from '../../business-logic/api-services/projects.service';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Store} from '@ngrx/store';
|
||||
import {AdminService} from '~/shared/services/admin.service';
|
||||
import {ApiTasksService} from '../../business-logic/api-services/tasks.service';
|
||||
import {ApiModelsService} from '../../business-logic/api-services/models.service';
|
||||
import {DeleteDialogEffectsBase} from '../../webapp-common/shared/entity-page/entity-delete/base-delete-dialog.effects';
|
||||
import {ConfigurationService} from '../../webapp-common/shared/services/configuration.service';
|
||||
import {DeleteDialogEffectsBase} from '@common/shared/entity-page/entity-delete/base-delete-dialog.effects';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class DeleteDialogEffects extends DeleteDialogEffectsBase {
|
||||
constructor(actions$: Actions,
|
||||
store: Store<any>,
|
||||
tasksApi: ApiTasksService,
|
||||
modelsApi: ApiModelsService,
|
||||
projectsApi: ApiProjectsService,
|
||||
adminService: AdminService,
|
||||
configService: ConfigurationService) {
|
||||
super(actions$, store, tasksApi, modelsApi, projectsApi, adminService, configService);
|
||||
constructor(actions$: Actions) {
|
||||
super(actions$);
|
||||
}
|
||||
// (Nir) don't delete this. Other repositories need to override some base functions.
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import {Overlay} from '@angular/cdk/overlay';
|
||||
import {ExperimentsComponent} from '@common/experiments/experiments.component';
|
||||
import {RouterTabNavBarComponent} from '@common/shared/components/router-tab-nav-bar/router-tab-nav-bar.component';
|
||||
import {MatTabsModule} from '@angular/material/tabs';
|
||||
import {LabeledFormFieldDirective} from '@common/shared/directive/labeled-form-field.directive';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@@ -84,6 +85,7 @@ import {MatTabsModule} from '@angular/material/tabs';
|
||||
RouterTabNavBarComponent,
|
||||
MatTabsModule,
|
||||
RouterTabNavBarComponent,
|
||||
LabeledFormFieldDirective,
|
||||
],
|
||||
declarations: [
|
||||
ExperimentsComponent,
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface IExecutionForm {
|
||||
branch?: string;
|
||||
entry_point: string;
|
||||
working_dir: string;
|
||||
binary: string;
|
||||
scriptType: sourceTypesEnum;
|
||||
};
|
||||
docker_cmd?: string;
|
||||
@@ -23,7 +24,7 @@ export interface IExecutionForm {
|
||||
diff: string;
|
||||
output: {
|
||||
destination: string;
|
||||
logLevel?: 'basic' | 'details'; // TODO: should be enum from gencode.
|
||||
logLevel?: 'INFO' | 'DEBUG' | 'ERROR'; // TODO: should be enum from gencode.
|
||||
};
|
||||
queue: Queue;
|
||||
container?: Container;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {
|
||||
NestedProjectViewPageExtendedComponent
|
||||
} from './nested-project-view-page-extended/nested-project-view-page-extended.component';
|
||||
import {NestedProjectViewModule} from "@common/nested-project-view/nested-project-view.module";
|
||||
import {CommonModule} from "@angular/common";
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
NestedProjectViewPageExtendedComponent,
|
||||
],
|
||||
exports: [NestedProjectViewPageExtendedComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NestedProjectViewModule,
|
||||
]
|
||||
})
|
||||
export class FeatureNestedProjectViewModule { }
|
||||
@@ -1,2 +0,0 @@
|
||||
<sm-nested-project-view-page>
|
||||
</sm-nested-project-view-page>
|
||||
@@ -1,33 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NestedProjectViewPageExtendedComponent } from './nested-project-view-page-extended.component';
|
||||
import {StoreModule} from '@ngrx/store';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {MatDialogModule} from '@angular/material/dialog';
|
||||
|
||||
describe('PipelinesPageComponent', () => {
|
||||
let component: NestedProjectViewPageExtendedComponent;
|
||||
let fixture: ComponentFixture<NestedProjectViewPageExtendedComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ NestedProjectViewPageExtendedComponent ],
|
||||
imports: [
|
||||
StoreModule.forRoot({}),
|
||||
RouterTestingModule,
|
||||
MatDialogModule
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NestedProjectViewPageExtendedComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import {
|
||||
NestedProjectViewPageComponent
|
||||
} from "@common/nested-project-view/nested-project-view-page/nested-project-view-page.component";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'sm-nested-project-view-page-extended',
|
||||
templateUrl: './nested-project-view-page-extended.component.html',
|
||||
styleUrls: ['./nested-project-view-page-extended.component.scss']
|
||||
})
|
||||
export class NestedProjectViewPageExtendedComponent extends NestedProjectViewPageComponent implements OnInit, OnDestroy {
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import {EntityTypeEnum} from '~/shared/constants/non-common-consts';
|
||||
|
||||
export enum EntityTypePluralEnum {
|
||||
pipelines = 'pipelines',
|
||||
datasets = 'datasets',
|
||||
reports = 'reports',
|
||||
}
|
||||
|
||||
export const getEntityTypeFromUrlConf = (conf: string[]) => conf[0] as EntityTypePluralEnum;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export const getDatasetUrlPrefix = (entityType)=> 'simple';
|
||||
export const getNestedEntityBaseUrl = (entityType) => entityType;
|
||||
export const isDatasetType = (entityType) => entityType === EntityTypePluralEnum.datasets ;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export const datasetLabel = (entityType) => 'DATASETS' ;
|
||||
|
||||
export const getNestedEntityName = (entityType: string): EntityTypeEnum => {
|
||||
switch (entityType) {
|
||||
case EntityTypePluralEnum.datasets:
|
||||
return EntityTypeEnum.simpleDataset;
|
||||
case EntityTypePluralEnum.reports:
|
||||
return EntityTypeEnum.report;
|
||||
case EntityTypePluralEnum.pipelines:
|
||||
return EntityTypeEnum.pipeline;
|
||||
default:
|
||||
return EntityTypeEnum.project;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,25 +1,38 @@
|
||||
import {ActivatedRouteSnapshot} from "@angular/router";
|
||||
import {ActivatedRouteSnapshot} from '@angular/router';
|
||||
import {
|
||||
getDatasetsRequest,
|
||||
getPipelineRequest,
|
||||
getReportRequest,
|
||||
isPipelines,
|
||||
isReports
|
||||
} from "@common/projects/common-projects.utils";
|
||||
import {ProjectsGetAllExRequest} from "~/business-logic/model/projects/projectsGetAllExRequest";
|
||||
} from '@common/projects/common-projects.utils';
|
||||
import {ProjectsGetAllExRequest} from '~/business-logic/model/projects/projectsGetAllExRequest';
|
||||
|
||||
export const isDeletableProject = readyForDeletion => (readyForDeletion.experiments.unarchived + readyForDeletion.models.unarchived) === 0;
|
||||
|
||||
export const popupEntitiesListConst = 'experiments or model';
|
||||
export const popupEntitiesListConst = 'experiments, dataviews pipelines or dataset';
|
||||
|
||||
export const getDeleteProjectPopupStatsBreakdown = (readyForDeletion, statsSubset: 'archived' | 'unarchived' | 'total', experimentCaption): string => `${readyForDeletion.experiments[statsSubset] > 0 ? `${readyForDeletion.experiments[statsSubset]} ${experimentCaption} ` : ''}
|
||||
${readyForDeletion.models[statsSubset] > 0 ? readyForDeletion.models[statsSubset] + ' models ' : ''}`;
|
||||
export const getDeleteProjectPopupStatsBreakdown = (readyForDeletion, statsSubset: 'archived' | 'unarchived' | 'total', experimentCaption) => {
|
||||
const errors = [
|
||||
readyForDeletion.experiments[statsSubset] > 0 ?
|
||||
`${readyForDeletion.experiments[statsSubset]} ${experimentCaption}${readyForDeletion.experiments[statsSubset] > 1 ? 's' : ''} ` : null,
|
||||
readyForDeletion.models[statsSubset] > 0 ? readyForDeletion.models[statsSubset] + ' models ' : null,
|
||||
readyForDeletion.pipelines[statsSubset] > 0 ? readyForDeletion.pipelines[statsSubset] + ' pipelines ' : null,
|
||||
readyForDeletion.datasets[statsSubset] > 0 ? readyForDeletion.datasets[statsSubset] + ' datasets ' : null,
|
||||
readyForDeletion.reports[statsSubset] > 0 ? readyForDeletion.reports[statsSubset] + ' reports' : null,
|
||||
].filter(error => error !== null);
|
||||
const first = errors.slice(0, -2);
|
||||
const last = errors.slice(-2);
|
||||
return [...first, last.join(' and ')].join(', ');
|
||||
};
|
||||
|
||||
export const readyForDeletionFilter = readyForDeletion => !(readyForDeletion.experiments === null || readyForDeletion.models === null);
|
||||
|
||||
export const isDatasets = (snapshot: ActivatedRouteSnapshot) => snapshot.firstChild.routeConfig.path === 'datasets';
|
||||
|
||||
export const routeConfToProjectType = (routeConf: string[]) => routeConf[0];
|
||||
export const getNoProjectsReRoute = ((routeConf: string[]) => 'experiments');
|
||||
export const isNestedDatasets = (routeConf: string[]) => ['simple'].includes(routeConf?.[1]);
|
||||
|
||||
export const getFeatureProjectRequest = (snapshot: ActivatedRouteSnapshot, nested: boolean, searchQuery: any, selectedProjectName: any, selectedProjectId: any): ProjectsGetAllExRequest => {
|
||||
const pipelines = isPipelines(snapshot);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import {createAction, props} from '@ngrx/store';
|
||||
import {PROJECTS_PREFIX} from '@common/core/actions/projects.actions';
|
||||
import {CommonReadyForDeletion} from '@common/projects/common-projects.reducer';
|
||||
|
||||
export const setProjectReadyForDeletion= createAction(
|
||||
PROJECTS_PREFIX + 'SET_PROJECT_READY_FOR_DELETION',
|
||||
props<{readyForDeletion: CommonReadyForDeletion}>()
|
||||
);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import {Actions, createEffect, ofType} from '@ngrx/effects';
|
||||
import {checkProjectForDeletion, setProjectReadyForDeletion} from '@common/projects/common-projects.actions';
|
||||
import {checkProjectForDeletion} from '@common/projects/common-projects.actions';
|
||||
import {mergeMap, switchMap} from 'rxjs/operators';
|
||||
import {ProjectsValidateDeleteResponse} from '~/business-logic/model/projects/projectsValidateDeleteResponse';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ApiProjectsService} from '~/business-logic/api-services/projects.service';
|
||||
import {ApiModelsService} from '~/business-logic/api-services/models.service';
|
||||
import {setProjectReadyForDeletion} from '~/features/projects/projects.actions';
|
||||
|
||||
@Injectable()
|
||||
export class ProjectsEffects {
|
||||
@@ -16,19 +17,32 @@ export class ProjectsEffects {
|
||||
checkIfProjectExperiments = createEffect(() => this.actions.pipe(
|
||||
ofType(checkProjectForDeletion),
|
||||
switchMap((action) => this.projectsApi.projectsValidateDelete({project: action.project.id})),
|
||||
mergeMap((projectsValidateDeleteResponse: ProjectsValidateDeleteResponse) => [
|
||||
mergeMap((res: ProjectsValidateDeleteResponse) => [
|
||||
setProjectReadyForDeletion({
|
||||
readyForDeletion: {
|
||||
experiments: {
|
||||
total: projectsValidateDeleteResponse.tasks,
|
||||
archived: projectsValidateDeleteResponse.tasks - projectsValidateDeleteResponse.non_archived_tasks,
|
||||
unarchived: projectsValidateDeleteResponse.non_archived_tasks
|
||||
total: res.tasks,
|
||||
archived: res.tasks - res.non_archived_tasks,
|
||||
unarchived: res.non_archived_tasks
|
||||
},
|
||||
models: {
|
||||
total: projectsValidateDeleteResponse.models,
|
||||
archived: projectsValidateDeleteResponse.models - projectsValidateDeleteResponse.non_archived_models,
|
||||
unarchived: projectsValidateDeleteResponse.non_archived_models
|
||||
}
|
||||
total: res.models,
|
||||
archived: res.models - res.non_archived_models,
|
||||
unarchived: res.non_archived_models
|
||||
},
|
||||
reports: {
|
||||
total: res.reports,
|
||||
archived: res.reports - res.non_archived_reports,
|
||||
unarchived: res.non_archived_reports
|
||||
},
|
||||
pipelines: {
|
||||
total: res.pipelines,
|
||||
unarchived: res.pipelines
|
||||
},
|
||||
datasets: {
|
||||
total: res.datasets,
|
||||
unarchived: res.datasets
|
||||
},
|
||||
}
|
||||
})
|
||||
])
|
||||
|
||||
@@ -1,37 +1,22 @@
|
||||
import {on, createReducer, createSelector} from '@ngrx/store';
|
||||
import {
|
||||
CommonProjectReadyForDeletion,
|
||||
commonProjectsInitState,
|
||||
commonProjectsReducers,
|
||||
CommonProjectsState
|
||||
CommonProjectsState, CommonReadyForDeletion
|
||||
} from '@common/projects/common-projects.reducer';
|
||||
import {checkProjectForDeletion, resetReadyToDelete, setProjectReadyForDeletion} from '@common/projects/common-projects.actions';
|
||||
import {setProjectReadyForDeletion} from '~/features/projects/projects.actions';
|
||||
|
||||
export type IProjectReadyForDeletion = CommonProjectReadyForDeletion;
|
||||
export type ProjectReadyForDeletion = CommonReadyForDeletion;
|
||||
|
||||
export interface ProjectsState extends CommonProjectsState {
|
||||
|
||||
projectReadyForDeletion: IProjectReadyForDeletion;
|
||||
projectReadyForDeletion: ProjectReadyForDeletion;
|
||||
}
|
||||
|
||||
const projectsInitState: ProjectsState = {
|
||||
...commonProjectsInitState,
|
||||
projectReadyForDeletion: {
|
||||
project: null, experiments: null, models: null
|
||||
}
|
||||
};
|
||||
|
||||
export const projectsReducer = createReducer(
|
||||
projectsInitState,
|
||||
on(checkProjectForDeletion, (state, action) => ({
|
||||
...state,
|
||||
projectReadyForDeletion: {
|
||||
...projectsInitState.projectReadyForDeletion,
|
||||
project: action.project
|
||||
}
|
||||
})),
|
||||
on(resetReadyToDelete, state => ({...state, projectReadyForDeletion: projectsInitState.projectReadyForDeletion})),
|
||||
on(setProjectReadyForDeletion, (state, action) => ({
|
||||
commonProjectsInitState,
|
||||
on(setProjectReadyForDeletion, (state, action): ProjectsState => ({
|
||||
...state,
|
||||
projectReadyForDeletion: {
|
||||
...state.projectReadyForDeletion,
|
||||
|
||||
@@ -12,6 +12,8 @@ import {DatasetEmptyComponent} from '@common/datasets/dataset-empty/dataset-empt
|
||||
import {NestedCardComponent} from '@common/nested-project-view/nested-card/nested-card.component';
|
||||
import {SharedPipesModule} from '@common/shared/pipes/shared-pipes.module';
|
||||
import {PipelinesEmptyStateComponent} from '@common/pipelines/pipelines-page/pipelines-empty-state/pipelines-empty-state.component';
|
||||
import {ProjectsHeaderComponent} from '@common/projects/dumb/projects-header/projects-header.component';
|
||||
import {NestedProjectViewPageComponent} from '@common/nested-project-view/nested-project-view-page/nested-project-view-page.component';
|
||||
|
||||
const _declarations = [
|
||||
ProjectCardComponent,
|
||||
@@ -21,6 +23,8 @@ const _declarations = [
|
||||
PipelineCardMenuComponent,
|
||||
NestedCardComponent,
|
||||
DatasetEmptyComponent,
|
||||
NestedProjectViewPageComponent,
|
||||
ProjectsHeaderComponent
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
<span
|
||||
class="add-button d-flex align-items-center pointer"
|
||||
[class.disabled]="creatingCredentials"
|
||||
(click)="createCredential()"><i class="al-icon sm al-ico-plus mr-1"></i> Create new credentials
|
||||
(click)="createCredential()"><i class="al-icon sm al-ico-plus me-1"></i> Create new credentials
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
@font-face {
|
||||
font-family: '#{$icomoon-font-family}';
|
||||
src: url('./#{$icomoon-font-family}.ttf?s0lnuq') format('truetype');
|
||||
src: url('./#{$icomoon-font-family}.ttf?n9hc0z') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@@ -24,6 +24,16 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.al-ico-model-filled {
|
||||
&:before {
|
||||
content: $al-ico-model-filled;
|
||||
}
|
||||
}
|
||||
.al-ico-type-report {
|
||||
&:before {
|
||||
content: $al-ico-type-report;
|
||||
}
|
||||
}
|
||||
.al-ico-info-circle-outline {
|
||||
&:before {
|
||||
content: $al-ico-info-circle-outline;
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,8 @@
|
||||
$icomoon-font-family: "trains" !default;
|
||||
$icomoon-font-path: "fonts" !default;
|
||||
|
||||
$al-ico-model-filled: "\e9f2";
|
||||
$al-ico-type-report: "\e9f1";
|
||||
$al-ico-info-circle-outline: "\e9f0";
|
||||
$al-ico-ghost: "\e9ef";
|
||||
$al-ico-flat-view: "\e9ee";
|
||||
|
||||
@@ -22,6 +22,7 @@ export const getScalar = createAction('[App] getScalar', props<{
|
||||
variants: string[];
|
||||
company: string;
|
||||
models: boolean;
|
||||
xaxis: string;
|
||||
otherSearchParams?: URLSearchParams;
|
||||
}>());
|
||||
export const getSample = createAction('[App] getSample', props<{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
[showLoaderOnDraw]="false"
|
||||
[identifier]="'lala'"
|
||||
[width]="400"
|
||||
[xAxisType]="xaxis"
|
||||
[isCompare]="true"
|
||||
[noMargins]="true"
|
||||
[legendConfiguration]="{noTextWrap: true}"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, OnInit, ViewChild} from '@angular/core';
|
||||
import {Store} from '@ngrx/store';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {Observable, withLatestFrom} from 'rxjs';
|
||||
import {Observable} from 'rxjs';
|
||||
import {filter, map, switchMap, take} from 'rxjs/operators';
|
||||
import {Environment} from '../environments/base';
|
||||
import {getParcoords, getPlot, getSample, getScalar, getSingleValues, reportsPlotlyReady} from './app.actions';
|
||||
@@ -14,8 +14,7 @@ import {
|
||||
selectSampleData,
|
||||
selectSignIsNeeded,
|
||||
selectSingleValuesData,
|
||||
selectTaskData,
|
||||
State
|
||||
selectTaskData
|
||||
} from './app.reducer';
|
||||
import {ExtFrame} from '@common/shared/single-graph/plotly-graph-base';
|
||||
import {DebugSample} from '@common/shared/debug-sample/debug-sample.reducer';
|
||||
@@ -33,6 +32,7 @@ import {isFileserverUrl} from '~/shared/utils/url';
|
||||
import {MetricValueType, SelectedMetric} from '@common/experiments-compare/experiments-compare.constants';
|
||||
import {ExtraTask} from '@common/experiments-compare/dumbs/parallel-coordinates-graph/parallel-coordinates-graph.component';
|
||||
import {EventsGetTaskSingleValueMetricsResponseValues} from '~/business-logic/model/events/eventsGetTaskSingleValueMetricsResponseValues';
|
||||
import {ScalarKeyEnum} from '~/business-logic/model/reports/scalarKeyEnum';
|
||||
|
||||
|
||||
type WidgetTypes = 'plot' | 'scalar' | 'sample' | 'parcoords' | 'single';
|
||||
@@ -64,6 +64,7 @@ export class AppComponent implements OnInit {
|
||||
@ViewChild(SingleGraphComponent) 'singleGraph': SingleGraphComponent;
|
||||
public singleValueData: EventsGetTaskSingleValueMetricsResponseValues[];
|
||||
public webappLink: string;
|
||||
public readonly xaxis: ScalarKeyEnum;
|
||||
|
||||
@HostListener('window:resize')
|
||||
onResize() {
|
||||
@@ -71,7 +72,7 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
constructor(
|
||||
private store: Store<State>,
|
||||
private store: Store,
|
||||
private configService: ConfigurationService,
|
||||
private dialog: MatDialog,
|
||||
private cdr: ChangeDetectorRef) {
|
||||
@@ -86,6 +87,7 @@ export class AppComponent implements OnInit {
|
||||
this.singleGraphHeight = window.innerHeight;
|
||||
this.otherSearchParams = this.getOtherSearchParams();
|
||||
this.isDarkTheme = !this.searchParams.get('light');
|
||||
this.xaxis = this.searchParams.get('xaxis') as ScalarKeyEnum;
|
||||
|
||||
try {
|
||||
const data = JSON.parse(localStorage.getItem('_saved_state_'));
|
||||
@@ -189,7 +191,11 @@ export class AppComponent implements OnInit {
|
||||
} else {
|
||||
const {merged,} = prepareMultiPlots(metricsPlots);
|
||||
const newGraphs = convertMultiPlots(merged);
|
||||
this.plotData = Object.values(newGraphs)[0]?.[0];
|
||||
const originalObject = this.searchParams.get('objects');
|
||||
const series = this.searchParams.get('series');
|
||||
this.plotData = Object.values(newGraphs)[0]?.find(a => originalObject === (a.task ?? a.data[0].task)) ??
|
||||
Object.values(newGraphs)[0].find(a => (a.data[0] as any).seriesName === series) ??
|
||||
Object.values(newGraphs)[0]?.[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -236,7 +242,10 @@ export class AppComponent implements OnInit {
|
||||
take(1))
|
||||
.subscribe(metrics => {
|
||||
this.plotLoaded = true;
|
||||
this.plotData = Object.values(mergeMultiMetricsGroupedVariant(metrics))?.[0]?.[0];
|
||||
|
||||
const lala = [ScalarKeyEnum.IsoTime, ScalarKeyEnum.Timestamp].includes(this.xaxis) ? this.calcXaxis(metrics) : metrics;
|
||||
|
||||
this.plotData = Object.values(mergeMultiMetricsGroupedVariant(lala))?.[0]?.[0];
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
}
|
||||
@@ -306,6 +315,7 @@ export class AppComponent implements OnInit {
|
||||
variants: this.searchParams.getAll('variants'),
|
||||
iterations: this.searchParams.getAll('iterations').map(iteration => parseInt(iteration, 10)),
|
||||
company: this.searchParams.get('company') || '',
|
||||
xaxis: this.searchParams.get('xaxis') || '',
|
||||
models
|
||||
};
|
||||
|
||||
@@ -381,14 +391,17 @@ export class AppComponent implements OnInit {
|
||||
private buildSourceLink(searchParams: URLSearchParams, project: string, tasks: string[]): string {
|
||||
const isModels = searchParams.has('models') || this.searchParams.get('objectType') === 'model';
|
||||
const objects = searchParams.getAll('objects');
|
||||
let entityIds = objects.length > 0? objects : searchParams.getAll(isModels ? 'models' : 'tasks');
|
||||
const variants = searchParams.getAll('variants');
|
||||
const metricPath = searchParams.get('metrics') || '';
|
||||
let entityIds = objects.length > 0 ? objects : searchParams.getAll(isModels ? 'models' : 'tasks');
|
||||
if (entityIds.length === 0 && tasks?.length > 0) {
|
||||
entityIds = tasks;
|
||||
}
|
||||
const isCompare = entityIds.length > 1;
|
||||
let url = `${window.location.origin.replace('4201', '4200')}/projects/${project ?? '*'}/`;
|
||||
if (isCompare) {
|
||||
url += `${isModels ? 'compare-models;ids=' : 'compare-experiments;ids='}${entityIds.join(',')}/${this.getComparePath(this.type)}`;
|
||||
url += `${isModels ? 'compare-models;ids=' : 'compare-experiments;ids='}${entityIds.join(',')}/
|
||||
${this.getComparePath(this.type)}?metricPath=${metricPath}&metricName=lala${variants.map(par => `¶ms=${par}`).join('')}`;
|
||||
} else {
|
||||
url += `${isModels ? 'models/' : 'experiments/'}${entityIds}/${this.getOutputPath(isModels, this.type)}`;
|
||||
}
|
||||
@@ -452,5 +465,21 @@ export class AppComponent implements OnInit {
|
||||
observer.observe(document.body);
|
||||
});
|
||||
}
|
||||
|
||||
private calcXaxis(metrics: MetricsPlotEvent[] | ReportsApiMultiplotsResponse) {
|
||||
return Object.keys(metrics).reduce((groupAcc, groupName) => {
|
||||
const group = metrics[groupName];
|
||||
groupAcc[groupName] = Object.keys(group).reduce((graphAcc, graphName) => {
|
||||
const expGraph = group[graphName];
|
||||
graphAcc[graphName] = {};
|
||||
Object.keys(expGraph).reduce((graphAcc2, exp) => {
|
||||
const graph = expGraph[exp];
|
||||
return graphAcc[graphName][exp] = {...graph, x: graph.x.map(ts => new Date(ts))};
|
||||
}, {});
|
||||
return graphAcc;
|
||||
}, {});
|
||||
return groupAcc;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import {HTTP} from '~/app.constants';
|
||||
import {DebugSample} from '@common/shared/debug-sample/debug-sample.reducer';
|
||||
import {requestFailed} from '@common/core/actions/http.actions';
|
||||
import {Task} from '~/business-logic/model/tasks/task';
|
||||
import {ScalarKeyEnum} from '~/business-logic/model/events/scalarKeyEnum';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@@ -33,7 +34,7 @@ export class AppEffects {
|
||||
|
||||
constructor(
|
||||
private httpClient: HttpClient,
|
||||
private store: Store<State>,
|
||||
private store: Store,
|
||||
private actions$: Actions,
|
||||
private reportsApi: ApiReportsService,
|
||||
private adminService: BaseAdminService) {
|
||||
@@ -78,7 +79,8 @@ export class AppEffects {
|
||||
model_events: action.models,
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
scalar_metrics_iter_histogram: {
|
||||
metrics: action.metrics.map(metric => ({metric, variants: action.variants}))
|
||||
metrics: action.metrics.map(metric => ({metric, variants: action.variants})),
|
||||
key: action.xaxis || ScalarKeyEnum.Iter
|
||||
}
|
||||
},
|
||||
{headers: this.getHeaders(action.company)}
|
||||
@@ -121,7 +123,7 @@ export class AppEffects {
|
||||
mergeMap((action) => this.httpClient.post<{ data: ReportsGetTaskDataResponse }>(`${this.basePath}/reports.get_task_data?${action.otherSearchParams.toString()}`, {
|
||||
id: action.tasks,
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
only_fields: ['last_metrics', 'name', 'last_iteration', ...action.variants.map(variant => `hyperparams.${variant}`)]
|
||||
only_fields: ['last_metrics', 'name', 'last_iteration', 'project', ...action.variants.map(variant => `hyperparams.${variant}`)]
|
||||
})
|
||||
.pipe(
|
||||
mergeMap(res => [
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DebugSample} from '@common/shared/debug-sample/debug-sample.reducer';
|
||||
import {MetricsPlotEvent} from '~/business-logic/model/events/metricsPlotEvent';
|
||||
import {MetricValueType, SelectedMetric} from '@common/experiments-compare/experiments-compare.constants';
|
||||
import {Task} from '~/business-logic/model/tasks/task';
|
||||
import {SingleValueTaskMetrics} from '~/business-logic/model/reports/singleValueTaskMetrics';
|
||||
import { SingleValueTaskMetrics} from '~/business-logic/model/reports/singleValueTaskMetrics';
|
||||
|
||||
export interface ParCoords {
|
||||
metric: SelectedMetric;
|
||||
|
||||
@@ -15,6 +15,8 @@ import {BASE_ENV, Environment} from './base';
|
||||
13 https://api.staging.hosted.allegro.ai
|
||||
14 https://api.clear.ml
|
||||
15 https://api.dev.hosted.clear.ml
|
||||
16 https://api.deloitte.hosted.allegro.ai
|
||||
17 https://api.trains-master.hosted.allegro.ai
|
||||
*/
|
||||
|
||||
export const environment = {
|
||||
|
||||
@@ -3,7 +3,42 @@
|
||||
@use '../../../../../../node_modules/@angular/material/index' as mat;
|
||||
// Plus imports for other components in your app.
|
||||
$neon-yellow: #d3ff00;
|
||||
$purple: #4d66ff;
|
||||
$white-primary-text: rgba(white, 0.87);
|
||||
$dark-primary-text: rgba(black, 0.87);
|
||||
$sm-purple: (
|
||||
50: lighten(#c3cdf0, 20%),
|
||||
100: lighten(#c3cdf0, 15%),
|
||||
200: lighten(#c3cdf0, 10%),
|
||||
300: lighten(#c3cdf0, 5%),
|
||||
400: #c3cdf0,
|
||||
500: #c3cdf0,
|
||||
600: #c3cdf0,
|
||||
700: darken(#c3cdf0, 15%),
|
||||
800: darken(#c3cdf0, 20%),
|
||||
900: darken(#c3cdf0, 55%),
|
||||
A100: $purple,
|
||||
A200: darken($purple, 5%),
|
||||
A400: darken($purple, 10%),
|
||||
A700: darken($purple, 15%),
|
||||
contrast: (
|
||||
50: $dark-primary-text,
|
||||
100: $dark-primary-text,
|
||||
200: $dark-primary-text,
|
||||
300: $dark-primary-text,
|
||||
400: white,
|
||||
500: white,
|
||||
600: white,
|
||||
700: white,
|
||||
800: white,
|
||||
900: white,
|
||||
A100: white,
|
||||
A200: white,
|
||||
A400: white,
|
||||
A700: white,
|
||||
)
|
||||
);
|
||||
|
||||
$sm-neon: (
|
||||
50: lighten($neon-yellow, 30%),
|
||||
100: lighten($neon-yellow, 25%),
|
||||
@@ -47,6 +82,9 @@ $sm-neon: (
|
||||
$theme-primary: mat.define-palette(mat.$indigo-palette);
|
||||
$theme-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
|
||||
|
||||
$sm-dark-palette-primary: mat.define-palette($sm-purple);
|
||||
$sm-dark-palette-accent: mat.define-palette($sm-purple, A200, A100, A400);
|
||||
|
||||
$sm-neon-palette-primary: mat.define-palette($sm-neon);
|
||||
$sm-neon-palette-accent: mat.define-palette($sm-neon, A200, A100, A400);
|
||||
// The warn palette is optional (defaults to red).
|
||||
@@ -76,6 +114,14 @@ $sm-neon-theme: mat.define-dark-theme((
|
||||
density: -2
|
||||
));
|
||||
|
||||
$sm-dark-theme: mat.define-dark-theme((
|
||||
color: (
|
||||
primary: $sm-dark-palette-primary,
|
||||
accent: $sm-dark-palette-accent,
|
||||
),
|
||||
typography: $custom-typography,
|
||||
density: -2
|
||||
));
|
||||
// Include theme styles for core and each component used in your app.
|
||||
// Alternatively, you can import and @include the theme mixins for each component
|
||||
// that you are using.
|
||||
@@ -83,6 +129,8 @@ $sm-neon-theme: mat.define-dark-theme((
|
||||
@include mat.slider-theme($sm-neon-theme);
|
||||
@include mat.form-field-theme($theme);
|
||||
|
||||
@include mat.select-theme($sm-dark-theme);
|
||||
|
||||
@import "src/app/webapp-common/shared/ui-components/styles/variables";
|
||||
|
||||
* {
|
||||
@@ -269,6 +317,59 @@ sm-debug-image-snippet {
|
||||
}
|
||||
}
|
||||
|
||||
.mat-mdc-select-panel {
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
|
||||
&.light-theme {
|
||||
--mdc-theme-surface: white;
|
||||
--mdc-theme-text-primary-on-background: #{$blue-500};
|
||||
}
|
||||
|
||||
&.dark, &.black, &.dark-theme {
|
||||
--mdc-theme-surface: #000;
|
||||
border: 1px solid $blue-500;
|
||||
|
||||
.mat-mdc-option {
|
||||
--mdc-theme-text-primary-on-background: #{$blue-200};
|
||||
}
|
||||
}
|
||||
|
||||
.mat-mdc-option {
|
||||
--mdc-typography-body1-line-height: 36px;
|
||||
--mdc-typography-body1-font-size: 14px;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.mat-mdc-option {
|
||||
--mdc-theme-text-primary-on-background: #{$blue-200};
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
line-height: 40px;
|
||||
margin-bottom: 2px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.mat-mdc-selected:not(.mat-mdc-option-multiple), &.mat-active {
|
||||
background: $blue-800;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-minimal::after {
|
||||
color: $blue-200;
|
||||
}
|
||||
|
||||
.mat-mdc-option:hover:not(.mdc-list-item--disabled),
|
||||
.mat-mdc-option:focus:not(.mdc-list-item--disabled),
|
||||
.mat-mdc-option.mat-mdc-option-active,
|
||||
.mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple):not(.mdc-list-item--disabled) {
|
||||
background: $dark-grey-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.dark-theme, .light-theme {
|
||||
.mat-mdc-form-field {
|
||||
--mdc-typography-body1-font-size: 14px;
|
||||
@@ -318,6 +419,44 @@ sm-debug-image-snippet {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.label-text {
|
||||
color: $blue-250;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.mat-mdc-slider.mdc-slider {
|
||||
$size: 36px;
|
||||
height: $size;
|
||||
|
||||
.mdc-slider__thumb {
|
||||
height: $size;
|
||||
width: $size;
|
||||
left: -$size * 0.5;
|
||||
}
|
||||
|
||||
.mat-ripple-element.mat-mdc-slider-active-ripple,
|
||||
.mat-ripple-element.mat-mdc-slider-focus-ripple,
|
||||
.mat-ripple-element.mat-mdc-slider-hover-ripple {
|
||||
height: $size !important;
|
||||
width: $size !important;
|
||||
left: 0 !important;
|
||||
top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-mdc-form-field {
|
||||
&.no-bottom {
|
||||
.mat-mdc-form-field-subscript-wrapper {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.dark-theme .mdc-text-field--disabled .mdc-text-field__input {
|
||||
color: rgba(255, 255, 255, 0.38);
|
||||
}
|
||||
|
||||
.mat-mdc-form-field.smooth-input {
|
||||
|
||||
@@ -27,7 +27,7 @@ export class CommonSearchComponent implements OnInit {
|
||||
minChars = 3;
|
||||
public regexError: boolean;
|
||||
|
||||
constructor(private store: Store<any>, private router: Router, private route: ActivatedRoute, private cdr: ChangeDetectorRef) {
|
||||
constructor(private store: Store, private router: Router, private route: ActivatedRoute, private cdr: ChangeDetectorRef) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
@import "angular-notifier/styles.scss";
|
||||
@import "angular-notifier/styles/themes/theme-material.scss";
|
||||
@import "shared/ui-components/styles/notifications";
|
||||
@import "britecharts/src/styles/charts/line";
|
||||
@import "britecharts/src/styles/charts/donut";
|
||||
@import "britecharts/src/styles/common/legend";
|
||||
@import "britecharts/src/styles/common/tooltip";
|
||||
@import "britecharts/src/styles/common/axes";
|
||||
@import "britecharts/src/styles/common/grid";
|
||||
@import "britecharts/src/styles/britecharts";
|
||||
// @import "ngx-markdown-editor/assets/highlight.js/agate.min.css";
|
||||
@import "shared/ui-components/styles/material-palette";
|
||||
@import "assets/fonts/trains-icons.scss";
|
||||
@@ -389,7 +384,6 @@ button {
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.empty-menu {
|
||||
@@ -600,6 +594,12 @@ html {
|
||||
.light-theme {
|
||||
.mat-mdc-menu-content {
|
||||
.mat-mdc-menu-item {
|
||||
&.cdk-keyboard-focused, &.cdk-program-focused {
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
&.mat-mdc-focus-indicator {
|
||||
--mdc-list-list-item-hover-label-text-color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
.mdc-list-item__primary-text {
|
||||
--mdc-list-list-item-label-text-color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
@@ -630,6 +630,10 @@ html {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.mat-mdc-menu-item {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
@@ -930,3 +934,9 @@ button.btn.button-outline-dark {
|
||||
min-width: fit-content;
|
||||
max-width: 50vw !important;
|
||||
}
|
||||
|
||||
.background-transparent {
|
||||
.mat-mdc-dialog-container {
|
||||
--mdc-dialog-container-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {ProjectStatsGraphData} from '@common/core/reducers/projects.reducer';
|
||||
import {User} from '~/business-logic/model/users/user';
|
||||
import {ProjectsGetAllResponseSingle} from '~/business-logic/model/projects/projectsGetAllResponseSingle';
|
||||
import {TaskStatusEnum} from '~/business-logic/model/tasks/taskStatusEnum';
|
||||
import {IBreadcrumbsLink, IBreadcrumbsOptions} from '@common/layout/breadcrumbs/breadcrumbs.component';
|
||||
|
||||
export const PROJECTS_PREFIX = '[ROOT_PROJECTS] ';
|
||||
|
||||
@@ -117,12 +118,12 @@ export const setCompanyTags = createAction(
|
||||
|
||||
export const setMainPageTagsFilter = createAction(
|
||||
PROJECTS_PREFIX + '[set main page tags filters]',
|
||||
props<{ tags: string[]; feature: string }>()
|
||||
props<{ tags?: string[]; feature: string}>()
|
||||
);
|
||||
|
||||
export const setMainPageTagsFilterMatchMode = createAction(
|
||||
PROJECTS_PREFIX + '[set main page tags filters match mode]',
|
||||
props<{ matchMode: string }>()
|
||||
props<{ matchMode: string; feature: string}>()
|
||||
);
|
||||
|
||||
export const addProjectTags = createAction(
|
||||
@@ -200,6 +201,20 @@ export const setDefaultNestedModeForFeature = createAction(
|
||||
PROJECTS_PREFIX + ' [set defaultNestedModeForFeature]',
|
||||
props<{ feature: string; isNested: boolean }>()
|
||||
);
|
||||
export const setSelectedBreadcrumbSubFeature = createAction(
|
||||
PROJECTS_PREFIX + ' [set SelectedSubFeature]',
|
||||
props<{ breadcrumb: IBreadcrumbsLink }>()
|
||||
);
|
||||
|
||||
export const setBreadcrumbMainFeature = createAction(
|
||||
PROJECTS_PREFIX + ' [setBreadcrumbMainFeature]',
|
||||
props<{ breadcrumb: IBreadcrumbsLink }>()
|
||||
);
|
||||
|
||||
export const setBreadcrumbsOptions = createAction(
|
||||
PROJECTS_PREFIX + ' [setBreadcrumbsOptions]',
|
||||
props<{ breadcrumbOptions: IBreadcrumbsOptions }>()
|
||||
);
|
||||
|
||||
export const resetTablesFilterProjectsOptions = createAction(
|
||||
PROJECTS_PREFIX + ' [reset tables filter projects options]'
|
||||
@@ -207,10 +222,15 @@ export const resetTablesFilterProjectsOptions = createAction(
|
||||
|
||||
export const getTablesFilterProjectsOptions = createAction(
|
||||
PROJECTS_PREFIX + ' [get tables filter projects options]',
|
||||
props<{ searchString: string; loadMore: boolean }>()
|
||||
props<{ searchString: string; loadMore: boolean}>()
|
||||
);
|
||||
|
||||
export const setTablesFilterProjectsOptions = createAction(
|
||||
PROJECTS_PREFIX + ' [set tables filter projects options]',
|
||||
props<{ projects: Partial<ProjectsGetAllResponseSingle>[]; scrollId: string; loadMore?: boolean }>()
|
||||
);
|
||||
|
||||
export const downloadForGetAll = createAction(
|
||||
PROJECTS_PREFIX + ' [downloadForGetAll]',
|
||||
props<{ prepareId: string}>()
|
||||
);
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
import {ISmAction} from '../models/actions';
|
||||
import {RECENT_TASKS_ACTIONS} from '../../../app.constants';
|
||||
|
||||
export class SetRecentTasks implements ISmAction {
|
||||
type = RECENT_TASKS_ACTIONS.SET_RECENT_TASKS;
|
||||
public payload: { tasks: Array<any> };
|
||||
|
||||
constructor(tasks: Array<any>) {
|
||||
this.payload = {tasks};
|
||||
}
|
||||
}
|
||||
import {createAction} from '@ngrx/store';
|
||||
import {Task} from '~/business-logic/model/tasks/task';
|
||||
|
||||
export const setRecentTasks = createAction('[RECENT_TASKS] SET_RECENT_TASKS', (tasks: Task[]) => ({ tasks }));
|
||||
|
||||
@@ -1,37 +1,25 @@
|
||||
import {ISmAction} from '../models/actions';
|
||||
import {NAVIGATION_ACTIONS, NAVIGATION_PREFIX} from '~/app.constants';
|
||||
import {Action, createAction, props} from '@ngrx/store';
|
||||
import {NAVIGATION_PREFIX} from '~/app.constants';
|
||||
import {createAction, props} from '@ngrx/store';
|
||||
import {Params} from '@angular/router';
|
||||
import {FilterMetadata} from 'primeng/api/filtermetadata';
|
||||
import {SortMeta} from 'primeng/api';
|
||||
import {CrumbTypeEnum, IBreadcrumbsLink} from "@common/layout/breadcrumbs/breadcrumbs.component";
|
||||
import {CrumbTypeEnum, IBreadcrumbsLink} from '@common/layout/breadcrumbs/breadcrumbs.component';
|
||||
|
||||
export const BREADCRUMBS_PREFIX = 'BREADCRUMBS_';
|
||||
|
||||
|
||||
// TODO: remove this action...
|
||||
export class NavigateTo implements ISmAction {
|
||||
readonly type = NAVIGATION_ACTIONS.NAVIGATE_TO;
|
||||
|
||||
constructor(public payload: {
|
||||
url: string;
|
||||
params?: Params;
|
||||
unGuard?: boolean;
|
||||
}) {
|
||||
}
|
||||
}
|
||||
|
||||
export class NavigationEnd implements Action {
|
||||
readonly type = NAVIGATION_ACTIONS.NAVIGATION_END;
|
||||
}
|
||||
export const navigationEnd = createAction(NAVIGATION_PREFIX + 'NAVIGATION_END');
|
||||
|
||||
export const setRouterSegments = createAction(
|
||||
NAVIGATION_ACTIONS.SET_ROUTER_SEGMENT, props<{
|
||||
NAVIGATION_PREFIX + 'SET_ROUTER_SEGMENT',
|
||||
props<{
|
||||
url: string;
|
||||
params: Params;
|
||||
queryParams: Params;
|
||||
config: string[];
|
||||
}>());
|
||||
data: any;
|
||||
}>()
|
||||
);
|
||||
|
||||
export const setURLParams = createAction(
|
||||
NAVIGATION_PREFIX + 'SET_URL_PARAMS',
|
||||
|
||||
@@ -1,24 +1,6 @@
|
||||
import {TASKS_ACTIONS} from '../../../app.constants';
|
||||
import {ISmAction} from '../models/actions';
|
||||
import {Action} from '@ngrx/store';
|
||||
import {createAction} from '@ngrx/store';
|
||||
|
||||
export class StopTask implements ISmAction {
|
||||
type = TASKS_ACTIONS.STOP_TASK;
|
||||
public payload = {task: ''};
|
||||
|
||||
constructor(taskId: string) {
|
||||
this.payload.task = taskId;
|
||||
}
|
||||
}
|
||||
|
||||
export class SetTaskInListAndInSelectedTask implements Action {
|
||||
type = TASKS_ACTIONS.TASKS_OPTIMISTIC;
|
||||
public payload: { task: string };
|
||||
|
||||
constructor(taskId: string, field: string, value) {
|
||||
this.payload = {
|
||||
task : taskId,
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
}
|
||||
export const setTaskInListAndInSelectedTask = createAction('[TASKS_PREFIX] OPTIMISTIC', (taskId: string, field: string, value) => ({
|
||||
task : taskId,
|
||||
[field]: value
|
||||
}));
|
||||
|
||||
12
src/app/webapp-common/core/cache/cache.module.ts
vendored
12
src/app/webapp-common/core/cache/cache.module.ts
vendored
@@ -1,12 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {EntitiesCacheService} from './entities-cache.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
declarations: [],
|
||||
providers: [EntitiesCacheService]
|
||||
})
|
||||
export class CacheModule { }
|
||||
@@ -1,70 +0,0 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Store} from '@ngrx/store';
|
||||
import {EntitiesEnum} from '../../../business-logic/constants';
|
||||
import {SmSyncStateSelectorService} from '../services/sync-state-selector.service';
|
||||
import {getCacheEntityObj} from './get-entity';
|
||||
import {IEntityObject} from './model';
|
||||
|
||||
@Injectable()
|
||||
export class EntitiesCacheService {
|
||||
|
||||
private readonly entities = [];
|
||||
|
||||
constructor(private syncSelector: SmSyncStateSelectorService, private store: Store<any>) {
|
||||
this.entities.forEach(entity => {
|
||||
entity.stream$.subscribe(({instance, force}) => {
|
||||
this.sendRequest(instance, force);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public startUpdating(entityName: EntitiesEnum) {
|
||||
const entity = this.getEntityObj(entityName);
|
||||
entity.startPinging(false);
|
||||
}
|
||||
|
||||
public stopUpdating(entityName: EntitiesEnum) {
|
||||
const entity = this.getEntityObj(entityName);
|
||||
entity.stopPinging();
|
||||
}
|
||||
|
||||
public getEntity(entityName: EntitiesEnum, force = false) {
|
||||
const entity = this.getEntityObj(entityName);
|
||||
this.sendRequest(entity, force);
|
||||
|
||||
return entity.selector$
|
||||
}
|
||||
|
||||
public updateEntity(entityName: EntitiesEnum) {
|
||||
const entity = this.getEntityObj(entityName);
|
||||
|
||||
this.sendRequest(entity, true);
|
||||
}
|
||||
|
||||
private getEntityObj(entityName): IEntityObject<any> {
|
||||
const entity = getCacheEntityObj(entityName);
|
||||
if (!entity) {
|
||||
throw 'Entity: ' + entityName + ' does not exist.';
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private sendRequest(entity, force) {
|
||||
if (force || this.shouldRequest(entity)) {
|
||||
this.store.dispatch(entity.getGetAction());
|
||||
// TODO:
|
||||
entity.setRequest('...');
|
||||
} else {
|
||||
// TODO: update request.
|
||||
}
|
||||
}
|
||||
|
||||
private shouldRequest(entity: IEntityObject<any>) {
|
||||
const data = this.syncSelector.selectSync(entity.selector);
|
||||
const shouldRequest = (!data || entity.didTimeExpire());
|
||||
|
||||
return shouldRequest;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,7 @@ export class CommonAuthEffects {
|
||||
constructor(
|
||||
private actions: Actions,
|
||||
private credentialsApi: ApiAuthService,
|
||||
private store: Store<any>,
|
||||
private store: Store,
|
||||
private adminService: AdminService,
|
||||
private matDialog: MatDialog
|
||||
) {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Actions, createEffect, ofType} from '@ngrx/effects';
|
||||
import {EmptyAction} from '~/app.constants';
|
||||
import {emptyAction} from '~/app.constants';
|
||||
import * as layoutActions from '../actions/layout.actions';
|
||||
import {addMessage} from '../actions/layout.actions';
|
||||
import {bufferTime, filter, map, mergeMap, switchMap, take} from 'rxjs/operators';
|
||||
@@ -92,7 +92,7 @@ export class LayoutEffects {
|
||||
this.notifierService.show({type: payload.severity, message: payload.msg, actions: payload.userActions}) :
|
||||
EMPTY
|
||||
),
|
||||
mergeMap((actions: Action[]) => actions.length > 0 ? actions : [new EmptyAction()])
|
||||
mergeMap((actions: Action[]) => actions.length > 0 ? actions : [emptyAction()])
|
||||
));
|
||||
|
||||
requestFailed: Observable<any> = createEffect( () => this.actions.pipe(
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Store} from '@ngrx/store';
|
||||
import {Actions, createEffect, ofType} from '@ngrx/effects';
|
||||
import {Actions, concatLatestFrom, createEffect, ofType} from '@ngrx/effects';
|
||||
import {ApiProjectsService} from '~/business-logic/api-services/projects.service';
|
||||
import * as actions from '../actions/projects.actions';
|
||||
import {setProjectAncestors, setShowHidden, setTablesFilterProjectsOptions} from '../actions/projects.actions';
|
||||
import {catchError, debounceTime, filter, map, mergeMap, switchMap, withLatestFrom} from 'rxjs/operators';
|
||||
import {
|
||||
downloadForGetAll,
|
||||
setMainPageTagsFilter,
|
||||
setProjectAncestors,
|
||||
setShowHidden,
|
||||
setTablesFilterProjectsOptions
|
||||
} from '../actions/projects.actions';
|
||||
import {
|
||||
catchError,
|
||||
debounceTime,
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
map,
|
||||
mergeMap,
|
||||
switchMap,
|
||||
withLatestFrom
|
||||
} from 'rxjs/operators';
|
||||
import {requestFailed} from '../actions/http.actions';
|
||||
import {activeLoader, deactivateLoader, setServerError} from '../actions/layout.actions';
|
||||
import {setSelectedModels} from '../../models/actions/models-view.actions';
|
||||
@@ -12,14 +27,17 @@ import {TagColorMenuComponent} from '../../shared/ui-components/tags/tag-color-m
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {ApiOrganizationService} from '~/business-logic/api-services/organization.service';
|
||||
import {OrganizationGetTagsResponse} from '~/business-logic/model/organization/organizationGetTagsResponse';
|
||||
import {selectRouterParams} from '../reducers/router-reducer';
|
||||
import {EMPTY, forkJoin, of} from 'rxjs';
|
||||
import {selectRouterConfig, selectRouterParams} from '../reducers/router-reducer';
|
||||
import {EMPTY, forkJoin, Observable, of} from 'rxjs';
|
||||
import {ProjectsGetTaskTagsResponse} from '~/business-logic/model/projects/projectsGetTaskTagsResponse';
|
||||
import {ProjectsGetModelTagsResponse} from '~/business-logic/model/projects/projectsGetModelTagsResponse';
|
||||
import {
|
||||
selectAllProjectsUsers, selectProjectsOptionsScrollId,
|
||||
selectAllProjectsUsers, selectIsDeepMode,
|
||||
selectMainPageTagsFilter,
|
||||
selectProjectsOptionsScrollId,
|
||||
selectSelectedMetricVariantForCurrProject,
|
||||
selectSelectedProjectId, selectShowHidden,
|
||||
selectSelectedProjectId,
|
||||
selectShowHidden,
|
||||
} from '../reducers/projects.reducer';
|
||||
import {
|
||||
OperationErrorDialogComponent
|
||||
@@ -36,6 +54,14 @@ import {escapeRegex} from '@common/shared/utils/escape-regex';
|
||||
import {ProjectsGetAllExRequest} from '~/business-logic/model/projects/projectsGetAllExRequest';
|
||||
import {ProjectsGetAllResponseSingle} from '~/business-logic/model/projects/projectsGetAllResponseSingle';
|
||||
import {rootProjectsPageSize} from '@common/constants';
|
||||
import {HTTP} from '~/app.constants';
|
||||
import {cleanTag} from '@common/shared/utils/helpers.util';
|
||||
import {selectProjectType} from '~/core/reducers/view.reducer';
|
||||
import {selectExperimentsTableFilters} from '@common/experiments/reducers';
|
||||
import {Params} from '@angular/router';
|
||||
import {selectCompareAddTableFilters} from '@common/experiments-compare/reducers';
|
||||
import {selectTableFilters} from '@common/models/reducers';
|
||||
import {selectSelectModelTableFilters} from '@common/select-model/select-model.reducer';
|
||||
|
||||
export const ALL_PROJECTS_OBJECT = {id: '*', name: 'All Experiments'};
|
||||
|
||||
@@ -45,7 +71,7 @@ export class ProjectsEffects {
|
||||
|
||||
constructor(
|
||||
private actions$: Actions, private projectsApi: ApiProjectsService, private orgApi: ApiOrganizationService,
|
||||
private store: Store<any>, private dialog: MatDialog, private tasksApi: ApiTasksService,
|
||||
private store: Store, private dialog: MatDialog, private tasksApi: ApiTasksService,
|
||||
private usersApi: ApiUsersService,
|
||||
) {
|
||||
}
|
||||
@@ -57,14 +83,23 @@ export class ProjectsEffects {
|
||||
));
|
||||
|
||||
|
||||
setDeep = createEffect(() => this.actions$.pipe(
|
||||
ofType(actions.setDeep),
|
||||
debounceTime(300),
|
||||
withLatestFrom(this.store.select(selectSelectedProjectId), this.store.select(selectIsDeepMode)),
|
||||
distinctUntilChanged(([, , preIsDeep], [, , currIsDeep]) => preIsDeep === currIsDeep),
|
||||
map(([, projectId,]) => actions.getProjectUsers({projectId}))));
|
||||
|
||||
|
||||
getTablesFilterProjectsOptions$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(actions.getTablesFilterProjectsOptions),
|
||||
debounceTime(300),
|
||||
withLatestFrom(
|
||||
concatLatestFrom(() => [
|
||||
this.store.select(selectShowHidden),
|
||||
this.store.select(selectProjectsOptionsScrollId),
|
||||
),
|
||||
switchMap(([action, showHidden, scrollId]) => forkJoin([
|
||||
this.getRelevantTableFilters(this.store.select(selectRouterConfig))
|
||||
]),
|
||||
switchMap(([action, showHidden, scrollId, filters]) => forkJoin([
|
||||
this.projectsApi.projectsGetAllEx({
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
page_size: rootProjectsPageSize,
|
||||
@@ -83,19 +118,30 @@ export class ProjectsEffects {
|
||||
_any_: {pattern: `^${escapeRegex(action.searchString)}$`, fields: ['name', 'id']},
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
} as ProjectsGetAllExRequest).pipe(map(res => res.projects)) :
|
||||
of([])
|
||||
of([]),
|
||||
!action.loadMore && filters['project.name']?.value.length ?
|
||||
this.projectsApi.projectsGetAllEx({
|
||||
id: filters['project.name']?.value,
|
||||
only_fields: ['name', 'company'],
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
} as ProjectsGetAllExRequest).pipe(map(res => res.projects)) :
|
||||
of([]),
|
||||
])
|
||||
.pipe(map(([allProjects, specificProjects]) => ({
|
||||
.pipe(map(([allProjects, specificProjects, selectedProjects]) => ({
|
||||
projects: [
|
||||
...(specificProjects.length > 0 && allProjects.projects.some(project => project.id === specificProjects[0]?.id) ? [] : specificProjects),
|
||||
...allProjects.projects
|
||||
...allProjects.projects,
|
||||
...selectedProjects
|
||||
],
|
||||
scrollId: allProjects.scroll_id,
|
||||
loadMore: action.loadMore
|
||||
})
|
||||
))
|
||||
),
|
||||
mergeMap((projects: { projects: ProjectsGetAllResponseSingle[]; scrollId: string }) => [setTablesFilterProjectsOptions({...projects})])
|
||||
mergeMap((projects: {
|
||||
projects: ProjectsGetAllResponseSingle[];
|
||||
scrollId: string;
|
||||
}) => [setTablesFilterProjectsOptions({...projects})])
|
||||
)
|
||||
);
|
||||
|
||||
@@ -107,7 +153,7 @@ export class ProjectsEffects {
|
||||
|
||||
resetAncestorProjects$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(actions.setSelectedProjectId),
|
||||
withLatestFrom(this.store.select(selectSelectedProjectId)),
|
||||
concatLatestFrom(() => this.store.select(selectSelectedProjectId)),
|
||||
filter(([action, prevProjectId]) => action.projectId !== prevProjectId),
|
||||
mergeMap(() => [setProjectAncestors({projects: null})])
|
||||
));
|
||||
@@ -191,7 +237,14 @@ export class ProjectsEffects {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
switchMap(action => this.projectsApi.projectsGetProjectTags({filter: {system_tags: [action.entity]}})
|
||||
.pipe(
|
||||
map((res: OrganizationGetTagsResponse) => actions.setTags({tags: res.tags})),
|
||||
withLatestFrom(this.store.select(selectMainPageTagsFilter), this.store.select(selectProjectType)),
|
||||
mergeMap(([res, fTags, projectType]) => [
|
||||
actions.setTags({tags: res.tags}),
|
||||
...(fTags?.length > 0 && fTags.some(fTag => !res.tags.includes(cleanTag(fTag))) ? [setMainPageTagsFilter({
|
||||
tags: fTags.filter(fTag => res.tags.includes(cleanTag(fTag))),
|
||||
feature: projectType
|
||||
})] : []),
|
||||
]),
|
||||
catchError(error => [requestFailed(error)])
|
||||
)
|
||||
)
|
||||
@@ -199,7 +252,7 @@ export class ProjectsEffects {
|
||||
|
||||
getTagsEffect = createEffect(() => this.actions$.pipe(
|
||||
ofType(actions.getTags),
|
||||
withLatestFrom(this.store.select(selectRouterParams).pipe(
|
||||
concatLatestFrom(() => this.store.select(selectRouterParams).pipe(
|
||||
map(params => (params === null || params?.projectId === '*') ? [] : [params.projectId]))),
|
||||
mergeMap(([action, projects]) => {
|
||||
const ids = action?.projectId ? [action.projectId] : projects;
|
||||
@@ -239,10 +292,10 @@ export class ProjectsEffects {
|
||||
|
||||
fetchProjectStats = createEffect(() => this.actions$.pipe(
|
||||
ofType(actions.fetchGraphData),
|
||||
withLatestFrom(
|
||||
concatLatestFrom(() => [
|
||||
this.store.select(selectSelectedProjectId),
|
||||
this.store.select(selectSelectedMetricVariantForCurrProject),
|
||||
),
|
||||
]),
|
||||
filter(([, , variant]) => !!variant),
|
||||
switchMap(([, projectId, variant]) => {
|
||||
const col = createMetricColumn(variant, projectId);
|
||||
@@ -290,10 +343,9 @@ export class ProjectsEffects {
|
||||
|
||||
getAllProjectsUsersEffect = createEffect(() => this.actions$.pipe(
|
||||
ofType(actions.getAllSystemProjects),
|
||||
switchMap(() => this.usersApi.usersGetAllEx({
|
||||
switchMap(() => this.projectsApi.projectsGetUserNames({
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
order_by: ['name'],
|
||||
only_fields: ['name'],
|
||||
include_subprojects: true
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
}, null, 'body', true).pipe(
|
||||
mergeMap(res => [actions.setAllProjectUsers(res)]),
|
||||
@@ -306,17 +358,14 @@ export class ProjectsEffects {
|
||||
|
||||
getUsersEffect = createEffect(() => this.actions$.pipe(
|
||||
ofType(actions.getProjectUsers),
|
||||
withLatestFrom(
|
||||
this.store.select(selectAllProjectsUsers)
|
||||
concatLatestFrom(() => [this.store.select(selectAllProjectsUsers), this.store.select(selectIsDeepMode)]
|
||||
),
|
||||
switchMap(([action, all]) => (!action.projectId || action.projectId === '*' ?
|
||||
switchMap(([action, all, isDeep]) => (!action.projectId || action.projectId === '*' ?
|
||||
of({users: all}) :
|
||||
this.usersApi.usersGetAllEx({
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
order_by: ['name'],
|
||||
only_fields: ['name'],
|
||||
active_in_projects: [action.projectId]
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
this.projectsApi.projectsGetUserNames({
|
||||
projects: [action.projectId],
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
include_subprojects: isDeep
|
||||
}, null, 'body', true)).pipe(
|
||||
mergeMap(res => [actions.setProjectUsers(res)]),
|
||||
catchError(error => [
|
||||
@@ -347,6 +396,55 @@ export class ProjectsEffects {
|
||||
))
|
||||
));
|
||||
|
||||
// downloadForGetAll$ = createEffect(() => this.actions$.pipe(
|
||||
// ofType(downloadForGetAll),
|
||||
// filter(action => !!action.prepareId),
|
||||
// withLatestFrom(this.store.select(selectActiveWorkspace)),
|
||||
// switchMap(([action, workspace]) => fromFetch(`${HTTP.API_BASE_URL}/organization.download_for_get_all`,
|
||||
// {
|
||||
// ...(workspace?.id && {headers: {[TENANT_HEADER] : workspace.id}}),
|
||||
// method: 'POST',
|
||||
// credentials: 'include',
|
||||
// // eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
// body: JSON.stringify({prepare_id: action.prepareId})
|
||||
// })
|
||||
// .pipe(
|
||||
// switchMap(res => from(res.blob())),
|
||||
// map(fileBlob => {
|
||||
// const url = window.URL.createObjectURL(fileBlob);
|
||||
// const a = document.createElement('a');
|
||||
// a.href = url;
|
||||
// a.target = '_blank';
|
||||
// a.download = `full-table.csv`;
|
||||
// a.click();
|
||||
// })
|
||||
// )),
|
||||
// ), {dispatch: false});
|
||||
|
||||
downloadForGetAll$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(downloadForGetAll),
|
||||
filter(action => !!action.prepareId),
|
||||
)).subscribe((action) => {
|
||||
const a = document.createElement('a');
|
||||
a.href = `${HTTP.API_BASE_URL}/organization.download_for_get_all?prepare_id=${action.prepareId}`;
|
||||
a.target = '_blank';
|
||||
a.click();
|
||||
}
|
||||
);
|
||||
|
||||
private getRelevantTableFilters(routerConfig$: Observable<Params>) {
|
||||
return routerConfig$.pipe(switchMap(config => {
|
||||
if (config.includes('compare-experiments')) {
|
||||
return this.store.select(selectCompareAddTableFilters);
|
||||
} else if (config?.includes('models')) {
|
||||
return this.store.select(selectTableFilters);
|
||||
} else if (config?.includes('compare-models') || config?.includes('input-model')) {
|
||||
return this.store.select(selectSelectModelTableFilters);
|
||||
} else {
|
||||
return this.store.select(selectExperimentsTableFilters);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,8 @@ import {ActivatedRoute, NavigationExtras, Params, Router} from '@angular/router'
|
||||
import {Actions, createEffect, ofType} from '@ngrx/effects';
|
||||
import {uniq} from 'lodash-es';
|
||||
import {map, tap} from 'rxjs/operators';
|
||||
import {NAVIGATION_ACTIONS} from '~/app.constants';
|
||||
import {encodeFilters, encodeOrder} from '../../shared/utils/tableParamEncode';
|
||||
import {NavigateTo, NavigationEnd, setRouterSegments, setURLParams} from '../actions/router.actions';
|
||||
import {navigationEnd, setRouterSegments, setURLParams} from '../actions/router.actions';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@@ -17,19 +16,15 @@ export class RouterEffects {
|
||||
) {
|
||||
}
|
||||
|
||||
// TODO: (itay) remove after delete old pages.
|
||||
activeLoader = createEffect(() => this.actions$.pipe(
|
||||
ofType<NavigateTo>(NAVIGATION_ACTIONS.NAVIGATE_TO),
|
||||
tap(action => {
|
||||
(!action.payload.params || !action.payload.url) ?
|
||||
this.router.navigateByUrl(action.payload.url, /* Removed unsupported properties by Angular migration: queryParams. */ {}) :
|
||||
this.router.navigate([action.payload.url, action.payload.params], {queryParams: {unGuard: action.payload.unGuard}});
|
||||
})
|
||||
), {dispatch: false});
|
||||
|
||||
routerNavigationEnd = createEffect(() => this.actions$.pipe(
|
||||
ofType<NavigationEnd>(NAVIGATION_ACTIONS.NAVIGATION_END),
|
||||
map(() => setRouterSegments({url: this.getRouterUrl(), params: this.getRouterParams(), config: this.getRouterConfig(), queryParams: this.route.snapshot.queryParams}))
|
||||
ofType(navigationEnd),
|
||||
map(() => setRouterSegments({
|
||||
url: this.getRouterUrl(),
|
||||
params: this.getRouterParams(),
|
||||
config: this.getRouterConfig(),
|
||||
queryParams: this.route.snapshot.queryParams,
|
||||
data: this.route.snapshot.firstChild?.data
|
||||
}))
|
||||
));
|
||||
|
||||
setTableParams = createEffect(() => this.actions$.pipe(
|
||||
|
||||
@@ -30,7 +30,7 @@ export class CommonUserEffects {
|
||||
private actions: Actions, private userService: ApiUsersService,
|
||||
private router: Router, private loginApi: ApiLoginService,
|
||||
private serverService: ApiServerService,
|
||||
private store: Store<any>, private errorService: ErrorService
|
||||
private store: Store, private errorService: ErrorService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {setCurrentUser} from '~/core/actions/users.action';
|
||||
export class WebappInterceptor implements HttpInterceptor {
|
||||
protected user: GetCurrentUserResponseUserObject;
|
||||
|
||||
constructor(protected router: Router, protected store: Store<any>) {
|
||||
constructor(protected router: Router, protected store: Store) {
|
||||
this.store.select(selectCurrentUser).subscribe(user => this.user = user);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export class WebappInterceptor implements HttpInterceptor {
|
||||
protected errorHandler(request: HttpRequest<any>, err: HttpErrorResponse) {
|
||||
const redirectUrl: string = window.location.pathname + window.location.search;
|
||||
if (request.url.endsWith('system.company_info')) {
|
||||
return throwError(err);
|
||||
return throwError(() => err);
|
||||
}
|
||||
// For automatic login don't go to login page (login in APP_INITIALIZER)
|
||||
if (err.status === 401 && (
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import {Action} from '@ngrx/store';
|
||||
|
||||
export interface ISmAction extends Action {
|
||||
payload?: any;
|
||||
meta?: ISmActionMeta; // deprecated
|
||||
}
|
||||
|
||||
export interface ISmActionMeta {
|
||||
loading?: boolean;
|
||||
}
|
||||
@@ -7,7 +7,10 @@ import {ITableExperiment} from '../../experiments/shared/common-experiment-model
|
||||
import {MetricColumn} from '@common/shared/utils/tableParamEncode';
|
||||
import {User} from '~/business-logic/model/users/user';
|
||||
import {ProjectsGetAllResponseSingle} from '~/business-logic/model/projects/projectsGetAllResponseSingle';
|
||||
import {selectRouterConfig} from "@common/core/reducers/router-reducer";
|
||||
import {selectRouterParams} from '@common/core/reducers/router-reducer';
|
||||
import {IBreadcrumbsLink, IBreadcrumbsOptions} from '@common/layout/breadcrumbs/breadcrumbs.component';
|
||||
import {selectProjectType} from '~/core/reducers/view.reducer';
|
||||
import {uniqBy} from 'lodash-es';
|
||||
|
||||
|
||||
export interface ProjectStatsGraphData {
|
||||
@@ -18,10 +21,11 @@ export interface ProjectStatsGraphData {
|
||||
type: string;
|
||||
status: string;
|
||||
user: string;
|
||||
title?: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface RootProjects {
|
||||
projects: Project[];
|
||||
selectedProject: Project;
|
||||
projectAncestors: Project[];
|
||||
archive: boolean;
|
||||
@@ -40,17 +44,18 @@ export interface RootProjects {
|
||||
extraUsers: User[];
|
||||
showHidden: boolean;
|
||||
hideExamples: boolean;
|
||||
mainPageTagsFilter: { [Feature: string]: string[] };
|
||||
mainPageTagsFilter: { [Feature: string]: { tags: string[]; filterMatchMode: string } };
|
||||
mainPageTagsFilterMatchMode: string;
|
||||
defaultNestedModeForFeature: { [feature: string]: boolean };
|
||||
selectedSubFeature: IBreadcrumbsLink;
|
||||
tablesFilterProjectsOptions: Partial<ProjectsGetAllResponseSingle>[];
|
||||
projectsOptionsScrollId: string;
|
||||
breadcrumbOptions: IBreadcrumbsOptions;
|
||||
}
|
||||
|
||||
const initRootProjects: RootProjects = {
|
||||
mainPageTagsFilter: {},
|
||||
mainPageTagsFilterMatchMode: 'AND',
|
||||
projects: null,
|
||||
selectedProject: null,
|
||||
projectAncestors: null,
|
||||
archive: false,
|
||||
@@ -70,13 +75,17 @@ const initRootProjects: RootProjects = {
|
||||
showHidden: false,
|
||||
hideExamples: false,
|
||||
defaultNestedModeForFeature: {},
|
||||
selectedSubFeature: null,
|
||||
breadcrumbOptions: null,
|
||||
tablesFilterProjectsOptions: null,
|
||||
projectsOptionsScrollId: null
|
||||
};
|
||||
|
||||
export const projects = state => state.rootProjects as RootProjects;
|
||||
export const selectRootProjects = createSelector(projects, (state): Project[] => state.projects);
|
||||
export const selectRouterProjectId = createSelector(selectRouterParams, params => params?.projectId);
|
||||
export const selectSelectedProject = createSelector(projects, state => state.selectedProject);
|
||||
export const selectSelectedBreadcrumbSubFeature = createSelector(projects, state => state.selectedSubFeature);
|
||||
export const selectBreadcrumbOptions = createSelector(projects, state => state.breadcrumbOptions);
|
||||
export const selectProjectAncestors = createSelector(projects, state => state.projectAncestors);
|
||||
export const selectSelectedProjectDescription = createSelector(projects, state => state.selectedProject?.description);
|
||||
export const selectSelectedProjectId = createSelector(selectSelectedProject, (selectedProject): string => selectedProject ? selectedProject.id : '');
|
||||
@@ -85,8 +94,9 @@ export const selectIsDeepMode = createSelector(projects, state => state.deep);
|
||||
export const selectTagsFilterByProject = createSelector(projects, selectSelectedProjectId,
|
||||
(state, projectId) => projectId !== '*' && state.tagsFilterByProject);
|
||||
export const selectProjectTags = createSelector(projects, state => state.projectTags);
|
||||
export const selectMainPageTagsFilter = createSelector(projects, selectRouterConfig, (state, config) => config?.[0] ? state.mainPageTagsFilter[config?.[0]] : []);
|
||||
export const selectMainPageTagsFilterMatchMode = createSelector(projects, state => state.mainPageTagsFilterMatchMode);
|
||||
|
||||
export const selectMainPageTagsFilter = createSelector(projects, selectProjectType,(state, projectType) => projectType? state.mainPageTagsFilter[projectType]?.tags : []);
|
||||
export const selectMainPageTagsFilterMatchMode = createSelector(projects, selectProjectType, (state, projectType) => projectType? state.mainPageTagsFilter[projectType]?.filterMatchMode : null);
|
||||
export const selectCompanyTags = createSelector(projects, state => state.companyTags);
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export const selectProjectSystemTags = createSelector(projects, state => getSystemTags({system_tags: state.systemTags} as ITableExperiment));
|
||||
@@ -107,12 +117,14 @@ export const selectProjectUsers = createSelector(projects, state => state.extraU
|
||||
state.users
|
||||
);
|
||||
export const selectAllProjectsUsers = createSelector(projects, state => state.allUsers);
|
||||
export const selectSelectedProjectUsers = createSelector(selectSelectedProjectId, selectProjectUsers, selectAllProjectsUsers,
|
||||
(projectId, projectUsers, allUsers) => projectId === '*' ? allUsers : projectUsers);
|
||||
export const selectTablesFilterProjectsOptions = createSelector(projects, state => state.tablesFilterProjectsOptions);
|
||||
|
||||
export const projectsReducer = createReducer(
|
||||
initRootProjects,
|
||||
on(projectsActions.resetProjects, state => ({...state, projects: [], lastUpdate: null})),
|
||||
on(projectsActions.setSelectedProjectId, (state, action) => {
|
||||
on(projectsActions.resetProjects, (state): RootProjects => ({...state, lastUpdate: null})),
|
||||
on(projectsActions.setSelectedProjectId, (state, action): RootProjects => {
|
||||
const projectId = action.projectId;
|
||||
return {
|
||||
...state,
|
||||
@@ -120,79 +132,103 @@ export const projectsReducer = createReducer(
|
||||
graphData: initRootProjects.graphData,
|
||||
};
|
||||
}),
|
||||
on(projectsActions.setSelectedProject, (state, action) => ({
|
||||
on(projectsActions.setSelectedProject, (state, action): RootProjects => ({
|
||||
...state,
|
||||
selectedProject: action.project,
|
||||
extraUsers: []
|
||||
})),
|
||||
on(projectsActions.setProjectAncestors, (state, action) => ({...state, projectAncestors: action.projects})),
|
||||
on(projectsActions.setSelectedProjectStats, (state, action) => ({
|
||||
on(projectsActions.setProjectAncestors, (state, action): RootProjects => ({
|
||||
...state,
|
||||
projectAncestors: action.projects
|
||||
})),
|
||||
on(projectsActions.setSelectedBreadcrumbSubFeature, (state, action): RootProjects => ({
|
||||
...state,
|
||||
selectedSubFeature: action.breadcrumb
|
||||
})),
|
||||
on(projectsActions.setBreadcrumbsOptions, (state, action): RootProjects => ({
|
||||
...state,
|
||||
breadcrumbOptions: action.breadcrumbOptions
|
||||
})),
|
||||
on(projectsActions.setSelectedProjectStats, (state, action): RootProjects => ({
|
||||
...state,
|
||||
selectedProject: {
|
||||
...state.selectedProject,
|
||||
stats: action.project?.stats
|
||||
}
|
||||
})),
|
||||
on(projectsActions.resetSelectedProject, state => ({
|
||||
on(projectsActions.resetSelectedProject, (state): RootProjects => ({
|
||||
...state,
|
||||
selectedProject: initRootProjects.selectedProject,
|
||||
users: [],
|
||||
extraUsers: []
|
||||
})),
|
||||
on(projectsActions.updateProjectCompleted, (state, action) => ({
|
||||
on(projectsActions.updateProjectCompleted, (state, action): RootProjects => ({
|
||||
...state,
|
||||
selectedProject: {...state.selectedProject, ...action.changes},
|
||||
projects: state.projects.map(project => project.id === action.id ? project : {...project, ...action.changes})
|
||||
})),
|
||||
on(projectsActions.setArchive, (state, action) => ({...state, archive: action.archive})),
|
||||
on(projectsActions.setDeep, (state, action) => ({...state, deep: action.deep})),
|
||||
on(projectsActions.setTags, (state, action) => ({...state, projectTags: action.tags})),
|
||||
on(projectsActions.setTagsFilterByProject, (state, action) => ({
|
||||
on(projectsActions.setArchive, (state, action): RootProjects => ({...state, archive: action.archive})),
|
||||
on(projectsActions.setDeep, (state, action): RootProjects => ({...state, deep: action.deep})),
|
||||
on(projectsActions.setTags, (state, action): RootProjects => ({...state, projectTags: action.tags})),
|
||||
on(projectsActions.setTagsFilterByProject, (state, action): RootProjects => ({
|
||||
...state,
|
||||
tagsFilterByProject: action.tagsFilterByProject
|
||||
})),
|
||||
on(projectsActions.setCompanyTags, (state, action) => ({
|
||||
on(projectsActions.setCompanyTags, (state, action): RootProjects => ({
|
||||
...state,
|
||||
companyTags: action.tags,
|
||||
systemTags: action.systemTags
|
||||
})),
|
||||
on(projectsActions.addProjectTags, (state, action) => ({
|
||||
on(projectsActions.addProjectTags, (state, action): RootProjects => ({
|
||||
...state,
|
||||
projectTags: Array.from(new Set(state.projectTags.concat(action.tags))).sort()
|
||||
})),
|
||||
on(projectsActions.setMainPageTagsFilter, (state, action) => ({
|
||||
on(projectsActions.setMainPageTagsFilter, (state, action): RootProjects => ({
|
||||
...state,
|
||||
mainPageTagsFilter: {...state.mainPageTagsFilter, [action.feature] : action.tags }})),
|
||||
on(projectsActions.setMainPageTagsFilterMatchMode, (state, action) => ({
|
||||
...state,
|
||||
mainPageTagsFilterMatchMode: action.matchMode
|
||||
mainPageTagsFilter: {
|
||||
...state.mainPageTagsFilter,
|
||||
[action.feature]: {...state.mainPageTagsFilter[action.feature], tags: action.tags}
|
||||
}
|
||||
})),
|
||||
on(projectsActions.setTagColors, (state, action) => ({
|
||||
on(projectsActions.setMainPageTagsFilterMatchMode, (state, action): RootProjects => ({
|
||||
...state,
|
||||
mainPageTagsFilter: {
|
||||
...state.mainPageTagsFilter,
|
||||
[action.feature]: {...state.mainPageTagsFilter[action.feature], filterMatchMode: action.matchMode}
|
||||
}
|
||||
})),
|
||||
on(projectsActions.setTagColors, (state, action): RootProjects => ({
|
||||
...state,
|
||||
tagsColors: {...state.tagsColors, [action.tag]: action.colors}
|
||||
})),
|
||||
on(projectsActions.setMetricVariant, (state, action) => ({
|
||||
on(projectsActions.setMetricVariant, (state, action): RootProjects => ({
|
||||
...state, graphVariant: {...state.graphVariant, [action.projectId]: action.col}
|
||||
})),
|
||||
on(projectsActions.setGraphData, (state, action) => ({...state, graphData: action.stats})),
|
||||
on(projectsActions.toggleState, (state, action) => ({
|
||||
on(projectsActions.setGraphData, (state, action): RootProjects => ({...state, graphData: action.stats})),
|
||||
on(projectsActions.toggleState, (state, action): RootProjects => ({
|
||||
...state,
|
||||
hiddenStates: {...state.hiddenStates, [action.state]: !state.hiddenStates?.[action.state]}
|
||||
})),
|
||||
on(projectsActions.setLastUpdate, (state, action) => ({...state, lastUpdate: action.lastUpdate})),
|
||||
on(projectsActions.setProjectUsers, (state, action) => ({...state, users: action.users, extraUsers: []})),
|
||||
on(projectsActions.setAllProjectUsers, (state, action) => ({...state, allUsers: action.users})),
|
||||
on(projectsActions.setProjectExtraUsers, (state, action) => ({...state, extraUsers: action.users})),
|
||||
on(projectsActions.setShowHidden, (state, action) => ({...state, showHidden: action.show})),
|
||||
on(projectsActions.setHideExamples, (state, action) => ({...state, hideExamples: action.hide})),
|
||||
on(projectsActions.setDefaultNestedModeForFeature, (state, action) => ({
|
||||
on(projectsActions.setLastUpdate, (state, action): RootProjects => ({...state, lastUpdate: action.lastUpdate})),
|
||||
on(projectsActions.setProjectUsers, (state, action): RootProjects => ({
|
||||
...state,
|
||||
users: action.users,
|
||||
extraUsers: []
|
||||
})),
|
||||
on(projectsActions.setAllProjectUsers, (state, action): RootProjects => ({...state, allUsers: action.users})),
|
||||
on(projectsActions.setProjectExtraUsers, (state, action): RootProjects => ({...state, extraUsers: action.users})),
|
||||
on(projectsActions.setShowHidden, (state, action): RootProjects => ({...state, showHidden: action.show})),
|
||||
on(projectsActions.setHideExamples, (state, action): RootProjects => ({...state, hideExamples: action.hide})),
|
||||
on(projectsActions.setDefaultNestedModeForFeature, (state, action): RootProjects => ({
|
||||
...state,
|
||||
defaultNestedModeForFeature: {...state.defaultNestedModeForFeature, [action.feature]: action.isNested}
|
||||
})),
|
||||
on(projectsActions.resetTablesFilterProjectsOptions, (state) => ({...state, tablesFilterProjectsOptions: null})),
|
||||
on(projectsActions.setTablesFilterProjectsOptions, (state, action) => ({
|
||||
on(projectsActions.resetTablesFilterProjectsOptions, (state): RootProjects => ({
|
||||
...state,
|
||||
tablesFilterProjectsOptions: action.loadMore ? (state.tablesFilterProjectsOptions || []).concat(action.projects) : action.projects,
|
||||
tablesFilterProjectsOptions: null
|
||||
})),
|
||||
on(projectsActions.setTablesFilterProjectsOptions, (state, action): RootProjects => ({
|
||||
...state,
|
||||
tablesFilterProjectsOptions: action.loadMore ? uniqBy((state.tablesFilterProjectsOptions || []).concat(action.projects), 'id') : uniqBy(action.projects, 'id'),
|
||||
projectsOptionsScrollId: action.scrollId
|
||||
}))
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {RECENT_TASKS_ACTIONS} from '../../../app.constants';
|
||||
import {SetRecentTasks} from '../actions/recent-tasks.actions';
|
||||
import {Task} from '../../../business-logic/model/tasks/task';
|
||||
import {setRecentTasks} from '../actions/recent-tasks.actions';
|
||||
import {Task} from '~/business-logic/model/tasks/task';
|
||||
import {createReducer, on} from '@ngrx/store';
|
||||
|
||||
const initTasks = {
|
||||
data : <Array<Partial<Task>>>[],
|
||||
@@ -8,11 +8,7 @@ const initTasks = {
|
||||
|
||||
export const recentTasks = state => state.recentTasks;
|
||||
|
||||
export function recentTasksReducer(state = initTasks, action: SetRecentTasks) {
|
||||
switch (action.type) {
|
||||
case RECENT_TASKS_ACTIONS.SET_RECENT_TASKS:
|
||||
return {...state, data: action.payload.tasks};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
export const recentTasksReducer = createReducer(
|
||||
initTasks,
|
||||
on(setRecentTasks, (state, action) => ({...state, data: action.tasks}))
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@ export interface RouterState {
|
||||
queryParams: Params;
|
||||
config: string[];
|
||||
skipNextNavigation: boolean;
|
||||
data: any;
|
||||
}
|
||||
|
||||
const initRouter: RouterState = {
|
||||
@@ -16,6 +17,7 @@ const initRouter: RouterState = {
|
||||
queryParams: null,
|
||||
config: null,
|
||||
skipNextNavigation: false,
|
||||
data: null
|
||||
};
|
||||
|
||||
export const selectRouter = state => state.router as RouterState;
|
||||
@@ -23,10 +25,11 @@ export const selectRouterUrl = createSelector(selectRouter, router => router &&
|
||||
export const selectRouterParams = createSelector(selectRouter, router => router && router?.params);
|
||||
export const selectRouterQueryParams = createSelector(selectRouter, router => router && router.queryParams);
|
||||
export const selectRouterConfig = createSelector(selectRouter, router => router && router.config);
|
||||
export const selectRouterData = createSelector(selectRouter, router => router && router.data);
|
||||
|
||||
export const routerReducer = createReducer(initRouter,
|
||||
on(setRouterSegments, (state, action) => ({
|
||||
on(setRouterSegments, (state, action): RouterState => ({
|
||||
...state, params: action.params, queryParams: action.queryParams,
|
||||
url: action.url, config: action.config
|
||||
url: action.url, config: action.config, data: action.data
|
||||
})),
|
||||
);
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface UsersState {
|
||||
showOnlyUserWork: boolean;
|
||||
serverVersions: { server: string; api: string };
|
||||
gettingStarted: any;
|
||||
settings: any;
|
||||
}
|
||||
|
||||
export const initUsers: UsersState = {
|
||||
@@ -33,11 +34,13 @@ export const initUsers: UsersState = {
|
||||
workspaces: [],
|
||||
showOnlyUserWork: false,
|
||||
serverVersions: null,
|
||||
gettingStarted: null
|
||||
gettingStarted: null,
|
||||
settings: null,
|
||||
};
|
||||
|
||||
export const users = state => state.users as UsersState;
|
||||
|
||||
export const selectSettings = createSelector(users, (state): any => state?.settings);
|
||||
export const selectMaxDownloadItems = createSelector(selectSettings, (state): number => state?.max_download_items ?? 1000);
|
||||
export const selectCurrentUser = createSelector(users, state => state.currentUser);
|
||||
export const selectActiveWorkspace = createSelector(users, state => state.activeWorkspace);
|
||||
export const selectUserWorkspaces = createSelector(users, state => state.userWorkspaces);
|
||||
|
||||
@@ -82,7 +82,6 @@ export const selectShowEmbedReportMenu = createSelector(views, state => state.sh
|
||||
export const selectBreadcrumbs = createSelector(views, state => state && state.breadcrumbs);
|
||||
|
||||
|
||||
|
||||
export const viewReducers = [
|
||||
on(requestFailed, (state, action) => {
|
||||
const isLoggedOut = action.err && action.err.status === 401;
|
||||
|
||||
@@ -5,7 +5,7 @@ import {take} from 'rxjs/operators';
|
||||
@Injectable()
|
||||
export class SmGetStateService {
|
||||
|
||||
constructor(private store: Store<any>) {}
|
||||
constructor(private store: Store) {}
|
||||
|
||||
getState() {
|
||||
let _state: any;
|
||||
|
||||
@@ -5,7 +5,7 @@ import {take} from 'rxjs/operators';
|
||||
@Injectable()
|
||||
export class SmSyncStateSelectorService {
|
||||
|
||||
constructor(private store: Store<any>) {
|
||||
constructor(private store: Store) {
|
||||
}
|
||||
|
||||
selectSync(selector: Selector<any, any>) {
|
||||
|
||||
@@ -29,7 +29,7 @@ import {ApiModelsService} from '~/business-logic/api-services/models.service';
|
||||
import {catchError, mergeMap, map, switchMap, withLatestFrom} from 'rxjs/operators';
|
||||
import {isEqual} from 'lodash-es';
|
||||
import {activeSearchLink} from '~/features/dashboard-search/dashboard-search.consts';
|
||||
import {EmptyAction} from '~/app.constants';
|
||||
import {emptyAction} from '~/app.constants';
|
||||
import {escapeRegex} from '@common/shared/utils/escape-regex';
|
||||
import {selectCurrentUser, selectShowOnlyUserWork} from '@common/core/reducers/users-reducer';
|
||||
import {selectHideExamples, selectShowHidden} from '@common/core/reducers/projects.reducer';
|
||||
@@ -60,6 +60,7 @@ export const getEntityStatQuery = (action, searchHidden) => ({
|
||||
...(action.query && {pattern: action.regExp ? action.query : escapeRegex(action.query)}),
|
||||
fields: ['name', 'id']
|
||||
},
|
||||
system_tags: ['-archived']
|
||||
},
|
||||
datasets: {
|
||||
_any_: {
|
||||
@@ -148,7 +149,7 @@ export class DashboardSearchEffects {
|
||||
case activeSearchLink.reports:
|
||||
return searchReports(term);
|
||||
}
|
||||
return new EmptyAction();
|
||||
return emptyAction();
|
||||
}
|
||||
)
|
||||
));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ApiProjectsService} from '~/business-logic/api-services/projects.service';
|
||||
import {Actions, createEffect, ofType} from '@ngrx/effects';
|
||||
import {Actions, concatLatestFrom, createEffect, ofType} from '@ngrx/effects';
|
||||
import {requestFailed} from '../core/actions/http.actions';
|
||||
import {activeLoader, deactivateLoader} from '../core/actions/layout.actions';
|
||||
import {
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import {CARDS_IN_ROW} from './common-dashboard.const';
|
||||
import {ApiTasksService} from '~/business-logic/api-services/tasks.service';
|
||||
import {ProjectsGetAllExRequest} from '~/business-logic/model/projects/projectsGetAllExRequest';
|
||||
import {catchError, mergeMap, map, switchMap, withLatestFrom} from 'rxjs/operators';
|
||||
import {catchError, mergeMap, map, switchMap} from 'rxjs/operators';
|
||||
import {ApiLoginService} from '~/business-logic/api-services/login.service';
|
||||
import {Store} from '@ngrx/store';
|
||||
import {ErrorService} from '../shared/services/error.service';
|
||||
@@ -24,7 +24,7 @@ export class CommonDashboardEffects {
|
||||
constructor(
|
||||
private actions: Actions, private projectsApi: ApiProjectsService,
|
||||
private tasksApi: ApiTasksService, private loginApi: ApiLoginService,
|
||||
private errorService: ErrorService, private store: Store<any>,
|
||||
private errorService: ErrorService, private store: Store,
|
||||
) {}
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
activeLoader = createEffect(() => this.actions.pipe(
|
||||
@@ -34,12 +34,12 @@ export class CommonDashboardEffects {
|
||||
|
||||
getRecentProjects = createEffect(() => this.actions.pipe(
|
||||
ofType(getRecentProjects),
|
||||
withLatestFrom(
|
||||
concatLatestFrom(() => [
|
||||
this.store.select(selectCurrentUser),
|
||||
this.store.select(selectShowOnlyUserWork),
|
||||
this.store.select(selectShowHidden),
|
||||
this.store.select(selectHideExamples),
|
||||
),
|
||||
]),
|
||||
mergeMap(([action, user, showOnlyUserWork, showHidden, hideExamples]) =>
|
||||
this.projectsApi.projectsGetAllEx({
|
||||
stats_for_state: ProjectsGetAllExRequest.StatsForStateEnum.Active,
|
||||
@@ -52,7 +52,7 @@ export class CommonDashboardEffects {
|
||||
...(showHidden && {search_hidden: true}),
|
||||
...(!showHidden && {include_stats_filter: {system_tags: ['-pipeline']}}),
|
||||
...(hideExamples && {allow_public: false}),
|
||||
only_fields: ['name', 'company', 'user', 'created', 'default_output_destination']
|
||||
only_fields: ['name', 'basename', 'company', 'user', 'created', 'default_output_destination']
|
||||
}).pipe(
|
||||
mergeMap(({projects}) => [setRecentProjects({projects}), deactivateLoader(action.type)]),
|
||||
catchError(error => [deactivateLoader(action.type), requestFailed(error)])
|
||||
@@ -62,11 +62,11 @@ export class CommonDashboardEffects {
|
||||
|
||||
getRecentTasks = createEffect(() => this.actions.pipe(
|
||||
ofType(getRecentExperiments),
|
||||
withLatestFrom(
|
||||
concatLatestFrom(() => [
|
||||
this.store.select(selectCurrentUser),
|
||||
this.store.select(selectShowOnlyUserWork),
|
||||
this.store.select(selectHideExamples),
|
||||
),
|
||||
]),
|
||||
switchMap(([action, user, showOnlyUserWork, hideExamples]) => this.tasksApi.tasksGetAllEx({
|
||||
page: 0,
|
||||
page_size: 5,
|
||||
|
||||
@@ -15,7 +15,7 @@ import {filter, take} from 'rxjs/operators';
|
||||
export class DashboardExperimentsComponent implements OnInit {
|
||||
@Input() recentTasks: IRecentTask[];
|
||||
|
||||
constructor(private store: Store<any>, private router: Router) {
|
||||
constructor(private store: Store, private router: Router) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
@@ -30,7 +30,7 @@ export class DashboardProjectsComponent implements OnInit, AfterViewInit, OnDest
|
||||
@Output() width = new EventEmitter<number>();
|
||||
|
||||
constructor(
|
||||
private store: Store<any>,
|
||||
private store: Store,
|
||||
public router: Router,
|
||||
private matDialog: MatDialog
|
||||
) {
|
||||
|
||||
@@ -66,7 +66,7 @@ export class DashboardSearchBaseComponent implements OnInit, OnDestroy{
|
||||
public resultsCount$: Observable<Map<ActiveSearchLink, number>>;
|
||||
public reportsResults$: Observable<Array<IReport>>;
|
||||
|
||||
constructor(public store: Store<any>, public router: Router){
|
||||
constructor(public store: Store, public router: Router){
|
||||
this.searchQuery$ = store.select(selectSearchQuery);
|
||||
this.activeSearch$ = store.select(selectActiveSearch);
|
||||
this.modelsResults$ = store.select(selectModelsResults);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div [id]="step.stepId" class="step-container pointer"
|
||||
[class.selected]="selected">
|
||||
[class.selected]="selected" data-id="processSteps">
|
||||
<div class="step-part step-title" [class]="step?.data?.status">
|
||||
<div
|
||||
class="title"
|
||||
@@ -7,12 +7,12 @@
|
||||
[smTooltip]="step?.data?.name ?? step.name + step?.data?.version ? ' v' + step.data.version : ''"
|
||||
matTooltipPosition="above"
|
||||
>{{step?.data?.name ?? step.name}}<ng-container *ngIf="step?.data?.version"> v{{step.data.version}}</ng-container></div>
|
||||
<i class="al-icon sm-md al-ico-console" (click)="openConsole.emit()"></i>
|
||||
<i data-id="consoleIcon" class="al-icon sm-md al-ico-console" (click)="openConsole.emit()"></i>
|
||||
</div>
|
||||
<div class="step-part step-footer" [class]="step?.data?.status">
|
||||
<div *ngIf="step?.data?.job_size">{{step.data.job_size | filesize: fileSizeConfigStorage}}</div>
|
||||
<div class="d-flex-center" *ngIf="step?.data?.last_update">
|
||||
<i class="al-icon al-ico-upload sm me-1"></i>{{step.data.last_update * 1000 | timeAgo}}
|
||||
<i class="al-icon al-ico-upload sm me-1" data-id="uploadIcon"></i>{{step.data.last_update * 1000 | timeAgo}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
font-size: 12px;
|
||||
|
||||
&.in_progress {
|
||||
background-color: $running-green;
|
||||
background-color: darken($running-green, 20%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
(smHesitate)="menuHesitate.hesitateStatus && menu.closed.emit()"
|
||||
>
|
||||
<i class="al-icon al-ico-download pointer line-item"
|
||||
data-id="downloadButton"
|
||||
#idElement
|
||||
[matMenuTriggerFor]="menu"
|
||||
(click)="openMenu(); menuHesitate.hesitateStatus = true"
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
</mat-expansion-panel-header>
|
||||
<div class="panel-body" *ngIf="entity">
|
||||
<div class="header mt-2">
|
||||
<div class="name ellipsis">{{entity.name}}<ng-container *ngIf="entity?.runtime?.version"> v{{entity.runtime.version}}</ng-container></div>
|
||||
<span class="status" [class]="entity.status">{{entity.status | replaceViaMapPipe:convertStatusMap | replaceViaMapPipe:convertStatusMapBase}}</span>
|
||||
<div class="name ellipsis" data-id="datasetName" >{{entity.name}}<ng-container *ngIf="entity?.runtime?.version"> v{{entity.runtime.version}}</ng-container></div>
|
||||
<span data-id="datasetStatus" class="status" [class]="entity.status">{{entity.status | replaceViaMapPipe:convertStatusMap | replaceViaMapPipe:convertStatusMapBase}}</span>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="param">
|
||||
<div class="key">ID</div>
|
||||
<div class="key" data-id="id" >ID</div>
|
||||
<div class="value d-flex align-item-center justify-content-between" [smTooltip]="entity.id" smShowTooltipIfEllipsis>
|
||||
<span>{{entity.id?.slice(0, 8)}}...</span>
|
||||
<i
|
||||
class="pointer al-icon al-ico-copy-to-clipboard sm"
|
||||
data-id="copyIcon"
|
||||
ngxClipboard
|
||||
[cbContent]="entity?.id"
|
||||
(cbOnSuccess)="copyToClipboard()"
|
||||
@@ -21,8 +22,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="param">
|
||||
<div class="key">Parent</div>
|
||||
<div class="value" [smTooltip]="entity?.parent?.name" smShowTooltipIfEllipsis>
|
||||
<div class="key" data-id="parent">Parent</div>
|
||||
<div data-id="parentValue" class="value" [smTooltip]="entity?.parent?.name" smShowTooltipIfEllipsis>
|
||||
<a
|
||||
*ngIf="entity?.parent?.id; else: empty"
|
||||
class="arr-link"
|
||||
@@ -36,39 +37,39 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="param continue">
|
||||
<div class="key">Size</div>
|
||||
<div class="value" [smTooltip]="entity?.runtime?.ds_total_size + ' (original)'" smShowTooltipIfEllipsis>{{($any(entity?.runtime?.ds_total_size) | filesize : fileSizeConfigStorage) || '-'}}<span class="comment">(original)</span></div>
|
||||
<div class="key" data-id="size">Size</div>
|
||||
<div data-id="sizeValue" class="value" [smTooltip]="entity?.runtime?.ds_total_size + ' (original)'" smShowTooltipIfEllipsis>{{($any(entity?.runtime?.ds_total_size) | filesize : fileSizeConfigStorage) || '-'}}<span class="comment">(original)</span></div>
|
||||
</div>
|
||||
<div class="param">
|
||||
<div class="key"></div>
|
||||
<div class="value" [smTooltip]="entity?.runtime?.ds_total_size_compressed + ' (compressed)'" smShowTooltipIfEllipsis>{{($any(entity?.runtime?.ds_total_size_compressed) | filesize : fileSizeConfigStorage) || '-'}}<span class="comment">(compressed)</span></div>
|
||||
</div>
|
||||
<div class="param">
|
||||
<div class="key">File count</div>
|
||||
<div class="value" [smTooltip]="entity?.runtime?.ds_file_count" smShowTooltipIfEllipsis>{{entity?.runtime?.ds_file_count ?? '-'}}</div>
|
||||
<div class="key" data-id="fileCount">File count</div>
|
||||
<div data-id="fileCountValue" class="value" [smTooltip]="entity?.runtime?.ds_file_count" smShowTooltipIfEllipsis>{{entity?.runtime?.ds_file_count ?? '-'}}</div>
|
||||
</div>
|
||||
<div class="param">
|
||||
<div class="key">Link count</div>
|
||||
<div class="value" [smTooltip]="entity?.runtime?.ds_link_count" smShowTooltipIfEllipsis>{{entity?.runtime?.ds_link_count ?? '-'}}</div>
|
||||
<div class="key" data-id="linkCount" >Link count</div>
|
||||
<div data-id="linkCountValue" class="value" [smTooltip]="entity?.runtime?.ds_link_count" smShowTooltipIfEllipsis>{{entity?.runtime?.ds_link_count ?? '-'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="header">FILES CHANGED</div>
|
||||
<div class="param">
|
||||
<div class="key">Added</div>
|
||||
<div class="value" [smTooltip]="entity?.runtime?.ds_change_add " smShowTooltipIfEllipsis>{{entity?.runtime?.ds_change_add ?? '-'}}</div>
|
||||
<div class="key" data-id="added">Added</div>
|
||||
<div data-id="addedValue" class="value" [smTooltip]="entity?.runtime?.ds_change_add " smShowTooltipIfEllipsis>{{entity?.runtime?.ds_change_add ?? '-'}}</div>
|
||||
</div>
|
||||
<div class="param">
|
||||
<div class="key">Modified</div>
|
||||
<div class="value" [smTooltip]="entity?.runtime?.ds_change_modify " smShowTooltipIfEllipsis>{{entity?.runtime?.ds_change_modify ?? '-'}}</div>
|
||||
<div class="key" data-id="modified">Modified</div>
|
||||
<div data-id="modifiedValue" class="value" [smTooltip]="entity?.runtime?.ds_change_modify " smShowTooltipIfEllipsis>{{entity?.runtime?.ds_change_modify ?? '-'}}</div>
|
||||
</div>
|
||||
<div class="param">
|
||||
<div class="key">Removed</div>
|
||||
<div class="value" [smTooltip]="entity?.runtime?.ds_change_remove " smShowTooltipIfEllipsis>{{entity?.runtime?.ds_change_remove ?? '-'}}</div>
|
||||
<div class="key" data-id="removed">Removed</div>
|
||||
<div data-id="removedValue" class="value" [smTooltip]="entity?.runtime?.ds_change_remove " smShowTooltipIfEllipsis>{{entity?.runtime?.ds_change_remove ?? '-'}}</div>
|
||||
</div>
|
||||
<div class="param">
|
||||
<div class="key">Size</div>
|
||||
<div class="value"
|
||||
<div class="key" data-id="size">Size</div>
|
||||
<div data-id="sizeValue" class="value"
|
||||
*ngIf="entity?.runtime?.ds_change_size"
|
||||
[smTooltip]="$any(entity?.runtime?.ds_change_size) | filesize: fileSizeConfigStorage"
|
||||
smShowTooltipIfEllipsis
|
||||
@@ -76,7 +77,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="header"><span>DESCRIPTION</span><i class="al-icon al-ico-edit sm" (click)="editDescription.emit(entity)"></i></div>
|
||||
<div class="header"><span>DESCRIPTION</span><i data-id="editIcon" class="al-icon al-ico-edit sm" (click)="editDescription.emit(entity)"></i></div>
|
||||
<div class="param continue h-auto">
|
||||
<div class="multi-line-value">{{entity?.comment}}</div>
|
||||
</div>
|
||||
@@ -87,7 +88,7 @@
|
||||
class="arr-link"
|
||||
target="_blank"
|
||||
[href]="'/projects/' + project + '/experiments/' + entity?.id + '/output/execution'">
|
||||
Task information<i class="al-icon al-ico-link-arrow sm"></i>
|
||||
Task information<i class="al-icon al-ico-link-arrow sm" data-id="taskInfoIcon" ></i>
|
||||
</a>
|
||||
</footer>
|
||||
</mat-expansion-panel>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
(editDescription)="editDescription($event)"
|
||||
></sm-simple-dataset-version-details>
|
||||
<div class="console-button">
|
||||
<button class="btn btn-cml-primary d-flex align-items-center" (click)="toggleDetails()">
|
||||
<button data-id="detailsButton" class="btn btn-cml-primary d-flex align-items-center" (click)="toggleDetails()">
|
||||
<i class="al-icon al-ico-console sm me-3"></i>DETAILS
|
||||
</button>
|
||||
</div>
|
||||
@@ -63,8 +63,8 @@
|
||||
(valueChanged)="detailsPanelMode = $event"
|
||||
></sm-button-toggle>
|
||||
<div class="close">
|
||||
<i class="al-icon pointer" [class]="maximizeResults ? 'al-ico-min-panel' : 'al-ico-max-panel'" (click)="toggleResultSize()"></i>
|
||||
<i class="al-icon al-ico-dialog-x pointer ms-4" (click)="openLog(false)"></i>
|
||||
<i class="al-icon pointer" [class]="maximizeResults ? 'al-ico-min-panel' : 'al-ico-max-panel'" (click)="toggleResultSize()" data-id="expandButton"></i>
|
||||
<i data-id="crossButton" class="al-icon al-ico-dialog-x pointer ms-4" (click)="openLog(false)"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div [ngSwitch]="detailsPanelMode" class="content">
|
||||
|
||||
@@ -26,7 +26,7 @@ export class SimpleDatasetVersionInfoComponent extends PipelineControllerInfoCom
|
||||
|
||||
constructor(
|
||||
protected _dagManager: DagManagerUnsortedService<PipelineItem>,
|
||||
protected store: Store<any>,
|
||||
protected store: Store,
|
||||
protected cdr: ChangeDetectorRef,
|
||||
protected zone: NgZone,
|
||||
private dialog: MatDialog,
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
[style.top.px]="position.y"
|
||||
[matMenuTriggerFor]="experimentMenu">
|
||||
</div>
|
||||
<mat-menu #experimentMenu="matMenu" [hasBackdrop]="false">
|
||||
<mat-menu #experimentMenu="matMenu" [hasBackdrop]="false" class="light-theme entity-context-menu">
|
||||
<button *ngIf="tableMode" mat-menu-item (click)="toggleDetails()">
|
||||
<i [class]="'al-icon '+ icons.DETAILS + ' sm-md'"></i>Details
|
||||
</button>
|
||||
<hr *ngIf="tableMode">
|
||||
<button mat-menu-item
|
||||
[matMenuTriggerFor]="tagMenu"
|
||||
[matMenuTriggerFor]="tagMenu.matMenu"
|
||||
[disabled]="selectedDisableAvailable[menuItems.tags]?.disable"
|
||||
(menuOpened)="tagMenuOpened()"
|
||||
(menuClosed)="tagMenuClosed()">
|
||||
@@ -34,14 +34,11 @@
|
||||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<mat-menu #tagMenu="matMenu">
|
||||
<sm-tags-menu
|
||||
#tagMenuContent
|
||||
class="light-theme"
|
||||
[tags]="experiment?.tags"
|
||||
[tagsFilterByProject]="tagsFilterByProject"
|
||||
[projectTags]="projectTags"
|
||||
[companyTags]="companyTags"
|
||||
(tagSelected)="tagSelected.emit($event)">
|
||||
</sm-tags-menu>
|
||||
</mat-menu>
|
||||
<sm-tags-menu
|
||||
#tagMenu
|
||||
[tags]="experiment?.tags"
|
||||
[tagsFilterByProject]="tagsFilterByProject"
|
||||
[projectTags]="projectTags"
|
||||
[companyTags]="companyTags"
|
||||
(tagSelected)="tagSelected.emit($event)">
|
||||
</sm-tags-menu>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user