mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 10:45:45 +01:00
Improve scanner UI
Signed-off-by: sshijun <sshijun@vmware.com>
This commit is contained in:
parent
ad053fc017
commit
b406611a3d
@ -10,7 +10,7 @@
|
|||||||
<clr-tab>
|
<clr-tab>
|
||||||
<button id="config-vulnerability" clrTabLink>{{'CONFIG.VULNERABILITY' | translate}}</button>
|
<button id="config-vulnerability" clrTabLink>{{'CONFIG.VULNERABILITY' | translate}}</button>
|
||||||
<clr-tab-content id="vulnerability" *clrIfActive>
|
<clr-tab-content id="vulnerability" *clrIfActive>
|
||||||
<vulnerability-config *ngIf="withClair" #vulnerabilityConfig [showSubTitle]="true"></vulnerability-config>
|
<vulnerability-config #vulnerabilityConfig [showSubTitle]="true"></vulnerability-config>
|
||||||
</clr-tab-content>
|
</clr-tab-content>
|
||||||
</clr-tab>
|
</clr-tab>
|
||||||
<clr-tab>
|
<clr-tab>
|
||||||
@ -21,4 +21,4 @@
|
|||||||
</clr-tab-content>
|
</clr-tab-content>
|
||||||
</clr-tab>
|
</clr-tab>
|
||||||
</clr-tabs>
|
</clr-tabs>
|
||||||
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
||||||
|
@ -18,4 +18,7 @@
|
|||||||
|
|
||||||
.replication-tooltip {
|
.replication-tooltip {
|
||||||
top: -8px;
|
top: -8px;
|
||||||
}
|
}
|
||||||
|
.margin-top-3px {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
</clr-checkbox-container>
|
</clr-checkbox-container>
|
||||||
|
|
||||||
|
|
||||||
<div class="clr-form-control d-f" *ngIf="withClair">
|
<div class="clr-form-control d-f">
|
||||||
<label for="systemWhitelist"
|
<label for="systemWhitelist"
|
||||||
class="clr-control-label">{{'CVE_WHITELIST.DEPLOYMENT_SECURITY'|translate}}</label>
|
class="clr-control-label">{{'CVE_WHITELIST.DEPLOYMENT_SECURITY'|translate}}</label>
|
||||||
<div class="form-content">
|
<div class="form-content">
|
||||||
@ -172,4 +172,4 @@
|
|||||||
[disabled]="(!isValid() || !hasChanges()) && (!hasWhitelistChanged) || inProgress">{{'BUTTON.CANCEL'
|
[disabled]="(!isValid() || !hasChanges()) && (!hasWhitelistChanged) || inProgress">{{'BUTTON.CANCEL'
|
||||||
| translate}}</button>
|
| translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.PUBLIC_POLICY' | translate }}
|
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.PUBLIC_POLICY' | translate }}
|
||||||
</clr-control-helper>
|
</clr-control-helper>
|
||||||
</clr-checkbox-container>
|
</clr-checkbox-container>
|
||||||
<clr-checkbox-container *ngIf="withNotary || withClair">
|
<clr-checkbox-container *ngIf="withNotary">
|
||||||
<label><span *ngIf="withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
<label><span *ngIf="withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||||
<clr-checkbox-wrapper *ngIf="withNotary">
|
<clr-checkbox-wrapper *ngIf="withNotary">
|
||||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrust" name="content-trust"
|
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrust" name="content-trust"
|
||||||
@ -20,9 +20,9 @@
|
|||||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.CONTENT_TRUST_POLCIY' | translate }}
|
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.CONTENT_TRUST_POLCIY' | translate }}
|
||||||
</clr-control-helper>
|
</clr-control-helper>
|
||||||
</clr-checkbox-container>
|
</clr-checkbox-container>
|
||||||
<clr-checkbox-container id="prevent-vulenrability-image" *ngIf="withNotary || withClair">
|
<clr-checkbox-container id="prevent-vulenrability-image" *ngIf="withNotary">
|
||||||
<label><span *ngIf="!withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
<label><span *ngIf="!withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||||
<clr-checkbox-wrapper *ngIf="withClair">
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.PreventVulImg"
|
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.PreventVulImg"
|
||||||
name="prevent-vulenrability-image-input" [disabled]="!hasChangeConfigRole" />
|
name="prevent-vulenrability-image-input" [disabled]="!hasChangeConfigRole" />
|
||||||
<label>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_TOGGLE' | translate }}</label>
|
<label>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_TOGGLE' | translate }}</label>
|
||||||
@ -46,7 +46,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</clr-control-helper>
|
</clr-control-helper>
|
||||||
</clr-checkbox-container>
|
</clr-checkbox-container>
|
||||||
<clr-checkbox-container *ngIf="withClair">
|
<clr-checkbox-container>
|
||||||
<label>{{ 'PROJECT_CONFIG.SCAN' | translate }}</label>
|
<label>{{ 'PROJECT_CONFIG.SCAN' | translate }}</label>
|
||||||
<clr-checkbox-wrapper id="scan-image-on-push-wrapper">
|
<clr-checkbox-wrapper id="scan-image-on-push-wrapper">
|
||||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ScanImgOnPush"
|
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ScanImgOnPush"
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.AUTOSCAN_POLICY' | translate }}
|
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.AUTOSCAN_POLICY' | translate }}
|
||||||
</clr-control-helper>
|
</clr-control-helper>
|
||||||
</clr-checkbox-container>
|
</clr-checkbox-container>
|
||||||
<div class="clr-form-control" [class.clr-form-control-disabled]="!hasChangeConfigRole" *ngIf="withClair">
|
<div class="clr-form-control" [class.clr-form-control-disabled]="!hasChangeConfigRole">
|
||||||
<label for="systemWhitelist" class="clr-control-label">{{'CVE_WHITELIST.CVE_WHITELIST'|translate}}</label>
|
<label for="systemWhitelist" class="clr-control-label">{{'CVE_WHITELIST.CVE_WHITELIST'|translate}}</label>
|
||||||
<div class="w-100 clr-control-container">
|
<div class="w-100 clr-control-container">
|
||||||
<div class="config-subtext">
|
<div class="config-subtext">
|
||||||
|
@ -55,10 +55,9 @@
|
|||||||
<section id="image" role="tabpanel" aria-labelledby="repo-image" [hidden]='!isCurrentTabContent("image")'>
|
<section id="image" role="tabpanel" aria-labelledby="repo-image" [hidden]='!isCurrentTabContent("image")'>
|
||||||
<div id=images-container>
|
<div id=images-container>
|
||||||
<hbr-tag ngProjectAs="clr-dg-row-detail" (tagClickEvent)="watchTagClickEvt($event)" (signatureOutput)="saveSignatures($event)"
|
<hbr-tag ngProjectAs="clr-dg-row-detail" (tagClickEvent)="watchTagClickEvt($event)" (signatureOutput)="saveSignatures($event)"
|
||||||
class="sub-grid-custom" [repoName]="repoName" [registryUrl]="registryUrl" [withNotary]="withNotary"
|
class="sub-grid-custom" [repoName]="repoName" [registryUrl]="registryUrl" [withNotary]="withNotary" [withAdmiral]="withAdmiral" [hasSignedIn]="hasSignedIn"
|
||||||
[withClair]="withClair" [withAdmiral]="withAdmiral" [hasSignedIn]="hasSignedIn"
|
|
||||||
[isGuest]="isGuest" [projectId]="projectId" [memberRoleID]="memberRoleID"></hbr-tag>
|
[isGuest]="isGuest" [projectId]="projectId" [memberRoleID]="memberRoleID"></hbr-tag>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
<clr-dg-column *ngIf="withNotary">{{'REPOSITORY.SIGNED' | translate}}</clr-dg-column>
|
<clr-dg-column *ngIf="withNotary">{{'REPOSITORY.SIGNED' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.AUTHOR' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.AUTHOR' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgSortBy]="createdComparator">{{'REPOSITORY.CREATED' | translate}}</clr-dg-column>
|
<clr-dg-column [clrDgSortBy]="createdComparator">{{'REPOSITORY.CREATED' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgField]="'docker_version'" *ngIf="!withClair">{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
|
<clr-dg-column [clrDgField]="'docker_version'">{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column *ngIf="!withAdmiral">{{'REPOSITORY.LABELS' | translate}}</clr-dg-column>
|
<clr-dg-column *ngIf="!withAdmiral">{{'REPOSITORY.LABELS' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgSortBy]="pushComparator">{{'REPOSITORY.PUSH_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column [clrDgSortBy]="pushComparator">{{'REPOSITORY.PUSH_TIME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgSortBy]="pullComparator">{{'REPOSITORY.PULL_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column [clrDgSortBy]="pullComparator">{{'REPOSITORY.PULL_TIME' | translate}}</clr-dg-column>
|
||||||
@ -111,7 +111,7 @@
|
|||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
<clr-dg-cell class="truncated" title="{{t.author}}">{{t.author}}</clr-dg-cell>
|
<clr-dg-cell class="truncated" title="{{t.author}}">{{t.author}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{t.created | date: 'short'}}</clr-dg-cell>
|
<clr-dg-cell>{{t.created | date: 'short'}}</clr-dg-cell>
|
||||||
<clr-dg-cell *ngIf="!withClair">{{t.docker_version}}</clr-dg-cell>
|
<clr-dg-cell>{{t.docker_version}}</clr-dg-cell>
|
||||||
<clr-dg-cell *ngIf="!withAdmiral">
|
<clr-dg-cell *ngIf="!withAdmiral">
|
||||||
<hbr-label-piece *ngIf="t.labels?.length" [label]="t.labels[0]" [labelWidth]="90"> </hbr-label-piece>
|
<hbr-label-piece *ngIf="t.labels?.length" [label]="t.labels[0]" [labelWidth]="90"> </hbr-label-piece>
|
||||||
<div class="signpost-item" [hidden]="t.labels?.length<=1">
|
<div class="signpost-item" [hidden]="t.labels?.length<=1">
|
||||||
@ -136,4 +136,4 @@
|
|||||||
</clr-dg-footer>
|
</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -723,9 +723,7 @@ export class TagComponent implements OnInit, AfterViewInit {
|
|||||||
canScanNow(t: Tag[]): boolean {
|
canScanNow(t: Tag[]): boolean {
|
||||||
if (!this.hasScanImagePermission) { return false; }
|
if (!this.hasScanImagePermission) { return false; }
|
||||||
let st: string = this.scanStatus(t[0]);
|
let st: string = this.scanStatus(t[0]);
|
||||||
|
return st !== VULNERABILITY_SCAN_STATUS.RUNNING;
|
||||||
return st !== VULNERABILITY_SCAN_STATUS.PENDING &&
|
|
||||||
st !== VULNERABILITY_SCAN_STATUS.RUNNING;
|
|
||||||
}
|
}
|
||||||
getImagePermissionRule(projectId: number): void {
|
getImagePermissionRule(projectId: number): void {
|
||||||
let hasAddLabelImagePermission = this.userPermissionService.getPermission(projectId, USERSTATICPERMISSION.REPOSITORY_TAG_LABEL.KEY,
|
let hasAddLabelImagePermission = this.userPermissionService.getPermission(projectId, USERSTATICPERMISSION.REPOSITORY_TAG_LABEL.KEY,
|
||||||
|
@ -43,12 +43,12 @@
|
|||||||
</a>
|
</a>
|
||||||
</clr-vertical-nav-group-children>
|
</clr-vertical-nav-group-children>
|
||||||
</clr-vertical-nav-group>
|
</clr-vertical-nav-group>
|
||||||
<clr-vertical-nav-group *ngIf="isSystemAdmin && (withClair || hasAdminRole)" routerLinkActive="active">
|
<clr-vertical-nav-group *ngIf="isSystemAdmin && hasAdminRole" routerLinkActive="active">
|
||||||
<clr-icon shape="event" clrVerticalNavIcon></clr-icon>
|
<clr-icon shape="event" clrVerticalNavIcon></clr-icon>
|
||||||
{{'SIDE_NAV.TASKS' | translate}}
|
{{'SIDE_NAV.TASKS' | translate}}
|
||||||
<a routerLink="#" hidden aria-hidden="true"></a>
|
<a routerLink="#" hidden aria-hidden="true"></a>
|
||||||
<clr-vertical-nav-group-children *clrIfExpanded="true">
|
<clr-vertical-nav-group-children *clrIfExpanded="true">
|
||||||
<a clrVerticalNavLink *ngIf="withClair" routerLink="/harbor/vulnerability"
|
<a clrVerticalNavLink routerLink="/harbor/vulnerability"
|
||||||
routerLinkActive="active">
|
routerLinkActive="active">
|
||||||
{{'SIDE_NAV.SYSTEM_MGMT.VULNERABILITY' | translate}}
|
{{'SIDE_NAV.SYSTEM_MGMT.VULNERABILITY' | translate}}
|
||||||
</a>
|
</a>
|
||||||
|
@ -17,18 +17,26 @@
|
|||||||
<button clrDropdownItem
|
<button clrDropdownItem
|
||||||
(click)="changeStat()"
|
(click)="changeStat()"
|
||||||
[disabled]="!(selectedRow && !selectedRow.is_default)">
|
[disabled]="!(selectedRow && !selectedRow.is_default)">
|
||||||
<span *ngIf="selectedRow && selectedRow.disabled">{{'BUTTON.ENABLE' | translate}}</span>
|
<span *ngIf="selectedRow && selectedRow.disabled">
|
||||||
<span *ngIf="!(selectedRow && selectedRow.disabled)">{{'BUTTON.DISABLE' | translate}}</span>
|
<clr-icon class="margin-top-2" size="16" shape="success-standard"></clr-icon>
|
||||||
|
<span class="margin-left-10">{{'SCANNER.ENABLE' | translate}}</span>
|
||||||
|
</span>
|
||||||
|
<span *ngIf="!(selectedRow && selectedRow.disabled)">
|
||||||
|
<clr-icon class="margin-top-2" size="16" shape="ban"></clr-icon>
|
||||||
|
<span class="margin-left-10">{{'SCANNER.DISABLE' | translate}}</span>
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button clrDropdownItem
|
<button clrDropdownItem
|
||||||
(click)="editScanner()"
|
(click)="editScanner()"
|
||||||
class="btn btn-sm btn-secondary" [disabled]="!selectedRow">
|
class="btn btn-sm btn-secondary" [disabled]="!selectedRow">
|
||||||
{{'BUTTON.EDIT' | translate}}
|
<clr-icon class="margin-top-0" size="16" shape="pencil"></clr-icon>
|
||||||
|
<span class="margin-left-10">{{'BUTTON.EDIT' | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button clrDropdownItem
|
<button clrDropdownItem
|
||||||
(click)="deleteScanners()"
|
(click)="deleteScanners()"
|
||||||
class="btn btn-sm btn-secondary" [disabled]="!selectedRow">
|
class="btn btn-sm btn-secondary" [disabled]="!selectedRow">
|
||||||
{{'BUTTON.DELETE' | translate}}
|
<clr-icon class="margin-top-0" size="16" shape="times"></clr-icon>
|
||||||
|
<span class="margin-left-10">{{'BUTTON.DELETE' | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
</clr-dropdown-menu>
|
</clr-dropdown-menu>
|
||||||
</clr-dropdown>
|
</clr-dropdown>
|
||||||
@ -45,7 +53,7 @@
|
|||||||
<clr-dg-column class="width-240" [clrDgField]="'name'">{{'SCANNER.NAME' | translate}}</clr-dg-column>
|
<clr-dg-column class="width-240" [clrDgField]="'name'">{{'SCANNER.NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column class="width-240" [clrDgField]="'url'">{{'SCANNER.ENDPOINT' | translate}}</clr-dg-column>
|
<clr-dg-column class="width-240" [clrDgField]="'url'">{{'SCANNER.ENDPOINT' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'SCANNER.HEALTH' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'SCANNER.HEALTH' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'SCANNER.DISABLED' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'SCANNER.ENABLED' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'SCANNER.AUTH' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'SCANNER.AUTH' | translate}}</clr-dg-column>
|
||||||
<clr-dg-placeholder>
|
<clr-dg-placeholder>
|
||||||
{{'SCANNER.NO_SCANNER' | translate}}
|
{{'SCANNER.NO_SCANNER' | translate}}
|
||||||
@ -62,7 +70,7 @@
|
|||||||
<span class="label label-danger">{{'SCANNER.UNHEALTHY' | translate}}</span>
|
<span class="label label-danger">{{'SCANNER.UNHEALTHY' | translate}}</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
<clr-dg-cell>{{scanner.disabled}}</clr-dg-cell>
|
<clr-dg-cell>{{!scanner.disabled}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{scanner.auth?scanner.auth:'None'}}</clr-dg-cell>
|
<clr-dg-cell>{{scanner.auth?scanner.auth:'None'}}</clr-dg-cell>
|
||||||
<scanner-metadata *clrIfExpanded [uid]="scanner.uuid" ngProjectAs="clr-dg-row-detail"></scanner-metadata>
|
<scanner-metadata *clrIfExpanded [uid]="scanner.uuid" ngProjectAs="clr-dg-row-detail"></scanner-metadata>
|
||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
|
@ -22,3 +22,12 @@
|
|||||||
.width-240 {
|
.width-240 {
|
||||||
min-width: 240px !important;
|
min-width: 240px !important;
|
||||||
}
|
}
|
||||||
|
.margin-top-0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.margin-top-2 {
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
.margin-left-10 {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
@ -35,7 +35,7 @@ export class ConfigurationScannerComponent implements OnInit, OnDestroy {
|
|||||||
confirmed.state === ConfirmationState.CONFIRMED) {
|
confirmed.state === ConfirmationState.CONFIRMED) {
|
||||||
this.configScannerService.deleteScanners(confirmed.data)
|
this.configScannerService.deleteScanners(confirmed.data)
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.msgHandler.showSuccess("Delete Success");
|
this.msgHandler.showSuccess("SCANNER.DELETE_SUCCESS");
|
||||||
this.getScanners();
|
this.getScanners();
|
||||||
}, error => {
|
}, error => {
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
@ -76,7 +76,7 @@ export class ConfigurationScannerComponent implements OnInit, OnDestroy {
|
|||||||
scanner.disabled = !scanner.disabled;
|
scanner.disabled = !scanner.disabled;
|
||||||
this.configScannerService.updateScanner(scanner)
|
this.configScannerService.updateScanner(scanner)
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.msgHandler.showSuccess("Update Success");
|
this.msgHandler.showSuccess("SCANNER.UPDATE_SUCCESS");
|
||||||
this.getScanners();
|
this.getScanners();
|
||||||
}, error => {
|
}, error => {
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
@ -87,7 +87,7 @@ export class ConfigurationScannerComponent implements OnInit, OnDestroy {
|
|||||||
if (this.selectedRow) {
|
if (this.selectedRow) {
|
||||||
this.configScannerService.setAsDefault(this.selectedRow.uuid)
|
this.configScannerService.setAsDefault(this.selectedRow.uuid)
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.msgHandler.showSuccess("Update Success");
|
this.msgHandler.showSuccess("SCANNER.UPDATE_SUCCESS");
|
||||||
this.getScanners();
|
this.getScanners();
|
||||||
}, error => {
|
}, error => {
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<label class="required clr-control-label">{{"SCANNER.NAME" | translate}}</label>
|
<label class="required clr-control-label">{{"SCANNER.NAME" | translate}}</label>
|
||||||
<div class="clr-control-container" [class.clr-error]="!isNameValid">
|
<div class="clr-control-container" [class.clr-error]="!isNameValid">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<input autocomplete="off" #name formControlName="name" class="clr-input width-312"
|
<input autocomplete="off" #name formControlName="name" class="clr-input width-280"
|
||||||
type="text"
|
type="text"
|
||||||
id="scanner-name">
|
id="scanner-name">
|
||||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<div class="clr-form-control">
|
<div class="clr-form-control">
|
||||||
<label class="clr-control-label">{{"SCANNER.DESCRIPTION" | translate}}</label>
|
<label class="clr-control-label">{{"SCANNER.DESCRIPTION" | translate}}</label>
|
||||||
<div class="clr-control-container">
|
<div class="clr-control-container">
|
||||||
<textarea autocomplete="off" formControlName="description" class="clr-textarea width-312" type="text"
|
<textarea autocomplete="off" formControlName="description" class="clr-textarea width-280" type="text"
|
||||||
id="description">
|
id="description">
|
||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<div class="clr-control-container" [class.clr-error]="!isEndpointValid || showEndpointError">
|
<div class="clr-control-container" [class.clr-error]="!isEndpointValid || showEndpointError">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<input (focus)="showEndpointError=false" (blur)="checkEndpointUrl()" #endpointUrl placeholder="http(s)://192.168.1.1" autocomplete="off" formControlName="url"
|
<input (focus)="showEndpointError=false" (blur)="checkEndpointUrl()" #endpointUrl placeholder="http(s)://192.168.1.1" autocomplete="off" formControlName="url"
|
||||||
class="clr-input width-312" type="text" id="scanner-endpoint">
|
class="clr-input width-280" type="text" id="scanner-endpoint">
|
||||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
<span class="spinner spinner-inline" [hidden]="!checkEndpointOnGoing"></span>
|
<span class="spinner spinner-inline" [hidden]="!checkEndpointOnGoing"></span>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<label class="clr-control-label">{{"SCANNER.AUTH" | translate}}</label>
|
<label class="clr-control-label">{{"SCANNER.AUTH" | translate}}</label>
|
||||||
<div class="clr-control-container">
|
<div class="clr-control-container">
|
||||||
<div class="clr-select-wrapper">
|
<div class="clr-select-wrapper">
|
||||||
<select formControlName="auth" class="clr-select width-312" id="scanner-authorization">
|
<select formControlName="auth" class="clr-select width-280" id="scanner-authorization">
|
||||||
<option value="None">{{"SCANNER.NONE" | translate}}</option>
|
<option value="None">{{"SCANNER.NONE" | translate}}</option>
|
||||||
<option value="Basic">{{"SCANNER.BASIC" | translate}}</option>
|
<option value="Basic">{{"SCANNER.BASIC" | translate}}</option>
|
||||||
<option value="Bearer">{{"SCANNER.BEARER" | translate}}</option>
|
<option value="Bearer">{{"SCANNER.BEARER" | translate}}</option>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<div class="clr-control-container" [class.clr-error]="!isUserNameValid">
|
<div class="clr-control-container" [class.clr-error]="!isUserNameValid">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<input formControlName="username" autocomplete="off"
|
<input formControlName="username" autocomplete="off"
|
||||||
class="clr-input width-312" type="text" id="scanner-username">
|
class="clr-input width-280" type="text" id="scanner-username">
|
||||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
</div>
|
</div>
|
||||||
<clr-control-error *ngIf="!isUserNameValid">
|
<clr-control-error *ngIf="!isUserNameValid">
|
||||||
@ -69,7 +69,7 @@
|
|||||||
<div class="clr-control-container" [class.clr-error]="!isPasswordValid">
|
<div class="clr-control-container" [class.clr-error]="!isPasswordValid">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<input formControlName="password" autocomplete="off"
|
<input formControlName="password" autocomplete="off"
|
||||||
class="clr-input width-312" type="password" id="scanner-password">
|
class="clr-input width-280" type="password" id="scanner-password">
|
||||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
</div>
|
</div>
|
||||||
<clr-control-error *ngIf="!isPasswordValid">
|
<clr-control-error *ngIf="!isPasswordValid">
|
||||||
@ -82,7 +82,7 @@
|
|||||||
<div class="clr-control-container" [class.clr-error]="!isTokenValid">
|
<div class="clr-control-container" [class.clr-error]="!isTokenValid">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<input formControlName="token" autocomplete="off"
|
<input formControlName="token" autocomplete="off"
|
||||||
class="clr-input width-312" type="text" id="scanner-token">
|
class="clr-input width-280" type="text" id="scanner-token">
|
||||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
</div>
|
</div>
|
||||||
<clr-control-error *ngIf="!isTokenValid">
|
<clr-control-error *ngIf="!isTokenValid">
|
||||||
@ -95,7 +95,7 @@
|
|||||||
<div class="clr-control-container" [class.clr-error]="!isApiKeyValid">
|
<div class="clr-control-container" [class.clr-error]="!isApiKeyValid">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<input formControlName="apiKey" autocomplete="off"
|
<input formControlName="apiKey" autocomplete="off"
|
||||||
class="clr-input width-312" type="text" id="scanner-apiKey">
|
class="clr-input width-280" type="text" id="scanner-apiKey">
|
||||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
</div>
|
</div>
|
||||||
<clr-control-error *ngIf="!isApiKeyValid">
|
<clr-control-error *ngIf="!isApiKeyValid">
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
.width-312 {
|
.width-280 {
|
||||||
width: 312px;
|
width: 280px;
|
||||||
}
|
}
|
||||||
.padding-top-3 {
|
.padding-top-3 {
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
}
|
}
|
||||||
|
.clr-control-label {
|
||||||
|
width: 9rem !important;
|
||||||
|
}
|
||||||
|
@ -21,7 +21,7 @@ export class NewScannerFormComponent implements OnInit, AfterViewInit, OnDestro
|
|||||||
checkOnGoing: boolean = false;
|
checkOnGoing: boolean = false;
|
||||||
newScannerForm: FormGroup = this.fb.group({
|
newScannerForm: FormGroup = this.fb.group({
|
||||||
name: this.fb.control("",
|
name: this.fb.control("",
|
||||||
[Validators.required, Validators.pattern(/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/)]),
|
[Validators.required]),
|
||||||
description: this.fb.control(""),
|
description: this.fb.control(""),
|
||||||
url: this.fb.control("",
|
url: this.fb.control("",
|
||||||
[Validators.required,
|
[Validators.required,
|
||||||
@ -57,7 +57,7 @@ export class NewScannerFormComponent implements OnInit, AfterViewInit, OnDestro
|
|||||||
if (this.isEdit && this.originValue && this.originValue.name === name) {
|
if (this.isEdit && this.originValue && this.originValue.name === name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.newScannerForm.get('name').valid && name.length > 1;
|
return this.newScannerForm.get('name').valid && name.length > 0;
|
||||||
}),
|
}),
|
||||||
debounceTime(500),
|
debounceTime(500),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
@ -130,15 +130,15 @@ export class NewScannerFormComponent implements OnInit, AfterViewInit, OnDestro
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (this.isNameExisting) {
|
if (this.isNameExisting) {
|
||||||
this.nameTooltip = 'NAME_EXISTS';
|
this.nameTooltip = 'SCANNER.NAME_EXISTS';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.newScannerForm.get('name').errors && this.newScannerForm.get('name').errors.required) {
|
if (this.newScannerForm.get('name').errors && this.newScannerForm.get('name').errors.required) {
|
||||||
this.nameTooltip = 'NAME_REQUIRED';
|
this.nameTooltip = 'SCANNER.NAME_REQUIRED';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.newScannerForm.get('name').errors && this.newScannerForm.get('name').errors.pattern) {
|
if (this.newScannerForm.get('name').errors && this.newScannerForm.get('name').errors.pattern) {
|
||||||
this.nameTooltip = 'NAME_REX';
|
this.nameTooltip = 'SCANNER.NAME_REX';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -151,11 +151,11 @@ export class NewScannerFormComponent implements OnInit, AfterViewInit, OnDestro
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (this.isEndpointUrlExisting) {
|
if (this.isEndpointUrlExisting) {
|
||||||
this.endpointTooltip = 'ENDPOINT_EXISTS';
|
this.endpointTooltip = 'SCANNER.ENDPOINT_EXISTS';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.newScannerForm.get('url').errors && this.newScannerForm.get('url').errors.required) {
|
if (this.newScannerForm.get('url').errors && this.newScannerForm.get('url').errors.required) {
|
||||||
this.endpointTooltip = 'ENDPOINT_REQUIRED';
|
this.endpointTooltip = 'SCANNER.ENDPOINT_REQUIRED';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// skip here, validate when onblur
|
// skip here, validate when onblur
|
||||||
@ -167,7 +167,7 @@ export class NewScannerFormComponent implements OnInit, AfterViewInit, OnDestro
|
|||||||
// validate endpointUrl when onblur
|
// validate endpointUrl when onblur
|
||||||
checkEndpointUrl() {
|
checkEndpointUrl() {
|
||||||
if (this.newScannerForm.get('url').errors && this.newScannerForm.get('url').errors.pattern) {
|
if (this.newScannerForm.get('url').errors && this.newScannerForm.get('url').errors.pattern) {
|
||||||
this.endpointTooltip = "ILLEGAL_ENDPOINT";
|
this.endpointTooltip = "SCANNER.ILLEGAL_ENDPOINT";
|
||||||
this.showEndpointError = true;
|
this.showEndpointError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<div class="clr-form-control">
|
<div class="clr-form-control">
|
||||||
<label class="clr-control-label name">{{'SCANNER.SCANNER' | translate}}</label>
|
<label class="clr-control-label name">{{'SCANNER.SCANNER' | translate}}</label>
|
||||||
<div class="clr-control-container">
|
<div class="clr-control-container">
|
||||||
<button *ngIf="scanners && scanners.length > 0" id="edit-scanner" class="btn btn-link edit" (click)="open()">{{'SCANNER.EDIT' | translate}}</button>
|
|
||||||
<label *ngIf="!(scanners && scanners.length > 0)" class="name">{{'SCANNER.NOT_AVAILABLE' | translate}}</label>
|
<label *ngIf="!(scanners && scanners.length > 0)" class="name">{{'SCANNER.NOT_AVAILABLE' | translate}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -16,9 +16,10 @@
|
|||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<div class="clr-input-wrapper">
|
<div class="clr-input-wrapper">
|
||||||
<span id="scanner-name" class="scanner-name">{{scanner?.name}}</span>
|
<span id="scanner-name" class="scanner-name">{{scanner?.name}}</span>
|
||||||
|
<button *ngIf="scanners && scanners.length > 0" id="edit-scanner" class="btn btn-primary btn-sm" (click)="open()">{{'SCANNER.EDIT' | translate}}</button>
|
||||||
<span *ngIf="scanner?.disabled" class="label label-warning ml-1">{{'SCANNER.DISABLED' | translate}}</span>
|
<span *ngIf="scanner?.disabled" class="label label-warning ml-1">{{'SCANNER.DISABLED' | translate}}</span>
|
||||||
<span *ngIf="scanner?.health" class="label label-success ml-1">{{'SCANNER.HEALTHY' | translate}}</span>
|
<span *ngIf="scanner?.health" class="label label-success ml-1">{{'SCANNER.HEALTHY' | translate}}</span>
|
||||||
<span *ngIf="!scanner?.health" class="label label-danger ml-1">{{'SCANNER.Unhealthy' | translate}}</span>
|
<span *ngIf="!scanner?.health" class="label label-danger ml-1">{{'SCANNER.UNHEALTHY' | translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,3 +18,6 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
.clr-form-control {
|
||||||
|
margin-top: 0.75rem !important;
|
||||||
|
}
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<hbr-tag-detail (backEvt)="goBack($event)"
|
<hbr-tag-detail (backEvt)="goBack($event)"
|
||||||
[tagId]="tagId"
|
[tagId]="tagId"
|
||||||
[withClair]="withClair"
|
|
||||||
[withAdmiral]="withAdmiral"
|
[withAdmiral]="withAdmiral"
|
||||||
[projectId]="projectId"
|
[projectId]="projectId"
|
||||||
[repositoryId]="repositoryId"></hbr-tag-detail>
|
[repositoryId]="repositoryId"></hbr-tag-detail>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1257,10 +1257,10 @@
|
|||||||
"ADD_SCANNER": "Add Scanner",
|
"ADD_SCANNER": "Add Scanner",
|
||||||
"EDIT_SCANNER": "Edit Scanner",
|
"EDIT_SCANNER": "Edit Scanner",
|
||||||
"TEST_CONNECTION": "TEST CONNECTION",
|
"TEST_CONNECTION": "TEST CONNECTION",
|
||||||
"ADD_SUCCESS": "Added successfully",
|
"ADD_SUCCESS": "Successfully added ",
|
||||||
"TEST_PASS": "Test passed",
|
"TEST_PASS": "Test passed",
|
||||||
"TEST_FAILED": "Test failed",
|
"TEST_FAILED": "Test failed",
|
||||||
"UPDATE_SUCCESS": "Updated successfully",
|
"UPDATE_SUCCESS": "Successfully updated",
|
||||||
"SCANNER_COLON": "Scanner:",
|
"SCANNER_COLON": "Scanner:",
|
||||||
"NAME_COLON": "Name:",
|
"NAME_COLON": "Name:",
|
||||||
"VENDOR_COLON": "Vendor:",
|
"VENDOR_COLON": "Vendor:",
|
||||||
@ -1284,6 +1284,10 @@
|
|||||||
"ADAPTER": "Adapter",
|
"ADAPTER": "Adapter",
|
||||||
"VENDOR": "Vendor",
|
"VENDOR": "Vendor",
|
||||||
"VERSION": "Version",
|
"VERSION": "Version",
|
||||||
"SELECT_SCANNER": "Select Scanner"
|
"SELECT_SCANNER": "Select Scanner",
|
||||||
|
"ENABLED": "Enabled",
|
||||||
|
"ENABLE": "Enable",
|
||||||
|
"DISABLE": "Disable",
|
||||||
|
"DELETE_SUCCESS": "Successfully deleted"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1254,10 +1254,10 @@
|
|||||||
"ADD_SCANNER": "Add Scanner",
|
"ADD_SCANNER": "Add Scanner",
|
||||||
"EDIT_SCANNER": "Edit Scanner",
|
"EDIT_SCANNER": "Edit Scanner",
|
||||||
"TEST_CONNECTION": "TEST CONNECTION",
|
"TEST_CONNECTION": "TEST CONNECTION",
|
||||||
"ADD_SUCCESS": "Added successfully",
|
"ADD_SUCCESS": "Successfully added ",
|
||||||
"TEST_PASS": "Test passed",
|
"TEST_PASS": "Test passed",
|
||||||
"TEST_FAILED": "Test failed",
|
"TEST_FAILED": "Test failed",
|
||||||
"UPDATE_SUCCESS": "Updated successfully",
|
"UPDATE_SUCCESS": "Successfully updated",
|
||||||
"SCANNER_COLON": "Scanner:",
|
"SCANNER_COLON": "Scanner:",
|
||||||
"NAME_COLON": "Name:",
|
"NAME_COLON": "Name:",
|
||||||
"VENDOR_COLON": "Vendor:",
|
"VENDOR_COLON": "Vendor:",
|
||||||
@ -1281,6 +1281,10 @@
|
|||||||
"ADAPTER": "Adapter",
|
"ADAPTER": "Adapter",
|
||||||
"VENDOR": "Vendor",
|
"VENDOR": "Vendor",
|
||||||
"VERSION": "Version",
|
"VERSION": "Version",
|
||||||
"SELECT_SCANNER": "Select Scanner"
|
"SELECT_SCANNER": "Select Scanner",
|
||||||
|
"ENABLED": "Enabled",
|
||||||
|
"ENABLE": "Enable",
|
||||||
|
"DISABLE": "Disable",
|
||||||
|
"DELETE_SUCCESS": "Successfully deleted"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1226,10 +1226,10 @@
|
|||||||
"ADD_SCANNER": "Add Scanner",
|
"ADD_SCANNER": "Add Scanner",
|
||||||
"EDIT_SCANNER": "Edit Scanner",
|
"EDIT_SCANNER": "Edit Scanner",
|
||||||
"TEST_CONNECTION": "TEST CONNECTION",
|
"TEST_CONNECTION": "TEST CONNECTION",
|
||||||
"ADD_SUCCESS": "Added successfully",
|
"ADD_SUCCESS": "Successfully added ",
|
||||||
"TEST_PASS": "Test passed",
|
"TEST_PASS": "Test passed",
|
||||||
"TEST_FAILED": "Test failed",
|
"TEST_FAILED": "Test failed",
|
||||||
"UPDATE_SUCCESS": "Updated successfully",
|
"UPDATE_SUCCESS": "Successfully updated",
|
||||||
"SCANNER_COLON": "Scanner:",
|
"SCANNER_COLON": "Scanner:",
|
||||||
"NAME_COLON": "Name:",
|
"NAME_COLON": "Name:",
|
||||||
"VENDOR_COLON": "Vendor:",
|
"VENDOR_COLON": "Vendor:",
|
||||||
@ -1253,6 +1253,10 @@
|
|||||||
"ADAPTER": "Adapter",
|
"ADAPTER": "Adapter",
|
||||||
"VENDOR": "Vendor",
|
"VENDOR": "Vendor",
|
||||||
"VERSION": "Version",
|
"VERSION": "Version",
|
||||||
"SELECT_SCANNER": "Select Scanner"
|
"SELECT_SCANNER": "Select Scanner",
|
||||||
|
"ENABLED": "Enabled",
|
||||||
|
"ENABLE": "Enable",
|
||||||
|
"DISABLE": "Disable",
|
||||||
|
"DELETE_SUCCESS": "Successfully deleted"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1251,10 +1251,10 @@
|
|||||||
"ADD_SCANNER": "Add Scanner",
|
"ADD_SCANNER": "Add Scanner",
|
||||||
"EDIT_SCANNER": "Edit Scanner",
|
"EDIT_SCANNER": "Edit Scanner",
|
||||||
"TEST_CONNECTION": "TEST CONNECTION",
|
"TEST_CONNECTION": "TEST CONNECTION",
|
||||||
"ADD_SUCCESS": "Added successfully",
|
"ADD_SUCCESS": "Successfully added ",
|
||||||
"TEST_PASS": "Test passed",
|
"TEST_PASS": "Test passed",
|
||||||
"TEST_FAILED": "Test failed",
|
"TEST_FAILED": "Test failed",
|
||||||
"UPDATE_SUCCESS": "Updated successfully",
|
"UPDATE_SUCCESS": "Successfully updated",
|
||||||
"SCANNER_COLON": "Scanner:",
|
"SCANNER_COLON": "Scanner:",
|
||||||
"NAME_COLON": "Name:",
|
"NAME_COLON": "Name:",
|
||||||
"VENDOR_COLON": "Vendor:",
|
"VENDOR_COLON": "Vendor:",
|
||||||
@ -1278,7 +1278,11 @@
|
|||||||
"ADAPTER": "Adapter",
|
"ADAPTER": "Adapter",
|
||||||
"VENDOR": "Vendor",
|
"VENDOR": "Vendor",
|
||||||
"VERSION": "Version",
|
"VERSION": "Version",
|
||||||
"SELECT_SCANNER": "Select Scanner"
|
"SELECT_SCANNER": "Select Scanner",
|
||||||
|
"ENABLED": "Enabled",
|
||||||
|
"ENABLE": "Enable",
|
||||||
|
"DISABLE": "Disable",
|
||||||
|
"DELETE_SUCCESS": "Successfully deleted"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1256,10 +1256,10 @@
|
|||||||
"ADD_SCANNER": "Add Scanner",
|
"ADD_SCANNER": "Add Scanner",
|
||||||
"EDIT_SCANNER": "Edit Scanner",
|
"EDIT_SCANNER": "Edit Scanner",
|
||||||
"TEST_CONNECTION": "TEST CONNECTION",
|
"TEST_CONNECTION": "TEST CONNECTION",
|
||||||
"ADD_SUCCESS": "Added successfully",
|
"ADD_SUCCESS": "Successfully added ",
|
||||||
"TEST_PASS": "Test passed",
|
"TEST_PASS": "Test passed",
|
||||||
"TEST_FAILED": "Test failed",
|
"TEST_FAILED": "Test failed",
|
||||||
"UPDATE_SUCCESS": "Updated successfully",
|
"UPDATE_SUCCESS": "Successfully updated",
|
||||||
"SCANNER_COLON": "Scanner:",
|
"SCANNER_COLON": "Scanner:",
|
||||||
"NAME_COLON": "Name:",
|
"NAME_COLON": "Name:",
|
||||||
"VENDOR_COLON": "Vendor:",
|
"VENDOR_COLON": "Vendor:",
|
||||||
@ -1283,6 +1283,10 @@
|
|||||||
"ADAPTER": "Adapter",
|
"ADAPTER": "Adapter",
|
||||||
"VENDOR": "Vendor",
|
"VENDOR": "Vendor",
|
||||||
"VERSION": "Version",
|
"VERSION": "Version",
|
||||||
"SELECT_SCANNER": "Select Scanner"
|
"SELECT_SCANNER": "Select Scanner",
|
||||||
|
"ENABLED": "Enabled",
|
||||||
|
"ENABLE": "Enable",
|
||||||
|
"DISABLE": "Disable",
|
||||||
|
"DELETE_SUCCESS": "Successfully deleted"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1280,6 +1280,10 @@
|
|||||||
"ADAPTER": "适配器",
|
"ADAPTER": "适配器",
|
||||||
"VENDOR": "供应商",
|
"VENDOR": "供应商",
|
||||||
"VERSION": "版本",
|
"VERSION": "版本",
|
||||||
"SELECT_SCANNER": "选择扫描器"
|
"SELECT_SCANNER": "选择扫描器",
|
||||||
|
"ENABLED": "启用",
|
||||||
|
"ENABLE": "启用",
|
||||||
|
"DISABLE": "禁用",
|
||||||
|
"DELETE_SUCCESS": "删除成功"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user