[YUNIKORN-2448] Implemented licenses modal (#175)
Closes: #175
Signed-off-by: Chia-Ping Tsai <chia7712@gmail.com>
diff --git a/angular.json b/angular.json
index b8116b3..2ff8fb0 100644
--- a/angular.json
+++ b/angular.json
@@ -30,7 +30,7 @@
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
- "assets": ["src/favicon.ico", "src/assets"],
+ "assets": ["src/favicon.ico", "src/assets", {"glob": "LICENSE", "input": "./", "output": "./"}],
"styles": [
"src/styles.scss",
"node_modules/fontsource-roboto/index.css",
@@ -64,7 +64,7 @@
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
- "extractLicenses": false,
+ "extractLicenses": true,
"sourceMap": true,
"namedChunks": true
}
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 1e9713e..f598ac1 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -93,6 +93,9 @@
<button mat-menu-item (click)="openYuniKornHelp('/community/get_involved')">
Get Involved
</button>
+ <button mat-menu-item (click)="openYuniKornLicense()">
+ License Information
+ </button>
</mat-menu>
</div>
</div>
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
index 04cc7f8..638c26e 100644
--- a/src/app/app.component.spec.ts
+++ b/src/app/app.component.spec.ts
@@ -26,6 +26,7 @@
import { AppComponent } from './app.component';
import { EventBusService } from './services/event-bus/event-bus.service';
import { MockEventBusService } from './testing/mocks';
+import { MatDialog } from '@angular/material/dialog';
describe('AppComponent', () => {
let component: AppComponent;
@@ -38,6 +39,7 @@
providers: [
{ provide: EventBusService, useValue: MockEventBusService },
{ provide: HAMMER_LOADER, useValue: () => new Promise(() => {}) },
+ { provide: MatDialog, useValue: {} },
],
}).compileComponents();
});
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 2f19a7a..3e29007 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -22,6 +22,8 @@
import { fromEvent } from 'rxjs';
import { EventBusService, EventMap } from '@app/services/event-bus/event-bus.service';
+import { LicensesModalComponent } from '@app/components/licenses-modal/licenses-modal.component';
+import { MatDialog } from '@angular/material/dialog';
@Component({
selector: 'app-root',
@@ -35,7 +37,8 @@
constructor(
private route: ActivatedRoute,
private router: Router,
- private eventBus: EventBusService
+ private eventBus: EventBusService,
+ private dialog: MatDialog
) {}
ngOnInit() {
@@ -101,4 +104,11 @@
const fullUrl = `http://yunikorn.apache.org${url}`;
window.open(fullUrl, '_blank');
}
+
+ openYuniKornLicense() {
+ this.dialog.open(LicensesModalComponent, {
+ maxWidth: '800px',
+ disableClose: true,
+ });
+ }
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 66b6458..413394b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -38,7 +38,8 @@
import { MatMenuModule } from '@angular/material/menu';
import { MatButtonModule } from '@angular/material/button';
import { MatExpansionModule } from '@angular/material/expansion';
-import {MatIconModule} from '@angular/material/icon';
+import { MatIconModule } from '@angular/material/icon';
+import { MatDialogModule } from '@angular/material/dialog';
import { AppRoutingModule } from '@app/app-routing.module';
import { envConfigFactory, EnvconfigService } from '@app/services/envconfig/envconfig.service';
@@ -61,6 +62,7 @@
import { HealthchecksComponent } from '@app/components/healthchecks/healthchecks.component';
import { AppNodeUtilizationsComponent } from '@app/components/app-node-utilizations/app-node-utilizations.component';
import { VerticalBarChartComponent } from '@app/components/vertical-bar-chart/vertical-bar-chart.component';
+import { LicensesModalComponent } from '@app/components/licenses-modal/licenses-modal.component';
@NgModule({
declarations: [
@@ -82,6 +84,7 @@
HealthchecksComponent,
AppNodeUtilizationsComponent,
VerticalBarChartComponent,
+ LicensesModalComponent,
],
imports: [
BrowserModule,
@@ -107,6 +110,7 @@
AppRoutingModule,
MatExpansionModule,
MatIconModule,
+ MatDialogModule,
],
providers: [
{
diff --git a/src/app/components/licenses-modal/licenses-modal.component.html b/src/app/components/licenses-modal/licenses-modal.component.html
new file mode 100644
index 0000000..14b671a
--- /dev/null
+++ b/src/app/components/licenses-modal/licenses-modal.component.html
@@ -0,0 +1,31 @@
+<!--
+ * 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.
+ -->
+
+<mat-dialog-content class="mat-typography licenses-modal">
+ <div class="modal-header">
+ <h2>Licenses used in YuniKorn project</h2>
+ </div>
+
+ <div class="modal-body">
+ <pre [innerHTML]="licenses"></pre>
+ </div>
+
+ <div class="modal-footer">
+ <button mat-button (click)="close()" [mat-dialog-close]="true">Close</button>
+ </div>
+</mat-dialog-content>
\ No newline at end of file
diff --git a/src/app/components/licenses-modal/licenses-modal.component.scss b/src/app/components/licenses-modal/licenses-modal.component.scss
new file mode 100644
index 0000000..a4b189c
--- /dev/null
+++ b/src/app/components/licenses-modal/licenses-modal.component.scss
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ */
+
+.licenses-modal {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ max-width: 750px;
+
+ .modal-header {
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ color: rgb(51,51,51);
+ }
+
+ .modal-body {
+ flex-grow: 1;
+ overflow-y: auto;
+
+ pre {
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ font-size: 12px;
+ line-height: 13px;
+ }
+ }
+
+ .modal-footer {
+ position: sticky;
+ bottom: 0;
+ padding-top: 10px;
+ border-top: 1px solid #e9e9e9;
+ z-index: 1;
+ text-align: right;
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/licenses-modal/licenses-modal.component.spec.ts b/src/app/components/licenses-modal/licenses-modal.component.spec.ts
new file mode 100644
index 0000000..37af6c7
--- /dev/null
+++ b/src/app/components/licenses-modal/licenses-modal.component.spec.ts
@@ -0,0 +1,43 @@
+/**
+ * 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 { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LicensesModalComponent } from './licenses-modal.component';
+import { MatDialogRef } from '@angular/material/dialog';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+
+describe('LicensesModalComponent', () => {
+ let component: LicensesModalComponent;
+ let fixture: ComponentFixture<LicensesModalComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [LicensesModalComponent],
+ providers: [{ provide: MatDialogRef, useValue: {} }],
+ imports: [HttpClientTestingModule],
+ }).compileComponents();
+ fixture = TestBed.createComponent(LicensesModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/licenses-modal/licenses-modal.component.ts b/src/app/components/licenses-modal/licenses-modal.component.ts
new file mode 100644
index 0000000..f61665c
--- /dev/null
+++ b/src/app/components/licenses-modal/licenses-modal.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 } from '@angular/core';
+import { MatDialogRef } from '@angular/material/dialog';
+import { HttpClient } from '@angular/common/http';
+import { isDevMode } from '@angular/core';
+
+@Component({
+ selector: 'app-licenses-modal',
+ templateUrl: './licenses-modal.component.html',
+ styleUrls: ['./licenses-modal.component.scss'],
+})
+export class LicensesModalComponent {
+ licenses = '';
+
+ constructor(
+ private dialogRef: MatDialogRef<LicensesModalComponent>,
+ private httpClient: HttpClient
+ ) {
+ // Licenses file is generated during build time and is available at /3rdpartylicenses.txt
+ // Dev mode uses the file from assets folder assets/example-licenses.txt
+ const licensePath = isDevMode() ? 'LICENSE' : '3rdpartylicenses.txt';
+
+ this.httpClient.get(licensePath, { responseType: 'text' }).subscribe((data) => {
+ if (data) this.licenses = data.replace(/\n/g, '<br/>');
+ else this.licenses = 'No licenses found';
+ });
+ }
+
+ close() {
+ this.dialogRef.close();
+ }
+}