You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datalab.apache.org by hs...@apache.org on 2022/10/19 16:32:24 UTC
[incubator-datalab] 01/01: added connected platform component
This is an automated email from the ASF dual-hosted git repository.
hshpak pushed a commit to branch epm-connected-platform
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
commit 7a9c52b578145a58804b02af72cf7fdfcdff5928
Author: Hennadii_Shpak <bo...@gmail.com>
AuthorDate: Wed Oct 19 19:32:00 2022 +0300
added connected platform component
---
.../administration/management/management.model.ts | 12 ++-
.../resources/webapp/src/app/app.routing.module.ts | 63 +++++------
.../configs/connected-platforms.model.ts} | 17 +--
.../configs/routing-list.config.ts} | 29 +++---
.../pipes/normalize-link/index.ts} | 12 +--
.../pipes/normalize-link/normalize-link.pipe.ts} | 14 +--
.../src/app/core/services/appRouting.service.ts | 3 +-
.../services/applicationServiceFacade.service.ts | 30 +++++-
.../services/connected-platform-api.service.ts | 54 ++++++++++
.../connected-platform-dialog.component.html | 80 ++++++++++++++
.../connected-platform-dialog.component.scss | 98 +++++++++++++++++
.../connected-platform-dialog.component.ts | 70 +++++++++++++
.../connected-platforms-routing.module.ts} | 21 ++--
.../connected-platforms.component.html | 96 +++++++++++++++++
.../connected-platforms.component.scss | 99 ++++++++++++++++++
.../connected-platforms.component.ts | 114 ++++++++++++++++++++
.../connected-platforms.config.ts} | 30 +++---
.../connected-platforms.models.ts} | 24 +++--
.../connected-platforms.module.ts | 53 ++++++++++
.../connected-platforms.service.ts | 61 +++++++++++
.../warning-dialog/warning-dialog.component.html} | 21 ++--
.../warning-dialog/warning-dialog.component.scss} | 26 +++--
.../warning-dialog/warning-dialog.component.ts | 49 +++++++++
.../access-denied/access-denied.component.ts | 10 +-
.../not-found/not-found.component.html | 4 +-
.../service-pages/not-found/not-found.component.ts | 5 +-
.../src/app/service-pages/service-pages.module.ts | 5 +-
.../modal-btn/modal-btn.component.html} | 27 ++---
.../modal-btn/modal-btn.component.scss} | 16 +--
.../modal-parts/modal-btn/modal-btn.component.ts} | 20 +++-
.../modal-header/modal-header.component.html} | 20 ++--
.../modal-header/modal-header.component.scss} | 35 ++++---
.../modal-header/modal-header.component.ts} | 21 ++--
.../modal-parts/modal-parts.module.ts} | 24 +++--
.../src/app/shared/navbar/navbar.component.html | 116 ++++++++++++---------
.../src/app/shared/navbar/navbar.component.ts | 31 +++---
.../webapp/src/app/shared/navbar/navbar.config.ts | 22 ++--
37 files changed, 1165 insertions(+), 267 deletions(-)
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/management.model.ts b/services/self-service/src/main/resources/webapp/src/app/administration/management/management.model.ts
index 56ce00ff7..14b5b15f2 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/management.model.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/management.model.ts
@@ -85,8 +85,14 @@ export interface GeneralEnvironmentStatus {
status: string;
projectAssigned: boolean;
bucketBrowser: object;
+ connectedPlatforms: ConnectedPlatformsStatus;
}
+export interface ConnectedPlatformsStatus {
+ add: boolean;
+ disconnect: boolean;
+ view: boolean;
+}
export class ManagementConfigModel {
@@ -117,8 +123,8 @@ export class ManagementConfigModel {
export interface ModalData {
action: ActionsType;
- resource_name?: any;
- user?: any,
+ resource_name?: any;
+ user?: any,
type: string;
notebooks?: any
}
@@ -134,4 +140,4 @@ export enum ActionsType {
start = 'start',
run = 'run',
recreate = 'recreate'
-}
\ No newline at end of file
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts b/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts
index d166b7d40..3ff739602 100644
--- a/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts
@@ -37,12 +37,13 @@ import {ProjectAdminGuard} from './core/services/projectAdmin.guard';
import {ReportingComponent} from './reports/reporting/reporting.component';
import {OdahuComponent} from './administration/odahu/odahu.component';
import {AuditComponent} from './reports/audit/audit.component';
+import { RoutingListConfig } from './core/configs/routing-list.config';
const routes: Routes = [
{
- path: 'login',
+ path: RoutingListConfig.login,
component: LoginComponent
- },
+ },
{
path: '',
canActivate: [CheckParamsGuard],
@@ -50,77 +51,81 @@ const routes: Routes = [
children: [
{
path: '',
- redirectTo: 'resources_list',
+ redirectTo: RoutingListConfig.instances,
pathMatch: 'full'
- },
+ },
{
- path: 'resources_list',
+ path: RoutingListConfig.instances,
component: ResourcesComponent,
canActivate: [AuthorizationGuard]
- },
+ },
{
- path: 'billing_report',
+ path: RoutingListConfig.connectedPlatforms,
+ loadChildren: () => import('./resources/connected-platforms/connected-platforms.module').then(m => m.ConnectedPlatformsModule)
+ },
+ {
+ path: RoutingListConfig.billing,
component: ReportingComponent,
canActivate: [AuthorizationGuard, CloudProviderGuard]
- },
+ },
{
- path: 'projects',
+ path: RoutingListConfig.projects,
component: ProjectComponent,
canActivate: [AuthorizationGuard, AdminGuard],
},
{
- // path: 'odahu',
- // component: OdahuComponent,
- // canActivate: [AuthorizationGuard, AdminGuard],
- // }, {
- path: 'roles',
+ // path: 'odahu',
+ // component: OdahuComponent,
+ // canActivate: [AuthorizationGuard, AdminGuard],
+ // }, {
+ path: RoutingListConfig.users,
component: RolesComponent,
canActivate: [AuthorizationGuard, AdminGuard],
- },
+ },
{
- path: 'environment_management',
+ path: RoutingListConfig.resources,
component: ManagementComponent,
canActivate: [AuthorizationGuard, AdminGuard]
- },
+ },
{
- path: 'configuration',
+ path: RoutingListConfig.configuration,
component: ConfigurationComponent,
canActivate: [AuthorizationGuard, AdminGuard, ProjectAdminGuard]
},
{
- path: 'swagger',
+ path: RoutingListConfig.swagger,
component: SwaggerComponent,
canActivate: [AuthorizationGuard]
- },
+ },
{
- path: 'help/publickeyguide',
+ path: RoutingListConfig.publickeyguide,
component: PublicKeyGuideComponent,
canActivate: [AuthorizationGuard]
- },
+ },
{
- path: 'help/accessnotebookguide',
+ path: RoutingListConfig.accessnotebookguide,
component: AccessNotebookGuideComponent,
canActivate: [AuthorizationGuard]
},
{
- path: 'audit',
+ path: RoutingListConfig.audit,
component: AuditComponent,
canActivate: [AuthorizationGuard, AuditGuard],
},
]
- },
+ },
{
path: 'terminal/:id/:endpoint',
component: WebterminalComponent
- },
+ },
{
path: '403',
component: AccessDeniedComponent,
canActivate: [AuthorizationGuard]
- },
+ },
{
- path: '**',
- component: NotFoundComponent
+ path: '**',
+ component: NotFoundComponent
}
];
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/core/configs/connected-platforms.model.ts
similarity index 77%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
copy to services/self-service/src/main/resources/webapp/src/app/core/configs/connected-platforms.model.ts
index 34f860f16..2344ed14a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/configs/connected-platforms.model.ts
@@ -17,11 +17,14 @@
* under the License.
*/
-import { Component } from '@angular/core';
+export enum ModalTitle {
+ share = 'Share image',
+ terminate = 'Terminate image',
+ unShare = '! Warning',
+ addPlatform = 'Add platform'
+}
-@Component({
- selector: 'not-found',
- templateUrl: 'not-found.component.html',
- styleUrls: ['not-found.component.scss']
-})
-export class NotFoundComponent { }
+export enum URL_Chunk {
+ sharingInfo = 'sharing_info',
+ autocomplete = 'share_autocomplete'
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts b/services/self-service/src/main/resources/webapp/src/app/core/configs/routing-list.config.ts
similarity index 66%
copy from services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
copy to services/self-service/src/main/resources/webapp/src/app/core/configs/routing-list.config.ts
index 38df6d2c5..171f80c4e 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/configs/routing-list.config.ts
@@ -17,19 +17,18 @@
* under the License.
*/
-export const sideBarNamesConfig: Record<string, string> = {
- resourses: 'Resources',
- reports: 'Reports',
- audit: 'Audit',
- billing: 'Billing',
- administration: 'Administration',
- users: 'Users',
- projects: 'Projects',
- resources: 'Resources',
- configuration: 'Configuration'
-}
-
-export interface UserInfo {
- email: string;
- name: string;
+export enum RoutingListConfig {
+ instances = 'instances',
+ images = 'images',
+ connectedPlatforms = 'connected-platforms',
+ login = 'login',
+ billing = 'billing',
+ projects = 'projects',
+ users = 'users',
+ resources = 'resources',
+ audit = 'audit',
+ configuration = 'configuration',
+ swagger = 'swagger',
+ publickeyguide = 'help/publickeyguide',
+ accessnotebookguide = 'help/accessnotebookguide',
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/normalize-link/index.ts
similarity index 73%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
copy to services/self-service/src/main/resources/webapp/src/app/core/pipes/normalize-link/index.ts
index f3da2fe6f..18c71d973 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/normalize-link/index.ts
@@ -19,12 +19,12 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
-import { NotFoundComponent } from './not-found/not-found.component';
-import { AccessDeniedComponent } from './access-denied/access-denied.component';
+import { NormalizeLinkPipe } from './normalize-link.pipe';
@NgModule({
- imports: [CommonModule],
- declarations: [NotFoundComponent, AccessDeniedComponent],
- exports: [NotFoundComponent, AccessDeniedComponent]
+ imports: [ CommonModule ],
+ declarations: [ NormalizeLinkPipe ],
+ exports: [ NormalizeLinkPipe ]
})
-export class ServicePagesModule { }
\ No newline at end of file
+
+export class NormalizeLinkPipeModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/normalize-link/normalize-link.pipe.ts
similarity index 76%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
copy to services/self-service/src/main/resources/webapp/src/app/core/pipes/normalize-link/normalize-link.pipe.ts
index 34f860f16..ecbd3efcf 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/normalize-link/normalize-link.pipe.ts
@@ -17,11 +17,13 @@
* under the License.
*/
-import { Component } from '@angular/core';
+import { Pipe, PipeTransform } from '@angular/core';
-@Component({
- selector: 'not-found',
- templateUrl: 'not-found.component.html',
- styleUrls: ['not-found.component.scss']
+@Pipe({
+ name: 'normalizeLink'
})
-export class NotFoundComponent { }
+export class NormalizeLinkPipe implements PipeTransform {
+ transform(value: string): string {
+ return value.includes('http') ? value : `//${value}`;
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/appRouting.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/appRouting.service.ts
index 1a8075973..4eac9090f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/appRouting.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/appRouting.service.ts
@@ -19,6 +19,7 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
+import { RoutingListConfig } from '../configs/routing-list.config';
@Injectable()
export class AppRoutingService {
@@ -34,7 +35,7 @@ export class AppRoutingService {
}
redirectToHomePage(): void {
- this.router.navigate(['/resources_list']);
+ this.router.navigate(['/', RoutingListConfig.instances]);
}
redirectToHealthStatusPage(): void {
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
index 3bb326d3e..e7218bc45 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
@@ -24,6 +24,7 @@ import { HttpClient } from '@angular/common/http';
import { Dictionary } from '../collections';
import { environment } from '../../../environments/environment';
import { HTTPMethod } from '../util';
+import { AddPlatformFromValue } from '../../resources/connected-platforms/connected-platforms.models';
// we can now access environment.apiUrl
const API_URL = environment.apiUrl;
@@ -81,6 +82,7 @@ export class ApplicationServiceFacade {
private static readonly AUDIT = 'audit';
private static readonly CONFIG = 'config';
private static readonly QUOTA = 'quota';
+ private static readonly CONNECTED_PLATFORMS = 'connected_platforms';
private requestRegistry: Dictionary<string>;
@@ -180,6 +182,28 @@ export class ApplicationServiceFacade {
null);
}
+ buildGetConnectedPlatformsPage(): Observable<any> {
+ console.log(`${this.requestRegistry.Item(ApplicationServiceFacade.CONNECTED_PLATFORMS)}/user`);
+ return this.buildRequest(HTTPMethod.GET,
+ `${this.requestRegistry.Item(ApplicationServiceFacade.CONNECTED_PLATFORMS)}/user`,
+ null
+ );
+ }
+
+ buildAddPlatform(platformParams: AddPlatformFromValue): Observable<any> {
+ return this.buildRequest(HTTPMethod.POST,
+ this.requestRegistry.Item(ApplicationServiceFacade.CONNECTED_PLATFORMS),
+ platformParams
+ );
+ }
+
+ buildDisconnectPlatform(platformName: string): Observable<any> {
+ return this.buildRequest(HTTPMethod.DELETE,
+ `${this.requestRegistry.Item(ApplicationServiceFacade.CONNECTED_PLATFORMS)}/${platformName}`,
+ null
+ );
+ }
+
public buildGetTemplatesRequest(params): Observable<any> {
return this.buildRequest(HTTPMethod.GET,
this.requestRegistry.Item(ApplicationServiceFacade.TEMPLATES) + params,
@@ -725,6 +749,10 @@ export class ApplicationServiceFacade {
this.requestRegistry.Add(ApplicationServiceFacade.SCHEDULER,
'/api/infrastructure_provision/exploratory_environment/scheduler');
+ // Connected Platforms
+ this.requestRegistry.Add(ApplicationServiceFacade.CONNECTED_PLATFORMS,
+ '/api/connected_platforms');
+
// Computational Resources
this.requestRegistry.Add(ApplicationServiceFacade.COMPUTATIONAL_RESOURCES,
'/infrastructure_provision/computational_resources');
@@ -805,4 +833,4 @@ export class ApplicationServiceFacade {
return this.http.get(body ? (url + body) : url, opt);
}
}
-}
\ No newline at end of file
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/connected-platform-api.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/connected-platform-api.service.ts
new file mode 100644
index 000000000..bd7153080
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/connected-platform-api.service.ts
@@ -0,0 +1,54 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Injectable } from '@angular/core';
+import { ApplicationServiceFacade } from './applicationServiceFacade.service';
+import { catchError } from 'rxjs/operators';
+import { ErrorUtils } from '../util';
+import { Observable } from 'rxjs';
+import { AddPlatformFromValue, ConnectedPlatformsInfo } from '../../resources/connected-platforms/connected-platforms.models';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ConnectedPlatformApiService {
+
+ constructor(
+ private applicationServiceFacade: ApplicationServiceFacade
+ ) { }
+
+ getConnectedPlatformsPage(): Observable<ConnectedPlatformsInfo> {
+ return this.applicationServiceFacade.buildGetConnectedPlatformsPage()
+ .pipe(
+ catchError(ErrorUtils.handleServiceError)
+ );
+ }
+
+ addPlatform(platformParams: AddPlatformFromValue) {
+ return this.applicationServiceFacade.buildAddPlatform(platformParams).pipe(
+ catchError(ErrorUtils.handleServiceError)
+ );
+ }
+
+ disconnectPlatform(platformName: string) {
+ return this.applicationServiceFacade.buildDisconnectPlatform(platformName).pipe(
+ catchError(ErrorUtils.handleServiceError)
+ );
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.html
new file mode 100644
index 000000000..9540c721f
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.html
@@ -0,0 +1,80 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+ <div id="dialog-box" class="dialog__wrapper">
+ <header class="dialog-header">
+ <h4 class="modal-title">
+ {{modalTitle.addPlatform}}
+ </h4>
+ <button type="button" class="close" (click)="dialogRef.close()">×</button>
+ </header>
+ <div class="dialog-content">
+ <form [formGroup]="connectedPlatformForm">
+ <div class="control__wrapper">
+ <label>Select platform</label>
+ <mat-form-field class="select__wrapper" appearance="fill">
+ <mat-select placeholder="Select platform" name="platformType" formControlName="type">
+ <mat-option *ngIf="!data.types.length" disabled="true">
+ No platforms to add
+ </mat-option><mat-option *ngFor="let type of data.types" [value]="type">
+ {{type}}
+ </mat-option>
+ </mat-select>
+ <button class="caret">
+ <i class="material-icons">keyboard_arrow_down</i>
+ </button>
+ </mat-form-field>
+ </div>
+
+ <div class="control__wrapper">
+ <label>Platform url</label>
+ <div class="input__wrapper">
+ <input placeholder="Platform url" type="text" formControlName="url">
+ <span
+ class="error"
+ *ngIf="!connectedPlatformForm?.controls.url.valid
+ && connectedPlatformForm.controls.url.touched"
+ >
+ Please provide a valid platform url.
+ </span>
+ </div>
+ </div>
+
+ <div class="control__wrapper">
+ <label>Name</label>
+ <div class="input__wrapper">
+ <input placeholder="Enter name" type="text" formControlName="name">
+ <span
+ class="error"
+ *ngIf="!connectedPlatformForm?.controls.name.valid && connectedPlatformForm.controls.name.touched"
+ >
+ Platform name cannot be longer than 6 characters.
+ </span>
+ </div>
+ </div>
+ <div class="button__wrapper">
+ <datalab-modal-btn
+ [isConfirmBtnDisabled]="!isFormValid"
+ [confirmBtnName]="confirmButtonName.add"
+ (closeEvent)="onBtnClick($event)"
+ ></datalab-modal-btn>
+ </div>
+ </form>
+ </div>
+ </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.scss
new file mode 100644
index 000000000..0becd0d19
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.scss
@@ -0,0 +1,98 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+.dialog-content {
+ padding: 25px 30px;
+}
+
+.control__wrapper {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ height: 56px;
+}
+
+.select__wrapper {
+ position: relative;
+ width: 320px;
+ height: 36px;
+
+ & ::ng-deep .mat-form-field-wrapper {
+ padding: 0;
+ }
+
+ &.mat-form-field .mat-form-field-flex {
+ background-color: red !important;
+ }
+
+ & ::ng-deep .mat-form-field-appearance-fill .mat-form-field-flex {
+ padding: 0;
+ }
+
+ & ::ng-deep .mat-form-field-infix {
+ border-top: none;
+ }
+
+ & ::ng-deep .mat-form-field-underline::before {
+ height: 0;
+ }
+
+ & ::ng-deep .mat-form-field-ripple {
+ display: none;
+ }
+
+ & ::ng-deep .mat-select-arrow {
+ border: none;
+
+ }
+
+ ::ng-deep .mat-select-placeholder {
+ font-size: 15px;
+ }
+}
+
+.caret {
+ position: absolute;
+ top: -9px;
+ right: -11px;
+ width: 40px;
+ height: 40px;
+ color: #35afd5;
+ background-color: transparent;
+ border: none;
+ border-left: 1px solid #ececec;
+ outline: none;
+ cursor: pointer;
+}
+
+::ng-deep {
+ .mat-form-field .mat-form-field-flex{
+ background-color: white;
+ box-shadow: 0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%);
+ }
+}
+
+.input__wrapper {
+ width: 320px;
+ height: 56px;
+}
+
+.button__wrapper {
+ padding-top: 20px;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.ts
new file mode 100644
index 000000000..bf9f96e2e
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platform-dialog/connected-platform-dialog.component.ts
@@ -0,0 +1,70 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Component, Inject, OnInit } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { AddModalData, AddPlatformFromValue } from '../connected-platforms.models';
+import { ConfirmButtonNames } from '../connected-platforms.config';
+import { PATTERNS } from '../../../core/util';
+import { ModalTitle } from '../../../core/configs/connected-platforms.model';
+
+const URL_REGEXP_VALIDATION_STRING = '^(http(s)?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]';
+
+@Component({
+ selector: 'datalab-connected-platform-dialog',
+ templateUrl: './connected-platform-dialog.component.html',
+ styleUrls: ['./connected-platform-dialog.component.scss']
+})
+export class ConnectedPlatformDialogComponent implements OnInit {
+ readonly modalTitle: typeof ModalTitle = ModalTitle;
+ readonly confirmButtonName: typeof ConfirmButtonNames = ConfirmButtonNames;
+
+ connectedPlatformForm!: FormGroup;
+
+ constructor(
+ public dialogRef: MatDialogRef<ConnectedPlatformDialogComponent>,
+ private fb: FormBuilder,
+ @Inject(MAT_DIALOG_DATA) public data: AddModalData
+ ) { }
+
+ ngOnInit(): void {
+ this.initForm();
+ }
+
+ onBtnClick(flag: boolean): void {
+ let responseObj: AddPlatformFromValue;
+ if (flag) {
+ responseObj = this.connectedPlatformForm.value;
+ }
+ this.dialogRef.close(responseObj);
+ }
+
+ private initForm(): void {
+ this.connectedPlatformForm = this.fb.group({
+ type: ['', Validators.required],
+ url: ['', [ Validators.required, Validators.pattern(URL_REGEXP_VALIDATION_STRING)]],
+ name: ['', [ Validators.required, Validators.pattern(PATTERNS.projectName), Validators.minLength(2)]]
+ });
+ }
+
+ get isFormValid(): boolean {
+ return this.connectedPlatformForm.valid;
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms-routing.module.ts
similarity index 69%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
copy to services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms-routing.module.ts
index f3da2fe6f..61d93807f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms-routing.module.ts
@@ -1,4 +1,4 @@
-/*
+/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -18,13 +18,18 @@
*/
import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { NotFoundComponent } from './not-found/not-found.component';
-import { AccessDeniedComponent } from './access-denied/access-denied.component';
+import { RouterModule, Routes } from '@angular/router';
+import { ConnectedPlatformsComponent } from './connected-platforms.component';
+
+const routes: Routes = [
+ {
+ path: '',
+ component: ConnectedPlatformsComponent
+ }
+];
@NgModule({
- imports: [CommonModule],
- declarations: [NotFoundComponent, AccessDeniedComponent],
- exports: [NotFoundComponent, AccessDeniedComponent]
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
})
-export class ServicePagesModule { }
\ No newline at end of file
+export class ConnectedPlatformsRoutingModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.html
new file mode 100644
index 000000000..08acd3619
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.html
@@ -0,0 +1,96 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<section class="connected-platforms__wrapper base-retreat">
+ <nav class="sub-nav">
+ <button
+ *ngIf="(connectedPlatformsStatus$ | async)?.add"
+ (click)="onAddNew()"
+ mat-raised-button
+ class="butt butt-create"
+ >
+ <i class="material-icons">add</i>Add new
+ </button>
+ </nav>
+
+ <mat-divider></mat-divider>
+
+ <table mat-table [dataSource]="(platformPageData$ | async).userPlatforms" class="mat-elevation-z8 table">
+
+ <ng-container matColumnDef="platformName">
+ <th mat-header-cell *matHeaderCellDef>{{tableHeaderCellTitles.platformName}}</th>
+ <td mat-cell class="column" *matCellDef="let element"> {{element.name}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="linkToPlatform">
+ <th mat-header-cell *matHeaderCellDef>{{tableHeaderCellTitles.linkToPlatform}}</th>
+ <td class="column" mat-cell *matCellDef="let element">
+ <a
+ class="link"
+ [href]="element.url | normalizeLink"
+ target="_blank"
+ [matTooltip]="element.url"
+ matTooltipPosition="above"
+ [matTooltipDisabled]="element.url.length < maxUrlLength"
+ >
+ {{element.url | truncateTextPipe : maxUrlLength}}
+ </a>
+ </td>
+ </ng-container>
+
+ <ng-container matColumnDef="actions">
+ <th
+ mat-header-cell
+ [ngClass]="{'hided-table-title': !(connectedPlatformsStatus$ | async)?.disconnect}"
+ *matHeaderCellDef
+ >
+ {{tableHeaderCellTitles.actions}}
+ </th>
+ <td mat-cell class="action-cell" *matCellDef="let element">
+ <span class="actions-menu"
+ #settings
+ (click)="actions.toggle($event, settings)">
+ <img
+ *ngIf="(connectedPlatformsStatus$ | async)?.disconnect"
+ class="action-icon"
+ [src]="'assets/svg/settings_icon.svg'"
+ alt="setting-icon"
+ >
+ </span>
+ <bubble-up #actions class="list-menu" position="bottom-left" alternative="top-left">
+ <ul class="list-unstyled">
+ <li>
+ <button
+ class="action-button__disconnect"
+ (click)="onPlatformDisconnect(element)"
+ >
+ <i class="material-icons icon">cast</i>
+ <span>Disconnect</span>
+ </button>
+ </li>
+ </ul>
+ </bubble-up>
+ </td>
+ </ng-container>
+
+ <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+ <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+ </table>
+
+</section>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.scss
new file mode 100644
index 000000000..7dd04357d
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.scss
@@ -0,0 +1,99 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+.table {
+ width: 100%;
+}
+
+.column {
+ width: 20%;
+}
+
+.action-icon,
+.link {
+ cursor: pointer;
+}
+
+.link {
+ text-decoration: underline;
+}
+
+.hided-table-title {
+ color: transparent;
+}
+
+.table-cell {
+ position: relative;
+}
+
+.list-menu {
+ left: auto;
+ top: 30px !important;
+ width: 190px;
+ max-height: calc(100vh / 2 - 70px);
+ margin-left: 0;
+ box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
+ border: none;
+}
+
+.actions-menu {
+ position: relative;
+ width: 190px;
+}
+
+.action-button__disconnect {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ padding: 10px 15px;
+ background-color: transparent;
+ color: rgb(87, 114, 137);
+ border: none;
+ outline: none;
+
+ &:hover {
+ color: #35afd5;
+ cursor: pointer;
+
+ & ::before {
+ background-color: #35afd5;
+ }
+ }
+}
+
+.action-cell {
+ position: relative;
+}
+
+.icon {
+ position: relative;
+ margin-right: 10px;
+
+ &::before {
+ position: absolute;
+ top: 11px;
+ left: -4px;
+ width: 32px;
+ height: 1px;
+ rotate: 40deg;
+ content: '';
+ background-color: #577289;
+ transform: rotateX(1deg);
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.ts
new file mode 100644
index 000000000..b49dbc545
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.component.ts
@@ -0,0 +1,114 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Component, OnInit } from '@angular/core';
+import { BehaviorSubject, EMPTY, Observable, pipe } from 'rxjs';
+import { switchMap, take, tap } from 'rxjs/operators';
+import { MatDialog } from '@angular/material/dialog';
+import { ToastrService } from 'ngx-toastr';
+
+import { ConnectedPlatformsStatus, GeneralEnvironmentStatus } from '../../administration/management/management.model';
+import { HealthStatusService } from '../../core/services';
+import { ConnectedPlatformsTableTitles, ConnectedPlatformDisplayedColumns } from './connected-platforms.config';
+import { ConnectedPlatformDialogComponent } from './connected-platform-dialog/connected-platform-dialog.component';
+import { ConnectedPlatformsInfo, Platform } from './connected-platforms.models';
+import { ConnectedPlatformsService } from './connected-platforms.service';
+import { WarningDialogComponent } from './warning-dialog/warning-dialog.component';
+
+@Component({
+ selector: 'datalab-connected-platforms',
+ templateUrl: './connected-platforms.component.html',
+ styleUrls: ['./connected-platforms.component.scss']
+})
+export class ConnectedPlatformsComponent implements OnInit {
+ readonly tableHeaderCellTitles: typeof ConnectedPlatformsTableTitles = ConnectedPlatformsTableTitles;
+ readonly maxUrlLength: number = 30;
+
+ // tslint:disable-next-line:max-line-length
+ private readonly connectedPlatformsStatus$$: BehaviorSubject<ConnectedPlatformsStatus> = new BehaviorSubject<ConnectedPlatformsStatus>({} as ConnectedPlatformsStatus);
+ readonly connectedPlatformsStatus$: Observable<ConnectedPlatformsStatus> = this.connectedPlatformsStatus$$.asObservable();
+
+ platformPageData$: Observable<ConnectedPlatformsInfo>;
+
+ displayedColumns: typeof ConnectedPlatformDisplayedColumns = ConnectedPlatformDisplayedColumns;
+
+ constructor(
+ private healthStatusService: HealthStatusService,
+ public toastr: ToastrService,
+ private dialog: MatDialog,
+ private connectedPlatformsService: ConnectedPlatformsService
+ ) { }
+
+ ngOnInit(): void {
+ this.getEnvironmentHealthStatus();
+ this.getConnectedPlatformPageInfo();
+ this.initPageData();
+ }
+
+ onAddNew(): void {
+ this.dialog.open(ConnectedPlatformDialogComponent, {
+ data: this.connectedPlatformsService.addModalData,
+ panelClass: 'modal-lg'
+ })
+ .afterClosed()
+ .pipe(
+ this.getModalAction(this.connectedPlatformsService.addPlatform),
+ ).subscribe();
+ }
+
+ onPlatformDisconnect({name}: Platform): void {
+ this.dialog.open(WarningDialogComponent,
+ {
+ data: name,
+ panelClass: 'modal-sm'
+ })
+ .afterClosed()
+ .pipe(
+ this.getModalAction(this.connectedPlatformsService.disconnectPlatform)
+ ).subscribe();
+ }
+
+ private getModalAction(callback: Function) {
+ callback = callback.bind(this.connectedPlatformsService);
+ return pipe(
+ switchMap((arg) => {
+ if (arg) {
+ return callback(arg);
+ }
+ return EMPTY;
+ }),
+ switchMap(() => this.connectedPlatformsService.getConnectedPlatformPageInfo())
+ );
+ }
+
+ private getEnvironmentHealthStatus(): void {
+ this.healthStatusService.getEnvironmentHealthStatus().pipe(
+ tap((response: GeneralEnvironmentStatus) => this.connectedPlatformsStatus$$.next(response.connectedPlatforms)),
+ take(1)
+ ).subscribe();
+ }
+
+ private getConnectedPlatformPageInfo(): void {
+ this.connectedPlatformsService.getConnectedPlatformPageInfo().subscribe();
+ }
+
+ private initPageData(): void {
+ this.platformPageData$ = this.connectedPlatformsService.platformPageData$;
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.config.ts
similarity index 68%
copy from services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
copy to services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.config.ts
index 38df6d2c5..708ff528e 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.config.ts
@@ -17,19 +17,23 @@
* under the License.
*/
-export const sideBarNamesConfig: Record<string, string> = {
- resourses: 'Resources',
- reports: 'Reports',
- audit: 'Audit',
- billing: 'Billing',
- administration: 'Administration',
- users: 'Users',
- projects: 'Projects',
- resources: 'Resources',
- configuration: 'Configuration'
+export enum ConnectedPlatformsTableTitles {
+ platformName = 'Platform name',
+ linkToPlatform = 'Link to platform',
+ actions = 'Actions'
}
-export interface UserInfo {
- email: string;
- name: string;
+export const ConnectedPlatformDisplayedColumns = [
+ 'platformName',
+ 'linkToPlatform',
+ 'actions',
+];
+
+export enum ModalTitles {
+ disconnect= 'Disconnect platform'
+}
+
+export enum ConfirmButtonNames {
+ yes = 'Yes',
+ add = 'Add'
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.models.ts
similarity index 69%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
copy to services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.models.ts
index 34f860f16..d51487953 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.models.ts
@@ -1,4 +1,4 @@
-/*
+/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -17,11 +17,19 @@
* under the License.
*/
-import { Component } from '@angular/core';
+export interface ConnectedPlatformsInfo {
+ userPlatforms: Platform[];
+ types: string[];
+ platformNames: string[];
+}
-@Component({
- selector: 'not-found',
- templateUrl: 'not-found.component.html',
- styleUrls: ['not-found.component.scss']
-})
-export class NotFoundComponent { }
+export interface Platform {
+ name: string;
+ type: string;
+ user: string;
+ url: string;
+}
+
+export type AddModalData = Omit<ConnectedPlatformsInfo, 'userPlatforms'>;
+
+export type AddPlatformFromValue = Omit<Platform, 'user'>;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.module.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.module.ts
new file mode 100644
index 000000000..1a653e50b
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.module.ts
@@ -0,0 +1,53 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { ConnectedPlatformsRoutingModule } from './connected-platforms-routing.module';
+import { ConnectedPlatformsComponent } from './connected-platforms.component';
+import { MaterialModule } from '../../shared/material.module';
+import { BubbleModule } from '../../shared';
+import { ReactiveFormsModule } from '@angular/forms';
+import { TruncateTextPipeModule } from '../../core/pipes/truncate-text-pipe';
+import { ModalPartsModule } from '../../shared/modal-parts/modal-parts.module';
+import { WarningDialogComponent } from './warning-dialog/warning-dialog.component';
+import { ConnectedPlatformDialogComponent } from './connected-platform-dialog/connected-platform-dialog.component';
+import { NormalizeLinkPipeModule } from '../../core/pipes/normalize-link';
+
+
+@NgModule({
+ declarations: [
+ ConnectedPlatformsComponent,
+ WarningDialogComponent,
+ ConnectedPlatformDialogComponent
+ ],
+ imports: [
+ CommonModule,
+ MaterialModule,
+ NormalizeLinkPipeModule,
+ ConnectedPlatformsRoutingModule,
+ BubbleModule,
+ ModalPartsModule,
+ ReactiveFormsModule,
+ TruncateTextPipeModule
+ ],
+ entryComponents: [ ConnectedPlatformDialogComponent, WarningDialogComponent ]
+})
+export class ConnectedPlatformsModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.service.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.service.ts
new file mode 100644
index 000000000..14eea05b6
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/connected-platforms.service.ts
@@ -0,0 +1,61 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Injectable } from '@angular/core';
+import { ConnectedPlatformApiService } from '../../core/services/connected-platform-api.service';
+import { tap } from 'rxjs/operators';
+import { BehaviorSubject, Observable } from 'rxjs';
+import { AddModalData, AddPlatformFromValue, ConnectedPlatformsInfo } from './connected-platforms.models';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ConnectedPlatformsService {
+ // tslint:disable-next-line:max-line-length
+ private platformPageData$$: BehaviorSubject<ConnectedPlatformsInfo> = new BehaviorSubject<ConnectedPlatformsInfo>({} as ConnectedPlatformsInfo);
+ platformPageData$: Observable<ConnectedPlatformsInfo> = this.platformPageData$$.asObservable();
+ addModalData: AddModalData;
+
+ constructor(
+ private connectedPlatformPageService: ConnectedPlatformApiService
+ ) { }
+
+ getConnectedPlatformPageInfo(): Observable<ConnectedPlatformsInfo> {
+ console.log(1);
+ return this.connectedPlatformPageService.getConnectedPlatformsPage()
+ .pipe(
+ tap(res => console.log(res)),
+ tap( result => this.platformPageData$$.next(result)),
+ tap( result => this.getAddModalData(result)),
+ );
+ }
+
+ addPlatform(platformParams: AddPlatformFromValue): Observable<any> {
+ return this.connectedPlatformPageService.addPlatform(platformParams);
+ }
+
+ disconnectPlatform(platformName: string): Observable<any> {
+ return this.connectedPlatformPageService.disconnectPlatform(platformName);
+ }
+
+ private getAddModalData(info: ConnectedPlatformsInfo): void {
+ const { platformNames, types } = info;
+ this.addModalData = { platformNames, types };
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.html
similarity index 67%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
copy to services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.html
index 2eb5e74b3..32d382c05 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.html
@@ -17,17 +17,12 @@
~ under the License.
-->
-<div class="not-found-page">
- <div class="content">
- <a class="logo" href="#/resources_list">
- <img src="assets/svg/not_found_page.svg" alt="">
- </a>
-
- <div class="message-block">
- <h3>Whooops... Page Not Found!</h3>
- <p>We couldn't seem to found the page you are looking for.
- <a href="#/resources_list">Go to the Homepage?</a>
- </p>
- </div>
- </div>
+<datalab-modal-header (close)="onClose()" [modalTitle]="title.disconnect"></datalab-modal-header>
+<div class="dialog-content">
+ <p class="content red">The <span class="platform-name">{{data}}</span> will be disconnected from this account.</p>
+ <datalab-modal-btn
+ [needAdditionalQuestion]="true"
+ (closeEvent)="onBtnClick($event)"
+ [confirmBtnName]="confirmButtonName.yes"
+ ></datalab-modal-btn>
</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.scss
similarity index 79%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
copy to services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.scss
index 34f860f16..310d4b09f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -17,11 +17,21 @@
* under the License.
*/
-import { Component } from '@angular/core';
+.dialog-content {
+ padding: 25px 30px;
+}
-@Component({
- selector: 'not-found',
- templateUrl: 'not-found.component.html',
- styleUrls: ['not-found.component.scss']
-})
-export class NotFoundComponent { }
+.red {
+ color: red;
+}
+
+.content {
+ margin-bottom: 50px;
+ padding-top: 20px;
+ text-align: center;
+ font-weight: 400;
+}
+
+.platform-name {
+ font-weight: 700;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.ts
new file mode 100644
index 000000000..f30f0d3be
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/connected-platforms/warning-dialog/warning-dialog.component.ts
@@ -0,0 +1,49 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Component, Inject } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
+import { ConfirmButtonNames, ModalTitles } from '../connected-platforms.config';
+
+@Component({
+ selector: 'datalab-warning-dialog',
+ templateUrl: './warning-dialog.component.html',
+ styleUrls: ['./warning-dialog.component.scss']
+})
+export class WarningDialogComponent {
+ readonly title: typeof ModalTitles = ModalTitles;
+ readonly confirmButtonName: typeof ConfirmButtonNames = ConfirmButtonNames;
+
+ constructor(
+ public dialogRef: MatDialogRef<WarningDialogComponent>,
+ @Inject(MAT_DIALOG_DATA) public data: string
+ ) { }
+
+ onClose(): void {
+ this.dialogRef.close();
+ }
+
+ onBtnClick(isConfirm: boolean): void {
+ let platformName;
+ if (isConfirm) {
+ platformName = this.data;
+ }
+ this.dialogRef.close(platformName);
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/access-denied/access-denied.component.ts b/services/self-service/src/main/resources/webapp/src/app/service-pages/access-denied/access-denied.component.ts
index cb290ec3c..b0075cac8 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/access-denied/access-denied.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/service-pages/access-denied/access-denied.component.ts
@@ -17,20 +17,21 @@
* under the License.
*/
import { Component, OnInit } from '@angular/core';
+import { RoutingListConfig } from '../../core/configs/routing-list.config';
@Component({
selector: 'datalab-access-denied',
template: `
<div class="no-access-page">
<div class="content">
- <a class="logo" href="#/resources_list">
+ <a class="logo" [routerLink]="['/', routerList.instances]">
<img src="assets/img/security-screen.png" alt="">
</a>
<div class="message-block">
<h3>Access Denied!</h3>
<p>The page you were trying to reach has restricted access.
- <a href="#/resources_list">Go to the Homepage?</a>
+ <a [routerLink]="['/', routerList.instances]">Go to the Homepage?</a>
</p>
</div>
</div>
@@ -38,7 +39,6 @@ import { Component, OnInit } from '@angular/core';
`,
styleUrls: ['./access-denied.component.scss']
})
-export class AccessDeniedComponent implements OnInit {
- constructor() { }
- ngOnInit() { }
+export class AccessDeniedComponent {
+ readonly routerList: typeof RoutingListConfig = RoutingListConfig;
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html b/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
index 2eb5e74b3..8dada3ee9 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
@@ -19,14 +19,14 @@
<div class="not-found-page">
<div class="content">
- <a class="logo" href="#/resources_list">
+ <a class="logo" [routerLink]="['/', routerList.instances]">
<img src="assets/svg/not_found_page.svg" alt="">
</a>
<div class="message-block">
<h3>Whooops... Page Not Found!</h3>
<p>We couldn't seem to found the page you are looking for.
- <a href="#/resources_list">Go to the Homepage?</a>
+ <a [routerLink]="['/', routerList.instances]">Go to the Homepage?</a>
</p>
</div>
</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
index 34f860f16..08b17cd32 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
@@ -18,10 +18,13 @@
*/
import { Component } from '@angular/core';
+import { RoutingListConfig } from '../../core/configs/routing-list.config';
@Component({
selector: 'not-found',
templateUrl: 'not-found.component.html',
styleUrls: ['not-found.component.scss']
})
-export class NotFoundComponent { }
+export class NotFoundComponent {
+ readonly routerList: typeof RoutingListConfig = RoutingListConfig;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts b/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
index f3da2fe6f..268bf75e4 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
@@ -21,10 +21,11 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NotFoundComponent } from './not-found/not-found.component';
import { AccessDeniedComponent } from './access-denied/access-denied.component';
+import { RouterModule } from '@angular/router';
@NgModule({
- imports: [CommonModule],
+ imports: [CommonModule, RouterModule],
declarations: [NotFoundComponent, AccessDeniedComponent],
exports: [NotFoundComponent, AccessDeniedComponent]
})
-export class ServicePagesModule { }
\ No newline at end of file
+export class ServicePagesModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.html
similarity index 66%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.html
index 2eb5e74b3..0a5089c4b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.html
@@ -16,18 +16,19 @@
~ specific language governing permissions and limitations
~ under the License.
-->
-
-<div class="not-found-page">
- <div class="content">
- <a class="logo" href="#/resources_list">
- <img src="assets/svg/not_found_page.svg" alt="">
- </a>
-
- <div class="message-block">
- <h3>Whooops... Page Not Found!</h3>
- <p>We couldn't seem to found the page you are looking for.
- <a href="#/resources_list">Go to the Homepage?</a>
- </p>
- </div>
+<div class="component__wrapper">
+ <p *ngIf="needAdditionalQuestion" class="question center">
+ Do you want proceed?
+ </p>
+ <div class="button__wrapper">
+ <button type="button" class="butt mat-raised-button" (click)="close()">No</button>
+ <button
+ [disabled]="isConfirmBtnDisabled"
+ type="button"
+ class="butt butt-success mat-raised-button"
+ (click)="close(true)">
+ {{confirmBtnName}}
+ </button>
</div>
</div>
+
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.scss
similarity index 79%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.scss
index 34f860f16..d46002dc1 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.scss
@@ -17,11 +17,13 @@
* under the License.
*/
-import { Component } from '@angular/core';
+.button__wrapper {
+ text-align: center;
+}
-@Component({
- selector: 'not-found',
- templateUrl: 'not-found.component.html',
- styleUrls: ['not-found.component.scss']
-})
-export class NotFoundComponent { }
+.question {
+ margin-bottom: 20px;
+ text-align: center;
+ color: #718ba6;
+ font-weight: bold;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.ts
similarity index 61%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.ts
index 34f860f16..4aa51fb0c 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-btn/modal-btn.component.ts
@@ -17,11 +17,21 @@
* under the License.
*/
-import { Component } from '@angular/core';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
- selector: 'not-found',
- templateUrl: 'not-found.component.html',
- styleUrls: ['not-found.component.scss']
+ selector: 'datalab-modal-btn',
+ templateUrl: './modal-btn.component.html',
+ styleUrls: ['./modal-btn.component.scss']
})
-export class NotFoundComponent { }
+export class ModalBtnComponent {
+ @Input() isConfirmBtnDisabled: boolean;
+ @Input() confirmBtnName: string;
+ @Input() needAdditionalQuestion: boolean = false;
+
+ @Output() closeEvent: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+ close(flag: boolean = false): void {
+ this.closeEvent.emit(flag);
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.html
similarity index 68%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.html
index 2eb5e74b3..83650e21b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.html
@@ -17,17 +17,11 @@
~ under the License.
-->
-<div class="not-found-page">
- <div class="content">
- <a class="logo" href="#/resources_list">
- <img src="assets/svg/not_found_page.svg" alt="">
- </a>
-
- <div class="message-block">
- <h3>Whooops... Page Not Found!</h3>
- <p>We couldn't seem to found the page you are looking for.
- <a href="#/resources_list">Go to the Homepage?</a>
- </p>
- </div>
- </div>
+<div>
+ <header class="dialog-header">
+ <h4 class="modal-title">
+ {{modalTitle}}
+ </h4>
+ <button type="button" class="close" (click)="onClose()">×</button>
+ </header>
</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.scss
similarity index 68%
copy from services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.scss
index 38df6d2c5..ece700481 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -17,19 +17,26 @@
* under the License.
*/
-export const sideBarNamesConfig: Record<string, string> = {
- resourses: 'Resources',
- reports: 'Reports',
- audit: 'Audit',
- billing: 'Billing',
- administration: 'Administration',
- users: 'Users',
- projects: 'Projects',
- resources: 'Resources',
- configuration: 'Configuration'
+.dialog-header {
+ position: relative;
+ padding-left: 30px;
+ height: 50px;
+ background: #f6fafe;
+ line-height: 50px;
}
-export interface UserInfo {
- email: string;
- name: string;
+.close {
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 50px;
+ width: 50px;
+ font-size: 24px;
+ font-weight: 300;
+ border: 0;
+ background: none;
+ color: #577289;
+ outline: none;
+ cursor: pointer;
+ transition: all 0.5s ease-in-out;
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.ts
similarity index 67%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.ts
index 34f860f16..7ef9b6d62 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/not-found/not-found.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-header/modal-header.component.ts
@@ -1,4 +1,4 @@
-/*
+/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -17,11 +17,20 @@
* under the License.
*/
-import { Component } from '@angular/core';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
- selector: 'not-found',
- templateUrl: 'not-found.component.html',
- styleUrls: ['not-found.component.scss']
+ selector: 'datalab-modal-header',
+ templateUrl: './modal-header.component.html',
+ styleUrls: ['./modal-header.component.scss']
})
-export class NotFoundComponent { }
+export class ModalHeaderComponent {
+ @Input() modalTitle: string;
+
+ @Output() close: EventEmitter<any> = new EventEmitter<any>();
+
+ onClose(): void {
+ this.close.emit();
+ }
+
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-parts.module.ts
similarity index 72%
copy from services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-parts.module.ts
index f3da2fe6f..3559594eb 100644
--- a/services/self-service/src/main/resources/webapp/src/app/service-pages/service-pages.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-parts/modal-parts.module.ts
@@ -1,4 +1,4 @@
-/*
+/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -19,12 +19,22 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
-import { NotFoundComponent } from './not-found/not-found.component';
-import { AccessDeniedComponent } from './access-denied/access-denied.component';
+import { ModalHeaderComponent } from './modal-header/modal-header.component';
+import { ModalBtnComponent } from './modal-btn/modal-btn.component';
+
+
@NgModule({
- imports: [CommonModule],
- declarations: [NotFoundComponent, AccessDeniedComponent],
- exports: [NotFoundComponent, AccessDeniedComponent]
+ declarations: [
+ ModalHeaderComponent,
+ ModalBtnComponent
+ ],
+ imports: [
+ CommonModule
+ ],
+ exports: [
+ ModalBtnComponent,
+ ModalHeaderComponent
+ ]
})
-export class ServicePagesModule { }
\ No newline at end of file
+export class ModalPartsModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html
index 8c52c46f9..9ff4b3754 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html
@@ -28,7 +28,7 @@
<span class="line"></span>
</button>
- <a [routerLink]="['/resources_list']" class="navbar-logo">
+ <a [routerLink]="[routerList.instances]" class="navbar-logo">
<img src="assets/svg/logo.svg" alt="">
</a>
</div>
@@ -37,11 +37,11 @@
<!-- <a *ngIf="healthStatus.status" [routerLink]="['/environment_management']" class="statusbar">
<span class="material-icons" ngClass="{{healthStatus.status || ''}}">radio_button_checked</span>
</a> -->
-
- <a
- *ngIf="metadata"
- class="statusbar about-btn--wrapper"
- #info
+
+ <a
+ *ngIf="metadata"
+ class="statusbar about-btn--wrapper"
+ #info
(click)="actions.toggle($event, info)">
<span class="about-btn">About</span>
</a>
@@ -72,7 +72,7 @@
<a class="help-link" href="https://github.com/apache/incubator-datalab/blob/master/USER_GUIDE.md" target="_blank">Help</a>
</span>
- <span
+ <span
class="material-icons account-icon--nav-bar account-icon" #login (click)="loginInfo.toggle($event, login)">
account_circle
</span>
@@ -85,53 +85,71 @@
<span class="user-mail">{{userData.email}}</span>
<button type="button" class="logout-btn" (click)="logout_btnClick()">
Log out from account
- </button>
+ </button>
</div>
</bubble-up>
</div>
</div>
<mat-sidenav-container class="example-container" autosize >
- <mat-sidenav
- #drawer
- mode="side"
- opened
- role="navigation"
- [style.width]="isExpanded ? '220px' : '60px'"
- disableClose
+ <mat-sidenav
+ #drawer
+ mode="side"
+ opened
+ role="navigation"
+ [style.width]="isExpanded ? '220px' : '60px'"
+ disableClose
*ngIf="healthStatus"
>
<mat-nav-list >
<nav>
<div>
- <a
- class="nav-item"
- [routerLink]="['/resources_list']"
- [routerLinkActive]="['active']"
- [routerLinkActiveOptions]="{exact:true}"
- >
- <span *ngIf="isExpanded; else resources">{{sideBarNames.resourses}}</span>
- <ng-template #resources><i class="material-icons">dashboard</i></ng-template>
+ <a class="nav-item has-children">
+ <span *ngIf="isExpanded">{{sideBarNames.resources}}</span>
+ <a
+ class="sub-nav-item"
+ [style.margin-left.px]="isExpanded ? '30' : '0'"
+ [routerLink]="[routerList.instances]"
+ [routerLinkActive]="['active']"
+ [routerLinkActiveOptions]="{exact:true}"
+ >
+ <span *ngIf="isExpanded; else instances">{{sideBarNames.instances}}</span>
+ <ng-template #instances><i class="material-icons">laptop</i></ng-template>
+ </a>
+
+ <a
+ *ngIf="healthStatus.connectedPlatforms?.view"
+ class="sub-nav-item"
+ [style.margin-left.px]="isExpanded ? '30' : '0'"
+ [routerLink]="[routerList.connectedPlatforms]"
+ [routerLinkActive]="['active']"
+ [routerLinkActiveOptions]="{exact:true}"
+ >
+ <span *ngIf="isExpanded; else connectedPlatforms">{{sideBarNames.connectedPlatforms}}</span>
+ <ng-template #connectedPlatforms><i class="material-icons">cast</i></ng-template>
+ </a>
+
</a>
+
<a class="nav-item has-children" *ngIf="healthStatus?.billingEnabled || healthStatus?.auditEnabled">
<span *ngIf="isExpanded">{{sideBarNames.reports}}</span>
- <a
- *ngIf="healthStatus?.auditEnabled"
- class="sub-nav-item"
- [routerLink]="['/audit']"
+ <a
+ *ngIf="healthStatus?.auditEnabled"
+ class="sub-nav-item"
+ [routerLink]="['/audit']"
[style.margin-left.px]="isExpanded ? '30' : '0'"
- [routerLinkActive]="['active']"
+ [routerLinkActive]="['active']"
[routerLinkActiveOptions]="{exact:true}"
>
<span *ngIf="isExpanded; else audit">{{sideBarNames.audit}}</span>
<ng-template #audit><i class="material-icons">library_books</i></ng-template>
</a>
- <a
- *ngIf="healthStatus?.billingEnabled"
- class="sub-nav-item"
+ <a
+ *ngIf="healthStatus?.billingEnabled"
+ class="sub-nav-item"
[routerLink]="['/billing_report']"
- [routerLinkActive]="['active']"
- [routerLinkActiveOptions]="{exact:true}"
+ [routerLinkActive]="['active']"
+ [routerLinkActiveOptions]="{exact:true}"
[style.margin-left.px]="isExpanded ? '30' : '0'"
>
<span *ngIf="isExpanded; else billing">{{sideBarNames.billing}}</span>
@@ -141,21 +159,21 @@
<a class="nav-item has-children" *ngIf="healthStatus?.admin || healthStatus?.projectAdmin">
<span *ngIf="isExpanded">{{sideBarNames.administration}}</span>
- <a
- class="sub-nav-item"
- [style.margin-left.px]="isExpanded ? '30' : '0'"
+ <a
+ class="sub-nav-item"
+ [style.margin-left.px]="isExpanded ? '30' : '0'"
[routerLink]="['/roles']"
- [routerLinkActive]="['active']"
+ [routerLinkActive]="['active']"
[routerLinkActiveOptions]="{exact:true}"
>
<span *ngIf="isExpanded; else roles">{{sideBarNames.users}}</span>
<ng-template #roles><i class="material-icons">account_box</i></ng-template>
</a>
- <a
- class="sub-nav-item"
- [style.margin-left.px]="isExpanded ? '30' : '0'"
+ <a
+ class="sub-nav-item"
+ [style.margin-left.px]="isExpanded ? '30' : '0'"
[routerLink]="['/projects']"
- [routerLinkActive]="['active']"
+ [routerLinkActive]="['active']"
[routerLinkActiveOptions]="{exact:true}"
>
<span *ngIf="isExpanded; else projects">{{sideBarNames.projects}}</span>
@@ -166,21 +184,21 @@
<!-- <span *ngIf="isExpanded; else odahu">Odahu deployment</span>-->
<!-- <ng-template #odahu><i class="material-icons">get_app</i></ng-template>-->
<!-- </a>-->
- <a
- class="sub-nav-item"
+ <a
+ class="sub-nav-item"
[style.margin-left.px]="isExpanded ? '30' : '0'"
- [routerLink]="['/environment_management']"
+ [routerLink]="['/environment_management']"
[routerLinkActive]="['active']"
[routerLinkActiveOptions]="{exact:true}"
>
<span *ngIf="isExpanded; else env">{{sideBarNames.resources}}</span>
<ng-template #env><i class="material-icons">settings</i></ng-template>
</a>
- <a
- *ngIf="healthStatus?.admin"
- class="sub-nav-item"
+ <a
+ *ngIf="healthStatus?.admin"
+ class="sub-nav-item"
[style.margin-left.px]="isExpanded ? '30' : '0'"
- [routerLink]="['/configuration']"
+ [routerLink]="['/configuration']"
[routerLinkActive]="['active']"
[routerLinkActiveOptions]="{exact:true}"
>
@@ -188,7 +206,7 @@
<ng-template #env><i class="material-icons">build_circle</i></ng-template>
</a>
</a>
-
+
</div>
<!-- <div>-->
<!-- <a class="nav-item" [routerLink]="['/swagger']" [routerLinkActive]="['active']"-->
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
index b01184dc8..862f9feb5 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
@@ -23,12 +23,12 @@ import { Subscription, timer } from 'rxjs';
import { ToastrService } from 'ngx-toastr';
import { RouterOutlet } from '@angular/router';
-import {
- ApplicationSecurityService,
- HealthStatusService,
- AppRoutingService,
- SchedulerService,
- StorageService
+import {
+ ApplicationSecurityService,
+ HealthStatusService,
+ AppRoutingService,
+ SchedulerService,
+ StorageService
} from '../../core/services';
import { GeneralEnvironmentStatus } from '../../administration/management/management.model';
import { NotificationDialogComponent } from '../modal-dialog/notification-dialog';
@@ -37,12 +37,13 @@ import {
animate,
transition,
style,
- query,
+ query,
group,
} from '@angular/animations';
import {skip, take} from 'rxjs/operators';
import {ProgressBarService} from '../../core/services/progress-bar.service';
-import{ sideBarNamesConfig, UserInfo } from './navbar.config'
+import { Sidebar_Names_Config, UserInfo } from './navbar.config';
+import { RoutingListConfig } from '../../core/configs/routing-list.config';
interface Quota {
projectQuotas: {};
@@ -85,6 +86,8 @@ export class NavbarComponent implements OnInit, OnDestroy {
private readonly CHECK_ACTIVE_SCHEDULE_TIMEOUT: number = 300000;
private readonly CHECK_ACTIVE_SCHEDULE_PERIOD: number = 15;
+ readonly routerList: typeof RoutingListConfig = RoutingListConfig;
+ readonly sideBarNames: typeof Sidebar_Names_Config = Sidebar_Names_Config;
currentUserName: string;
quotesLimit: number = 70;
@@ -93,7 +96,6 @@ export class NavbarComponent implements OnInit, OnDestroy {
isExpanded: boolean = true;
healthStatus: GeneralEnvironmentStatus;
subscriptions: Subscription = new Subscription();
- sideBarNames!: Record<string, string>;
userData!: UserInfo;
commitMaxLength: number = 22;
@@ -109,7 +111,6 @@ export class NavbarComponent implements OnInit, OnDestroy {
) { }
ngOnInit() {
- this.sideBarNames = sideBarNamesConfig;
this.applicationSecurityService.loggedInStatus.subscribe(response => {
this.subscriptions.unsubscribe();
this.subscriptions.closed = false;
@@ -197,22 +198,22 @@ export class NavbarComponent implements OnInit, OnDestroy {
} else {
this.storage.setBillingQuoteUsed('');
}
-
+
if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.totalQuotaUsed, exceedProjects, informProjects);
});
}
}
-
+
private getUserData(): UserInfo {
- const token = localStorage.getItem('JWT_TOKEN')
+ const token = localStorage.getItem('JWT_TOKEN');
const [_, tokenInfo] = token.split('.');
const {name, email} = JSON.parse(atob(tokenInfo));
-
+
return {
name: name || 'Jhon Doe',
email: email || 'Email not found'
- }
+ };
}
private checkAssignment(params): void {
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
index 38df6d2c5..7dfa42522 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.config.ts
@@ -17,16 +17,18 @@
* under the License.
*/
-export const sideBarNamesConfig: Record<string, string> = {
- resourses: 'Resources',
- reports: 'Reports',
- audit: 'Audit',
- billing: 'Billing',
- administration: 'Administration',
- users: 'Users',
- projects: 'Projects',
- resources: 'Resources',
- configuration: 'Configuration'
+export enum Sidebar_Names_Config {
+ reports = 'Reports',
+ audit = 'Audit',
+ billing = 'Billing',
+ administration = 'Administration',
+ users = 'Users',
+ projects = 'Projects',
+ resources = 'Resources',
+ configuration = 'Configuration',
+ instances = 'Instances',
+ images = 'Images',
+ connectedPlatforms = 'Connected platforms'
}
export interface UserInfo {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datalab.apache.org
For additional commands, e-mail: commits-help@datalab.apache.org