mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-18 14:47:38 +01:00
Merge pull request #12988 from AllForNothing/test-4
Fix UI issues found on testing day
This commit is contained in:
commit
5586fe86bf
@ -265,7 +265,7 @@ export class ConfigurationAuthComponent implements OnChanges, OnInit {
|
||||
}
|
||||
changeAutoOnBoard() {
|
||||
if (!this.currentConfig.oidc_auto_onboard.value) {
|
||||
this.currentConfig.oidc_user_claim.value = null;
|
||||
this.currentConfig.oidc_user_claim.value = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@
|
||||
<label for="create_project_storage_limit" class="clr-control-label"></label>
|
||||
<div class="clr-control-container">
|
||||
<div class="clr-input-wrapper">
|
||||
<label class="clr-control-label endpoint">{{ 'PROJECT.ENDPOINT' | translate }}</label>
|
||||
<label class="clr-control-label endpoint required">{{ 'PROJECT.ENDPOINT' | translate }}</label>
|
||||
<input placeholder="http(s)://192.168.1.1" [value]="getEndpoint()" readonly class="clr-input" type="text" id="endpoint"
|
||||
autocomplete="off">
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@
|
||||
// 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 { Subscription, forkJoin } from "rxjs";
|
||||
import {Subscription, forkJoin, of} from "rxjs";
|
||||
import {
|
||||
Component,
|
||||
Output,
|
||||
@ -35,6 +35,7 @@ import { calculatePage, CustomComparator, doFiltering, doSorting } from "../../.
|
||||
import { OperationService } from "../../../lib/components/operation/operation.service";
|
||||
import { operateChanges, OperateInfo, OperationState } from "../../../lib/components/operation/operate";
|
||||
import { errorHandler } from "../../../lib/utils/shared/shared.utils";
|
||||
import {HttpErrorResponse} from "@angular/common/http";
|
||||
|
||||
@Component({
|
||||
selector: "list-project",
|
||||
@ -204,10 +205,22 @@ export class ListProjectComponent implements OnDestroy {
|
||||
projects.forEach(data => {
|
||||
observableLists.push(this.delOperate(data));
|
||||
});
|
||||
forkJoin(...observableLists).subscribe(item => {
|
||||
forkJoin(...observableLists).subscribe(resArr => {
|
||||
let error;
|
||||
if (resArr && resArr.length) {
|
||||
resArr.forEach(item => {
|
||||
if (item instanceof HttpErrorResponse) {
|
||||
error = errorHandler(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (error) {
|
||||
this.msgHandler.handleError(error);
|
||||
} else {
|
||||
this.translate.get("BATCH.DELETED_SUCCESS").subscribe(res => {
|
||||
this.msgHandler.showSuccess(res);
|
||||
});
|
||||
}
|
||||
let st: State = this.getStateAfterDeletion();
|
||||
this.selectedRow = [];
|
||||
if (!st) {
|
||||
@ -216,8 +229,6 @@ export class ListProjectComponent implements OnDestroy {
|
||||
this.clrLoad(st);
|
||||
this.statisticHandler.refresh();
|
||||
}
|
||||
}, error => {
|
||||
this.msgHandler.handleError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -237,10 +248,10 @@ export class ListProjectComponent implements OnDestroy {
|
||||
}), catchError(
|
||||
error => {
|
||||
const message = errorHandler(error);
|
||||
this.translateService.get(message).subscribe(res =>
|
||||
operateChanges(operMessage, OperationState.failure, res)
|
||||
);
|
||||
return observableThrowError(error);
|
||||
this.translateService.get(message).subscribe(res => {
|
||||
operateChanges(operMessage, OperationState.failure, res);
|
||||
});
|
||||
return of(error);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 config-top ">
|
||||
<hbr-project-policy-config [projectId]="projectId" [projectName]="projectName" [hasSignedIn]="hasSignedIn"></hbr-project-policy-config>
|
||||
<hbr-project-policy-config [projectId]="projectId" [projectName]="projectName" [isProxyCacheProject]="isProxyCacheProject" [hasSignedIn]="hasSignedIn"></hbr-project-policy-config>
|
||||
</div>
|
||||
</div>
|
@ -28,7 +28,7 @@ export class ProjectConfigComponent implements OnInit {
|
||||
projectName: string;
|
||||
currentUser: SessionUser;
|
||||
hasSignedIn: boolean;
|
||||
|
||||
isProxyCacheProject: boolean = false;
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
@ -42,6 +42,9 @@ export class ProjectConfigComponent implements OnInit {
|
||||
if (resolverData) {
|
||||
let pro: Project = <Project>resolverData['projectResolver'];
|
||||
this.projectName = pro.name;
|
||||
if (pro.registry_id) {
|
||||
this.isProxyCacheProject = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
<ng-container *ngIf="!loading">
|
||||
<!-- tags -->
|
||||
<artifact-tag [artifactDetails]="artifact" [projectName]="projectName" [projectId]="projectId" [repositoryName]="repositoryName"
|
||||
<artifact-tag [artifactDetails]="artifact" [projectName]="projectName" [isProxyCacheProject]="isProxyCacheProject" [projectId]="projectId" [repositoryName]="repositoryName"
|
||||
></artifact-tag>
|
||||
|
||||
<!-- Overview -->
|
||||
|
@ -30,6 +30,7 @@ export class ArtifactSummaryComponent implements OnInit {
|
||||
@Output()
|
||||
backEvt: EventEmitter<any> = new EventEmitter<any>();
|
||||
projectName: string;
|
||||
isProxyCacheProject: boolean = false;
|
||||
loading: boolean = false;
|
||||
|
||||
constructor(
|
||||
@ -80,6 +81,9 @@ export class ArtifactSummaryComponent implements OnInit {
|
||||
if (resolverData) {
|
||||
const pro: Project = <Project>(resolverData['artifactResolver'][1]);
|
||||
this.projectName = pro.name;
|
||||
if (pro.registry_id) {
|
||||
this.isProxyCacheProject = true;
|
||||
}
|
||||
this.artifact = <Artifact>(resolverData['artifactResolver'][0]);
|
||||
this.getIconFromBackEnd();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<clr-datagrid [clrDgLoading]="loading" (clrDgRefresh)="getCurrentArtifactTags($event)" [(clrDgSelected)]="selectedRow">
|
||||
<clr-dg-action-bar>
|
||||
<button id="new-tag" type="button" [disabled]="!hasCreateTagPermission" class="btn btn-secondary" (click)="addTag()">
|
||||
<button *ngIf="!isProxyCacheProject" id="new-tag" type="button" [disabled]="!hasCreateTagPermission" class="btn btn-secondary" (click)="addTag()">
|
||||
<clr-icon shape="plus" size="16"></clr-icon> {{'TAG.ADD_TAG' | translate}}
|
||||
</button>
|
||||
<button id="delete-tag" type="button" class="btn btn-secondary" [disabled]="!(selectedRow.length>=1&& !hasImmutableOnTag() && hasDeleteTagPermission)" (click)="removeTag()">
|
||||
|
@ -34,7 +34,7 @@ class InitTag {
|
||||
name = "";
|
||||
}
|
||||
const DeleteTagWithNotoryCommand1 = 'notary -s https://';
|
||||
const DeleteTagWithNotoryCommand2 = ':4443 -d ~/.docker/trust remove -p ';
|
||||
const DeleteTagWithNotoryCommand2 = ' -d ~/.docker/trust remove -p ';
|
||||
@Component({
|
||||
selector: 'artifact-tag',
|
||||
templateUrl: './artifact-tag.component.html',
|
||||
@ -43,6 +43,7 @@ const DeleteTagWithNotoryCommand2 = ':4443 -d ~/.docker/trust remove -p ';
|
||||
export class ArtifactTagComponent implements OnInit, OnDestroy {
|
||||
@Input() artifactDetails: Artifact;
|
||||
@Input() projectName: string;
|
||||
@Input() isProxyCacheProject: boolean = false;
|
||||
@Input() projectId: number;
|
||||
@Input() repositoryName: string;
|
||||
newTagName = new InitTag();
|
||||
|
@ -9,11 +9,11 @@ import {
|
||||
SimpleChanges,
|
||||
Inject, OnDestroy
|
||||
} from "@angular/core";
|
||||
import { forkJoin, Subscription } from "rxjs";
|
||||
import {forkJoin, of, Subscription} from "rxjs";
|
||||
import { debounceTime, distinctUntilChanged, switchMap } from "rxjs/operators";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { map, catchError } from "rxjs/operators";
|
||||
import { Observable, throwError as observableThrowError } from "rxjs";
|
||||
import { Observable } from "rxjs";
|
||||
import { ClrDatagridStateInterface } from "@clr/angular";
|
||||
import {
|
||||
RepositoryService as NewRepositoryService
|
||||
@ -49,6 +49,7 @@ import { SessionService } from "../../shared/session.service";
|
||||
import { GridViewComponent } from "./gridview/grid-view.component";
|
||||
import { Repository as NewRepository } from "../../../../ng-swagger-gen/models/repository";
|
||||
import { StrictHttpResponse as __StrictHttpResponse } from '../../../../ng-swagger-gen/strict-http-response';
|
||||
import {HttpErrorResponse} from "@angular/common/http";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -192,8 +193,6 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy
|
||||
}
|
||||
|
||||
confirmDeletion(message: ConfirmationAcknowledgement) {
|
||||
this.loading = true;
|
||||
// forkJoin(...repArr).subscribe(() => {
|
||||
if (message &&
|
||||
message.source === ConfirmationTargets.REPOSITORY &&
|
||||
message.state === ConfirmationState.CONFIRMED) {
|
||||
@ -203,19 +202,29 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy
|
||||
repoLists.forEach(repo => {
|
||||
observableLists.push(this.delOperate(repo));
|
||||
});
|
||||
forkJoin(observableLists).subscribe((item) => {
|
||||
forkJoin(observableLists).subscribe(resArr => {
|
||||
let error;
|
||||
if (resArr && resArr.length) {
|
||||
resArr.forEach(item => {
|
||||
if (item instanceof HttpErrorResponse) {
|
||||
error = errorHandler(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (error) {
|
||||
this.errorHandlerService.error(error);
|
||||
} else {
|
||||
this.translateService.get("BATCH.DELETED_SUCCESS").subscribe(res => {
|
||||
this.errorHandlerService.info(res);
|
||||
});
|
||||
}
|
||||
this.selectedRow = [];
|
||||
this.refresh();
|
||||
let st: ClrDatagridStateInterface = this.getStateAfterDeletion();
|
||||
if (!st) {
|
||||
this.refresh();
|
||||
} else {
|
||||
this.clrLoad(st);
|
||||
}
|
||||
}, error => {
|
||||
this.errorHandlerService.error(error);
|
||||
this.loading = false;
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -243,10 +252,10 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit, OnDestroy
|
||||
});
|
||||
}), catchError(error => {
|
||||
const message = errorHandler(error);
|
||||
this.translateService.get(message).subscribe(res =>
|
||||
operateChanges(operMessage, OperationState.failure, res)
|
||||
);
|
||||
return observableThrowError(error);
|
||||
this.translateService.get(message).subscribe(res => {
|
||||
operateChanges(operMessage, OperationState.failure, res);
|
||||
});
|
||||
return of(error);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell class="hand" (click)="openDetail(i,execution.id)">{{execution.status}}</clr-dg-cell>
|
||||
<clr-dg-cell class="hand"
|
||||
(click)="openDetail(i,execution.id)">{{execution.dry_run ? 'YES' : 'NO'}}</clr-dg-cell>
|
||||
(click)="openDetail(i,execution.id)">{{(execution.dry_run ? 'TAG_RETENTION.YES' : 'TAG_RETENTION.NO') | translate}}</clr-dg-cell>
|
||||
<clr-dg-cell class="hand"
|
||||
(click)="openDetail(i,execution.id)">{{execution.trigger}}</clr-dg-cell>
|
||||
<clr-dg-cell class="hand"
|
||||
|
@ -85,7 +85,7 @@ body {
|
||||
}
|
||||
|
||||
.color-green {
|
||||
color: #1d5100;
|
||||
color: #00d40f;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
|
@ -1330,7 +1330,9 @@
|
||||
"COUNT_LARGE": "Parameter \"COUNT\" is too large",
|
||||
"DAYS_LARGE": "Parameter \"DAYS\" is too large",
|
||||
"EXECUTION_TYPE": "Execution Type",
|
||||
"ACTION": "ACTION"
|
||||
"ACTION": "ACTION",
|
||||
"YES": "Yes",
|
||||
"NO": "No"
|
||||
},
|
||||
"IMMUTABLE_TAG": {
|
||||
"IMMUTABLE_RULES": "Immutability rules",
|
||||
|
@ -1328,7 +1328,9 @@
|
||||
"COUNT_LARGE": "Parameter \"COUNT\" is too large",
|
||||
"DAYS_LARGE": "Parameter \"DAYS\" is too large",
|
||||
"EXECUTION_TYPE": "Execution Type",
|
||||
"ACTION": "ACTION"
|
||||
"ACTION": "ACTION",
|
||||
"YES": "Yes",
|
||||
"NO": "No"
|
||||
},
|
||||
"IMMUTABLE_TAG": {
|
||||
"IMMUTABLE_RULES": "Immutability rules",
|
||||
|
@ -1298,7 +1298,9 @@
|
||||
"COUNT_LARGE": "Parameter \"COUNT\" is too large",
|
||||
"DAYS_LARGE": "Parameter \"DAYS\" is too large",
|
||||
"EXECUTION_TYPE": "Execution Type",
|
||||
"ACTION": "ACTION"
|
||||
"ACTION": "ACTION",
|
||||
"YES": "Yes",
|
||||
"NO": "No"
|
||||
},
|
||||
"IMMUTABLE_TAG": {
|
||||
"IMMUTABLE_RULES": "Immutability rules",
|
||||
|
@ -1326,7 +1326,9 @@
|
||||
"COUNT_LARGE": "Parameter \"COUNT\" is too large",
|
||||
"DAYS_LARGE": "Parameter \"DAYS\" is too large",
|
||||
"EXECUTION_TYPE": "Execution Type",
|
||||
"ACTION": "ACTION"
|
||||
"ACTION": "ACTION",
|
||||
"YES": "Yes",
|
||||
"NO": "No"
|
||||
},
|
||||
"IMMUTABLE_TAG": {
|
||||
"IMMUTABLE_RULES": "Immutability rules",
|
||||
|
@ -1330,7 +1330,9 @@
|
||||
"COUNT_LARGE": "Parameter \"COUNT\" is too large",
|
||||
"DAYS_LARGE": "Parameter \"DAYS\" is too large",
|
||||
"EXECUTION_TYPE": "Execution Type",
|
||||
"ACTION": "ACTION"
|
||||
"ACTION": "ACTION",
|
||||
"YES": "Yes",
|
||||
"NO": "No"
|
||||
},
|
||||
"IMMUTABLE_TAG": {
|
||||
"IMMUTABLE_RULES": "Immutability rules",
|
||||
|
@ -1327,7 +1327,9 @@
|
||||
"COUNT_LARGE": "参数“个数”太大",
|
||||
"DAYS_LARGE": "参数“天数”太大",
|
||||
"EXECUTION_TYPE": "执行类型",
|
||||
"ACTION": "操作"
|
||||
"ACTION": "操作",
|
||||
"YES": "是",
|
||||
"NO": "否"
|
||||
},
|
||||
"IMMUTABLE_TAG": {
|
||||
"IMMUTABLE_RULES": "不可变的 Tag 规则",
|
||||
|
@ -1314,7 +1314,9 @@
|
||||
"COUNT_LARGE": "參數“個數”太大",
|
||||
"DAYS_LARGE": "參數“天數”太大",
|
||||
"EXECUTION_TYPE": "執行類型",
|
||||
"ACTION": "操作"
|
||||
"ACTION": "操作",
|
||||
"YES": "Yes",
|
||||
"NO": "No"
|
||||
},
|
||||
"IMMUTABLE_TAG": {
|
||||
"IMMUTABLE_RULES": "不可變的 Tag 規則",
|
||||
|
@ -13,7 +13,7 @@
|
||||
<clr-dg-row *ngFor="let job of jobs" [clrDgItem]='job'>
|
||||
<clr-dg-cell>{{job.id }}</clr-dg-cell>
|
||||
<clr-dg-cell>{{(job.type ? 'SCHEDULE.'+ job.type.toUpperCase() : '') | translate }}</clr-dg-cell>
|
||||
<clr-dg-cell>{{isDryRun(job?.parameters)}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{isDryRun(job?.parameters) | translate}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{job.status.toUpperCase() | translate}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{job.createTime | date:'medium'}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{job.updateTime | date:'medium'}}</clr-dg-cell>
|
||||
|
@ -9,8 +9,8 @@ const JOB_STATUS = {
|
||||
PENDING: "pending",
|
||||
RUNNING: "running"
|
||||
};
|
||||
const YES: string = 'Yes';
|
||||
const NO: string = 'No';
|
||||
const YES: string = 'TAG_RETENTION.YES';
|
||||
const NO: string = 'TAG_RETENTION.NO';
|
||||
@Component({
|
||||
selector: 'gc-history',
|
||||
templateUrl: './gc-history.component.html',
|
||||
|
@ -10,9 +10,9 @@
|
||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.PUBLIC_POLICY' | translate }}
|
||||
</clr-control-helper>
|
||||
</clr-checkbox-container>
|
||||
<clr-checkbox-container *ngIf="withNotary">
|
||||
<label><span *ngIf="withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-wrapper *ngIf="withNotary">
|
||||
<clr-checkbox-container *ngIf="withNotary && !isProxyCacheProject">
|
||||
<label><span *ngIf="withNotary && !isProxyCacheProject">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-wrapper *ngIf="withNotary && !isProxyCacheProject">
|
||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrust" name="content-trust"
|
||||
[disabled]="!hasChangeConfigRole" />
|
||||
<label>{{ 'PROJECT_CONFIG.CONTENT_TRUST_TOGGLE' | translate }}</label>
|
||||
@ -21,7 +21,7 @@
|
||||
</clr-control-helper>
|
||||
</clr-checkbox-container>
|
||||
<clr-checkbox-container id="prevent-vulenrability-image" class="margin-top-05">
|
||||
<label><span *ngIf="!withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<label><span *ngIf="!(withNotary && !isProxyCacheProject)">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||
<clr-checkbox-wrapper>
|
||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.PreventVulImg"
|
||||
name="prevent-vulenrability-image-input" [disabled]="!hasChangeConfigRole" />
|
||||
|
@ -57,6 +57,7 @@ export class ProjectPolicyConfigComponent implements OnInit {
|
||||
onGoing = false;
|
||||
@Input() projectId: number;
|
||||
@Input() projectName = 'unknown';
|
||||
@Input() isProxyCacheProject: boolean = false;
|
||||
|
||||
@Input() hasSignedIn: boolean;
|
||||
@Input() hasProjectAdminRole: boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user