Skip to content
GitLab
Menu
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
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