Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Harbor
Commits
791004c1
Commit
791004c1
authored
7 years ago
by
pfh
Browse files
Options
Download
Email Patches
Plain Diff
Add username adn pwd for target and unselected project name and target first time
parent
6f857411
master
add-expect-file-from-linux-os
add-retry-for-get-project-Quotas-1
angular6
bump_up_legacy_api_version
cron
csrf-local
debug_oidc_onboard
dev-center
dev-center1
enable-code-scanning
enable_ssl_on_all_components
enable_tls_on_all_components
f9272e25
feat/retention/GH-6655-boilerplate
feat/retention/GH-6656-filter-chain-builder
feat/retention/GH-6657-keep-or-delete-everything
feat/retention/GH-6658-always-keep-or-delete-tag
feat/retention/GH-6660-keep-most-recent-n-tags
feat/retention/GH-6661-delete-older-than-n-days
feat/retention/GH-7933-database-persistence
feat/retention/linter-fixups
feat/retention/tracking
feature/pluggable_scanner_s3
fix-images
fix_ldap_group_admin_dn
fix_nightly
fix_prepare_file_permission
fixing-links
harbor-tile-testcase
jonasrosland-patch-2
maria-to-pg
michmike-patch-1
michmike-patch-2
michmike-patch-3
michmike-patch-4
michmike-patch-5
michmike-patch-6
michmike-patch-7
michmike-patch-8
modify-log
ninjadq-fix-type-on-migration-doc
optimize_cicd
p2p_preheat
pr/upgrade2angular5
project-quota-dev
proxy_prototype
query
redirects
ref_admin_driver
refactor_ldap_group_180
release-1.10-doc
release-1.10.0
release-1.4.0
release-1.5.0
release-1.5.0-chart-perm-fix
release-1.6.0
release-1.7.0
release-1.8.0
release-1.9.0
release-2.0.0
remove_adminserver
remove_adminserver_review
rename-master-role
rep-aws-drv
replication
replication_ng
revert-8494-fix-global-search
revert-9506-token-sevice
sclem-helm-link
sclements-1.10-cherrypick
sclements-1.10-doc-updates
script-project-quotas-nightly-test-case-2
seprate_harbor_portal_from_harbor_core
srcipt-cnab-bundle-api-test
stonezdj-patch-1.5.2
test_tag_retention
update_clarity
upgrade_clarity
upgrade_clarity-2.1
upgrade_clarity_2.0
webhook-dev
webhook-dev-20200303
wwp-weighting
xaleeks-patch-2
xaleeks-patch-3
v2.1.0-tech-prview
v2.1.0-tech-preview
v2.0.2
v2.0.2-rc1
v2.0.1
v2.0.1-rc1
v2.0.0
v2.0.0-rc3
v2.0.0-rc2
v2.0.0-rc1
v1.10.4
v1.10.4-rc1
v1.10.3
v1.10.3-rc2
v1.10.3-rc1
v1.10.2
v1.10.2-rc1
v1.10.1
v1.10.1-rc1
v1.10.0
v1.10.0-rc2
v1.10.0-rc1
v1.9.4
v1.9.4-rc2
v1.9.4-rc1
v1.9.3
v1.9.3-rc1
v1.9.2
v1.9.2-rc1
v1.9.1
v1.9.1-rc1
v1.9.0
v1.9.0-rc2
v1.9.0-rc1
v1.8.6
v1.8.6-rc1
v1.8.5
v1.8.5-rc1
v1.8.4
v1.8.4-rc1
v1.8.3
v1.8.3-rc1
v1.8.2
v1.8.2-rc2
v1.8.2-rc1
v1.8.1
v1.8.0
v1.8.0-rc2
v1.8.0-rc1
v1.7.7-rc1
v1.7.6
v1.7.6-rc1
v1.7.5
v1.7.4
v1.7.3
v1.7.2
v1.7.1
v1.7.0
v1.7.0-rc2
v1.7.0-rc1
v1.6.3
v1.6.2
v1.6.1
v1.6.0
v1.6.0-rc3
v1.6.0-rc2
v1.6.0-rc1
v1.5.4
v1.5.3
v1.5.2
v1.5.2-RC1
v1.5.1
v1.5.0
v1.5.0-rc5
v1.5.0-rc4
v1.5.0-rc3
v1.5.0-rc2
v1.5.0-rc1
v1.4.1
v1.4.0
v1.4.0-rc2
No related merge requests found
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts
+3
-1
...rc/create-edit-endpoint/create-edit-endpoint.component.ts
src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts
+7
-7
...-replication-rule/list-replication-rule.component.html.ts
src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts
+0
-1
.../list-replication-rule/list-replication-rule.component.ts
src/ui_ng/package.json
+1
-1
src/ui_ng/package.json
src/ui_ng/src/app/project/create-project/create-project.component.html
+1
-1
.../app/project/create-project/create-project.component.html
src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.html
+1
-1
...rule/list-project-model/list-project-model.component.html
src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts
+106
-38
...eplication/replication-rule/replication-rule.component.ts
src/ui_ng/src/app/replication/replication-rule/replication-rule.css
+11
-7
...src/app/replication/replication-rule/replication-rule.css
src/ui_ng/src/app/replication/replication-rule/replication-rule.html
+30
-33
...rc/app/replication/replication-rule/replication-rule.html
src/ui_ng/src/app/replication/replication-rule/replication-rule.service.ts
+27
-0
.../replication/replication-rule/replication-rule.service.ts
src/ui_ng/src/app/replication/replication-rule/replication-rule.ts
+19
-8
.../src/app/replication/replication-rule/replication-rule.ts
src/ui_ng/src/app/user/user.component.ts
+1
-0
src/ui_ng/src/app/user/user.component.ts
src/ui_ng/src/i18n/lang/en-us-lang.json
+1
-1
src/ui_ng/src/i18n/lang/en-us-lang.json
src/ui_ng/src/i18n/lang/es-es-lang.json
+1
-1
src/ui_ng/src/i18n/lang/es-es-lang.json
src/ui_ng/src/i18n/lang/zh-cn-lang.json
+2
-2
src/ui_ng/src/i18n/lang/zh-cn-lang.json
with
211 additions
and
102 deletions
+211
-102
src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts
+
3
-
1
View file @
791004c1
...
...
@@ -241,15 +241,16 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
this
.
onGoing
=
false
;
this
.
close
();
}).
catch
(
error
=>
{
this
.
onGoing
=
false
;
let
errorMessageKey
=
this
.
handleErrorMessageKey
(
error
.
status
);
this
.
translateService
.
get
(
errorMessageKey
)
.
subscribe
(
res
=>
{
this
.
inlineAlert
.
showInlineError
(
res
);
this
.
onGoing
=
false
;
});
}
);
this
.
forceRefreshView
(
1000
);
}
updateEndpoint
()
{
...
...
@@ -295,6 +296,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
this
.
onGoing
=
false
;
}
);
this
.
forceRefreshView
(
100
);
}
handleErrorMessageKey
(
status
:
number
):
string
{
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts
+
7
-
7
View file @
791004c1
...
...
@@ -13,14 +13,14 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = `
<clr-dg-column [clrDgField]="'targets'">{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'trigger'">{{'REPLICATION.TRIGGER_MODE' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let p of changedRules" [clrDgItem]="p" [style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
<clr-dg-cell
(click)="selectRule(p)"
>{{p.name}}</clr-dg-cell>
<clr-dg-cell *ngIf="!projectScope"
(click)="selectRule(p)"
>
<a href="javascript:void(0)"
(click)="redirectTo(p)"
>{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>
<clr-dg-row *clrDgItems="let p of changedRules" [clrDgItem]="p"
(click)="selectRule(p)"
[style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
<clr-dg-cell>{{p.name}}</clr-dg-cell>
<clr-dg-cell *ngIf="!projectScope">
<a href="javascript:void(0)">{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>
</clr-dg-cell>
<clr-dg-cell
(click)="selectRule(p)"
>{{p.description ? p.description : '-'}}</clr-dg-cell>
<clr-dg-cell
(click)="selectRule(p)"
>{{p.targets?.length>0 ? p.targets[0].name : ''}}</clr-dg-cell>
<clr-dg-cell
(click)="selectRule(p)"
>{{p.trigger ? p.trigger.kind : ''}}</clr-dg-cell>
<clr-dg-cell>{{p.description ? p.description : '-'}}</clr-dg-cell>
<clr-dg-cell>{{p.targets?.length>0 ? p.targets[0].name : ''}}</clr-dg-cell>
<clr-dg-cell>{{p.trigger ? p.trigger.kind : ''}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<span *ngIf="pagination.totalItems">{{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'REPLICATION.OF' | translate}} </span>{{pagination.totalItems }} {{'REPLICATION.ITEMS' | translate}}
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts
+
0
-
1
View file @
791004c1
...
...
@@ -187,7 +187,6 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
selectRule
(
rule
:
ReplicationRule
):
void
{
this
.
selectedId
=
rule
.
id
||
''
;
this
.
selectedRow
=
null
;
this
.
selectOne
.
emit
(
rule
);
}
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/package.json
+
1
-
1
View file @
791004c1
...
...
@@ -31,7 +31,7 @@
"clarity-icons"
:
"^0.10.17"
,
"clarity-ui"
:
"^0.10.17"
,
"core-js"
:
"^2.4.1"
,
"harbor-ui"
:
"0.6.3
0
"
,
"harbor-ui"
:
"0.6.3
2
"
,
"intl"
:
"^1.2.5"
,
"mutationobserver-shim"
:
"^0.3.2"
,
"ngx-cookie"
:
"^1.0.0"
,
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/project/create-project/create-project.component.html
+
1
-
1
View file @
791004c1
...
...
@@ -8,7 +8,7 @@
<label
for=
"create_project_name"
class=
"col-md-3 form-group-label-override 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
type=
"text"
id=
"create_project_name"
[(ngModel)]=
"project.name"
name=
"create_project_name"
size=
"255"
name=
"create_project_name"
size=
"255"
style=
"width: 296px;"
required
pattern=
"^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
minlength=
"2"
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/replication/replication-rule/list-project-model/list-project-model.component.html
+
1
-
1
View file @
791004c1
<clr-modal
[(clrModalOpen)]=
"ismodelOpen"
>
<clr-modal
[(clrModalOpen)]=
"ismodelOpen"
[clrModalClosable]=
"false"
>
<h3
class=
"modal-title"
>
{{'PROJECT.ALL_PROJECTS' | translate}}
</h3>
<inline-alert
class=
"modal-title"
></inline-alert>
<div
class=
"modal-body"
>
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts
+
106
-
38
View file @
791004c1
...
...
@@ -17,6 +17,7 @@ import {CreateEditEndpointComponent} from "harbor-ui/src/create-edit-endpoint/cr
const
ONE_HOUR_SECONDS
:
number
=
3600
;
const
ONE_DAY_SECONDS
:
number
=
24
*
ONE_HOUR_SECONDS
;
const
FAKE_PASSWORD
=
'
rjGcfuRu
'
;
@
Component
({
selector
:
'
repliction-rule
'
,
...
...
@@ -33,11 +34,12 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
weeklySchedule
:
boolean
;
isScheduleOpt
:
boolean
;
isImmediate
:
boolean
=
true
;
noProjectInfo
:
string
;
noEndpointInfo
:
boolean
;
noProjectInfo
:
string
=
""
;
noSelectedProject
:
boolean
=
true
;
noSelectedEndpoint
:
boolean
=
true
;
filterCount
:
number
=
0
;
selectedprojectList
:
Project
[]
=
[];
triggerNames
:
string
[]
=
[
'
Immediate
'
,
'
Scheduled
'
,
'
Manual
'
];
triggerNames
:
string
[]
=
[
'
Manual
'
,
'
Immediate
'
,
'
Scheduled
'
];
scheduleNames
:
string
[]
=
[
'
Daily
'
,
'
Weekly
'
];
weekly
:
string
[]
=
[
'
Monday
'
,
'
Tuesday
'
,
'
Wednesday
'
,
'
Thursday
'
,
'
Friday
'
,
'
Saturday
'
,
'
Sunday
'
];
filterSelect
:
string
[]
=
[
'
repository
'
,
'
tag
'
];
...
...
@@ -50,6 +52,8 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
isRuleNameExist
:
boolean
=
false
;
isSubmitOver
:
boolean
=
false
;
nameChecker
:
Subject
<
string
>
=
new
Subject
<
string
>
();
firstEndpointData
:
{
[
key
:
string
]:
string
};
realEndpointData
:
{
[
key
:
string
]:
string
}
=
this
.
initEndpointData
();
confirmSub
:
Subscription
;
ruleForm
:
FormGroup
;
...
...
@@ -61,6 +65,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
@
ViewChild
(
CreateEditEndpointComponent
)
createEditEndpointComponent
:
CreateEditEndpointComponent
;
baseFilterData
(
name
:
string
,
option
:
string
[],
state
:
boolean
)
{
return
{
name
:
name
,
...
...
@@ -70,6 +75,13 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
};
}
initEndpointData
():
{
[
key
:
string
]:
string
}
{
return
{
userName
:
""
,
password
:
""
};
}
constructor
(
public
projectService
:
ProjectService
,
private
router
:
Router
,
private
fb
:
FormBuilder
,
...
...
@@ -83,11 +95,14 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
Promise
.
all
([
this
.
repService
.
getEndpoints
(),
this
.
repService
.
listProjects
()])
.
then
(
res
=>
{
if
(
!
res
[
0
])
{
this
.
noEndpoint
Info
=
true
;
this
.
no
Selected
Endpoint
=
true
;
}
else
{
this
.
targetList
=
res
[
0
];
if
(
!
this
.
policyId
)
{
this
.
setTarget
([
res
[
0
][
0
]]);
this
.
realEndpointData
.
userName
=
res
[
0
][
0
].
username
;
this
.
realEndpointData
.
password
=
FAKE_PASSWORD
;
this
.
firstEndpointData
=
Object
.
assign
({},
this
.
realEndpointData
);
}
}
if
(
!
res
[
1
])
{
...
...
@@ -98,6 +113,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}
if
(
!
this
.
policyId
&&
this
.
projectId
)
{
this
.
setProject
(
res
[
1
].
filter
(
rule
=>
rule
.
project_id
===
this
.
projectId
));
this
.
noSelectedProject
=
false
;
}
}
if
(
!
this
.
policyId
)
{
...
...
@@ -148,7 +164,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}
get
isVaild
()
{
return
!
(
this
.
isRuleNameExist
||
this
.
noProject
Info
||
this
.
noEndpoint
Info
||
this
.
inProgress
||
this
.
isSubmitOver
);
return
!
(
this
.
isRuleNameExist
||
this
.
no
Selected
Project
||
this
.
no
Selected
Endpoint
||
this
.
inProgress
||
this
.
isSubmitOver
);
}
createForm
()
{
...
...
@@ -169,7 +185,6 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
replicate_existing_image_now
:
true
,
replicate_deletion
:
false
});
}
updateForm
(
rule
:
ReplicationRule
):
void
{
...
...
@@ -182,7 +197,14 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
replicate_deletion
:
rule
.
replicate_deletion
});
this
.
setProject
(
rule
.
projects
);
this
.
noSelectedProject
=
false
;
this
.
setTarget
(
rule
.
targets
);
this
.
noSelectedEndpoint
=
false
;
this
.
realEndpointData
.
userName
=
rule
.
targets
[
0
].
username
;
this
.
realEndpointData
.
password
=
FAKE_PASSWORD
;
this
.
firstEndpointData
=
Object
.
assign
({},
this
.
realEndpointData
);
if
(
rule
.
filters
)
{
this
.
setFilter
(
rule
.
filters
);
this
.
updateFilter
(
rule
.
filters
);
...
...
@@ -250,6 +272,9 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
if
(
$event
&&
$event
.
target
&&
event
.
target
[
'
value
'
])
{
let
selecedTarget
:
Target
=
this
.
targetList
.
find
(
target
=>
target
.
id
===
+
$event
.
target
[
'
value
'
]);
this
.
setTarget
([
selecedTarget
]);
this
.
noSelectedEndpoint
=
false
;
this
.
realEndpointData
.
userName
=
selecedTarget
.
username
;
this
.
firstEndpointData
=
Object
.
assign
({},
this
.
realEndpointData
);
}
}
...
...
@@ -258,7 +283,12 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}
selectedProject
(
project
:
Project
):
void
{
this
.
setProject
([
project
]);
if
(
!
project
)
{
this
.
noSelectedProject
=
true
;
}
else
{
this
.
noSelectedProject
=
false
;
this
.
setProject
([
project
]);
}
}
addNewFilter
():
void
{
...
...
@@ -308,15 +338,15 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
selectTrigger
(
$event
:
any
):
void
{
if
(
$event
&&
$event
.
target
&&
$event
.
target
[
'
value
'
])
{
let
val
:
string
=
$event
.
target
[
'
value
'
];
if
(
val
===
this
.
triggerNames
[
1
])
{
if
(
val
===
this
.
triggerNames
[
2
])
{
this
.
isScheduleOpt
=
true
;
this
.
isImmediate
=
false
;
}
if
(
val
===
this
.
triggerNames
[
0
])
{
if
(
val
===
this
.
triggerNames
[
1
])
{
this
.
isScheduleOpt
=
false
;
this
.
isImmediate
=
true
;
}
if
(
val
===
this
.
triggerNames
[
2
])
{
if
(
val
===
this
.
triggerNames
[
0
])
{
this
.
isScheduleOpt
=
false
;
this
.
isImmediate
=
false
;
}
...
...
@@ -381,7 +411,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
trigger
[
'
schedule_param
'
][
'
weekday
'
]
=
1
;
}
}
else
{
if
(
trigger
[
'
kind
'
]
===
this
.
triggerNames
[
2
])
{
if
(
trigger
[
'
kind
'
]
===
this
.
triggerNames
[
0
])
{
this
.
isImmediate
=
false
;
}
trigger
[
'
schedule_param
'
]
=
{
type
:
this
.
scheduleNames
[
0
],
...
...
@@ -412,50 +442,86 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
onSubmit
()
{
// add new Replication rule
this
.
inProgress
=
true
;
let
endpointId
:
string
|
number
=
this
.
ruleForm
.
value
.
targets
[
0
].
id
;
let
pullData
:
{
[
key
:
string
]:
string
|
number
}
=
this
.
initEndpointData
();
if
(
compareValue
(
this
.
firstEndpointData
,
this
.
realEndpointData
))
{
this
.
saveRuleOpe
();
}
else
{
if
(
this
.
realEndpointData
.
userName
!==
this
.
firstEndpointData
.
userName
)
{
pullData
.
userName
=
this
.
realEndpointData
.
userName
;
}
else
{
delete
pullData
.
userName
;
}
if
(
this
.
realEndpointData
.
password
!==
this
.
firstEndpointData
.
password
)
{
pullData
.
password
=
this
.
realEndpointData
.
password
;
}
else
{
delete
pullData
.
password
;
}
pullData
.
id
=
endpointId
;
this
.
repService
.
pingEndpoint
(
pullData
)
.
then
((
res
:
any
)
=>
{
delete
pullData
.
id
;
this
.
repService
.
updateEndpoint
(
endpointId
,
pullData
)
.
then
((
res
:
any
)
=>
{
this
.
saveRuleOpe
();
})
.
catch
((
error
:
any
)
=>
{
this
.
inProgress
=
false
;
this
.
msgHandler
.
handleError
(
error
);
});
})
.
catch
((
error
:
any
)
=>
{
this
.
inProgress
=
false
;
this
.
msgHandler
.
handleError
(
'
DESTINATION.TEST_CONNECTION_FAILURE
'
);
return
false
;
});
}
}
saveRuleOpe
():
void
{
// add new Replication rule
let
copyRuleForm
:
ReplicationRule
=
this
.
ruleForm
.
value
;
copyRuleForm
.
trigger
=
this
.
setTriggerVaule
(
copyRuleForm
.
trigger
);
if
(
!
this
.
policyId
)
{
this
.
repService
.
createReplicationRule
(
copyRuleForm
)
.
then
(()
=>
{
this
.
msgHandler
.
showSuccess
(
'
REPLICATION.CREATED_SUCCESS
'
);
this
.
inProgress
=
false
;
this
.
isSubmitOver
=
true
;
setTimeout
(()
=>
{
this
.
copyUpdateForm
=
Object
.
assign
({},
this
.
ruleForm
.
value
);
if
(
this
.
projectId
)
{
this
.
router
.
navigate
([
'
harbor/projects
'
,
this
.
projectId
,
'
replications
'
]);
}
else
{
this
.
router
.
navigate
([
'
/harbor/replications
'
]);
}
},
2000
);
this
.
msgHandler
.
showSuccess
(
'
REPLICATION.CREATED_SUCCESS
'
);
this
.
inProgress
=
false
;
this
.
isSubmitOver
=
true
;
setTimeout
(()
=>
{
this
.
copyUpdateForm
=
Object
.
assign
({},
this
.
ruleForm
.
value
);
if
(
this
.
projectId
)
{
this
.
router
.
navigate
([
'
harbor/projects
'
,
this
.
projectId
,
'
replications
'
]);
}
else
{
this
.
router
.
navigate
([
'
/harbor/replications
'
]);
}
},
2000
);
}).
catch
((
error
:
any
)
=>
{
}).
catch
((
error
:
any
)
=>
{
this
.
inProgress
=
false
;
this
.
msgHandler
.
handleError
(
error
);
});
}
else
{
this
.
repService
.
updateReplicationRule
(
this
.
policyId
,
this
.
ruleForm
.
value
)
.
then
(()
=>
{
this
.
msgHandler
.
showSuccess
(
'
REPLICATION.UPDATED_SUCCESS
'
);
this
.
inProgress
=
false
;
this
.
isSubmitOver
=
true
;
setTimeout
(()
=>
{
this
.
copyUpdateForm
=
Object
.
assign
({},
this
.
ruleForm
.
value
);
if
(
this
.
projectId
)
{
this
.
router
.
navigate
([
'
harbor/projects
'
,
this
.
projectId
,
'
replications
'
]);
}
else
{
this
.
router
.
navigate
([
'
/harbor/replications
'
]);
}
},
2000
);
this
.
msgHandler
.
showSuccess
(
'
REPLICATION.UPDATED_SUCCESS
'
);
this
.
inProgress
=
false
;
this
.
isSubmitOver
=
true
;
setTimeout
(()
=>
{
this
.
copyUpdateForm
=
Object
.
assign
({},
this
.
ruleForm
.
value
);
if
(
this
.
projectId
)
{
this
.
router
.
navigate
([
'
harbor/projects
'
,
this
.
projectId
,
'
replications
'
]);
}
else
{
this
.
router
.
navigate
([
'
/harbor/replications
'
]);
}
},
2000
);
}).
catch
((
error
:
any
)
=>
{
}).
catch
((
error
:
any
)
=>
{
this
.
inProgress
=
false
;
this
.
msgHandler
.
handleError
(
error
);
});
}
}
openModal
()
{
...
...
@@ -467,8 +533,10 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
Promise
.
all
([
this
.
repService
.
getEndpoints
()]).
then
(
res
=>
{
this
.
targetList
=
res
[
0
];
this
.
setTarget
([
this
.
targetList
[
this
.
targetList
.
length
-
1
]]);
this
.
noSelectedEndpoint
=
false
;
this
.
realEndpointData
.
userName
=
this
.
targetList
[
this
.
targetList
.
length
-
1
].
username
;
this
.
firstEndpointData
=
Object
.
assign
({},
this
.
realEndpointData
);
});
this
.
noEndpointInfo
=
false
;
}
}
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/replication/replication-rule/replication-rule.css
+
11
-
7
View file @
791004c1
...
...
@@ -23,9 +23,11 @@ label:first-child {
font-size
:
15px
;
left
:
-10px
!important
;
}
.endpointSelect
{
width
:
290px
;}
.filterSelect
{
width
:
320px
;}
.filterSelect
label
{
width
:
160px
;}
.inputWidth
{
width
:
310px
;}
.endpointSelect
{
width
:
290px
;
margin-right
:
34px
;}
.filterSelect
{
width
:
350px
;}
.filterSelect
clr-icon
{
margin-left
:
10px
;}
.filterSelect
label
{
width
:
175px
;}
.filterSelect
label
input
{
width
:
100%
;}
.cursor
{
cursor
:
pointer
;}
.pull-left
{
float
:
left
;}
...
...
@@ -34,7 +36,9 @@ label:first-child {
.form-group
{
min-height
:
36px
;}
.projectInput
{
float
:
left
;}
.projectInput
input
{
width
:
185px
;
background-color
:
white
;}
.switchIcon
{
width
:
20px
;
height
:
20px
;
margin-top
:
2px
;
margin-left
:
5px
;}
.addEndpoint
{
display
:
inline-block
;
line-height
:
20px
;
margin-top
:
8px
;
vertical-align
:
bottom
;
padding-left
:
10px
;
cursor
:
pointer
;}
\ No newline at end of file
.projectInput
input
{
background-color
:
white
;}
.switchIcon
{
width
:
20px
;
height
:
20px
;
margin-top
:
16px
;
margin-left
:
10px
;}
.addEndpoint
{
margin-top
:
.25em
!important
;}
.shadow
{
position
:
absolute
;
top
:
8px
;}
.shadow1
{
width
:
270px
;
height
:
24px
;
background-color
:
#fafafa
;
z-index
:
10
;
top
:
5px
;}
.hoverBg
:hover
{
display
:
none
;}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/replication/replication-rule/replication-rule.html
+
30
-
33
View file @
791004c1
...
...
@@ -2,37 +2,37 @@
<a
class=
"cursor"
*ngIf=
"!projectId"
(click)=
"backReplication()"
><
{{'
SIDE_NAV.SYSTEM_MGMT.REPLICATION
'
|
translate
}}</
a
>
<a
class=
"cursor"
*ngIf=
"projectId"
(click)=
"backProjectReplication()"
><
{{'
SIDE_NAV.PROJECTS
'
|
translate
}}
&
nbsp
;
{{'
SIDE_NAV.SYSTEM_MGMT.REPLICATION
'
|
translate
|
lowercase
}}</
a
>
<h1
class=
"sub-header-title"
>
{{headerTitle | translate}}
</h1>
<form
[formGroup]=
"ruleForm"
(ngSubmit)=
"onSubmit()"
novalidate
>
<form
[formGroup]=
"ruleForm"
novalidate
>
<section
class=
"form-block"
>
<div
class=
"form-group"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'REPLICATION.NAME' | translate}}
<span
class=
"colorRed"
>
*
</span></label>
<label
class=
"col-md-8"
aria-haspopup=
"true"
role=
"tooltip"
class=
"tooltip tooltip-validation tooltip-md tooltip-bottom-left"
[class.invalid]=
'(ruleForm.controls.name.touched && ruleForm.controls.name.invalid) || isRuleNameExist'
>
<input
type=
"text"
id=
"ruleName"
required
formControlName=
"name"
#ruleName
(keyup)=
'checkRuleName()'
autocomplete=
"off"
>
<input
type=
"text"
id=
"ruleName"
class=
"inputWidth"
required
maxlength=
"255"
formControlName=
"name"
#ruleName
(keyup)=
'checkRuleName()'
autocomplete=
"off"
>
<span
class=
"tooltip-content"
>
{{ruleNameTooltip | translate}}
</span>
</label><span
class=
"spinner spinner-inline spinner-pos"
[hidden]=
"!inNameChecking"
></span>
</div>
<!--Description-->
<div
class=
"form-group"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'REPLICATION.DESCRIPTION' | translate}}
</label>
<textarea
type=
"text"
id=
"ruleDescription"
style=
" width: 355px;
"
row=
3;
formControlName=
"description"
></textarea>
<textarea
type=
"text"
id=
"ruleDescription"
class=
"inputWidth
"
row=
3;
formControlName=
"description"
></textarea>
</div>
<!--Projects-->
<h4>
{{'REPLICATION.SOURCE' | translate}}
</h4>
<div
class=
"form-group"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'PROJECT.PROJECTS' | translate}}
<span
class=
"colorRed"
>
*
</span></label>
<div
formArrayName=
"projects"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'
REPLICATION.SOURCE' | translate}}
{{'
PROJECT.PROJECTS' | translate
| lowercase
}}
<span
class=
"colorRed"
>
*
</span></label>
<div
formArrayName=
"projects"
[style.visibility]=
"noSelectedProject?'hidden':'visible'"
>
<div
class=
"projectInput"
*ngFor=
"let project of projects.controls; let i= index"
[formGroupName]=
"i"
>
<input
formControlName=
"name"
class=
"label"
readonly
value=
"name"
>
<input
formControlName=
"name"
type=
"text"
class=
"inputWidth"
disabled
value=
"name"
>
</div>
</div>
<clr-icon
*ngIf=
"!(noProjectInfo || projectId)"
shape=
"search"
class=
"is-solid switchIcon"
(click)=
"openProjectModel()"
></clr-icon>
<label
*ngIf=
"noProjectInfo"
class=
"colorRed"
>
{{noProjectInfo | translate}}
</label>
<clr-icon
*ngIf=
"!(noProjectInfo.length !=0 || projectId)"
shape=
"search"
class=
"is-solid switchIcon"
(click)=
"openProjectModel()"
></clr-icon>
<label
*ngIf=
"noProjectInfo.length != 0"
class=
"colorRed"
>
{{noProjectInfo | translate}}
</label>
<div
class=
"shadow"
[hidden]=
"!noSelectedProject || noProjectInfo.length != 0"
><input
type=
"text"
class=
"inputWidth"
disabled
></div>
</div>
<!--images/Filter-->
<div
class=
"form-group"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'REPLICATION.FILTER' | translate}}
</label>
<label
class=
"col-md-4 form-group-label-override"
>
{{'REPLICATION.
SOURCE_IMAGES_
FILTER' | translate}}
</label>
<div
formArrayName=
"filters"
>
<div
class=
"filterSelect"
*ngFor=
"let filter of filters.controls; let i=index"
[formGroupName]=
"i"
>
<div>
...
...
@@ -53,43 +53,44 @@
<clr-icon
shape=
"plus-circle"
class=
"is-solid"
[hidden]=
"isFilterHide"
(click)=
"addNewFilter()"
style=
"margin-top: 11px;"
></clr-icon>
</div>
<!--Targets-->
<h4>
{{'REPLICATION.TARGETS' | translate}}
</h4>
<div
class=
"form-group"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'DESTINATION.ENDPOINT' | translate}}
<span
class=
"colorRed"
>
*
</span></label>
<div
formArrayName=
"targets"
>
<div
class=
"select endpointSelect pull-left"
*ngFor=
"let target of targets.controls; let i= index"
[formGroupName]=
"i"
>
<select
id=
"ruleTarget"
(change)=
"targetChange($event)"
formControlName=
"id"
>
<select
id=
"ruleTarget
"
class=
"inputWidth"
(mouseenter)=
"noSelectedEndpoint= false
"
(change)=
"targetChange($event)"
formControlName=
"id"
>
<option
*ngFor=
"let target of targetList"
value=
"{{target.id}}"
>
{{target.name}}: {{target.endpoint}}
</option>
</select>
</div>
<a
class=
"addEndpoint"
(click)=
"openModal()"
><clr-icon
shape=
"plus"
style=
"vertical-align: sub;"
></clr-icon>
{{'REPLICATION.NEW' | translate}}
</a>
</div>
<button
class=
"btn btn-info btn-sm addEndpoint"
(click)=
"openModal()"
><clr-icon
shape=
"plus"
></clr-icon>
{{'REPLICATION.NEW' | translate}}
</button>
<div
[hidden]=
"noSelectedEndpoint"
>
userName:
<input
type=
"text"
[(ngModel)]=
"realEndpointData.userName"
[ngModelOptions]=
"{standalone:true}"
></div>
<div
[hidden]=
"noSelectedEndpoint"
>
password:
<input
type=
"password"
[(ngModel)]=
"realEndpointData.password"
[ngModelOptions]=
"{standalone:true}"
></div>
</div>
<div
class=
"shadow shadow1 hoverBg"
#shadowDiv
[hidden]=
"!noSelectedEndpoint || !targetList.length"
></div>
</div>
<!--Trigger-->
<h4>
{{'REPLICATION.TRIGGER' | translate}}
</h4>
<div
class=
"form-group"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'REPLICATION.MODE' | translate}}
</label>
<label
class=
"col-md-4 form-group-label-override"
>
{{'REPLICATION.
TRIGGER_
MODE' | translate}}
</label>
<div
formGroupName=
"trigger"
>
<!--on trigger-->
<div
class=
"select floatSet
pull-left
"
>
<div
class=
"select floatSet"
>
<select
id=
"ruleTrigger"
formControlName=
"kind"
(change)=
"selectTrigger($event)"
>
<option
value=
"Manual"
>
{{'REPLICATION.MANUAL' | translate}}
</option>
<option
value=
"Immediate"
>
{{'REPLICATION.IMMEDIATE' | translate}}
</option>
<option
value=
"Scheduled"
>
{{'REPLICATION.SCHEDULE' | translate}}
</option>
<option
value=
"Manual"
>
{{'REPLICATION.MANUAL' | translate}}
</option>
</select>
</div>
<!--on push-->
<div
style=
"float: left;"
formGroupName=
"schedule_param"
>
<div
class=
"select floatSet
pull-left
"
[hidden]=
"!isScheduleOpt"
>
<div
formGroupName=
"schedule_param"
>
<div
class=
"select floatSet"
[hidden]=
"!isScheduleOpt"
>
<select
name=
"scheduleType"
formControlName=
"type"
(change)=
"selectSchedule($event)"
>
<option
value=
"Daily"
>
{{'REPLICATION.DAILY' | translate}}
</option>
<option
value=
"Weekly"
>
{{'REPLICATION.WEEKLY' | translate}}
</option>
</select>
</div>
<!--weekly-->
<span
style=
"float: left;"
[hidden]=
"!weeklySchedule || !isScheduleOpt"
>
on
</span>
<div
[hidden]=
"!weeklySchedule || !isScheduleOpt"
class=
"select floatSet
pull-left
"
>
<span
[hidden]=
"!weeklySchedule || !isScheduleOpt"
>
on
</span>
<div
[hidden]=
"!weeklySchedule || !isScheduleOpt"
class=
"select floatSet"
>
<select
name=
"scheduleDay"
formControlName=
"weekday"
>
<option
value=
"1"
>
{{'WEEKLY.MONDAY' | translate}}
</option>
<option
value=
"2"
>
{{'WEEKLY.TUESDAY' | translate}}
</option>
...
...
@@ -110,22 +111,18 @@
{{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}
</clr-checkbox>
</div>
</div>
<!--Setting-->
<div
class=
"form-group"
>
<label
class=
"col-md-4 form-group-label-override"
>
{{'REPLICATION.SETTING' | translate}}
</label>
<div
class=
"col-lg-7 padLeft0"
>
<clr-checkbox
[clrChecked]=
"true"
id=
"ruleExit"
formControlName=
"replicate_existing_image_now"
>
{{'REPLICATION.REPLICATE_IMMEDIATE' | translate}}
</clr-checkbox>
</div>
<div
style=
"width: 100%;"
>
<clr-checkbox
[clrChecked]=
"true"
id=
"ruleExit"
formControlName=
"replicate_existing_image_now"
>
{{'REPLICATION.REPLICATE_IMMEDIATE' | translate}}
</clr-checkbox>
</div>
</div>
<div
class=
"offset-md-4"
>
<span
class=
"spinner spinner-inline"
[hidden]=
"inProgress === false"
></span>
<br>
<button
type=
"button"
id=
"ruleBtnCancel"
class=
"btn btn-outline"
[disabled]=
"!hasFormChange()"
(click)=
"onCancel()"
>
{{ 'BUTTON.CANCEL' | translate }}
</button>
<button
type=
"submit"
id=
"ruleBtnOk"
class=
"btn btn-primary"
[disabled]=
"!ruleForm.valid || !isVaild || !hasFormChange()"
>
{{ 'BUTTON.OK' | translate }}
</button>
<button
type=
"button"
id=
"ruleBtnCancel"
class=
"btn btn-outline"
[disabled]=
"!hasFormChange()
|| this.inProgress || this.isSubmitOver
"
(click)=
"onCancel()"
>
{{ 'BUTTON.CANCEL' | translate }}
</button>
<button
type=
"submit"
id=
"ruleBtnOk"
class=
"btn btn-primary"
(click)=
"onSubmit()"
[disabled]=
"!ruleForm.valid || !isVaild || !hasFormChange()"
>
{{ 'BUTTON.OK' | translate }}
</button>
</div>
<!-- [disabled]="!ruleForm.valid"-->
</section>
</form>
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/replication/replication-rule/replication-rule.service.ts
+
27
-
0
View file @
791004c1
...
...
@@ -72,4 +72,31 @@ export class ReplicationRuleServie {
.
catch
(
error
=>
Promise
.
reject
(
error
));
}
public
updateEndpoint
(
endpointId
:
number
|
string
,
endpoint
:
any
):
Promise
<
any
>
|
any
{
if
(
!
endpointId
||
endpointId
<=
0
)
{
return
Promise
.
reject
(
'
Bad request argument.
'
);
}
if
(
!
endpoint
)
{
return
Promise
.
reject
(
'
Invalid endpoint.
'
);
}
let
requestUrl
:
string
=
`/api/targets/
${
endpointId
}
`
;
return
this
.
http
.
put
(
requestUrl
,
JSON
.
stringify
(
endpoint
),
HTTP_JSON_OPTIONS
)
.
toPromise
()
.
then
(
response
=>
response
.
status
)
.
catch
(
error
=>
Promise
.
reject
(
error
));
}
public
pingEndpoint
(
endpoint
:
any
):
Promise
<
any
>
|
any
{
if
(
!
endpoint
)
{
return
Promise
.
reject
(
'
Invalid endpoint.
'
);
}
let
requestUrl
:
string
=
`/api/targets/ping`
;
return
this
.
http
.
post
(
requestUrl
,
endpoint
,
HTTP_JSON_OPTIONS
)
.
toPromise
()
.
then
(
response
=>
response
.
status
)
.
catch
(
error
=>
Promise
.
reject
(
error
));
}
}
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/replication/replication-rule/replication-rule.ts
+
19
-
8
View file @
791004c1
...
...
@@ -4,15 +4,26 @@ import {Project} from "../../project/project";
*/
export
class
Target
{
id
:
0
;
endpoint
:
'
string
'
;
name
:
'
string
'
;
username
:
'
string
'
;
password
:
'
string
'
;
type
:
0
;
id
:
number
;
endpoint
:
string
;
name
:
string
;
username
:
string
;
password
:
string
;
type
:
number
;
insecure
:
true
;
creation_time
:
'
string
'
;
update_time
:
'
string
'
;
creation_time
:
string
;
update_time
:
string
;
constructor
()
{
this
.
id
=
-
1
;
this
.
endpoint
=
""
;
this
.
name
=
""
;
this
.
username
=
""
;
this
.
password
=
""
;
this
.
type
=
0
;
this
.
insecure
=
true
;
this
.
creation_time
=
""
;
this
.
update_time
=
""
;
}
}
export
class
Filter
{
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/app/user/user.component.ts
+
1
-
0
View file @
791004c1
...
...
@@ -277,6 +277,7 @@ export class UserComponent implements OnInit, OnDestroy {
//Refresh the user list
refreshUser
(
from
:
number
,
to
:
number
):
void
{
this
.
selectedRow
=
[];
//Start to get
this
.
currentTerm
=
''
;
this
.
onGoing
=
true
;
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/i18n/lang/en-us-lang.json
+
1
-
1
View file @
791004c1
...
...
@@ -324,7 +324,7 @@
"JOB_LOG_VIEWER"
:
"View Replication Job Log"
,
"NO_ENDPOINT_INFO"
:
"Please go to registries and add an endpoint first"
,
"NO_PROJECT_INFO"
:
"Please go to projects and add a project name first"
,
"
FILTER"
:
"F
ilter"
,
"
SOURCE_IMAGES_FILTER"
:
"Source images f
ilter"
,
"SCHEDULE"
:
"Scheduled"
,
"MANUAL"
:
"Manual"
,
"IMMEDIATE"
:
"Immediate"
,
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/i18n/lang/es-es-lang.json
+
1
-
1
View file @
791004c1
...
...
@@ -324,7 +324,7 @@
"JOB_LOG_VIEWER"
:
"View Replication Job Log"
,
"NO_ENDPOINT_INFO"
:
"Please go to registries and add an endpoint first"
,
"NO_PROJECT_INFO"
:
"Please go to projects and add a project name first"
,
"
FILTER"
:
"F
ilter"
,
"
SOURCE_IMAGES_FILTER"
:
"Source images f
ilter"
,
"SCHEDULE"
:
"Scheduled"
,
"MANUAL"
:
"Manual"
,
"IMMEDIATE"
:
"Immediate"
,
...
...
This diff is collapsed.
Click to expand it.
src/ui_ng/src/i18n/lang/zh-cn-lang.json
+
2
-
2
View file @
791004c1
...
...
@@ -324,7 +324,7 @@
"JOB_LOG_VIEWER"
:
"查看复制任务日志"
,
"NO_ENDPOINT_INFO"
:
"请先添加目标"
,
"NO_PROJECT_INFO"
:
"请先去项目添加一个新的项目名称"
,
"FILTER"
:
"过滤"
,
"
SOURCE_IMAGES_
FILTER"
:
"
源镜像
过滤
器
"
,
"SCHEDULE"
:
"定时"
,
"MANUAL"
:
"手动"
,
"IMMEDIATE"
:
"即刻"
,
...
...
@@ -335,7 +335,7 @@
"TARGETS"
:
"目标"
,
"MODE"
:
"模式"
,
"TRIGGER_MODE"
:
"触发模式"
,
"SOURCE"
:
"
资
源"
,
"SOURCE"
:
"源"
,
"REPLICATE"
:
"复制"
,
"DELETE_REMOTE_IMAGES"
:
"删除本地镜像时同时也删除远程的镜像。"
,
"REPLICATE_IMMEDIATE"
:
"立即复制现有的镜像。"
,
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help