mirror of
https://github.com/clearml/clearml-web
synced 2025-06-26 18:27:02 +00:00
parent
ff27bad900
commit
946d6ec9ae
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
node-version: '22'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
@ -29,4 +29,4 @@ jobs:
|
||||
run: npm run build
|
||||
|
||||
- name: Check for production build
|
||||
run: test -f build/index.html
|
||||
run: test -f build/browser/index.html
|
||||
|
129
angular.json
129
angular.json
@ -6,30 +6,35 @@
|
||||
"trains-webapp": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "sm",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser-esbuild",
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"options": {
|
||||
"preserveSymlinks": true,
|
||||
"outputPath": "build",
|
||||
"outputPath": {
|
||||
"base": "build"
|
||||
},
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"polyfills": [
|
||||
"zone.js"
|
||||
],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"src/app/webapp-common/shared/ui-components/styles/"
|
||||
"",
|
||||
"src/app/webapp-common/shared/ui-components/styles/",
|
||||
"src/app/webapp-common/styles/",
|
||||
"."
|
||||
]
|
||||
},
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico",
|
||||
"src/env.js",
|
||||
"src/version.json",
|
||||
"src/404.html",
|
||||
"src/manifest.webmanifest",
|
||||
"src/app/webapp-common/assets",
|
||||
{
|
||||
"glob": "**/*",
|
||||
@ -38,11 +43,12 @@
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/primeng/resources/components/table/table.css",
|
||||
"node_modules/primeicons/primeicons.css",
|
||||
"node_modules/ngx-markdown-editor/assets/highlight.js/agate.min.css",
|
||||
"src/styles.scss",
|
||||
"src/fonts.scss"
|
||||
{
|
||||
"bundleName": "global-styles",
|
||||
"inject": true,
|
||||
"input": "src/app/webapp-common/styles/style.scss"
|
||||
}
|
||||
],
|
||||
"scripts": [
|
||||
"node_modules/ngx-markdown-editor/assets/highlight.js/highlight.min.js"
|
||||
@ -56,27 +62,29 @@
|
||||
"fast-xml-parser",
|
||||
"url",
|
||||
"@aws-crypto/sha256-browser",
|
||||
"@aws-crypto/crc32",
|
||||
"@aws-crypto/sha1-browser",
|
||||
"@aws-crypto/crc32",
|
||||
"@aws-crypto/crc32c",
|
||||
"bowser",
|
||||
"@smithy/util-defaults-mode-browser",
|
||||
"filesize/lib/filesize.es6",
|
||||
"hex-rgb",
|
||||
"ace-builds",
|
||||
"localforage",
|
||||
"dom-to-image",
|
||||
"ace-builds",
|
||||
"hocon-parser",
|
||||
"taira",
|
||||
"base64",
|
||||
"base-64",
|
||||
"export-to-csv",
|
||||
"dompurify",
|
||||
"hammerjs"
|
||||
],
|
||||
"extractLicenses": false,
|
||||
"buildOptimizer": false,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
"namedChunks": true
|
||||
"namedChunks": true,
|
||||
"browser": "src/main.ts"
|
||||
},
|
||||
"configurations": {
|
||||
"appdev": {
|
||||
@ -91,7 +99,6 @@
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"buildOptimizer": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
@ -111,7 +118,6 @@
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"buildOptimizer": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
@ -121,7 +127,8 @@
|
||||
"replace": "src/app/build-specifics/index.ts",
|
||||
"with": "src/app/build-specifics/index.prod.ts"
|
||||
}
|
||||
]
|
||||
],
|
||||
"serviceWorker": false
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": ""
|
||||
@ -158,22 +165,23 @@
|
||||
"main": "src/test.ts",
|
||||
"karmaConfig": "./karma.conf.js",
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
"zone.js"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"src/app/webapp-common/shared/ui-components/styles/"
|
||||
]
|
||||
},
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"tsConfig": "./tsconfig.spec.json",
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"",
|
||||
"src/app/webapp-common/shared/ui-components/styles/"
|
||||
]
|
||||
},
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico",
|
||||
"src/version.json",
|
||||
"src/manifest.webmanifest",
|
||||
"src/app/webapp-common/assets"
|
||||
]
|
||||
}
|
||||
@ -201,30 +209,34 @@
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser-esbuild",
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"options": {
|
||||
"preserveSymlinks": true,
|
||||
"outputPath": "dist/report-widgets",
|
||||
"baseHref": "widgets",
|
||||
"index": "src/app/webapp-common/clearml-applications/report-widgets/src/index.html",
|
||||
"main": "src/app/webapp-common/clearml-applications/report-widgets/src/main.ts",
|
||||
"outputPath": {
|
||||
"base": "dist/report-widgets"
|
||||
},
|
||||
"polyfills": [
|
||||
"zone.js"
|
||||
],
|
||||
"baseHref": "",
|
||||
"index": "src/app/webapp-common/clearml-applications/report-widgets/src/index.html",
|
||||
"tsConfig": "src/app/webapp-common/clearml-applications/report-widgets/tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/favicon.ico",
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/assets",
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/app/webapp-common/assets"
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/app/webapp-common/assets",
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/app/webapp-common/assets/fonts/trains.ttf"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"",
|
||||
"src/app/webapp-common/styles/",
|
||||
"src/app/webapp-common/shared/ui-components/styles/"
|
||||
]
|
||||
},
|
||||
"styles": [
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/styles.scss",
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/app/styles/styles.scss",
|
||||
{
|
||||
"input": "src/app/webapp-common/assets/fonts/trains-icons.scss",
|
||||
"bundleName": "trains-icons",
|
||||
@ -233,18 +245,20 @@
|
||||
],
|
||||
"scripts": [],
|
||||
"allowedCommonJsDependencies": [
|
||||
"string-to-color",
|
||||
"dom-to-image",
|
||||
"dompurify",
|
||||
"url",
|
||||
"taira",
|
||||
"@aws-crypto/crc32",
|
||||
"@aws-crypto/crc32c",
|
||||
"fast-xml-parser",
|
||||
"@aws-crypto/sha1-browser",
|
||||
"@aws-crypto/sha256-browser",
|
||||
"fast-xml-parser",
|
||||
"bowser"
|
||||
]
|
||||
"@aws-crypto/crc32",
|
||||
"@aws-crypto/crc32c",
|
||||
"bowser",
|
||||
"hammerjs",
|
||||
"dom-to-image",
|
||||
"dompurify",
|
||||
"string-to-color",
|
||||
"taira",
|
||||
"url"
|
||||
],
|
||||
"browser": "src/app/webapp-common/clearml-applications/report-widgets/src/main.ts"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
@ -257,7 +271,7 @@
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
"maximumError": "5kb"
|
||||
}
|
||||
],
|
||||
"fileReplacements": [
|
||||
@ -269,7 +283,6 @@
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
@ -313,16 +326,10 @@
|
||||
"assets": [
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/favicon.ico",
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/assets",
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/app/webapp-common/assets",
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/app/webapp-common/assets/fonts/trains.ttf"
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/app/webapp-common/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/styles.scss",
|
||||
{
|
||||
"input": "src/app/webapp-common/assets/fonts/trains-icons.scss",
|
||||
"bundleName": "trains-icons",
|
||||
"inject": false
|
||||
}
|
||||
"src/app/webapp-common/clearml-applications/report-widgets/src/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
@ -335,14 +342,20 @@
|
||||
"prefix": "sm",
|
||||
"style": "scss"
|
||||
},
|
||||
"@angular-eslint/schematics:application": {
|
||||
"setParserOptionsProject": true
|
||||
"al-schematics:component": {
|
||||
"prefix": "sm",
|
||||
"styleext": "scss"
|
||||
},
|
||||
"@angular-eslint/schematics:library": {
|
||||
"setParserOptionsProject": true
|
||||
"al-schematics:directive": {
|
||||
"prefix": "sm"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
"analytics": false,
|
||||
"schematicCollections": [
|
||||
"@angular-eslint/schematics",
|
||||
"@ngrx/schematics",
|
||||
"ngxtension"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
3150
package-lock.json
generated
3150
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
92
package.json
92
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clearml-webapp",
|
||||
"version": "1.17.0",
|
||||
"version": "2.0.0",
|
||||
"license": "",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
@ -19,21 +19,21 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^18.2.10",
|
||||
"@angular/cdk": "^18.2.11",
|
||||
"@angular/common": "^18.2.10",
|
||||
"@angular/compiler": "^18.2.10",
|
||||
"@angular/core": "^18.2.10",
|
||||
"@angular/forms": "^18.2.10",
|
||||
"@angular/material": "^18.2.11",
|
||||
"@angular/platform-browser": "^18.2.10",
|
||||
"@angular/platform-browser-dynamic": "^18.2.10",
|
||||
"@angular/platform-server": "^18.2.10",
|
||||
"@angular/router": "^18.2.10",
|
||||
"@angular/service-worker": "^18.2.10",
|
||||
"@angular/youtube-player": "^18.2.11",
|
||||
"@aws-sdk/client-s3": "^3.637.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.637.0",
|
||||
"@angular/animations": "^18.2.12",
|
||||
"@angular/cdk": "^18.2.14",
|
||||
"@angular/common": "^18.2.12",
|
||||
"@angular/compiler": "^18.2.12",
|
||||
"@angular/core": "^18.2.12",
|
||||
"@angular/forms": "^18.2.12",
|
||||
"@angular/material": "^18.2.14",
|
||||
"@angular/platform-browser": "^18.2.12",
|
||||
"@angular/platform-browser-dynamic": "^18.2.12",
|
||||
"@angular/platform-server": "^18.2.12",
|
||||
"@angular/router": "^18.2.12",
|
||||
"@angular/service-worker": "^18.2.12",
|
||||
"@angular/youtube-player": "^18.2.14",
|
||||
"@aws-sdk/client-s3": "^3.693.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.693.0",
|
||||
"@ctrl/ngx-github-buttons": "^9.0.0",
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@ngneat/dag": "^2.0.0",
|
||||
@ -43,23 +43,24 @@
|
||||
"@ngrx/operators": "^18.1.1",
|
||||
"@ngrx/router-store": "^18.1.1",
|
||||
"@ngrx/store": "^18.1.1",
|
||||
"ace-builds": "^1.36.2",
|
||||
"@typescript-eslint/types": "^8.15.0",
|
||||
"ace-builds": "^1.36.5",
|
||||
"angular-resizable-element": "^7.0.2",
|
||||
"angular-split": "^17.2.0",
|
||||
"angular-split": "^18.0.0",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
"bootstrap": "^5.3.3",
|
||||
"chart.js": "^4.4.4",
|
||||
"chart.js": "^4.4.6",
|
||||
"chartjs-adapter-date-fns": "^3.0.0",
|
||||
"chartjs-plugin-annotation": "^3.0.1",
|
||||
"chartjs-plugin-zoom": "^2.0.1",
|
||||
"chartjs-plugin-annotation": "^3.1.0",
|
||||
"chartjs-plugin-zoom": "^2.1.0",
|
||||
"curved-arrows": "^0.3.0",
|
||||
"d3-selection": "^3.0.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"diff": "^5.2.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"diff": "^7.0.0",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"dompurify": "^3.1.6",
|
||||
"export-to-csv": "^1.3.0",
|
||||
"filesize": "^10.1.4",
|
||||
"dompurify": "^3.2.0",
|
||||
"export-to-csv": "^1.4.0",
|
||||
"filesize": "^10.1.6",
|
||||
"has-ansi": "^6.0.0",
|
||||
"hocon-parser": "^1.0.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
@ -75,43 +76,44 @@
|
||||
"ngxtension": "^4.1.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"primeicons": "^7.0.0",
|
||||
"primeng": "^17.18.9",
|
||||
"primeng": "^17.18.15",
|
||||
"rxjs": "^7.8.1",
|
||||
"string-to-color": "^2.2.2",
|
||||
"taira": "^3.2.2",
|
||||
"tslib": "^2.7.0",
|
||||
"tslib": "^2.8.1",
|
||||
"url": "^0.11.4",
|
||||
"uuid": "^10.0.0",
|
||||
"uuid": "^11.0.3",
|
||||
"zone.js": "~0.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^18.2.11",
|
||||
"@angular-devkit/core": "^18.2.11",
|
||||
"@angular-devkit/schematics": "^18.2.11",
|
||||
"@angular-devkit/schematics-cli": "^18.2.1",
|
||||
"@angular/cli": "^18.2.11",
|
||||
"@angular/compiler-cli": "^18.2.10",
|
||||
"@angular/language-service": "^18.2.10",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@angular-devkit/build-angular": "^18.2.12",
|
||||
"@angular-devkit/core": "^18.2.12",
|
||||
"@angular-devkit/schematics": "^18.2.12",
|
||||
"@angular-devkit/schematics-cli": "^18.2.12",
|
||||
"@angular/cli": "^18.2.12",
|
||||
"@angular/compiler-cli": "^18.2.12",
|
||||
"@angular/language-service": "^18.2.12",
|
||||
"@ngrx/eslint-plugin": "^18.1.1",
|
||||
"@ngrx/schematics": "^18.1.1",
|
||||
"@ngrx/store-devtools": "^18.1.1",
|
||||
"@types/d3-selection": "^3.0.10",
|
||||
"@types/d3-selection": "^3.0.11",
|
||||
"@types/diff": "^6.0.0",
|
||||
"@types/dom-to-image": "^2.6.7",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"@types/has-ansi": "^5.0.2",
|
||||
"@types/jasmine": "^5.1.4",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^20.14.10",
|
||||
"@types/plotly.js": "^2.33.3",
|
||||
"@types/node": "^22.9.0",
|
||||
"@types/plotly.js": "^2.35.0",
|
||||
"@types/tinycolor2": "^1.4.6",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"angular-eslint": "^18.3.0",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-jsdoc": "^50.2.2",
|
||||
"angular-eslint": "^18.4.1",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-jsdoc": "^50.5.0",
|
||||
"eslint-plugin-prefer-arrow": "1.2.3",
|
||||
"primeng-sass-theme": "github:primefaces/primeng-sass-theme",
|
||||
"typescript": "^5.5.4",
|
||||
"typescript-eslint": "^8.2.0"
|
||||
"typescript-eslint": "^8.15.0"
|
||||
}
|
||||
}
|
||||
|
21
src/app/app.component.html
Executable file → Normal file
21
src/app/app.component.html
Executable file → Normal file
@ -1,17 +1,20 @@
|
||||
<sm-update-notifier #update
|
||||
[availableUpdates]="!hideUpdate && (updatesAvailable$ | async)"
|
||||
[currentUser]="currentUser"
|
||||
[dismissedVersion]="serverUpdatesService.lastDismissedVersion"
|
||||
(versionDismissed)="versionDismissed($event)"
|
||||
(notifierActive)="notifierActive($event)">
|
||||
</sm-update-notifier>
|
||||
[availableUpdates]="(updatesAvailable$ | async)"
|
||||
[currentUser]="$any(currentUser())"
|
||||
[dismissedVersion]="serverUpdatesService.lastDismissedVersion"
|
||||
(versionDismissed)="versionDismissed($event)"
|
||||
></sm-update-notifier>
|
||||
<sm-color-picker-wrapper id="color-picker-outlet"></sm-color-picker-wrapper>
|
||||
<sm-server-notification-dialog-container></sm-server-notification-dialog-container>
|
||||
<sm-spinner></sm-spinner>
|
||||
<div class="root-container">
|
||||
<sm-side-nav *ngIf="currentUser"></sm-side-nav>
|
||||
<div class="app-container" [class.login-page]="!currentUser" [class.notifier-open]="update?.active">
|
||||
<sm-header *ngIf="currentUser" [isLogin]="isLoginContext" [isShareMode]="isSharedAndNotOwner$ | async"></sm-header>
|
||||
@if (currentUser()) {
|
||||
<sm-side-nav></sm-side-nav>
|
||||
}
|
||||
<div class="app-container" [class.login-page]="!currentUser()" [class.notifier-open]="update?.active()">
|
||||
@if (currentUser()) {
|
||||
<sm-header [isLogin]="loginContext | ngrxPush" [isShareMode]="isSharedAndNotOwner()"></sm-header>
|
||||
}
|
||||
<router-outlet class="main-router"></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
|
6
src/app/app.component.scss
Executable file → Normal file
6
src/app/app.component.scss
Executable file → Normal file
@ -1,4 +1,4 @@
|
||||
@import "webapp-common/shared/ui-components/styles/variables";
|
||||
@import "variables";
|
||||
@import "webapp-common/layout/layout.scss";
|
||||
|
||||
$notifier-height: 30px;
|
||||
@ -18,6 +18,7 @@ notification-container {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
width: calc(100% - #{$side-bar-close-width});
|
||||
background-color: var(--color-surface);
|
||||
|
||||
&.notifier-open {
|
||||
height: calc(100% - #{$notifier-height});
|
||||
@ -52,4 +53,5 @@ iframe.iframe-maximized {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 999;
|
||||
}
|
||||
background-color: var(--color-surface);
|
||||
}
|
||||
|
114
src/app/app.component.ts
Executable file → Normal file
114
src/app/app.component.ts
Executable file → Normal file
@ -1,18 +1,14 @@
|
||||
import {selectCurrentUser} from '@common/core/reducers/users-reducer';
|
||||
import {Component, OnDestroy, OnInit, ViewEncapsulation, HostListener, Renderer2, inject} from '@angular/core';
|
||||
import {Component, ViewEncapsulation, HostListener, Renderer2, inject, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {NavigationEnd, Router} from '@angular/router';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
import {selectBreadcrumbs, selectLoggedOut} from '@common/core/reducers/view.reducer';
|
||||
import {Store} from '@ngrx/store';
|
||||
import {selectRouterParams, selectRouterUrl} from '@common/core/reducers/router-reducer';
|
||||
import {Project} from './business-logic/model/projects/project';
|
||||
import {getAllSystemProjects, setSelectedProjectId, updateProject} from '@common/core/actions/projects.actions';
|
||||
import {selectRouterProjectId, selectSelectedProject} from '@common/core/reducers/projects.reducer';
|
||||
import {selectRouterUrl} from '@common/core/reducers/router-reducer';
|
||||
import {getAllSystemProjects, setSelectedProjectId} from '@common/core/actions/projects.actions';
|
||||
import {selectRouterProjectId} from '@common/core/reducers/projects.reducer';
|
||||
import {getTutorialBucketCredentials} from '@common/core/actions/common-auth.actions';
|
||||
import {termsOfUseAccepted} from '@common/core/actions/users.actions';
|
||||
import {distinctUntilChanged, filter, tap} from 'rxjs/operators';
|
||||
import {distinctUntilChanged, filter, map} from 'rxjs/operators';
|
||||
import * as routerActions from './webapp-common/core/actions/router.actions';
|
||||
import {combineLatest, Observable, Subscription} from 'rxjs';
|
||||
import {ServerUpdatesService} from '@common/shared/services/server-updates.service';
|
||||
import {selectAvailableUpdates} from './core/reducers/view.reducer';
|
||||
import {UPDATE_SERVER_PATH} from './app.constants';
|
||||
@ -23,63 +19,42 @@ import {ConfigurationService} from '@common/shared/services/configuration.servic
|
||||
import {selectIsSharedAndNotOwner} from './features/experiments/reducers';
|
||||
import {TipsService} from '@common/shared/services/tips.service';
|
||||
import {USER_PREFERENCES_KEY} from '@common/user-preferences';
|
||||
import {Environment} from '../environments/base';
|
||||
import {loadExternalLibrary} from '@common/shared/utils/load-external-library';
|
||||
import {User} from '~/business-logic/model/users/user';
|
||||
import {BreadcrumbsService} from '@common/shared/services/breadcrumbs.service';
|
||||
import {ThemeService} from '@common/shared/services/theme.service';
|
||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'sm-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
providers: [ThemeService]
|
||||
})
|
||||
export class AppComponent implements OnInit, OnDestroy {
|
||||
export class AppComponent {
|
||||
private router = inject(Router);
|
||||
private titleService = inject(Title);
|
||||
private store = inject(Store);
|
||||
public serverUpdatesService = inject(ServerUpdatesService);
|
||||
private uiUpdatesService = inject(UiUpdatesService);
|
||||
private tipsService = inject(TipsService);
|
||||
private renderer = inject(Renderer2);
|
||||
private configService = inject(ConfigurationService);
|
||||
private config = inject(ConfigurationService);
|
||||
private breadcrumbsService = inject(BreadcrumbsService); // don't delete
|
||||
protected loggedOut$: Observable<boolean>;
|
||||
private urlSubscription: Subscription;
|
||||
protected selectedProject$: Observable<Project>;
|
||||
protected projectId: string;
|
||||
protected isWorkersContext: boolean;
|
||||
protected updatesAvailable$: Observable<string>;
|
||||
private breadcrumbsSubscription: Subscription;
|
||||
private selectedCurrentUserSubscription: Subscription;
|
||||
protected showNotification = true;
|
||||
protected isLoginContext: boolean;
|
||||
protected currentUser: User;
|
||||
protected isSharedAndNotOwner$: Observable<boolean>;
|
||||
private activeWorkspace: string;
|
||||
protected hideUpdate: boolean;
|
||||
protected showSurvey: boolean;
|
||||
private environment: Environment;
|
||||
private title = 'ClearML';
|
||||
private themeService = inject(ThemeService); // don't delete
|
||||
|
||||
protected updatesAvailable$ = this.store.select(selectAvailableUpdates);
|
||||
protected currentUser = this.store.selectSignal(selectCurrentUser);
|
||||
protected isSharedAndNotOwner = this.store.selectSignal(selectIsSharedAndNotOwner);
|
||||
|
||||
protected loginContext = this.store.select(selectRouterUrl).pipe(map(url => url?.includes('login')));
|
||||
|
||||
@HostListener('document:visibilitychange') onVisibilityChange() {
|
||||
this.store.dispatch(visibilityChanged({visible: !document.hidden}));
|
||||
}
|
||||
|
||||
@HostListener('window:beforeunload', ['$event'])
|
||||
beforeunloadHandler() {
|
||||
window.localStorage.setItem('lastWorkspace', this.activeWorkspace);
|
||||
}
|
||||
constructor() {
|
||||
|
||||
constructor(
|
||||
) {
|
||||
this.loggedOut$ = this.store.select(selectLoggedOut);
|
||||
this.isSharedAndNotOwner$ = this.store.select(selectIsSharedAndNotOwner);
|
||||
this.selectedProject$ = this.store.select(selectSelectedProject);
|
||||
this.updatesAvailable$ = this.store.select(selectAvailableUpdates);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
window.addEventListener('message', e => {
|
||||
if (e.data.maximizing) {
|
||||
const drawerContent = document.querySelector('sm-report mat-drawer-container');
|
||||
@ -94,20 +69,16 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
this.configService.globalEnvironmentObservable.subscribe(env => {
|
||||
this.hideUpdate = env.hideUpdateNotice;
|
||||
this.showSurvey = env.showSurvey;
|
||||
this.environment = env;
|
||||
});
|
||||
this.router.events
|
||||
.pipe(filter(event => event instanceof NavigationEnd))
|
||||
.subscribe(() => this.store.dispatch(routerActions.navigationEnd()));
|
||||
|
||||
this.selectedCurrentUserSubscription = this.store.select(selectCurrentUser).pipe(
|
||||
tap(user => this.currentUser = user as unknown as User),
|
||||
filter(user => !!user?.id),
|
||||
distinctUntilChanged((prev, next) => prev?.id === next?.id)
|
||||
)
|
||||
this.store.select(selectCurrentUser)
|
||||
.pipe(
|
||||
takeUntilDestroyed(),
|
||||
filter(user => !!user?.id),
|
||||
distinctUntilChanged((prev, next) => prev?.id === next?.id)
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.store.dispatch(getAllSystemProjects());
|
||||
this.store.dispatch(getTutorialBucketCredentials());
|
||||
@ -127,28 +98,11 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
this.store.dispatch(setSelectedProjectId({projectId}));
|
||||
});
|
||||
|
||||
this.urlSubscription = combineLatest([
|
||||
this.store.select(selectRouterUrl),
|
||||
this.store.select(selectRouterParams)
|
||||
])
|
||||
.subscribe(([url, params]) => {
|
||||
this.projectId = params?.projectId;
|
||||
this.isLoginContext = url && url.includes('login');
|
||||
this.isWorkersContext = url && url.includes('workers-and-queues');
|
||||
});
|
||||
|
||||
this.breadcrumbsSubscription = this.store.select(selectBreadcrumbs).subscribe(breadcrumbs => {
|
||||
const crumbs = breadcrumbs.flat().filter((breadcrumb => !!breadcrumb?.name)).map(breadcrumb => breadcrumb.name);
|
||||
if (crumbs.length> 0) {
|
||||
this.titleService.setTitle(`${this.title ? this.title + '-' : ''} ${crumbs.join(' / ')}`);
|
||||
}
|
||||
});
|
||||
|
||||
if (window.localStorage.getItem('disableHidpi') !== 'true') {
|
||||
this.setScale();
|
||||
}
|
||||
|
||||
loadExternalLibrary(this.store, this.environment.plotlyURL, plotlyReady);
|
||||
loadExternalLibrary(this.store, this.config.configuration().plotlyURL, plotlyReady);
|
||||
loadExternalLibrary(this.store, 'assets/ace-builds/ace.js', aceReady);
|
||||
}
|
||||
|
||||
@ -162,21 +116,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
this.renderer.setStyle(document.body, 'width', `${dimensionRatio}vw`);
|
||||
}
|
||||
|
||||
nameChanged(name) {
|
||||
this.store.dispatch(updateProject({id: this.projectId, changes: {name}}));
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.urlSubscription.unsubscribe();
|
||||
this.breadcrumbsSubscription.unsubscribe();
|
||||
this.selectedCurrentUserSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
versionDismissed(version: string) {
|
||||
this.serverUpdatesService.setDismissedVersion(version);
|
||||
}
|
||||
|
||||
notifierActive(show: boolean) {
|
||||
this.showNotification = show;
|
||||
}
|
||||
}
|
||||
|
0
src/app/app.constants.ts
Executable file → Normal file
0
src/app/app.constants.ts
Executable file → Normal file
13
src/app/app.module.ts
Executable file → Normal file
13
src/app/app.module.ts
Executable file → Normal file
@ -1,4 +1,4 @@
|
||||
import {APP_INITIALIZER, NgModule} from '@angular/core';
|
||||
import {APP_INITIALIZER, inject, NgModule} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {PreloadAllModules, RouteReuseStrategy, RouterModule} from '@angular/router';
|
||||
@ -27,7 +27,9 @@ import {MAT_TOOLTIP_DEFAULT_OPTIONS, MatTooltipDefaultOptions} from '@angular/ma
|
||||
import {UpdateNotifierComponent} from '@common/shared/ui-components/overlay/update-notifier/update-notifier.component';
|
||||
import {ChooseColorModule} from '@common/shared/ui-components/directives/choose-color/choose-color.module';
|
||||
import {SpinnerComponent} from '@common/shared/ui-components/overlay/spinner/spinner.component';
|
||||
import {MatIconRegistry} from '@angular/material/icon';
|
||||
import {provideCharts, withDefaultRegisterables} from 'ng2-charts';
|
||||
import {PushPipe} from '@ngrx/component';
|
||||
|
||||
@NgModule({
|
||||
declarations : [AppComponent],
|
||||
@ -62,6 +64,7 @@ import {provideCharts, withDefaultRegisterables} from 'ng2-charts';
|
||||
UpdateNotifierComponent,
|
||||
ChooseColorModule,
|
||||
SpinnerComponent,
|
||||
PushPipe,
|
||||
],
|
||||
providers: [
|
||||
UserPreferences,
|
||||
@ -84,4 +87,10 @@ import {provideCharts, withDefaultRegisterables} from 'ng2-charts';
|
||||
bootstrap : [AppComponent],
|
||||
exports : []
|
||||
})
|
||||
export class AppModule {}
|
||||
export class AppModule {
|
||||
public matIconRegistry = inject(MatIconRegistry);
|
||||
|
||||
constructor() {
|
||||
this.matIconRegistry.registerFontClassAlias('al', 'al-icon');
|
||||
}
|
||||
}
|
||||
|
41
src/app/app.routes.ts
Executable file → Normal file
41
src/app/app.routes.ts
Executable file → Normal file
@ -13,8 +13,8 @@ export const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'projects',
|
||||
loadChildren: () => import('./features/projects/projects.module').then(m => m.ProjectsModule),
|
||||
data: {search: true},
|
||||
loadChildren: () => import('./features/projects/projects.module').then(m => m.ProjectsModule),
|
||||
},
|
||||
{path: 'login', loadChildren: () => import('./features/login/login.module').then(m => m.LoginModule)},
|
||||
{
|
||||
@ -22,7 +22,6 @@ export const routes: Routes = [
|
||||
loadChildren: () => import('./features/settings/settings.module').then(m => m.SettingsModule),
|
||||
data: {search: false, workspaceNeutral: false, },
|
||||
},
|
||||
|
||||
{
|
||||
path: 'projects',
|
||||
data: {search: true},
|
||||
@ -33,15 +32,15 @@ export const routes: Routes = [
|
||||
data: {search: true},
|
||||
children: [
|
||||
{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),
|
||||
canDeactivate: [resetContextMenuGuard]
|
||||
},
|
||||
{path: 'projects', loadChildren: () => import('./features/projects/projects.module').then(m => m.ProjectsModule)},
|
||||
{path: 'experiments', redirectTo: 'tasks'},
|
||||
{
|
||||
path: 'experiments',
|
||||
path: 'tasks',
|
||||
loadChildren: () => import('./features/experiments/experiments.module').then(m => m.ExperimentsModule),
|
||||
canDeactivate: [resetContextMenuGuard]
|
||||
},
|
||||
@ -50,10 +49,12 @@ export const routes: Routes = [
|
||||
loadChildren: () => import('./webapp-common/models/models.module').then(m => m.ModelsModule),
|
||||
canDeactivate: [resetContextMenuGuard]
|
||||
},
|
||||
{path: 'compare-experiments', redirectTo: 'compare-tasks'},
|
||||
{
|
||||
path: 'compare-experiments',
|
||||
loadChildren: () => import('./webapp-common/experiments-compare/experiments-compare.module').then(m => m.ExperimentsCompareModule),
|
||||
path: 'compare-tasks',
|
||||
data: {entityType: EntityTypeEnum.experiment},
|
||||
loadChildren: () =>
|
||||
import('./webapp-common/experiments-compare/experiments-compare.module').then(m => m.ExperimentsCompareModule)
|
||||
},
|
||||
{
|
||||
path: 'compare-models',
|
||||
@ -76,16 +77,27 @@ export const routes: Routes = [
|
||||
{
|
||||
path: ':projectId',
|
||||
children: [
|
||||
{path: 'pipelines', loadChildren: () => import('@common/pipelines/pipelines.module').then(m => m.PipelinesModule)},
|
||||
{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)
|
||||
path: 'pipelines',
|
||||
loadChildren: () =>
|
||||
import('@common/pipelines/pipelines.module').then(m => m.PipelinesModule)},
|
||||
{
|
||||
path: 'projects',
|
||||
loadComponent: () =>
|
||||
import('@common/pipelines/nested-pipeline-page/nested-pipeline-page.component').then(m => m.NestedPipelinePageComponent)
|
||||
},
|
||||
{path: 'experiments', redirectTo: 'tasks'},
|
||||
{
|
||||
path: 'compare-experiments',
|
||||
path: 'tasks',
|
||||
loadChildren: () =>
|
||||
import('@common/pipelines-controller/pipelines-controller.module').then(m => m.PipelinesControllerModule)
|
||||
},
|
||||
{path: 'compare-experiments', redirectTo: 'compare-tasks'},
|
||||
{
|
||||
path: 'compare-tasks',
|
||||
data: {entityType: EntityTypeEnum.controller},
|
||||
loadChildren: () => import('./webapp-common/experiments-compare/experiments-compare.module').then(m => m.ExperimentsCompareModule)
|
||||
loadChildren: () =>
|
||||
import('./webapp-common/experiments-compare/experiments-compare.module').then(m => m.ExperimentsCompareModule)
|
||||
},
|
||||
]
|
||||
},
|
||||
@ -106,6 +118,11 @@ export const routes: Routes = [
|
||||
loadChildren: () => import('./webapp-common/serving/serving.module').then(m => m.ServingModule),
|
||||
canDeactivate: [resetContextMenuGuard]
|
||||
},
|
||||
{
|
||||
path: 'enterprise',
|
||||
loadChildren: () => import('@common/enterprise-visibility/enterprise.routes').then(r => r.routes),
|
||||
canDeactivate: [resetContextMenuGuard],
|
||||
},
|
||||
{path: '404', loadChildren: () => import('./features/not-found/not-found.module').then(m => m.NotFoundModule)},
|
||||
{path: '**', loadChildren: () => import('./features/not-found/not-found.module').then(m => m.NotFoundModule)},
|
||||
|
||||
|
@ -2,6 +2,9 @@ import { StoreDevtoolsModule } from '@ngrx/store-devtools';
|
||||
|
||||
export const extCoreModules = [
|
||||
StoreDevtoolsModule.instrument({
|
||||
maxAge: 50
|
||||
, connectInZone: true})
|
||||
maxAge: 100,
|
||||
trace: true,
|
||||
traceLimit: 50,
|
||||
connectInZone: true
|
||||
})
|
||||
];
|
||||
|
0
src/app/business-logic/api-services/api-requests.service.ts
Executable file → Normal file
0
src/app/business-logic/api-services/api-requests.service.ts
Executable file → Normal file
103
src/app/business-logic/api-services/storage.service.ts
Normal file
103
src/app/business-logic/api-services/storage.service.ts
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* storage
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/member-ordering */
|
||||
|
||||
import {HTTP} from '~/app.constants';
|
||||
import {SmApiRequestsService} from './api-requests.service';
|
||||
|
||||
import { Inject, Injectable, Optional } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams,
|
||||
HttpResponse, HttpEvent } from '@angular/common/http';
|
||||
import { CustomHttpUrlEncodingCodec } from '../encoder';
|
||||
import { ApiOptions } from './api';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { StorageGetSettingsResponse } from '../model/storage/storageGetSettingsResponse';
|
||||
import { StorageResetSettingsRequest } from '../model/storage/storageResetSettingsRequest';
|
||||
import { StorageResetSettingsResponse } from '../model/storage/storageResetSettingsResponse';
|
||||
import { StorageSetSettingsRequest } from '../model/storage/storageSetSettingsRequest';
|
||||
import { StorageSetSettingsResponse } from '../model/storage/storageSetSettingsResponse';
|
||||
|
||||
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
||||
import { Configuration } from '../configuration';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class ApiStorageService {
|
||||
|
||||
protected basePath = HTTP.API_BASE_URL;
|
||||
public defaultHeaders = new HttpHeaders({'Accept': 'application/json'});
|
||||
public configuration = new Configuration();
|
||||
|
||||
constructor(protected apiRequest: SmApiRequestsService, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
|
||||
if (basePath) {
|
||||
this.basePath = basePath;
|
||||
}
|
||||
if (configuration) {
|
||||
this.configuration = configuration;
|
||||
this.basePath = basePath || configuration.basePath || this.basePath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal. Get storage settings
|
||||
* @param request request body
|
||||
* @param options flags and headers to use in webapp
|
||||
*/
|
||||
public storageGetSettings(request: object, options?: ApiOptions): Observable<any> {
|
||||
return this.apiRequest.post<StorageGetSettingsResponse>(`${this.basePath}/storage.get_settings`,
|
||||
request,
|
||||
{
|
||||
headers: this.defaultHeaders,
|
||||
withCredentials: this.configuration.withCredentials
|
||||
},
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal. Reset selected storage settings
|
||||
* @param request request body
|
||||
* @param options flags and headers to use in webapp
|
||||
*/
|
||||
public storageResetSettings(request: StorageResetSettingsRequest, options?: ApiOptions): Observable<any> {
|
||||
return this.apiRequest.post<StorageResetSettingsResponse>(`${this.basePath}/storage.reset_settings`,
|
||||
request,
|
||||
{
|
||||
headers: this.defaultHeaders,
|
||||
withCredentials: this.configuration.withCredentials
|
||||
},
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal. Set Storage settings
|
||||
* @param request request body
|
||||
* @param options flags and headers to use in webapp
|
||||
*/
|
||||
public storageSetSettings(request: StorageSetSettingsRequest, options?: ApiOptions): Observable<any> {
|
||||
return this.apiRequest.post<StorageSetSettingsResponse>(`${this.basePath}/storage.set_settings`,
|
||||
request,
|
||||
{
|
||||
headers: this.defaultHeaders,
|
||||
withCredentials: this.configuration.withCredentials
|
||||
},
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
}
|
4
src/app/business-logic/business-logic.module.ts
Executable file → Normal file
4
src/app/business-logic/business-logic.module.ts
Executable file → Normal file
@ -18,6 +18,7 @@ import {ApiLoginService} from './api-services/login.service';
|
||||
import {ApiPipelinesService} from '~/business-logic/api-services/pipelines.service';
|
||||
import {ApiReportsService} from '~/business-logic/api-services/reports.service';
|
||||
import {ApiServingService} from '~/business-logic/api-services/serving.service';
|
||||
import {ApiStorageService} from '~/business-logic/api-services/storage.service';
|
||||
|
||||
@NgModule({
|
||||
imports : [CommonModule, HttpClientModule],
|
||||
@ -40,7 +41,8 @@ import {ApiServingService} from '~/business-logic/api-services/serving.service';
|
||||
ApiLoginService,
|
||||
ApiPipelinesService,
|
||||
ApiReportsService,
|
||||
ApiServingService
|
||||
ApiServingService,
|
||||
ApiStorageService
|
||||
]
|
||||
})
|
||||
export class BusinessLogicModule {
|
||||
|
0
src/app/business-logic/configuration.ts
Executable file → Normal file
0
src/app/business-logic/configuration.ts
Executable file → Normal file
0
src/app/business-logic/constants.ts
Executable file → Normal file
0
src/app/business-logic/constants.ts
Executable file → Normal file
0
src/app/business-logic/encoder.ts
Executable file → Normal file
0
src/app/business-logic/encoder.ts
Executable file → Normal file
0
src/app/business-logic/model/al-task.ts
Executable file → Normal file
0
src/app/business-logic/model/al-task.ts
Executable file → Normal file
0
src/app/business-logic/model/api-request.ts
Executable file → Normal file
0
src/app/business-logic/model/api-request.ts
Executable file → Normal file
@ -52,4 +52,5 @@ export interface Queue {
|
||||
* Queue metadata
|
||||
*/
|
||||
metadata?: Array<MetadataItem>;
|
||||
display_name: string;
|
||||
}
|
||||
|
@ -25,4 +25,5 @@ export interface QueuesCreateRequest {
|
||||
* System tags list. This field is reserved for system use, please don\'t use it.
|
||||
*/
|
||||
system_tags?: Array<string>;
|
||||
display_name?: string
|
||||
}
|
||||
|
@ -29,4 +29,5 @@ export interface QueuesUpdateRequest {
|
||||
* System tags list. This field is reserved for system use, please don\'t use it.
|
||||
*/
|
||||
system_tags?: Array<string>;
|
||||
display_name: string;
|
||||
}
|
||||
|
44
src/app/business-logic/model/storage/aws.ts
Normal file
44
src/app/business-logic/model/storage/aws.ts
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 { AwsBucket } from '././awsBucket';
|
||||
|
||||
|
||||
/**
|
||||
* AWS S3 storage settings
|
||||
*/
|
||||
export interface Aws {
|
||||
/**
|
||||
* Access key
|
||||
*/
|
||||
key?: string;
|
||||
/**
|
||||
* Secret key
|
||||
*/
|
||||
secret?: string;
|
||||
/**
|
||||
* AWS region
|
||||
*/
|
||||
region?: string;
|
||||
/**
|
||||
* Access token
|
||||
*/
|
||||
token?: string;
|
||||
/**
|
||||
* If set then use host credentials
|
||||
*/
|
||||
use_credentials_chain?: boolean;
|
||||
/**
|
||||
* Credential settings per bucket
|
||||
*/
|
||||
buckets?: Array<AwsBucket>;
|
||||
}
|
67
src/app/business-logic/model/storage/awsBucket.ts
Normal file
67
src/app/business-logic/model/storage/awsBucket.ts
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* storage
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Settings per S3 bucket
|
||||
*/
|
||||
export interface AwsBucket {
|
||||
/**
|
||||
* The name of the bucket
|
||||
*/
|
||||
bucket?: string;
|
||||
/**
|
||||
* The path to match
|
||||
*/
|
||||
subdir?: string;
|
||||
/**
|
||||
* Host address (for minio servers)
|
||||
*/
|
||||
host?: string;
|
||||
/**
|
||||
* Access key
|
||||
*/
|
||||
key?: string;
|
||||
/**
|
||||
* Secret key
|
||||
*/
|
||||
secret?: string;
|
||||
/**
|
||||
* Access token
|
||||
*/
|
||||
token?: string;
|
||||
/**
|
||||
* Multipart upload
|
||||
*/
|
||||
multipart?: boolean;
|
||||
/**
|
||||
* ACL
|
||||
*/
|
||||
acl?: string;
|
||||
/**
|
||||
* Use SSL connection
|
||||
*/
|
||||
secure?: boolean;
|
||||
/**
|
||||
* AWS Region
|
||||
*/
|
||||
region?: string;
|
||||
/**
|
||||
* Verify server certificate
|
||||
*/
|
||||
verify?: boolean;
|
||||
/**
|
||||
* Use host configured credentials
|
||||
*/
|
||||
use_credentials_chain?: boolean;
|
||||
}
|
24
src/app/business-logic/model/storage/azure.ts
Normal file
24
src/app/business-logic/model/storage/azure.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 { AzureContainer } from '././azureContainer';
|
||||
|
||||
|
||||
/**
|
||||
* Azure storage settings
|
||||
*/
|
||||
export interface Azure {
|
||||
/**
|
||||
* Credentials per container
|
||||
*/
|
||||
containers?: Array<AzureContainer>;
|
||||
}
|
31
src/app/business-logic/model/storage/azureContainer.ts
Normal file
31
src/app/business-logic/model/storage/azureContainer.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* storage
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Azure container settings
|
||||
*/
|
||||
export interface AzureContainer {
|
||||
/**
|
||||
* Account name
|
||||
*/
|
||||
account_name?: string;
|
||||
/**
|
||||
* Account key
|
||||
*/
|
||||
account_key?: string;
|
||||
/**
|
||||
* The name of the container
|
||||
*/
|
||||
container_name?: string;
|
||||
}
|
24
src/app/business-logic/model/storage/credentials.ts
Normal file
24
src/app/business-logic/model/storage/credentials.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 Credentials {
|
||||
/**
|
||||
* Credentials access key
|
||||
*/
|
||||
access_key?: string;
|
||||
/**
|
||||
* Credentials secret key
|
||||
*/
|
||||
secret_key?: string;
|
||||
}
|
32
src/app/business-logic/model/storage/google.ts
Normal file
32
src/app/business-logic/model/storage/google.ts
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 { GoogleBucket } from '././googleBucket';
|
||||
|
||||
|
||||
/**
|
||||
* Google storage settings
|
||||
*/
|
||||
export interface Google {
|
||||
/**
|
||||
* Project name
|
||||
*/
|
||||
project?: string;
|
||||
/**
|
||||
* The contents of the credentials json file
|
||||
*/
|
||||
credentials_json?: string;
|
||||
/**
|
||||
* Credentials per bucket
|
||||
*/
|
||||
buckets?: Array<GoogleBucket>;
|
||||
}
|
35
src/app/business-logic/model/storage/googleBucket.ts
Normal file
35
src/app/business-logic/model/storage/googleBucket.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.30
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Settings per Google storage bucket
|
||||
*/
|
||||
export interface GoogleBucket {
|
||||
/**
|
||||
* The name of the bucket
|
||||
*/
|
||||
bucket?: string;
|
||||
/**
|
||||
* The name of the project
|
||||
*/
|
||||
project?: string;
|
||||
/**
|
||||
* The path to match
|
||||
*/
|
||||
subdir?: string;
|
||||
/**
|
||||
* The contents of the credentials json file
|
||||
*/
|
||||
credentials_json?: string;
|
||||
}
|
8
src/app/business-logic/model/storage/models.ts
Normal file
8
src/app/business-logic/model/storage/models.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export * from './credentials';
|
||||
export * from './storage';
|
||||
export * from './storageCreateRequest';
|
||||
export * from './storageCreateResponse';
|
||||
export * from './storageDeleteRequest';
|
||||
export * from './storageDeleteResponse';
|
||||
export * from './storageGetAllRequest';
|
||||
export * from './storageGetAllResponse';
|
38
src/app/business-logic/model/storage/storage.ts
Normal file
38
src/app/business-logic/model/storage/storage.ts
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 { Credentials } from './credentials';
|
||||
|
||||
|
||||
export interface Storage {
|
||||
/**
|
||||
* Entry ID
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* Entry name
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Company ID
|
||||
*/
|
||||
company?: string;
|
||||
/**
|
||||
* Entry creation time
|
||||
*/
|
||||
created?: Date;
|
||||
/**
|
||||
* Storage URI
|
||||
*/
|
||||
uri?: string;
|
||||
credentials?: Credentials;
|
||||
}
|
30
src/app/business-logic/model/storage/storageCreateRequest.ts
Normal file
30
src/app/business-logic/model/storage/storageCreateRequest.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 { Credentials } from './credentials';
|
||||
|
||||
|
||||
export interface StorageCreateRequest {
|
||||
/**
|
||||
* Storage name
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Storage URI
|
||||
*/
|
||||
uri: string;
|
||||
credentials?: Credentials;
|
||||
/**
|
||||
* Company under which to add this storage. Only valid for users with the root or system role, otherwise the calling user's company will be used.
|
||||
*/
|
||||
company?: string;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 StorageCreateResponse {
|
||||
/**
|
||||
* New storage ID
|
||||
*/
|
||||
id?: string;
|
||||
}
|
20
src/app/business-logic/model/storage/storageDeleteRequest.ts
Normal file
20
src/app/business-logic/model/storage/storageDeleteRequest.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 StorageDeleteRequest {
|
||||
/**
|
||||
* Storage entry ID
|
||||
*/
|
||||
storage: string;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 StorageDeleteResponse {
|
||||
/**
|
||||
* Number of storage entries deleted (0 or 1)
|
||||
*/
|
||||
deleted?: number;
|
||||
}
|
40
src/app/business-logic/model/storage/storageGetAllRequest.ts
Normal file
40
src/app/business-logic/model/storage/storageGetAllRequest.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 StorageGetAllRequest {
|
||||
/**
|
||||
* Get only storage entries whose name matches this pattern (python regular expression syntax)
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* List of Storage IDs used to filter results
|
||||
*/
|
||||
id?: Array<string>;
|
||||
/**
|
||||
* Page number, returns a specific page out of the result list of results.
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* Page size, specifies the number of results returned in each page (last page may contain fewer results)
|
||||
*/
|
||||
page_size?: number;
|
||||
/**
|
||||
* 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>;
|
||||
/**
|
||||
* List of document 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>;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* storage
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* OpenAPI spec version: 2.12
|
||||
*
|
||||
*
|
||||
* 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 { Storage } from './storage';
|
||||
|
||||
|
||||
export interface StorageGetAllResponse {
|
||||
/**
|
||||
* Storage entries list
|
||||
*/
|
||||
results?: Array<Storage>;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 { Google } from '././google';
|
||||
import { Azure } from '././azure';
|
||||
import { Aws } from '././aws';
|
||||
|
||||
|
||||
export interface StorageGetSettingsResponse {
|
||||
/**
|
||||
* Settings last update time (UTC)
|
||||
*/
|
||||
last_update?: string;
|
||||
aws?: Aws;
|
||||
google?: Google;
|
||||
azure?: Azure;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 StorageResetSettingsRequest {
|
||||
/**
|
||||
* The names of the settings to delete
|
||||
*/
|
||||
keys?: Array<StorageResetSettingsRequest.KeysEnum>;
|
||||
}
|
||||
export namespace StorageResetSettingsRequest {
|
||||
export type KeysEnum = 'azure' | 'aws' | 'google';
|
||||
export const KeysEnum = {
|
||||
Azure: 'azure' as KeysEnum,
|
||||
Aws: 'aws' as KeysEnum,
|
||||
Google: 'google' as KeysEnum
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 StorageResetSettingsResponse {
|
||||
/**
|
||||
* Number of settings documents updated (0 or 1)
|
||||
*/
|
||||
updated?: number;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 { Google } from '././google';
|
||||
import { Azure } from '././azure';
|
||||
import { Aws } from '././aws';
|
||||
|
||||
|
||||
export interface StorageSetSettingsRequest {
|
||||
aws?: Aws;
|
||||
google?: Google;
|
||||
azure?: Azure;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* storage
|
||||
* 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 StorageSetSettingsResponse {
|
||||
/**
|
||||
* Number of settings documents updated (0 or 1)
|
||||
*/
|
||||
updated?: number;
|
||||
}
|
0
src/app/business-logic/services/models.service.ts
Executable file → Normal file
0
src/app/business-logic/services/models.service.ts
Executable file → Normal file
0
src/app/business-logic/services/tasks.service.ts
Executable file → Normal file
0
src/app/business-logic/services/tasks.service.ts
Executable file → Normal file
0
src/app/business-logic/variables.ts
Executable file → Normal file
0
src/app/business-logic/variables.ts
Executable file → Normal file
@ -1,12 +1,14 @@
|
||||
import {LoginService} from '~/shared/services/login.service';
|
||||
import {ConfigurationService} from '@common/shared/services/configuration.service';
|
||||
import {switchMap} from 'rxjs';
|
||||
import {combineLatest} from 'rxjs';
|
||||
|
||||
export const loadUserAndPreferences = (
|
||||
loginService: LoginService,
|
||||
confService: ConfigurationService,
|
||||
): () => Promise<any> => (): Promise<any> => new Promise((resolve) => {
|
||||
confService.initConfigurationService()
|
||||
.pipe(switchMap(() => loginService.initCredentials()))
|
||||
combineLatest([
|
||||
confService.initConfigurationService(),
|
||||
loginService.initCredentials()
|
||||
])
|
||||
.subscribe(() => loginService.loginFlow(resolve));
|
||||
});
|
||||
|
2
src/app/core/core.module.ts
Executable file → Normal file
2
src/app/core/core.module.ts
Executable file → Normal file
@ -96,7 +96,7 @@ const userPrefMetaFactory = (userPreferences: UserPreferences): MetaReducer[] =>
|
||||
(reducer: ActionReducer<any>) =>
|
||||
createUserPrefReducer('rootProjects', ['tagsColors', 'graphVariant', 'showHidden', 'hideExamples', 'defaultNestedModeForFeature', 'blockUserScript'], [ROOT_PROJECTS_PREFIX], userPreferences, reducer),
|
||||
(reducer: ActionReducer<any>) =>
|
||||
createUserPrefReducer('views', ['autoRefresh', 'neverShowPopupAgain', 'redactedArguments', 'hideRedactedArguments'], [VIEW_PREFIX], userPreferences, reducer),
|
||||
createUserPrefReducer('views', ['autoRefresh', 'neverShowPopupAgain', 'redactedArguments', 'hideRedactedArguments', 'theme', 'hideEnterpriseFeatures'], [VIEW_PREFIX], userPreferences, reducer),
|
||||
localStorageReducer,
|
||||
(reducer: ActionReducer<any>) =>
|
||||
createUserPrefReducer('projects', projectSyncedKeys, [PROJECTS_PREFIX], userPreferences, reducer),
|
||||
|
0
src/app/core/effects/users.effects.ts
Executable file → Normal file
0
src/app/core/effects/users.effects.ts
Executable file → Normal file
0
src/app/core/models/actions.ts
Executable file → Normal file
0
src/app/core/models/actions.ts
Executable file → Normal file
0
src/app/core/models/model-data.ts
Executable file → Normal file
0
src/app/core/models/model-data.ts
Executable file → Normal file
@ -1,7 +1,7 @@
|
||||
import {createSelector} from '@ngrx/store';
|
||||
import {ActionCreator, createReducer, createSelector, on, ReducerTypes} from '@ngrx/store';
|
||||
import {
|
||||
initViewState as commonInitState,
|
||||
viewReducer as commonViewReducer,
|
||||
viewReducers,
|
||||
ViewState as CommonViewState
|
||||
} from '@common/core/reducers/view.reducer';
|
||||
import {dismissSurvey} from '../actions/layout.actions';
|
||||
@ -16,7 +16,7 @@ interface ViewState extends CommonViewState {
|
||||
const initViewState: ViewState = {
|
||||
...commonInitState,
|
||||
availableUpdates : null,
|
||||
showSurvey: true
|
||||
showSurvey: true,
|
||||
};
|
||||
|
||||
export const views = state => state.views as ViewState;
|
||||
@ -27,14 +27,11 @@ export const selectActiveWorkspaceReady = createSelector(views, (state) => true)
|
||||
export const selectProjectType = createSelector(selectRouterConfig,
|
||||
config => (config && routeConfToProjectType(config)) ?? 'datasets');
|
||||
|
||||
export function viewReducer(viewState: ViewState = initViewState, action) {
|
||||
|
||||
switch (action.type) {
|
||||
case setServerUpdatesAvailable.type:
|
||||
return {...viewState, availableUpdates: (action as ReturnType<typeof setServerUpdatesAvailable>).availableUpdates};
|
||||
case dismissSurvey.type:
|
||||
return {...viewState, showSurvey: false};
|
||||
default:
|
||||
return commonViewReducer(viewState, action);
|
||||
}
|
||||
}
|
||||
export const viewReducer = createReducer(
|
||||
initViewState,
|
||||
on(setServerUpdatesAvailable, (state, action): ViewState =>
|
||||
({...state, availableUpdates: action.availableUpdates})),
|
||||
on(dismissSurvey, (state): ViewState =>
|
||||
({...state, showSurvey: false})),
|
||||
...viewReducers as unknown as ReducerTypes<ViewState, ActionCreator[]>[]
|
||||
);
|
||||
|
@ -8,7 +8,7 @@
|
||||
(openDatasetSelected)="openDatasetCardClicked($event)"
|
||||
(loadMoreClicked)="loadMore()"
|
||||
[projectsList]="projectsResults$ | async"
|
||||
[experimentsList]="experimentsResults$ | async"
|
||||
[tasksList]="experimentsResults$ | async"
|
||||
[modelsList]="modelsResults$ | async"
|
||||
[datasetsList]="datasetsResults$ | async"
|
||||
[pipelinesList]="pipelinesResults$ | async"
|
||||
|
@ -1,30 +1,28 @@
|
||||
<div class="search-container">
|
||||
<div class="d-flex-center tabs">
|
||||
<div class="ps-3 py-3">
|
||||
@for (searchTab of activeLinksList; track searchTab.name) {
|
||||
<span
|
||||
class="pointer category-link"
|
||||
[class.active]="activeLink === searchTab.name"
|
||||
[tabindex]="$count"
|
||||
(click)="activeLinkChanged.emit(searchTab.name)"
|
||||
(keyup)="activeLinkChanged.emit(searchTab.name)"
|
||||
>{{searchTab.label}} ({{resultsCount?.[searchTab.name]}})</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-100">
|
||||
<mat-tab-group
|
||||
[selectedIndex]="activeIndex()"
|
||||
(selectedTabChange)="activeLinkChanged.emit(activeLinksList[$event.index].name)"
|
||||
[mat-stretch-tabs]="false" mat-align-tabs="center">
|
||||
@for (searchTab of activeLinksList; track searchTab.name) {
|
||||
<mat-tab
|
||||
[label]="searchTab.label + (resultsCount()?.[searchTab.name] !== null ? ' (' + resultsCount()?.[searchTab.name] + ')' : '')"
|
||||
class="tab-link"
|
||||
></mat-tab>
|
||||
}
|
||||
</mat-tab-group>
|
||||
<div class="page-container">
|
||||
<sm-virtual-grid
|
||||
[cardTemplate]="
|
||||
activeLink === searchPages.projects ? ProjectTemplate :
|
||||
activeLink === searchPages.experiments ? ExperimentTemplate :
|
||||
activeLink === searchPages.models ? ModelsTemplate :
|
||||
activeLink === searchPages.openDatasets ? openDatasetTemplate :
|
||||
activeLink === searchPages.pipelines ? PipelineTemplate :
|
||||
activeLink === searchPages.reports ? ReportsTemplate :
|
||||
activeLink() === searchPages.projects ? ProjectTemplate :
|
||||
activeLink() === searchPages.experiments ? ExperimentTemplate :
|
||||
activeLink() === searchPages.models ? ModelsTemplate :
|
||||
activeLink() === searchPages.openDatasets ? openDatasetTemplate :
|
||||
activeLink() === searchPages.pipelines ? PipelineTemplate :
|
||||
activeLink() === searchPages.reports ? ReportsTemplate :
|
||||
ProjectTemplate"
|
||||
[items]="getResults()"
|
||||
[cardHeight]="getCardHeight()"
|
||||
[showLoadMoreButton]="getResults().length < resultsCount?.[activeLink]"
|
||||
[showLoadMoreButton]="getResults().length < resultsCount()?.[activeLink()] && !loading()"
|
||||
(itemClicked)="projectClicked($event)"
|
||||
(loadMoreClicked)="loadMoreClicked.emit()"
|
||||
>
|
||||
@ -62,11 +60,11 @@
|
||||
</ng-template>
|
||||
|
||||
<ng-template #openDatasetTemplate let-dataset>
|
||||
<sm-simple-dataset-card
|
||||
<sm-open-dataset-card
|
||||
[hideMenu]="true"
|
||||
[project]="dataset"
|
||||
(projectCardClicked)="openDatasetClicked($event)"
|
||||
></sm-simple-dataset-card>
|
||||
></sm-open-dataset-card>
|
||||
</ng-template>
|
||||
<ng-template #ReportsTemplate let-report>
|
||||
<sm-report-card
|
||||
@ -75,5 +73,4 @@
|
||||
(cardClicked)="reportClicked($event)"
|
||||
></sm-report-card>
|
||||
</ng-template>
|
||||
|
||||
</div>
|
||||
|
@ -1,24 +1,8 @@
|
||||
@import "../../../../webapp-common/shared/ui-components/styles/variables";
|
||||
@import "../../../../webapp-common/shared/ui-components/styles/mixins/common";
|
||||
|
||||
.category-link{
|
||||
padding-right: 24px;
|
||||
color: $blue-300;
|
||||
&:hover {
|
||||
color: $blue-200;
|
||||
}
|
||||
&.active {
|
||||
color: $neon-yellow;
|
||||
}
|
||||
}
|
||||
|
||||
.search-container{
|
||||
height: calc(100% - 24px);
|
||||
.tabs {
|
||||
@include recent-title();
|
||||
}
|
||||
.mat-mdc-tab-group {
|
||||
--mat-tab-header-label-text-size: 14px;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
height: calc(100% - 35px);
|
||||
height: calc(100% - 67px);
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
import {Component, output, input, computed} from '@angular/core';
|
||||
import {Project} from '~/business-logic/model/projects/project';
|
||||
import {Task} from '~/business-logic/model/tasks/task';
|
||||
import {ITask} from '~/business-logic/model/al-task';
|
||||
@ -12,26 +12,31 @@ import {IReport} from '@common/reports/reports.consts';
|
||||
styleUrls: ['./search-results-page.component.scss']
|
||||
})
|
||||
export class SearchResultsPageComponent {
|
||||
public searchPages = activeSearchLink;
|
||||
public activeLinksList = activeLinksList;
|
||||
protected readonly searchPages = activeSearchLink;
|
||||
protected readonly activeLinksList = activeLinksList;
|
||||
|
||||
@Input() projectsList: Array<Project> = [];
|
||||
@Input() experimentsList: Array<Task> = [];
|
||||
@Input() modelsList: Array<Model> = [];
|
||||
@Input() pipelinesList: Array<Project> = [];
|
||||
@Input() datasetsList: Array<Project> = [];
|
||||
@Input() reportsList: Array<IReport> = [];
|
||||
@Input() activeLink: ActiveSearchLink;
|
||||
@Input() resultsCount: Map<ActiveSearchLink, number>;
|
||||
|
||||
@Output() projectSelected = new EventEmitter<Project>();
|
||||
@Output() activeLinkChanged = new EventEmitter<string>();
|
||||
@Output() experimentSelected = new EventEmitter<ITask>();
|
||||
@Output() modelSelected = new EventEmitter<Model>();
|
||||
@Output() pipelineSelected = new EventEmitter<Project>();
|
||||
@Output() reportSelected = new EventEmitter<IReport>();
|
||||
@Output() openDatasetSelected = new EventEmitter<Project>();
|
||||
@Output() loadMoreClicked = new EventEmitter();
|
||||
projectsList = input<Project[]>([]);
|
||||
datasetsList = input<Project[]>([]);
|
||||
tasksList = input<Task[]>([]);
|
||||
modelsList = input<Model[]>([]);
|
||||
pipelinesList = input<Project[]>([]);
|
||||
reportsList = input<IReport[]>([]);
|
||||
activeLink = input<ActiveSearchLink>();
|
||||
resultsCount = input<Map<ActiveSearchLink, number>>();
|
||||
|
||||
projectSelected = output<Project>();
|
||||
activeLinkChanged = output<string>();
|
||||
openDatasetSelected = output<Project>();
|
||||
experimentSelected = output<ITask>();
|
||||
modelSelected = output<Model>();
|
||||
reportSelected = output<IReport>();
|
||||
pipelineSelected = output<Project>();
|
||||
loadMoreClicked = output();
|
||||
|
||||
protected loading = computed<boolean>(() => [null, undefined].includes(this.resultsCount()?.[this.activeLink()]));
|
||||
protected getResults = computed(() => this[`${this.activeLink()}List`]());
|
||||
activeIndex = computed<number>(() => activeLinksList.findIndex(item => item.name === this.activeLink()));
|
||||
|
||||
public projectClicked(project: Project) {
|
||||
this.projectSelected.emit(project);
|
||||
@ -57,10 +62,9 @@ export class SearchResultsPageComponent {
|
||||
this.reportSelected.emit(report);
|
||||
}
|
||||
|
||||
getResults = () => this[`${this.activeLink}List`];
|
||||
|
||||
getCardHeight() {
|
||||
switch (this.activeLink) {
|
||||
switch (this.activeLink()) {
|
||||
case activeSearchLink.projects:
|
||||
return 246;
|
||||
case activeSearchLink.experiments:
|
||||
|
@ -4,7 +4,7 @@ import {CrumbTypeEnum} from '@common/layout/breadcrumbs/breadcrumbs.component';
|
||||
import {DashboardSearchComponent} from '~/features/dashboard-search/containers/dashboard-search/dashboard-search.component';
|
||||
|
||||
const staticBreadcrumb = [[{
|
||||
name: 'DASHBOARD',
|
||||
name: 'GLOBAL SEARCH',
|
||||
type: CrumbTypeEnum.Feature
|
||||
}]];
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
export type ActiveSearchLink = 'projects' | 'experiments' | 'models' | 'pipelines' | 'datasets';
|
||||
export type ActiveSearchLink = 'projects' | 'tasks' | 'models' | 'pipelines' | 'datasets';
|
||||
|
||||
export const activeSearchLink = {
|
||||
projects: 'projects' as ActiveSearchLink,
|
||||
experiments: 'experiments' as ActiveSearchLink,
|
||||
experiments: 'tasks' as ActiveSearchLink,
|
||||
models: 'models' as ActiveSearchLink,
|
||||
pipelines: 'pipelines' as ActiveSearchLink,
|
||||
openDatasets: 'datasets' as ActiveSearchLink,
|
||||
@ -19,7 +19,7 @@ export const activeLinksList = [
|
||||
name: activeSearchLink.openDatasets,
|
||||
},
|
||||
{
|
||||
label: 'EXPERIMENTS',
|
||||
label: 'TASKS',
|
||||
name: activeSearchLink.experiments,
|
||||
},
|
||||
{
|
||||
|
@ -18,23 +18,22 @@ export class DashboardSearchEffects {
|
||||
) {}
|
||||
|
||||
getResultsCount = createEffect(() => this.actions.pipe(
|
||||
ofType(getResultsCount),
|
||||
withLatestFrom(
|
||||
this.store.select(selectShowOnlyUserWork),
|
||||
this.store.select(selectCurrentUser),
|
||||
this.store.select(selectShowHidden),
|
||||
this.store.select(selectHideExamples),
|
||||
),
|
||||
switchMap(([action, userFocus, user, hidden, hideExamples]) => this.organizationApi.organizationGetEntitiesCount({
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
...(userFocus && {active_users: [user.id]}),
|
||||
...(hidden && {search_hidden: true}),
|
||||
...(hideExamples && {allow_public: false}),
|
||||
...getEntityStatQuery(action, hidden)
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
})),
|
||||
map(({tasks: experiments, ...rest}) =>
|
||||
setResultsCount({counts: {...rest, experiments}}))
|
||||
));
|
||||
|
||||
ofType(getResultsCount),
|
||||
withLatestFrom(
|
||||
this.store.select(selectShowOnlyUserWork),
|
||||
this.store.select(selectCurrentUser),
|
||||
this.store.select(selectShowHidden),
|
||||
this.store.select(selectHideExamples),
|
||||
),
|
||||
switchMap(([action, userFocus, user, hidden, hideExamples]) => this.organizationApi.organizationGetEntitiesCount({
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
...(userFocus && {active_users: [user.id]}),
|
||||
...(hidden && {search_hidden: true}),
|
||||
...(hideExamples && {allow_public: false}),
|
||||
...getEntityStatQuery(action, hidden)
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
})),
|
||||
map(res => setResultsCount({counts: res}))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import {DashboardSearchComponent} from '~/features/dashboard-search/containers/d
|
||||
import {DatasetsSharedModule} from '~/features/datasets/shared/datasets-shared.module';
|
||||
import {ReportCardComponent} from '@common/reports/report-card/report-card.component';
|
||||
import {DashboardSearchRoutingModule} from '~/features/dashboard-search/dashboard-search-routing.module';
|
||||
import {MatTab, MatTabGroup} from '@angular/material/tabs';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -31,6 +32,8 @@ import {DashboardSearchRoutingModule} from '~/features/dashboard-search/dashboar
|
||||
PipelineCardComponent,
|
||||
DatasetsSharedModule,
|
||||
ReportCardComponent,
|
||||
MatTabGroup,
|
||||
MatTab,
|
||||
],
|
||||
declarations:[
|
||||
SearchResultsPageComponent, DashboardSearchComponent
|
||||
|
9
src/app/features/dashboard/dashboard-routing.module.ts
Executable file → Normal file
9
src/app/features/dashboard/dashboard-routing.module.ts
Executable file → Normal file
@ -4,18 +4,19 @@ import {DashboardComponent} from './dashboard.component';
|
||||
import {CrumbTypeEnum} from '@common/layout/breadcrumbs/breadcrumbs.component';
|
||||
|
||||
const staticBreadcrumb = [[{
|
||||
name: 'DASHBOARD',
|
||||
type: CrumbTypeEnum.Feature
|
||||
name: 'PROJECTS DASHBOARD',
|
||||
type: CrumbTypeEnum.Feature
|
||||
}]];
|
||||
|
||||
export const routes: Routes = [
|
||||
{path: '', component: DashboardComponent, data: {staticBreadcrumb}},
|
||||
{
|
||||
path: 'search',
|
||||
loadChildren: () => import('~/features/dashboard-search/dashboard-search.module').then(m => m.DashboardSearchModule),
|
||||
data: {staticBreadcrumb}}
|
||||
loadChildren: () => import('~/features/dashboard-search/dashboard-search.module').then(m => m.DashboardSearchModule)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(routes)
|
||||
|
10
src/app/features/dashboard/dashboard.component.html
Executable file → Normal file
10
src/app/features/dashboard/dashboard.component.html
Executable file → Normal file
@ -1,16 +1,16 @@
|
||||
<div class="dashboard-body">
|
||||
<div class="recent">
|
||||
<sm-dashboard-projects (width)="setWidth($event)"></sm-dashboard-projects>
|
||||
<sm-dashboard-reports></sm-dashboard-reports>
|
||||
<sm-dashboard-experiments
|
||||
[style.width]="width && width > 900 ? width + 'px' : '100%'"
|
||||
[recentTasks]="recentTasks$| async"
|
||||
>
|
||||
<div header-buttons>
|
||||
<button
|
||||
*smCheckPermission="true"
|
||||
class="btn btn-cml-primary d-flex align-items-center"
|
||||
(click)="redirectToWorkers()"
|
||||
><i class="al-icon al-ico-queues al-color light-grey-blue sm me-2"></i>MANAGE WORKERS AND QUEUES</button>
|
||||
<button mat-flat-button data-id="Manage Workers And Queues" (click)="redirectToWorkers()">
|
||||
<mat-icon fontSet="al" fontIcon="al-ico-queues"></mat-icon>
|
||||
MANAGE WORKERS AND QUEUES
|
||||
</button>
|
||||
</div>
|
||||
</sm-dashboard-experiments>
|
||||
</div>
|
||||
|
11
src/app/features/dashboard/dashboard.component.scss
Executable file → Normal file
11
src/app/features/dashboard/dashboard.component.scss
Executable file → Normal file
@ -1,16 +1,14 @@
|
||||
@import "../../webapp-common/shared/ui-components/styles/mixins/common";
|
||||
@import "../../webapp-common/shared/ui-components/styles/variables";
|
||||
@import "mixins/common";
|
||||
@import "variables";
|
||||
|
||||
:host {
|
||||
.dashboard-body {
|
||||
height: 100%;
|
||||
padding: 0 24px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.recent {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
max-width: 2400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@ -28,8 +26,9 @@
|
||||
|
||||
sm-dashboard-experiments {
|
||||
display: block;
|
||||
margin: 24px auto 0;
|
||||
height: calc(100% - 356px);
|
||||
padding-top: 24px;
|
||||
margin: 0 auto;
|
||||
height: calc(100% - 620px);
|
||||
}
|
||||
|
||||
.dashboard-search {
|
||||
|
3
src/app/features/dashboard/dashboard.component.ts
Executable file → Normal file
3
src/app/features/dashboard/dashboard.component.ts
Executable file → Normal file
@ -5,7 +5,7 @@ import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {selectCurrentUser, selectShowOnlyUserWork} from '@common/core/reducers/users-reducer';
|
||||
import {debounceTime, filter, take} from 'rxjs/operators';
|
||||
import {setDeep} from '@common/core/actions/projects.actions';
|
||||
import {getRecentProjects, getRecentExperiments} from '@common/dashboard/common-dashboard.actions';
|
||||
import {getRecentProjects, getRecentExperiments, getRecentReports} from '@common/dashboard/common-dashboard.actions';
|
||||
import {selectFirstLogin} from '@common/core/reducers/view.reducer';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {WelcomeMessageComponent} from '@common/layout/welcome-message/welcome-message.component';
|
||||
@ -52,6 +52,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
||||
.subscribe(() => {
|
||||
this.store.dispatch(getRecentProjects());
|
||||
this.store.dispatch(getRecentExperiments());
|
||||
this.store.dispatch(getRecentReports());
|
||||
});
|
||||
|
||||
this.welcomeSub = this.store.select(selectFirstLogin)
|
||||
|
13
src/app/features/dashboard/dashboard.module.ts
Executable file → Normal file
13
src/app/features/dashboard/dashboard.module.ts
Executable file → Normal file
@ -4,7 +4,6 @@ import {DashboardComponent} from './dashboard.component';
|
||||
import {ExperimentSharedModule} from '../experiments/shared/experiment-shared.module';
|
||||
import {DashboardRoutingModule} from './dashboard-routing.module';
|
||||
import {StoreModule} from '@ngrx/store';
|
||||
import {GettingStartedCardComponent} from './dumb/getting-started-card/getting-started-card.component';
|
||||
import {CommonDashboardModule} from '@common/dashboard/common-dashboard.module';
|
||||
import {commonDashboardReducer} from '@common/dashboard/common-dashboard.reducer';
|
||||
import {SharedModule} from '~/shared/shared.module';
|
||||
@ -14,13 +13,15 @@ import {DatasetsSharedModule} from '~/features/datasets/shared/datasets-shared.m
|
||||
import {ScrollingModule} from '@angular/cdk/scrolling';
|
||||
import {CheckPermissionDirective} from '~/shared/directives/check-permission.directive';
|
||||
import {PlusCardComponent} from '@common/shared/ui-components/panel/plus-card/plus-card.component';
|
||||
import {NeonButtonComponent} from '@common/shared/ui-components/buttons/neon-button/neon-button.component';
|
||||
import {OverflowsDirective} from '@common/shared/ui-components/directives/overflows.directive';
|
||||
import {PipelineCardComponent} from '@common/pipelines/pipeline-card/pipeline-card.component';
|
||||
import {ModelCardComponent} from '@common/shared/ui-components/panel/model-card/model-card.component';
|
||||
import {ExperimentCardComponent} from '@common/shared/ui-components/panel/experiment-card/experiment-card.component';
|
||||
import {ProjectCardComponent} from '@common/shared/ui-components/panel/project-card/project-card.component';
|
||||
import {VirtualGridComponent} from '@common/shared/components/virtual-grid/virtual-grid.component';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {DashboardReportsComponent} from '@common/dashboard/containers/dashboard-reports/dashboard-reports.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -36,15 +37,17 @@ import {VirtualGridComponent} from '@common/shared/components/virtual-grid/virtu
|
||||
ScrollingModule,
|
||||
CheckPermissionDirective,
|
||||
PlusCardComponent,
|
||||
NeonButtonComponent,
|
||||
OverflowsDirective,
|
||||
PipelineCardComponent,
|
||||
ModelCardComponent,
|
||||
ExperimentCardComponent,
|
||||
ProjectCardComponent,
|
||||
VirtualGridComponent
|
||||
VirtualGridComponent,
|
||||
MatIcon,
|
||||
MatButton,
|
||||
DashboardReportsComponent
|
||||
],
|
||||
declarations : [DashboardComponent, GettingStartedCardComponent]
|
||||
declarations : [DashboardComponent]
|
||||
})
|
||||
export class DashboardModule {
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
<div class="no-data-box">
|
||||
<img [src]="'../../../assets/icons/empty-data/'+ icon"
|
||||
class="main-image">
|
||||
<div class="empty-label">{{title}}</div>
|
||||
<div class="empty-sub-label line-breaker">{{subtitle}}
|
||||
</div>
|
||||
<sm-neon-button [label]="buttonLabel">
|
||||
</sm-neon-button>
|
||||
</div>
|
@ -1,34 +0,0 @@
|
||||
@import "../../../../webapp-common/shared/ui-components/styles/variables";
|
||||
|
||||
.no-data-box {
|
||||
text-align: center;
|
||||
padding: 32px;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
height: 359px;
|
||||
border-radius: 6px;
|
||||
background-color: $blue-800;
|
||||
}
|
||||
|
||||
.main-image {
|
||||
margin: 15px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.empty-label{
|
||||
padding: 15px;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: $blue-100;
|
||||
}
|
||||
.empty-sub-label{
|
||||
padding: 15px;
|
||||
font-size: 16px;
|
||||
line-height: 1.31;
|
||||
color: $blue-300;
|
||||
}
|
||||
.line-breaker {
|
||||
white-space: pre-line;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'sm-getting-started-card',
|
||||
templateUrl: './getting-started-card.component.html',
|
||||
styleUrls: ['./getting-started-card.component.scss']
|
||||
})
|
||||
export class GettingStartedCardComponent implements OnInit {
|
||||
@Input() icon;
|
||||
@Input() title;
|
||||
@Input() subtitle;
|
||||
@Input() buttonLabel;
|
||||
@Output() buttonClicked = new EventEmitter();
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
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 {CrumbTypeEnum} from '@common/layout/breadcrumbs/breadcrumbs.component';
|
||||
import {NestedSimpleDatasetsPageComponent} from '@common/datasets/nested-simple-datasets-page/nested-simple-datasets-page.component';
|
||||
import {OpenDatasetsComponent} from '@common/datasets/open-datasets/open-datasets.component';
|
||||
import {NestedOpenDatasetsPageComponent} from '@common/datasets/nested-open-datasets-page/nested-open-datasets-page.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '',
|
||||
component: SimpleDatasetsComponent,
|
||||
component: OpenDatasetsComponent,
|
||||
data: {search: true, staticBreadcrumb:[[{
|
||||
name: 'DATASETS',
|
||||
type: CrumbTypeEnum.Feature
|
||||
@ -20,21 +20,22 @@ const routes: Routes = [
|
||||
children: [
|
||||
{
|
||||
path: 'datasets',
|
||||
component: SimpleDatasetsComponent,
|
||||
component: OpenDatasetsComponent,
|
||||
data: {search: true}
|
||||
},
|
||||
{
|
||||
path: 'projects',
|
||||
component: NestedSimpleDatasetsPageComponent,
|
||||
component: NestedOpenDatasetsPageComponent,
|
||||
data: {search: true}
|
||||
},
|
||||
{path: 'experiments', redirectTo: 'tasks'},
|
||||
{
|
||||
path: 'experiments',
|
||||
path: 'tasks',
|
||||
loadChildren: () => import('@common/dataset-version/dataset-version.module')
|
||||
.then(m => m.DatasetVersionModule)
|
||||
},
|
||||
{
|
||||
path: 'compare-experiments',
|
||||
path: 'compare-tasks',
|
||||
data: {entityType: EntityTypeEnum.dataset},
|
||||
loadChildren: () => import('@common/experiments-compare/experiments-compare.module').then(m => m.ExperimentsCompareModule)
|
||||
},
|
||||
|
@ -1,15 +1,16 @@
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {NgModule, NO_ERRORS_SCHEMA} from '@angular/core';
|
||||
import {SimpleDatasetsComponent} from '@common/datasets/simple-datasets/simple-datasets.component';
|
||||
import {CommonProjectsModule} from '@common/projects/common-projects.module';
|
||||
import {DatasetsRoutingModule} from '~/features/datasets/datasets-routing.module';
|
||||
import {DatasetsSharedModule} from '~/features/datasets/shared/datasets-shared.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';
|
||||
import {ButtonToggleComponent} from '@common/shared/ui-components/inputs/button-toggle/button-toggle.component';
|
||||
import {ShowTooltipIfEllipsisDirective} from '@common/shared/ui-components/indicators/tooltip/show-tooltip-if-ellipsis.directive';
|
||||
import {PushPipe} from '@ngrx/component';
|
||||
import {OpenDatasetsComponent} from '@common/datasets/open-datasets/open-datasets.component';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {DotsLoadMoreComponent} from '@common/shared/ui-components/indicators/dots-load-more/dots-load-more.component';
|
||||
|
||||
|
||||
@ -21,14 +22,15 @@ import {DotsLoadMoreComponent} from '@common/shared/ui-components/indicators/dot
|
||||
DatasetsSharedModule,
|
||||
NestedDatasetsPageComponent,
|
||||
ProjectsSharedModule,
|
||||
LabeledFormFieldDirective,
|
||||
ButtonToggleComponent,
|
||||
ShowTooltipIfEllipsisDirective,
|
||||
PushPipe,
|
||||
MatButton,
|
||||
MatIcon,
|
||||
DotsLoadMoreComponent
|
||||
],
|
||||
declarations: [
|
||||
SimpleDatasetsComponent,
|
||||
OpenDatasetsComponent,
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
exports: []
|
||||
|
@ -12,24 +12,27 @@
|
||||
(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
|
||||
mat-flat-button
|
||||
(click)="createExamples()">
|
||||
<mat-icon fontSet="al" fontIcon="al-ico-add"></mat-icon>
|
||||
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
|
||||
@if (allExamples) {
|
||||
or <a href="" (click)="$event.preventDefault(); createExamples()" class="link">generate
|
||||
example
|
||||
</a></ng-container>
|
||||
</div>
|
||||
<sm-dataset-empty [showButton]="true"></sm-dataset-empty>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
<sm-dataset-empty [showButton]="true"></sm-dataset-empty>
|
||||
</div>
|
||||
|
||||
</sm-nested-project-view-page>
|
||||
|
||||
@ -37,21 +40,21 @@
|
||||
<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>
|
||||
[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>
|
||||
@if (!hideMenu) {
|
||||
<sm-tag-list
|
||||
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>
|
||||
} @else {
|
||||
<sm-tag-list [tags]="project.tags"></sm-tag-list>
|
||||
}
|
||||
</sm-circle-counter>
|
||||
<ng-template #ReadOnlyTags>
|
||||
<sm-tag-list [tags]="project.tags"></sm-tag-list>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
||||
|
||||
|
@ -2,26 +2,31 @@ 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 {AsyncPipe, NgIf} from '@angular/common';
|
||||
import { AsyncPipe } 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';
|
||||
import {CircleCounterComponent} from '@common/shared/ui-components/indicators/circle-counter/circle-counter.component';
|
||||
import {TagListComponent} from '@common/shared/ui-components/tags/tag-list/tag-list.component';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {ClickStopPropagationDirective} from '@common/shared/ui-components/directives/click-stop-propagation.directive';
|
||||
|
||||
@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'
|
||||
'../../../webapp-common/datasets/open-datasets/open-datasets.component.scss'
|
||||
],
|
||||
imports: [
|
||||
ProjectsSharedModule,
|
||||
AsyncPipe,
|
||||
NgIf,
|
||||
CircleCounterComponent,
|
||||
TagListComponent
|
||||
],
|
||||
TagListComponent,
|
||||
MatButton,
|
||||
MatIcon,
|
||||
ClickStopPropagationDirective
|
||||
],
|
||||
standalone: true
|
||||
})
|
||||
export class NestedDatasetsPageComponent extends CommonProjectsPageComponent {
|
||||
|
4
src/app/features/datasets/shared/datasets-shared.module.ts
Executable file → Normal file
4
src/app/features/datasets/shared/datasets-shared.module.ts
Executable file → Normal file
@ -2,7 +2,6 @@ import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {SharedModule} from '~/shared/shared.module';
|
||||
import {SimpleDatasetCardComponent} from '@common/datasets/simple-dataset-card/simple-dataset-card.component';
|
||||
import {ProjectsSharedModule} from '~/features/projects/shared/projects-shared.module';
|
||||
import {ClickStopPropagationDirective} from '@common/shared/ui-components/directives/click-stop-propagation.directive';
|
||||
import {TagListComponent} from '@common/shared/ui-components/tags/tag-list/tag-list.component';
|
||||
@ -16,9 +15,10 @@ import {NAPipe} from '@common/shared/pipes/na.pipe';
|
||||
import {FileSizePipe} from '@common/shared/pipes/filesize.pipe';
|
||||
import {TooltipDirective} from '@common/shared/ui-components/indicators/tooltip/tooltip.directive';
|
||||
import {ShowTooltipIfEllipsisDirective} from '@common/shared/ui-components/indicators/tooltip/show-tooltip-if-ellipsis.directive';
|
||||
import {OpenDatasetCardComponent} from '@common/datasets/open-dataset-card/open-dataset-card.component';
|
||||
|
||||
const _declerations = [
|
||||
SimpleDatasetCardComponent
|
||||
OpenDatasetCardComponent
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
0
src/app/features/delete-entity/delete-dialog.effects.ts
Executable file → Normal file
0
src/app/features/delete-entity/delete-dialog.effects.ts
Executable file → Normal file
0
src/app/features/experiments/actions/experiments-info.actions.ts
Executable file → Normal file
0
src/app/features/experiments/actions/experiments-info.actions.ts
Executable file → Normal file
@ -4,7 +4,7 @@
|
||||
border-bottom: 1px solid #efefef;
|
||||
|
||||
&.minimized {
|
||||
grid-template-columns: 0 1fr 90px;
|
||||
grid-template-columns: 0 1fr 108px;
|
||||
}
|
||||
|
||||
@media(max-width: 1200px) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, computed} from '@angular/core';
|
||||
import {Component, computed, Signal} from '@angular/core';
|
||||
import {ExperimentMenuComponent} from '@common/experiments/shared/components/experiment-menu/experiment-menu.component';
|
||||
|
||||
@Component({
|
||||
|
@ -23,20 +23,34 @@
|
||||
<span class="refresh-position" refresh>
|
||||
<div class="scalar-buttons">
|
||||
@if (routerConfig.includes('scalar')) {
|
||||
<div class="table-graph-toggle" [class.maximized]="!minimized">
|
||||
<i class="al-icon pointer al-color blue-400"
|
||||
[smTooltip]="(metricValuesView$ | async)===false? 'Metric values': 'Graphs'"
|
||||
[class]="(metricValuesView$ | async)===false? 'al-ico-table-view': 'al-ico-charts-view'"
|
||||
(click)="toggleTableView()"
|
||||
></i>
|
||||
</div>
|
||||
<button mat-icon-button class="table-graph-toggle"
|
||||
[smTooltip]="(metricValuesView$ | async)===false? 'Metric values': 'Graphs'"
|
||||
[class.maximized]="!minimized"
|
||||
(click)="toggleTableView()">
|
||||
<mat-icon fontSet="al" [fontIcon]="(metricValuesView$ | async)===false? 'al-ico-table-view': 'al-ico-charts-view'"></mat-icon>
|
||||
</button>
|
||||
}
|
||||
@if ((metricValuesView$ | async) === false && routerConfig.includes('scalar') && minimized) {
|
||||
<sm-experiment-settings
|
||||
[class.maximized]="!minimized"
|
||||
[showSettings]="routerConfig.includes('scalar') && minimized"
|
||||
(toggleSettings)="toggleSettingsBar()"
|
||||
></sm-experiment-settings>
|
||||
<button mat-icon-button [matMenuTriggerFor]="graphSettingsMenu" smTooltip="Settings">
|
||||
<mat-icon fontSet="al" fontIcon="al-ico-settings"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #graphSettingsMenu="matMenu">
|
||||
<sm-graph-settings-bar
|
||||
class="graph-settings-menu"
|
||||
(click)="$event.stopPropagation()"
|
||||
[verticalLayout]="true"
|
||||
[smoothWeight]="smoothWeight$ | ngrxPush"
|
||||
[smoothType]="smoothType$ | ngrxPush"
|
||||
[xAxisType]="xAxisType$ | ngrxPush"
|
||||
[groupBy]="groupBy$ | ngrxPush"
|
||||
[groupByOptions]="groupByOptions"
|
||||
(changeWeight)="changeSmoothness($event)"
|
||||
(changeXAxisType)="changeXAxisType($event)"
|
||||
(changeGroupBy)="changeGroupBy($event)"
|
||||
(changeSmoothType)="changeSmoothType($event)"
|
||||
></sm-graph-settings-bar>
|
||||
</mat-menu>
|
||||
|
||||
}
|
||||
</div>
|
||||
@if (!minimized){
|
||||
|
0
src/app/features/experiments/experiments-routing.module.ts
Executable file → Normal file
0
src/app/features/experiments/experiments-routing.module.ts
Executable file → Normal file
0
src/app/features/experiments/experiments.consts.ts
Executable file → Normal file
0
src/app/features/experiments/experiments.consts.ts
Executable file → Normal file
139
src/app/features/experiments/experiments.module.ts
Executable file → Normal file
139
src/app/features/experiments/experiments.module.ts
Executable file → Normal file
@ -10,7 +10,6 @@ import {LayoutModule} from '~/layout/layout.module';
|
||||
import {ExperimentGraphsModule} from '@common/shared/experiment-graphs/experiment-graphs.module';
|
||||
import {ExperimentCompareSharedModule} from '@common/experiments-compare/shared/experiment-compare-shared.module';
|
||||
import {AngularSplitModule} from 'angular-split';
|
||||
import {CommonLayoutModule} from '@common/layout/layout.module';
|
||||
import {DebugImagesModule} from '@common/debug-images/debug-images.module';
|
||||
import {
|
||||
ExperimentInfoExecutionComponent
|
||||
@ -71,7 +70,6 @@ import {
|
||||
import {ExperimentOutputLogModule} from '@common/experiments/shared/experiment-output-log/experiment-output-log.module';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {ScrollingModule} from '@angular/cdk/scrolling';
|
||||
import {CommonDeleteDialogModule} from '@common/shared/entity-page/entity-delete/common-delete-dialog.module';
|
||||
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
||||
import {MatRadioModule} from '@angular/material/radio';
|
||||
import {SharedModule} from '~/shared/shared.module';
|
||||
@ -81,7 +79,6 @@ 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';
|
||||
import {OverlayComponent} from '@common/shared/ui-components/overlay/overlay/overlay.component';
|
||||
import {RefreshButtonComponent} from '@common/shared/components/refresh-button/refresh-button.component';
|
||||
import {
|
||||
@ -133,75 +130,79 @@ import {
|
||||
import {
|
||||
ExperimentArtifactsNavbarComponent
|
||||
} from '@common/experiments/dumb/experiment-artifacts-navbar/experiment-artifacts-navbar.component';
|
||||
import {CommonDeleteDialogModule} from '@common/shared/entity-page/entity-delete/common-delete-dialog.module';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatButton, MatIconButton} from '@angular/material/button';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
LayoutModule,
|
||||
ReactiveFormsModule,
|
||||
CommonModule,
|
||||
ExperimentRouterModule,
|
||||
ExperimentSharedModule,
|
||||
ExperimentGraphsModule,
|
||||
SelectModelModule,
|
||||
DebugImagesModule,
|
||||
ExperimentCompareSharedModule,
|
||||
CommonLayoutModule,
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
AngularSplitModule,
|
||||
ScrollingModule,
|
||||
CommonDeleteDialogModule,
|
||||
RouterModule,
|
||||
SharedModule,
|
||||
ExperimentOutputLogModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatRadioModule,
|
||||
RouterTabNavBarComponent,
|
||||
MatTabsModule,
|
||||
RouterTabNavBarComponent,
|
||||
LabeledFormFieldDirective,
|
||||
OverlayComponent,
|
||||
RefreshButtonComponent,
|
||||
InfoHeaderStatusIconLabelComponent,
|
||||
NAPipe,
|
||||
SortPipe,
|
||||
safeAngularUrlParameterPipe,
|
||||
ReplaceViaMapPipe,
|
||||
FilterOutPipe,
|
||||
DurationPipe,
|
||||
FilterInternalPipe,
|
||||
FileSizePipe,
|
||||
HideRedactedArgumentsPipe,
|
||||
MenuItemComponent,
|
||||
CopyClipboardComponent,
|
||||
SectionHeaderComponent,
|
||||
InlineEditComponent,
|
||||
TagsMenuComponent,
|
||||
EntityFooterComponent,
|
||||
MenuComponent,
|
||||
ExperimentTypeIconLabelComponent,
|
||||
SearchComponent,
|
||||
IdBadgeComponent,
|
||||
ScrollTextareaComponent,
|
||||
TagListComponent,
|
||||
TooltipDirective,
|
||||
LabeledRowComponent,
|
||||
EditableSectionComponent,
|
||||
SelectableGroupedFilterListComponent,
|
||||
MatMenuModule,
|
||||
MatExpansionModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
HesitateDirective,
|
||||
ShowTooltipIfEllipsisDirective,
|
||||
SelectQueueModule,
|
||||
PushPipe,
|
||||
ExperimentHeaderComponent,
|
||||
ExperimentOperationsLogComponent,
|
||||
ExperimentArtifactsNavbarComponent,
|
||||
],
|
||||
imports: [
|
||||
FormsModule,
|
||||
LayoutModule,
|
||||
ReactiveFormsModule,
|
||||
CommonModule,
|
||||
ExperimentRouterModule,
|
||||
ExperimentSharedModule,
|
||||
ExperimentGraphsModule,
|
||||
SelectModelModule,
|
||||
DebugImagesModule,
|
||||
ExperimentCompareSharedModule,
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
AngularSplitModule,
|
||||
ScrollingModule,
|
||||
RouterModule,
|
||||
SharedModule,
|
||||
ExperimentOutputLogModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatRadioModule,
|
||||
RouterTabNavBarComponent,
|
||||
MatTabsModule,
|
||||
RouterTabNavBarComponent,
|
||||
OverlayComponent,
|
||||
RefreshButtonComponent,
|
||||
InfoHeaderStatusIconLabelComponent,
|
||||
NAPipe,
|
||||
SortPipe,
|
||||
safeAngularUrlParameterPipe,
|
||||
ReplaceViaMapPipe,
|
||||
FilterOutPipe,
|
||||
DurationPipe,
|
||||
FilterInternalPipe,
|
||||
FileSizePipe,
|
||||
HideRedactedArgumentsPipe,
|
||||
MenuItemComponent,
|
||||
CopyClipboardComponent,
|
||||
SectionHeaderComponent,
|
||||
InlineEditComponent,
|
||||
TagsMenuComponent,
|
||||
EntityFooterComponent,
|
||||
MenuComponent,
|
||||
ExperimentTypeIconLabelComponent,
|
||||
SearchComponent,
|
||||
IdBadgeComponent,
|
||||
ScrollTextareaComponent,
|
||||
TagListComponent,
|
||||
TooltipDirective,
|
||||
LabeledRowComponent,
|
||||
EditableSectionComponent,
|
||||
SelectableGroupedFilterListComponent,
|
||||
MatMenuModule,
|
||||
MatExpansionModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
HesitateDirective,
|
||||
ShowTooltipIfEllipsisDirective,
|
||||
SelectQueueModule,
|
||||
PushPipe,
|
||||
ExperimentHeaderComponent,
|
||||
ExperimentOperationsLogComponent,
|
||||
ExperimentArtifactsNavbarComponent,
|
||||
CommonDeleteDialogModule,
|
||||
MatIcon,
|
||||
MatButton,
|
||||
MatIconButton
|
||||
],
|
||||
declarations: [
|
||||
ExperimentsComponent,
|
||||
ExperimentInfoExecutionComponent,
|
||||
|
0
src/app/features/experiments/reducers/experiment-info.reducer.ts
Executable file → Normal file
0
src/app/features/experiments/reducers/experiment-info.reducer.ts
Executable file → Normal file
0
src/app/features/experiments/reducers/index.ts
Executable file → Normal file
0
src/app/features/experiments/reducers/index.ts
Executable file → Normal file
0
src/app/features/experiments/shared/experiment-execution.model.ts
Executable file → Normal file
0
src/app/features/experiments/shared/experiment-execution.model.ts
Executable file → Normal file
2
src/app/features/experiments/shared/experiment-info.model.ts
Executable file → Normal file
2
src/app/features/experiments/shared/experiment-info.model.ts
Executable file → Normal file
@ -23,7 +23,7 @@ import {Output} from '~/business-logic/model/tasks/output';
|
||||
* an extended object of task that includes projection, will come from the server as an api response.
|
||||
*/
|
||||
export interface ISelectedExperiment {
|
||||
id?: string;
|
||||
id: string;
|
||||
name?: string;
|
||||
user?: User;
|
||||
company?: GetCurrentUserResponseUserObjectCompany;
|
||||
|
31
src/app/features/experiments/shared/experiment-shared.module.ts
Executable file → Normal file
31
src/app/features/experiments/shared/experiment-shared.module.ts
Executable file → Normal file
@ -5,7 +5,6 @@ import { ExperimentMenuComponent } from '@common/experiments/shared/components/e
|
||||
import {ExperimentMenuExtendedComponent} from '../containers/experiment-menu-extended/experiment-menu-extended.component';
|
||||
import {ExperimentExecutionParametersComponent} from '@common/experiments/dumb/experiment-execution-parameters/experiment-execution-parameters.component';
|
||||
import {CloneDialogComponent} from '@common/experiments/shared/components/clone-dialog/clone-dialog.component';
|
||||
import {ExperimentSystemTagsComponent} from '@common/experiments/shared/components/experiments-system-tags/experiment-system-tags.component';
|
||||
import {AbortAllChildrenDialogComponent} from '@common/experiments/shared/components/abort-all-children-dialog/abort-all-children-dialog.component';
|
||||
import {ExperimentsTableComponent} from '@common/experiments/dumb/experiments-table/experiments-table.component';
|
||||
import {ChangeProjectDialogComponent} from '@common/experiments/shared/components/change-project-dialog/change-project-dialog.component';
|
||||
@ -16,8 +15,7 @@ import {CommonExperimentOutputEffects} from '@common/experiments/effects/common-
|
||||
import {ScrollingModule} from '@angular/cdk/scrolling';
|
||||
import {ExperimentsMenuEffects} from '~/features/experiments/effects/experiments-menu.effects';
|
||||
import {ActionReducer, StoreConfig, StoreModule} from '@ngrx/store';
|
||||
import {CommonLayoutModule} from '@common/layout/layout.module';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
||||
import {ExperimentOutputEffects} from '~/features/experiments/effects/experiment-output.effects';
|
||||
import {EXPERIMENTS_PREFIX, EXPERIMENTS_STORE_KEY} from '@common/experiments/experiment.consts';
|
||||
@ -34,7 +32,6 @@ import {EXPERIMENTS_INFO_PREFIX} from '@common/experiments/actions/common-experi
|
||||
import {experimentsReducers} from '~/features/experiments/reducers';
|
||||
import {CommonExperimentConverterService} from '@common/experiments/shared/services/common-experiment-converter.service';
|
||||
import {HyperParamMetricColumnComponent} from '@common/experiments/shared/components/hyper-param-metric-column/hyper-param-metric-column.component';
|
||||
import {LabeledFormFieldDirective} from '@common/shared/directive/labeled-form-field.directive';
|
||||
import {StringIncludedInArrayPipe} from '@common/shared/pipes/string-included-in-array.pipe';
|
||||
import {TimeAgoPipe} from '@common/shared/pipes/timeAgo';
|
||||
import {ReplaceViaMapPipe} from '@common/shared/pipes/replaceViaMap';
|
||||
@ -44,7 +41,6 @@ import {MenuItemComponent} from '@common/shared/ui-components/panel/menu-item/me
|
||||
import {UniqueNameValidatorDirective} from '@common/shared/ui-components/template-forms-ui/unique-name-validator.directive';
|
||||
import {TagsMenuComponent} from '@common/shared/ui-components/tags/tags-menu/tags-menu.component';
|
||||
import {CustomColumnsListComponent} from '@common/shared/components/custom-columns-list/custom-columns-list.component';
|
||||
import {CheckboxControlComponent} from '@common/shared/ui-components/forms/checkbox-control/checkbox-control.component';
|
||||
import {MenuComponent} from '@common/shared/ui-components/panel/menu/menu.component';
|
||||
import {StatusIconLabelComponent} from '@common/shared/experiment-status-icon-label/status-icon-label.component';
|
||||
import {ExperimentTypeIconLabelComponent} from '@common/shared/experiment-type-icon-label/experiment-type-icon-label.component';
|
||||
@ -57,9 +53,8 @@ import {TagListComponent} from '@common/shared/ui-components/tags/tag-list/tag-l
|
||||
import {TagComponent} from '@common/shared/ui-components/indicators/tag/tag.component';
|
||||
import {MatMenuModule} from '@angular/material/menu';
|
||||
import {MatSidenavModule} from '@angular/material/sidenav';
|
||||
import {TableFilterSortTemplateComponent} from '@common/shared/ui-components/data/table/table-filter-sort-template/table-filter-sort-template.component';
|
||||
import {TableFilterSortComponent} from '@common/shared/ui-components/data/table/table-filter-sort/table-filter-sort.component';
|
||||
import {TableComponent} from '@common/shared/ui-components/data/table/table.component';
|
||||
import {TableCardFilterTemplateComponent} from '@common/shared/ui-components/data/table/table-card-filter-template/table-card-filter-template.component';
|
||||
import {MatSelectModule} from '@angular/material/select';
|
||||
import {ButtonToggleComponent} from '@common/shared/ui-components/inputs/button-toggle/button-toggle.component';
|
||||
import {GroupedCheckedFilterListComponent} from '@common/shared/ui-components/data/grouped-checked-filter-list/grouped-checked-filter-list.component';
|
||||
@ -79,6 +74,12 @@ import {ExperimentCustomColsMenuComponent} from '@common/experiments/dumb/experi
|
||||
import {SelectMetricForCustomColComponent} from '@common/experiments/dumb/select-metric-for-custom-col/select-metric-for-custom-col.component';
|
||||
import {SelectHyperParamsForCustomColComponent} from '@common/experiments/dumb/select-hyper-params-for-custom-col/select-hyper-params-for-custom-col.component';
|
||||
import {PushPipe} from '@ngrx/component';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatButton, MatIconButton} from '@angular/material/button';
|
||||
import {MatDialogActions, MatDialogClose} from '@angular/material/dialog';
|
||||
import {IsRowSelectedPipe} from '@common/shared/ui-components/data/table/is-rwo-selected.pipe';
|
||||
import {MiniTagsListComponent} from '@common/shared/ui-components/tags/user-tag/mini-tags-list/mini-tags-list.component';
|
||||
import {TableCardFilterComponent} from '@common/shared/ui-components/data/table/table-card-filter-template/table-card-filter.component';
|
||||
|
||||
export const experimentSyncedKeys = [
|
||||
'view.projectColumnsSortOrder',
|
||||
@ -126,7 +127,6 @@ export const getExperimentsConfig = (userPreferences: UserPreferences) => ({
|
||||
const DECLARATIONS = [
|
||||
ExperimentMenuComponent,
|
||||
ExperimentMenuExtendedComponent,
|
||||
ExperimentSystemTagsComponent,
|
||||
ChangeProjectDialogComponent,
|
||||
CloneDialogComponent,
|
||||
AbortAllChildrenDialogComponent,
|
||||
@ -151,9 +151,7 @@ const DECLARATIONS = [
|
||||
ExperimentGraphsModule,
|
||||
MatProgressSpinnerModule,
|
||||
ScrollingModule,
|
||||
CommonLayoutModule,
|
||||
HyperParamMetricColumnComponent,
|
||||
LabeledFormFieldDirective,
|
||||
StringIncludedInArrayPipe,
|
||||
TimeAgoPipe,
|
||||
ReplaceViaMapPipe,
|
||||
@ -163,7 +161,6 @@ const DECLARATIONS = [
|
||||
UniqueNameValidatorDirective,
|
||||
TagsMenuComponent,
|
||||
CustomColumnsListComponent,
|
||||
CheckboxControlComponent,
|
||||
MenuComponent,
|
||||
StatusIconLabelComponent,
|
||||
ExperimentTypeIconLabelComponent,
|
||||
@ -176,9 +173,8 @@ const DECLARATIONS = [
|
||||
TagComponent,
|
||||
MatMenuModule,
|
||||
MatSidenavModule,
|
||||
TableFilterSortTemplateComponent,
|
||||
TableFilterSortComponent,
|
||||
TableComponent,
|
||||
TableCardFilterTemplateComponent,
|
||||
MatSelectModule,
|
||||
ButtonToggleComponent,
|
||||
GroupedCheckedFilterListComponent,
|
||||
@ -198,6 +194,15 @@ const DECLARATIONS = [
|
||||
SelectMetricForCustomColComponent,
|
||||
SelectHyperParamsForCustomColComponent,
|
||||
PushPipe,
|
||||
MatIcon,
|
||||
MatIconButton,
|
||||
MatDialogActions,
|
||||
MatDialogClose,
|
||||
MatButton,
|
||||
IsRowSelectedPipe,
|
||||
MiniTagsListComponent,
|
||||
TableCardFilterComponent,
|
||||
ReactiveFormsModule,
|
||||
],
|
||||
declarations : [...DECLARATIONS],
|
||||
providers : [
|
||||
|
4
src/app/features/experiments/shared/experiments.const.ts
Executable file → Normal file
4
src/app/features/experiments/shared/experiments.const.ts
Executable file → Normal file
@ -40,7 +40,9 @@ export enum ExperimentTagsEnum {
|
||||
Development = 'development',
|
||||
Hidden = 'archived',
|
||||
Shared = 'shared',
|
||||
Pipeline = 'pipeline'
|
||||
Pipeline = 'pipeline',
|
||||
Example = 'example',
|
||||
Dataset = 'dataset'
|
||||
}
|
||||
|
||||
export const EXPERIMENTS_TAGS = {
|
||||
|
0
src/app/features/experiments/shared/experiments.model.ts
Executable file → Normal file
0
src/app/features/experiments/shared/experiments.model.ts
Executable file → Normal file
12
src/app/features/experiments/shared/experiments.utils.ts
Executable file → Normal file
12
src/app/features/experiments/shared/experiments.utils.ts
Executable file → Normal file
@ -1,6 +1,7 @@
|
||||
import {Model} from '../../../business-logic/model/models/model';
|
||||
import {ISelectedExperiment} from './experiment-info.model';
|
||||
import {isExample} from '../../../webapp-common/shared/utils/shared-utils';
|
||||
import {ExperimentTagsEnum} from '~/features/experiments/shared/experiments.const';
|
||||
|
||||
|
||||
export function areLabelsEqualss(modelLabels: Model['labels'], labels: Model['labels']) {
|
||||
@ -12,11 +13,14 @@ export function isDevelopment(entity): boolean {
|
||||
}
|
||||
|
||||
export function getSystemTags(experiment: ISelectedExperiment) {
|
||||
const sysTags = [];
|
||||
if (isExample(experiment)) {
|
||||
sysTags.push('example');
|
||||
const ignoredTags: string[] = [ExperimentTagsEnum.Hidden, ExperimentTagsEnum.Development];
|
||||
ignoredTags.push(ExperimentTagsEnum.Pipeline, ExperimentTagsEnum.Dataset);
|
||||
if (experiment?.system_tags?.includes(ExperimentTagsEnum.Dataset) || experiment?.system_tags?.includes(ExperimentTagsEnum.Pipeline)) {
|
||||
ignoredTags.push(ExperimentTagsEnum.Development);
|
||||
}
|
||||
return sysTags;
|
||||
return experiment?.system_tags?.filter(tag => !ignoredTags.includes(tag)) // remove ignored tags
|
||||
.map(tag => tag === ExperimentTagsEnum.Development ? 'dev' : tag) // development => dev
|
||||
.concat(isExample(experiment) ? [ExperimentTagsEnum.Example] : []); // add example when needed
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
0
src/app/features/experiments/shared/services/experiment-converter.service.ts
Executable file → Normal file
0
src/app/features/experiments/shared/services/experiment-converter.service.ts
Executable file → Normal file
0
src/app/features/experiments/shared/services/experiment-reverter.service.ts
Executable file → Normal file
0
src/app/features/experiments/shared/services/experiment-reverter.service.ts
Executable file → Normal file
0
src/app/features/login/login.actions.ts
Executable file → Normal file
0
src/app/features/login/login.actions.ts
Executable file → Normal file
@ -1,41 +1,10 @@
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { LoginRoutingModule } from './login-routing.module';
|
||||
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
||||
import {MatCheckboxModule} from '@angular/material/checkbox';
|
||||
import {SignupComponent} from './signup/signup.component';
|
||||
import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
import {MatSelectModule} from '@angular/material/select';
|
||||
import {MatInputModule} from '@angular/material/input';
|
||||
import {MatRadioModule} from '@angular/material/radio';
|
||||
import {LoginComponent} from '@common/login/login/login.component';
|
||||
import {NtkmeButtonModule} from '@ctrl/ngx-github-buttons';
|
||||
import {SafePipe} from '@common/shared/pipes/safe.pipe';
|
||||
import {PushPipe} from '@ngrx/component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [LoginComponent, SignupComponent],
|
||||
providers: [],
|
||||
imports: [
|
||||
CommonModule,
|
||||
LoginRoutingModule,
|
||||
FormsModule,
|
||||
MatAutocompleteModule,
|
||||
HttpClientModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatCheckboxModule,
|
||||
MatFormFieldModule,
|
||||
MatSelectModule,
|
||||
MatInputModule,
|
||||
MatRadioModule,
|
||||
NtkmeButtonModule,
|
||||
SafePipe,
|
||||
PushPipe
|
||||
]
|
||||
})
|
||||
export class LoginModule { }
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component} from '@angular/core';
|
||||
import {ModelMenuComponent} from '@common/models/containers/model-menu/model-menu.component';
|
||||
import {Component, signal} from '@angular/core';
|
||||
import {ModelMenuComponent} from '../../../../webapp-common/models/containers/model-menu/model-menu.component';
|
||||
|
||||
@Component({
|
||||
selector: 'sm-model-menu-extended',
|
||||
@ -7,7 +7,6 @@ import {ModelMenuComponent} from '@common/models/containers/model-menu/model-men
|
||||
styleUrls: ['../../../../webapp-common/models/containers/model-menu/model-menu.component.scss']
|
||||
})
|
||||
export class ModelMenuExtendedComponent extends ModelMenuComponent {
|
||||
get contextMenu() {
|
||||
return this;
|
||||
}
|
||||
|
||||
contextMenu = signal(this);
|
||||
}
|
||||
|
@ -1,21 +1,23 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import { ModelMenuComponent } from '@common/models/containers/model-menu/model-menu.component';
|
||||
import {CommonLayoutModule} from '@common/layout/layout.module';
|
||||
import { ModelMenuExtendedComponent } from './containers/model-menu-extended/model-menu-extended.component';
|
||||
import {MenuItemTextPipe} from '@common/shared/pipes/menu-item-text.pipe';
|
||||
import {TagsMenuComponent} from '@common/shared/ui-components/tags/tags-menu/tags-menu.component';
|
||||
import {MatMenuModule} from '@angular/material/menu';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatIconButton} from '@angular/material/button';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ModelMenuComponent, ModelMenuExtendedComponent],
|
||||
exports : [ModelMenuComponent, ModelMenuExtendedComponent],
|
||||
imports : [
|
||||
CommonLayoutModule,
|
||||
imports: [
|
||||
CommonModule,
|
||||
MenuItemTextPipe,
|
||||
TagsMenuComponent,
|
||||
MatMenuModule
|
||||
MatMenuModule,
|
||||
MatIcon,
|
||||
MatIconButton
|
||||
]
|
||||
})
|
||||
export class FeatureModelsModule {
|
||||
|
0
src/app/features/not-found/not-found-routing.module.ts
Executable file → Normal file
0
src/app/features/not-found/not-found-routing.module.ts
Executable file → Normal file
12
src/app/features/not-found/not-found.module.ts
Executable file → Normal file
12
src/app/features/not-found/not-found.module.ts
Executable file → Normal file
@ -4,13 +4,15 @@ import { CommonModule } from '@angular/common';
|
||||
import { NotFoundRoutingModule } from './not-found-routing.module';
|
||||
import { NotFoundComponent } from './not-found/not-found.component';
|
||||
import {CheckPermissionDirective} from '~/shared/directives/check-permission.directive';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
NotFoundRoutingModule,
|
||||
CheckPermissionDirective
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NotFoundRoutingModule,
|
||||
CheckPermissionDirective,
|
||||
MatIcon
|
||||
],
|
||||
declarations: [NotFoundComponent]
|
||||
})
|
||||
export class NotFoundModule { }
|
||||
|
4
src/app/features/not-found/not-found/not-found.component.html
Executable file → Normal file
4
src/app/features/not-found/not-found/not-found.component.html
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<div id="not-found-container" class="">
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="cat al-icon al-ico-cat al-color white"></div>
|
||||
<div class="d-flex justify-content-center align-items-center">
|
||||
<mat-icon fontSet="al" fontIcon="al-ico-cat" class="cat"></mat-icon>
|
||||
<h1>404</h1>
|
||||
</div>
|
||||
|
||||
|
39
src/app/features/not-found/not-found/not-found.component.scss
Executable file → Normal file
39
src/app/features/not-found/not-found/not-found.component.scss
Executable file → Normal file
@ -1,13 +1,14 @@
|
||||
@import "../../../webapp-common/shared/ui-components/styles/variables";
|
||||
@import "variables";
|
||||
|
||||
:host{
|
||||
#not-found-container {
|
||||
margin-top: 5%;
|
||||
color: white;
|
||||
color: var(--color-on-surface);
|
||||
|
||||
h1 {
|
||||
font-size: 200px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
|
||||
}
|
||||
h2 {
|
||||
@ -19,38 +20,10 @@
|
||||
font-weight: 100;
|
||||
}
|
||||
}
|
||||
.navbar-links {
|
||||
li {
|
||||
list-style: none;
|
||||
height: 130px;
|
||||
width: 130px;
|
||||
border: 1px solid white;
|
||||
border-radius: 4px;
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
li:hover {
|
||||
background: $blue-600;
|
||||
}
|
||||
.icon {
|
||||
margin: 10px auto;
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
display: block;
|
||||
}
|
||||
span {
|
||||
text-align: center;
|
||||
font-size: 17px;
|
||||
font-weight: 400;
|
||||
display: block;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
.cat{
|
||||
.cat {
|
||||
font-size: 140px;
|
||||
width:140px;
|
||||
height:140px;
|
||||
margin-top:44px;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
}
|
||||
}
|
||||
|
||||
|
0
src/app/features/not-found/not-found/not-found.component.ts
Executable file → Normal file
0
src/app/features/not-found/not-found/not-found.component.ts
Executable file → Normal file
4
src/app/features/projects/projects-page.utils.ts
Executable file → Normal file
4
src/app/features/projects/projects-page.utils.ts
Executable file → Normal file
@ -10,7 +10,7 @@ import {ProjectsGetAllExRequest} from '~/business-logic/model/projects/projectsG
|
||||
|
||||
export const isDeletableProject = readyForDeletion => (readyForDeletion.experiments.unarchived + readyForDeletion.models.unarchived) === 0;
|
||||
|
||||
export const popupEntitiesListConst = 'experiments, dataviews pipelines or dataset';
|
||||
export const popupEntitiesListConst = 'tasks, pipelines or dataset';
|
||||
|
||||
export const getDeleteProjectPopupStatsBreakdown = (readyForDeletion, statsSubset: 'archived' | 'unarchived' | 'total', experimentCaption) => {
|
||||
const errors = [
|
||||
@ -31,7 +31,7 @@ export const readyForDeletionFilter = readyForDeletion => !(readyForDeletion.exp
|
||||
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 getNoProjectsReRoute = (() => 'tasks');
|
||||
export const isNestedDatasets = (routeConf: string[]) => ['simple'].includes(routeConf?.[1]);
|
||||
|
||||
export const getFeatureProjectRequest = (snapshot: ActivatedRouteSnapshot, nested: boolean, searchQuery: any, selectedProjectName: any, selectedProjectId: any): ProjectsGetAllExRequest => {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user