mirror of
https://github.com/goharbor/harbor
synced 2024-09-21 06:27:41 +00:00
updates for adding replication section of UI.
This commit is contained in:
parent
8d30879fc2
commit
a180b852b9
34
controllers/ng/navigationdetail.go
Normal file
34
controllers/ng/navigationdetail.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package ng
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/dao"
|
||||||
|
"github.com/vmware/harbor/models"
|
||||||
|
"github.com/vmware/harbor/utils/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NavigationDetailController struct {
|
||||||
|
BaseController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ndc *NavigationDetailController) Get() {
|
||||||
|
sessionUserID := ndc.GetSession("userId")
|
||||||
|
var isAdmin int
|
||||||
|
if sessionUserID != nil {
|
||||||
|
userID := sessionUserID.(int)
|
||||||
|
u, err := dao.GetUser(models.User{UserID: userID})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Error occurred in GetUser, error: %v", err)
|
||||||
|
ndc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
log.Warningf("User was deleted already, user id: %d, canceling request.", userID)
|
||||||
|
ndc.CustomAbort(http.StatusUnauthorized, "")
|
||||||
|
}
|
||||||
|
isAdmin = u.HasAdminRole
|
||||||
|
}
|
||||||
|
ndc.Data["IsAdmin"] = isAdmin
|
||||||
|
ndc.TplName = "ng/navigation-detail.htm"
|
||||||
|
ndc.Render()
|
||||||
|
}
|
21
static/ng/resources/css/replication.css
Normal file
21
static/ng/resources/css/replication.css
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
.create-policy {
|
||||||
|
height: 535px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group-custom {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h4-custom {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hr-line {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-custom {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
|
@ -28,8 +28,6 @@
|
||||||
|
|
||||||
.switch-pane-tabs {
|
.switch-pane-tabs {
|
||||||
width: 265px;
|
width: 265px;
|
||||||
min-width: 265px;
|
|
||||||
float: right;
|
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
<div class="modal fade" id="createPolicyModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title"><span class="glyphicon glyphicon-plus"></span> Create New Policy</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="create-policy">
|
||||||
|
<form name="form" class="form-horizontal" ng-submit="form.$valid" novalidate>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h4>General</h4>
|
||||||
|
<hr class="hr-line"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<label for="name" class="col-md-3 control-label">Name:</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<input type="text" class="form-control form-control-custom" id="name" ng-model="policy.name" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.policy.name" name="uName" required>
|
||||||
|
<div ng-messages="form.$dirty && form.uName.$error">
|
||||||
|
<span ng-message="required">Name is required.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<label for="description" class="col-md-3 control-label">Description:</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<textarea class="form-control form-control-custom" id="description" ng-model="policy.description" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.policy.enable" name="uDescription" required ></textarea>
|
||||||
|
<div ng-messages="form.$dirty && form.uDescription.$error">
|
||||||
|
<span ng-message="required">Description is required.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<label for="enable" class="col-md-3 control-label">Enable:</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<input type="checkbox" class="form-control" style="margin-top: 10px; height: auto;" id="enable" ng-model="policy.enable" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.policy.enable" name="uEnable">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h4 class="h4-custom">Destination Setting</h4>
|
||||||
|
<hr class="hr-line"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<label for="destinationName" class="col-md-3 control-label">Name:</label>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<select class="form-control form-control-custom" id="destinationName" ng-model="policy.destinationName" ng-options="d as d.name for d in vm.destinations track by d.id" ng-click="vm.selectDestination()"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<label for="endpoint" class="col-md-3 control-label">Endpoint:</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<input type="text" class="form-control form-control-custom" id="endpoint" ng-model="policy.endpoint" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.endpoint" name="uEndpoint" required>
|
||||||
|
<div ng-messages="form.$dirty && form.uEndpoint.$error">
|
||||||
|
<span ng-message="required">Endpoint is required.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<label for="username" class="col-md-3 control-label">Username:</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<input type="text" class="form-control" id="username" ng-model="policy.username" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.username" name="uUsername" required>
|
||||||
|
<div ng-messages="form.$dirty && form.uUsername.$error">
|
||||||
|
<span ng-message="required">Username is required.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<label for="password" class="col-md-3 control-label">Password:</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<input type="password" class="form-control" id="password" ng-model="policy.password" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.password" name="uPassword" required>
|
||||||
|
<div ng-messages="form.$dirty && form.uPassword.$error">
|
||||||
|
<span ng-message="required">Password is required.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-12 form-group-custom">
|
||||||
|
<div class="col-md-3"></div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<button class="btn btn-default" ng-click="vm.testConnection()">Test Connection</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" id="btnOk">// 'ok' | tr //</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">// 'close' | tr //</button>
|
||||||
|
</div>
|
||||||
|
</div><!-- /.modal-content -->
|
||||||
|
</div><!-- /.modal-dialog -->
|
||||||
|
</div><!-- /.modal -->
|
|
@ -0,0 +1,26 @@
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('harbor.replication')
|
||||||
|
.directive('createPolicy', createPolicy);
|
||||||
|
|
||||||
|
function CreatePolicyController() {
|
||||||
|
var vm = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPolicy() {
|
||||||
|
var directive = {
|
||||||
|
'restrict': 'E',
|
||||||
|
'templateUrl': '/static/ng/resources/js/components/replication/create-policy.directive.html',
|
||||||
|
'scope': true,
|
||||||
|
'replace': true,
|
||||||
|
'controller': CreatePolicyController,
|
||||||
|
'controllerAs': 'vm',
|
||||||
|
'bindToController': true
|
||||||
|
};
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
|
@ -0,0 +1,32 @@
|
||||||
|
<div class="tab-pane">
|
||||||
|
<div class="col-xs-12 col-md-12 each-tab-pane">
|
||||||
|
<div class="form-inline">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" placeholder="" ng-model="vm.replicationName" size="30">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-primary" type="button" ng-click="vm.search()"><span class="glyphicon glyphicon-search"></span></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button ng-if="!vm.isOpen" class="btn btn-success" type="button" ng-click="vm.addReplication()" data-toggle="modal" data-target="#createPolicyModal"><span class="glyphicon glyphicon-plus"></span>New Replication</button>
|
||||||
|
<create-policy></create-policy>
|
||||||
|
</div>
|
||||||
|
<div class="pane">
|
||||||
|
<div class="sub-pane">
|
||||||
|
<table class="table table-pane" >
|
||||||
|
<thead>
|
||||||
|
<th width="12%">Name</th>
|
||||||
|
<th width="14%">Description</th>
|
||||||
|
<th width="14%">Destination</th>
|
||||||
|
<th width="12%">Start Time</th>
|
||||||
|
<th width="12%">Status</th>
|
||||||
|
<th width="12%">Activation</th>
|
||||||
|
<th width="14%">Actions</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,34 @@
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('harbor.replication')
|
||||||
|
.directive('listReplication', listReplication);
|
||||||
|
|
||||||
|
ListReplicationController.$inject = [];
|
||||||
|
|
||||||
|
function ListReplicationController() {
|
||||||
|
var vm = this;
|
||||||
|
vm.addReplication = addReplication;
|
||||||
|
|
||||||
|
function addReplication() {
|
||||||
|
vm.modalTitle = 'Create New Policy';
|
||||||
|
vm.modalMessage = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function listReplication() {
|
||||||
|
var directive = {
|
||||||
|
'restrict': 'E',
|
||||||
|
'templateUrl': '/static/ng/resources/js/components/replication/list-replication.directive.html',
|
||||||
|
'scope': true,
|
||||||
|
'controller': ListReplicationController,
|
||||||
|
'controllerAs': 'vm',
|
||||||
|
'bindToController': true
|
||||||
|
};
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
|
@ -0,0 +1,8 @@
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('harbor.replication', []);
|
||||||
|
|
||||||
|
})();
|
|
@ -22,6 +22,7 @@
|
||||||
'harbor.layout.log',
|
'harbor.layout.log',
|
||||||
'harbor.layout.admin.option',
|
'harbor.layout.admin.option',
|
||||||
'harbor.layout.search',
|
'harbor.layout.search',
|
||||||
|
'harbor.layout.replication',
|
||||||
'harbor.services.i18n',
|
'harbor.services.i18n',
|
||||||
'harbor.services.project',
|
'harbor.services.project',
|
||||||
'harbor.services.user',
|
'harbor.services.user',
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
'harbor.project.member',
|
'harbor.project.member',
|
||||||
'harbor.user',
|
'harbor.user',
|
||||||
'harbor.log',
|
'harbor.log',
|
||||||
'harbor.validator'
|
'harbor.validator',
|
||||||
|
'harbor.replication'
|
||||||
]);
|
]);
|
||||||
})();
|
})();
|
|
@ -15,6 +15,11 @@
|
||||||
controller: 'RepositoryController',
|
controller: 'RepositoryController',
|
||||||
controllerAs: 'vm'
|
controllerAs: 'vm'
|
||||||
})
|
})
|
||||||
|
.when('/replication', {
|
||||||
|
templateUrl: '/static/ng/resources/js/layout/replication/replication.controller.html',
|
||||||
|
controller: 'ReplicationController',
|
||||||
|
controllerAs: 'vm'
|
||||||
|
})
|
||||||
.when('/users', {
|
.when('/users', {
|
||||||
templateUrl: '/static/ng/resources/js/layout/project-member/project-member.controller.html',
|
templateUrl: '/static/ng/resources/js/layout/project-member/project-member.controller.html',
|
||||||
controller: 'ProjectMemberController',
|
controller: 'ProjectMemberController',
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
function navigationDetails() {
|
function navigationDetails() {
|
||||||
var directive = {
|
var directive = {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
templateUrl: '/static/ng/resources/js/layout/navigation/navigation-details.directive.html',
|
templateUrl: '/ng/navigation_detail',
|
||||||
link: link,
|
link: link,
|
||||||
scope: {
|
scope: {
|
||||||
'selectedProject': '='
|
'selectedProject': '='
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<list-replication></list-replication>
|
|
@ -0,0 +1,12 @@
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('harbor.layout.replication')
|
||||||
|
.controller('ReplicationController', ReplicationController);
|
||||||
|
|
||||||
|
function ReplicationController() {
|
||||||
|
var vm = this;
|
||||||
|
}
|
||||||
|
})();
|
|
@ -0,0 +1,8 @@
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('harbor.layout.replication', []);
|
||||||
|
|
||||||
|
})();
|
|
@ -25,5 +25,6 @@ func initNgRouters() {
|
||||||
|
|
||||||
beego.Router("/ng/optional_menu", &ng.OptionalMenuController{})
|
beego.Router("/ng/optional_menu", &ng.OptionalMenuController{})
|
||||||
beego.Router("/ng/navigation_header", &ng.NavigationHeaderController{})
|
beego.Router("/ng/navigation_header", &ng.NavigationHeaderController{})
|
||||||
|
beego.Router("/ng/navigation_detail", &ng.NavigationDetailController{})
|
||||||
beego.Router("/ng/sign_in", &ng.SignInController{})
|
beego.Router("/ng/sign_in", &ng.SignInController{})
|
||||||
}
|
}
|
||||||
|
|
8
views/ng/navigation-detail.htm
Normal file
8
views/ng/navigation-detail.htm
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<ul class="switch-pane-tabs pull-right" {{ if eq .IsAdmin 1 }} style="width: 360px" {{ end }} role="tablist">
|
||||||
|
<li><a tag="repositories" href="#/repositories?project_id=//vm.projectId//">// 'repositories' | tr //</a><span class="gutter">|</span></li>
|
||||||
|
{{ if eq .IsAdmin 1 }}
|
||||||
|
<li><a tag="replication" href="#/replication?project_id=//vm.projectId//">Replication</a><span class="gutter">|</span></li>
|
||||||
|
{{ end }}
|
||||||
|
<li><a tag="users" href="#/users?project_id=//vm.projectId//">// 'users' | tr //</a><span class="gutter">|</span></li>
|
||||||
|
<li><a tag="logs" href="#/logs?project_id=//vm.projectId//">// 'logs' | tr //</a></li>
|
||||||
|
</ul>
|
|
@ -31,6 +31,7 @@
|
||||||
<link rel="stylesheet" href="/static/ng/resources/css/repository.css">
|
<link rel="stylesheet" href="/static/ng/resources/css/repository.css">
|
||||||
<link rel="stylesheet" href="/static/ng/resources/css/sign-up.css">
|
<link rel="stylesheet" href="/static/ng/resources/css/sign-up.css">
|
||||||
<link rel="stylesheet" href="/static/ng/resources/css/search.css">
|
<link rel="stylesheet" href="/static/ng/resources/css/search.css">
|
||||||
|
<link rel="stylesheet" href="/static/ng/resources/css/replication.css">
|
||||||
|
|
||||||
<script src="/static/ng/vendors/angularjs/angular.js"></script>
|
<script src="/static/ng/vendors/angularjs/angular.js"></script>
|
||||||
<script src="/static/ng/vendors/angularjs/angular-route.js"></script>
|
<script src="/static/ng/vendors/angularjs/angular-route.js"></script>
|
||||||
|
@ -96,6 +97,9 @@
|
||||||
<script src="/static/ng/resources/js/layout/search/search.module.js"></script>
|
<script src="/static/ng/resources/js/layout/search/search.module.js"></script>
|
||||||
<script src="/static/ng/resources/js/layout/search/search.controller.js"></script>
|
<script src="/static/ng/resources/js/layout/search/search.controller.js"></script>
|
||||||
|
|
||||||
|
<script src="/static/ng/resources/js/layout/replication/replication.module.js"></script>
|
||||||
|
<script src="/static/ng/resources/js/layout/replication/replication.controller.js"></script>
|
||||||
|
|
||||||
<script src="/static/ng/resources/js/services/i18n/services.i18n.module.js"></script>
|
<script src="/static/ng/resources/js/services/i18n/services.i18n.module.js"></script>
|
||||||
|
|
||||||
{{ if eq .Lang "zh-CN" }}
|
{{ if eq .Lang "zh-CN" }}
|
||||||
|
@ -197,3 +201,7 @@
|
||||||
<script src="/static/ng/resources/js/components/log/log.config.js"></script>
|
<script src="/static/ng/resources/js/components/log/log.config.js"></script>
|
||||||
<script src="/static/ng/resources/js/components/log/list-log.directive.js"></script>
|
<script src="/static/ng/resources/js/components/log/list-log.directive.js"></script>
|
||||||
<script src="/static/ng/resources/js/components/log/advanced-search.directive.js"></script>
|
<script src="/static/ng/resources/js/components/log/advanced-search.directive.js"></script>
|
||||||
|
|
||||||
|
<script src="/static/ng/resources/js/components/replication/replication.module.js"></script>
|
||||||
|
<script src="/static/ng/resources/js/components/replication/list-replication.directive.js"></script>
|
||||||
|
<script src="/static/ng/resources/js/components/replication/create-policy.directive.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user