mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Merge pull request #9011 from jwangyangls/upgrade_clarity-2.1
Upgrade angular from 7.1.3 to 8.2.0 and clarity from 1.0 to 2.2
This commit is contained in:
commit
6dd2ae90a0
@ -20,7 +20,8 @@ matrix:
|
|||||||
- go: 1.12.5
|
- go: 1.12.5
|
||||||
env:
|
env:
|
||||||
- OFFLINE=true
|
- OFFLINE=true
|
||||||
- node_js: 10.16.2
|
- language: node_js
|
||||||
|
node_js: 10.16.2
|
||||||
env:
|
env:
|
||||||
- UI_UT=true
|
- UI_UT=true
|
||||||
env:
|
env:
|
||||||
|
@ -6,6 +6,7 @@ COPY ./LICENSE /portal_src
|
|||||||
|
|
||||||
WORKDIR /build_dir
|
WORKDIR /build_dir
|
||||||
|
|
||||||
|
|
||||||
RUN cp -r /portal_src/* /build_dir \
|
RUN cp -r /portal_src/* /build_dir \
|
||||||
&& ls -la \
|
&& ls -la \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
@ -14,7 +15,7 @@ RUN cp -r /portal_src/* /build_dir \
|
|||||||
&& npm install \
|
&& npm install \
|
||||||
&& npm run build_lib \
|
&& npm run build_lib \
|
||||||
&& npm run link_lib \
|
&& npm run link_lib \
|
||||||
&& npm run release
|
&& node --max_old_space_size=8192 'node_modules/@angular/cli/bin/ng' build --prod
|
||||||
|
|
||||||
|
|
||||||
FROM photon:2.0
|
FROM photon:2.0
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"node_modules/@clr/ui/clr-ui.min.css",
|
"node_modules/@clr/ui/clr-ui.min.css",
|
||||||
"node_modules/swagger-ui/dist/swagger-ui.css",
|
"node_modules/swagger-ui/dist/swagger-ui.css",
|
||||||
"node_modules/prismjs/themes/prism-solarizedlight.css",
|
"node_modules/prismjs/themes/prism-solarizedlight.css",
|
||||||
|
"src/global.scss",
|
||||||
"src/styles.css"
|
"src/styles.css"
|
||||||
],
|
],
|
||||||
"scripts": [
|
"scripts": [
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
"deleteDestPath": false,
|
"deleteDestPath": false,
|
||||||
"lib": {
|
"lib": {
|
||||||
"entryFile": "index.ts",
|
"entryFile": "index.ts",
|
||||||
"externals": {
|
|
||||||
"@ngx-translate/core": "ngx-translate-core",
|
|
||||||
"@ngx-translate/core/index": "ngx-translate-core",
|
|
||||||
"ngx-markdown": "ngx-markdown"
|
|
||||||
},
|
|
||||||
"umdModuleIds": {
|
"umdModuleIds": {
|
||||||
"@clr/angular" : "angular",
|
"@clr/angular" : "angular",
|
||||||
"ngx-markdown" : "ngxMarkdown",
|
"ngx-markdown" : "ngxMarkdown",
|
||||||
|
@ -3,11 +3,6 @@
|
|||||||
"dest": "./dist",
|
"dest": "./dist",
|
||||||
"lib": {
|
"lib": {
|
||||||
"entryFile": "index.ts",
|
"entryFile": "index.ts",
|
||||||
"externals": {
|
|
||||||
"@ngx-translate/core": "ngx-translate-core",
|
|
||||||
"@ngx-translate/core/index": "ngx-translate-core",
|
|
||||||
"ngx-markdown": "ngx-markdown"
|
|
||||||
},
|
|
||||||
"umdModuleIds": {
|
"umdModuleIds": {
|
||||||
"@clr/angular" : "angular",
|
"@clr/angular" : "angular",
|
||||||
"ngx-markdown" : "ngxMarkdown",
|
"ngx-markdown" : "ngxMarkdown",
|
||||||
|
5
src/portal/lib/package-lock.json
generated
Normal file
5
src/portal/lib/package-lock.json
generated
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "@harbor/ui",
|
||||||
|
"version": "1.10.0",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@harbor/ui",
|
"name": "@harbor/ui",
|
||||||
"version": "1.9.0",
|
"version": "1.10.0",
|
||||||
"description": "Harbor shared UI components based on Clarity and Angular7",
|
"description": "Harbor shared UI components based on Clarity and Angular8",
|
||||||
"author": "CNCF",
|
"author": "CNCF",
|
||||||
"module": "index.js",
|
"module": "index.js",
|
||||||
"main": "bundles/harborui.umd.min.js",
|
"main": "bundles/harborui.umd.min.js",
|
||||||
@ -19,26 +19,26 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/vmware/harbor#readme",
|
"homepage": "https://github.com/vmware/harbor#readme",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/animations": "^7.1.3",
|
"@angular/animations": "^8.2.0",
|
||||||
"@angular/common": "^7.1.3",
|
"@angular/common": "^8.2.0",
|
||||||
"@angular/compiler": "^7.1.3",
|
"@angular/compiler": "^8.2.0",
|
||||||
"@angular/core": "^7.1.3",
|
"@angular/core": "^8.2.0",
|
||||||
"@angular/forms": "^7.1.3",
|
"@angular/forms": "^8.2.0",
|
||||||
"@angular/http": "^7.1.3",
|
"@angular/http": "^8.2.0",
|
||||||
"@angular/platform-browser": "^7.1.3",
|
"@angular/platform-browser": "^8.2.0",
|
||||||
"@angular/platform-browser-dynamic": "^7.1.3",
|
"@angular/platform-browser-dynamic": "^8.2.0",
|
||||||
"@angular/router": "^7.1.3",
|
"@angular/router": "^8.2.0",
|
||||||
"@ngx-translate/core": "^10.0.2",
|
"@ngx-translate/core": "^10.0.2",
|
||||||
"@ngx-translate/http-loader": "^3.0.1",
|
"@ngx-translate/http-loader": "^3.0.1",
|
||||||
"@webcomponents/custom-elements": "^1.1.3",
|
"@webcomponents/custom-elements": "^1.1.3",
|
||||||
"@clr/angular": "^1.0.0",
|
"@clr/angular": "^2.1.0",
|
||||||
"@clr/ui": "^1.0.0",
|
"@clr/icons": "^2.1.0",
|
||||||
"@clr/icons": "^1.0.0",
|
"@clr/ui": "^2.1.0",
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.5.4",
|
||||||
"intl": "^1.2.5",
|
"intl": "^1.2.5",
|
||||||
"mutationobserver-shim": "^0.3.2",
|
"mutationobserver-shim": "^0.3.2",
|
||||||
"ngx-cookie": "^1.0.0",
|
"ngx-cookie": "^1.0.0",
|
||||||
"ngx-markdown": "^6.2.0",
|
"ngx-markdown": "^8.1.0",
|
||||||
"rxjs": "^6.3.3",
|
"rxjs": "^6.3.3",
|
||||||
"ts-helpers": "^1.1.1",
|
"ts-helpers": "^1.1.1",
|
||||||
"web-animations-js": "^2.2.1",
|
"web-animations-js": "^2.2.1",
|
||||||
|
@ -100,6 +100,7 @@ export class Configuration {
|
|||||||
oidc_scope?: StringValueItem;
|
oidc_scope?: StringValueItem;
|
||||||
count_per_project: NumberValueItem;
|
count_per_project: NumberValueItem;
|
||||||
storage_per_project: NumberValueItem;
|
storage_per_project: NumberValueItem;
|
||||||
|
cfg_expiration: NumberValueItem;
|
||||||
public constructor() {
|
public constructor() {
|
||||||
this.auth_mode = new StringValueItem("db_auth", true);
|
this.auth_mode = new StringValueItem("db_auth", true);
|
||||||
this.project_creation_restriction = new StringValueItem("everyone", true);
|
this.project_creation_restriction = new StringValueItem("everyone", true);
|
||||||
|
@ -9,6 +9,7 @@ import { GcViewModelFactory } from './gc.viewmodel.factory';
|
|||||||
import { CronScheduleComponent } from '../../cron-schedule/cron-schedule.component';
|
import { CronScheduleComponent } from '../../cron-schedule/cron-schedule.component';
|
||||||
import { CronTooltipComponent } from "../../cron-schedule/cron-tooltip/cron-tooltip.component";
|
import { CronTooltipComponent } from "../../cron-schedule/cron-tooltip/cron-tooltip.component";
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
|
import { GcJobData } from './gcLog';
|
||||||
|
|
||||||
describe('GcComponent', () => {
|
describe('GcComponent', () => {
|
||||||
let component: GcComponent;
|
let component: GcComponent;
|
||||||
@ -18,13 +19,17 @@ describe('GcComponent', () => {
|
|||||||
systemInfoEndpoint: "/api/system/gc"
|
systemInfoEndpoint: "/api/system/gc"
|
||||||
};
|
};
|
||||||
let mockSchedule = [];
|
let mockSchedule = [];
|
||||||
let mockJobs = [
|
let mockJobs: GcJobData[] = [
|
||||||
{
|
{
|
||||||
id: 22222,
|
id: 22222,
|
||||||
schedule: null,
|
schedule: null,
|
||||||
job_status: 'string',
|
job_status: 'string',
|
||||||
creation_time: new Date(),
|
creation_time: new Date().toDateString(),
|
||||||
update_time: new Date(),
|
update_time: new Date().toDateString(),
|
||||||
|
job_name: 'string',
|
||||||
|
job_kind: 'string',
|
||||||
|
job_uuid: 'string',
|
||||||
|
delete: false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
let spySchedule: jasmine.Spy;
|
let spySchedule: jasmine.Spy;
|
||||||
|
@ -32,7 +32,7 @@ export class GcComponent implements OnInit {
|
|||||||
getText = 'CONFIG.GC';
|
getText = 'CONFIG.GC';
|
||||||
getLabelCurrent = 'GC.CURRENT_SCHEDULE';
|
getLabelCurrent = 'GC.CURRENT_SCHEDULE';
|
||||||
@Output() loadingGcStatus = new EventEmitter<boolean>();
|
@Output() loadingGcStatus = new EventEmitter<boolean>();
|
||||||
@ViewChild(CronScheduleComponent)
|
@ViewChild(CronScheduleComponent, {static: false})
|
||||||
CronScheduleComponent: CronScheduleComponent;
|
CronScheduleComponent: CronScheduleComponent;
|
||||||
constructor(
|
constructor(
|
||||||
private gcRepoService: GcRepoService,
|
private gcRepoService: GcRepoService,
|
||||||
|
@ -4,79 +4,73 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<label>{{defaultTextsObj.setQuota}}</label>
|
<label>{{defaultTextsObj.setQuota}}</label>
|
||||||
|
|
||||||
<form #quotaForm="ngForm" class="clr-form-compact"
|
<form #quotaForm="ngForm" class=" clr-form clr-form-horizontal"
|
||||||
[class.clr-form-compact-common]="!defaultTextsObj.isSystemDefaultQuota">
|
[class.clr-form-compact-common]="!defaultTextsObj.isSystemDefaultQuota">
|
||||||
<div class="form-group">
|
|
||||||
<label for="count" class="required">{{ defaultTextsObj.countQuota | translate}}</label>
|
<clr-input-container>
|
||||||
<label for="count" aria-haspopup="true" role="tooltip"
|
<label class="left-label required" for="storage">{{ defaultTextsObj?.storageQuota | translate}}
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right mr-3px"
|
<clr-tooltip>
|
||||||
[class.invalid]="countInput.invalid && (countInput.dirty || countInput.touched)">
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<input name="count" type="text" #countInput="ngModel" class="quota-input"
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
[(ngModel)]="quotaHardLimitValue.countLimit" pattern="(^-1$)|(^([1-9]+)([0-9]+)*$)" required id="count"
|
<span>{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
||||||
size="40">
|
</clr-tooltip-content>
|
||||||
<span class="tooltip-content">
|
</clr-tooltip>
|
||||||
{{ 'PROJECT.COUNT_QUOTA_TIP' | translate }}
|
<div class="progress-block progress-min-width progress-div" *ngIf="!defaultTextsObj.isSystemDefaultQuota">
|
||||||
</span>
|
<div class="progress success" [class.warning]="isWarningColor(+quotaHardLimitValue.countLimit, quotaHardLimitValue.countUsed)"
|
||||||
</label>
|
[class.danger]="isDangerColor(+quotaHardLimitValue.countLimit, quotaHardLimitValue.countUsed)">
|
||||||
<div class="select-div"></div>
|
<progress value="{{countInput.invalid || +quotaHardLimitValue.countLimit===-1?0:quotaHardLimitValue.countUsed}}"
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
max="{{countInput.invalid?100:quotaHardLimitValue.countLimit}}" data-displayval="100%"></progress>
|
||||||
class="tooltip tooltip-lg tooltip-top-right mr-0">
|
</div>
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
<label class="progress-label">{{ quotaHardLimitValue?.countUsed }} {{ 'QUOTA.OF' | translate }}
|
||||||
<span class="tooltip-content">{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
{{ countInput?.valid?+quotaHardLimitValue?.countLimit===-1 ? ('QUOTA.UNLIMITED' | translate): quotaHardLimitValue?.countLimit:('QUOTA.INVALID_INPUT' | translate)}}
|
||||||
</a>
|
</label>
|
||||||
<div class="progress-block progress-min-width progress-div" *ngIf="!defaultTextsObj.isSystemDefaultQuota">
|
</div>
|
||||||
<div class="progress success" [class.warning]="isWarningColor(+quotaHardLimitValue.countLimit, quotaHardLimitValue.countUsed)"
|
|
||||||
[class.danger]="isDangerColor(+quotaHardLimitValue.countLimit, quotaHardLimitValue.countUsed)">
|
|
||||||
<progress value="{{countInput.invalid || +quotaHardLimitValue.countLimit===-1?0:quotaHardLimitValue.countUsed}}"
|
|
||||||
max="{{countInput.invalid?100:quotaHardLimitValue.countLimit}}" data-displayval="100%"></progress>
|
|
||||||
</div>
|
|
||||||
<label class="progress-label">{{ quotaHardLimitValue?.countUsed }} {{ 'QUOTA.OF' | translate }}
|
|
||||||
{{ countInput?.valid?+quotaHardLimitValue?.countLimit===-1 ? ('QUOTA.UNLIMITED' | translate): quotaHardLimitValue?.countLimit:('QUOTA.INVALID_INPUT' | translate)}}
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
<input clrInput type="text" name="count" #countInput="ngModel" class="quota-input"
|
||||||
</div>
|
[(ngModel)]="quotaHardLimitValue.countLimit" pattern="(^-1$)|(^([1-9]+)([0-9]+)*$)" required id="count"
|
||||||
<div class="form-group">
|
size="40" />
|
||||||
<label for="storage" class="required">{{ defaultTextsObj?.storageQuota | translate}}</label>
|
<clr-control-error>{{ 'PROJECT.COUNT_QUOTA_TIP' | translate }}</clr-control-error>
|
||||||
<label for="storage" aria-haspopup="true" role="tooltip"
|
</clr-input-container>
|
||||||
class="tooltip tooltip-validation tooltip-lg mr-3px tooltip-top-right"
|
|
||||||
[class.invalid]="(storageInput.invalid && (storageInput.dirty || storageInput.touched))||storageInput.errors">
|
<clr-input-container>
|
||||||
<input name="storage" type="text" #storageInput="ngModel" class="quota-input"
|
<label for="count" class="left-label required">{{ defaultTextsObj.countQuota | translate}}
|
||||||
[(ngModel)]="quotaHardLimitValue.storageLimit"
|
<clr-tooltip>
|
||||||
id="storage" size="40">
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<span class="tooltip-content">
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
{{ 'PROJECT.STORAGE_QUOTA_TIP' | translate }}
|
<span>{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
||||||
</span>
|
</clr-tooltip-content>
|
||||||
</label>
|
</clr-tooltip>
|
||||||
<div class="select-div">
|
<div class="clr-select-wrapper">
|
||||||
<select clrSelect name="storageUnit" [(ngModel)]="quotaHardLimitValue.storageUnit">
|
<select id="select-error" class="clr-select" name="storageUnit" [(ngModel)]="quotaHardLimitValue.storageUnit">
|
||||||
<ng-template ngFor let-quotaUnit [ngForOf]="quotaUnits" let-i="index">
|
<ng-template ngFor let-quotaUnit [ngForOf]="quotaUnits" let-i="index">
|
||||||
<option *ngIf="i>1" [value]="quotaUnit.UNIT">{{ quotaUnit?.UNIT }}</option>
|
<option *ngIf="i>1" [value]="quotaUnit.UNIT">{{ quotaUnit?.UNIT }}</option>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-lg tooltip-top-right mr-0">
|
<div class="progress-block progress-min-width progress-div" *ngIf="!defaultTextsObj.isSystemDefaultQuota">
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
<div class="progress success" [class.danger]="isDangerColor(+quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUsed, quotaHardLimitValue.storageUnit)"
|
||||||
<span class="tooltip-content">{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
[class.warning]="isWarningColor(+quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUsed, quotaHardLimitValue.storageUnit)" >
|
||||||
</a>
|
<progress value="{{storageInput.invalid || +quotaHardLimitValue.storageLimit === -1 ?0:quotaHardLimitValue.storageUsed}}"
|
||||||
<div class="progress-block progress-min-width progress-div" *ngIf="!defaultTextsObj.isSystemDefaultQuota">
|
max="{{storageInput.invalid?0:getByte(+quotaHardLimitValue.storageLimit, quotaHardLimitValue.storageUnit)}}"
|
||||||
<div class="progress success" [class.danger]="isDangerColor(+quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUsed, quotaHardLimitValue.storageUnit)"
|
data-displayval="100%"></progress>
|
||||||
[class.warning]="isWarningColor(+quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUsed, quotaHardLimitValue.storageUnit)">
|
</div>
|
||||||
<progress value="{{storageInput.invalid || +quotaHardLimitValue.storageLimit === -1 ?0:quotaHardLimitValue.storageUsed}}"
|
<label class="progress-label">
|
||||||
max="{{storageInput.invalid?0:getByte(+quotaHardLimitValue.storageLimit, quotaHardLimitValue.storageUnit)}}"
|
<!-- the comments of progress , when storageLimit !=-1 get integet and unit in hard storage and used storage;and the unit of used storage <= the unit of hard storage
|
||||||
data-displayval="100%"></progress>
|
the other : get suitable number and unit-->
|
||||||
</div>
|
{{ +quotaHardLimitValue.storageLimit !== -1 ?(getIntegerAndUnit(getByte(quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUnit), quotaHardLimitValue.storageUsed).partNumberUsed
|
||||||
<label class="progress-label">
|
+ getIntegerAndUnit(getByte(quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUnit), quotaHardLimitValue.storageUsed).partCharacterUsed) : getSuitableUnit(quotaHardLimitValue.storageUsed)}}
|
||||||
<!-- the comments of progress , when storageLimit !=-1 get integet and unit in hard storage and used storage;and the unit of used storage <= the unit of hard storage
|
{{ 'QUOTA.OF' | translate }}
|
||||||
the other : get suitable number and unit-->
|
{{ storageInput?.valid? +quotaHardLimitValue?.storageLimit ===-1? ('QUOTA.UNLIMITED' | translate): quotaHardLimitValue?.storageLimit :('QUOTA.INVALID_INPUT' | translate)}}
|
||||||
{{ +quotaHardLimitValue.storageLimit !== -1 ?(getIntegerAndUnit(getByte(quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUnit), quotaHardLimitValue.storageUsed).partNumberUsed
|
{{+quotaHardLimitValue?.storageLimit ===-1?'':quotaHardLimitValue?.storageUnit }}
|
||||||
+ getIntegerAndUnit(getByte(quotaHardLimitValue.storageLimit,quotaHardLimitValue.storageUnit), quotaHardLimitValue.storageUsed).partCharacterUsed) : getSuitableUnit(quotaHardLimitValue.storageUsed)}}
|
</label>
|
||||||
{{ 'QUOTA.OF' | translate }}
|
</div>
|
||||||
{{ storageInput?.valid? +quotaHardLimitValue?.storageLimit ===-1? ('QUOTA.UNLIMITED' | translate): quotaHardLimitValue?.storageLimit :('QUOTA.INVALID_INPUT' | translate)}}
|
|
||||||
{{+quotaHardLimitValue?.storageLimit ===-1?'':quotaHardLimitValue?.storageUnit }}
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
<input clrInput name="storage" type="text" #storageInput="ngModel" class="quota-input"
|
||||||
</div>
|
[(ngModel)]="quotaHardLimitValue.storageLimit"
|
||||||
|
id="storage" size="40"/>
|
||||||
|
<clr-control-error>{{ 'PROJECT.STORAGE_QUOTA_TIP' | translate }}</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -3,44 +3,61 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal-body {
|
.modal-body {
|
||||||
|
outline: none;
|
||||||
padding-top: 0.8rem;
|
padding-top: 0.8rem;
|
||||||
overflow-y: visible;
|
overflow-y: visible;
|
||||||
overflow-x: visible;
|
overflow-x: visible;
|
||||||
|
|
||||||
.clr-form-compact {
|
.clr-form {
|
||||||
div.form-group {
|
.left-label {
|
||||||
padding-left: 8.5rem;
|
width: 9.5rem;
|
||||||
|
|
||||||
.mr-3px {
|
|
||||||
margin-right: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quota-input {
|
|
||||||
width: 2rem;
|
|
||||||
padding-right: 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-div {
|
|
||||||
width: 2.5rem;
|
|
||||||
|
|
||||||
::ng-deep .clr-form-control {
|
|
||||||
margin-top: 0.28rem;
|
|
||||||
|
|
||||||
select {
|
|
||||||
padding-right: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mr-3px {
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-label {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quota-input {
|
||||||
|
width: 1.5rem;
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-right: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-validate-icon {
|
||||||
|
margin-left: -0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-div {
|
||||||
|
width: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-select-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
right: -5rem;
|
||||||
|
top: -0.08rem;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.clr-form-compact-common {
|
.clr-form-compact-common {
|
||||||
div.form-group {
|
.left-label {
|
||||||
padding-left: 6rem;
|
width: 7.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.select-div {
|
.quota-input {
|
||||||
width: 1.6rem;
|
margin-left: 0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.select-div {
|
||||||
|
width: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-select-wrapper {
|
||||||
|
right: -4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,35 +67,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.progress-div {
|
.progress-div {
|
||||||
position: relative;
|
position: absolute;
|
||||||
padding-right: 0.6rem;
|
padding-right: 0.6rem;
|
||||||
width: 9rem;
|
width: 9rem;
|
||||||
}
|
top: 0.2rem;
|
||||||
|
right: -13.1rem;
|
||||||
::ng-deep {
|
|
||||||
.progress {
|
|
||||||
&.warning>progress {
|
|
||||||
color: orange;
|
|
||||||
|
|
||||||
&::-webkit-progress-value {
|
|
||||||
background-color: orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-moz-progress-bar {
|
|
||||||
background-color: orange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-label {
|
.progress-label {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: -2.3rem;
|
right: -3rem;
|
||||||
top: 0;
|
margin-top: 0;
|
||||||
width: 3.5rem;
|
width: 4rem;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
overflow: hidden;
|
::ng-deep {
|
||||||
text-overflow: ellipsis;
|
.clr-error {
|
||||||
|
.clr-validate-icon {
|
||||||
|
margin-left: -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -38,10 +38,10 @@ export class EditProjectQuotasComponent implements OnInit {
|
|||||||
staticBackdrop = true;
|
staticBackdrop = true;
|
||||||
closable = false;
|
closable = false;
|
||||||
quotaForm: NgForm;
|
quotaForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent, {static: false})
|
||||||
inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
@ViewChild('quotaForm')
|
@ViewChild('quotaForm', {static: true})
|
||||||
currentForm: NgForm;
|
currentForm: NgForm;
|
||||||
@Output() confirmAction = new EventEmitter();
|
@Output() confirmAction = new EventEmitter();
|
||||||
quotaDangerCoefficient: number = QUOTA_DANGER_COEFFICIENT;
|
quotaDangerCoefficient: number = QUOTA_DANGER_COEFFICIENT;
|
||||||
|
@ -40,3 +40,19 @@
|
|||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::ng-deep {
|
||||||
|
.progress {
|
||||||
|
&.warning>progress {
|
||||||
|
color: orange;
|
||||||
|
|
||||||
|
&::-webkit-progress-value {
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-progress-bar {
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@ const QuotaType = 'project';
|
|||||||
export class ProjectQuotasComponent implements OnChanges {
|
export class ProjectQuotasComponent implements OnChanges {
|
||||||
|
|
||||||
config: Configuration = new Configuration();
|
config: Configuration = new Configuration();
|
||||||
@ViewChild('editProjectQuotas')
|
@ViewChild('editProjectQuotas', {static: false})
|
||||||
editQuotaDialog: EditProjectQuotasComponent;
|
editQuotaDialog: EditProjectQuotasComponent;
|
||||||
loading = true;
|
loading = true;
|
||||||
quotaHardLimitValue: QuotaHardLimitInterface;
|
quotaHardLimitValue: QuotaHardLimitInterface;
|
||||||
|
@ -29,10 +29,10 @@ export class RegistryConfigComponent implements OnInit {
|
|||||||
|
|
||||||
@Input() hasAdminRole: boolean = false;
|
@Input() hasAdminRole: boolean = false;
|
||||||
|
|
||||||
@ViewChild("systemSettings") systemSettings: SystemSettingsComponent;
|
@ViewChild("systemSettings", {static: false}) systemSettings: SystemSettingsComponent;
|
||||||
@ViewChild("vulnerabilityConfig") vulnerabilityCfg: VulnerabilityConfigComponent;
|
@ViewChild("vulnerabilityConfig", {static: false}) vulnerabilityCfg: VulnerabilityConfigComponent;
|
||||||
@ViewChild("gc") gc: GcComponent;
|
@ViewChild("gc", {static: false}) gc: GcComponent;
|
||||||
@ViewChild("cfgConfirmationDialog") confirmationDlg: ConfirmationDialogComponent;
|
@ViewChild("cfgConfirmationDialog", {static: false}) confirmationDlg: ConfirmationDialogComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private configService: ConfigurationService,
|
private configService: ConfigurationService,
|
||||||
|
@ -22,7 +22,7 @@ export class ReplicationConfigComponent {
|
|||||||
|
|
||||||
@Input() showSubTitle: boolean = false;
|
@Input() showSubTitle: boolean = false;
|
||||||
|
|
||||||
@ViewChild("replicationConfigFrom") replicationConfigForm: NgForm;
|
@ViewChild("replicationConfigFrom", { static: false }) replicationConfigForm: NgForm;
|
||||||
|
|
||||||
get editable(): boolean {
|
get editable(): boolean {
|
||||||
return this.replicationConfig &&
|
return this.replicationConfig &&
|
||||||
|
@ -1,140 +1,142 @@
|
|||||||
<form #systemConfigFrom="ngForm" class="compact">
|
<form #systemConfigFrom="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<section class="form-block">
|
<section>
|
||||||
<label class="subtitle" *ngIf="showSubTitle">{{'CONFIG.SYSTEM' | translate}}</label>
|
<label class="subtitle" *ngIf="showSubTitle">{{'CONFIG.SYSTEM' | translate}}</label>
|
||||||
<div class="form-group">
|
<clr-select-container>
|
||||||
<label for="proCreation">{{'CONFIG.PRO_CREATION_RESTRICTION' | translate}}</label>
|
<label for="proCreation">{{'CONFIG.PRO_CREATION_RESTRICTION' | translate}}
|
||||||
<div class="select">
|
<clr-tooltip>
|
||||||
<select id="proCreation" name="proCreation"
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
[(ngModel)]="systemSettings.project_creation_restriction.value"
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
[disabled]="disabled(systemSettings.project_creation_restriction)">
|
<span>{{'CONFIG.TOOLTIP.PRO_CREATION_RESTRICTION' | translate}}</span>
|
||||||
<option value="everyone">{{'CONFIG.PRO_CREATION_EVERYONE' | translate }}</option>
|
</clr-tooltip-content>
|
||||||
<option value="adminonly">{{'CONFIG.PRO_CREATION_ADMIN' | translate }}</option>
|
</clr-tooltip>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-lg tooltip-top-right">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.PRO_CREATION_RESTRICTION' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="tokenExpiration" class="required">{{'CONFIG.TOKEN_EXPIRATION' | translate}}</label>
|
|
||||||
<label for="tokenExpiration" aria-haspopup="true" role="tooltip"
|
|
||||||
class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
|
||||||
[class.invalid]="tokenExpirationInput.invalid && (tokenExpirationInput.dirty || tokenExpirationInput.touched)">
|
|
||||||
<input name="tokenExpiration" type="text" #tokenExpirationInput="ngModel"
|
|
||||||
[(ngModel)]="systemSettings.token_expiration.value"
|
|
||||||
required pattern="^[1-9]{1}[0-9]*$" id="tokenExpiration" size="20" [disabled]="!editable">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.NUMBER_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
|
<select clrSelect id="proCreation" name="proCreation"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
[(ngModel)]="systemSettings.project_creation_restriction.value"
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.TOKEN_EXPIRATION' | translate}}</span>
|
[disabled]="disabled(systemSettings.project_creation_restriction)">
|
||||||
</a>
|
<option value="everyone">{{'CONFIG.PRO_CREATION_EVERYONE' | translate }}</option>
|
||||||
</div>
|
<option value="adminonly">{{'CONFIG.PRO_CREATION_ADMIN' | translate }}</option>
|
||||||
<div class="form-group">
|
</select>
|
||||||
<label for="robotTokenExpiration" class="required">{{'ROBOT_ACCOUNT.TOKEN_EXPIRATION' | translate}}</label>
|
</clr-select-container>
|
||||||
<label for="robotTokenExpiration" aria-haspopup="true" role="tooltip"
|
<clr-input-container>
|
||||||
class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
<label for="tokenExpiration" class="required">{{'CONFIG.TOKEN_EXPIRATION' | translate}}
|
||||||
[class.invalid]="robotTokenExpirationInput.invalid && (robotTokenExpirationInput.dirty || robotTokenExpirationInput.touched)">
|
<clr-tooltip>
|
||||||
<input name="robotTokenExpiration" type="text" #robotTokenExpirationInput="ngModel"
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
(ngModelChange)="changeToken($event)" [(ngModel)]="robotTokenExpiration"
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
required pattern="^[1-9]{1}[0-9]*$" id="robotTokenExpiration" size="20"
|
<span>{{'CONFIG.TOOLTIP.TOKEN_EXPIRATION' | translate}}</span>
|
||||||
[disabled]="!robotExpirationEditable">
|
</clr-tooltip-content>
|
||||||
<span class="tooltip-content">
|
</clr-tooltip>
|
||||||
{{'ROBOT_ACCOUNT.NUMBER_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
|
<input clrInput name="tokenExpiration" type="text" #tokenExpirationInput="ngModel"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
[(ngModel)]="systemSettings.token_expiration.value" required pattern="^[1-9]{1}[0-9]*$"
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.ROBOT_TOKEN_EXPIRATION' | translate}}</span>
|
id="tokenExpiration" size="20" [disabled]="!editable" />
|
||||||
</a>
|
<clr-control-error>{{'TOOLTIP.NUMBER_REQUIRED' | translate}}</clr-control-error>
|
||||||
</div>
|
|
||||||
<div class="form-group" *ngIf="canDownloadCert">
|
</clr-input-container>
|
||||||
<label for="certDownloadLink" class="required">{{'CONFIG.ROOT_CERT' | translate}}</label>
|
<clr-input-container>
|
||||||
|
<label for="robotTokenExpiration" class="required">{{'ROBOT_ACCOUNT.TOKEN_EXPIRATION' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.ROBOT_TOKEN_EXPIRATION' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="robotTokenExpiration" type="text" #robotTokenExpirationInput="ngModel"
|
||||||
|
(ngModelChange)="changeToken($event)" [(ngModel)]="robotTokenExpiration" required
|
||||||
|
pattern="^[1-9]{1}[0-9]*$" id="robotTokenExpiration" size="20" [disabled]="!robotExpirationEditable" />
|
||||||
|
<clr-control-error>{{'ROBOT_ACCOUNT.NUMBER_REQUIRED' | translate}}</clr-control-error>
|
||||||
|
|
||||||
|
</clr-input-container>
|
||||||
|
<label *ngIf="canDownloadCert" for="certDownloadLink"
|
||||||
|
class="required clr-control-label mt-1">{{'CONFIG.ROOT_CERT' | translate}}
|
||||||
<a #certDownloadLink [href]="downloadLink" target="_blank">{{'CONFIG.ROOT_CERT_LINK' | translate}}</a>
|
<a #certDownloadLink [href]="downloadLink" target="_blank">{{'CONFIG.ROOT_CERT_LINK' | translate}}</a>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
|
<clr-tooltip>
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.ROOT_CERT_DOWNLOAD' | translate}}</span>
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
</a>
|
<span>{{'CONFIG.TOOLTIP.ROOT_CERT_DOWNLOAD' | translate}}</span>
|
||||||
</div>
|
</clr-tooltip-content>
|
||||||
<div *ngIf="!withAdmiral" class="form-group">
|
</clr-tooltip>
|
||||||
<label for="repoReadOnly">{{'CONFIG.REPO_READ_ONLY' | translate}}</label>
|
</label>
|
||||||
|
<clr-checkbox-container *ngIf="!withAdmiral">
|
||||||
|
<label for="repoReadOnly">{{'CONFIG.REPO_READ_ONLY' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.REPO_TOOLTIP' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" clrCheckbox name="repoReadOnly" id="repoReadOnly"
|
<input type="checkbox" clrCheckbox name="repoReadOnly" id="repoReadOnly"
|
||||||
[ngModel]="systemSettings.read_only.value"
|
[ngModel]="systemSettings.read_only.value" (ngModelChange)="setRepoReadOnlyValue($event)" />
|
||||||
(ngModelChange)="setRepoReadOnlyValue($event)"/>
|
|
||||||
<label>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-top-right read-tooltip">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.REPO_TOOLTIP' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</label>
|
|
||||||
</clr-checkbox-wrapper>
|
</clr-checkbox-wrapper>
|
||||||
</div>
|
</clr-checkbox-container>
|
||||||
<div class="form-group" *ngIf="withClair">
|
|
||||||
<label for="systemWhitelist">{{'CVE_WHITELIST.DEPLOYMENT_SECURITY'|translate}}</label>
|
|
||||||
<div class="form-content w-100">
|
<div class="clr-form-control d-f" *ngIf="withClair">
|
||||||
<div>
|
<label for="systemWhitelist"
|
||||||
<div>
|
class="clr-control-label">{{'CVE_WHITELIST.DEPLOYMENT_SECURITY'|translate}}</label>
|
||||||
<span class="title">{{'CVE_WHITELIST.CVE_WHITELIST'|translate}}</span>
|
<div class="form-content">
|
||||||
|
<div class="font-size-13">
|
||||||
|
<div class="mt-05">
|
||||||
|
<span class="title font-size-13">{{'CVE_WHITELIST.CVE_WHITELIST'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mt-05">
|
||||||
<span>{{'CVE_WHITELIST.SYS_WHITELIST_EXPLAIN'|translate}}</span>
|
<span>{{'CVE_WHITELIST.SYS_WHITELIST_EXPLAIN'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mt-05">
|
||||||
<span>{{'CVE_WHITELIST.ADD_SYS'|translate}}</span>
|
<span>{{'CVE_WHITELIST.ADD_SYS'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="hasExpired">
|
<div class="mt-05" *ngIf="hasExpired">
|
||||||
<span class="label label-warning">{{'CVE_WHITELIST.WARNING_SYS'|translate}}</span>
|
<span class="label label-warning">{{'CVE_WHITELIST.WARNING_SYS'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clr-row width-70per">
|
<div class="clr-row width-90per">
|
||||||
<div class="clr-col position-relative">
|
<div class="position-relative pl-05">
|
||||||
<div>
|
<div>
|
||||||
<button id="show-add-modal-button" (click)="showAddModal=!showAddModal"
|
<button id="show-add-modal-button" (click)="showAddModal=!showAddModal"
|
||||||
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="add-modal" *ngIf="showAddModal">
|
<div class="add-modal" *ngIf="showAddModal">
|
||||||
<clr-icon (click)="showAddModal=false" class="float-lg-right margin-top-4" shape="window-close"></clr-icon>
|
<clr-icon (click)="showAddModal=false" class="float-lg-right margin-top-4"
|
||||||
|
shape="window-close"></clr-icon>
|
||||||
<div>
|
<div>
|
||||||
<clr-textarea-container>
|
<clr-textarea-container class="flex-direction-column">
|
||||||
<label>{{'CVE_WHITELIST.ENTER'|translate}}</label>
|
<label>{{'CVE_WHITELIST.ENTER'|translate}}</label>
|
||||||
<textarea id="whitelist-textarea" class="w-100 font-italic" clrTextarea [(ngModel)]="cveIds"
|
<textarea id="whitelist-textarea" class="w-100 font-italic" clrTextarea [(ngModel)]="cveIds"
|
||||||
name="cveIds"></textarea>
|
name="cveIds"></textarea>
|
||||||
<clr-control-helper>{{'CVE_WHITELIST.HELP'|translate}}</clr-control-helper>
|
<clr-control-helper>{{'CVE_WHITELIST.HELP'|translate}}</clr-control-helper>
|
||||||
</clr-textarea-container>
|
</clr-textarea-container>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button id="add-to-system" [disabled]="isDisabled()" (click)="addToSystemWhitelist()"
|
<button id="add-to-system" [disabled]="isDisabled()" (click)="addToSystemWhitelist()"
|
||||||
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="whitelist-window">
|
<ul class="whitelist-window">
|
||||||
<li *ngIf="systemWhitelist?.items?.length<1"
|
<li *ngIf="systemWhitelist?.items?.length<1" class="none">{{'CVE_WHITELIST.NONE'|translate}}
|
||||||
class="none">{{'CVE_WHITELIST.NONE'|translate}}</li>
|
</li>
|
||||||
<li *ngFor="let item of systemWhitelist?.items;let i = index;">
|
<li *ngFor="let item of systemWhitelist?.items;let i = index;">
|
||||||
<span class="hand" (click)="goToDetail(item.cve_id)">{{item.cve_id}}</span>
|
<span class="hand" (click)="goToDetail(item.cve_id)">{{item.cve_id}}</span>
|
||||||
<clr-icon (click)="deleteItem(i)" class="float-lg-right margin-top-4"
|
<clr-icon (click)="deleteItem(i)" class="float-lg-right margin-top-4"
|
||||||
shape="times-circle"></clr-icon>
|
shape="times-circle"></clr-icon>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="clr-col padding-top-8">
|
<div class="clr-col padding-top-8">
|
||||||
<div class="form-group padding-left-80">
|
<div class="clr-row expire-data">
|
||||||
<label for="expires">{{'CVE_WHITELIST.EXPIRES_AT'|translate}}</label>
|
<label class="bottom-line clr-col-4"
|
||||||
<div class="underline">
|
for="expires">{{'CVE_WHITELIST.EXPIRES_AT'|translate}}</label>
|
||||||
|
<div>
|
||||||
<input #dateInput placeholder="{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}" readonly
|
<input #dateInput placeholder="{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}" readonly
|
||||||
type="date" [(clrDate)]="expiresDate" newFormLayout="true">
|
type="date" [(clrDate)]="expiresDate" newFormLayout="true">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group padding-left-80">
|
<div class="clr-row">
|
||||||
|
<label class="clr-col-4"></label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input [checked]="neverExpires" [(ngModel)]="neverExpires" type="checkbox" clrCheckbox
|
<input [checked]="neverExpires" [(ngModel)]="neverExpires" type="checkbox" clrCheckbox
|
||||||
name="neverExpires" id="neverExpires"/>
|
name="neverExpires" id="neverExpires" />
|
||||||
<label>
|
<label>
|
||||||
{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}
|
{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}
|
||||||
</label>
|
</label>
|
||||||
@ -144,27 +146,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<clr-checkbox-container *ngIf="!withAdmiral">
|
||||||
<label for="webhookNotificationEnabled">{{'CONFIG.WEBHOOK_NOTIFICATION_ENABLED' | translate}}</label>
|
<label for="webhookNotificationEnabled">{{'CONFIG.WEBHOOK_NOTIFICATION_ENABLED' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.WEBHOOK_TOOLTIP' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" clrCheckbox name="webhookNotificationEnabled" id="webhookNotificationEnabled" [ngModel]="systemSettings.notification_enable.value"
|
<input type="checkbox" clrCheckbox name="webhookNotificationEnabled" id="webhookNotificationEnabled"
|
||||||
(ngModelChange)="setWebhookNotificationEnabledValue($event)" [ngModel]="systemSettings.notification_enable.value"/>
|
[ngModel]="systemSettings.notification_enable.value"
|
||||||
<label>
|
(ngModelChange)="setWebhookNotificationEnabledValue($event)"
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right read-tooltip">
|
[ngModel]="systemSettings.notification_enable.value" />
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.WEBHOOK_TOOLTIP' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</label>
|
|
||||||
</clr-checkbox-wrapper>
|
</clr-checkbox-wrapper>
|
||||||
</div>
|
</clr-checkbox-container>
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
<div>
|
<div>
|
||||||
<button type="button" id="config_system_save" class="btn btn-primary" (click)="save()"
|
<button type="button" id="config_system_save" class="btn btn-primary" (click)="save()"
|
||||||
[disabled]="(!isValid() || !hasChanges()) && (!hasWhitelistChanged) || inProgress">{{'BUTTON.SAVE'
|
[disabled]="(!isValid() || !hasChanges()) && (!hasWhitelistChanged) || inProgress">{{'BUTTON.SAVE'
|
||||||
| translate}}</button>
|
| translate}}</button>
|
||||||
<button type="button" class="btn btn-outline" (click)="cancel()"
|
<button type="button" class="btn btn-outline" (click)="cancel()"
|
||||||
[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>
|
@ -3,12 +3,43 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-tooltip {
|
.clr-form-horizontal {
|
||||||
top: -1;
|
.clr-form-control {
|
||||||
|
& >.clr-control-label {
|
||||||
|
width: 10rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.flex-direction-column {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom-line {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
.expire-data {
|
||||||
|
min-width: 12.5rem;
|
||||||
|
margin-top: -1rem;
|
||||||
|
}
|
||||||
|
.position-relative {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.pl-05 {
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
}
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.read-tooltip {
|
.d-f {
|
||||||
top: -7px;
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-size-13 {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.mt-05 {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@ -34,18 +65,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.width-70per {
|
.width-90per {
|
||||||
width: 70%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.none {
|
.none {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.underline {
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-0079bb {
|
.color-0079bb {
|
||||||
color: #0079bb;
|
color: #0079bb;
|
||||||
}
|
}
|
||||||
|
@ -66,9 +66,9 @@ export class SystemSettingsComponent implements OnChanges, OnInit {
|
|||||||
@Input() hasCAFile: boolean = false;
|
@Input() hasCAFile: boolean = false;
|
||||||
@Input() withAdmiral = false;
|
@Input() withAdmiral = false;
|
||||||
|
|
||||||
@ViewChild("systemConfigFrom") systemSettingsForm: NgForm;
|
@ViewChild("systemConfigFrom", {static: false}) systemSettingsForm: NgForm;
|
||||||
@ViewChild("cfgConfirmationDialog") confirmationDlg: ConfirmationDialogComponent;
|
@ViewChild("cfgConfirmationDialog", {static: false}) confirmationDlg: ConfirmationDialogComponent;
|
||||||
@ViewChild('dateInput') dateInput: ElementRef;
|
@ViewChild('dateInput', {static: false}) dateInput: ElementRef;
|
||||||
|
|
||||||
get editable(): boolean {
|
get editable(): boolean {
|
||||||
return this.systemSettings &&
|
return this.systemSettings &&
|
||||||
|
@ -34,7 +34,7 @@ export class VulnerabilityConfigComponent implements OnInit {
|
|||||||
openState: boolean = false;
|
openState: boolean = false;
|
||||||
getLabelCurrent: string;
|
getLabelCurrent: string;
|
||||||
|
|
||||||
@ViewChild(CronScheduleComponent)
|
@ViewChild(CronScheduleComponent, {static: false})
|
||||||
CronScheduleComponent: CronScheduleComponent;
|
CronScheduleComponent: CronScheduleComponent;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
@ -109,7 +109,7 @@ export class VulnerabilityConfigComponent implements OnInit {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ViewChild("systemConfigFrom") systemSettingsForm: NgForm;
|
@ViewChild("systemConfigFrom", {static: false}) systemSettingsForm: NgForm;
|
||||||
|
|
||||||
get isValid(): boolean {
|
get isValid(): boolean {
|
||||||
return this.systemSettingsForm && this.systemSettingsForm.valid;
|
return this.systemSettingsForm && this.systemSettingsForm.valid;
|
||||||
|
@ -9,98 +9,96 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form #targetForm="ngForm">
|
<form #targetForm="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<section class="form-block">
|
<!-- provider -->
|
||||||
<!-- provider -->
|
<clr-select-container>
|
||||||
<div class="form-group">
|
<label class="required">{{'DESTINATION.PROVIDER' | translate}}</label>
|
||||||
<label class="form-group-label-override required">{{'DESTINATION.PROVIDER' | translate}}</label>
|
<select clrSelect name="adapter" id="adapter" (change)="adapterChange($event)" [(ngModel)]="target.type" [disabled]="testOngoing || editDisabled">
|
||||||
<div class="form-select">
|
<option *ngFor="let adapter of adapterList" value="{{adapter}}">{{adapter}}</option>
|
||||||
<div class="select inputWidth pull-left">
|
</select>
|
||||||
<select name="adapter" id="adapter" (change)="adapterChange($event)" [(ngModel)]="target.type" [disabled]="testOngoing || editDisabled">
|
</clr-select-container>
|
||||||
<option *ngFor="let adapter of adapterList" value="{{adapter}}">{{adapter}}</option>
|
<!-- Endpoint name -->
|
||||||
</select>
|
<clr-input-container>
|
||||||
</div>
|
<label class="required">{{ 'DESTINATION.NAME' | translate }}</label>
|
||||||
|
<input clrInput type="text" id="destination_name" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.name"
|
||||||
|
name="targetName" size="30" #targetName="ngModel" required>
|
||||||
|
<clr-control-error *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
||||||
|
{{ 'DESTINATION.NAME_IS_REQUIRED' | translate }}
|
||||||
|
</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
|
<!--Description-->
|
||||||
|
<clr-textarea-container>
|
||||||
|
<label>{{'REPLICATION.DESCRIPTION' | translate}}</label>
|
||||||
|
<textarea clrTextarea type="text" class="inputWidth" row=3 name="description" [(ngModel)]="target.description"></textarea>
|
||||||
|
</clr-textarea-container>
|
||||||
|
<!-- Endpoint Url -->
|
||||||
|
<div class="clr-form-control">
|
||||||
|
<label for="destination_url" class="required clr-control-label">{{ 'DESTINATION.URL' | translate }}</label>
|
||||||
|
<div class="clr-control-container" [class.clr-error]="targetEndpoint?.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
||||||
|
<div class="clr-input-wrapper" *ngIf="!endpointList.length">
|
||||||
|
<input class="clr-input" type="text" id="destination_url" [disabled]="testOngoing || urlDisabled" [readonly]="!editable"
|
||||||
|
[(ngModel)]="target.url" size="30" name="endpointUrl" #targetEndpoint="ngModel" required placeholder="http(s)://192.168.1.1">
|
||||||
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="clr-select-wrapper" *ngIf="endpointList.length">
|
||||||
<!-- Endpoint name -->
|
<select id="destination_url" class="clr-select" *ngIf="endpointList.length" [(ngModel)]="target.url"
|
||||||
<div class="form-group">
|
name="endpointUrl" #targetEndpoint="ngModel">
|
||||||
<label for="destination_name" class="col-md-4 form-group-label-override required">{{ 'DESTINATION.NAME' |
|
|
||||||
translate }}</label>
|
|
||||||
<label class="col-md-8" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="targetName.errors && (targetName.dirty || targetName.touched)"
|
|
||||||
[class.valid]="targetName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
|
||||||
<input type="text" id="destination_name" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.name"
|
|
||||||
name="targetName" size="25" #targetName="ngModel" required>
|
|
||||||
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
|
||||||
{{ 'DESTINATION.NAME_IS_REQUIRED' | translate }}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<!--Description-->
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
|
|
||||||
<textarea type="text" class="inputWidth" row=3 name="description" [(ngModel)]="target.description"></textarea>
|
|
||||||
</div>
|
|
||||||
<!-- Endpoint Url -->
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="destination_url" class="col-md-4 form-group-label-override required">{{ 'DESTINATION.URL' |
|
|
||||||
translate }}</label>
|
|
||||||
<label class="col-md-8" for="destination_url" aria-haspopup="true" role="tooltip" [class.invalid]="targetEndpoint?.errors && (targetEndpoint?.dirty || targetEndpoint?.touched)"
|
|
||||||
[class.valid]="targetEndpoint?.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left clr-select-wrapper">
|
|
||||||
<input *ngIf="!endpointList.length" type="text" id="destination_url" [disabled]="testOngoing || urlDisabled" [readonly]="!editable" [(ngModel)]="target.url"
|
|
||||||
size="25" name="endpointUrl" #targetEndpoint="ngModel" required placeholder="http(s)://192.168.1.1">
|
|
||||||
<select id="destination_url" *ngIf="endpointList.length" [(ngModel)]="target.url" class="clr-select" name="endpointUrl" #targetEndpoint="ngModel">
|
|
||||||
<option class="display-none" value=""></option>
|
<option class="display-none" value=""></option>
|
||||||
<option *ngFor="let endpoint of endpointList" value="{{endpoint.value}}">{{endpoint.key}}</option>
|
<option *ngFor="let endpoint of endpointList" value="{{endpoint.value}}">{{endpoint.key}}</option>
|
||||||
</select>
|
</select>
|
||||||
<span class="tooltip-content" *ngIf="targetEndpoint?.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
</div>
|
||||||
{{ 'DESTINATION.URL_IS_REQUIRED' | translate }}
|
<clr-control-error *ngIf="targetEndpoint?.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
||||||
</span>
|
{{ 'DESTINATION.URL_IS_REQUIRED' | translate }}
|
||||||
</label>
|
</clr-control-error>
|
||||||
</div>
|
</div>
|
||||||
<!-- access_key -->
|
</div>
|
||||||
<div class="form-group">
|
<!-- access_key -->
|
||||||
<label for="destination_access_key" class="col-md-4 form-group-label-override">{{ 'DESTINATION.ACCESS_ID' |
|
<clr-input-container>
|
||||||
translate }}</label>
|
<label>{{ 'DESTINATION.ACCESS_ID' | translate }}</label>
|
||||||
<input type="text" placeholder="Access ID" class="col-md-8" id="destination_access_key" [disabled]="testOngoing" [readonly]="target.type ==='google-gcr' || !editable"
|
<input clrInput type="text" placeholder="Access ID" id="destination_access_key" [disabled]="testOngoing" [readonly]="target.type ==='google-gcr' || !editable"
|
||||||
[(ngModel)]="target.credential.access_key" size="28" name="access_key" #access_key="ngModel">
|
[(ngModel)]="target.credential.access_key" size="30" name="access_key" #access_key="ngModel">
|
||||||
|
</clr-input-container>
|
||||||
|
<!-- access_secret -->
|
||||||
|
<div class="clr-form-control">
|
||||||
|
<label for="destination_password" class="clr-control-label">{{ 'DESTINATION.ACCESS_SECRET' | translate }}</label>
|
||||||
|
<div class="clr-control-container">
|
||||||
|
<div class="clr-textarea-wrapper">
|
||||||
|
<input class="clr-input" *ngIf="target.type !=='google-gcr';else gcr_secret" type="password" placeholder="Access Secret"
|
||||||
|
id="destination_password" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.credential.access_secret"
|
||||||
|
size="30" name="access_secret" #access_secret="ngModel">
|
||||||
|
<ng-template #gcr_secret>
|
||||||
|
<textarea type="text" row="3" placeholder="Json Secret" class="clr-textarea" id="destination_password" [disabled]="testOngoing"
|
||||||
|
[readonly]="!editable" [(ngModel)]="target.credential.access_secret" name="access_secret" #access_secret="ngModel"></textarea>
|
||||||
|
</ng-template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- access_secret -->
|
</div>
|
||||||
<div class="form-group">
|
<!-- Verify Remote Cert -->
|
||||||
<label for="destination_password" class="col-md-4 form-group-label-override">{{ 'DESTINATION.ACCESS_SECRET' |
|
<clr-checkbox-container>
|
||||||
translate }}</label>
|
<label id="destination_insecure_checkbox"
|
||||||
<input *ngIf="target.type !=='google-gcr';else gcr_secret" type="password" placeholder="Access Secret" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="!editable"
|
for="destination_insecure">{{'CONFIG.VERIFY_REMOTE_CERT' | translate }}
|
||||||
[(ngModel)]="target.credential.access_secret" size="28" name="access_secret" #access_secret="ngModel">
|
|
||||||
<ng-template #gcr_secret>
|
|
||||||
<textarea type="text" row="3" placeholder="Json Secret" class="inputWidth" id="destination_password" [disabled]="testOngoing" [readonly]="!editable"
|
|
||||||
[(ngModel)]="target.credential.access_secret" name="access_secret" #access_secret="ngModel"></textarea>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
<!-- Verify Remote Cert -->
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="destination_insecure" id="destination_insecure_checkbox">{{'CONFIG.VERIFY_REMOTE_CERT' |
|
|
||||||
translate }}</label>
|
|
||||||
<input type="checkbox" clrCheckbox #insecure id="destination_insecure" [disabled]="testOngoing || !editable"
|
|
||||||
name="insecure" [ngModel]="!target.insecure" (ngModelChange)="setInsecureValue($event)" class="clr-checkbox">
|
|
||||||
<clr-tooltip>
|
<clr-tooltip>
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="md" *clrIfOpen>
|
<clr-tooltip-content clrPosition="top-right" clrSize="md" *clrIfOpen>
|
||||||
{{'CONFIG.TOOLTIP.VERIFY_REMOTE_CERT' | translate}}
|
{{'CONFIG.TOOLTIP.VERIFY_REMOTE_CERT' | translate}}
|
||||||
</clr-tooltip-content>
|
</clr-tooltip-content>
|
||||||
</clr-tooltip>
|
</clr-tooltip>
|
||||||
</div>
|
</label>
|
||||||
<div class="form-group" class="form-height">
|
<clr-checkbox-wrapper>
|
||||||
<label for="spin" class="col-md-4"></label>
|
<input type="checkbox" clrCheckbox #insecure id="destination_insecure" [disabled]="testOngoing || !editable" name="insecure"
|
||||||
<span class="col-md-8 spinner spinner-inline" [hidden]="!inProgress"></span>
|
[ngModel]="!target.insecure" (ngModelChange)="setInsecureValue($event)">
|
||||||
</div>
|
</clr-checkbox-wrapper>
|
||||||
</section>
|
</clr-checkbox-container>
|
||||||
|
<div class="clr-form-control" class="form-height">
|
||||||
|
<label for="spin" class="col-md-4"></label>
|
||||||
|
<span class="col-md-8 spinner spinner-inline" [hidden]="!inProgress"></span>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="inProgress || (targetEndpoint?.errors)">{{
|
<button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="inProgress || (targetEndpoint?.errors)">{{ 'DESTINATION.TEST_CONNECTION' | translate }}</button>
|
||||||
'DESTINATION.TEST_CONNECTION' | translate }}</button>
|
<button type="button" class="btn btn-outline" (click)="onCancel()" [disabled]="inProgress">{{ 'BUTTON.CANCEL' | translate }}</button>
|
||||||
<button type="button" class="btn btn-outline" (click)="onCancel()" [disabled]="inProgress">{{ 'BUTTON.CANCEL' |
|
<button type="submit" class="btn btn-primary" (click)="onSubmit()" [disabled]="!isValid">{{ 'BUTTON.OK' | translate }}
|
||||||
translate }}</button>
|
</button>
|
||||||
<button type="submit" class="btn btn-primary" (click)="onSubmit()" [disabled]="!isValid">{{ 'BUTTON.OK' | translate
|
|
||||||
}}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</clr-modal>
|
</clr-modal>
|
@ -63,13 +63,13 @@ export class CreateEditEndpointComponent
|
|||||||
selectedType: string;
|
selectedType: string;
|
||||||
initVal: Endpoint;
|
initVal: Endpoint;
|
||||||
targetForm: NgForm;
|
targetForm: NgForm;
|
||||||
@ViewChild("targetForm") currentForm: NgForm;
|
@ViewChild("targetForm", {static: false}) currentForm: NgForm;
|
||||||
targetEndpoint;
|
targetEndpoint;
|
||||||
testOngoing: boolean;
|
testOngoing: boolean;
|
||||||
onGoing: boolean;
|
onGoing: boolean;
|
||||||
endpointId: number | string;
|
endpointId: number | string;
|
||||||
|
|
||||||
@ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
|
@ViewChild(InlineAlertComponent, {static: false}) inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
@Output() reload = new EventEmitter<boolean>();
|
@Output() reload = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
<section>
|
<section>
|
||||||
<label>
|
<label>
|
||||||
<label for="name">{{'LABEL.LABEL_NAME' | translate}}</label>
|
<label for="name">{{'LABEL.LABEL_NAME' | translate}}</label>
|
||||||
<label aria-haspopup="true" role="tooltip" [class.invalid]="isLabelNameExist"
|
<label class="clr-control-container" [class.clr-error]="isLabelNameExist">
|
||||||
class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
|
<input clrInput type="text" id="name" name="name" required size="20" autocomplete="off"
|
||||||
<input type="text" id="name" name="name" required size="20" autocomplete="off"
|
|
||||||
[(ngModel)]="labelModel.name" #name="ngModel" (keyup)="existValid(labelModel.name)">
|
[(ngModel)]="labelModel.name" #name="ngModel" (keyup)="existValid(labelModel.name)">
|
||||||
<span class="tooltip-content">
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
{{'LABEL.NAME_ALREADY_EXISTS' | translate }}
|
<clr-control-error class="position-ab" *ngIf="isLabelNameExist">
|
||||||
</span>
|
{{'LABEL.NAME_ALREADY_EXISTS' | translate }}
|
||||||
|
</clr-control-error>
|
||||||
</label>
|
</label>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
@ -21,11 +21,11 @@
|
|||||||
[class.borderSty]="i.color == '#FFFFFF'" [ngStyle]="{'background-color': i.color, 'color': i.textColor }">Aa</label>
|
[class.borderSty]="i.color == '#FFFFFF'" [ngStyle]="{'background-color': i.color, 'color': i.textColor }">Aa</label>
|
||||||
</clr-dropdown-menu>
|
</clr-dropdown-menu>
|
||||||
</clr-dropdown>
|
</clr-dropdown>
|
||||||
<input type="text" id="color" size="8" name="color" disabled [(ngModel)]="labelModel.color" #color="ngModel">
|
<input clrInput type="text" id="color" size="8" name="color" disabled [(ngModel)]="labelModel.color" #color="ngModel">
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<label for="description">{{'LABEL.DESCRIPTION' | translate}}</label>
|
<label for="description">{{'LABEL.DESCRIPTION' | translate}}</label>
|
||||||
<input type="text" id="description" name="description" size="30" [(ngModel)]="labelModel.description"
|
<input clrInput type="text" id="description" name="description" size="30" [(ngModel)]="labelModel.description"
|
||||||
#description="ngModel">
|
#description="ngModel">
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
|
@ -58,8 +58,15 @@ form {
|
|||||||
|
|
||||||
.borderSty
|
.borderSty
|
||||||
{
|
{
|
||||||
border: 1px solid #A1A1A1 !important;
|
border: 1px solid #A1A1A1 !important;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
::ng-deep {
|
||||||
|
.clr-form-control {
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.position-ab {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
@ -58,7 +58,7 @@ describe("CreateEditLabelComponent (inline template)", () => {
|
|||||||
labelService = fixture.debugElement.injector.get(LabelService);
|
labelService = fixture.debugElement.injector.get(LabelService);
|
||||||
|
|
||||||
spy = spyOn(labelService, "getLabels").and.returnValue(
|
spy = spyOn(labelService, "getLabels").and.returnValue(
|
||||||
of(mockOneData)
|
of([mockOneData])
|
||||||
);
|
);
|
||||||
spyOne = spyOn(labelService, "createLabel").and.returnValue(
|
spyOne = spyOn(labelService, "createLabel").and.returnValue(
|
||||||
of(mockOneData)
|
of(mockOneData)
|
||||||
|
@ -52,7 +52,7 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
nameChecker = new Subject<string>();
|
nameChecker = new Subject<string>();
|
||||||
|
|
||||||
labelForm: NgForm;
|
labelForm: NgForm;
|
||||||
@ViewChild("labelForm") currentForm: NgForm;
|
@ViewChild("labelForm", {static: true}) currentForm: NgForm;
|
||||||
|
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Input() scope: string;
|
@Input() scope: string;
|
||||||
@ -71,7 +71,7 @@ export class CreateEditLabelComponent implements OnInit, OnDestroy {
|
|||||||
this.isLabelNameExist = false;
|
this.isLabelNameExist = false;
|
||||||
if (targets && targets.length) {
|
if (targets && targets.length) {
|
||||||
if (targets.find((target) => {
|
if (targets.find((target) => {
|
||||||
return target.name === name;
|
return target.name === name && target.id !== this.labelId;
|
||||||
})) {
|
})) {
|
||||||
this.isLabelNameExist = true;
|
this.isLabelNameExist = true;
|
||||||
}
|
}
|
||||||
|
@ -2,212 +2,223 @@
|
|||||||
<h3 class="modal-title">{{headerTitle | translate}}</h3>
|
<h3 class="modal-title">{{headerTitle | translate}}</h3>
|
||||||
<hbr-inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></hbr-inline-alert>
|
<hbr-inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></hbr-inline-alert>
|
||||||
<div class="modal-body modal-body-height">
|
<div class="modal-body modal-body-height">
|
||||||
<form [formGroup]="ruleForm" novalidate>
|
<form [formGroup]="ruleForm" novalidate class="clr-form clr-form-horizontal">
|
||||||
<section class="form-block">
|
<div class="clr-form-control" [class.clr-error]="(ruleForm.controls.name.touched && ruleForm.controls.name.invalid) || !isRuleNameValid">
|
||||||
<div class="form-group form-group-override">
|
<label class="clr-control-label required">{{'REPLICATION.NAME' | translate}}</label>
|
||||||
<label class="form-group-label-override required">{{'REPLICATION.NAME' | translate}}</label>
|
<div class="clr-control-container">
|
||||||
<label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='(ruleForm.controls.name.touched && ruleForm.controls.name.invalid) || !isRuleNameValid'>
|
<div class="clr-input-wrapper">
|
||||||
<input type="text" id="ruleName" pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" class="inputWidth" required maxlength="255" formControlName="name"
|
<input class="clr-input" type="text" id="ruleName" size="35" pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" required maxlength="255"
|
||||||
#ruleName (keyup)='checkRuleName()' autocomplete="off">
|
formControlName="name" #ruleName (keyup)='checkRuleName()' autocomplete="off">
|
||||||
<span class="tooltip-content">{{ruleNameTooltip | translate}}</span>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
|
<span class="spinner spinner-inline spinner-pos" [hidden]="!inNameChecking"></span>
|
||||||
|
</div>
|
||||||
|
<clr-control-error *ngIf="(ruleForm.controls.name.touched && ruleForm.controls.name.invalid) || !isRuleNameValid">{{ruleNameTooltip | translate}}</clr-control-error>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--Description-->
|
||||||
|
<clr-textarea-container>
|
||||||
|
<label>{{'REPLICATION.DESCRIPTION' | translate}}</label>
|
||||||
|
<textarea clrTextarea type="text" id="ruleDescription" class="inputWidth" row=3 formControlName="description"></textarea>
|
||||||
|
</clr-textarea-container>
|
||||||
|
<!-- replication mode -->
|
||||||
|
<clr-radio-container clrInline>
|
||||||
|
<label>{{'REPLICATION.REPLI_MODE' | translate}}</label>
|
||||||
|
<clr-radio-wrapper>
|
||||||
|
<input clrRadio type="radio" id="push_base" name="replicationMode" [value]=true [disabled]="policyId >= 0 || onGoing" [(ngModel)]="isPushMode"
|
||||||
|
(change)="pushModeChange()" [ngModelOptions]="{standalone: true}">
|
||||||
|
<label for="push_base">Push-based
|
||||||
|
<clr-tooltip class="mode-tooltip">
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
||||||
|
<span>{{'TOOLTIP.PUSH_BASED' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
</label>
|
</label>
|
||||||
<span class="spinner spinner-inline spinner-pos" [hidden]="!inNameChecking"></span>
|
</clr-radio-wrapper>
|
||||||
</div>
|
<clr-radio-wrapper>
|
||||||
<!--Description-->
|
<input clrRadio type="radio" id="pull_base" name="replicationMode" [value]=false [disabled]="policyId >= 0 || onGoing" [(ngModel)]="isPushMode"
|
||||||
<div class="form-group form-group-override">
|
(change)="pullModeChange()" [ngModelOptions]="{standalone: true}">
|
||||||
<label class="form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
|
<label for="pull_base">Pull-based
|
||||||
<textarea type="text" id="ruleDescription" class="inputWidth" row=3 formControlName="description"></textarea>
|
|
||||||
</div>
|
|
||||||
<!-- replication mode -->
|
|
||||||
<div class="form-group form-group-override">
|
|
||||||
<label class="form-group-label-override">{{'REPLICATION.REPLI_MODE' | translate}}</label>
|
|
||||||
<div class="radio-inline" [class.disabled]="policyId >= 0 || onGoing">
|
|
||||||
<input type="radio" id="push_base" name="replicationMode" [value]=true [disabled]="policyId >= 0 || onGoing" [(ngModel)]="isPushMode" (change)="pushModeChange()" [ngModelOptions]="{standalone: true}">
|
|
||||||
<label for="push_base">Push-based</label>
|
|
||||||
<clr-tooltip class="mode-tooltip">
|
<clr-tooltip class="mode-tooltip">
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
||||||
<span>{{'TOOLTIP.PUSH_BASED' | translate}}</span>
|
<span>{{'TOOLTIP.PULL_BASED' | translate}}</span>
|
||||||
</clr-tooltip-content>
|
</clr-tooltip-content>
|
||||||
</clr-tooltip>
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
</clr-radio-wrapper>
|
||||||
|
</clr-radio-container>
|
||||||
|
<!--source registry-->
|
||||||
|
<div class="clr-form-control" *ngIf="!isPushMode">
|
||||||
|
<label class="required clr-control-label">{{'REPLICATION.SOURCE_REGISTRY' | translate}}</label>
|
||||||
|
<div class="clr-control-container">
|
||||||
|
<div class="clr-select-wrapper">
|
||||||
|
<select class="clr-select select-width" id="src_registry_id" (change)="sourceChange($event)" formControlName="src_registry"
|
||||||
|
[compareWith]="equals">
|
||||||
|
<option class="display-none"></option>
|
||||||
|
<option *ngFor="let source of sourceList" [ngValue]="source">{{source.name}}-{{source.url}}</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="radio-inline" [class.disabled]="policyId >= 0 || onGoing">
|
<div class="space-between">
|
||||||
<input type="radio" id="pull_base" name="replicationMode" [value]=false [disabled]="policyId >= 0 || onGoing" [(ngModel)]="isPushMode" (change)="pullModeChange()" [ngModelOptions]="{standalone: true}">
|
<span *ngIf="noEndpointInfo.length != 0" class="alert-label">{{noEndpointInfo | translate}}</span>
|
||||||
<label for="pull_base">Pull-based</label>
|
<span class="alert-label go-link" *ngIf="noEndpointInfo.length != 0" (click)="goRegistry()">{{'REPLICATION.ENDPOINTS' | translate}}</span>
|
||||||
<clr-tooltip class="mode-tooltip">
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
|
||||||
<span>{{'TOOLTIP.PULL_BASED' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--source registry-->
|
</div>
|
||||||
<div *ngIf="!isPushMode" class="form-group form-group-override">
|
<!--images/Filter-->
|
||||||
<label class="form-group-label-override required">{{'REPLICATION.SOURCE_REGISTRY' | translate}}</label>
|
<div class="clr-form-control">
|
||||||
<div class="form-select">
|
<label class="clr-control-label">{{'REPLICATION.SOURCE_RESOURCE_FILTER' | translate}}</label>
|
||||||
<div class="select endpointSelect pull-left">
|
<span class="spinner spinner-inline spinner-position" [hidden]="onGoing === false"></span>
|
||||||
<select id="src_registry_id" (change)="sourceChange($event)" formControlName="src_registry" [compareWith]="equals">
|
<div formArrayName="filters" class="clr-control-container">
|
||||||
<option class="display-none"></option>
|
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index">
|
||||||
<option *ngFor="let source of sourceList" [ngValue]="source">{{source.name}}-{{source.url}}</option>
|
<div [formGroupName]="i" *ngIf="supportedFilters[i]?.type !=='label' || (supportedFilters[i]?.type==='label' && supportedFilterLabels?.length)">
|
||||||
</select>
|
<div class="width-70">
|
||||||
</div>
|
<label>{{"REPLICATION." + supportedFilters[i]?.type.toUpperCase() | translate}}:</label>
|
||||||
</div>
|
</div>
|
||||||
<label *ngIf="noEndpointInfo.length != 0" class="colorRed alertLabel">{{noEndpointInfo | translate}}</label>
|
<label *ngIf="supportedFilters[i]?.style==='input'" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
|
||||||
<span class="alertLabel goLink" *ngIf="noEndpointInfo.length != 0" (click)="goRegistry()">{{'REPLICATION.ENDPOINTS' | translate}}</span>
|
[class.invalid]='(filter.value.dirty || filter.value.touched) && filter.value.invalid'>
|
||||||
</div>
|
<input class="clr-input" (input)="trimText($event)" type="text" #filterValue size="14" formControlName="value" id="{{'filter_'+ supportedFilters[i]?.type}}">
|
||||||
<!--images/Filter-->
|
</label>
|
||||||
<div class="form-group form-group-override">
|
<div class="select resource-box clr-select-wrapper" *ngIf="supportedFilters[i]?.style==='radio' && supportedFilters[i]?.values.length > 1">
|
||||||
<label class="form-group-label-override">{{'REPLICATION.SOURCE_RESOURCE_FILTER' | translate}}</label>
|
<select class="clr-select width-100" formControlName="value" #selectedValue id="{{'select_'+ supportedFilters[i]?.type}}"
|
||||||
<span class="spinner spinner-inline spinner-position" [hidden]="onGoing === false"></span>
|
name="{{supportedFilters[i]?.type}}">
|
||||||
<div formArrayName="filters">
|
<option value="">{{'REPLICATION.BOTH' | translate}}</option>
|
||||||
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index">
|
<option *ngFor="let value of supportedFilters[i]?.values;" value="{{value}}">{{value}}</option>
|
||||||
<div [formGroupName]="i" *ngIf="supportedFilters[i]?.type !=='label' || (supportedFilters[i]?.type==='label' && supportedFilterLabels?.length)">
|
</select>
|
||||||
<div class="width-70" >
|
</div>
|
||||||
<label>{{"REPLICATION." + supportedFilters[i]?.type.toUpperCase() | translate}}:</label>
|
<div class="select resource-box" *ngIf="supportedFilters[i]?.type==='label'&& supportedFilters[i]?.style==='list'">
|
||||||
</div>
|
<div class="dropdown width-100 clr-select-wrapper" formArrayName="value">
|
||||||
<label *ngIf="supportedFilters[i]?.style==='input'" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
|
<clr-dropdown class="width-100">
|
||||||
[class.invalid]='(filter.value.dirty || filter.value.touched) && filter.value.invalid'>
|
<button type="button" class="width-100 dropdown-toggle btn btn-link statistic-data label-text" clrDropdownTrigger>
|
||||||
<input (input)="trimText($event)" type="text" #filterValue required size="14" formControlName="value" id="{{'filter_'+ supportedFilters[i]?.type}}">
|
<ng-template ngFor let-label [ngForOf]="filter.value.value" let-m="index">
|
||||||
<span class="tooltip-content">{{'TOOLTIP.EMPTY' | translate}}</span>
|
<span class="label" *ngIf="m<1"> {{label}} </span>
|
||||||
</label>
|
</ng-template>
|
||||||
<div class="select resource-box" *ngIf="supportedFilters[i]?.style==='radio' && supportedFilters[i]?.values.length > 1">
|
<span class="ellipsis" *ngIf="filter.value.value.length>1">···</span>
|
||||||
<select formControlName="value" #selectedValue id="{{'select_'+ supportedFilters[i]?.type}}" name="{{supportedFilters[i]?.type}}">
|
<div *ngFor="let label1 of filter.value.value;let k = index" hidden="true">
|
||||||
<option value="">{{'REPLICATION.BOTH' | translate}}</option>
|
<input type="text" [formControlName]="k" #labelValue id="{{'label_'+ supportedFilters[i]?.type + '_' + label1}}" name="{{'label_'+ supportedFilters[i]?.type + '_' + label1}}"
|
||||||
<option *ngFor="let value of supportedFilters[i]?.values;" value="{{value}}">{{value}}</option>
|
placeholder="select labels">
|
||||||
</select>
|
</div>
|
||||||
</div>
|
</button>
|
||||||
<div class="select resource-box" *ngIf="supportedFilters[i]?.type==='label'&& supportedFilters[i]?.style==='list'">
|
<clr-dropdown-menu class="width-100" clrPosition="bottom-left" *clrIfOpen>
|
||||||
<div class="dropdown width-100" formArrayName="value">
|
<button type="button" class="dropdown-item" *ngFor="let value of supportedFilterLabels" (click)="stickLabel(value,i)">
|
||||||
<clr-dropdown class="width-100">
|
<clr-icon shape="check" [hidden]="!value.select" class='pull-left'></clr-icon>
|
||||||
<button type="button" class="width-100 dropdown-toggle btn btn-link statistic-data label-text" clrDropdownTrigger>
|
<div class='labelDiv'>
|
||||||
<ng-template ngFor let-label [ngForOf]="filter.value.value" let-m="index">
|
<hbr-label-piece [label]="value" [labelWidth]="130"></hbr-label-piece>
|
||||||
<span class="label" *ngIf="m<1"> {{label}} </span>
|
|
||||||
</ng-template>
|
|
||||||
<span class="ellipsis" *ngIf="filter.value.value.length>1">···</span>
|
|
||||||
<div *ngFor="let label1 of filter.value.value;let k = index" hidden="true">
|
|
||||||
<input type="text" [formControlName]="k" #labelValue id="{{'label_'+ supportedFilters[i]?.type + '_' + label1}}" name="{{'label_'+ supportedFilters[i]?.type + '_' + label1}}" placeholder="select labels" >
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<clr-dropdown-menu class="width-100" clrPosition="bottom-left" *clrIfOpen>
|
</clr-dropdown-menu>
|
||||||
<button type="button" class="dropdown-item" *ngFor="let value of supportedFilterLabels" (click)="stickLabel(value,i)">
|
</clr-dropdown>
|
||||||
<clr-icon shape="check" [hidden]="!value.select" class='pull-left'></clr-icon>
|
|
||||||
<div class='labelDiv'><hbr-label-piece [label]="value" [labelWidth]="130"></hbr-label-piece></div>
|
|
||||||
</button>
|
|
||||||
</clr-dropdown-menu>
|
|
||||||
</clr-dropdown>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="resource-box" *ngIf="supportedFilters[i]?.style==='radio' && supportedFilters[i]?.values.length <= 1">
|
|
||||||
<span>{{supportedFilters[i]?.values}}</span>
|
|
||||||
</div>
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
|
||||||
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='name'">{{'TOOLTIP.NAME_FILTER' | translate}}</span>
|
|
||||||
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='tag'">{{'TOOLTIP.TAG_FILTER' | translate}}</span>
|
|
||||||
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='label'">{{'TOOLTIP.LABEL_FILTER' | translate}}</span>
|
|
||||||
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='resource'">{{'TOOLTIP.RESOURCE_FILTER' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="resource-box" *ngIf="supportedFilters[i]?.style==='radio' && supportedFilters[i]?.values.length <= 1">
|
||||||
|
<span>{{supportedFilters[i]?.values}}</span>
|
||||||
|
</div>
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
||||||
|
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='name'">{{'TOOLTIP.NAME_FILTER' | translate}}</span>
|
||||||
|
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='tag'">{{'TOOLTIP.TAG_FILTER' | translate}}</span>
|
||||||
|
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='label'">{{'TOOLTIP.LABEL_FILTER' | translate}}</span>
|
||||||
|
<span class="tooltip-content" *ngIf="supportedFilters[i]?.type==='resource'">{{'TOOLTIP.RESOURCE_FILTER' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--destination registry-->
|
</div>
|
||||||
<div *ngIf="isPushMode" class="form-group form-group-override">
|
<!--destination registry-->
|
||||||
<label class="form-group-label-override required">{{'REPLICATION.DEST_REGISTRY' | translate}}</label>
|
<div *ngIf="isPushMode" class="clr-form-control">
|
||||||
<div class="form-select">
|
<label class="clr-control-label required">{{'REPLICATION.DEST_REGISTRY' | translate}}
|
||||||
<div class="select endpointSelect pull-left">
|
<clr-tooltip>
|
||||||
<select id="dest_registry" (change)="targetChange($event)" formControlName="dest_registry" [compareWith]="equals">
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<option class="display-none"></option>
|
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
||||||
<option *ngFor="let target of targetList" [ngValue]="target">{{target.name}}-{{target.url}}</option>
|
<span>{{'TOOLTIP.DESTINATION_NAMESPACE' | translate}}</span>
|
||||||
</select>
|
</clr-tooltip-content>
|
||||||
</div>
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<div class="form-select clr-control-container">
|
||||||
|
<div class="clr-select-wrapper">
|
||||||
|
<select class="clr-select select-width" id="dest_registry" (change)="targetChange($event)" formControlName="dest_registry"
|
||||||
|
[compareWith]="equals">
|
||||||
|
<option class="display-none"></option>
|
||||||
|
<option *ngFor="let target of targetList" [ngValue]="target">{{target.name}}-{{target.url}}</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<label *ngIf="noEndpointInfo.length != 0" class="colorRed alertLabel">{{noEndpointInfo | translate}}</label>
|
<div class="space-between">
|
||||||
<span class="alertLabel goLink" *ngIf="noEndpointInfo.length != 0" (click)="goRegistry()">{{'REPLICATION.ENDPOINTS' | translate}}</span>
|
<label *ngIf="noEndpointInfo.length != 0" class="alert-label">{{noEndpointInfo | translate}}</label>
|
||||||
</div>
|
<span class="alert-label go-link" *ngIf="noEndpointInfo.length != 0" (click)="goRegistry()">{{'REPLICATION.ENDPOINTS' | translate}}</span>
|
||||||
<!--destination namespaces -->
|
|
||||||
<div class="form-group form-group-override">
|
|
||||||
<label class="form-group-label-override">{{'REPLICATION.DEST_NAMESPACE' | translate}}</label>
|
|
||||||
<div class="form-select">
|
|
||||||
<div class="endpointSelect pull-left">
|
|
||||||
<label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='ruleForm.controls.dest_namespace.touched && ruleForm.controls.dest_namespace.invalid'>
|
|
||||||
<input formControlName="dest_namespace" type="text" id="dest_namespace" pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" class="inputWidth"
|
|
||||||
maxlength="255">
|
|
||||||
<span class="tooltip-content">{{'REPLICATION.DESTINATION_NAME_TOOLTIP' | translate}}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
|
||||||
<span>{{'TOOLTIP.DESTINATION_NAMESPACE' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!--Trigger-->
|
<!--destination namespaces -->
|
||||||
<div class="form-group form-group-override">
|
<clr-input-container>
|
||||||
<label class="form-group-label-override required">{{'REPLICATION.TRIGGER_MODE' | translate}}</label>
|
<label>{{'REPLICATION.DEST_NAMESPACE' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
||||||
|
<span>{{'TOOLTIP.DESTINATION_NAMESPACE' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput formControlName="dest_namespace" type="text" id="dest_namespace" pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
|
||||||
|
class="inputWidth" maxlength="255">
|
||||||
|
<clr-control-error *ngIf='ruleForm.controls.dest_namespace.touched && ruleForm.controls.dest_namespace.invalid'>{{'REPLICATION.DESTINATION_NAME_TOOLTIP' | translate}}</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
|
<!--Trigger-->
|
||||||
|
<div class="clr-form-control">
|
||||||
|
<label class="clr-control-label required">{{'REPLICATION.TRIGGER_MODE' | translate}}</label>
|
||||||
|
<div class="clr-control-container">
|
||||||
<div formGroupName="trigger">
|
<div formGroupName="trigger">
|
||||||
<!--on trigger-->
|
<!--on trigger-->
|
||||||
<div class="select width-115">
|
<div class="select width-115 clr-select-wrapper">
|
||||||
<select id="ruleTrigger" formControlName="type">
|
<select id="ruleTrigger" formControlName="type" class="clr-select">
|
||||||
<option *ngFor="let trigger of supportedTriggers" [value]="trigger">{{'REPLICATION.' + trigger.toUpperCase() | translate }}</option>
|
<option *ngFor="let trigger of supportedTriggers" [value]="trigger">{{'REPLICATION.' + trigger.toUpperCase() | translate }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<!--on push-->
|
<div formGroupName="trigger_settings" class="clr-form-control">
|
||||||
<div formGroupName="trigger_settings">
|
<div [hidden]="isNotSchedule()">
|
||||||
<div [hidden]="isNotSchedule()" class="form-group form-cron">
|
|
||||||
<label class="required">Cron String</label>
|
<label class="required">Cron String</label>
|
||||||
<label for="targetCron" aria-haspopup="true" role="tooltip"class="tooltip tooltip-validation tooltip-sm tooltip-top-right"
|
<label for="targetCron" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-sm tooltip-top-right"
|
||||||
[class.invalid]="!isNotSchedule() && cronTouched && !cronInputValid(ruleForm.value.trigger?.trigger_settings?.cron || '')" >
|
[class.invalid]="!isNotSchedule() && cronTouched && !cronInputValid(ruleForm.value.trigger?.trigger_settings?.cron || '')">
|
||||||
<input type="text" name=targetCron id="targetCron" required class="form-control cron-input" formControlName="cron">
|
<input type="text" name=targetCron id="targetCron" required class="form-control cron-input clr-input" formControlName="cron">
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
{{'TOOLTIP.CRON_REQUIRED' | translate }}
|
{{'TOOLTIP.CRON_REQUIRED' | translate }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-lg tooltip-top-left top-7 cron-tooltip">
|
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-lg tooltip-top-left top-7 cron-tooltip">
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
||||||
<div class="tooltip-content table-box">
|
<div class="tooltip-content table-box">
|
||||||
<cron-tooltip></cron-tooltip>
|
<cron-tooltip></cron-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div [hidden]="isNotEventBased()" class="clr-form-control rule-width">
|
<div class="clr-checkbox-wrapper clr-form-control" [hidden]="isNotEventBased()">
|
||||||
<clr-checkbox-wrapper>
|
<input type="checkbox" class="clr-checkbox" [checked]="false" id="ruleDeletion" formControlName="deletion">
|
||||||
<input type="checkbox" clrCheckbox [checked]="false" id="ruleDeletion" formControlName="deletion" class="clr-checkbox">
|
<label for="ruleDeletion">{{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}</label>
|
||||||
<label for="ruleDeletion" class="clr-control-label">{{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}</label>
|
|
||||||
</clr-checkbox-wrapper>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="clr-form-control rule-width override-box">
|
<div class="clr-checkbox-wrapper clr-form-control">
|
||||||
<clr-checkbox-wrapper>
|
<input type="checkbox" class="clr-checkbox" [checked]="true" id="overridePolicy" formControlName="override">
|
||||||
<input type="checkbox" clrCheckbox [checked]="true" id="overridePolicy" formControlName="override" class="clr-checkbox">
|
<label for="overridePolicy">{{'REPLICATION.OVERRIDE_INFO' | translate}}
|
||||||
<label for="overridePolicy" class="clr-control-label">{{'REPLICATION.OVERRIDE_INFO' | translate}}</label>
|
|
||||||
</clr-checkbox-wrapper>
|
|
||||||
<clr-tooltip class="override-tooltip">
|
<clr-tooltip class="override-tooltip">
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
<clr-tooltip-content clrPosition="top-left" clrSize="md" *clrIfOpen>
|
||||||
<span>{{'TOOLTIP.OVERRIDE' | translate}}</span>
|
<span>{{'TOOLTIP.OVERRIDE' | translate}}</span>
|
||||||
</clr-tooltip-content>
|
</clr-tooltip-content>
|
||||||
</clr-tooltip>
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="clr-checkbox-wrapper clr-form-control">
|
||||||
|
<input type="checkbox" [checked]="true" id="enablePolicy" formControlName="enabled" class="clr-checkbox">
|
||||||
|
<label for="enablePolicy" class="clr-control-label">{{'REPLICATION.ENABLED_RULE' | translate}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="clr-form-control rule-width">
|
|
||||||
<clr-checkbox-wrapper>
|
|
||||||
<input type="checkbox" clrCheckbox [checked]="true" id="enablePolicy" formControlName="enabled" class="clr-checkbox">
|
|
||||||
<label for="enablePolicy" class="clr-control-label">{{'REPLICATION.ENABLED_RULE' | translate}}</label>
|
|
||||||
</clr-checkbox-wrapper>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="loading-center">
|
<div class="loading-center">
|
||||||
<span class="spinner spinner-inline" [hidden]="inProgress === false"></span>
|
<span class="spinner spinner-inline" [hidden]="inProgress === false"></span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</form>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" id="ruleBtnCancel" class="btn btn-outline" [disabled]="this.inProgress" (click)="onCancel()">{{ 'BUTTON.CANCEL' | translate }}</button>
|
<button type="button" id="ruleBtnCancel" class="btn btn-outline" [disabled]="this.inProgress" (click)="onCancel()">{{ 'BUTTON.CANCEL' | translate }}</button>
|
||||||
|
@ -14,19 +14,8 @@ h4 {
|
|||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colorRed {
|
.alert-label {
|
||||||
color: red;
|
color:red;
|
||||||
}
|
|
||||||
|
|
||||||
.colorRed a {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: #007CBB;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alertLabel {
|
|
||||||
display: block;
|
|
||||||
margin-top: 2px;
|
|
||||||
line-height: 1em;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +31,7 @@ h4 {
|
|||||||
.filterSelect {
|
.filterSelect {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 315px;
|
width: 315px;
|
||||||
|
margin-bottom:0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filterSelect clr-icon {
|
.filterSelect clr-icon {
|
||||||
@ -86,10 +76,6 @@ h4 {
|
|||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group {
|
|
||||||
min-height: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.projectInput {
|
.projectInput {
|
||||||
float: left;
|
float: left;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -167,10 +153,10 @@ h4 {
|
|||||||
margin-right: 120px;
|
margin-right: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goLink {
|
.go-link {
|
||||||
color: blue;
|
color: blue;
|
||||||
border-bottom: 1px solid blue;
|
border-bottom: 1px solid blue;
|
||||||
line-height: 14px;
|
line-height: 1rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,4 +279,13 @@ clr-modal {
|
|||||||
margin-left: 0.2rem;
|
margin-left: 0.2rem;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-between {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-width {
|
||||||
|
min-width:11rem;
|
||||||
}
|
}
|
@ -75,7 +75,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
@Output() goToRegistry = new EventEmitter<any>();
|
@Output() goToRegistry = new EventEmitter<any>();
|
||||||
@Output() reload = new EventEmitter<boolean>();
|
@Output() reload = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
|
@ViewChild(InlineAlertComponent, {static: true}) inlineAlert: InlineAlertComponent;
|
||||||
constructor(
|
constructor(
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private repService: ReplicationService,
|
private repService: ReplicationService,
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="setting-wrapper flex-layout" *ngIf="isEditMode">
|
<div class="setting-wrapper flex-layout" *ngIf="isEditMode">
|
||||||
<span class="font-style">{{ labelEdit | translate }}</span>
|
<span class="font-style">{{ labelEdit | translate }}</span>
|
||||||
<div class="select select-schedule">
|
<div class="select select-schedule clr-select-wrapper">
|
||||||
<select name="selectPolicy" id="selectPolicy" [(ngModel)]="scheduleType">
|
<select name="selectPolicy" id="selectPolicy" [(ngModel)]="scheduleType">
|
||||||
<option [value]="SCHEDULE_TYPE.NONE">{{'SCHEDULE.NONE' | translate}}</option>
|
<option [value]="SCHEDULE_TYPE.NONE">{{'SCHEDULE.NONE' | translate}}</option>
|
||||||
<option [value]="SCHEDULE_TYPE.HOURLY">{{'SCHEDULE.HOURLY' | translate}}</option>
|
<option [value]="SCHEDULE_TYPE.HOURLY">{{'SCHEDULE.HOURLY' | translate}}</option>
|
||||||
<option [value]="SCHEDULE_TYPE.DAILY">{{'SCHEDULE.DAILY' | translate}}</option>
|
<option [value]="SCHEDULE_TYPE.DAILY">{{'SCHEDULE.DAILY' | translate}}</option>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<span class="required" [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }}</span>
|
<span class="required" [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM">{{ "SCHEDULE.CRON" | translate }}</span>
|
||||||
<div [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM" class="cron-input">
|
<div [hidden]="scheduleType!==SCHEDULE_TYPE.CUSTOM" class="cron-input">
|
||||||
<label for="targetCron" aria-haspopup="true" role="tooltip" [class.invalid]="dateInvalid" class="tooltip tooltip-validation tooltip-md tooltip-top-left cron-label">
|
<label for="targetCron" aria-haspopup="true" role="tooltip" [class.invalid]="dateInvalid" class="tooltip tooltip-validation tooltip-md tooltip-top-left cron-label">
|
||||||
<input type="text" (blur)="blurInvalid()" (input)="inputInvalid()" name=targetCron id="targetCron" #cronStringInput="ngModel" required class="form-control"
|
<input type="text" (blur)="blurInvalid()" (input)="inputInvalid()" name=targetCron id="targetCron" #cronStringInput="ngModel" required class="clr-input form-control"
|
||||||
[(ngModel)]="cronString">
|
[(ngModel)]="cronString">
|
||||||
<span class="tooltip-content" *ngIf="dateInvalid">
|
<span class="tooltip-content" *ngIf="dateInvalid">
|
||||||
{{'TOOLTIP.CRON_REQUIRED' | translate }}
|
{{'TOOLTIP.CRON_REQUIRED' | translate }}
|
||||||
|
@ -17,7 +17,7 @@ export class DatePickerComponent implements OnChanges {
|
|||||||
@Input() dateInput: string;
|
@Input() dateInput: string;
|
||||||
@Input() oneDayOffset: boolean;
|
@Input() oneDayOffset: boolean;
|
||||||
|
|
||||||
@ViewChild("searchTime") searchTime: NgModel;
|
@ViewChild("searchTime", {static: true}) searchTime: NgModel;
|
||||||
|
|
||||||
@Output() search = new EventEmitter<string>();
|
@Output() search = new EventEmitter<string>();
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ describe("EndpointComponent (inline template)", () => {
|
|||||||
spyOnRules = spyOn(
|
spyOnRules = spyOn(
|
||||||
endpointService,
|
endpointService,
|
||||||
"getEndpointWithReplicationRules"
|
"getEndpointWithReplicationRules"
|
||||||
).and.returnValue([]);
|
).and.returnValue(of([]));
|
||||||
spyOne = spyOn(endpointService, "getEndpoint").and.returnValue(
|
spyOne = spyOn(endpointService, "getEndpoint").and.returnValue(
|
||||||
of(mockOne[0])
|
of(mockOne[0])
|
||||||
);
|
);
|
||||||
|
@ -53,10 +53,10 @@ import { OperationService } from "../operation/operation.service";
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class EndpointComponent implements OnInit, OnDestroy {
|
export class EndpointComponent implements OnInit, OnDestroy {
|
||||||
@ViewChild(CreateEditEndpointComponent)
|
@ViewChild(CreateEditEndpointComponent, {static: false})
|
||||||
createEditEndpointComponent: CreateEditEndpointComponent;
|
createEditEndpointComponent: CreateEditEndpointComponent;
|
||||||
|
|
||||||
@ViewChild("confirmationDialog")
|
@ViewChild("confirmationDialog", {static: false})
|
||||||
confirmationDialogComponent: ConfirmationDialogComponent;
|
confirmationDialogComponent: ConfirmationDialogComponent;
|
||||||
|
|
||||||
targets: Endpoint[];
|
targets: Endpoint[];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<span>
|
<span>
|
||||||
<clr-icon shape="search" size="20" class="search-btn" [class.filter-icon]="isShowSearchBox" (click)="onClick()"></clr-icon>
|
<clr-icon shape="search" size="20" class="search-btn" [class.filter-icon]="isShowSearchBox" (click)="onClick()"></clr-icon>
|
||||||
<input [hidden]="!isShowSearchBox" type="text" class="filter-input" autofocus (keyup)="valueChange()" (focus)="inputFocus()"
|
<input [hidden]="!isShowSearchBox" type="text" class="filter-input clr-input" autofocus (keyup)="valueChange()" (focus)="inputFocus()"
|
||||||
placeholder="{{placeHolder}}" [(ngModel)]="currentValue" />
|
placeholder="{{placeHolder}}" [(ngModel)]="currentValue" />
|
||||||
<span class="filter-divider" *ngIf="withDivider"></span>
|
<span class="filter-divider" *ngIf="withDivider"></span>
|
||||||
</span>
|
</span>
|
@ -61,8 +61,8 @@ export class GridViewComponent implements AfterViewInit {
|
|||||||
@Output() loadNextPageEvent = new EventEmitter<any>();
|
@Output() loadNextPageEvent = new EventEmitter<any>();
|
||||||
|
|
||||||
@ViewChildren("cardItem") cards: any;
|
@ViewChildren("cardItem") cards: any;
|
||||||
@ViewChild("itemsHolder") itemsHolder: any;
|
@ViewChild("itemsHolder", {static: false}) itemsHolder: any;
|
||||||
@ContentChild(TemplateRef) gridItemTmpl: any;
|
@ContentChild(TemplateRef, {static: false}) gridItemTmpl: any;
|
||||||
|
|
||||||
_items: any[] = [];
|
_items: any[] = [];
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import { ChannelService } from "../channel/index";
|
|||||||
import { Project } from "../project-policy-config/project";
|
import { Project } from "../project-policy-config/project";
|
||||||
import { IServiceConfig, SERVICE_CONFIG } from "../service.config";
|
import { IServiceConfig, SERVICE_CONFIG } from "../service.config";
|
||||||
import { of } from "rxjs";
|
import { of } from "rxjs";
|
||||||
|
import { HttpResponse } from "@angular/common/http";
|
||||||
|
|
||||||
describe("ImageNameInputComponent (inline template)", () => {
|
describe("ImageNameInputComponent (inline template)", () => {
|
||||||
let comp: ImageNameInputComponent;
|
let comp: ImageNameInputComponent;
|
||||||
@ -55,7 +56,7 @@ describe("ImageNameInputComponent (inline template)", () => {
|
|||||||
|
|
||||||
let projectService: ProjectService;
|
let projectService: ProjectService;
|
||||||
projectService = fixture.debugElement.injector.get(ProjectService);
|
projectService = fixture.debugElement.injector.get(ProjectService);
|
||||||
spy = spyOn(projectService, "listProjects").and.returnValues(of(mockProjects));
|
spy = spyOn(projectService, "listProjects").and.returnValues(of(new HttpResponse({ body: mockProjects })));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should load data", async(() => {
|
it("should load data", async(() => {
|
||||||
|
@ -56,9 +56,9 @@ export class LabelComponent implements OnInit {
|
|||||||
@Input() hasUpdateLabelPermission: boolean;
|
@Input() hasUpdateLabelPermission: boolean;
|
||||||
@Input() hasDeleteLabelPermission: boolean;
|
@Input() hasDeleteLabelPermission: boolean;
|
||||||
|
|
||||||
@ViewChild(CreateEditLabelComponent)
|
@ViewChild(CreateEditLabelComponent, {static: false})
|
||||||
createEditLabel: CreateEditLabelComponent;
|
createEditLabel: CreateEditLabelComponent;
|
||||||
@ViewChild("confirmationDialog")
|
@ViewChild("confirmationDialog", {static: false})
|
||||||
confirmationDialogComponent: ConfirmationDialogComponent;
|
confirmationDialogComponent: ConfirmationDialogComponent;
|
||||||
|
|
||||||
constructor(private labelService: LabelService,
|
constructor(private labelService: LabelService,
|
||||||
|
@ -85,10 +85,10 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
selectedRow: ReplicationRule;
|
selectedRow: ReplicationRule;
|
||||||
|
|
||||||
@ViewChild("toggleConfirmDialog")
|
@ViewChild("toggleConfirmDialog", {static: false})
|
||||||
toggleConfirmDialog: ConfirmationDialogComponent;
|
toggleConfirmDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
@ViewChild("deletionConfirmDialog")
|
@ViewChild("deletionConfirmDialog", {static: false})
|
||||||
deletionConfirmDialog: ConfirmationDialogComponent;
|
deletionConfirmDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
startTimeComparator: Comparator<ReplicationRule> = new CustomComparator<ReplicationRule>("start_time", "date");
|
startTimeComparator: Comparator<ReplicationRule> = new CustomComparator<ReplicationRule>("start_time", "date");
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="row flex-items-xs-between flex-items-xs-bottom">
|
<div class="row flex-items-xs-between flex-items-xs-bottom">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="action-head-pos">
|
<div class="action-head-pos">
|
||||||
<div class="select filterTag" [hidden]="!isOpenFilterTag">
|
<div class="select filter-tag clr-select-wrapper" [hidden]="!isOpenFilterTag">
|
||||||
<select id="selectKey" (change)="selectFilterKey($event)">
|
<select id="selectKey" (change)="selectFilterKey($event)">
|
||||||
<option value="username">{{"AUDIT_LOG.USERNAME" | translate | lowercase}}</option>
|
<option value="username">{{"AUDIT_LOG.USERNAME" | translate | lowercase}}</option>
|
||||||
<option value="repository">{{"CONFIG.REPOSITORY" | translate | lowercase}}</option>
|
<option value="repository">{{"CONFIG.REPOSITORY" | translate | lowercase}}</option>
|
||||||
@ -20,11 +20,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<clr-datagrid (clrDgRefresh)="load($event)" [clrDgLoading]="loading">
|
<clr-datagrid (clrDgRefresh)="load($event)" [clrDgLoading]="loading">
|
||||||
<clr-dg-column [clrDgField]="'username'">{{'AUDIT_LOG.USERNAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.USERNAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgField]="'repo_name'">{{'AUDIT_LOG.REPOSITORY_NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.REPOSITORY_NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgField]="'repo_tag'">{{'AUDIT_LOG.TAGS' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.TAGS' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgField]="'operation'">{{'AUDIT_LOG.OPERATION' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.OPERATION' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgSortBy]="opTimeComparator">{{'AUDIT_LOG.TIMESTAMP' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.TIMESTAMP' | translate}}</clr-dg-column>
|
||||||
<clr-dg-placeholder>{{ 'AUDIT_LOG.NOT_FOUND' | translate }}</clr-dg-placeholder>
|
<clr-dg-placeholder>{{ 'AUDIT_LOG.NOT_FOUND' | translate }}</clr-dg-placeholder>
|
||||||
<clr-dg-row *ngFor="let l of recentLogs">
|
<clr-dg-row *ngFor="let l of recentLogs">
|
||||||
<clr-dg-cell>{{l.username}}</clr-dg-cell>
|
<clr-dg-cell>{{l.username}}</clr-dg-cell>
|
||||||
@ -40,4 +40,4 @@
|
|||||||
</clr-dg-footer>
|
</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -52,7 +52,7 @@
|
|||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filterTag {
|
.filter-tag {
|
||||||
float: left;
|
float: left;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
@ -76,7 +76,7 @@ describe('RecentLogComponent (inline template)', () => {
|
|||||||
spy = spyOn(logService, 'getRecentLogs')
|
spy = spyOn(logService, 'getRecentLogs')
|
||||||
.and.callFake(function (params: RequestQueryParams) {
|
.and.callFake(function (params: RequestQueryParams) {
|
||||||
if (params && params.get('username')) {
|
if (params && params.get('username')) {
|
||||||
return of(mockData2).pipe(delay(0));
|
return of(mockData2);
|
||||||
} else {
|
} else {
|
||||||
if (params.get('page') === '1') {
|
if (params.get('page') === '1') {
|
||||||
mockData.data = mockItems.slice(0, 15);
|
mockData.data = mockItems.slice(0, 15);
|
||||||
|
@ -24,10 +24,8 @@ import { ErrorHandler } from '../error-handler/index';
|
|||||||
import { CustomComparator } from '../utils';
|
import { CustomComparator } from '../utils';
|
||||||
import {
|
import {
|
||||||
DEFAULT_PAGE_SIZE,
|
DEFAULT_PAGE_SIZE,
|
||||||
calculatePage,
|
|
||||||
doFiltering,
|
|
||||||
doSorting
|
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
import { finalize } from "rxjs/operators";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-log',
|
selector: 'hbr-log',
|
||||||
@ -43,14 +41,8 @@ export class RecentLogComponent implements OnInit {
|
|||||||
defaultFilter = "username";
|
defaultFilter = "username";
|
||||||
isOpenFilterTag: boolean;
|
isOpenFilterTag: boolean;
|
||||||
@Input() withTitle: boolean = false;
|
@Input() withTitle: boolean = false;
|
||||||
|
pageSize: number = 3;
|
||||||
pageSize: number = DEFAULT_PAGE_SIZE;
|
|
||||||
currentPage: number = 1; // Double bound to pagination component
|
currentPage: number = 1; // Double bound to pagination component
|
||||||
currentPagePvt: number = 0; // Used to confirm whether page is changed
|
|
||||||
currentState: State;
|
|
||||||
|
|
||||||
opTimeComparator: Comparator<AccessLogItem> = new CustomComparator<AccessLogItem>('op_time', 'date');
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private logService: AccessLogService,
|
private logService: AccessLogService,
|
||||||
private errorHandler: ErrorHandler) { }
|
private errorHandler: ErrorHandler) { }
|
||||||
@ -67,31 +59,14 @@ export class RecentLogComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public doFilter(terms: string): void {
|
public doFilter(terms: string): void {
|
||||||
|
|
||||||
// allow search by null characters
|
// allow search by null characters
|
||||||
if (terms === undefined || terms === null) {
|
if (terms === undefined || terms === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.currentTerm = terms.trim();
|
this.currentTerm = terms.trim();
|
||||||
// Trigger data loading and start from first page
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
if (this.currentPagePvt === 1) {
|
this.load({page: {}});
|
||||||
// Force reloading
|
|
||||||
let st: State = this.currentState;
|
|
||||||
if (!st) {
|
|
||||||
st = {
|
|
||||||
page: {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
st.page.from = 0;
|
|
||||||
st.page.to = this.pageSize - 1;
|
|
||||||
st.page.size = this.pageSize;
|
|
||||||
|
|
||||||
this.currentPagePvt = 0; // Reset pvt
|
|
||||||
|
|
||||||
this.load(st);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public refresh(): void {
|
public refresh(): void {
|
||||||
@ -111,57 +86,23 @@ export class RecentLogComponent implements OnInit {
|
|||||||
this.doFilter(this.currentTerm);
|
this.doFilter(this.currentTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
load(state: State) {
|
load(state) {
|
||||||
if (!state || !state.page) {
|
if (!state || !state.page) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Keep it for future filter
|
// Keep it for future filter
|
||||||
this.currentState = state;
|
// this.currentState = state;
|
||||||
|
let params: RequestQueryParams = new RequestQueryParams().set("page", '' + this.currentPage).set("page_size", '' + this.pageSize);
|
||||||
let pageNumber: number = calculatePage(state);
|
if (this.currentTerm && this.currentTerm !== "") {
|
||||||
if (pageNumber !== this.currentPagePvt) {
|
params = params.set(this.defaultFilter, this.currentTerm);
|
||||||
// load data
|
}
|
||||||
let params: RequestQueryParams = new RequestQueryParams().set("page", '' + pageNumber).set("page_size", '' + this.pageSize);
|
this.loading = true;
|
||||||
if (this.currentTerm && this.currentTerm !== "") {
|
this.logService.getRecentLogs(params).pipe(finalize(() => (this.loading = false)))
|
||||||
params = params.set(this.defaultFilter, this.currentTerm);
|
.subscribe(response => {
|
||||||
}
|
this.logsCache = response; // Keep the data
|
||||||
|
this.recentLogs = response.data;
|
||||||
this.loading = true;
|
|
||||||
this.logService.getRecentLogs(params)
|
|
||||||
.subscribe(response => {
|
|
||||||
this.logsCache = response; // Keep the data
|
|
||||||
this.recentLogs = this.logsCache.data.filter(log => log.username !== ""); // To display
|
|
||||||
|
|
||||||
// Do customized filter
|
|
||||||
this.recentLogs = doFiltering<AccessLogItem>(this.recentLogs, state);
|
|
||||||
|
|
||||||
// Do customized sorting
|
|
||||||
this.recentLogs = doSorting<AccessLogItem>(this.recentLogs, state);
|
|
||||||
|
|
||||||
this.currentPagePvt = pageNumber;
|
|
||||||
|
|
||||||
this.loading = false;
|
|
||||||
}, error => {
|
}, error => {
|
||||||
this.loading = false;
|
|
||||||
this.errorHandler.error(error);
|
this.errorHandler.error(error);
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// Column sorting and filtering
|
|
||||||
|
|
||||||
this.recentLogs = this.logsCache.data.filter(log => log.username !== ""); // Reset data
|
|
||||||
|
|
||||||
// Do customized filter
|
|
||||||
this.recentLogs = doFiltering<AccessLogItem>(this.recentLogs, state);
|
|
||||||
|
|
||||||
// Do customized sorting
|
|
||||||
this.recentLogs = doSorting<AccessLogItem>(this.recentLogs, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isMatched(terms: string, log: AccessLogItem): boolean {
|
|
||||||
let reg = new RegExp('.*' + terms + '.*', 'i');
|
|
||||||
return reg.test(log.username) ||
|
|
||||||
reg.test(log.repo_name) ||
|
|
||||||
reg.test(log.operation) ||
|
|
||||||
reg.test(log.repo_tag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,162 +1,159 @@
|
|||||||
<form #projectPolicyForm="ngForm">
|
<form #projectPolicyForm="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="form-group">
|
<clr-checkbox-container id="clr-wrapper-public">
|
||||||
<label for="projectPolicyForm">{{ 'PROJECT_CONFIG.REGISTRY' | translate }}</label>
|
<label>{{ 'PROJECT_CONFIG.REGISTRY' | translate }}</label>
|
||||||
<div class="form-content" id="clr-wrapper-public">
|
<clr-checkbox-wrapper>
|
||||||
<clr-checkbox-wrapper>
|
<input type="checkbox" id="clr-checkbox-wrapper-public" clrCheckbox [(ngModel)]="projectPolicy.Public"
|
||||||
<input type="checkbox" id="clr-checkbox-wrapper-public" clrCheckbox
|
name="public" [disabled]="!hasChangeConfigRole" />
|
||||||
[(ngModel)]="projectPolicy.Public" name="public"
|
<label>{{ 'PROJECT_CONFIG.PUBLIC_TOGGLE' | translate }}</label>
|
||||||
[disabled]="!hasChangeConfigRole"/>
|
</clr-checkbox-wrapper>
|
||||||
<label for="clr-checkbox-wrapper-public">{{ 'PROJECT_CONFIG.PUBLIC_TOGGLE' | translate }}</label>
|
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.PUBLIC_POLICY' | translate }}
|
||||||
</clr-checkbox-wrapper>
|
</clr-control-helper>
|
||||||
|
</clr-checkbox-container>
|
||||||
<div>
|
<clr-checkbox-container *ngIf="withNotary || withClair">
|
||||||
<label> {{ 'PROJECT_CONFIG.PUBLIC_POLICY' | translate }} </label>
|
<label><span *ngIf="withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||||
</div>
|
<clr-checkbox-wrapper *ngIf="withNotary">
|
||||||
</div>
|
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrust" name="content-trust"
|
||||||
</div>
|
[disabled]="!hasChangeConfigRole" />
|
||||||
<div class="form-group" *ngIf="withNotary || withClair">
|
<label>{{ 'PROJECT_CONFIG.CONTENT_TRUST_TOGGLE' | translate }}</label>
|
||||||
<label for="projectPolicyForm">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</label>
|
</clr-checkbox-wrapper>
|
||||||
<div class="form-content">
|
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.CONTENT_TRUST_POLCIY' | translate }}
|
||||||
<div *ngIf="withNotary">
|
</clr-control-helper>
|
||||||
<clr-checkbox-wrapper>
|
</clr-checkbox-container>
|
||||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.ContentTrust" name="content-trust"
|
<clr-checkbox-container id="prevent-vulenrability-image" *ngIf="withNotary || withClair">
|
||||||
[disabled]="!hasChangeConfigRole"/>
|
<label><span *ngIf="!withNotary">{{ 'PROJECT_CONFIG.SECURITY' | translate }}</span></label>
|
||||||
<label>{{ 'PROJECT_CONFIG.CONTENT_TRUST_TOGGLE' | translate }}</label>
|
<clr-checkbox-wrapper *ngIf="withClair">
|
||||||
</clr-checkbox-wrapper>
|
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.PreventVulImg"
|
||||||
|
name="prevent-vulenrability-image-input" [disabled]="!hasChangeConfigRole" />
|
||||||
<div class="chk-explain"><label> {{ 'PROJECT_CONFIG.CONTENT_TRUST_POLCIY' | translate }} </label>
|
<label>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_TOGGLE' | translate }}</label>
|
||||||
</div>
|
</clr-checkbox-wrapper>
|
||||||
</div>
|
<clr-control-helper class="config-subtext">
|
||||||
<div *ngIf="withClair" id="prevent-vulenrability-image">
|
<div class="chk-explain">
|
||||||
<clr-checkbox-wrapper>
|
<label class="config-subtext">
|
||||||
<input type="checkbox" clrCheckbox [(ngModel)]="projectPolicy.PreventVulImg"
|
<div id="severity-blk">
|
||||||
name="prevent-vulenrability-image-input"
|
<div>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_1' | translate }}</div>
|
||||||
[disabled]="!hasChangeConfigRole"/>
|
<div class="clr-select-wrapper">
|
||||||
<label>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_TOGGLE' | translate }}</label>
|
<select id="severity" name="severity" class="clr-select"
|
||||||
</clr-checkbox-wrapper>
|
[(ngModel)]="projectPolicy.PreventVulImgSeverity"
|
||||||
|
[disabled]="!projectPolicy.PreventVulImg">
|
||||||
<div class="chk-explain">
|
<option *ngFor='let s of severityOptions' [ngValue]="s.severity">
|
||||||
<label>
|
{{ s.severityLevel | translate }}</option>
|
||||||
<div id="severity-blk">
|
</select>
|
||||||
<div>{{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_1' | translate }}</div>
|
|
||||||
<div class="select">
|
|
||||||
<select id="severity" name="severity"
|
|
||||||
[(ngModel)]="projectPolicy.PreventVulImgSeverity"
|
|
||||||
[disabled]="!projectPolicy.PreventVulImg">
|
|
||||||
<option *ngFor='let s of severityOptions'
|
|
||||||
[ngValue]="s.severity">{{ s.severityLevel | translate }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div> {{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_2' | translate }} </div>
|
|
||||||
</div>
|
</div>
|
||||||
</label>
|
<div> {{ 'PROJECT_CONFIG.PREVENT_VULNERABLE_2' | translate }} </div>
|
||||||
</div>
|
</div>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</clr-control-helper>
|
||||||
</div>
|
</clr-checkbox-container>
|
||||||
<div class="form-group" *ngIf="withClair">
|
<clr-checkbox-container *ngIf="withClair">
|
||||||
<label for="projectPolicyForm">{{ 'PROJECT_CONFIG.SCAN' | translate }}</label>
|
<label>{{ 'PROJECT_CONFIG.SCAN' | translate }}</label>
|
||||||
<div class="form-content">
|
<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"
|
[disabled]="!hasChangeConfigRole" name="scan-image-on-push" />
|
||||||
[disabled]="!hasChangeConfigRole"
|
<label>{{ 'PROJECT_CONFIG.AUTOSCAN_TOGGLE' | translate }}</label>
|
||||||
name="scan-image-on-push"/>
|
</clr-checkbox-wrapper>
|
||||||
<label>{{ 'PROJECT_CONFIG.AUTOSCAN_TOGGLE' | translate }}</label>
|
<clr-control-helper class="config-subtext"> {{ 'PROJECT_CONFIG.AUTOSCAN_POLICY' | translate }}
|
||||||
</clr-checkbox-wrapper>
|
</clr-control-helper>
|
||||||
<div class="chk-explain"><label> {{ 'PROJECT_CONFIG.AUTOSCAN_POLICY' | translate }}</label></div>
|
</clr-checkbox-container>
|
||||||
</div>
|
<div class="clr-form-control" *ngIf="withClair">
|
||||||
</div>
|
<label for="systemWhitelist" class="clr-control-label">{{'CVE_WHITELIST.CVE_WHITELIST'|translate}}</label>
|
||||||
<div class="form-group" *ngIf="withClair">
|
<div class="w-100 clr-control-container">
|
||||||
<label for="systemWhitelist">{{'CVE_WHITELIST.CVE_WHITELIST'|translate}}</label>
|
<div class="config-subtext">
|
||||||
<div class="form-content w-100">
|
<div class="mt-05">
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<span>{{'CVE_WHITELIST.PRO_WHITELIST_EXPLAIN'|translate}}</span>
|
<span>{{'CVE_WHITELIST.PRO_WHITELIST_EXPLAIN'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mt-05">
|
||||||
<span>{{'CVE_WHITELIST.PRO_OR_SYS'|translate}}</span>
|
<span>{{'CVE_WHITELIST.PRO_OR_SYS'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mt-05">
|
||||||
<span>{{'CVE_WHITELIST.MERGE_INTO'|translate}}</span>
|
<span>{{'CVE_WHITELIST.MERGE_INTO'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="hasExpired">
|
<div *ngIf="hasExpired" class="mt-05">
|
||||||
<span *ngIf="isUseSystemWhitelist()"
|
<span *ngIf="isUseSystemWhitelist()"
|
||||||
class="label label-warning">{{'CVE_WHITELIST.WARNING_SYS'|translate}}</span>
|
class="label label-warning">{{'CVE_WHITELIST.WARNING_SYS'|translate}}</span>
|
||||||
<span *ngIf="!isUseSystemWhitelist()"
|
<span *ngIf="!isUseSystemWhitelist()"
|
||||||
class="label label-warning">{{'CVE_WHITELIST.WARNING_PRO'|translate}}</span>
|
class="label label-warning">{{'CVE_WHITELIST.WARNING_PRO'|translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<clr-radio-container clrInline>
|
<clr-radio-container clrInline>
|
||||||
<clr-radio-wrapper>
|
<clr-radio-wrapper>
|
||||||
<input id="use-system" [disabled]="!hasChangeConfigRole" type="radio" clrRadio name="systemWhitelistOrProjectWhitelist" required value="true"
|
<input id="use-system" [disabled]="!hasChangeConfigRole" type="radio" clrRadio
|
||||||
[(ngModel)]="systemWhitelistOrProjectWhitelist"/>
|
name="systemWhitelistOrProjectWhitelist" required value="true"
|
||||||
|
[(ngModel)]="systemWhitelistOrProjectWhitelist" />
|
||||||
<label>{{'CVE_WHITELIST.SYS_WHITELIST'|translate}}</label>
|
<label>{{'CVE_WHITELIST.SYS_WHITELIST'|translate}}</label>
|
||||||
</clr-radio-wrapper>
|
</clr-radio-wrapper>
|
||||||
<clr-radio-wrapper>
|
<clr-radio-wrapper>
|
||||||
<input id="use-project" [disabled]="!hasChangeConfigRole" type="radio" clrRadio name="systemWhitelistOrProjectWhitelist" required value="false"
|
<input id="use-project" [disabled]="!hasChangeConfigRole" type="radio" clrRadio
|
||||||
[(ngModel)]="systemWhitelistOrProjectWhitelist"/>
|
name="systemWhitelistOrProjectWhitelist" required value="false"
|
||||||
|
[(ngModel)]="systemWhitelistOrProjectWhitelist" />
|
||||||
<label>{{'CVE_WHITELIST.PRO_WHITELIST'|translate}}</label>
|
<label>{{'CVE_WHITELIST.PRO_WHITELIST'|translate}}</label>
|
||||||
</clr-radio-wrapper>
|
</clr-radio-wrapper>
|
||||||
</clr-radio-container>
|
</clr-radio-container>
|
||||||
<div class="clr-row width-90per">
|
<div class="clr-row width-90per">
|
||||||
<div class="clr-col position-relative">
|
<div class="clr-col position-relative col-flex-grow-0 ">
|
||||||
<div>
|
<div>
|
||||||
<button id="show-add-modal" [disabled]="isUseSystemWhitelist() || !hasChangeConfigRole"
|
<button id="show-add-modal" [disabled]="isUseSystemWhitelist() || !hasChangeConfigRole"
|
||||||
(click)="showAddModal=!showAddModal"
|
(click)="showAddModal=!showAddModal"
|
||||||
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
||||||
<button id="add-system" [disabled]="isUseSystemWhitelist() || !hasChangeConfigRole" (click)="addSystem()"
|
<button id="add-system" [disabled]="isUseSystemWhitelist() || !hasChangeConfigRole"
|
||||||
class="btn btn-link ml-1">{{'CVE_WHITELIST.ADD_SYSTEM'|translate}}</button>
|
(click)="addSystem()"
|
||||||
|
class="btn btn-link ml-1">{{'CVE_WHITELIST.ADD_SYSTEM'|translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="add-modal" *ngIf="showAddModal && !isUseSystemWhitelist()">
|
<div class="add-modal" *ngIf="showAddModal && !isUseSystemWhitelist()">
|
||||||
<clr-icon (click)="showAddModal=false" class="float-lg-right margin-top-4" shape="window-close"></clr-icon>
|
<clr-icon (click)="showAddModal=false" class="float-lg-right margin-top-4"
|
||||||
|
shape="window-close"></clr-icon>
|
||||||
<div>
|
<div>
|
||||||
<clr-textarea-container>
|
<clr-textarea-container class="flex-direction-column">
|
||||||
<label>{{'CVE_WHITELIST.ENTER'|translate}}</label>
|
<label>{{'CVE_WHITELIST.ENTER'|translate}}</label>
|
||||||
<textarea id="whitelist-textarea" class="w-100" clrTextarea [(ngModel)]="cveIds" name="cveIds"></textarea>
|
<textarea id="whitelist-textarea" class="w-100" clrTextarea [(ngModel)]="cveIds"
|
||||||
|
name="cveIds"></textarea>
|
||||||
<clr-control-helper>{{'CVE_WHITELIST.HELP'|translate}}</clr-control-helper>
|
<clr-control-helper>{{'CVE_WHITELIST.HELP'|translate}}</clr-control-helper>
|
||||||
</clr-textarea-container>
|
</clr-textarea-container>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button id="add-to-whitelist" [disabled]="isDisabled()" (click)="addToProjectWhitelist()"
|
<button id="add-to-whitelist" [disabled]="isDisabled()"
|
||||||
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
(click)="addToProjectWhitelist()"
|
||||||
|
class="btn btn-link">{{'CVE_WHITELIST.ADD'|translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="whitelist-window" *ngIf="isUseSystemWhitelist()">
|
<ul class="whitelist-window" *ngIf="isUseSystemWhitelist()">
|
||||||
<li *ngIf="systemWhitelist?.items?.length<1"
|
<li *ngIf="systemWhitelist?.items?.length<1" class="none">{{'CVE_WHITELIST.NONE'|translate}}
|
||||||
class="none">{{'CVE_WHITELIST.NONE'|translate}}</li>
|
</li>
|
||||||
<li *ngFor="let item of systemWhitelist?.items">
|
<li *ngFor="let item of systemWhitelist?.items">
|
||||||
<span class="hand" (click)="goToDetail(item.cve_id)">{{item.cve_id}}</span>
|
<span class="hand" (click)="goToDetail(item.cve_id)">{{item.cve_id}}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="whitelist-window" *ngIf="!isUseSystemWhitelist()">
|
<ul class="whitelist-window" *ngIf="!isUseSystemWhitelist()">
|
||||||
<li class="none"
|
<li class="none" *ngIf="projectWhitelist?.items?.length<1">
|
||||||
*ngIf="projectWhitelist?.items?.length<1">{{'CVE_WHITELIST.NONE'|translate}}</li>
|
{{'CVE_WHITELIST.NONE'|translate}}</li>
|
||||||
<li *ngFor="let item of projectWhitelist?.items;let i = index;">
|
<li *ngFor="let item of projectWhitelist?.items;let i = index;">
|
||||||
<span class="hand" (click)="goToDetail(item.cve_id)">{{item.cve_id}}</span>
|
<span class="hand" (click)="goToDetail(item.cve_id)">{{item.cve_id}}</span>
|
||||||
<clr-icon (click)="deleteItem(i)" class="float-lg-right margin-top-4"
|
<clr-icon (click)="deleteItem(i)" class="float-lg-right margin-top-4"
|
||||||
shape="times-circle"></clr-icon>
|
shape="times-circle"></clr-icon>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="clr-col padding-top-8">
|
<div class="clr-col padding-top-8 ">
|
||||||
<div class="form-group padding-left-80">
|
<div class="clr-row expire-data">
|
||||||
<label for="expires">{{'CVE_WHITELIST.EXPIRES_AT'|translate}}</label>
|
<label for="expires"
|
||||||
|
class="bottom-line clr-col-4">{{'CVE_WHITELIST.EXPIRES_AT'|translate}}</label>
|
||||||
<div class="underline">
|
<div class="underline">
|
||||||
<input #dateSystemInput readonly type="date" [(clrDate)]="systemExpiresDate">
|
<input #dateSystemInput readonly type="date" [(clrDate)]="systemExpiresDate">
|
||||||
<input [disabled]="!hasChangeConfigRole" *ngIf="!isUseSystemWhitelist()" #dateInput
|
<input [disabled]="!hasChangeConfigRole" *ngIf="!isUseSystemWhitelist()" #dateInput
|
||||||
placeholder="{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}" readonly type="date"
|
placeholder="{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}" readonly type="date"
|
||||||
[(clrDate)]="expiresDate" newFormLayout="true">
|
[(clrDate)]="expiresDate" newFormLayout="true">
|
||||||
<input [disabled]="!hasChangeConfigRole" *ngIf="isUseSystemWhitelist()"
|
<input clrInput [disabled]="!hasChangeConfigRole" *ngIf="isUseSystemWhitelist()"
|
||||||
placeholder="{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}" readonly type="text"
|
placeholder="{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}" readonly type="text"
|
||||||
value="{{systemExpiresDateString}}">
|
value="{{systemExpiresDateString}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group padding-left-80">
|
<div class="clr-row">
|
||||||
|
<label for="expires" class="clr-col-4"></label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input [disabled]="isUseSystemWhitelist() || !hasChangeConfigRole" [checked]="neverExpires"
|
<input [disabled]="isUseSystemWhitelist() || !hasChangeConfigRole"
|
||||||
[(ngModel)]="neverExpires" type="checkbox" clrCheckbox name="neverExpires"
|
[checked]="neverExpires" [(ngModel)]="neverExpires" type="checkbox" clrCheckbox
|
||||||
id="neverExpires"/>
|
name="neverExpires" id="neverExpires" />
|
||||||
<label>
|
<label>
|
||||||
{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}
|
{{'CVE_WHITELIST.NEVER_EXPIRES'|translate}}
|
||||||
</label>
|
</label>
|
||||||
@ -164,14 +161,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-primary" (click)="save()"
|
<button type="button" class="btn btn-primary" (click)="save()"
|
||||||
[disabled]="((!isValid() || !hasChanges()) && !hasWhitelistChanged) || !hasChangeConfigRole">{{'BUTTON.SAVE'
|
[disabled]="((!isValid() || !hasChanges()) && !hasWhitelistChanged) || !hasChangeConfigRole">{{'BUTTON.SAVE'
|
||||||
| translate}}</button>
|
| translate}}</button>
|
||||||
<button type="button" class="btn btn-outline" (click)="cancel()"
|
<button type="button" class="btn btn-outline" (click)="cancel()"
|
||||||
[disabled]="((!isValid() || !hasChanges()) && !hasWhitelistChanged) || !hasChangeConfigRole">{{'BUTTON.CANCEL'
|
[disabled]="((!isValid() || !hasChanges()) && !hasWhitelistChanged) || !hasChangeConfigRole">{{'BUTTON.CANCEL'
|
||||||
| translate}}</button>
|
| translate}}</button>
|
||||||
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
||||||
</section>
|
</section>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
.select {
|
.select {
|
||||||
width: 120px;
|
width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.margin-top-4 {
|
.margin-top-4 {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
@ -17,6 +18,7 @@
|
|||||||
width: 270px;
|
width: 270px;
|
||||||
color: #0079bb;
|
color: #0079bb;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
@ -43,16 +45,16 @@
|
|||||||
.padding-top-8 {
|
.padding-top-8 {
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
}
|
}
|
||||||
|
.position-relative {
|
||||||
.padding-left-80 {
|
position: relative;
|
||||||
padding-left: 80px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-modal {
|
.add-modal {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
background-color: rgb(238, 238, 238);
|
background-color: rgb(238, 238, 238);
|
||||||
|
.flex-direction-column {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
input {
|
input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
@ -63,8 +65,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hand{
|
.hand {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.config-subtext {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
line-height: 1.2rem;
|
||||||
|
color: rgb(86, 86, 86);
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-05 {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-flex-grow-0 {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expire-data {
|
||||||
|
min-width: 12.5rem;
|
||||||
|
margin-top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-line {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
@ -61,9 +61,9 @@ export class ProjectPolicyConfigComponent implements OnInit {
|
|||||||
@Input() hasSignedIn: boolean;
|
@Input() hasSignedIn: boolean;
|
||||||
@Input() hasProjectAdminRole: boolean;
|
@Input() hasProjectAdminRole: boolean;
|
||||||
|
|
||||||
@ViewChild('cfgConfirmationDialog') confirmationDlg: ConfirmationDialogComponent;
|
@ViewChild('cfgConfirmationDialog', {static: false}) confirmationDlg: ConfirmationDialogComponent;
|
||||||
@ViewChild('dateInput') dateInput: ElementRef;
|
@ViewChild('dateInput', {static: false}) dateInput: ElementRef;
|
||||||
@ViewChild('dateSystemInput') dateSystemInput: ElementRef;
|
@ViewChild('dateSystemInput', {static: false}) dateSystemInput: ElementRef;
|
||||||
|
|
||||||
systemInfo: SystemInfo;
|
systemInfo: SystemInfo;
|
||||||
orgProjectPolicy = new ProjectPolicy();
|
orgProjectPolicy = new ProjectPolicy();
|
||||||
|
@ -39,7 +39,7 @@ describe('PushImageButtonComponent (inline template)', () => {
|
|||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open the drop-down panel', fakeAsync(() => {
|
it('should open the drop-down panel', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@ -57,6 +57,6 @@ describe('PushImageButtonComponent (inline template)', () => {
|
|||||||
expect(copyInputs[1].value.trim()).toEqual(`docker push ${component.registryUrl}/${component.projectName}/IMAGE[:TAG]`);
|
expect(copyInputs[1].value.trim()).toEqual(`docker push ${component.registryUrl}/${component.projectName}/IMAGE[:TAG]`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -13,9 +13,9 @@ export class PushImageButtonComponent {
|
|||||||
@Input() registryUrl: string = "unknown";
|
@Input() registryUrl: string = "unknown";
|
||||||
@Input() projectName: string = "unknown";
|
@Input() projectName: string = "unknown";
|
||||||
|
|
||||||
@ViewChild("tagCopy") tagCopyInput: CopyInputComponent;
|
@ViewChild("tagCopy", {static: false}) tagCopyInput: CopyInputComponent;
|
||||||
@ViewChild("pushCopy") pushCopyInput: CopyInputComponent;
|
@ViewChild("pushCopy", {static: false}) pushCopyInput: CopyInputComponent;
|
||||||
@ViewChild("copyAlert") copyAlert: InlineAlertComponent;
|
@ViewChild("copyAlert", {static: false}) copyAlert: InlineAlertComponent;
|
||||||
|
|
||||||
public get tagCommand(): string {
|
public get tagCommand(): string {
|
||||||
return `docker tag SOURCE_IMAGE[:TAG] ${this.registryUrl}/${
|
return `docker tag SOURCE_IMAGE[:TAG] ${this.registryUrl}/${
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
.command-input {
|
.command-input {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host>>>.dropdown-menu {
|
:host>>>.dropdown-menu {
|
||||||
|
@ -120,16 +120,16 @@ export class ReplicationComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
jobs: ReplicationJobItem[];
|
jobs: ReplicationJobItem[];
|
||||||
|
|
||||||
@ViewChild(ListReplicationRuleComponent)
|
@ViewChild(ListReplicationRuleComponent, {static: false})
|
||||||
listReplicationRule: ListReplicationRuleComponent;
|
listReplicationRule: ListReplicationRuleComponent;
|
||||||
|
|
||||||
@ViewChild(CreateEditRuleComponent)
|
@ViewChild(CreateEditRuleComponent, {static: false})
|
||||||
createEditPolicyComponent: CreateEditRuleComponent;
|
createEditPolicyComponent: CreateEditRuleComponent;
|
||||||
|
|
||||||
@ViewChild("replicationConfirmDialog")
|
@ViewChild("replicationConfirmDialog", {static: false})
|
||||||
replicationConfirmDialog: ConfirmationDialogComponent;
|
replicationConfirmDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
@ViewChild("StopConfirmDialog")
|
@ViewChild("StopConfirmDialog", {static: false})
|
||||||
StopConfirmDialog: ConfirmationDialogComponent;
|
StopConfirmDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
creationTimeComparator: Comparator<ReplicationJob> = new CustomComparator<
|
creationTimeComparator: Comparator<ReplicationJob> = new CustomComparator<
|
||||||
|
@ -80,10 +80,10 @@ export class RepositoryGridviewComponent implements OnChanges, OnInit {
|
|||||||
totalCount = 0;
|
totalCount = 0;
|
||||||
currentState: State;
|
currentState: State;
|
||||||
|
|
||||||
@ViewChild("confirmationDialog")
|
@ViewChild("confirmationDialog", {static: false})
|
||||||
confirmationDialog: ConfirmationDialogComponent;
|
confirmationDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
@ViewChild("gridView") gridView: GridViewComponent;
|
@ViewChild("gridView", {static: false}) gridView: GridViewComponent;
|
||||||
hasCreateRepositoryPermission: boolean;
|
hasCreateRepositoryPermission: boolean;
|
||||||
hasDeleteRepositoryPermission: boolean;
|
hasDeleteRepositoryPermission: boolean;
|
||||||
constructor(@Inject(SERVICE_CONFIG) private configInfo: IServiceConfig,
|
constructor(@Inject(SERVICE_CONFIG) private configInfo: IServiceConfig,
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<span>{{ 'REPOSITORY.MARKDOWN' | translate }}</span>
|
<span>{{ 'REPOSITORY.MARKDOWN' | translate }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!editing">
|
<div id="no-editing" *ngIf="!editing">
|
||||||
<div *ngIf="!hasInfo()" class="no-info-div">
|
<div *ngIf="!hasInfo()" class="no-info-div">
|
||||||
<p>{{'REPOSITORY.NO_INFO' | translate }}<p>
|
<p>{{'REPOSITORY.NO_INFO' | translate }}<p>
|
||||||
</div>
|
</div>
|
||||||
@ -42,7 +42,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="editing">
|
<div *ngIf="editing">
|
||||||
<textarea rows="5" name="info-edit-textarea" [(ngModel)]="imageInfo"></textarea>
|
<textarea id="info-edit-textarea" class="clr-textarea w-100" rows="5" name="info-edit-textarea"
|
||||||
|
[(ngModel)]="imageInfo"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-sm" *ngIf="editing">
|
<div class="btn-sm" *ngIf="editing">
|
||||||
<button class="btn btn-primary" [disabled]="!hasChanges()" (click)="saveInfo()">{{'BUTTON.SAVE' | translate}}</button>
|
<button class="btn btn-primary" [disabled]="!hasChanges()" (click)="saveInfo()">{{'BUTTON.SAVE' | translate}}</button>
|
||||||
|
@ -56,7 +56,7 @@ export class RepositoryComponent implements OnInit {
|
|||||||
|
|
||||||
timerHandler: any;
|
timerHandler: any;
|
||||||
|
|
||||||
@ViewChild('confirmationDialog')
|
@ViewChild('confirmationDialog', {static: false})
|
||||||
confirmationDlg: ConfirmationDialogComponent;
|
confirmationDlg: ConfirmationDialogComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -89,8 +89,8 @@
|
|||||||
<hbr-vulnerabilities-grid [repositoryId]="repositoryId" [projectId]="projectId" [tagId]="tagId"></hbr-vulnerabilities-grid>
|
<hbr-vulnerabilities-grid [repositoryId]="repositoryId" [projectId]="projectId" [tagId]="tagId"></hbr-vulnerabilities-grid>
|
||||||
</clr-tab-content>
|
</clr-tab-content>
|
||||||
</clr-tab>
|
</clr-tab>
|
||||||
<clr-tab>
|
<clr-tab *ngIf="hasBuildHistoryPermission">
|
||||||
<button [clrTabLinkInOverflow]="false" *ngIf="hasBuildHistoryPermission" id="tag-history" clrTabLink class="btn btn-link nav-link" [class.active]='isCurrentTabLink("tag-history")' type="button" (click)='tabLinkClick("tag-history")'>{{ 'REPOSITORY.BUILD_HISTORY' | translate }}</button>
|
<button [clrTabLinkInOverflow]="false" id="tag-history" clrTabLink class="btn btn-link nav-link" [class.active]='isCurrentTabLink("tag-history")' type="button" (click)='tabLinkClick("tag-history")'>{{ 'REPOSITORY.BUILD_HISTORY' | translate }}</button>
|
||||||
<clr-tab-content *clrIfActive>
|
<clr-tab-content *clrIfActive>
|
||||||
<hbr-tag-history [repositoryId]="repositoryId" [tagId]="tagId">{{ 'REPOSITORY.BUILD_HISTORY' | translate }}</hbr-tag-history>
|
<hbr-tag-history [repositoryId]="repositoryId" [tagId]="tagId">{{ 'REPOSITORY.BUILD_HISTORY' | translate }}</hbr-tag-history>
|
||||||
</clr-tab-content>
|
</clr-tab-content>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<h3 class="modal-title">{{ manifestInfoTitle | translate }}</h3>
|
<h3 class="modal-title">{{ manifestInfoTitle | translate }}</h3>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row col-md-12">
|
<div class="row col-md-12">
|
||||||
<textarea rows="2" #digestTarget>{{digestId}}</textarea>
|
<textarea class="clr-textarea w-100" rows="2" #digestTarget>{{digestId}}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<div class="labelFilterPanel" *ngIf="!withAdmiral" [hidden]="!openLabelFilterPanel">
|
<div class="labelFilterPanel" *ngIf="!withAdmiral" [hidden]="!openLabelFilterPanel">
|
||||||
<a class="filterClose" (click)="closeFilter()">×</a>
|
<a class="filterClose" (click)="closeFilter()">×</a>
|
||||||
<label class="filterLabelHeader">{{'REPOSITORY.FILTER_BY_LABEL' | translate}}</label>
|
<label class="filterLabelHeader">{{'REPOSITORY.FILTER_BY_LABEL' | translate}}</label>
|
||||||
<div class="form-group"><input type="text" placeholder="Filter labels" [(ngModel)]="filterName" (keyup)="handleInputFilter()"></div>
|
<div class="form-group"><input clrInput type="text" placeholder="Filter labels" [(ngModel)]="filterName" (keyup)="handleInputFilter()"></div>
|
||||||
<div [hidden]='imageFilterLabels.length' class="no-labels">{{'LABEL.NO_LABELS' | translate }}</div>
|
<div [hidden]='imageFilterLabels.length' class="no-labels">{{'LABEL.NO_LABELS' | translate }}</div>
|
||||||
<div [hidden]='!imageFilterLabels.length' class="has-label">
|
<div [hidden]='!imageFilterLabels.length' class="has-label">
|
||||||
<button type="button" class="labelBtn" *ngFor='let label of imageFilterLabels' [hidden]="!label.show" (click)="rightFilterLabel(label)">
|
<button type="button" class="labelBtn" *ngFor='let label of imageFilterLabels' [hidden]="!label.show" (click)="rightFilterLabel(label)">
|
||||||
@ -60,9 +60,10 @@
|
|||||||
<clr-dropdown *ngIf="!withAdmiral">
|
<clr-dropdown *ngIf="!withAdmiral">
|
||||||
<button type="button" class="btn btn-sm btn-secondary" clrDropdownTrigger [disabled]="!(selectedRow.length==1)||!hasAddLabelImagePermission" (click)="addLabels(selectedRow)"><clr-icon shape="plus" size="16"></clr-icon>{{'REPOSITORY.ADD_LABELS' | translate}}</button>
|
<button type="button" class="btn btn-sm btn-secondary" clrDropdownTrigger [disabled]="!(selectedRow.length==1)||!hasAddLabelImagePermission" (click)="addLabels(selectedRow)"><clr-icon shape="plus" size="16"></clr-icon>{{'REPOSITORY.ADD_LABELS' | translate}}</button>
|
||||||
<clr-dropdown-menu clrPosition="bottom-left" *clrIfOpen>
|
<clr-dropdown-menu clrPosition="bottom-left" *clrIfOpen>
|
||||||
<div class="filter-grid">
|
<clr-dropdown>
|
||||||
|
<div class="filter-grid">
|
||||||
<label class="dropdown-header">{{'REPOSITORY.ADD_LABEL_TO_IMAGE' | translate}}</label>
|
<label class="dropdown-header">{{'REPOSITORY.ADD_LABEL_TO_IMAGE' | translate}}</label>
|
||||||
<div class="form-group"><input type="text" placeholder="Filter labels" [(ngModel)]="stickName" (keyup)="handleStickInputFilter()"></div>
|
<div class="form-group"><input clrInput type="text" placeholder="Filter labels" [(ngModel)]="stickName" (keyup)="handleStickInputFilter()"></div>
|
||||||
<div [hidden]='imageStickLabels.length' class="no-labels">{{'LABEL.NO_LABELS' | translate }}</div>
|
<div [hidden]='imageStickLabels.length' class="no-labels">{{'LABEL.NO_LABELS' | translate }}</div>
|
||||||
<div [hidden]='!imageStickLabels.length' class="has-label">
|
<div [hidden]='!imageStickLabels.length' class="has-label">
|
||||||
<button type="button" class="dropdown-item" *ngFor='let label of imageStickLabels' [hidden]='!label.show' (click)="stickLabel(label)">
|
<button type="button" class="dropdown-item" *ngFor='let label of imageStickLabels' [hidden]='!label.show' (click)="stickLabel(label)">
|
||||||
@ -71,6 +72,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</clr-dropdown>
|
||||||
</clr-dropdown-menu>
|
</clr-dropdown-menu>
|
||||||
</clr-dropdown>
|
</clr-dropdown>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" *ngIf="!withAdmiral" [disabled]="!(selectedRow.length===1)|| !hasRetagImagePermission" (click)="retag(selectedRow)"><clr-icon shape="copy" size="16"></clr-icon> {{'REPOSITORY.RETAG' | translate}}</button>
|
<button type="button" class="btn btn-sm btn-secondary" *ngIf="!withAdmiral" [disabled]="!(selectedRow.length===1)|| !hasRetagImagePermission" (click)="retag(selectedRow)"><clr-icon shape="copy" size="16"></clr-icon> {{'REPOSITORY.RETAG' | translate}}</button>
|
||||||
|
@ -246,3 +246,7 @@ clr-datagrid {
|
|||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::ng-deep .clr-form-control {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
@ -134,14 +134,14 @@ export class TagComponent implements OnInit, AfterViewInit {
|
|||||||
};
|
};
|
||||||
filterOneLabel: Label = this.initFilter;
|
filterOneLabel: Label = this.initFilter;
|
||||||
|
|
||||||
@ViewChild("confirmationDialog")
|
@ViewChild("confirmationDialog", {static: false})
|
||||||
confirmationDialog: ConfirmationDialogComponent;
|
confirmationDialog: ConfirmationDialogComponent;
|
||||||
|
|
||||||
@ViewChild("imageNameInput")
|
@ViewChild("imageNameInput", {static: false})
|
||||||
imageNameInput: ImageNameInputComponent;
|
imageNameInput: ImageNameInputComponent;
|
||||||
|
|
||||||
@ViewChild("digestTarget") textInput: ElementRef;
|
@ViewChild("digestTarget", {static: false}) textInput: ElementRef;
|
||||||
@ViewChild("copyInput") copyInput: CopyInputComponent;
|
@ViewChild("copyInput", {static: false}) copyInput: CopyInputComponent;
|
||||||
|
|
||||||
pageSize: number = DEFAULT_PAGE_SIZE;
|
pageSize: number = DEFAULT_PAGE_SIZE;
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
Renderer,
|
Renderer,
|
||||||
SkipSelf
|
SkipSelf
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { DOCUMENT } from "@angular/platform-browser";
|
import { DOCUMENT } from "@angular/common";
|
||||||
import { WINDOW } from "../ngx-window-token/index";
|
import { WINDOW } from "../ngx-window-token/index";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -245,7 +245,12 @@ export function calculatePage(state: State): number {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.ceil((state.page.to + 1) / state.page.size);
|
let pageNumber = Math.ceil((state.page.to + 1) / state.page.size);
|
||||||
|
if (pageNumber === 0) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return pageNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { VulnerabilityItem, VulnerabilitySeverity } from '../service/index';
|
import { VulnerabilityItem, VulnerabilitySeverity } from '../service/index';
|
||||||
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import { ResultGridComponent } from './result-grid.component';
|
import { ResultGridComponent } from './result-grid.component';
|
||||||
import { ScanningResultService, ScanningResultDefaultService } from '../service/scanning.service';
|
import { ScanningResultService, ScanningResultDefaultService } from '../service/scanning.service';
|
||||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
||||||
@ -26,7 +26,8 @@ describe('ResultGridComponent (inline template)', () => {
|
|||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
SharedModule
|
SharedModule,
|
||||||
|
NoopAnimationsModule
|
||||||
],
|
],
|
||||||
declarations: [ResultGridComponent, FilterComponent],
|
declarations: [ResultGridComponent, FilterComponent],
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -15,7 +15,10 @@
|
|||||||
"lib": [
|
"lib": [
|
||||||
"dom",
|
"dom",
|
||||||
"es2015"
|
"es2015"
|
||||||
]
|
],
|
||||||
|
"paths": {
|
||||||
|
"@angular/*": [ "../node_modules/@angular/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"angularCompilerOptions": {
|
"angularCompilerOptions": {
|
||||||
"annotateForClosureCompiler": true,
|
"annotateForClosureCompiler": true,
|
||||||
|
9771
src/portal/package-lock.json
generated
9771
src/portal/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "harbor",
|
"name": "harbor",
|
||||||
"version": "1.9.0",
|
"version": "1.10.0",
|
||||||
"description": "Harbor UI with Clarity",
|
"description": "Harbor UI with Clarity",
|
||||||
"angular-cli": {},
|
"angular-cli": {},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -20,24 +20,23 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^7.1.3",
|
"@angular/animations": "^8.2.0",
|
||||||
"@angular/common": "^7.1.3",
|
"@angular/common": "^8.2.0",
|
||||||
"@angular/compiler": "^7.1.3",
|
"@angular/compiler": "^8.2.0",
|
||||||
"@angular/core": "^7.1.3",
|
"@angular/core": "^8.2.0",
|
||||||
"@angular/forms": "^7.1.3",
|
"@angular/forms": "^8.2.0",
|
||||||
"@angular/http": "^7.1.3",
|
"@angular/platform-browser": "^8.2.0",
|
||||||
"@angular/platform-browser": "^7.1.3",
|
"@angular/platform-browser-dynamic": "^8.2.0",
|
||||||
"@angular/platform-browser-dynamic": "^7.1.3",
|
"@angular/router": "^8.2.0",
|
||||||
"@angular/router": "^7.1.3",
|
"@clr/angular": "^2.2.0",
|
||||||
"@clr/angular": "^1.0.0",
|
"@clr/icons": "^2.2.0",
|
||||||
"@clr/icons": "^1.0.0",
|
"@clr/ui": "^2.2.0",
|
||||||
"@clr/ui": "^1.0.0",
|
|
||||||
"@fortawesome/fontawesome-free": "^5.1.0-4",
|
"@fortawesome/fontawesome-free": "^5.1.0-4",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^4.0.0",
|
"@ng-bootstrap/ng-bootstrap": "^5.1.0",
|
||||||
"@ngx-translate/core": "^10.0.2",
|
"@ngx-translate/core": "^10.0.2",
|
||||||
"@ngx-translate/http-loader": "^3.0.1",
|
"@ngx-translate/http-loader": "^3.0.1",
|
||||||
"@types/jquery": "^2.0.41",
|
"@types/jquery": "^2.0.41",
|
||||||
"@webcomponents/custom-elements": "^1.1.3",
|
"@webcomponents/custom-elements": "^1.2.4",
|
||||||
"bootstrap": "^4.1.1",
|
"bootstrap": "^4.1.1",
|
||||||
"buffer": "^5.2.1",
|
"buffer": "^5.2.1",
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.5.4",
|
||||||
@ -45,26 +44,26 @@
|
|||||||
"jasmine-core": "^3.3.0",
|
"jasmine-core": "^3.3.0",
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"mutationobserver-shim": "^0.3.2",
|
"mutationobserver-shim": "^0.3.2",
|
||||||
"ng-packagr": "^4.5.0",
|
"ng-packagr": "^5.3.0",
|
||||||
"ngx-clipboard": "^12.0.0",
|
"ngx-clipboard": "^12.0.0",
|
||||||
"ngx-cookie": "^1.0.0",
|
"ngx-cookie": "^1.0.0",
|
||||||
"ngx-markdown": "^7.1.5",
|
"ngx-markdown": "^8.1.0",
|
||||||
"popper.js": "^1.14.3",
|
"popper.js": "^1.14.3",
|
||||||
"rxjs": "^6.3.3",
|
"rxjs": "^6.5.2",
|
||||||
"stream": "^0.0.2",
|
"stream": "^0.0.2",
|
||||||
"swagger-ui": "^3.22.1",
|
"swagger-ui": "^3.23.4",
|
||||||
"ts-helpers": "^1.1.1",
|
"ts-helpers": "^1.1.1",
|
||||||
"tslib": "^1.9.0",
|
"tslib": "^1.9.0",
|
||||||
"types": "^0.1.1",
|
"types": "^0.1.1",
|
||||||
"web-animations-js": "^2.2.1",
|
"web-animations-js": "^2.3.2",
|
||||||
"zone.js": "^0.8.26"
|
"zone.js": "^0.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^0.13.8",
|
"@angular-devkit/build-angular": "~0.802.0",
|
||||||
"@angular-devkit/build-ng-packagr": "~0.13.8",
|
"@angular-devkit/build-ng-packagr": "~0.802.0",
|
||||||
"@angular/cli": "^7.1.3",
|
"@angular/cli": "^8.2.0",
|
||||||
"@angular/compiler-cli": "^7.1.3",
|
"@angular/compiler-cli": "^8.2.0",
|
||||||
"@angular/language-service": "^7.1.3",
|
"@angular/language-service": "^8.2.0",
|
||||||
"@types/core-js": "^0.9.41",
|
"@types/core-js": "^0.9.41",
|
||||||
"@types/jasmine": "^3.3.1",
|
"@types/jasmine": "^3.3.1",
|
||||||
"@types/jasminewd2": "~2.0.3",
|
"@types/jasminewd2": "~2.0.3",
|
||||||
@ -86,9 +85,9 @@
|
|||||||
"rollup-plugin-node-resolve": "^3.0.0",
|
"rollup-plugin-node-resolve": "^3.0.0",
|
||||||
"rollup-plugin-uglify": "^1.0.1",
|
"rollup-plugin-uglify": "^1.0.1",
|
||||||
"ts-node": "~5.0.1",
|
"ts-node": "~5.0.1",
|
||||||
"tsickle": "^0.33.1",
|
"tsickle": "^0.36.0",
|
||||||
"tslint": "~5.9.1",
|
"tslint": "~5.9.1",
|
||||||
"typescript": "3.1.3",
|
"typescript": "^3.5.3",
|
||||||
"typings": "^1.5.0",
|
"typings": "^1.5.0",
|
||||||
"uglify-js": "3.3.18",
|
"uglify-js": "3.3.18",
|
||||||
"webdriver-manager": "10.2.5"
|
"webdriver-manager": "10.2.5"
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="false">
|
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="false">
|
||||||
<h3 class="modal-title">{{'PROFILE.TITLE' | translate}}</h3>
|
<h3 class="modal-title">{{'PROFILE.TITLE' | translate}}</h3>
|
||||||
<inline-alert class="modal-title" (confirmEvt)="confirmYes($event)" (closeEvt)="confirmNo($event)"></inline-alert>
|
|
||||||
<div class="modal-body body-format">
|
<div class="modal-body body-format">
|
||||||
<form #accountSettingsFrom="ngForm" class="form">
|
<inline-alert (confirmEvt)="confirmYes($event)" (closeEvt)="confirmNo($event)"></inline-alert>
|
||||||
<section class="form-block">
|
<form #accountSettingsFrom="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<div class="form-group form-group-override">
|
<div class="clr-form-control">
|
||||||
<label for="account_settings_username" aria-haspopup="true" class="form-group-label-override">{{'PROFILE.USER_NAME' | translate}}</label>
|
<label for="account_settings_username" aria-haspopup="true" class="clr-control-label">{{'PROFILE.USER_NAME' | translate}}</label>
|
||||||
<input type="text" name="account_settings_username" [(ngModel)]="account.username" disabled id="account_settings_username" size="33">
|
<div class="clr-control-container display-flex">
|
||||||
<div *ngIf="canRename" class="rename-tool">
|
<input class="clr-input" type="text" name="account_settings_username" [(ngModel)]="account.username" disabled id="account_settings_username"
|
||||||
<button [disabled]="RenameOnGoing" (click)="onRename()" class="btn btn-outline btn-sm">
|
size="30">
|
||||||
|
<div *ngIf="canRename" class="rename-tool">
|
||||||
|
<button [disabled]="RenameOnGoing" (click)="onRename()" class="btn btn-outline btn-sm">
|
||||||
{{'PROFILE.ADMIN_RENAME_BUTTON' | translate}}
|
{{'PROFILE.ADMIN_RENAME_BUTTON' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<clr-tooltip>
|
<clr-tooltip>
|
||||||
@ -19,56 +20,58 @@
|
|||||||
</clr-tooltip>
|
</clr-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group form-group-override">
|
</div>
|
||||||
<label for="account_settings_email" class="required form-group-label-override">{{'PROFILE.EMAIL' | translate}}</label>
|
<div class="clr-form-control">
|
||||||
<label for="account_settings_email" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left" [class.invalid]='!getValidationState("account_settings_email")'>
|
<label for="account_settings_email" class="required clr-control-label">{{'PROFILE.EMAIL' | translate}}</label>
|
||||||
<input name="account_settings_email" type="text" #eamilInput="ngModel" [(ngModel)]="account.email"
|
<div class="clr-control-container" [class.clr-error]="!getValidationState('account_settings_email')">
|
||||||
required
|
<div class="clr-input-wrapper">
|
||||||
email
|
<input name="account_settings_email" type="text" #eamilInput="ngModel" class="clr-input" [(ngModel)]="account.email" required
|
||||||
id="account_settings_email" size="30"
|
email id="account_settings_email" size="30" (input)='handleValidation("account_settings_email", false)'
|
||||||
(input)='handleValidation("account_settings_email", false)'
|
(blur)='handleValidation("account_settings_email", true)'>
|
||||||
(blur)='handleValidation("account_settings_email", true)'>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
<span class="tooltip-content">
|
<span class="spinner spinner-inline" [hidden]="!checkProgress"></span>
|
||||||
{{emailTooltip | translate}}
|
|
||||||
</span>
|
|
||||||
</label><span class="spinner spinner-inline" [hidden]="!checkProgress"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group form-group-override">
|
|
||||||
<label for="account_settings_full_name" class="form-group-label-override" [class.required]="!account.oidc_user_meta">{{'PROFILE.FULL_NAME' | translate}}</label>
|
|
||||||
<label for="account_settings_full_name" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left" [class.invalid]='!getValidationState("account_settings_full_name")'>
|
|
||||||
<input type="text" name="account_settings_full_name" #fullNameInput="ngModel" [(ngModel)]="account.realname" [required]="!account.oidc_user_meta" maxLengthExt="20" id="account_settings_full_name" size="30" (input)='handleValidation("account_settings_full_name", false)' (blur)='handleValidation("account_settings_full_name", true)'>
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.FULL_NAME' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group form-group-override">
|
|
||||||
<label for="account_settings_comments" class="form-group-label-override">{{'PROFILE.COMMENT' | translate}}</label>
|
|
||||||
<label for="account_settings_comments" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left" [class.invalid]="commentInput.invalid && (commentInput.dirty || commentInput.touched)">
|
|
||||||
<input type="text" #commentInput="ngModel" maxLengthExt="30" name="account_settings_comments" [(ngModel)]="account.comment" id="account_settings_comments" size="30">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.COMMENT' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group form-group-override cli-secret" *ngIf="account.oidc_user_meta">
|
|
||||||
<label for="cli_password" aria-haspopup="true" class="form-group-label-override"><span class="label-inner-text">{{'PROFILE.CLI_PASSWORD' | translate}}</span>
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="20"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="md" *clrIfOpen>
|
|
||||||
<span> {{'PROFILE.CLI_PASSWORD_TIP' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip></label>
|
|
||||||
<input type="password" name="cli_password" disabled [ngModel]="'account.oidc_user_meta.secret'" size="33">
|
|
||||||
<button (click)="generateCli(account.user_id)" id="generate-cli-btn" class="btn btn-outline btn-sm btn-padding-less" *ngIf="showGenerateCli">
|
|
||||||
{{'PROFILE.ADMIN_CIL_SECRET_BUTTON' | translate}}
|
|
||||||
</button>
|
|
||||||
<div class="rename-tool reset-cli">
|
|
||||||
<hbr-copy-input #copyInput (onCopySuccess)="onSuccess($event)" (onCopyError)="onError($event)" iconMode="true" [defaultValue]="account.oidc_user_meta.secret"></hbr-copy-input>
|
|
||||||
</div>
|
</div>
|
||||||
<div (click)="showGenerateCliFn()" *ngIf="!showGenerateCli" id="hidden-generate-cli" class="hidden-generate-cli">···</div>
|
<clr-control-error *ngIf="!getValidationState('account_settings_email')">
|
||||||
|
{{emailTooltip | translate}}
|
||||||
|
</clr-control-error>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
|
<clr-input-container>
|
||||||
|
<label [class.required]="!account.oidc_user_meta">{{'PROFILE.FULL_NAME' | translate}}</label>
|
||||||
|
<input clrInput type="text" name="account_settings_full_name" #fullNameInput="ngModel" [(ngModel)]="account.realname" [required]="!account.oidc_user_meta"
|
||||||
|
maxLengthExt="20" id="account_settings_full_name" size="30" (input)='handleValidation("account_settings_full_name", false)'
|
||||||
|
(blur)='handleValidation("account_settings_full_name", true)'>
|
||||||
|
<clr-control-error *ngIf="!getValidationState('account_settings_full_name')">
|
||||||
|
{{'TOOLTIP.FULL_NAME' | translate}}
|
||||||
|
</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
|
<clr-input-container>
|
||||||
|
<label>{{'PROFILE.COMMENT' | translate}}</label>
|
||||||
|
<input clrInput type="text" #commentInput="ngModel" maxlength="30" size="30" name="account_settings_comments" [(ngModel)]="account.comment"
|
||||||
|
id="account_settings_comments">
|
||||||
|
<clr-control-error *ngIf="commentInput.invalid && (commentInput.dirty || commentInput.touched)">
|
||||||
|
{{'TOOLTIP.COMMENT' | translate}}
|
||||||
|
</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<div class="clr-form-control cli-secret" *ngIf="account.oidc_user_meta">
|
||||||
|
<label class="clr-control-label">{{'PROFILE.CLI_PASSWORD' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="20"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="md" *clrIfOpen>
|
||||||
|
<span> {{'PROFILE.CLI_PASSWORD_TIP' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input class="clr-input" type="password" name="cli_password" disabled [ngModel]="'account.oidc_user_meta.secret'" size="33">
|
||||||
|
<button (click)="generateCli(account.user_id)" id="generate-cli-btn" class="btn btn-outline btn-sm btn-padding-less" *ngIf="showGenerateCli">
|
||||||
|
{{'PROFILE.ADMIN_CIL_SECRET_BUTTON' | translate}}
|
||||||
|
</button>
|
||||||
|
<div class="rename-tool reset-cli">
|
||||||
|
<hbr-copy-input #copyInput (onCopySuccess)="onSuccess($event)" (onCopyError)="onError($event)" iconMode="true" [defaultValue]="account.oidc_user_meta.secret"></hbr-copy-input>
|
||||||
|
</div>
|
||||||
|
<div (click)="showGenerateCliFn()" *ngIf="!showGenerateCli" id="hidden-generate-cli" class="hidden-generate-cli">···</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@ -77,4 +80,4 @@
|
|||||||
<button type="button" class="btn btn-primary" [disabled]="!isValid || showProgress" (click)="submit()">{{'BUTTON.OK' | translate}}</button>
|
<button type="button" class="btn btn-primary" [disabled]="!isValid || showProgress" (click)="submit()">{{'BUTTON.OK' | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</clr-modal>
|
</clr-modal>
|
||||||
<confirmation-dialog #confirmationDialog (confirmAction)="confirmGenerate($event)"></confirmation-dialog>
|
<confirmation-dialog #confirmationDialog (confirmAction)="confirmGenerate($event)"></confirmation-dialog>
|
@ -31,4 +31,8 @@ clr-modal {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-flex {
|
||||||
|
display: flex;
|
||||||
}
|
}
|
@ -51,13 +51,13 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
renameConfirmation = false;
|
renameConfirmation = false;
|
||||||
// confirmRename = false;
|
// confirmRename = false;
|
||||||
showGenerateCli: boolean = false;
|
showGenerateCli: boolean = false;
|
||||||
@ViewChild("confirmationDialog")
|
@ViewChild("confirmationDialog", {static: false})
|
||||||
confirmationDialogComponent: ConfirmationDialogComponent;
|
confirmationDialogComponent: ConfirmationDialogComponent;
|
||||||
|
|
||||||
accountFormRef: NgForm;
|
accountFormRef: NgForm;
|
||||||
@ViewChild("accountSettingsFrom") accountForm: NgForm;
|
@ViewChild("accountSettingsFrom", {static: true}) accountForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
|
@ViewChild(InlineAlertComponent, {static: false}) inlineAlert: InlineAlertComponent;
|
||||||
@ViewChild("copyInput") copyInput: CopyInputComponent;
|
@ViewChild("copyInput", {static: false}) copyInput: CopyInputComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private session: SessionService,
|
private session: SessionService,
|
||||||
|
@ -1,26 +1,17 @@
|
|||||||
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
||||||
<h3 class="modal-title">{{'RESET_PWD.TITLE' | translate}}</h3>
|
<h3 class="modal-title">{{'RESET_PWD.TITLE' | translate}}</h3>
|
||||||
<label class="modal-title reset-modal-title-override">{{'RESET_PWD.CAPTION' | translate}}</label>
|
|
||||||
<inline-alert class="modal-title"></inline-alert>
|
|
||||||
<div class="modal-body body-format password-body">
|
<div class="modal-body body-format password-body">
|
||||||
<form #forgotPasswordFrom="ngForm" class="form">
|
<inline-alert></inline-alert>
|
||||||
<section class="form-block">
|
<label>{{'RESET_PWD.CAPTION' | translate}}</label>
|
||||||
<div class="form-group form-group-override">
|
<form #forgotPasswordFrom="ngForm" clrForm>
|
||||||
<label for="reset_pwd_email" class="required form-group-label-override">{{'RESET_PWD.EMAIL' | translate}}</label>
|
<clr-input-container>
|
||||||
<label for="reset_pwd_email" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]="!validationState">
|
<label class="required">{{'RESET_PWD.EMAIL' | translate}}</label>
|
||||||
<input [disabled]="isSuccess" name="reset_pwd_email" type="text" #eamilInput="ngModel" [(ngModel)]="email"
|
<input clrInput [disabled]="isSuccess" name="reset_pwd_email" type="text" #eamilInput="ngModel" [(ngModel)]="email" required email
|
||||||
required
|
id="reset_pwd_email" size="50" (input)="handleValidation(true)" (blur)="handleValidation(false)">
|
||||||
email
|
<clr-control-error *ngIf="!validationState">
|
||||||
id="reset_pwd_email"
|
{{'TOOLTIP.EMAIL' | translate}}
|
||||||
size="30"
|
</clr-control-error>
|
||||||
(input)="handleValidation(true)"
|
</clr-input-container>
|
||||||
(blur)="handleValidation(false)">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.EMAIL' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -29,8 +29,8 @@ export class ForgotPasswordComponent {
|
|||||||
validationState: boolean = true;
|
validationState: boolean = true;
|
||||||
isSuccess: boolean = false;
|
isSuccess: boolean = false;
|
||||||
|
|
||||||
@ViewChild("forgotPasswordFrom") forgotPwdForm: NgForm;
|
@ViewChild("forgotPasswordFrom", {static: true}) forgotPwdForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent, {static: false})
|
||||||
inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(private pwdService: PasswordSettingService) { }
|
constructor(private pwdService: PasswordSettingService) { }
|
||||||
|
@ -1,56 +1,34 @@
|
|||||||
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
||||||
<h3 class="modal-title">{{'CHANGE_PWD.TITLE' | translate}}</h3>
|
<h3 class="modal-title">{{'CHANGE_PWD.TITLE' | translate}}</h3>
|
||||||
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
|
||||||
<div class="modal-body body-format">
|
<div class="modal-body body-format">
|
||||||
<form #changepwdForm="ngForm" class="form">
|
<inline-alert (confirmEvt)="confirmCancel($event)"></inline-alert>
|
||||||
<section class="form-block">
|
<form #changepwdForm="ngForm" clrForm>
|
||||||
<div class="form-group form-group-override">
|
<clr-input-container>
|
||||||
<label for="oldPassword" class="required form-group-label-override">{{'CHANGE_PWD.CURRENT_PWD' | translate}}</label>
|
<label class="required">{{'CHANGE_PWD.CURRENT_PWD' | translate}}</label>
|
||||||
<label for="oldPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]="oldPassInput.invalid && (oldPassInput.dirty || oldPassInput.touched)">
|
<input clrInput type="password" id="oldPassword" required name="oldPassword" [(ngModel)]="oldPwd" #oldPassInput="ngModel"
|
||||||
<input type="password" id="oldPassword"
|
size="40">
|
||||||
required
|
<clr-control-error *ngIf="oldPassInput.invalid && (oldPassInput.dirty || oldPassInput.touched)">
|
||||||
name="oldPassword"
|
|
||||||
[(ngModel)]="oldPwd"
|
|
||||||
#oldPassInput="ngModel" size="30">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.CURRENT_PWD' | translate}}
|
{{'TOOLTIP.CURRENT_PWD' | translate}}
|
||||||
</span>
|
</clr-control-error>
|
||||||
</label>
|
</clr-input-container>
|
||||||
</div>
|
<clr-input-container>
|
||||||
<div class="form-group form-group-override">
|
<label class="required">{{'CHANGE_PWD.NEW_PWD' | translate}}</label>
|
||||||
<label for="newPassword" class="required form-group-label-override">{{'CHANGE_PWD.NEW_PWD' | translate}}</label>
|
<input clrInput type="password" id="newPassword" required pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$" name="newPassword"
|
||||||
<label for="newPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left" [class.invalid]='!getValidationState("newPassword")'>
|
[(ngModel)]="newPwd" #newPassInput="ngModel" size="40" (input)='handleValidation("newPassword", false)' (blur)='handleValidation("newPassword", true)'>
|
||||||
<input type="password" id="newPassword"
|
<clr-control-helper>{{'CHANGE_PWD.PASS_TIPS' | translate}}</clr-control-helper>
|
||||||
required
|
<clr-control-error *ngIf="!getValidationState('newPassword')">
|
||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
|
||||||
name="newPassword"
|
|
||||||
[(ngModel)]="newPwd"
|
|
||||||
#newPassInput="ngModel" size="30"
|
|
||||||
(input)='handleValidation("newPassword", false)'
|
|
||||||
(blur)='handleValidation("newPassword", true)'>
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.PASSWORD' | translate}}
|
{{'TOOLTIP.PASSWORD' | translate}}
|
||||||
</span>
|
</clr-control-error>
|
||||||
</label>
|
</clr-input-container>
|
||||||
<label class="sub-label-for-input">{{'CHANGE_PWD.PASS_TIPS' | translate}}</label>
|
<clr-input-container>
|
||||||
</div>
|
<label class="required">{{'CHANGE_PWD.CONFIRM_PWD' | translate}}</label>
|
||||||
<div class="form-group form-group-override">
|
<input clrInput type="password" id="reNewPassword" required pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$" name="reNewPassword"
|
||||||
<label for="reNewPassword" class="required form-group-label-override">{{'CHANGE_PWD.CONFIRM_PWD' | translate}}</label>
|
[(ngModel)]="reNewPwd" #reNewPassInput="ngModel" size="40" (input)='handleValidation("reNewPassword", false)'
|
||||||
<label for="reNewPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left" [class.invalid]='!getValidationState("reNewPassword")'>
|
|
||||||
<input type="password" id="reNewPassword"
|
|
||||||
required
|
|
||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
|
||||||
name="reNewPassword"
|
|
||||||
[(ngModel)]="reNewPwd"
|
|
||||||
#reNewPassInput="ngModel" size="30"
|
|
||||||
(input)='handleValidation("reNewPassword", false)'
|
|
||||||
(blur)='handleValidation("reNewPassword", true)'>
|
(blur)='handleValidation("reNewPassword", true)'>
|
||||||
<span class="tooltip-content">
|
<clr-control-error *ngIf='!getValidationState("reNewPassword")'>
|
||||||
{{'TOOLTIP.CONFIRM_PWD' | translate}}
|
{{'TOOLTIP.CONFIRM_PWD' | translate}}
|
||||||
</span>
|
</clr-control-error>
|
||||||
</label>
|
</clr-input-container>
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -40,8 +40,8 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pwdFormRef: NgForm;
|
pwdFormRef: NgForm;
|
||||||
@ViewChild("changepwdForm") pwdForm: NgForm;
|
@ViewChild("changepwdForm", {static: true}) pwdForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent, {static: true})
|
||||||
inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -7,37 +7,27 @@
|
|||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="newPassword" class="form-group-label-override">{{'CHANGE_PWD.NEW_PWD' | translate}}</label>
|
<label for="newPassword" class="form-group-label-override">{{'CHANGE_PWD.NEW_PWD' | translate}}</label>
|
||||||
<label for="newPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='!getValidationState("newPassword")'>
|
<label for="newPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
|
||||||
<input [disabled]="resetOk" type="password" id="newPassword" placeholder='{{"PLACEHOLDER.NEW_PWD" | translate}}'
|
[class.invalid]='!getValidationState("newPassword")'>
|
||||||
required
|
<input [disabled]="resetOk" type="password" id="newPassword" placeholder='{{"PLACEHOLDER.NEW_PWD" | translate}}' required
|
||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$" name="newPassword" [(ngModel)]="password"
|
||||||
name="newPassword"
|
#newPassInput="ngModel" size="25" (input)='handleValidation("newPassword", false)' (blur)='handleValidation("newPassword", true)'>
|
||||||
[(ngModel)]="password"
|
<span class="tooltip-content">
|
||||||
#newPassInput="ngModel"
|
{{'TOOLTIP.PASSWORD' | translate}}
|
||||||
size="25"
|
</span>
|
||||||
(input)='handleValidation("newPassword", false)'
|
</label>
|
||||||
(blur)='handleValidation("newPassword", true)'>
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.PASSWORD' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="reNewPassword" class="form-group-label-override">{{'CHANGE_PWD.CONFIRM_PWD' | translate}}</label>
|
<label for="reNewPassword" class="form-group-label-override">{{'CHANGE_PWD.CONFIRM_PWD' | translate}}</label>
|
||||||
<label for="reNewPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left" [class.invalid]='!getValidationState("reNewPassword")'>
|
<label for="reNewPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left"
|
||||||
<input [disabled]="resetOk" type="password" id="reNewPassword" placeholder='{{"PLACEHOLDER.CONFIRM_PWD" | translate}}'
|
[class.invalid]='!getValidationState("reNewPassword")'>
|
||||||
required
|
<input [disabled]="resetOk" type="password" id="reNewPassword" placeholder='{{"PLACEHOLDER.CONFIRM_PWD" | translate}}' required
|
||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$" name="reNewPassword" [(ngModel)]="confirmPwd"
|
||||||
name="reNewPassword"
|
#reNewPassInput size="25" (input)='handleValidation("reNewPassword", false)' (blur)='handleValidation("reNewPassword", true)'>
|
||||||
[(ngModel)]="confirmPwd"
|
<span class="tooltip-content">
|
||||||
#reNewPassInput
|
{{'TOOLTIP.CONFIRM_PWD' | translate}}
|
||||||
size="25"
|
</span>
|
||||||
(input)='handleValidation("reNewPassword", false)'
|
</label>
|
||||||
(blur)='handleValidation("reNewPassword", true)'>
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.CONFIRM_PWD' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
|
@ -37,8 +37,8 @@ export class ResetPasswordComponent implements OnInit {
|
|||||||
resetOk: boolean = false;
|
resetOk: boolean = false;
|
||||||
confirmPwd: string = "";
|
confirmPwd: string = "";
|
||||||
|
|
||||||
@ViewChild("resetPwdForm") resetPwdForm: NgForm;
|
@ViewChild("resetPwdForm", {static: false}) resetPwdForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent, {static: false})
|
||||||
inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -35,7 +35,7 @@ export class SignUpPageComponent implements OnInit {
|
|||||||
private msgService: MessageService,
|
private msgService: MessageService,
|
||||||
private router: Router) { }
|
private router: Router) { }
|
||||||
|
|
||||||
@ViewChild(NewUserFormComponent)
|
@ViewChild(NewUserFormComponent, {static: false})
|
||||||
newUserForm: NewUserFormComponent;
|
newUserForm: NewUserFormComponent;
|
||||||
|
|
||||||
getNewUser(): User {
|
getNewUser(): User {
|
||||||
|
@ -39,13 +39,13 @@ export class SignUpComponent {
|
|||||||
private session: SessionService,
|
private session: SessionService,
|
||||||
private userService: UserService) { }
|
private userService: UserService) { }
|
||||||
|
|
||||||
@ViewChild(NewUserFormComponent)
|
@ViewChild(NewUserFormComponent, {static: true})
|
||||||
newUserForm: NewUserFormComponent;
|
newUserForm: NewUserFormComponent;
|
||||||
|
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent, {static: false})
|
||||||
inlienAlert: InlineAlertComponent;
|
inlienAlert: InlineAlertComponent;
|
||||||
|
|
||||||
@ViewChild(Modal)
|
@ViewChild(Modal, {static: false})
|
||||||
modal: Modal;
|
modal: Modal;
|
||||||
|
|
||||||
getNewUser(): User {
|
getNewUser(): User {
|
||||||
|
@ -45,7 +45,6 @@ registerLocaleData(localeFr, 'fr-fr');
|
|||||||
registerLocaleData(localePt, 'pt-br');
|
registerLocaleData(localePt, 'pt-br');
|
||||||
registerLocaleData(localeTr, 'tr-tr');
|
registerLocaleData(localeTr, 'tr-tr');
|
||||||
|
|
||||||
|
|
||||||
export function initConfig(configService: AppConfigService, skinableService: SkinableConfig) {
|
export function initConfig(configService: AppConfigService, skinableService: SkinableConfig) {
|
||||||
return () => {
|
return () => {
|
||||||
skinableService.getCustomFile().subscribe();
|
skinableService.getCustomFile().subscribe();
|
||||||
@ -87,11 +86,7 @@ export function getCurrentLanguage(translateService: TranslateService) {
|
|||||||
deps: [ AppConfigService, SkinableConfig],
|
deps: [ AppConfigService, SkinableConfig],
|
||||||
multi: true
|
multi: true
|
||||||
},
|
},
|
||||||
{
|
{provide: LOCALE_ID, useValue: "en-US"}
|
||||||
provide: LOCALE_ID,
|
|
||||||
useFactory: getCurrentLanguage,
|
|
||||||
deps: [ TranslateService ]
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -36,16 +36,16 @@ import { CommonRoutes } from '@harbor/ui';
|
|||||||
|
|
||||||
export class HarborShellComponent implements OnInit, OnDestroy {
|
export class HarborShellComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@ViewChild(AccountSettingsModalComponent)
|
@ViewChild(AccountSettingsModalComponent, {static: false})
|
||||||
accountSettingsModal: AccountSettingsModalComponent;
|
accountSettingsModal: AccountSettingsModalComponent;
|
||||||
|
|
||||||
@ViewChild(PasswordSettingComponent)
|
@ViewChild(PasswordSettingComponent, {static: false})
|
||||||
pwdSetting: PasswordSettingComponent;
|
pwdSetting: PasswordSettingComponent;
|
||||||
|
|
||||||
@ViewChild(NavigatorComponent)
|
@ViewChild(NavigatorComponent, {static: false})
|
||||||
navigator: NavigatorComponent;
|
navigator: NavigatorComponent;
|
||||||
|
|
||||||
@ViewChild(AboutDialogComponent)
|
@ViewChild(AboutDialogComponent, {static: false})
|
||||||
aboutDialog: AboutDialogComponent;
|
aboutDialog: AboutDialogComponent;
|
||||||
|
|
||||||
// To indicator whwther or not the search results page is displayed
|
// To indicator whwther or not the search results page is displayed
|
||||||
|
@ -1,421 +1,379 @@
|
|||||||
<form #authConfigFrom="ngForm" class="form">
|
<form #authConfigFrom="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<section class="form-block">
|
<clr-select-container>
|
||||||
<div class="form-group">
|
<label >{{'CONFIG.AUTH_MODE' | translate}}
|
||||||
<label for="authMode">{{'CONFIG.AUTH_MODE' | translate }}</label>
|
<clr-tooltip>
|
||||||
<div class="select">
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<select id="authMode" name="authMode" (change)="handleOnChange($event)"
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
[disabled]="disabled(currentConfig.auth_mode)" [(ngModel)]="currentConfig.auth_mode.value">
|
<span>{{'CONFIG.TOOLTIP.AUTH_MODE' | translate}}</span>
|
||||||
<option value="db_auth">{{'CONFIG.AUTH_MODE_DB' | translate }}</option>
|
</clr-tooltip-content>
|
||||||
<option value="ldap_auth">{{'CONFIG.AUTH_MODE_LDAP' | translate }}</option>
|
</clr-tooltip>
|
||||||
<option value="uaa_auth">{{'CONFIG.AUTH_MODE_UAA' | translate }}</option>
|
|
||||||
<option *ngIf="showHttpAuth" value="http_auth">{{'CONFIG.AUTH_MODE_HTTP' | translate }}</option>
|
|
||||||
<option value="oidc_auth">{{'CONFIG.AUTH_MODE_OIDC' | translate }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-lg tooltip-top-right top-1">
|
|
||||||
<clr-icon shape="info-circle" size="24" class="info-tips-icon"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.AUTH_MODE' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
<a href="https://openid.net/connect/" *ngIf="currentConfig?.auth_mode?.value==='oidc_auth'" target="_blank"
|
<a href="https://openid.net/connect/" *ngIf="currentConfig?.auth_mode?.value==='oidc_auth'" target="_blank"
|
||||||
class="more-info-link">{{ 'BUTTON.MORE_INFO' | translate }}</a>
|
class="more-info-link">{{ 'BUTTON.MORE_INFO' | translate }}</a>
|
||||||
</div>
|
</label>
|
||||||
</section>
|
<select clrSelect id="authMode" name="authMode" (change)="handleOnChange($event)"
|
||||||
<section class="form-block" *ngIf="showUAA">
|
[disabled]="disabled(currentConfig.auth_mode)" [(ngModel)]="currentConfig.auth_mode.value">
|
||||||
<div class="form-group">
|
<option value="db_auth">{{'CONFIG.AUTH_MODE_DB' | translate }}</option>
|
||||||
|
<option value="ldap_auth">{{'CONFIG.AUTH_MODE_LDAP' | translate }}</option>
|
||||||
|
<option value="uaa_auth">{{'CONFIG.AUTH_MODE_UAA' | translate }}</option>
|
||||||
|
<option *ngIf="showHttpAuth" value="http_auth">{{'CONFIG.AUTH_MODE_HTTP' | translate }}</option>
|
||||||
|
<option value="oidc_auth">{{'CONFIG.AUTH_MODE_OIDC' | translate }}</option>
|
||||||
|
</select>
|
||||||
|
</clr-select-container>
|
||||||
|
|
||||||
|
<section *ngIf="showUAA">
|
||||||
|
<clr-input-container>
|
||||||
<label for="uaa-endpoint" class="required">{{'CONFIG.UAA.ENDPOINT' | translate}}</label>
|
<label for="uaa-endpoint" class="required">{{'CONFIG.UAA.ENDPOINT' | translate}}</label>
|
||||||
<input type="text" id="uaa-endpoint" name="uaa-endpoint" size="35"
|
<input type="text" id="uaa-endpoint" clrInput name="uaa-endpoint" size="35"
|
||||||
[(ngModel)]="currentConfig.uaa_endpoint.value" [disabled]="!currentConfig.uaa_verify_cert.editable">
|
[(ngModel)]="currentConfig.uaa_endpoint.value" [disabled]="!currentConfig.uaa_verify_cert.editable">
|
||||||
</div>
|
</clr-input-container>
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="uaa-id" class="required">{{'CONFIG.UAA.CLIENT_ID' | translate}}</label>
|
<label for="uaa-id" class="required">{{'CONFIG.UAA.CLIENT_ID' | translate}}</label>
|
||||||
<input type="text" id="uaa-cid" name="uaa-client-id" size="35"
|
<input clrInput type="text" id="uaa-id" name="uaa-client-id" size="35"
|
||||||
[(ngModel)]="currentConfig.uaa_client_id.value" [disabled]="!currentConfig.uaa_verify_cert.editable">
|
[(ngModel)]="currentConfig.uaa_client_id.value" [disabled]="!currentConfig.uaa_verify_cert.editable">
|
||||||
</div>
|
</clr-input-container>
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="uaa-id" class="required">{{'CONFIG.UAA.CLIENT_SECRET' | translate}}</label>
|
<label for="uaa-secret" class="required">{{'CONFIG.UAA.CLIENT_SECRET' | translate}}</label>
|
||||||
<input id="uaa-secret" name="uaa-client-secret" type="password" size="35"
|
<input clrInput id="uaa-secret" name="uaa-client-secret" type="password" size="35"
|
||||||
[(ngModel)]="currentConfig.uaa_client_secret.value"
|
[(ngModel)]="currentConfig.uaa_client_secret.value"
|
||||||
[disabled]="!currentConfig.uaa_verify_cert.editable">
|
[disabled]="!currentConfig.uaa_verify_cert.editable">
|
||||||
</div>
|
</clr-input-container>
|
||||||
<div class="form-group">
|
<clr-checkbox-container>
|
||||||
|
<label for="uaa-cert">{{'CONFIG.UAA.VERIFY_CERT' | translate}}</label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" clrCheckbox name="uaa-cert" id="uaa-cert" required
|
<input type="checkbox" clrCheckbox name="uaa-cert" id="uaa-cert"
|
||||||
[(ngModel)]="currentConfig.uaa_verify_cert.value"
|
[(ngModel)]="currentConfig.uaa_verify_cert.value"
|
||||||
[disabled]="!currentConfig.uaa_verify_cert.editable" />
|
[disabled]="!currentConfig.uaa_verify_cert.editable" />
|
||||||
<label for="uaa-cert" class="required">{{'CONFIG.UAA.VERIFY_CERT' | translate}}</label>
|
|
||||||
</clr-checkbox-wrapper>
|
</clr-checkbox-wrapper>
|
||||||
</div>
|
</clr-checkbox-container>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="form-block" *ngIf="showLdap">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapUrl" class="required">{{'CONFIG.LDAP.URL' | translate}}</label>
|
|
||||||
<label for="ldapUrl" aria-haspopup="true" role="tooltip"
|
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right"
|
|
||||||
[class.invalid]="ldapUrlInput.invalid && (ldapUrlInput.dirty || ldapUrlInput.touched)">
|
|
||||||
<input name="ldapUrl" type="text" #ldapUrlInput="ngModel" [(ngModel)]="currentConfig.ldap_url.value"
|
|
||||||
required id="ldapUrl" size="40" [disabled]="disabled(currentConfig.ldap_url)">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapSearchDN">{{'CONFIG.LDAP.SEARCH_DN' | translate}}</label>
|
|
||||||
<label for="ldapSearchDN" aria-haspopup="true" role="tooltip"
|
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right">
|
|
||||||
<input name="ldapSearchDN" type="text" #ldapSearchDNInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_search_dn.value" id="ldapSearchDN" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_search_dn)">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-lg tooltip-top-right top-1">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.LDAP_SEARCH_DN' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapSearchPwd">{{'CONFIG.LDAP.SEARCH_PWD' | translate}}</label>
|
|
||||||
<label for="ldapSearchPwd" aria-haspopup="true" role="tooltip"
|
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right">
|
|
||||||
<input name="ldapSearchPwd" type="password" #ldapSearchPwdInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_search_password.value" id="ldapSearchPwd" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_search_password)">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapBaseDN" class="required">{{'CONFIG.LDAP.BASE_DN' | translate}}</label>
|
|
||||||
<label for="ldapBaseDN" aria-haspopup="true" role="tooltip"
|
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right"
|
|
||||||
[class.invalid]="ldapBaseDNInput.invalid && (ldapBaseDNInput.dirty || ldapBaseDNInput.touched)">
|
|
||||||
<input name="ldapBaseDN" type="text" #ldapBaseDNInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_base_dn.value" required id="ldapBaseDN" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_base_dn)">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right top-1">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.LDAP_BASE_DN' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapFilter">{{'CONFIG.LDAP.FILTER' | translate}}</label>
|
|
||||||
<label for="ldapFilter" aria-haspopup="true" role="tooltip"
|
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right">
|
|
||||||
<input name="ldapFilter" type="text" #ldapFilterInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_filter.value" id="ldapFilter" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_filter)">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapUid" class="required">{{'CONFIG.LDAP.UID' | translate}}</label>
|
|
||||||
<label for="ldapUid" aria-haspopup="true" role="tooltip"
|
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right"
|
|
||||||
[class.invalid]="ldapUidInput.invalid && (ldapUidInput.dirty || ldapUidInput.touched)">
|
|
||||||
<input name="ldapUid" type="text" #ldapUidInput="ngModel" [(ngModel)]="currentConfig.ldap_uid.value"
|
|
||||||
required id="ldapUid" size="40" [disabled]="disabled(currentConfig.ldap_uid)">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-lg tooltip-top-right top-1">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.LDAP_UID' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapScope">{{'CONFIG.LDAP.SCOPE' | translate}}</label>
|
|
||||||
<div class="select">
|
|
||||||
<select id="ldapScope" name="ldapScope" [(ngModel)]="currentConfig.ldap_scope.value"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_scope)">
|
|
||||||
<option value="0">{{'CONFIG.SCOPE_BASE' | translate }}</option>
|
|
||||||
<option value="1">{{'CONFIG.SCOPE_ONE_LEVEL' | translate }}</option>
|
|
||||||
<option value="2">{{'CONFIG.SCOPE_SUBTREE' | translate }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right top-1">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.LDAP_SCOPE' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapGroupBaseDN">{{'CONFIG.LDAP.LDAP_GROUP_BASE_DN' | translate}}</label>
|
|
||||||
<input name="ldapGroupBaseDN" class="padding-right-28" type="text" #ldapGroupDNInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_group_base_dn.value" id="ldapGroupBaseDN" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_group_base_dn)">
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
|
||||||
<span>{{'CONFIG.LDAP.LDAP_GROUP_BASE_DN_INFO' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapGroupFilter">{{'CONFIG.LDAP.LDAP_GROUP_FILTER' | translate}}</label>
|
|
||||||
<input name="ldapGroupFilter" type="text" class="padding-right-28" #ldapGroupFilterInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_group_search_filter.value" id="ldapGroupFilter" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_group_search_filter)">
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
|
||||||
<span>{{'CONFIG.LDAP.LDAP_GROUP_FILTER_INFO' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapGroupGID">{{'CONFIG.LDAP.LDAP_GROUP_GID' | translate}}</label>
|
|
||||||
<input name="ldapGroupGID" class="padding-right-28" type="text" #ldapGroupDNInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_group_attribute_name.value" id="ldapGroupGID" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_group_attribute_name)">
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
|
||||||
<span>{{'CONFIG.LDAP.LDAP_GROUP_GID_INFO' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
|
||||||
<!-- This is for ldap group admin dn -->
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{'CONFIG.LDAP.LDAP_GROUP_ADMIN_DN' | translate}}</label>
|
|
||||||
<input name="ldapGroupAdminDN" class="padding-right-28" type="text" #ldapGroupFilterInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_group_admin_dn.value" id="ldapGroupAdminDN" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_group_admin_dn)">
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
|
||||||
<span>{{'CONFIG.LDAP.LDAP_GROUP_ADMIN_DN_INFO' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
|
||||||
<!-- End of ldap group admin dn -->
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{'CONFIG.LDAP.LDAP_GROUP_MEMBERSHIP' | translate}}</label>
|
|
||||||
<input name="ldapGroupMembership" class="padding-right-28" type="text" #ldapGroupFilterInput="ngModel"
|
|
||||||
[(ngModel)]="currentConfig.ldap_group_membership_attribute.value" id="ldapGroupMembership" size="40"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_group_membership_attribute)">
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
|
||||||
<span>{{'CONFIG.LDAP.LDAP_GROUP_MEMBERSHIP_INFO' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="ldapGroupScope">{{'CONFIG.LDAP.GROUP_SCOPE' | translate}}</label>
|
|
||||||
<div class="select">
|
|
||||||
<select id="ldapGroupScope" name="ldapGroupScope"
|
|
||||||
[(ngModel)]="currentConfig.ldap_group_search_scope.value"
|
|
||||||
[disabled]="disabled(currentConfig.ldap_group_search_scope)">
|
|
||||||
<option value="0">{{'CONFIG.SCOPE_BASE' | translate }}</option>
|
|
||||||
<option value="1">{{'CONFIG.SCOPE_ONE_LEVEL' | translate }}</option>
|
|
||||||
<option value="2">{{'CONFIG.SCOPE_SUBTREE' | translate }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<clr-tooltip>
|
|
||||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
|
||||||
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
|
||||||
<span>{{'CONFIG.LDAP.GROUP_SCOPE_INFO' | translate}}</span>
|
|
||||||
</clr-tooltip-content>
|
|
||||||
</clr-tooltip>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="form-block">
|
|
||||||
<div class="form-group" *ngIf="showSelfReg">
|
|
||||||
<label for="selfReg">{{'CONFIG.SELF_REGISTRATION' | translate}}</label>
|
|
||||||
<clr-checkbox-wrapper>
|
|
||||||
<input type="checkbox" clrCheckbox name="selfReg" id="selfReg"
|
|
||||||
[(ngModel)]="currentConfig.self_registration.value"
|
|
||||||
[disabled]="disabled(currentConfig.self_registration)" />
|
|
||||||
<label>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-top-right top-5">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span *ngIf="checkable; else elseBlock" class="tooltip-content">{{'CONFIG.TOOLTIP.SELF_REGISTRATION_ENABLE'
|
|
||||||
| translate}}</span>
|
|
||||||
<ng-template #elseBlock>
|
|
||||||
<span
|
|
||||||
class="tooltip-content">{{'CONFIG.TOOLTIP.SELF_REGISTRATION_DISABLE' | translate}}</span>
|
|
||||||
</ng-template>
|
|
||||||
</a>
|
|
||||||
</label>
|
|
||||||
</clr-checkbox-wrapper>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section *ngIf="showLdap">
|
<section *ngIf="showLdap">
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="ldapVerifyCert">{{'CONFIG.LDAP.VERIFY_CERT' | translate}}</label>
|
<label for="ldapUrl" class="required">{{'CONFIG.LDAP.URL' | translate}}
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapUrl" type="text" #ldapUrlInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_url.value" required id="ldapUrl" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_url)" />
|
||||||
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapSearchDN" >{{'CONFIG.LDAP.SEARCH_DN' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.LDAP_SEARCH_DN' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapSearchDN" type="text" #ldapSearchDNInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_search_dn.value" id="ldapSearchDN" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_search_dn)" />
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapSearchPwd">{{'CONFIG.LDAP.SEARCH_PWD' | translate}}</label>
|
||||||
|
<input clrInput name="ldapSearchPwd" type="password" #ldapSearchPwdInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_search_password.value" id="ldapSearchPwd" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_search_password)" />
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapBaseDN" class="required">{{'CONFIG.LDAP.BASE_DN' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.LDAP_BASE_DN' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapBaseDN" type="text" #ldapBaseDNInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_base_dn.value" required id="ldapBaseDN" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_base_dn)" />
|
||||||
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapFilter">{{'CONFIG.LDAP.FILTER' | translate}}</label>
|
||||||
|
<input clrInput name="ldapFilter" type="text" #ldapFilterInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_filter.value" id="ldapFilter" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_filter)" />
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapUid" class="required">{{'CONFIG.LDAP.UID' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.LDAP_UID' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapUid" type="text" #ldapUidInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_uid.value" required id="ldapUid" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_uid)" />
|
||||||
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<clr-select-container>
|
||||||
|
<label for="ldapScope">{{'CONFIG.LDAP.SCOPE' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.LDAP_SCOPE' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<select clrSelect id="ldapScope" name="ldapScope" [(ngModel)]="currentConfig.ldap_scope.value"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_scope)">
|
||||||
|
<option value="0">{{'CONFIG.SCOPE_BASE' | translate }}</option>
|
||||||
|
<option value="1">{{'CONFIG.SCOPE_ONE_LEVEL' | translate }}</option>
|
||||||
|
<option value="2">{{'CONFIG.SCOPE_SUBTREE' | translate }}</option>
|
||||||
|
</select>
|
||||||
|
</clr-select-container>
|
||||||
|
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapGroupBaseDN">{{'CONFIG.LDAP.LDAP_GROUP_BASE_DN' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.LDAP.LDAP_GROUP_BASE_DN_INFO' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapGroupBaseDN" type="text" #ldapGroupDNInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_group_base_dn.value" id="ldapGroupBaseDN" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_group_base_dn)" />
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapGroupFilter">{{'CONFIG.LDAP.LDAP_GROUP_FILTER' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.LDAP.LDAP_GROUP_FILTER_INFO' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapGroupFilter" type="text" #ldapGroupFilterInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_group_search_filter.value" id="ldapGroupFilter" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_group_search_filter)" />
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapGroupGID">{{'CONFIG.LDAP.LDAP_GROUP_GID' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.LDAP.LDAP_GROUP_GID_INFO' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapGroupGID" type="text" #ldapGroupDNInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_group_attribute_name.value" id="ldapGroupGID" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_group_attribute_name)" />
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<!-- This is for ldap group admin dn -->
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapGroupAdminDN">{{'CONFIG.LDAP.LDAP_GROUP_ADMIN_DN' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.LDAP.LDAP_GROUP_ADMIN_DN_INFO' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapGroupAdminDN" type="text" #ldapGroupFilterInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_group_admin_dn.value" id="ldapGroupAdminDN" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_group_admin_dn)" />
|
||||||
|
</clr-input-container>
|
||||||
|
|
||||||
|
<!-- End of ldap group admin dn -->
|
||||||
|
<clr-input-container>
|
||||||
|
<label for="ldapGroupAdminDN">{{'CONFIG.LDAP.LDAP_GROUP_MEMBERSHIP' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.LDAP.LDAP_GROUP_MEMBERSHIP_INFO' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<input clrInput name="ldapGroupMembership" type="text" #ldapGroupFilterInput="ngModel"
|
||||||
|
[(ngModel)]="currentConfig.ldap_group_membership_attribute.value" id="ldapGroupMembership" size="40"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_group_membership_attribute)" />
|
||||||
|
</clr-input-container>
|
||||||
|
<clr-select-container>
|
||||||
|
<label for="ldapGroupScope">{{'CONFIG.LDAP.SCOPE' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.LDAP.GROUP_SCOPE_INFO' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<select clrSelect id="ldapGroupScope" name="ldapGroupScope"
|
||||||
|
[(ngModel)]="currentConfig.ldap_group_search_scope.value"
|
||||||
|
[disabled]="disabled(currentConfig.ldap_group_search_scope)">
|
||||||
|
<option value="0">{{'CONFIG.SCOPE_BASE' | translate }}</option>
|
||||||
|
<option value="1">{{'CONFIG.SCOPE_ONE_LEVEL' | translate }}</option>
|
||||||
|
<option value="2">{{'CONFIG.SCOPE_SUBTREE' | translate }}</option>
|
||||||
|
</select>
|
||||||
|
</clr-select-container>
|
||||||
|
</section>
|
||||||
|
<clr-checkbox-container *ngIf="showSelfReg">
|
||||||
|
<label for="selfReg">{{'CONFIG.SELF_REGISTRATION' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span *ngIf="checkable; else elseBlock" class="tooltip-content">{{'CONFIG.TOOLTIP.SELF_REGISTRATION_ENABLE'
|
||||||
|
| translate}}</span>
|
||||||
|
<ng-template #elseBlock>
|
||||||
|
<span
|
||||||
|
class="tooltip-content">{{'CONFIG.TOOLTIP.SELF_REGISTRATION_DISABLE' | translate}}</span>
|
||||||
|
</ng-template>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
|
<clr-checkbox-wrapper>
|
||||||
|
<input type="checkbox" clrCheckbox name="selfReg" id="selfReg"
|
||||||
|
[(ngModel)]="currentConfig.self_registration.value"
|
||||||
|
[disabled]="disabled(currentConfig.self_registration)" />
|
||||||
|
</clr-checkbox-wrapper>
|
||||||
|
</clr-checkbox-container>
|
||||||
|
|
||||||
|
<section *ngIf="showLdap">
|
||||||
|
|
||||||
|
<clr-checkbox-container>
|
||||||
|
<label for="ldapVerifyCert">{{'CONFIG.LDAP.VERIFY_CERT' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.TOOLTIP.VERIFY_CERT' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
|
</label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" clrCheckbox name="ldapVerifyCert" id="ldapVerifyCert"
|
<input type="checkbox" clrCheckbox name="ldapVerifyCert" id="ldapVerifyCert"
|
||||||
[ngModel]="currentConfig.ldap_verify_cert.value" [disabled]="disabled(currentConfig.ldap_scope)"
|
[ngModel]="currentConfig.ldap_verify_cert.value" [disabled]="disabled(currentConfig.ldap_scope)"
|
||||||
(ngModelChange)="setVerifyCertValue($event)" />
|
(ngModelChange)="setVerifyCertValue($event)" />
|
||||||
<label>
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-top-right top-5">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.VERIFY_CERT' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</label>
|
|
||||||
</clr-checkbox-wrapper>
|
</clr-checkbox-wrapper>
|
||||||
</div>
|
</clr-checkbox-container>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
<section class="form-block" *ngIf="showHttpAuth">
|
<section *ngIf="showHttpAuth">
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="http_authproxy_endpoint" class="required">{{'CONFIG.HTTP_AUTH.ENDPOINT' | translate}}</label>
|
<label for="http_authproxy_endpoint" class="required">{{'CONFIG.HTTP_AUTH.ENDPOINT' | translate}}</label>
|
||||||
<label for="http_authproxy_endpoint" aria-haspopup="true" role="tooltip"
|
<input clrInput type="text" pattern="^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(.*?)*$"
|
||||||
class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
#httpAuthproxyEndpointInput="ngModel" required id="http_authproxy_endpoint"
|
||||||
[class.invalid]="httpAuthproxyEndpointInput.invalid && (httpAuthproxyEndpointInput.dirty || httpAuthproxyEndpointInput.touched)">
|
name="http_authproxy_endpoint" size="35" [(ngModel)]="currentConfig.http_authproxy_endpoint.value"
|
||||||
<input type="text" pattern="^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(.*?)*$"
|
[disabled]="!currentConfig.http_authproxy_endpoint.editable" />
|
||||||
#httpAuthproxyEndpointInput="ngModel" required id="http_authproxy_endpoint"
|
<clr-control-error>{{'TOOLTIP.ENDPOINT_FORMAT' | translate}}</clr-control-error>
|
||||||
name="http_authproxy_endpoint" size="35" [(ngModel)]="currentConfig.http_authproxy_endpoint.value"
|
</clr-input-container>
|
||||||
[disabled]="!currentConfig.http_authproxy_endpoint.editable">
|
<clr-input-container>
|
||||||
<span class="tooltip-content">
|
<label for="http_authproxy_tokenreview_endpoint"
|
||||||
{{'TOOLTIP.ENDPOINT_FORMAT' | translate}}
|
class="required">{{'CONFIG.HTTP_AUTH.TOKEN_REVIEW' | translate}}</label>
|
||||||
</span>
|
<input clrInput type="text" #httpAuthproxyTokenReviewInput="ngModel"
|
||||||
</label>
|
pattern="^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(.*?)*$" required
|
||||||
</div>
|
id="http_authproxy_tokenreview_endpoint" name="http_authproxy_tokenreview_endpoint" size="35"
|
||||||
<div class="form-group">
|
[(ngModel)]="currentConfig.http_authproxy_tokenreview_endpoint.value"
|
||||||
<label for="http_authproxy_tokenreview_endpoint" class="required">{{'CONFIG.HTTP_AUTH.TOKEN_REVIEW' | translate}}</label>
|
[disabled]="!currentConfig.http_authproxy_tokenreview_endpoint.editable" />
|
||||||
<label for="http_authproxy_tokenreview_endpoint" aria-haspopup="true" role="tooltip"
|
<clr-control-error>{{'TOOLTIP.ENDPOINT_FORMAT' | translate}}</clr-control-error>
|
||||||
class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
</clr-input-container>
|
||||||
[class.invalid]="httpAuthproxyTokenReviewInput.invalid && (httpAuthproxyTokenReviewInput.dirty || httpAuthproxyTokenReviewInput.touched)">
|
<clr-checkbox-container clrInline>
|
||||||
<input type="text" #httpAuthproxyTokenReviewInput="ngModel" pattern="^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(.*?)*$"
|
|
||||||
required id="http_authproxy_tokenreview_endpoint" name="http_authproxy_tokenreview_endpoint" size="35"
|
|
||||||
[(ngModel)]="currentConfig.http_authproxy_tokenreview_endpoint.value" [disabled]="!currentConfig.http_authproxy_tokenreview_endpoint.editable">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ENDPOINT_FORMAT' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="http_authproxy_verify_cert"
|
<label for="http_authproxy_verify_cert"
|
||||||
class="required">{{'CONFIG.HTTP_AUTH.VERIFY_CERT' | translate}}</label>
|
class="required">{{'CONFIG.HTTP_AUTH.VERIFY_CERT' | translate}}</label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" clrCheckbox name="http_authproxy_verify_cert"
|
<input type="checkbox" clrCheckbox name="http_authproxy_verify_cert" id="http_authproxy_verify_cert"
|
||||||
id="http_authproxy_verify_cert"
|
|
||||||
[(ngModel)]="currentConfig.http_authproxy_verify_cert.value"
|
[(ngModel)]="currentConfig.http_authproxy_verify_cert.value"
|
||||||
[disabled]="!currentConfig.http_authproxy_verify_cert.editable" />
|
[disabled]="!currentConfig.http_authproxy_verify_cert.editable" />
|
||||||
</clr-checkbox-wrapper>
|
</clr-checkbox-wrapper>
|
||||||
</div>
|
</clr-checkbox-container>
|
||||||
<div class="form-group">
|
<clr-checkbox-container clrInline>
|
||||||
<label for="http_authproxy_skip_search"
|
<label for="http_authproxy_skip_search"
|
||||||
class="required">{{'CONFIG.HTTP_AUTH.SKIP_SEARCH' | translate}}</label>
|
class="required">{{'CONFIG.HTTP_AUTH.SKIP_SEARCH' | translate}}</label>
|
||||||
<clr-checkbox-wrapper>
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" clrCheckbox name="http_authproxy_skip_search"
|
<input type="checkbox" clrCheckbox name="http_authproxy_skip_search" id="http_authproxy_skip_search"
|
||||||
id="http_authproxy_skip_search"
|
|
||||||
[disabled]="!currentConfig.http_authproxy_skip_search.editable"
|
[disabled]="!currentConfig.http_authproxy_skip_search.editable"
|
||||||
[(ngModel)]="currentConfig.http_authproxy_skip_search.value" />
|
[(ngModel)]="currentConfig.http_authproxy_skip_search.value" />
|
||||||
</clr-checkbox-wrapper>
|
</clr-checkbox-wrapper>
|
||||||
</div>
|
</clr-checkbox-container>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="form-block" *ngIf="showOIDC">
|
<section *ngIf="showOIDC">
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="oidcName" class="required">{{'CONFIG.OIDC.OIDC_PROVIDER' | translate}}</label>
|
<label class="required" for="oidcName">{{'CONFIG.OIDC.OIDC_PROVIDER' | translate}}
|
||||||
<label for="oidcName" aria-haspopup="true" role="tooltip"
|
<clr-tooltip>
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right"
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
[class.invalid]="oidcNameInput.invalid && (oidcNameInput.dirty || oidcNameInput.touched)">
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
<input name="oidcName" required type="text" #oidcNameInput="ngModel"
|
<span>{{'TOOLTIP.OIDC_NAME' | translate}}</span>
|
||||||
[(ngModel)]="currentConfig.oidc_name.value" required id="oidcName" size="40"
|
</clr-tooltip-content>
|
||||||
[disabled]="disabled(currentConfig.oidc_name)">
|
</clr-tooltip>
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
<input clrInput name="oidcName" required type="text" #oidcNameInput="ngModel"
|
||||||
class="tooltip tooltip-lg tooltip-top-right top-1">
|
[(ngModel)]="currentConfig.oidc_name.value" id="oidcName" size="40"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
[disabled]="disabled(currentConfig.oidc_name)" />
|
||||||
<span class="tooltip-content">{{'TOOLTIP.OIDC_NAME' | translate}}</span>
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
</a>
|
</clr-input-container>
|
||||||
</div>
|
<clr-input-container>
|
||||||
<div class="form-group">
|
<label class="required" for="oidcEndpoint">{{'CONFIG.OIDC.ENDPOINT' | translate}}
|
||||||
<label for="oidcEndpoint" class="required">{{'CONFIG.OIDC.ENDPOINT' | translate}}</label>
|
<clr-tooltip>
|
||||||
<label for="oidcEndpoint" aria-haspopup="true" role="tooltip"
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
[class.invalid]="oidcEndpointInput.invalid && (oidcEndpointInput.dirty || oidcEndpointInput.touched)"
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right">
|
<span>{{'TOOLTIP.OIDC_ENDPOINT' | translate}}</span>
|
||||||
<input name="oidcEndpoint" type="text" #oidcEndpointInput="ngModel" required
|
</clr-tooltip-content>
|
||||||
[(ngModel)]="currentConfig.oidc_endpoint.value" id="oidcEndpoint" size="40"
|
</clr-tooltip>
|
||||||
[disabled]="disabled(currentConfig.oidc_endpoint)" pattern="^([hH][tT]{2}[pP][sS]:\/\/)(.*?)*$">
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.OIDC_ENDPOIT_FORMAT' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
<input clrInput name="oidcEndpoint" type="text" #oidcEndpointInput="ngModel" required
|
||||||
class="tooltip tooltip-lg tooltip-top-right top-1">
|
[(ngModel)]="currentConfig.oidc_endpoint.value" id="oidcEndpoint" size="40"
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
[disabled]="disabled(currentConfig.oidc_endpoint)"
|
||||||
<span class="tooltip-content">{{'TOOLTIP.OIDC_ENDPOINT' | translate}}</span>
|
pattern="^([hH][tT]{2}[pP][sS]:\/\/)(.*?)*$" />
|
||||||
</a>
|
<clr-control-error>{{'TOOLTIP.OIDC_ENDPOIT_FORMAT' | translate}}</clr-control-error>
|
||||||
</div>
|
</clr-input-container>
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="oidcClientId" class="required">{{'CONFIG.OIDC.CLIENT_ID' | translate}}</label>
|
<label for="oidcClientId" class="required">{{'CONFIG.OIDC.CLIENT_ID' | translate}}</label>
|
||||||
<label for="oidcClientId" aria-haspopup="true" role="tooltip"
|
<input clrInput name="oidcClientId" type="text" #oidcClientIdInput="ngModel" required
|
||||||
[class.invalid]="oidcClientIdInput.invalid && (oidcClientIdInput.dirty || oidcClientIdInput.touched)"
|
[(ngModel)]="currentConfig.oidc_client_id.value" id="oidcClientId" size="40"
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right">
|
[disabled]="disabled(currentConfig.oidc_client_id)" />
|
||||||
<input name="oidcClientId" type="text" #oidcClientIdInput="ngModel" required
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
[(ngModel)]="currentConfig.oidc_client_id.value" id="oidcClientId" size="40"
|
</clr-input-container>
|
||||||
[disabled]="disabled(currentConfig.oidc_client_id)">
|
<clr-input-container>
|
||||||
<span class="tooltip-content">
|
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="oidcClientSecret" class="required">{{'CONFIG.OIDC.CLIENTSECRET' | translate}}</label>
|
<label for="oidcClientSecret" class="required">{{'CONFIG.OIDC.CLIENTSECRET' | translate}}</label>
|
||||||
<label for="oidcClientSecret" aria-haspopup="true" role="tooltip"
|
<input clrInput name="oidcClientSecret" type="password" #oidcClientSecretInput="ngModel" required
|
||||||
[class.invalid]="oidcClientSecretInput.invalid && (oidcClientSecretInput.dirty || oidcClientSecretInput.touched)"
|
[(ngModel)]="currentConfig.oidc_client_secret.value" id="oidcClientSecret" size="40"
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right">
|
[disabled]="disabled(currentConfig.oidc_client_secret)" />
|
||||||
<input name="oidcClientSecret" type="password" #oidcClientSecretInput="ngModel" required
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
[(ngModel)]="currentConfig.oidc_client_secret.value" id="oidcClientSecret" size="40"
|
</clr-input-container>
|
||||||
[disabled]="disabled(currentConfig.oidc_client_secret)">
|
<clr-input-container>
|
||||||
<span class="tooltip-content">
|
<label class="required" for="oidcScope">{{'CONFIG.OIDC.SCOPE' | translate}}
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
<clr-tooltip>
|
||||||
</span>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
</label>
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
</div>
|
<span>{{'TOOLTIP.OIDC_SCOPE' | translate}}</span>
|
||||||
<div class="form-group">
|
</clr-tooltip-content>
|
||||||
<label for="oidcScope" class="required">{{'CONFIG.OIDC.SCOPE' | translate}}</label>
|
</clr-tooltip>
|
||||||
<label for="oidcScope" aria-haspopup="true" role="tooltip"
|
</label>
|
||||||
[class.invalid]="oidcScopeInput.invalid && (oidcScopeInput.dirty || oidcScopeInput.touched)"
|
<input clrInput name="oidcScope" type="text" #oidcScopeInput="ngModel"
|
||||||
class="tooltip tooltip-validation tooltip-lg tooltip-top-right">
|
[(ngModel)]="currentConfig.oidc_scope.value" id="oidcScope" size="40" required
|
||||||
<input name="oidcScope" type="text" #oidcScopeInput="ngModel"
|
[disabled]="disabled(currentConfig.oidc_scope)" pattern="^(\w+,){0,}openid(,\w+){0,}$" />
|
||||||
[(ngModel)]="currentConfig.oidc_scope.value" id="oidcScope" size="40" required
|
<clr-control-error>{{'TOOLTIP.SCOPE_REQUIRED' | translate}}</clr-control-error>
|
||||||
[disabled]="disabled(currentConfig.oidc_scope)" pattern="^(\w+,){0,}openid(,\w+){0,}$">
|
</clr-input-container>
|
||||||
<span class="tooltip-content">
|
<clr-checkbox-container>
|
||||||
{{'TOOLTIP.SCOPE_REQUIRED' | translate}}
|
<label for="oidc_verify_cert">{{'CONFIG.OIDC.OIDC_VERIFYCERT' | translate}}
|
||||||
</span>
|
<clr-tooltip>
|
||||||
</label>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
class="tooltip tooltip-lg tooltip-top-right top-1">
|
<span>{{'TOOLTIP.OIDC_VERIFYCERT' | translate}}</span>
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
</clr-tooltip-content>
|
||||||
<span class="tooltip-content">{{'TOOLTIP.OIDC_SCOPE' | translate}}</span>
|
</clr-tooltip>
|
||||||
</a>
|
</label>
|
||||||
</div>
|
<clr-checkbox-wrapper>
|
||||||
<div class="form-group">
|
<input type="checkbox" clrCheckbox name="oidc_verify_cert" id="oidc_verify_cert"
|
||||||
<label for="oidc_verify_cert">{{'CONFIG.OIDC.OIDC_VERIFYCERT' | translate}}</label>
|
[disabled]="disabled(currentConfig.oidc_verify_cert)"
|
||||||
<clr-checkbox-wrapper>
|
[(ngModel)]="currentConfig.oidc_verify_cert.value" />
|
||||||
<input type="checkbox" clrCheckbox name="oidc_verify_cert" id="oidc_verify_cert"
|
</clr-checkbox-wrapper>
|
||||||
[disabled]="disabled(currentConfig.oidc_verify_cert)"
|
</clr-checkbox-container>
|
||||||
[(ngModel)]="currentConfig.oidc_verify_cert.value" />
|
<div class="oidc-tip">{{ 'CONFIG.OIDC.OIDC_REDIREC_URL' | translate}}
|
||||||
</clr-checkbox-wrapper>
|
<span>{{redirectUrl}}/c/oidc/callback</span></div>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
|
||||||
class="tooltip tooltip-lg tooltip-top-right top-1px">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'TOOLTIP.OIDC_VERIFYCERT' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="oidc-tip">{{ 'CONFIG.OIDC.OIDC_REDIREC_URL' | translate}} <span>{{redirectUrl}}/c/oidc/callback</span></div>
|
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
<div>
|
<div>
|
||||||
@ -426,4 +384,4 @@
|
|||||||
<button type="button" class="btn btn-outline" (click)="pingTestServer()" *ngIf="showTestingServerBtn"
|
<button type="button" class="btn btn-outline" (click)="pingTestServer()" *ngIf="showTestingServerBtn"
|
||||||
[disabled]="!isConfigValidForTesting()">{{(showLdap?'BUTTON.TEST_LDAP':'BUTTON.TEST_OIDC') | translate}}</button>
|
[disabled]="!isConfigValidForTesting()">{{(showLdap?'BUTTON.TEST_LDAP':'BUTTON.TEST_OIDC') | translate}}</button>
|
||||||
<span id="forTestingLDAP" class="spinner spinner-inline" [hidden]="hideTestingSpinner"></span>
|
<span id="forTestingLDAP" class="spinner spinner-inline" [hidden]="hideTestingSpinner"></span>
|
||||||
</div>
|
</div>
|
@ -1,23 +1,11 @@
|
|||||||
clr-tooltip {
|
|
||||||
top: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.padding-right-28 {
|
|
||||||
padding-right:28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-1 {
|
|
||||||
top: -1px;
|
|
||||||
}
|
|
||||||
.top-1px {
|
|
||||||
top: 1px;
|
|
||||||
}
|
|
||||||
.top-5 {
|
|
||||||
top: -5px;
|
|
||||||
}
|
|
||||||
.oidc-tip {
|
.oidc-tip {
|
||||||
color: rgb(10, 10, 10);
|
color: rgb(10, 10, 10);
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
.more-info-link {
|
.more-info-link {
|
||||||
color: #101010;
|
color: #101010;
|
||||||
|
}
|
||||||
|
.ml-04 {
|
||||||
|
margin-left: 0.4rem;
|
||||||
}
|
}
|
@ -37,7 +37,7 @@ export class ConfigurationAuthComponent implements OnChanges, OnInit {
|
|||||||
// tslint:disable-next-line:no-input-rename
|
// tslint:disable-next-line:no-input-rename
|
||||||
@Input('allConfig') currentConfig: Configuration = new Configuration();
|
@Input('allConfig') currentConfig: Configuration = new Configuration();
|
||||||
private originalConfig: Configuration;
|
private originalConfig: Configuration;
|
||||||
@ViewChild('authConfigFrom') authForm: NgForm;
|
@ViewChild('authConfigFrom', {static: false}) authForm: NgForm;
|
||||||
@Output() refreshAllconfig = new EventEmitter<any>();
|
@Output() refreshAllconfig = new EventEmitter<any>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -11,14 +11,22 @@ clr-icon {
|
|||||||
color: grey;
|
color: grey;
|
||||||
margin-top: -3px;
|
margin-top: -3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
clr-icon:hover {
|
clr-icon:hover {
|
||||||
color: #007CBB;
|
color: #007CBB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clr-validate-icon {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
.config-title {
|
.config-title {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-position {
|
.tooltip-position {
|
||||||
top: -7px;
|
top: -7px;
|
||||||
|
}
|
||||||
|
.clr-form-control-disabled {
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
@ -48,9 +48,9 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
originalCopy: Configuration = new Configuration();
|
originalCopy: Configuration = new Configuration();
|
||||||
confirmSub: Subscription;
|
confirmSub: Subscription;
|
||||||
|
|
||||||
@ViewChild(SystemSettingsComponent) systemSettingsConfig: SystemSettingsComponent;
|
@ViewChild(SystemSettingsComponent, {static: false}) systemSettingsConfig: SystemSettingsComponent;
|
||||||
@ViewChild(ConfigurationEmailComponent) mailConfig: ConfigurationEmailComponent;
|
@ViewChild(ConfigurationEmailComponent, {static: false}) mailConfig: ConfigurationEmailComponent;
|
||||||
@ViewChild(ConfigurationAuthComponent) authConfig: ConfigurationAuthComponent;
|
@ViewChild(ConfigurationAuthComponent, {static: false}) authConfig: ConfigurationAuthComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private msgHandler: MessageHandlerService,
|
private msgHandler: MessageHandlerService,
|
||||||
|
@ -1,91 +1,81 @@
|
|||||||
<form #mailConfigFrom="ngForm" class="form">
|
<form #mailConfigFrom="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="mailServer" class="required">{{'CONFIG.MAIL_SERVER' | translate}}</label>
|
<label for="mailServer" class="required">{{'CONFIG.MAIL_SERVER' | translate}}</label>
|
||||||
<label for="mailServer" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
<input clrInput name="mailServer" type="text" #mailServerInput="ngModel"
|
||||||
[class.invalid]="mailServerInput.invalid && (mailServerInput.dirty || mailServerInput.touched)">
|
[(ngModel)]="currentConfig.email_host.value" required id="mailServer" size="40"
|
||||||
<input name="mailServer" type="text" #mailServerInput="ngModel" [(ngModel)]="currentConfig.email_host.value"
|
[disabled]="disabled(currentConfig.email_host)" />
|
||||||
required id="mailServer" size="40" [disabled]="disabled(currentConfig.email_host)">
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
<span class="tooltip-content">
|
</clr-input-container>
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
<clr-input-container>
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="emailPort" class="required">{{'CONFIG.MAIL_SERVER_PORT' | translate}}</label>
|
<label for="emailPort" class="required">{{'CONFIG.MAIL_SERVER_PORT' | translate}}</label>
|
||||||
<label for="emailPort" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
<input clrInput name="emailPort" type="text" #emailPortInput="ngModel"
|
||||||
[class.invalid]="emailPortInput.invalid && (emailPortInput.dirty || emailPortInput.touched)">
|
[(ngModel)]="currentConfig.email_port.value" required port id="emailPort" size="40"
|
||||||
<input name="emailPort" type="text" #emailPortInput="ngModel" [(ngModel)]="currentConfig.email_port.value"
|
[disabled]="disabled(currentConfig.email_port)" />
|
||||||
required port id="emailPort" size="40" [disabled]="disabled(currentConfig.email_port)">
|
<clr-control-error>{{'TOOLTIP.PORT_REQUIRED' | translate}}</clr-control-error>
|
||||||
<span class="tooltip-content">
|
</clr-input-container>
|
||||||
{{'TOOLTIP.PORT_REQUIRED' | translate}}
|
<clr-input-container>
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="emailUsername">{{'CONFIG.MAIL_USERNAME' | translate}}</label>
|
<label for="emailUsername">{{'CONFIG.MAIL_USERNAME' | translate}}</label>
|
||||||
<label for="emailUsername" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
<input clrInput name="emailUsername" type="text" #emailUsernameInput="ngModel"
|
||||||
[class.invalid]="false">
|
[(ngModel)]="currentConfig.email_username.value" id="emailUsername" size="40"
|
||||||
<input name="emailUsername" type="text" #emailUsernameInput="ngModel" [(ngModel)]="currentConfig.email_username.value"
|
[disabled]="disabled(currentConfig.email_username)" />
|
||||||
id="emailUsername" size="40" [disabled]="disabled(currentConfig.email_username)">
|
</clr-input-container>
|
||||||
<span class="tooltip-content">
|
<clr-input-container>
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="emailPassword">{{'CONFIG.MAIL_PASSWORD' | translate}}</label>
|
<label for="emailPassword">{{'CONFIG.MAIL_PASSWORD' | translate}}</label>
|
||||||
<label for="emailPassword" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
<input clrInput name="emailPassword" type="password" #emailPasswordInput="ngModel"
|
||||||
[class.invalid]="false">
|
[(ngModel)]="currentConfig.email_password.value" id="emailPassword" size="40"
|
||||||
<input name="emailPassword" type="password" #emailPasswordInput="ngModel" [(ngModel)]="currentConfig.email_password.value"
|
[disabled]="disabled(currentConfig.email_password)" />
|
||||||
id="emailPassword" size="40" [disabled]="disabled(currentConfig.email_password)">
|
</clr-input-container>
|
||||||
<span class="tooltip-content">
|
<clr-input-container>
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="emailFrom" class="required">{{'CONFIG.MAIL_FROM' | translate}}</label>
|
<label for="emailFrom" class="required">{{'CONFIG.MAIL_FROM' | translate}}</label>
|
||||||
<label for="emailFrom" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right"
|
<input clrInput name="emailFrom" type="text" #emailFromInput="ngModel"
|
||||||
[class.invalid]="emailFromInput.invalid && (emailFromInput.dirty || emailFromInput.touched)">
|
[(ngModel)]="currentConfig.email_from.value" required id="emailFrom" size="40"
|
||||||
<input name="emailFrom" type="text" #emailFromInput="ngModel" [(ngModel)]="currentConfig.email_from.value"
|
[disabled]="disabled(currentConfig.email_from)" />
|
||||||
required id="emailFrom" size="40" [disabled]="disabled(currentConfig.email_from)">
|
<clr-control-error>{{'TOOLTIP.ITEM_REQUIRED' | translate}}</clr-control-error>
|
||||||
<span class="tooltip-content">
|
</clr-input-container>
|
||||||
{{'TOOLTIP.ITEM_REQUIRED' | translate}}
|
<div class="clr-form-control">
|
||||||
</span>
|
<label class="clr-control-label" for="emailSSL">{{'CONFIG.MAIL_SSL' | translate}}
|
||||||
|
<clr-tooltip>
|
||||||
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'CONFIG.SSL_TOOLTIP' | translate}}</span>
|
||||||
|
</clr-tooltip-content>
|
||||||
|
</clr-tooltip>
|
||||||
</label>
|
</label>
|
||||||
|
<div class="clr-control-container">
|
||||||
|
<div class="clr-checkbox-wrapper" id="emailSSL-wrapper">
|
||||||
|
<input type="checkbox" name="emailSSL" id="emailSSL" [(ngModel)]="currentConfig.email_ssl.value"
|
||||||
|
[disabled]="disabled(currentConfig.email_ssl)" />
|
||||||
|
<label class="clr-control-label" for="emailSSL">
|
||||||
|
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="clr-form-control">
|
||||||
<label for="selfReg">{{'CONFIG.MAIL_SSL' | translate}}</label>
|
<label class="clr-control-label" for="emailInsecure">{{'CONFIG.MAIL_INSECURE' | translate}}
|
||||||
<!--for = selfReg?-->
|
<clr-tooltip>
|
||||||
<clr-checkbox-wrapper id="emailSSL-wrapper">
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<input type="checkbox" clrCheckbox name="emailSSL" id="emailSSL" [(ngModel)]="currentConfig.email_ssl.value"
|
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
|
||||||
[disabled]="disabled(currentConfig.email_ssl)" />
|
<span>{{'CONFIG.INSECURE_TOOLTIP' | translate}}</span>
|
||||||
<label>
|
</clr-tooltip-content>
|
||||||
<a role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right top-7">
|
</clr-tooltip>
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
</label>
|
||||||
<span class="tooltip-content">{{'CONFIG.SSL_TOOLTIP' | translate}}</span>
|
<div class="clr-control-container">
|
||||||
</a>
|
<div class="clr-checkbox-wrapper" id="emailInsecure-wrapper">
|
||||||
</label>
|
<input type="checkbox" name="emailInsecure" id="emailInsecure"
|
||||||
</clr-checkbox-wrapper>
|
[ngModel]="!currentConfig.email_insecure.value"
|
||||||
</div>
|
[disabled]="disabled(currentConfig.email_insecure)"
|
||||||
<div class="form-group">
|
(ngModelChange)="setInsecureValue($event)" />
|
||||||
<label for="insecure">{{'CONFIG.MAIL_INSECURE' | translate}}</label>
|
<label class="clr-control-label" for="emailInsecure"></label>
|
||||||
<clr-checkbox-wrapper id="emailInsecure-wrapper">
|
</div>
|
||||||
<input type="checkbox" clrCheckbox name="emaiInsecure" id="emailInsecure" [ngModel]="!currentConfig.email_insecure.value"
|
</div>
|
||||||
[disabled]="disabled(currentConfig.email_insecure)" (ngModelChange)="setInsecureValue($event)" />
|
|
||||||
<label>
|
|
||||||
<a role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right top-7">
|
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content">{{'CONFIG.INSECURE_TOOLTIP' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
</label>
|
|
||||||
</clr-checkbox-wrapper>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
<div>
|
<div>
|
||||||
<button type="button" id="config_email_save" class="btn btn-primary" (click)="save()" [disabled]="!isValid() || !hasChanges()">{{'BUTTON.SAVE'
|
<button type="button" id="config_email_save" class="btn btn-primary" (click)="save()"
|
||||||
|
[disabled]="!isValid() || !hasChanges()">{{'BUTTON.SAVE'
|
||||||
| translate}}</button>
|
| translate}}</button>
|
||||||
<button type="button" class="btn btn-outline" (click)="cancel()" [disabled]="!isValid() || !hasChanges()">{{'BUTTON.CANCEL'
|
<button type="button" class="btn btn-outline" (click)="cancel()" [disabled]="!isValid() || !hasChanges()">{{'BUTTON.CANCEL'
|
||||||
| translate}}</button>
|
| translate}}</button>
|
||||||
|
@ -31,7 +31,7 @@ export class ConfigurationEmailComponent implements OnChanges {
|
|||||||
private originalConfig: Configuration;
|
private originalConfig: Configuration;
|
||||||
testingMailOnGoing = false;
|
testingMailOnGoing = false;
|
||||||
onGoing = false;
|
onGoing = false;
|
||||||
@ViewChild("mailConfigFrom") mailForm: NgForm;
|
@ViewChild("mailConfigFrom", {static: true}) mailForm: NgForm;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private msgHandler: MessageHandlerService,
|
private msgHandler: MessageHandlerService,
|
||||||
|
@ -25,7 +25,7 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
formChangeSubscription: Subscription;
|
formChangeSubscription: Subscription;
|
||||||
|
|
||||||
@ViewChild('groupForm')
|
@ViewChild('groupForm', {static: false})
|
||||||
groupForm: NgForm;
|
groupForm: NgForm;
|
||||||
|
|
||||||
submitted = false;
|
submitted = false;
|
||||||
|
@ -39,7 +39,7 @@ export class GroupComponent implements OnInit, OnDestroy {
|
|||||||
batchInfos = new Map();
|
batchInfos = new Map();
|
||||||
isLdapMode: boolean;
|
isLdapMode: boolean;
|
||||||
|
|
||||||
@ViewChild(AddGroupModalComponent) newGroupModal: AddGroupModalComponent;
|
@ViewChild(AddGroupModalComponent, {static: false}) newGroupModal: AddGroupModalComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private operationService: OperationService,
|
private operationService: OperationService,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 datagrid-margin-top ">
|
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 datagrid-margin-top ">
|
||||||
<clr-datagrid (clrDgRefresh)="retrievePage($event)">
|
<clr-datagrid (clrDgRefresh)="retrievePage()">
|
||||||
<clr-dg-column>{{'AUDIT_LOG.USERNAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.USERNAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'AUDIT_LOG.REPOSITORY_NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.REPOSITORY_NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'AUDIT_LOG.TAGS' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.TAGS' | translate}}</clr-dg-column>
|
||||||
|
@ -109,12 +109,9 @@ export class AuditLogComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
retrievePage(state: State) {
|
retrievePage() {
|
||||||
if (state && state.page) {
|
this.queryParam.page = this.currentPage;
|
||||||
this.queryParam.page = Math.ceil((state.page.to + 1) / this.pageSize);
|
this.retrieve();
|
||||||
this.currentPage = this.queryParam.page;
|
|
||||||
this.retrieve();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doSearchAuditLogs(searchUsername: string): void {
|
doSearchAuditLogs(searchUsername: string): void {
|
||||||
|
@ -1,85 +1,75 @@
|
|||||||
<clr-modal [(clrModalOpen)]="createProjectOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
<clr-modal [(clrModalOpen)]="createProjectOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
||||||
<h3 class="modal-title">{{'PROJECT.NEW_PROJECT' | translate}}</h3>
|
<h3 class="modal-title">{{'PROJECT.NEW_PROJECT' | translate}}</h3>
|
||||||
<inline-alert class="modal-title"></inline-alert>
|
|
||||||
<div class="modal-body modal-height">
|
<div class="modal-body modal-height">
|
||||||
<form #projectForm="ngForm">
|
<inline-alert></inline-alert>
|
||||||
<section class="form-block">
|
<form #projectForm="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<div class="form-group">
|
<clr-input-container>
|
||||||
<label for="create_project_name" class="col-md-3 form-group-label-override required">{{'PROJECT.NAME' | translate}}</label>
|
<label class="required">{{'PROJECT.NAME' | translate}}</label>
|
||||||
<label for="create_project_name" aria-haspopup="true" role="tooltip" [class.invalid]="!isNameValid" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
|
<input clrInput type="text" id="create_project_name" [(ngModel)]="project.name" name="create_project_name" class="input-width"
|
||||||
<input type="text" id="create_project_name" [(ngModel)]="project.name"
|
required pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" minlength="2" #projectName="ngModel" autocomplete="off"
|
||||||
name="create_project_name" size="255" class="input-width"
|
(keyup)='handleValidation()'>
|
||||||
required
|
<clr-control-error *ngIf="!isNameValid" class="tooltip-content">
|
||||||
pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
|
{{ nameTooltipText | translate }}
|
||||||
minlength="2"
|
</clr-control-error>
|
||||||
#projectName="ngModel"
|
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
|
||||||
autocomplete="off"
|
</clr-input-container>
|
||||||
(keyup)='handleValidation()'>
|
<clr-checkbox-container>
|
||||||
<span class="tooltip-content">
|
<label class="form-group-label-override">{{'PROJECT.ACCESS_LEVEL' | translate}}
|
||||||
{{ nameTooltipText | translate }}
|
<clr-tooltip>
|
||||||
</span>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
</label>
|
<clr-tooltip-content clrPosition="bottom-left" clrSize="lg" *clrIfOpen>
|
||||||
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
|
<span>{{'PROJECT.INLINE_HELP_PUBLIC' | translate }}</span>
|
||||||
</div>
|
</clr-tooltip-content>
|
||||||
<div class="form-group">
|
</clr-tooltip>
|
||||||
<label class="col-md-4 form-group-label-override">{{'PROJECT.ACCESS_LEVEL' | translate}}</label>
|
</label>
|
||||||
<div class="checkbox-inline">
|
<clr-checkbox-wrapper>
|
||||||
<input type="checkbox" id="create_project_public" [(ngModel)]="project.metadata.public" name="public">
|
<input clrCheckbox type="checkbox" id="create_project_public" [(ngModel)]="project.metadata.public" name="public">
|
||||||
<label for="create_project_public"></label>
|
<label>{{ 'PROJECT.PUBLIC' | translate}}</label>
|
||||||
<span class="access-level-label">{{ 'PROJECT.PUBLIC' | translate}}</span>
|
</clr-checkbox-wrapper>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-md tooltip-right public-tooltip">
|
</clr-checkbox-container>
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
<clr-input-container *ngIf="isSystemAdmin">
|
||||||
<span class="tooltip-content inline-help-public">{{'PROJECT.INLINE_HELP_PUBLIC' | translate }}</span>
|
<label for="create_project_count_limit" class="required">{{'PROJECT.COUNT_QUOTA' | translate}}
|
||||||
</a>
|
<clr-tooltip>
|
||||||
</div>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
</div>
|
<clr-tooltip-content clrPosition="bottom-left" clrSize="lg" *clrIfOpen>
|
||||||
|
<span>{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
||||||
<div class="form-group" *ngIf="isSystemAdmin">
|
</clr-tooltip-content>
|
||||||
<label for="create_project_count_limit" class="required col-md-3 form-group-label-override">{{'PROJECT.COUNT_QUOTA' | translate}}</label>
|
</clr-tooltip>
|
||||||
<label for="create_project_count_limit" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left"
|
</label>
|
||||||
[class.invalid]="projectCountLimit.invalid && (projectCountLimit.dirty || projectCountLimit.touched)" >
|
<input clrInput type="text" id="create_project_count_limit" [(ngModel)]="countLimit" name="create_project_count_limit" class="input-width"
|
||||||
<input type="text" id="create_project_count_limit" [(ngModel)]="countLimit"
|
#projectCountLimit="ngModel" autocomplete="off">
|
||||||
name="create_project_count_limit" class="input-width"
|
<clr-control-error class="tooltip-content">
|
||||||
pattern="(^-1$)|(^([1-9]+)([0-9]+)*$)"
|
{{ 'PROJECT.COUNT_QUOTA_TIP' | translate }}
|
||||||
required
|
</clr-control-error>
|
||||||
#projectCountLimit="ngModel"
|
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
|
||||||
autocomplete="off" >
|
</clr-input-container>
|
||||||
<span class="tooltip-content">
|
<div class="clr-form-control" *ngIf="isSystemAdmin">
|
||||||
{{ 'PROJECT.COUNT_QUOTA_TIP' | translate }}
|
<label for="create_project_storage_limit" class="required clr-control-label">{{'PROJECT.STORAGE_QUOTA' | translate}}
|
||||||
</span>
|
<clr-tooltip>
|
||||||
</label>
|
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||||
<div class="checkbox-inline">
|
<clr-tooltip-content clrPosition="bottom-left" clrSize="lg" *clrIfOpen>
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-md tooltip-top-left public-tooltip">
|
<span>{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
||||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
</clr-tooltip-content>
|
||||||
<span class="tooltip-content inline-help-public">{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
</clr-tooltip>
|
||||||
</a>
|
</label>
|
||||||
</div>
|
<div class="clr-control-container" [class.clr-error]="(projectStorageLimit.invalid && (projectStorageLimit.dirty || projectStorageLimit.touched))||projectStorageLimit.errors">
|
||||||
</div>
|
<input type="text" id="create_project_storage_limit" [(ngModel)]="storageLimit" name="create_project_storage_limit" class="mr-10 clr-input"
|
||||||
<div class="form-group" *ngIf="isSystemAdmin">
|
#projectStorageLimit="ngModel" autocomplete="off">
|
||||||
<label for="create_project_storage_limit" class="required col-md-3 form-group-label-override">{{'PROJECT.STORAGE_QUOTA' | translate}}</label>
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
<label for="create_project_storage_limit" aria-haspopup="true" role="tooltip" class="tooltip-quota-storage tooltip tooltip-validation tooltip-md tooltip-top-left"
|
<div class="clr-select-wrapper">
|
||||||
[class.invalid]="(projectStorageLimit.invalid && (projectStorageLimit.dirty || projectStorageLimit.touched))||projectStorageLimit.errors" >
|
<select id="create_project_storage_limit_unit" name="create_project_storage_limit_unit" [(ngModel)]="storageLimitUnit">
|
||||||
<input type="text" id="create_project_storage_limit" [(ngModel)]="storageLimit"
|
|
||||||
name="create_project_storage_limit" size="255" class="input-width"
|
|
||||||
#projectStorageLimit="ngModel"
|
|
||||||
autocomplete="off" >
|
|
||||||
<span class="tooltip-content">
|
|
||||||
{{ 'PROJECT.STORAGE_QUOTA_TIP' | translate }}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<select clrSelect id="create_project_storage_limit_unit" name="create_project_storage_limit_unit" [(ngModel)]="storageLimitUnit">
|
|
||||||
<ng-template ngFor let-quotaUnit [ngForOf]="quotaUnits" let-i="index">
|
<ng-template ngFor let-quotaUnit [ngForOf]="quotaUnits" let-i="index">
|
||||||
<option *ngIf="i>1"[value]="quotaUnit.UNIT">{{ quotaUnit.UNIT }}</option>
|
<option *ngIf="i>1" [value]="quotaUnit.UNIT">{{ quotaUnit.UNIT }}</option>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</select>
|
</select>
|
||||||
<div class="checkbox-inline">
|
|
||||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-md tooltip-top-left public-tooltip">
|
|
||||||
<clr-icon shape="info-circle" size="24"></clr-icon>
|
|
||||||
<span class="tooltip-content inline-help-public">{{'PROJECT.QUOTA_UNLIMIT_TIP' | translate }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<clr-control-error *ngIf="(projectStorageLimit.invalid && (projectStorageLimit.dirty || projectStorageLimit.touched))||projectStorageLimit.errors"
|
||||||
|
class="tooltip-content">
|
||||||
|
{{ 'PROJECT.STORAGE_QUOTA_TIP' | translate }}
|
||||||
|
</clr-control-error>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -34,8 +34,7 @@ import { InlineAlertComponent } from "../../shared/inline-alert/inline-alert.com
|
|||||||
|
|
||||||
import { Project } from "../project";
|
import { Project } from "../project";
|
||||||
import { ProjectService, QuotaUnits, QuotaHardInterface, QuotaUnlimited, getByte
|
import { ProjectService, QuotaUnits, QuotaHardInterface, QuotaUnlimited, getByte
|
||||||
, GetIntegerAndUnit, clone, StorageMultipleConstant, validateLimit, validateCountLimit} from "@harbor/ui";
|
, GetIntegerAndUnit, clone, validateLimit, validateCountLimit} from "@harbor/ui";
|
||||||
import { errorHandler } from '@angular/platform-browser/src/browser';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "create-project",
|
selector: "create-project",
|
||||||
@ -46,7 +45,7 @@ export class CreateProjectComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
|
|
||||||
projectForm: NgForm;
|
projectForm: NgForm;
|
||||||
|
|
||||||
@ViewChild("projectForm")
|
@ViewChild("projectForm", {static: true})
|
||||||
currentForm: NgForm;
|
currentForm: NgForm;
|
||||||
quotaUnits = QuotaUnits;
|
quotaUnits = QuotaUnits;
|
||||||
project: Project = new Project();
|
project: Project = new Project();
|
||||||
@ -74,7 +73,7 @@ export class CreateProjectComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
@Output() create = new EventEmitter<boolean>();
|
@Output() create = new EventEmitter<boolean>();
|
||||||
@Input() quotaObj: QuotaHardInterface;
|
@Input() quotaObj: QuotaHardInterface;
|
||||||
@Input() isSystemAdmin: boolean;
|
@Input() isSystemAdmin: boolean;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent, {static: true})
|
||||||
inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(private projectService: ProjectService,
|
constructor(private projectService: ProjectService,
|
||||||
|
@ -1,47 +1,18 @@
|
|||||||
.form-group-label-override {
|
|
||||||
font-size: 14px;
|
.mr-10 {
|
||||||
font-weight: 400;
|
margin-right:0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.access-level-label {
|
.display-flex {
|
||||||
font-size: 14px;
|
display: flex;
|
||||||
font-weight: 400;
|
align-items:center;
|
||||||
margin-left: -4px;
|
|
||||||
margin-right: 12px;
|
|
||||||
top: -6px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.modal-height {
|
|
||||||
height: 15.3em;
|
|
||||||
overflow-y: hidden;
|
|
||||||
.form-block > div {
|
|
||||||
padding-left: 135px;
|
|
||||||
.input-width {
|
|
||||||
width: 196px;
|
|
||||||
}
|
|
||||||
.public-tooltip {
|
|
||||||
top: -8px;
|
|
||||||
left: -8px;
|
|
||||||
}
|
|
||||||
.inline-help-public {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group {
|
.pos-inherit {
|
||||||
::ng-deep {
|
position: inherit;
|
||||||
clr-select-container {
|
|
||||||
margin-top: 0.3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.checkbox-inline {
|
|
||||||
margin-left: 5px;
|
|
||||||
height: 1rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.clr-error {
|
||||||
|
.clr-select-wrapper::after {
|
||||||
|
right: 0.25rem !important;
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ export class LabelFilterComponent implements ClrDatagridFilterInterface<any>, On
|
|||||||
@Input() labels: Label[] = [];
|
@Input() labels: Label[] = [];
|
||||||
@Input() resourceType: ResourceType;
|
@Input() resourceType: ResourceType;
|
||||||
|
|
||||||
@ViewChild('filterInput') filterInputRef: ElementRef;
|
@ViewChild('filterInput', {static: false}) filterInputRef: ElementRef;
|
||||||
|
|
||||||
selectedLabels: Map<number, boolean> = new Map<number, boolean>();
|
selectedLabels: Map<number, boolean> = new Map<number, boolean>();
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export class LabelMarkerComponent implements OnInit {
|
|||||||
|
|
||||||
labelChangeDebouncer: Subject<any> = new Subject();
|
labelChangeDebouncer: Subject<any> = new Subject();
|
||||||
|
|
||||||
@ViewChild('filterInput') filterInputRef: ElementRef;
|
@ViewChild('filterInput', {static: false}) filterInputRef: ElementRef;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.sortedLabels = this.labels;
|
this.sortedLabels = this.labels;
|
||||||
|
@ -82,7 +82,7 @@ export class ChartVersionComponent implements OnInit {
|
|||||||
|
|
||||||
addLabelHeaders = 'HELM_CHART.ADD_LABEL_TO_CHART_VERSION';
|
addLabelHeaders = 'HELM_CHART.ADD_LABEL_TO_CHART_VERSION';
|
||||||
|
|
||||||
@ViewChild("confirmationDialog")
|
@ViewChild("confirmationDialog", {static: false})
|
||||||
confirmationDialog: ConfirmationDialogComponent;
|
confirmationDialog: ConfirmationDialogComponent;
|
||||||
hasAddRemoveHelmChartVersionPermission: boolean;
|
hasAddRemoveHelmChartVersionPermission: boolean;
|
||||||
hasDownloadHelmChartVersionPermission: boolean;
|
hasDownloadHelmChartVersionPermission: boolean;
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<div class="row flex-items-xs-right option-right rightPos">
|
<div class="row flex-items-xs-right option-right rightPos">
|
||||||
<div class="flex-xs-middle">
|
<div class="flex-xs-middle">
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder="{{'HELM_CHART.FILTER_FOR_CHARTS' | translate}}"
|
<hbr-filter [withDivider]="true" filterPlaceholder="{{'HELM_CHART.FILTER_FOR_CHARTS' | translate}}" [currentValue]="lastFilteredChartName"
|
||||||
[currentValue]="lastFilteredChartName" (filterEvt)="updateFilterValue($event)"></hbr-filter>
|
(filterEvt)="updateFilterValue($event)"></hbr-filter>
|
||||||
<span class="card-btn" (click)="showCard(true)" (mouseenter)="mouseEnter('card') " (mouseleave)="mouseLeave('card')">
|
<span class="card-btn" (click)="showCard(true)" (mouseenter)="mouseEnter('card') " (mouseleave)="mouseLeave('card')">
|
||||||
<clr-icon [ngClass]="{'is-highlight': isCardView || isHovering('card') }" shape="view-cards"></clr-icon>
|
<clr-icon [ngClass]="{'is-highlight': isCardView || isHovering('card') }" shape="view-cards"></clr-icon>
|
||||||
</span>
|
</span>
|
||||||
@ -23,14 +23,16 @@
|
|||||||
<div *ngIf="!isCardView" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
<div *ngIf="!isCardView" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||||
<clr-datagrid (clrDgRefresh)="refresh()" [clrDgLoading]="loading" [(clrDgSelected)]="selectedRows">
|
<clr-datagrid (clrDgRefresh)="refresh()" [clrDgLoading]="loading" [(clrDgSelected)]="selectedRows">
|
||||||
<clr-dg-action-bar>
|
<clr-dg-action-bar>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasUploadHelmChartsPermission" (click)="onChartUpload()">
|
<button type="button" id="helm-chart-upload" class="btn btn-sm btn-secondary"
|
||||||
|
[disabled]="!hasUploadHelmChartsPermission" (click)="onChartUpload()">
|
||||||
<clr-icon shape="upload" size="16"></clr-icon>{{'HELM_CHART.UPLOAD' | translate}}
|
<clr-icon shape="upload" size="16"></clr-icon>{{'HELM_CHART.UPLOAD' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasDeleteHelmChartsPermission || selectedRows.length<1"
|
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasDeleteHelmChartsPermission || selectedRows.length<1"
|
||||||
(click)="openChartDeleteModal(selectedRows)">
|
(click)="openChartDeleteModal(selectedRows)">
|
||||||
<clr-icon shape="trash" size="16"></clr-icon>{{'BUTTON.DELETE' | translate}}
|
<clr-icon shape="trash" size="16"></clr-icon>{{'BUTTON.DELETE' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasDownloadHelmChartsPermission ||selectedRows.length!==1" (click)="downloadLatestVersion()">
|
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!hasDownloadHelmChartsPermission ||selectedRows.length!==1"
|
||||||
|
(click)="downloadLatestVersion()">
|
||||||
<clr-icon shape="download" size="16"></clr-icon>{{'HELM_CHART.DOWNLOAD' | translate}}
|
<clr-icon shape="download" size="16"></clr-icon>{{'HELM_CHART.DOWNLOAD' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</clr-dg-action-bar>
|
</clr-dg-action-bar>
|
||||||
@ -42,8 +44,7 @@
|
|||||||
<clr-dg-row *ngFor="let chart of charts" [clrDgItem]="chart">
|
<clr-dg-row *ngFor="let chart of charts" [clrDgItem]="chart">
|
||||||
<clr-dg-cell>
|
<clr-dg-cell>
|
||||||
<span class="list-img">
|
<span class="list-img">
|
||||||
<img class="size-24 margin-right-12" [src]="chart.icon ?chart.icon:chartDefaultIcon"
|
<img class="size-24 margin-right-12" [src]="chart.icon ?chart.icon:chartDefaultIcon" (error)="getDefaultIcon(chart);" />
|
||||||
(error)="getDefaultIcon(chart);" />
|
|
||||||
</span>
|
</span>
|
||||||
<a href="javascript:void(0)" (click)="onChartClick(chart)">{{ chart.name }}</a>
|
<a href="javascript:void(0)" (click)="onChartClick(chart)">{{ chart.name }}</a>
|
||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
@ -75,14 +76,13 @@
|
|||||||
<div class="row flex-items-xs-between">
|
<div class="row flex-items-xs-between">
|
||||||
<div>
|
<div>
|
||||||
<span class="version-text">{{item.total_versions}}</span>
|
<span class="version-text">{{item.total_versions}}</span>
|
||||||
<label class="card-label" *ngIf="item.total_versions !== 1">{{'HELM_CHART.CHARTVERSIONS' |
|
<label class="card-label" *ngIf="item.total_versions !== 1">{{'HELM_CHART.CHARTVERSIONS' | translate}}
|
||||||
translate}}</label>
|
</label>
|
||||||
<label class="card-label" *ngIf="item.total_versions === 1">{{'HELM_CHART.VERSION' |
|
<label class="card-label" *ngIf="item.total_versions === 1">{{'HELM_CHART.VERSION' | translate}}
|
||||||
translate}}</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="label" [class.label-danger]="item.deprecated" [class.label-success]="!item.deprecated">{{getStatusString(item)
|
<span class="label" [class.label-danger]="item.deprecated" [class.label-success]="!item.deprecated">{{getStatusString(item) | translate}}</span>
|
||||||
| translate}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -97,37 +97,39 @@
|
|||||||
<clr-modal [(clrModalOpen)]="isUploadModalOpen" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
<clr-modal [(clrModalOpen)]="isUploadModalOpen" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
||||||
<h3 class="modal-title">{{'HELM_CHART.UPLOAD_TITLE' | translate | titlecase}}</h3>
|
<h3 class="modal-title">{{'HELM_CHART.UPLOAD_TITLE' | translate | titlecase}}</h3>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form #chartUploadForm="ngForm" enctype="multipart/form-data" (ngSubmit)="upload()">
|
<form #chartUploadForm="ngForm" clrForm enctype="multipart/form-data">
|
||||||
<section class="form-block">
|
<div class="clr-form-control">
|
||||||
<div class="form-group">
|
<label class="filename-label clr-control-label clr-col-md-3"> {{'HELM_CHART.CHART_FILE' | translate}}</label>
|
||||||
<label class="filename-label"> {{'HELM_CHART.CHART_FILE' | translate}} </label>
|
<div class="clr-input-wrapper">
|
||||||
<input class="filename-input" type="text" placeholder="{{this.chartFile?.name || 'BUTTON.NO_FILE' | translate}}"
|
<input class="filename-input clr-input" type="text" placeholder="{{this.chartFile?.name || 'BUTTON.NO_FILE' | translate}}"
|
||||||
disabled>
|
disabled>
|
||||||
<label for="chart" class="btn btn-secondary btn-sm file-browser-btn">{{'BUTTON.BROWSE' |
|
<label for="chart" class="btn btn-secondary btn-sm file-browser-btn">{{'BUTTON.BROWSE' | translate}}
|
||||||
translate}}</label>
|
</label>
|
||||||
<input class="file-input" type="file" id="chart" name="chart" ngModel (change)="onChartFileChangeEvent($event)">
|
<input class="file-input" type="file" id="chart" name="chart" ngModel (change)="onChartFileChangeEvent($event)">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label class="filename-label"> {{'HELM_CHART.CHART_PROV' | translate}} </label>
|
<div class="clr-form-control mb-10">
|
||||||
<input class="filename-input" type="text" placeholder="{{this.provFile?.name || 'BUTTON.NO_FILE' | translate}}"
|
<label class="filename-label clr-control-label clr-col-md-3"> {{'HELM_CHART.CHART_PROV' | translate}} </label>
|
||||||
|
<div class="clr-input-wrapper">
|
||||||
|
<input class="filename-input clr-input" type="text" placeholder="{{this.provFile?.name || 'BUTTON.NO_FILE' | translate}}"
|
||||||
disabled>
|
disabled>
|
||||||
<label for="prov" class="btn btn-secondary btn-sm file-browser-btn">{{'BUTTON.BROWSE' |
|
<label for="prov" class="btn btn-secondary btn-sm file-browser-btn">{{'BUTTON.BROWSE' | translate}}
|
||||||
translate}}</label>
|
</label>
|
||||||
<input class="file-input" type="file" id="prov" name="prov" ngModel (change)="onProvFileChangeEvent($event)">
|
<input class="file-input" type="file" id="prov" name="prov" ngModel (change)="onProvFileChangeEvent($event)">
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
<div class="row flex-items-xs-right">
|
|
||||||
<button class="btn btn-secondary" [disabled]="isUploading" (click)="cancelUpload()">
|
|
||||||
<span>{{'BUTTON.CANCEL' | translate}}</span>
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="btn btn-primary" [disabled]="isUploading">
|
|
||||||
<span>{{'HELM_CHART.UPLOAD' | translate}}</span>
|
|
||||||
<span *ngIf="isUploading" class="spinner spinner-inline">
|
|
||||||
Loading...
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" [disabled]="isUploading" (click)="cancelUpload()">
|
||||||
|
<span>{{'BUTTON.CANCEL' | translate}}</span>
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="btn btn-primary" id="upload-chart" [disabled]="isUploading" (click)="upload()">
|
||||||
|
<span>{{'HELM_CHART.UPLOAD' | translate}}</span>
|
||||||
|
<span *ngIf="isUploading" class="spinner spinner-inline">
|
||||||
|
Loading...
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</clr-modal>
|
</clr-modal>
|
||||||
</div>
|
</div>
|
@ -92,22 +92,18 @@ $size60:60px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
clr-modal {
|
clr-modal {
|
||||||
.form-group {
|
.filename-label {
|
||||||
padding-left: 6rem;
|
padding-top: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
.filename-label {
|
.filename-input {
|
||||||
padding-top: 9px;
|
margin-top: 12px;
|
||||||
}
|
width: 68%;
|
||||||
|
}
|
||||||
|
|
||||||
.filename-input {
|
.file-browser-btn {
|
||||||
margin-top: 12px;
|
margin-left: 15px;
|
||||||
width: 68%;
|
max-width: 32%;
|
||||||
}
|
|
||||||
|
|
||||||
.file-browser-btn {
|
|
||||||
margin-left: 15px;
|
|
||||||
max-width: 25%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,4 +111,8 @@ button {
|
|||||||
clr-icon {
|
clr-icon {
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-10 {
|
||||||
|
margin-bottom:10px;
|
||||||
}
|
}
|
@ -68,9 +68,9 @@ export class HelmChartComponent implements OnInit {
|
|||||||
totalCount = 0;
|
totalCount = 0;
|
||||||
currentState: State;
|
currentState: State;
|
||||||
|
|
||||||
@ViewChild('chartUploadForm') uploadForm: NgForm;
|
@ViewChild('chartUploadForm', {static: false}) uploadForm: NgForm;
|
||||||
|
|
||||||
@ViewChild("confirmationDialog") confirmationDialog: ConfirmationDialogComponent;
|
@ViewChild("confirmationDialog", {static: false}) confirmationDialog: ConfirmationDialogComponent;
|
||||||
hasUploadHelmChartsPermission: boolean;
|
hasUploadHelmChartsPermission: boolean;
|
||||||
hasDownloadHelmChartsPermission: boolean;
|
hasDownloadHelmChartsPermission: boolean;
|
||||||
hasDeleteHelmChartsPermission: boolean;
|
hasDeleteHelmChartsPermission: boolean;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<clr-dg-action-bar>
|
<clr-dg-action-bar>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" (click)="addNewProject()" *ngIf="projectCreationRestriction">
|
<button type="button" class="btn btn-sm btn-secondary" (click)="addNewProject()" *ngIf="projectCreationRestriction">
|
||||||
<clr-icon shape="plus" size="16"></clr-icon> {{'PROJECT.NEW_PROJECT' | translate}}</button>
|
<clr-icon shape="plus" size="16"></clr-icon> {{'PROJECT.NEW_PROJECT' | translate}}</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!canDelete"
|
<button id="delete-project" type="button" class="btn btn-sm btn-secondary" [disabled]="!canDelete"
|
||||||
(click)="deleteProjects(selectedRow)">
|
(click)="deleteProjects(selectedRow)">
|
||||||
<clr-icon shape="times" size="16"></clr-icon> {{'PROJECT.DELETE' | translate}}</button>
|
<clr-icon shape="times" size="16"></clr-icon> {{'PROJECT.DELETE' | translate}}</button>
|
||||||
</clr-dg-action-bar>
|
</clr-dg-action-bar>
|
||||||
|
@ -2,60 +2,63 @@
|
|||||||
<h3 class="modal-title">{{'MEMBER.IMPORT_GROUP' | translate}}</h3>
|
<h3 class="modal-title">{{'MEMBER.IMPORT_GROUP' | translate}}</h3>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<label>{{ 'MEMBER.NEW_GROUP_INFO' | translate}}</label>
|
<label>{{ 'MEMBER.NEW_GROUP_INFO' | translate}}</label>
|
||||||
|
<div class="modeSelectradios">
|
||||||
<div class="form-group modeSelectradios">
|
<clr-radio-wrapper>
|
||||||
<div class="radio">
|
<input clrRadio type="radio" name="modeRadios" [value]="false" id="select_group" [(ngModel)]="createGroupMode">
|
||||||
<input type="radio" name="modeRadios" [value]="false" id="select_group" [(ngModel)]="createGroupMode">
|
|
||||||
<label for="select_group">{{'MEMBER.ADD_GROUP_SELECT' | translate}}</label>
|
<label for="select_group">{{'MEMBER.ADD_GROUP_SELECT' | translate}}</label>
|
||||||
</div>
|
</clr-radio-wrapper>
|
||||||
<div class="radio">
|
<clr-radio-wrapper>
|
||||||
<input type="radio" name="modeRadios" [value]="true" id="create_group" [(ngModel)]="createGroupMode">
|
<input clrRadio type="radio" name="modeRadios" [value]="true" id="create_group" [(ngModel)]="createGroupMode">
|
||||||
<label for="create_group">{{'MEMBER.CREATE_GROUP_SELECT' | translate}}</label>
|
<label for="create_group">{{'MEMBER.CREATE_GROUP_SELECT' | translate}}</label>
|
||||||
</div>
|
</clr-radio-wrapper>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="createGroupMode">
|
<div *ngIf="createGroupMode">
|
||||||
<form #groupForm="ngForm">
|
<form #groupForm="ngForm" class="clr-form clr-form-horizontal">
|
||||||
<section class="form-block">
|
<div class="clr-form-control">
|
||||||
<div class="form-group">
|
<label class="required clr-control-label">{{ 'MEMBER.LDAP_SEARCH_DN' | translate}}</label>
|
||||||
<label for="ldap_group_dn" class="required">{{ 'MEMBER.LDAP_SEARCH_DN' | translate}}</label>
|
<div class="clr-control-container" [class.clr-error]="isDNInvalid">
|
||||||
<label for="ldap_group_dn"
|
<div class="clr-input-wrapper">
|
||||||
aria-haspopup="true"
|
<input class="clr-input" type="text" name="ldap_group_dn" size="45"
|
||||||
role="tooltip"
|
required
|
||||||
class="tooltip tooltip-validation tooltip-md tooltip-right"
|
[(ngModel)]="group.ldap_group_dn"
|
||||||
[class.invalid]="isDNInvalid">
|
#groupDN="ngModel">
|
||||||
<input type="text" name="ldap_group_dn" size="45"
|
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||||
required
|
</div>
|
||||||
[(ngModel)]="group.ldap_group_dn"
|
<clr-control-error *ngIf="isDNInvalid" class="tooltip-content">
|
||||||
#groupDN="ngModel">
|
{{dnTooltip | translate}}
|
||||||
<span class="tooltip-content">
|
</clr-control-error>
|
||||||
{{dnTooltip | translate}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="name">{{'MEMBER.LDAP_SEARCH_NAME' | translate}}</label>
|
<div class="clr-form-control">
|
||||||
<input type="text" name="ldap_group_name" size="35" [(ngModel)]="group.group_name">
|
<label class="clr-control-label">{{'MEMBER.LDAP_SEARCH_NAME' | translate}}</label>
|
||||||
</div>
|
<div class="clr-control-container">
|
||||||
<div class="form-group">
|
<div class="clr-input-wrapper">
|
||||||
<label for="member_role1">{{ 'MEMBER.ROLE' | translate}}</label>
|
<input class="clr-input" type="text" name="ldap_group_name" size="35" [(ngModel)]="group.group_name">
|
||||||
<div class="select">
|
|
||||||
<select id="member_role1" name="member_role" [(ngModel)]="selectedRole">
|
|
||||||
<option *ngFor="let role of roles" [ngValue]="role.id"> {{role.value | translate}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
|
<div class="clr-form-control">
|
||||||
|
<label class="clr-control-label" for="member_role1">{{ 'MEMBER.ROLE' | translate}}</label>
|
||||||
|
<div class="clr-select-wrapper">
|
||||||
|
<select class="clr-select" id="member_role1" name="member_role" [(ngModel)]="selectedRole">
|
||||||
|
<option *ngFor="let role of roles" [ngValue]="role.id"> {{role.value | translate}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!createGroupMode">
|
<div *ngIf="!createGroupMode">
|
||||||
<div class='row flex-items-xs-between'>
|
<div>
|
||||||
<div></div>
|
<div class="row flex-items-xs-between">
|
||||||
<div class="filterTool">
|
<div class="left">
|
||||||
<hbr-filter [withDivider]="true" filterPlaceholder='{{"MEMBER.FILTER_PLACEHOLDER" | translate}}' (filterEvt)="doFilter($event)"
|
</div>
|
||||||
[currentValue]="currentTerm"></hbr-filter>
|
<div class="right">
|
||||||
<span class="refresh-btn" (click)="loadGroups()">
|
<hbr-filter [withDivider]="true" filterPlaceholder='{{"MEMBER.FILTER_PLACEHOLDER" | translate}}' (filterEvt)="doFilter($event)"
|
||||||
<clr-icon shape="refresh"></clr-icon>
|
[currentValue]="currentTerm"></hbr-filter>
|
||||||
</span>
|
<span class="refresh-btn" (click)="loadGroups()">
|
||||||
|
<clr-icon shape="refresh"></clr-icon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -85,13 +88,11 @@
|
|||||||
</clr-datagrid>
|
</clr-datagrid>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="clr-form clr-form-horizontal">
|
||||||
<div class="col-lg-1 col-md-1 col-sm-1 col-xs-1">
|
<div class="clr-form-control">
|
||||||
<label>{{ 'MEMBER.ROLE' | translate}}</label>
|
<label class="clr-control-label" for="member_role1">{{ 'MEMBER.ROLE' | translate}}</label>
|
||||||
</div>
|
<div class="clr-select-wrapper">
|
||||||
<div class="class=col-lg-4 col-md-4 col-sm-2 col-xs-1">
|
<select class="clr-select" id="member_role2" [(ngModel)]="selectedRole">
|
||||||
<div class="select">
|
|
||||||
<select id="member_role2" [(ngModel)]="selectedRole">
|
|
||||||
<option *ngFor="let role of roles" [ngValue]="role.id"> {{role.value | translate}}</option>
|
<option *ngFor="let role of roles" [ngValue]="role.id"> {{role.value | translate}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,10 @@ clr-datagrid {
|
|||||||
.modeSelectradios {
|
.modeSelectradios {
|
||||||
margin-top: 21px;
|
margin-top: 21px;
|
||||||
}
|
}
|
||||||
.filterTool {
|
.left {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
|
@ -41,7 +41,7 @@ export class AddGroupComponent implements OnInit {
|
|||||||
@Input() memberList: Member[] = [];
|
@Input() memberList: Member[] = [];
|
||||||
@Output() added = new EventEmitter<boolean>();
|
@Output() added = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@ViewChild('groupForm')
|
@ViewChild('groupForm', {static: false})
|
||||||
groupForm: NgForm;
|
groupForm: NgForm;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user