Skip to content

Commit 5ff4050

Browse files
hsuanxyzzjffdu
authored andcommitted
[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) ![repos](https://user-images.githubusercontent.com/22736418/70308435-338edf00-1846-11ea-9030-bcf4ecaf22bb.gif) ### Questions: * Does the licenses files need update? No * Is there breaking changes for older versions? No * Does this needs documentation? No Author: Hsuan Lee <[email protected]> Closes #3543 from hsuanxyz/feat/notebook-repos and squashes the following commits: d148902 [Hsuan Lee] feat: add notebook repository page
1 parent 3aaa111 commit 5ff4050

14 files changed

+439
-1
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License.
11+
*/
12+
13+
export interface NotebookRepo {
14+
name: string;
15+
className: string;
16+
settings: NotebookRepoSettingsItem[];
17+
}
18+
19+
export interface NotebookRepoPutData {
20+
name: string;
21+
settings: {
22+
[key: string]: string;
23+
};
24+
}
25+
26+
export interface NotebookRepoSettingsItem {
27+
type: string;
28+
// tslint:disable-next-line:no-any
29+
value: any[];
30+
selected: string;
31+
name: string;
32+
}

zeppelin-web-angular/src/app/interfaces/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export * from './interpreter';
1616
export * from './message-interceptor';
1717
export * from './security';
1818
export * from './credential';
19+
export * from './notebook-repo';
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!--
2+
~ Licensed under the Apache License, Version 2.0 (the "License");
3+
~ you may not use this file except in compliance with the License.
4+
~ You may obtain a copy of the License at
5+
~ http://www.apache.org/licenses/LICENSE-2.0
6+
~ Unless required by applicable law or agreed to in writing, software
7+
~ distributed under the License is distributed on an "AS IS" BASIS,
8+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
~ See the License for the specific language governing permissions and
10+
~ limitations under the License.
11+
-->
12+
13+
<nz-card class="repo-item"
14+
[class.edit]="editMode"
15+
[nzTitle]="repo.name"
16+
[nzExtra]="extraTemplate">
17+
<ng-template #extraTemplate>
18+
<div class="extra-wrap" *ngIf="!editMode">
19+
<button nz-button
20+
nzSize="small"
21+
(click)="triggerEditMode()">
22+
<i nz-icon nzType="edit"></i>
23+
Edit
24+
</button>
25+
</div>
26+
<div class="extra-wrap" *ngIf="editMode">
27+
<button nz-button
28+
nzType="primary"
29+
nzSize="small"
30+
[disabled]="!settingFormArray.valid"
31+
(click)="save()">
32+
<i nz-icon nzType="save" nzTheme="outline"></i>
33+
Save
34+
</button>
35+
<button nz-button
36+
nzSize="small"
37+
(click)="cancel()">
38+
<i nz-icon nzType="close" nzTheme="outline"></i>
39+
Cancel
40+
</button>
41+
</div>
42+
</ng-template>
43+
<h3>Setting</h3>
44+
<form nz-form>
45+
<nz-table nzTemplateMode nzSize="small">
46+
<thead>
47+
<tr>
48+
<th>Name</th>
49+
<th>Value</th>
50+
</tr>
51+
</thead>
52+
<tbody>
53+
<tr *ngFor="let setting of repo.settings; index as i">
54+
<td>{{setting.name}}</td>
55+
<ng-container *ngIf="!editMode">
56+
<td>{{setting.selected}}</td>
57+
</ng-container>
58+
<ng-container *ngIf="editMode">
59+
<td>
60+
<input *ngIf="setting.type === 'INPUT'"
61+
nzSize="small"
62+
nz-input
63+
[formControl]="settingFormArray.controls[i]">
64+
65+
<nz-select *ngIf="setting.type === 'DROPDOWN'" [formControl]="settingFormArray.controls[i]">
66+
<nz-option
67+
*ngFor="let option of setting.value"
68+
[nzLabel]="option"
69+
[nzValue]="option">
70+
</nz-option>
71+
</nz-select>
72+
</td>
73+
</ng-container>
74+
</tr>
75+
</tbody>
76+
</nz-table>
77+
</form>
78+
79+
</nz-card>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License.
11+
*/
12+
13+
@import 'theme-mixin';
14+
15+
.themeMixin({
16+
17+
display: block;
18+
margin-bottom: @card-padding-base;
19+
position: relative;
20+
21+
::ng-deep .repo-item {
22+
&.edit {
23+
background: @orange-1;
24+
}
25+
}
26+
27+
.extra-wrap {
28+
button {
29+
transition: none;
30+
}
31+
button + button {
32+
margin-bottom: 0;
33+
margin-left: 8px;
34+
}
35+
}
36+
37+
});
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License.
11+
*/
12+
import {
13+
ChangeDetectionStrategy,
14+
ChangeDetectorRef,
15+
Component,
16+
EventEmitter,
17+
Input,
18+
OnChanges,
19+
Output,
20+
SimpleChanges
21+
} from '@angular/core';
22+
import { FormArray, FormBuilder, Validators } from '@angular/forms';
23+
import { NotebookRepo } from '@zeppelin/interfaces';
24+
25+
@Component({
26+
selector: 'zeppelin-notebook-repo-item',
27+
templateUrl: './item.component.html',
28+
styleUrls: ['./item.component.less'],
29+
changeDetection: ChangeDetectionStrategy.OnPush
30+
})
31+
export class NotebookRepoItemComponent implements OnChanges {
32+
@Input() repo: NotebookRepo;
33+
@Output() readonly repoChange = new EventEmitter<NotebookRepo>();
34+
35+
settingFormArray: FormArray;
36+
editMode = false;
37+
38+
constructor(private cdr: ChangeDetectorRef, private fb: FormBuilder) {}
39+
40+
triggerEditMode() {
41+
this.editMode = !this.editMode;
42+
this.cdr.markForCheck();
43+
}
44+
45+
save() {
46+
this.settingFormArray.controls.forEach(control => {
47+
control.markAsDirty();
48+
control.updateValueAndValidity();
49+
});
50+
51+
if (this.settingFormArray.valid) {
52+
const values = this.settingFormArray.getRawValue() as string[];
53+
values.forEach((value, i) => (this.repo.settings[i].selected = value));
54+
this.repoChange.emit(this.repo);
55+
this.editMode = false;
56+
this.cdr.markForCheck();
57+
}
58+
}
59+
60+
cancel() {
61+
this.buildForm();
62+
this.editMode = false;
63+
this.cdr.markForCheck();
64+
}
65+
66+
buildForm() {
67+
const controls = this.repo.settings.map(setting => {
68+
return this.fb.control(setting.selected, [Validators.required]);
69+
});
70+
this.settingFormArray = this.fb.array(controls);
71+
}
72+
73+
ngOnChanges(changes: SimpleChanges): void {
74+
if (changes.repo) {
75+
this.buildForm();
76+
}
77+
}
78+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License.
11+
*/
12+
import { NgModule } from '@angular/core';
13+
import { RouterModule, Routes } from '@angular/router';
14+
15+
import { NotebookReposComponent } from './notebook-repos.component';
16+
17+
const routes: Routes = [
18+
{
19+
path: '',
20+
component: NotebookReposComponent
21+
}
22+
];
23+
24+
@NgModule({
25+
imports: [RouterModule.forChild(routes)],
26+
exports: [RouterModule]
27+
})
28+
export class NotebookReposRoutingModule {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!--
2+
~ Licensed under the Apache License, Version 2.0 (the "License");
3+
~ you may not use this file except in compliance with the License.
4+
~ You may obtain a copy of the License at
5+
~ http://www.apache.org/licenses/LICENSE-2.0
6+
~ Unless required by applicable law or agreed to in writing, software
7+
~ distributed under the License is distributed on an "AS IS" BASIS,
8+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
~ See the License for the specific language governing permissions and
10+
~ limitations under the License.
11+
-->
12+
<zeppelin-page-header title="Notebook Repository" description="Manage your Notebook Repositories' settings.">
13+
</zeppelin-page-header>
14+
<div class="content">
15+
<zeppelin-notebook-repo-item
16+
*ngFor="let repo of repositories"
17+
(repoChange)="updateRepoSetting($event)"
18+
[repo]="repo">
19+
20+
</zeppelin-notebook-repo-item>
21+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License.
11+
*/
12+
13+
@import 'theme-mixin';
14+
15+
.themeMixin({
16+
17+
.content {
18+
padding: @card-padding-base / 2;
19+
}
20+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License.
11+
*/
12+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
13+
import { NotebookRepo } from '@zeppelin/interfaces';
14+
import { NotebookRepoService } from '@zeppelin/services';
15+
16+
@Component({
17+
selector: 'zeppelin-notebook-repos',
18+
templateUrl: './notebook-repos.component.html',
19+
styleUrls: ['./notebook-repos.component.less'],
20+
changeDetection: ChangeDetectionStrategy.OnPush
21+
})
22+
export class NotebookReposComponent implements OnInit {
23+
repositories: NotebookRepo[] = [];
24+
25+
constructor(private notebookRepoService: NotebookRepoService, private cdr: ChangeDetectorRef) {}
26+
27+
ngOnInit() {
28+
this.getRepos();
29+
}
30+
31+
getRepos() {
32+
this.notebookRepoService.getRepos().subscribe(data => {
33+
this.repositories = data.sort((a, b) => a.name.charCodeAt(0) - b.name.charCodeAt(0));
34+
this.cdr.markForCheck();
35+
});
36+
}
37+
38+
updateRepoSetting(repo: NotebookRepo) {
39+
const data = {
40+
name: repo.className,
41+
settings: {}
42+
};
43+
repo.settings.forEach(({ name, selected }) => {
44+
data.settings[name] = selected;
45+
});
46+
47+
this.notebookRepoService.updateRepo(data).subscribe(() => {
48+
this.getRepos();
49+
});
50+
}
51+
}

0 commit comments

Comments
 (0)