Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
CSAN
Csan
Commits
041a489f
Commit
041a489f
authored
Aug 06, 2020
by
AllForNothing
Browse files
Add name and endpoint check for p2p-preheat
Signed-off-by:
AllForNothing
<
sshijun@vmware.com
>
parent
19234cdb
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
403 additions
and
124 deletions
+403
-124
src/portal/src/app/distribution/distribution-instances/distribution-instances.component.scss
...tribution-instances/distribution-instances.component.scss
+1
-0
src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.html
...ution-setup-modal/distribution-setup-modal.component.html
+51
-40
src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.spec.ts
...on-setup-modal/distribution-setup-modal.component.spec.ts
+8
-1
src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.ts
...ibution-setup-modal/distribution-setup-modal.component.ts
+91
-6
src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.html
...p2p-provider/add-p2p-policy/add-p2p-policy.component.html
+8
-6
src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.spec.ts
...-provider/add-p2p-policy/add-p2p-policy.component.spec.ts
+4
-1
src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts
...t/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts
+52
-4
src/portal/src/app/project/p2p-provider/policy/policy.component.html
...src/app/project/p2p-provider/policy/policy.component.html
+5
-6
src/portal/src/app/project/p2p-provider/policy/policy.component.scss
...src/app/project/p2p-provider/policy/policy.component.scss
+1
-1
src/portal/src/app/project/p2p-provider/policy/policy.component.ts
...l/src/app/project/p2p-provider/policy/policy.component.ts
+37
-19
src/portal/src/app/project/p2p-provider/task-list/task-list.component.html
...p/project/p2p-provider/task-list/task-list.component.html
+26
-14
src/portal/src/app/project/p2p-provider/task-list/task-list.component.scss
...p/project/p2p-provider/task-list/task-list.component.scss
+13
-1
src/portal/src/app/project/p2p-provider/task-list/task-list.component.spec.ts
...roject/p2p-provider/task-list/task-list.component.spec.ts
+8
-2
src/portal/src/app/project/p2p-provider/task-list/task-list.component.ts
...app/project/p2p-provider/task-list/task-list.component.ts
+94
-19
src/portal/src/i18n/lang/zh-cn-lang.json
src/portal/src/i18n/lang/zh-cn-lang.json
+4
-4
No files found.
src/portal/src/app/distribution/distribution-instances/distribution-instances.component.scss
View file @
041a489f
...
...
@@ -16,6 +16,7 @@ $refrsh-btn-color: #007CBB;
}
.action-head-pos
{
padding-top
:
12px
;
padding-right
:
18px
;
height
:
24px
;
display
:
flex
;
...
...
src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.html
View file @
041a489f
...
...
@@ -33,24 +33,30 @@
</clr-select-container>
<!-- 2. name -->
<clr-input-container>
<label
class=
"required clr-control-label"
for=
"name"
>
{{
'DISTRIBUTION.NAME' | translate
}}
</label>
<input
class=
"width-280"
clrInput
required
type=
"text"
id=
"name"
autocomplete=
"off"
[(ngModel)]=
"model.name"
name=
"name"
[disabled]=
"editingMode"
/>
<clr-control-error>
{{ 'TOOLTIP.ITEM_REQUIRED' | translate }}
</clr-control-error>
</clr-input-container>
<div
class=
"clr-form-control"
>
<label
class=
"required clr-control-label"
for=
"name"
>
{{'DISTRIBUTION.NAME' | translate}}
</label>
<div
class=
"clr-control-container"
[class.clr-error]=
"((nameNg.dirty || nameNg.touched) && nameNg.invalid) || isNameExisting"
>
<div
class=
"clr-input-wrapper"
>
<input
class=
"width-280 clr-input"
required
type=
"text"
id=
"name"
autocomplete=
"off"
[(ngModel)]=
"model.name"
name=
"name"
#nameNg
="
ngModel
"
[disabled]=
"editingMode"
(input)=
"inputName()"
/>
<clr-icon
class=
"clr-validate-icon"
shape=
"exclamation-circle"
></clr-icon>
<span
class=
"spinner spinner-inline"
[hidden]=
"!checkNameOnGoing"
></span>
</div>
<clr-control-error
*ngIf=
"((nameNg.dirty || nameNg.touched) && nameNg.invalid) || isNameExisting"
>
<span
*ngIf=
"!((nameNg.dirty || nameNg.touched) && nameNg.invalid) && isNameExisting"
>
{{'SCANNER.NAME_EXISTS' | translate}}
</span>
<span
*ngIf=
"(nameNg.dirty || nameNg.touched) && nameNg.invalid"
>
{{ 'TOOLTIP.ITEM_REQUIRED' | translate }}
</span>
</clr-control-error>
</div>
</div>
<!-- 3. description -->
<clr-textarea-container>
...
...
@@ -65,27 +71,32 @@
[ngModelOptions]=
"{ standalone: true }"
></textarea>
</clr-textarea-container>
<!-- 4. endpoint -->
<clr-input-container>
<label
class=
"required clr-control-label"
for=
"endpoint"
>
{{
'DISTRIBUTION.ENDPOINT' | translate
}}
</label>
<input
class=
"width-280"
clrInput
required
pattern=
"^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(.*?)*$"
type=
"text"
id=
"endpoint"
placeholder=
"http(s)://192.168.1.1"
[(ngModel)]=
"model.endpoint"
name=
"endpoint"
autocomplete=
"off"
/>
<clr-control-error>
{{
'TOOLTIP.ENDPOINT_FORMAT' | translate
}}
</clr-control-error>
</clr-input-container>
<div
class=
"clr-form-control"
>
<label
class=
"required clr-control-label"
for=
"name"
>
{{'DISTRIBUTION.ENDPOINT' | translate}}
</label>
<div
class=
"clr-control-container"
[class.clr-error]=
"((endpointNg.dirty || endpointNg.touched) && endpointNg.invalid) || isEndpointExisting"
>
<div
class=
"clr-input-wrapper"
>
<input
class=
"width-280 clr-input"
required
pattern=
"^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(.*?)*$"
type=
"text"
id=
"endpoint"
placeholder=
"http(s)://192.168.1.1"
[(ngModel)]=
"model.endpoint"
name=
"endpoint"
#endpointNg
="
ngModel
"
autocomplete=
"off"
(input)=
"inputEndpoint()"
/>
<clr-icon
class=
"clr-validate-icon"
shape=
"exclamation-circle"
></clr-icon>
<span
class=
"spinner spinner-inline"
[hidden]=
"!checkEndpointOngoing"
></span>
</div>
<clr-control-error
*ngIf=
"((endpointNg.dirty || endpointNg.touched) && endpointNg.invalid) || isEndpointExisting"
>
<span
*ngIf=
"!((endpointNg.dirty || endpointNg.touched) && endpointNg.invalid) && isEndpointExisting"
>
{{'SCANNER.ENDPOINT_EXISTS' | translate}}
</span>
<span
*ngIf=
"(endpointNg.dirty || endpointNg.touched) && endpointNg.invalid"
>
{{ 'TOOLTIP.ENDPOINT_FORMAT' | translate }}
</span>
</clr-control-error>
</div>
</div>
<!-- auth mode -->
<clr-radio-container
clrInline
>
<label>
{{ 'DISTRIBUTION.AUTH_MODE' | translate }}
</label>
...
...
@@ -232,7 +243,7 @@
</form>
</div>
<div
class=
"modal-footer"
>
<button
id=
"button-test"
type=
"button"
[clrLoading]=
"checkBtnState"
class=
"btn btn-outline"
(click)=
"onTestEndpoint()"
[disabled]=
"!isValid || onTesting"
>
{{'SCANNER.TEST_CONNECTION' | translate}}
</button>
<button
id=
"button-test"
type=
"button"
[clrLoading]=
"checkBtnState"
class=
"btn btn-outline"
(click)=
"onTestEndpoint()"
[disabled]=
"!isValid || onTesting
|| checkNameOnGoing || checkEndpointOngoing || isEndpointExisting || isNameExisting
"
>
{{'SCANNER.TEST_CONNECTION' | translate}}
</button>
<button
type=
"button"
class=
"btn btn-outline"
(click)=
"cancel()"
>
{{ 'BUTTON.CANCEL' | translate }}
</button>
...
...
@@ -241,7 +252,7 @@
type=
"button"
class=
"btn btn-primary"
(click)=
"submit()"
[disabled]=
"!isValid || !hasChangesForEdit()"
[disabled]=
"!isValid || !hasChangesForEdit()
|| checkNameOnGoing || checkEndpointOngoing
"
>
{{ 'BUTTON.OK' | translate }}
</button>
...
...
src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.spec.ts
View file @
041a489f
...
...
@@ -7,6 +7,8 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
import
{
DistributionSetupModalComponent
}
from
'
./distribution-setup-modal.component
'
;
import
{
PreheatService
}
from
"
../../../../ng-swagger-gen/services/preheat.service
"
;
import
{
Instance
}
from
'
../../../../ng-swagger-gen/models/instance
'
;
import
{
of
}
from
'
rxjs
'
;
import
{
delay
}
from
'
rxjs/operators
'
;
describe
(
'
DistributionSetupModalComponent
'
,
()
=>
{
let
component
:
DistributionSetupModalComponent
;
...
...
@@ -24,6 +26,11 @@ describe('DistributionSetupModalComponent', () => {
vendor
:
'
kraken
'
,
status
:
'
Healthy
'
};
const
fakedPreheatService
=
{
ListInstances
()
{
return
of
([]).
pipe
(
delay
(
0
));
}
};
beforeEach
(
async
(()
=>
{
TestBed
.
configureTestingModule
({
...
...
@@ -34,7 +41,7 @@ describe('DistributionSetupModalComponent', () => {
HttpClientTestingModule
],
schemas
:
[
CUSTOM_ELEMENTS_SCHEMA
],
providers
:
[
PreheatService
],
providers
:
[
{
provide
:
PreheatService
,
useValue
:
fakedPreheatService
}
],
declarations
:
[
DistributionSetupModalComponent
]
}).
compileComponents
();
}));
...
...
src/portal/src/app/distribution/distribution-setup-modal/distribution-setup-modal.component.ts
View file @
041a489f
import
{
MessageHandlerService
}
from
'
../../shared/message-handler/message-handler.service
'
;
import
{
Component
,
EventEmitter
,
Input
,
OnChanges
,
OnInit
,
Output
,
SimpleChanges
,
ViewChild
}
from
'
@angular/core
'
;
import
{
NgForm
,
Validators
}
from
'
@angular/forms
'
;
import
{
Component
,
EventEmitter
,
Input
,
OnDestroy
,
OnInit
,
Output
,
ViewChild
}
from
'
@angular/core
'
;
import
{
NgForm
}
from
'
@angular/forms
'
;
import
{
TranslateService
}
from
'
@ngx-translate/core
'
;
import
{
errorHandler
}
from
'
../../../lib/utils/shared/shared.utils
'
;
import
{
PreheatService
}
from
'
../../../../ng-swagger-gen/services/preheat.service
'
;
import
{
Instance
}
from
'
../../../../ng-swagger-gen/models/instance
'
;
import
{
AuthMode
,
FrontInstance
,
HEALTHY
}
from
'
../distribution-interface
'
;
import
{
AuthMode
,
FrontInstance
}
from
'
../distribution-interface
'
;
import
{
clone
}
from
'
../../../lib/utils/utils
'
;
import
{
InlineAlertComponent
}
from
'
../../shared/inline-alert/inline-alert.component
'
;
import
{
ClrLoadingState
}
from
'
@clr/angular
'
;
import
{
Metadata
}
from
'
../../../../ng-swagger-gen/models/metadata
'
;
import
{
operateChanges
,
OperateInfo
,
OperationState
}
from
'
../../../lib/components/operation/operate
'
;
import
{
OperationService
}
from
'
../../../lib/components/operation/operation.service
'
;
import
{
finalize
}
from
'
rxjs/operators
'
;
import
{
debounceTime
,
distinctUntilChanged
,
filter
,
finalize
,
switchMap
}
from
'
rxjs/operators
'
;
import
{
Subject
,
Subscription
}
from
'
rxjs
'
;
const
DEFAULT_PROVIDER
:
string
=
'
dragonfly
'
;
...
...
@@ -21,7 +30,7 @@ const DEFAULT_PROVIDER: string = 'dragonfly';
templateUrl
:
'
./distribution-setup-modal.component.html
'
,
styleUrls
:
[
'
./distribution-setup-modal.component.scss
'
]
})
export
class
DistributionSetupModalComponent
implements
OnInit
{
export
class
DistributionSetupModalComponent
implements
OnInit
,
OnDestroy
{
@
Input
()
providers
:
Metadata
[]
=
[];
model
:
Instance
;
...
...
@@ -37,6 +46,14 @@ export class DistributionSetupModalComponent implements OnInit {
refresh
:
EventEmitter
<
any
>
=
new
EventEmitter
<
any
>
();
checkBtnState
:
ClrLoadingState
=
ClrLoadingState
.
DEFAULT
;
onTesting
:
boolean
=
false
;
private
_nameSubject
:
Subject
<
string
>
=
new
Subject
<
string
>
();
private
_endpointSubject
:
Subject
<
string
>
=
new
Subject
<
string
>
();
private
_nameSubscription
:
Subscription
;
private
_endpointSubscription
:
Subscription
;
isNameExisting
:
boolean
=
false
;
isEndpointExisting
:
boolean
=
false
;
checkNameOnGoing
:
boolean
=
false
;
checkEndpointOngoing
:
boolean
=
false
;
constructor
(
private
distributionService
:
PreheatService
,
private
msgHandler
:
MessageHandlerService
,
...
...
@@ -45,8 +62,72 @@ export class DistributionSetupModalComponent implements OnInit {
)
{}
ngOnInit
()
{
this
.
subscribeName
();
this
.
subscribeEndpoint
();
this
.
reset
();
}
ngOnDestroy
()
{
if
(
this
.
_nameSubscription
)
{
this
.
_nameSubscription
.
unsubscribe
();
this
.
_nameSubscription
=
null
;
}
if
(
this
.
_endpointSubscription
)
{
this
.
_endpointSubscription
.
unsubscribe
();
this
.
_endpointSubscription
=
null
;
}
}
subscribeName
()
{
if
(
!
this
.
_nameSubscription
)
{
this
.
_nameSubscription
=
this
.
_nameSubject
.
pipe
(
debounceTime
(
500
),
distinctUntilChanged
(),
filter
(
name
=>
{
return
name
.
length
>
0
;
}),
switchMap
((
name
)
=>
{
this
.
isNameExisting
=
false
;
this
.
checkNameOnGoing
=
true
;
return
this
.
distributionService
.
ListInstances
({
q
:
encodeURIComponent
(
`name=
${
name
}
`
)
}).
pipe
(
finalize
(()
=>
this
.
checkNameOnGoing
=
false
));
}))
.
subscribe
(
res
=>
{
if
(
res
&&
res
.
length
>
0
)
{
this
.
isNameExisting
=
true
;
}
});
}
}
subscribeEndpoint
()
{
if
(
!
this
.
_endpointSubscription
)
{
this
.
_endpointSubscription
=
this
.
_endpointSubject
.
pipe
(
debounceTime
(
500
),
distinctUntilChanged
(),
filter
(
endpoint
=>
{
return
this
.
instanceForm
.
control
.
get
(
'
endpoint
'
).
valid
;
}),
switchMap
((
endpoint
)
=>
{
this
.
isEndpointExisting
=
false
;
this
.
checkEndpointOngoing
=
true
;
return
this
.
distributionService
.
ListInstances
({
q
:
encodeURIComponent
(
`endpoint=
${
endpoint
}
`
)
}).
pipe
(
finalize
(()
=>
this
.
checkEndpointOngoing
=
false
));
}))
.
subscribe
(
res
=>
{
if
(
res
&&
res
.
length
>
0
)
{
this
.
isEndpointExisting
=
true
;
}
});
}
}
inputName
()
{
this
.
_nameSubject
.
next
(
this
.
model
.
name
);
}
inputEndpoint
()
{
this
.
_endpointSubject
.
next
(
this
.
model
.
endpoint
);
}
public
get
isValid
():
boolean
{
return
this
.
instanceForm
&&
this
.
instanceForm
.
valid
;
}
...
...
@@ -100,7 +181,10 @@ export class DistributionSetupModalComponent implements OnInit {
auth_mode
:
AuthMode
.
NONE
,
auth_info
:
this
.
authData
};
this
.
instanceForm
.
reset
();
this
.
instanceForm
.
reset
({
enabled
:
true
,
insecure
:
true
,
});
}
cancel
()
{
...
...
@@ -190,6 +274,7 @@ export class DistributionSetupModalComponent implements OnInit {
this
.
originModelForEdit
=
clone
(
data
);
this
.
authData
=
this
.
model
.
auth_info
||
{};
}
else
{
this
.
reset
();
if
(
this
.
providers
&&
this
.
providers
.
length
)
{
this
.
providers
.
forEach
(
item
=>
{
if
(
item
.
id
===
DEFAULT_PROVIDER
)
{
...
...
src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.html
View file @
041a489f
...
...
@@ -34,14 +34,16 @@
<!-- name -->
<div
class=
"clr-form-control"
>
<label
for=
"name"
class=
"clr-control-label required width-6rem"
>
{{'P2P_PROVIDER.NAME' | translate}}
</label>
<div
class=
"clr-control-container"
[class.clr-error]=
"name.
errors && name.errors.requir
ed &&
(
name.
dirty || name.touched)
"
>
<div
class=
"clr-control-container"
[class.clr-error]=
"
((
name.
dirty || name.touch
ed
)
&& name.
invalid) || isNameExisting
"
>
<div
class=
"clr-input-wrapper"
>
<input
pattern=
"^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
[disabled]=
"loading"
autocomplete=
"off"
class=
"clr-input width-380"
type=
"text"
id=
"name"
[(ngModel)]=
"policy.name"
size=
"30"
name=
"name"
#name
="
ngModel
"
required
>
size=
"30"
name=
"name"
#name
="
ngModel
"
required
(input)=
"inputName()"
>
<clr-icon
class=
"clr-validate-icon"
shape=
"exclamation-circle"
></clr-icon>
<span
class=
"spinner spinner-inline"
[hidden]=
"!checkNameOnGoing"
></span>
</div>
<clr-control-error
*ngIf=
"name.errors && name.errors.required && (name.dirty || name.touched)"
class=
"tooltip-content"
>
{{'P2P_PROVIDER.NAME_REQUIRED' | translate}}
<clr-control-error
*ngIf=
"((name.dirty || name.touched) && name.invalid) || isNameExisting"
>
<span
*ngIf=
"!((name.dirty || name.touched) && name.invalid) && isNameExisting"
>
{{'SCANNER.NAME_EXISTS' | translate}}
</span>
<span
*ngIf=
"(name.dirty || name.touched) && name.invalid"
>
{{ 'PROJECT.NAME_TOOLTIP' | translate }}
</span>
</clr-control-error>
</div>
</div>
...
...
@@ -172,12 +174,12 @@
</form>
<div
class=
"mt-1 bottom-btn"
*ngIf=
"!isEdit"
>
<button
type=
"button"
class=
"btn btn-outline"
id=
"add-policy-cancel"
(click)=
"onCancel()"
>
{{'BUTTON.CANCEL' | translate}}
</button>
<button
type=
"button"
id=
"new-policy"
class=
"btn btn-primary"
[clrLoading]=
"buttonStatus"
[disabled]=
"loading || !valid()"
(click)=
"addOrSave(true)"
>
{{'BUTTON.ADD' | translate}}
</button>
<button
type=
"button"
id=
"new-policy"
class=
"btn btn-primary"
[clrLoading]=
"buttonStatus"
[disabled]=
"
isNameExisting ||checkNameOnGoing ||
loading || !valid()"
(click)=
"addOrSave(true)"
>
{{'BUTTON.ADD' | translate}}
</button>
</div>
<div
class=
"mt-1 bottom-btn"
*ngIf=
"isEdit"
>
<button
type=
"button"
class=
"btn btn-outline"
id=
"edit-policy-cancel"
(click)=
"onCancel()"
>
{{'BUTTON.CANCEL' | translate}}
</button>
<button
type=
"button"
class=
"btn btn-primary"
id=
"edit-policy-save"
[clrLoading]=
"buttonStatus"
[disabled]=
"loading || !valid() || !hasChange()"
(click)=
"addOrSave(false)"
>
{{'BUTTON.SAVE' | translate}}
</button>
[clrLoading]=
"buttonStatus"
[disabled]=
"
isNameExisting || checkNameOnGoing ||
loading || !valid() || !hasChange()"
(click)=
"addOrSave(false)"
>
{{'BUTTON.SAVE' | translate}}
</button>
</div>
</div>
</div>
...
...
src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.spec.ts
View file @
041a489f
...
...
@@ -33,6 +33,9 @@ describe('AddP2pPolicyComponent', () => {
},
UpdatePolicy
()
{
return
of
(
true
).
pipe
(
delay
(
0
));
},
ListPolicies
()
{
return
of
([]).
pipe
(
delay
(
0
));
}
};
const
mockActivatedRoute
=
{
...
...
@@ -135,7 +138,7 @@ describe('AddP2pPolicyComponent', () => {
nameInput
.
dispatchEvent
(
new
Event
(
'
input
'
));
nameInput
.
blur
();
const
errorEle
:
HTMLElement
=
fixture
.
nativeElement
.
querySelector
(
"
clr-control-error
"
);
expect
(
errorEle
.
innerText
).
toEqual
(
'
P
2P_PROVIDER.NAME_REQUIRED
'
);
expect
(
errorEle
.
innerText
).
toEqual
(
'
P
ROJECT.NAME_TOOLTIP
'
);
});
it
(
"
save button should work
"
,
async
()
=>
{
fixture
.
autoDetectChanges
(
true
);
...
...
src/portal/src/app/project/p2p-provider/add-p2p-policy/add-p2p-policy.component.ts
View file @
041a489f
import
{
Component
,
EventEmitter
,
Input
,
OnInit
,
Output
,
ViewChild
,
}
from
'
@angular/core
'
;
import
{
Component
,
EventEmitter
,
Input
,
OnDestroy
,
OnInit
,
Output
,
ViewChild
,
}
from
'
@angular/core
'
;
import
{
PreheatPolicy
}
from
'
../../../../../ng-swagger-gen/models/preheat-policy
'
;
import
{
InlineAlertComponent
}
from
'
../../../shared/inline-alert/inline-alert.component
'
;
import
{
NgForm
}
from
'
@angular/forms
'
;
import
{
OriginCron
,
ProjectService
}
from
'
../../../../lib/services
'
;
import
{
CronScheduleComponent
}
from
'
../../../../lib/components/cron-schedule
'
;
import
{
PreheatService
}
from
'
../../../../../ng-swagger-gen/services/preheat.service
'
;
import
{
finalize
}
from
'
rxjs/operators
'
;
import
{
debounceTime
,
distinctUntilChanged
,
filter
,
finalize
,
switchMap
}
from
'
rxjs/operators
'
;
import
{
deleteEmptyKey
}
from
'
../../../../lib/utils/utils
'
;
import
{
ClrLoadingState
}
from
'
@clr/angular
'
;
import
{
SessionService
}
from
'
../../../shared/session.service
'
;
...
...
@@ -14,6 +14,7 @@ import { ActivatedRoute } from '@angular/router';
import
{
FILTER_TYPE
,
PROJECT_SEVERITY_LEVEL_MAP
,
TRIGGER
,
TRIGGER_I18N_MAP
}
from
'
../p2p-provider.service
'
;
import
{
ProviderUnderProject
}
from
'
../../../../../ng-swagger-gen/models/provider-under-project
'
;
import
{
AppConfigService
}
from
'
../../../services/app-config.service
'
;
import
{
Subject
,
Subscription
}
from
'
rxjs
'
;
const
SCHEDULE_TYPE
=
{
NONE
:
"
None
"
,
...
...
@@ -28,7 +29,7 @@ const TRUE: string = 'true';
templateUrl
:
'
./add-p2p-policy.component.html
'
,
styleUrls
:
[
'
./add-p2p-policy.component.scss
'
]
})
export
class
AddP2pPolicyComponent
implements
OnInit
{
export
class
AddP2pPolicyComponent
implements
OnInit
,
OnDestroy
{
severityOptions
=
[
{
severity
:
5
,
severityLevel
:
'
VULNERABILITY.SEVERITY.CRITICAL
'
},
{
severity
:
4
,
severityLevel
:
'
VULNERABILITY.SEVERITY.HIGH
'
},
...
...
@@ -73,7 +74,10 @@ export class AddP2pPolicyComponent implements OnInit {
projectSeverity
:
string
;
triggers
:
string
[]
=
[
TRIGGER
.
MANUAL
,
TRIGGER
.
SCHEDULED
,
TRIGGER
.
EVENT_BASED
];
enableContentTrust
:
boolean
=
false
;
private
_nameSubject
:
Subject
<
string
>
=
new
Subject
<
string
>
();
private
_nameSubscription
:
Subscription
;
isNameExisting
:
boolean
=
false
;
checkNameOnGoing
:
boolean
=
false
;
constructor
(
private
preheatService
:
PreheatService
,
private
session
:
SessionService
,
private
route
:
ActivatedRoute
,
...
...
@@ -90,6 +94,43 @@ export class AddP2pPolicyComponent implements OnInit {
// get latest project info
this
.
getProject
();
}
this
.
subscribeName
();
}
ngOnDestroy
()
{
if
(
this
.
_nameSubscription
)
{
this
.
_nameSubscription
.
unsubscribe
();
this
.
_nameSubscription
=
null
;
}
}
subscribeName
()
{
if
(
!
this
.
_nameSubscription
)
{
this
.
_nameSubscription
=
this
.
_nameSubject
.
pipe
(
debounceTime
(
500
),
distinctUntilChanged
(),
filter
(
name
=>
{
if
(
this
.
isEdit
&&
this
.
originPolicyForEdit
&&
this
.
originPolicyForEdit
.
name
===
name
)
{
return
false
;
}
return
name
.
length
>
0
;
}),
switchMap
((
name
)
=>
{
this
.
isNameExisting
=
false
;
this
.
checkNameOnGoing
=
true
;
return
this
.
preheatService
.
ListPolicies
({
projectName
:
this
.
projectName
,
q
:
encodeURIComponent
(
`name=
${
name
}
`
)
}).
pipe
(
finalize
(()
=>
this
.
checkNameOnGoing
=
false
));
}))
.
subscribe
(
res
=>
{
if
(
res
&&
res
.
length
>
0
)
{
this
.
isNameExisting
=
true
;
}
});
}
}
inputName
()
{
this
.
_nameSubject
.
next
(
this
.
policy
.
name
);
}
getProject
()
{
this
.
projectService
.
getProject
(
this
.
projectId
)
...
...
@@ -115,6 +156,13 @@ export class AddP2pPolicyComponent implements OnInit {
severity
:
PROJECT_SEVERITY_LEVEL_MAP
[
this
.
projectSeverity
],
onlySignedImages
:
this
.
enableContentTrust
});
if
(
this
.
providers
&&
this
.
providers
.
length
)
{
this
.
providers
.
forEach
(
item
=>
{
if
(
item
.
default
)
{
this
.
policy
.
provider_id
=
item
.
id
;
}
});
}
}
setCron
(
event
:
any
)
{
...
...
src/portal/src/app/project/p2p-provider/policy/policy.component.html
View file @
041a489f
...
...
@@ -77,7 +77,7 @@
</clr-dg-action-bar>
<clr-dg-column
[clrDgField]=
"'name'"
>
{{'P2P_PROVIDER.NAME' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'P2P_PROVIDER.ENABLED' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'P2P_PROVIDER.PROVIDER' | translate}}
</clr-dg-column>
<clr-dg-column
[clrDgField]=
"'provider_name'"
>
{{'P2P_PROVIDER.PROVIDER' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'P2P_PROVIDER.FILTERS' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'P2P_PROVIDER.TRIGGER' | translate}}
</clr-dg-column>
<clr-dg-column
[clrDgSortBy]=
"creationTimeComparator"
>
{{'P2P_PROVIDER.CREATED' | translate}}
</clr-dg-column>
...
...
@@ -164,20 +164,19 @@
<select
id=
"selectKey"
(change)=
"selectFilterKey($event)"
>
<option
value=
"id"
>
{{"P2P_PROVIDER.ID" | translate | lowercase}}
</option>
<option
value=
"status"
>
{{"REPLICATION.STATUS" | translate | lowercase}}
</option>
<option
value=
"vendor_type"
>
{{"P2P_PROVIDER.PROVIDER_TYPE" | translate | lowercase}}
</option>
</select>
</div>
<hbr-filter
(filterEvt)=
"doFilter($event)"
[currentValue]=
"searchString"
id=
"filter-executions"
[withDivider]=
"true"
(openFlag)=
"openFilter($event)"
filterPlaceholder=
'{{"REPLICATION.FILTER_EXECUTIONS_PLACEHOLDER" | translate}}'
></hbr-filter>
<span
class=
"refresh-btn"
>
<clr-icon
shape=
"refresh"
(click)=
"refresh()"
[hidden]=
"loading"
></clr-icon>
<clr-icon
shape=
"refresh"
(click)=
"refresh
Jobs
()"
[hidden]=
"loading"
></clr-icon>
</span>
</div>
</div>
</clr-dg-action-bar>
<clr-dg-column>
{{'REPLICATION.ID' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'REPLICATION.STATUS' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'
REPLICATION.REPLICATION_
TRIGGER' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'
P2P_PROVIDER.
TRIGGER' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'REPLICATION.CREATION_TIME' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'REPLICATION.DURATION' | translate}}
</clr-dg-column>
<clr-dg-column>
{{'REPLICATION.SUCCESS_RATE' | translate}}
</clr-dg-column>
...
...
@@ -196,7 +195,7 @@
</clr-tooltip-content>
</clr-tooltip>
</clr-dg-cell>
<clr-dg-cell>
{{execution.trigger}}
</clr-dg-cell>
<clr-dg-cell>
{{
getTriggerTypeI18nForExecution(
execution.trigger
) | translate
}}
</clr-dg-cell>
<clr-dg-cell>
{{execution.start_time | date: 'short'}}
</clr-dg-cell>
<clr-dg-cell>
{{getDuration(execution)}}
</clr-dg-cell>
<clr-dg-cell>
{{getSuccessRate(execution.metrics)}}
</clr-dg-cell>
...
...
@@ -206,7 +205,7 @@
<span
*ngIf=
"totalExecutionCount"
>
{{pagination.firstItem + 1}}
- {{pagination.lastItem + 1}} {{'REPLICATION.OF' | translate}}
</span>
{{totalExecutionCount}} {{'REPLICATION.ITEMS' | translate}}
<clr-dg-pagination
#pagination
[(clrDgPage)]=
"currentExecutionPage"
[clrDgPageSize]=
"
10
"
<clr-dg-pagination
#pagination
[(clrDgPage)]=
"currentExecutionPage"
[clrDgPageSize]=
"
pageSize
"
[clrDgTotalItems]=
"totalExecutionCount"
></clr-dg-pagination>
</clr-dg-footer>
</clr-datagrid>
...
...
src/portal/src/app/project/p2p-provider/policy/policy.component.scss
View file @
041a489f
...
...
@@ -33,7 +33,7 @@
cursor
:
pointer
;
}
.filter-tag
{
margin-top
:
6
px
;
margin-top
:
7
px
;
}
.filter-title
{
font-weight
:
400
;
...
...
src/portal/src/app/project/p2p-provider/policy/policy.component.ts
View file @
041a489f
...
...
@@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
{
distinctUntilChanged
,
finalize
,
switchMap
}
from
'
rxjs/operators
'
;
import
{
debounceTime
,
distinctUntilChanged
,
finalize
,
switchMap
}
from
'
rxjs/operators
'
;
import
{
TranslateService
}
from
'
@ngx-translate/core
'
;
import
{
Component
,
OnDestroy
,
OnInit
,
ViewChild
}
from
'
@angular/core
'
;
import
{
ActivatedRoute
,
Router
}
from
'
@angular/router
'
;
...
...
@@ -106,10 +106,7 @@ export class PolicyComponent implements OnInit, OnDestroy {
this
.
_searchSubscription
.
unsubscribe
();
this
.
_searchSubscription
=
null
;
}
if
(
this
.
timeout
)
{
clearTimeout
(
this
.
timeout
);
this
.
timeout
=
null
;
}
this
.
clearLoop
();
}
getPermissions
()
{
const
permissionsList
:
Observable
<
boolean
>
[]
=
[];
...
...
@@ -134,7 +131,11 @@ export class PolicyComponent implements OnInit, OnDestroy {
getProviders
()
{
this
.
preheatService
.
ListProvidersUnderProject
({
projectName
:
this
.
projectName
})
.
subscribe
(
res
=>
{
this
.
providers
=
res
;
if
(
res
&&
res
.
length
)
{
this
.
providers
=
res
.
filter
(
provider
=>
{
return
provider
.
enabled
;
});
}
});
}
refresh
()
{
...
...
@@ -358,23 +359,13 @@ export class PolicyComponent implements OnInit, OnDestroy {
}).
pipe
(
finalize
(()
=>
this
.
jobsLoading
=
false
))
.
subscribe
(
response
=>
{
if
(
response
.
headers
)
{
let
xHeader
:
string
=
response
.
headers
.
get
(
'
x-t
otal-
c
ount
'
);
let
xHeader
:
string
=
response
.
headers
.
get
(
'
X-T
otal-
C
ount
'
);
if
(
xHeader
)
{
this
.
totalExecutionCount
=
parseInt
(
xHeader
,
0
);
}
}
this
.
executionList
=
response
.
body
;
if
(
this
.
executionList
&&
this
.
executionList
.
length
)
{