mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-20 07:37:38 +01:00
Updates for project actions.
This commit is contained in:
parent
7795850e07
commit
98927cf72e
@ -0,0 +1,11 @@
|
|||||||
|
<clr-dropdown [clrMenuPosition]="'bottom-right'" [clrCloseMenuOnItemClick]="true">
|
||||||
|
<button clrDropdownToggle>
|
||||||
|
<clr-icon shape="ellipses-vertical"></clr-icon>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<a href="javascript:void(0)" clrDropdownItem>New Policy</a>
|
||||||
|
<a href="javascript:void(0)" clrDropdownItem (click)="toggle()">Make {{project.public === 0 ? 'Public' : 'Private'}} </a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a href="javascript:void(0)" clrDropdownItem (click)="delete()">Delete</a>
|
||||||
|
</div>
|
||||||
|
</clr-dropdown>
|
@ -0,0 +1,30 @@
|
|||||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
import { Project } from '../project';
|
||||||
|
import { ProjectService } from '../project.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'action-project',
|
||||||
|
templateUrl: 'action-project.component.html'
|
||||||
|
})
|
||||||
|
export class ActionProjectComponent {
|
||||||
|
|
||||||
|
@Output() togglePublic = new EventEmitter<Project>();
|
||||||
|
@Output() deleteProject = new EventEmitter<Project>();
|
||||||
|
|
||||||
|
@Input() project: Project;
|
||||||
|
|
||||||
|
constructor(private projectService: ProjectService) {}
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
if(this.project) {
|
||||||
|
this.project.public === 0 ? this.project.public = 1 : this.project.public = 0;
|
||||||
|
this.togglePublic.emit(this.project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete() {
|
||||||
|
if(this.project) {
|
||||||
|
this.deleteProject.emit(this.project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,4 +27,3 @@
|
|||||||
<button type="button" class="btn btn-primary" (click)="onSubmit()">Ok</button>
|
<button type="button" class="btn btn-primary" (click)="onSubmit()">Ok</button>
|
||||||
</div>
|
</div>
|
||||||
</clr-modal>
|
</clr-modal>
|
||||||
<button class="btn btn-sm" (click)="newProject()">New Project</button>
|
|
@ -4,6 +4,7 @@ import { Response } from '@angular/http';
|
|||||||
import { Project } from '../project';
|
import { Project } from '../project';
|
||||||
import { ProjectService } from '../project.service';
|
import { ProjectService } from '../project.service';
|
||||||
|
|
||||||
|
import { MessageService } from '../../global-message/message.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'create-project',
|
selector: 'create-project',
|
||||||
@ -19,13 +20,13 @@ export class CreateProjectComponent {
|
|||||||
hasError: boolean;
|
hasError: boolean;
|
||||||
|
|
||||||
@Output() create = new EventEmitter<boolean>();
|
@Output() create = new EventEmitter<boolean>();
|
||||||
|
|
||||||
constructor(private projectService: ProjectService) {}
|
constructor(private projectService: ProjectService, private messageService: MessageService) {}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.hasError = false;
|
this.hasError = false;
|
||||||
this.projectService
|
this.projectService
|
||||||
.createProject(this.project.name, this.project.public)
|
.createProject(this.project.name, this.project.public ? 1 : 0)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
status=>{
|
status=>{
|
||||||
this.create.emit(true);
|
this.create.emit(true);
|
||||||
@ -33,7 +34,7 @@ export class CreateProjectComponent {
|
|||||||
},
|
},
|
||||||
error=>{
|
error=>{
|
||||||
this.hasError = true;
|
this.hasError = true;
|
||||||
if (error instanceof Response) {
|
if (error instanceof Response) {
|
||||||
switch(error.status) {
|
switch(error.status) {
|
||||||
case 409:
|
case 409:
|
||||||
this.errorMessage = 'Project name already exists.'; break;
|
this.errorMessage = 'Project name already exists.'; break;
|
||||||
@ -41,6 +42,7 @@ export class CreateProjectComponent {
|
|||||||
this.errorMessage = 'Project name is illegal.'; break;
|
this.errorMessage = 'Project name is illegal.'; break;
|
||||||
default:
|
default:
|
||||||
this.errorMessage = 'Unknown error for project name.';
|
this.errorMessage = 'Unknown error for project name.';
|
||||||
|
this.messageService.announceMessage(this.errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<clr-dropdown [clrMenuPosition]="'bottom-left'">
|
<clr-dropdown [clrMenuPosition]="'bottom-left'">
|
||||||
<button class="btn btn-sm btn-outline-primary" clrDropdownToggle>
|
<button class="btn btn-sm btn-link" clrDropdownToggle>
|
||||||
{{currentType.value}}
|
{{currentType.value}}
|
||||||
<clr-icon shape="caret down"></clr-icon>
|
<clr-icon shape="caret down"></clr-icon>
|
||||||
</button>
|
</button>
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
<clr-datagrid>
|
<clr-datagrid [(clrDgSelected)]="selected">
|
||||||
<clr-dg-column>Name</clr-dg-column>
|
<clr-dg-column>Name</clr-dg-column>
|
||||||
<clr-dg-column>Public/Private</clr-dg-column>
|
<clr-dg-column>Public/Private</clr-dg-column>
|
||||||
<clr-dg-column>Repositories</clr-dg-column>
|
<clr-dg-column>Repositories</clr-dg-column>
|
||||||
<clr-dg-column>Creation time</clr-dg-column>
|
<clr-dg-column>Creation time</clr-dg-column>
|
||||||
<clr-dg-column>Destination</clr-dg-column>
|
<clr-dg-column>Description</clr-dg-column>
|
||||||
<clr-dg-column>Owner</clr-dg-column>
|
<clr-dg-row *clrDgItems="let p of projects" [clrDgItem]="p" [(clrDgSelected)]="p.selected">
|
||||||
<clr-dg-column>Description</clr-dg-column>
|
<!--<clr-dg-action-overflow>
|
||||||
<clr-dg-row *ngFor="let p of projects">
|
<button class="action-item" (click)="onEdit(p)">Edit</button>
|
||||||
|
<button class="action-item" (click)="onDelete(p)">Delete</button>
|
||||||
|
</clr-dg-action-overflow>-->
|
||||||
<clr-dg-cell><a [routerLink]="['/harbor', 'projects', p.id, 'repository']" >{{p.name}}</a></clr-dg-cell>
|
<clr-dg-cell><a [routerLink]="['/harbor', 'projects', p.id, 'repository']" >{{p.name}}</a></clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.public == 1 ? 'Public': 'Private'}}</clr-dg-cell>
|
<clr-dg-cell>{{p.public == 1 ? 'Public': 'Private'}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.repo_count}}</clr-dg-cell>
|
<clr-dg-cell>{{p.repo_count}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.creation_time}}</clr-dg-cell>
|
<clr-dg-cell>{{p.creation_time}}</clr-dg-cell>
|
||||||
<clr-dg-cell>--</clr-dg-cell>
|
<clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.owner}}</clr-dg-cell>
|
{{p.description}}
|
||||||
<clr-dg-cell>{{p.description}}</clr-dg-cell>
|
<span style="float: right;">
|
||||||
|
<action-project (togglePublic)="toggleProject($event)" (deleteProject)="deleteProject($event)" [project]="p"></action-project>
|
||||||
|
</span>
|
||||||
|
</clr-dg-cell>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
<clr-dg-footer>{{ (projects ? projects.length : 0) }} item(s)</clr-dg-footer>
|
<clr-dg-footer>{{ (projects ? projects.length : 0) }} item(s)</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, EventEmitter, Output } from '@angular/core';
|
||||||
import { Project } from '../project';
|
import { Project } from '../project';
|
||||||
import { ProjectService } from '../project.service';
|
import { ProjectService } from '../project.service';
|
||||||
|
|
||||||
@ -12,6 +12,10 @@ export class ListProjectComponent {
|
|||||||
projects: Project[];
|
projects: Project[];
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
|
|
||||||
|
selected = [];
|
||||||
|
|
||||||
|
@Output() actionPerform = new EventEmitter<boolean>();
|
||||||
|
|
||||||
constructor(private projectService: ProjectService) {}
|
constructor(private projectService: ProjectService) {}
|
||||||
|
|
||||||
retrieve(name: string, isPublic: number): void {
|
retrieve(name: string, isPublic: number): void {
|
||||||
@ -21,4 +25,37 @@ export class ListProjectComponent {
|
|||||||
response => this.projects = response,
|
response => this.projects = response,
|
||||||
error => this.errorMessage = <any>error);
|
error => this.errorMessage = <any>error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleProject(p: Project) {
|
||||||
|
this.projectService
|
||||||
|
.toggleProjectPublic(p.project_id, p.public)
|
||||||
|
.subscribe(
|
||||||
|
response=>console.log(response),
|
||||||
|
error=>console.log(error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteProject(p: Project) {
|
||||||
|
this.projectService
|
||||||
|
.deleteProject(p.project_id)
|
||||||
|
.subscribe(
|
||||||
|
response=>{
|
||||||
|
console.log(response);
|
||||||
|
this.actionPerform.emit(true);
|
||||||
|
},
|
||||||
|
error=>console.log(error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteSelectedProjects() {
|
||||||
|
this.selected.forEach(p=>this.deleteProject(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
onEdit(p: Project) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onDelete(p: Project) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,13 +1,15 @@
|
|||||||
<h3>Projects</h3>
|
<h3>Projects</h3>
|
||||||
<div class="row flex-items-xs-between">
|
<div class="row flex-items-xs-between">
|
||||||
<div class="col-xs-4">
|
<div class="col-xs-4">
|
||||||
<create-project (create)="createProject($event)"></create-project>
|
<button class="btn btn-link" (click)="openModal()"><clr-icon shape="add"></clr-icon>New Project</button>
|
||||||
|
<button class="btn btn-link" (click)="deleteSelectedProjects()"><clr-icon shape="close"></clr-icon>Delete</button>
|
||||||
|
<create-project (create)="createProject($event)" (openModal)="openModal($event)"></create-project>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-4">
|
<div class="col-xs-4">
|
||||||
<filter-project (filter)="filterProjects($event)"></filter-project>
|
<filter-project (filter)="filterProjects($event)"></filter-project>
|
||||||
<search-project (search)="searchProjects($event)"></search-project>
|
<search-project (search)="searchProjects($event)"></search-project>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||||
<list-project></list-project>
|
<list-project (actionPerform)="actionPerform($event)"></list-project>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -3,6 +3,7 @@ import { Component, OnInit, ViewChild } from '@angular/core';
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { ListProjectComponent } from './list-project/list-project.component';
|
import { ListProjectComponent } from './list-project/list-project.component';
|
||||||
|
import { CreateProjectComponent } from './create-project/create-project.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'project',
|
selector: 'project',
|
||||||
@ -13,8 +14,20 @@ export class ProjectComponent implements OnInit {
|
|||||||
|
|
||||||
@ViewChild(ListProjectComponent)
|
@ViewChild(ListProjectComponent)
|
||||||
listProjects: ListProjectComponent;
|
listProjects: ListProjectComponent;
|
||||||
|
|
||||||
|
@ViewChild(CreateProjectComponent)
|
||||||
|
creationProject: CreateProjectComponent;
|
||||||
|
|
||||||
lastFilteredType: number = 0;
|
lastFilteredType: number = 0;
|
||||||
|
|
||||||
|
openModal(): void {
|
||||||
|
this.creationProject.newProject();
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteSelectedProjects(): void {
|
||||||
|
this.listProjects.deleteSelectedProjects();
|
||||||
|
}
|
||||||
|
|
||||||
createProject(created: boolean): void {
|
createProject(created: boolean): void {
|
||||||
console.log('Project has been created:' + created);
|
console.log('Project has been created:' + created);
|
||||||
this.listProjects.retrieve('', 0);
|
this.listProjects.retrieve('', 0);
|
||||||
@ -32,6 +45,10 @@ export class ProjectComponent implements OnInit {
|
|||||||
this.listProjects.retrieve(projectName, this.lastFilteredType);
|
this.listProjects.retrieve(projectName, this.lastFilteredType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionPerform(performed: boolean): void {
|
||||||
|
this.listProjects.retrieve('', 0);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.listProjects.retrieve('', 0);
|
this.listProjects.retrieve('', 0);
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,15 @@ import { ProjectComponent } from './project.component';
|
|||||||
import { CreateProjectComponent } from './create-project/create-project.component';
|
import { CreateProjectComponent } from './create-project/create-project.component';
|
||||||
import { SearchProjectComponent } from './search-project/search-project.component';
|
import { SearchProjectComponent } from './search-project/search-project.component';
|
||||||
import { FilterProjectComponent } from './filter-project/filter-project.component';
|
import { FilterProjectComponent } from './filter-project/filter-project.component';
|
||||||
|
import { ActionProjectComponent } from './action-project/action-project.component';
|
||||||
import { ListProjectComponent } from './list-project/list-project.component';
|
import { ListProjectComponent } from './list-project/list-project.component';
|
||||||
import { ProjectDetailComponent } from './project-detail/project-detail.component';
|
import { ProjectDetailComponent } from './project-detail/project-detail.component';
|
||||||
|
|
||||||
import { MemberComponent } from './member/member.component';
|
import { MemberComponent } from './member/member.component';
|
||||||
import { ProjectRoutingModule } from './project-routing.module';
|
import { ProjectRoutingModule } from './project-routing.module';
|
||||||
|
|
||||||
import { ProjectService } from './project.service';
|
import { ProjectService } from './project.service';
|
||||||
|
import { DATAGRID_DIRECTIVES } from 'clarity-angular';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -29,9 +32,10 @@ import { ProjectService } from './project.service';
|
|||||||
CreateProjectComponent,
|
CreateProjectComponent,
|
||||||
SearchProjectComponent,
|
SearchProjectComponent,
|
||||||
FilterProjectComponent,
|
FilterProjectComponent,
|
||||||
|
ActionProjectComponent,
|
||||||
ListProjectComponent,
|
ListProjectComponent,
|
||||||
ProjectDetailComponent,
|
ProjectDetailComponent,
|
||||||
MemberComponent
|
MemberComponent
|
||||||
],
|
],
|
||||||
exports: [ ListProjectComponent ],
|
exports: [ ListProjectComponent ],
|
||||||
providers: [ ProjectService ]
|
providers: [ ProjectService ]
|
||||||
|
@ -8,6 +8,7 @@ import { BaseService } from '../service/base.service';
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import 'rxjs/add/operator/catch';
|
import 'rxjs/add/operator/catch';
|
||||||
import 'rxjs/add/operator/map';
|
import 'rxjs/add/operator/map';
|
||||||
|
import 'rxjs/add/observable/throw';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectService extends BaseService {
|
export class ProjectService extends BaseService {
|
||||||
@ -29,10 +30,23 @@ export class ProjectService extends BaseService {
|
|||||||
createProject(name: string, isPublic: number): Observable<any> {
|
createProject(name: string, isPublic: number): Observable<any> {
|
||||||
return this.http
|
return this.http
|
||||||
.post(`/ng/api/projects`,
|
.post(`/ng/api/projects`,
|
||||||
JSON.stringify({'project_name': name, 'public': (isPublic ? 1 : 0)})
|
JSON.stringify({'project_name': name, 'public': isPublic})
|
||||||
, this.options)
|
, this.options)
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
.catch(error=>Observable.throw(error));
|
.catch(error=>Observable.throw(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleProjectPublic(projectId: number, isPublic: number): Observable<any> {
|
||||||
|
return this.http
|
||||||
|
.put(`/ng/api/projects/${projectId}/publicity`, { 'public': isPublic }, this.options)
|
||||||
|
.map(response=>response.status)
|
||||||
|
.catch(error=>Observable.throw(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteProject(projectId: number): Observable<any> {
|
||||||
|
return this.http
|
||||||
|
.delete(`/ng/api/projects/${projectId}`)
|
||||||
|
.map(response=>response.status)
|
||||||
|
.catch(error=>Observable.throw(error));
|
||||||
|
}
|
||||||
}
|
}
|
@ -29,4 +29,5 @@ export class Project {
|
|||||||
update_time: Date;
|
update_time: Date;
|
||||||
current_user_role_id: number;
|
current_user_role_id: number;
|
||||||
repo_count: number;
|
repo_count: number;
|
||||||
|
selected: boolean;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user