You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by zj...@apache.org on 2020/01/12 06:38:24 UTC
[zeppelin] 07/16: [ZEPPELIN-4398] Add notebook repository page
This is an automated email from the ASF dual-hosted git repository.
zjffdu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git
commit 5ff4050285f4511b033c4ef09760cffccf932d8d
Author: Hsuan Lee <hs...@gmail.com>
AuthorDate: Fri Dec 6 16:18:18 2019 +0800
[ZEPPELIN-4398] Add notebook repository page
### What is this PR for?
Add the notebook repository page
### What type of PR is it?
[Feature]
### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-4398
### How should this be tested?
Not applicable
### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No
Author: Hsuan Lee <hs...@gmail.com>
Closes #3543 from hsuanxyz/feat/notebook-repos and squashes the following commits:
d148902f2 [Hsuan Lee] feat: add notebook repository page
---
.../interfaces/{public-api.ts => notebook-repo.ts} | 26 +++++--
.../src/app/interfaces/public-api.ts | 1 +
.../notebook-repos/item/item.component.html | 79 ++++++++++++++++++++++
.../notebook-repos/item/item.component.less} | 31 +++++++--
.../notebook-repos/item/item.component.ts | 78 +++++++++++++++++++++
.../notebook-repos-routing.module.ts} | 22 ++++--
.../notebook-repos/notebook-repos.component.html | 21 ++++++
.../notebook-repos/notebook-repos.component.less} | 14 ++--
.../notebook-repos/notebook-repos.component.ts | 51 ++++++++++++++
.../notebook-repos/notebook-repos.module.ts | 49 ++++++++++++++
.../pages/workspace/workspace-routing.module.ts | 5 ++
.../src/app/services/notebook-repos.service.ts | 36 ++++++++++
.../src/app/services/public-api.ts | 1 +
.../src/app/share/header/header.component.html | 2 +-
14 files changed, 391 insertions(+), 25 deletions(-)
diff --git a/zeppelin-web-angular/src/app/interfaces/public-api.ts b/zeppelin-web-angular/src/app/interfaces/notebook-repo.ts
similarity index 60%
copy from zeppelin-web-angular/src/app/interfaces/public-api.ts
copy to zeppelin-web-angular/src/app/interfaces/notebook-repo.ts
index f00e442..de03778 100644
--- a/zeppelin-web-angular/src/app/interfaces/public-api.ts
+++ b/zeppelin-web-angular/src/app/interfaces/notebook-repo.ts
@@ -10,9 +10,23 @@
* limitations under the License.
*/
-export * from './ticket';
-export * from './trash-folder-id';
-export * from './interpreter';
-export * from './message-interceptor';
-export * from './security';
-export * from './credential';
+export interface NotebookRepo {
+ name: string;
+ className: string;
+ settings: NotebookRepoSettingsItem[];
+}
+
+export interface NotebookRepoPutData {
+ name: string;
+ settings: {
+ [key: string]: string;
+ };
+}
+
+export interface NotebookRepoSettingsItem {
+ type: string;
+ // tslint:disable-next-line:no-any
+ value: any[];
+ selected: string;
+ name: string;
+}
diff --git a/zeppelin-web-angular/src/app/interfaces/public-api.ts b/zeppelin-web-angular/src/app/interfaces/public-api.ts
index f00e442..8c54e3d 100644
--- a/zeppelin-web-angular/src/app/interfaces/public-api.ts
+++ b/zeppelin-web-angular/src/app/interfaces/public-api.ts
@@ -16,3 +16,4 @@ export * from './interpreter';
export * from './message-interceptor';
export * from './security';
export * from './credential';
+export * from './notebook-repo';
diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.html b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.html
new file mode 100644
index 0000000..3f4875a
--- /dev/null
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.html
@@ -0,0 +1,79 @@
+<!--
+ ~ Licensed 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.
+ -->
+
+<nz-card class="repo-item"
+ [class.edit]="editMode"
+ [nzTitle]="repo.name"
+ [nzExtra]="extraTemplate">
+ <ng-template #extraTemplate>
+ <div class="extra-wrap" *ngIf="!editMode">
+ <button nz-button
+ nzSize="small"
+ (click)="triggerEditMode()">
+ <i nz-icon nzType="edit"></i>
+ Edit
+ </button>
+ </div>
+ <div class="extra-wrap" *ngIf="editMode">
+ <button nz-button
+ nzType="primary"
+ nzSize="small"
+ [disabled]="!settingFormArray.valid"
+ (click)="save()">
+ <i nz-icon nzType="save" nzTheme="outline"></i>
+ Save
+ </button>
+ <button nz-button
+ nzSize="small"
+ (click)="cancel()">
+ <i nz-icon nzType="close" nzTheme="outline"></i>
+ Cancel
+ </button>
+ </div>
+ </ng-template>
+ <h3>Setting</h3>
+ <form nz-form>
+ <nz-table nzTemplateMode nzSize="small">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Value</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let setting of repo.settings; index as i">
+ <td>{{setting.name}}</td>
+ <ng-container *ngIf="!editMode">
+ <td>{{setting.selected}}</td>
+ </ng-container>
+ <ng-container *ngIf="editMode">
+ <td>
+ <input *ngIf="setting.type === 'INPUT'"
+ nzSize="small"
+ nz-input
+ [formControl]="settingFormArray.controls[i]">
+
+ <nz-select *ngIf="setting.type === 'DROPDOWN'" [formControl]="settingFormArray.controls[i]">
+ <nz-option
+ *ngFor="let option of setting.value"
+ [nzLabel]="option"
+ [nzValue]="option">
+ </nz-option>
+ </nz-select>
+ </td>
+ </ng-container>
+ </tr>
+ </tbody>
+ </nz-table>
+ </form>
+
+</nz-card>
diff --git a/zeppelin-web-angular/src/app/interfaces/public-api.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.less
similarity index 62%
copy from zeppelin-web-angular/src/app/interfaces/public-api.ts
copy to zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.less
index f00e442..bc6d280 100644
--- a/zeppelin-web-angular/src/app/interfaces/public-api.ts
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.less
@@ -10,9 +10,28 @@
* limitations under the License.
*/
-export * from './ticket';
-export * from './trash-folder-id';
-export * from './interpreter';
-export * from './message-interceptor';
-export * from './security';
-export * from './credential';
+@import 'theme-mixin';
+
+.themeMixin({
+
+ display: block;
+ margin-bottom: @card-padding-base;
+ position: relative;
+
+ ::ng-deep .repo-item {
+ &.edit {
+ background: @orange-1;
+ }
+ }
+
+ .extra-wrap {
+ button {
+ transition: none;
+ }
+ button + button {
+ margin-bottom: 0;
+ margin-left: 8px;
+ }
+ }
+
+});
diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.ts
new file mode 100644
index 0000000..f66247c
--- /dev/null
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/item/item.component.ts
@@ -0,0 +1,78 @@
+/*
+ * Licensed 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 {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ EventEmitter,
+ Input,
+ OnChanges,
+ Output,
+ SimpleChanges
+} from '@angular/core';
+import { FormArray, FormBuilder, Validators } from '@angular/forms';
+import { NotebookRepo } from '@zeppelin/interfaces';
+
+@Component({
+ selector: 'zeppelin-notebook-repo-item',
+ templateUrl: './item.component.html',
+ styleUrls: ['./item.component.less'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class NotebookRepoItemComponent implements OnChanges {
+ @Input() repo: NotebookRepo;
+ @Output() readonly repoChange = new EventEmitter<NotebookRepo>();
+
+ settingFormArray: FormArray;
+ editMode = false;
+
+ constructor(private cdr: ChangeDetectorRef, private fb: FormBuilder) {}
+
+ triggerEditMode() {
+ this.editMode = !this.editMode;
+ this.cdr.markForCheck();
+ }
+
+ save() {
+ this.settingFormArray.controls.forEach(control => {
+ control.markAsDirty();
+ control.updateValueAndValidity();
+ });
+
+ if (this.settingFormArray.valid) {
+ const values = this.settingFormArray.getRawValue() as string[];
+ values.forEach((value, i) => (this.repo.settings[i].selected = value));
+ this.repoChange.emit(this.repo);
+ this.editMode = false;
+ this.cdr.markForCheck();
+ }
+ }
+
+ cancel() {
+ this.buildForm();
+ this.editMode = false;
+ this.cdr.markForCheck();
+ }
+
+ buildForm() {
+ const controls = this.repo.settings.map(setting => {
+ return this.fb.control(setting.selected, [Validators.required]);
+ });
+ this.settingFormArray = this.fb.array(controls);
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.repo) {
+ this.buildForm();
+ }
+ }
+}
diff --git a/zeppelin-web-angular/src/app/interfaces/public-api.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos-routing.module.ts
similarity index 59%
copy from zeppelin-web-angular/src/app/interfaces/public-api.ts
copy to zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos-routing.module.ts
index f00e442..e7e7ca1 100644
--- a/zeppelin-web-angular/src/app/interfaces/public-api.ts
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos-routing.module.ts
@@ -9,10 +9,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
-export * from './ticket';
-export * from './trash-folder-id';
-export * from './interpreter';
-export * from './message-interceptor';
-export * from './security';
-export * from './credential';
+import { NotebookReposComponent } from './notebook-repos.component';
+
+const routes: Routes = [
+ {
+ path: '',
+ component: NotebookReposComponent
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class NotebookReposRoutingModule {}
diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.html b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.html
new file mode 100644
index 0000000..d47ad87
--- /dev/null
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Licensed 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.
+ -->
+<zeppelin-page-header title="Notebook Repository" description="Manage your Notebook Repositories' settings.">
+</zeppelin-page-header>
+<div class="content">
+ <zeppelin-notebook-repo-item
+ *ngFor="let repo of repositories"
+ (repoChange)="updateRepoSetting($event)"
+ [repo]="repo">
+
+ </zeppelin-notebook-repo-item>
+</div>
diff --git a/zeppelin-web-angular/src/app/interfaces/public-api.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.less
similarity index 74%
copy from zeppelin-web-angular/src/app/interfaces/public-api.ts
copy to zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.less
index f00e442..5a3f8f0 100644
--- a/zeppelin-web-angular/src/app/interfaces/public-api.ts
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.less
@@ -10,9 +10,11 @@
* limitations under the License.
*/
-export * from './ticket';
-export * from './trash-folder-id';
-export * from './interpreter';
-export * from './message-interceptor';
-export * from './security';
-export * from './credential';
+@import 'theme-mixin';
+
+.themeMixin({
+
+ .content {
+ padding: @card-padding-base / 2;
+ }
+});
diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.ts
new file mode 100644
index 0000000..1faffee
--- /dev/null
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.component.ts
@@ -0,0 +1,51 @@
+/*
+ * Licensed 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 { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
+import { NotebookRepo } from '@zeppelin/interfaces';
+import { NotebookRepoService } from '@zeppelin/services';
+
+@Component({
+ selector: 'zeppelin-notebook-repos',
+ templateUrl: './notebook-repos.component.html',
+ styleUrls: ['./notebook-repos.component.less'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class NotebookReposComponent implements OnInit {
+ repositories: NotebookRepo[] = [];
+
+ constructor(private notebookRepoService: NotebookRepoService, private cdr: ChangeDetectorRef) {}
+
+ ngOnInit() {
+ this.getRepos();
+ }
+
+ getRepos() {
+ this.notebookRepoService.getRepos().subscribe(data => {
+ this.repositories = data.sort((a, b) => a.name.charCodeAt(0) - b.name.charCodeAt(0));
+ this.cdr.markForCheck();
+ });
+ }
+
+ updateRepoSetting(repo: NotebookRepo) {
+ const data = {
+ name: repo.className,
+ settings: {}
+ };
+ repo.settings.forEach(({ name, selected }) => {
+ data.settings[name] = selected;
+ });
+
+ this.notebookRepoService.updateRepo(data).subscribe(() => {
+ this.getRepos();
+ });
+ }
+}
diff --git a/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.module.ts b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.module.ts
new file mode 100644
index 0000000..2bb9d25
--- /dev/null
+++ b/zeppelin-web-angular/src/app/pages/workspace/notebook-repos/notebook-repos.module.ts
@@ -0,0 +1,49 @@
+/*
+ * Licensed 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 { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+
+import { ShareModule } from '@zeppelin/share';
+
+import {
+ NzButtonModule,
+ NzCardModule,
+ NzFormModule,
+ NzIconModule,
+ NzInputModule,
+ NzSelectModule,
+ NzTableModule
+} from 'ng-zorro-antd';
+
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { NotebookRepoItemComponent } from './item/item.component';
+import { NotebookReposRoutingModule } from './notebook-repos-routing.module';
+import { NotebookReposComponent } from './notebook-repos.component';
+
+@NgModule({
+ declarations: [NotebookReposComponent, NotebookRepoItemComponent],
+ imports: [
+ CommonModule,
+ ShareModule,
+ FormsModule,
+ ReactiveFormsModule,
+ NotebookReposRoutingModule,
+ NzCardModule,
+ NzButtonModule,
+ NzInputModule,
+ NzTableModule,
+ NzIconModule,
+ NzFormModule,
+ NzSelectModule
+ ]
+})
+export class NotebookReposModule {}
diff --git a/zeppelin-web-angular/src/app/pages/workspace/workspace-routing.module.ts b/zeppelin-web-angular/src/app/pages/workspace/workspace-routing.module.ts
index 6815b80..16928a3 100644
--- a/zeppelin-web-angular/src/app/pages/workspace/workspace-routing.module.ts
+++ b/zeppelin-web-angular/src/app/pages/workspace/workspace-routing.module.ts
@@ -53,6 +53,11 @@ const routes: Routes = [
path: 'credential',
loadChildren: () =>
import('@zeppelin/pages/workspace/credential/credential.module').then(m => m.CredentialModule)
+ },
+ {
+ path: 'notebook-repos',
+ loadChildren: () =>
+ import('@zeppelin/pages/workspace/notebook-repos/notebook-repos.module').then(m => m.NotebookReposModule)
}
]
}
diff --git a/zeppelin-web-angular/src/app/services/notebook-repos.service.ts b/zeppelin-web-angular/src/app/services/notebook-repos.service.ts
new file mode 100644
index 0000000..624599a
--- /dev/null
+++ b/zeppelin-web-angular/src/app/services/notebook-repos.service.ts
@@ -0,0 +1,36 @@
+/*
+ * Licensed 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 { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { NotebookRepo, NotebookRepoPutData } from '@zeppelin/interfaces';
+
+import { BaseRest } from './base-rest';
+import { BaseUrlService } from './base-url.service';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class NotebookRepoService extends BaseRest {
+ constructor(baseUrlService: BaseUrlService, private http: HttpClient) {
+ super(baseUrlService);
+ }
+
+ getRepos() {
+ return this.http.get<NotebookRepo[]>(this.restUrl`/notebook-repositories`);
+ }
+
+ updateRepo(repo: NotebookRepoPutData) {
+ return this.http.put(this.restUrl`/notebook-repositories`, repo);
+ }
+}
diff --git a/zeppelin-web-angular/src/app/services/public-api.ts b/zeppelin-web-angular/src/app/services/public-api.ts
index 6c3dbc0..f9bdfe9 100644
--- a/zeppelin-web-angular/src/app/services/public-api.ts
+++ b/zeppelin-web-angular/src/app/services/public-api.ts
@@ -29,3 +29,4 @@ export * from './runtime-compiler.service';
export * from './shortcut.service';
export * from './configuration.service';
export * from './credential.service';
+export * from './notebook-repos.service';
diff --git a/zeppelin-web-angular/src/app/share/header/header.component.html b/zeppelin-web-angular/src/app/share/header/header.component.html
index 71e8cd7..645da9a 100644
--- a/zeppelin-web-angular/src/app/share/header/header.component.html
+++ b/zeppelin-web-angular/src/app/share/header/header.component.html
@@ -47,7 +47,7 @@
<a [routerLink]="['/interpreter']">Interpreter</a>
</li>
<li nz-menu-item routerLinkActive="ant-dropdown-menu-item-selected">
- <a [routerLink]="['/notebookRepos']">Notebook
+ <a [routerLink]="['/notebook-repos']">Notebook
Repos
</a>
</li>