diff --git a/api/replication_job.go b/api/replication_job.go index 346e58f96..fd9da76cc 100644 --- a/api/replication_job.go +++ b/api/replication_job.go @@ -58,7 +58,7 @@ func (ra *RepJobAPI) Prepare() { // List filters jobs according to the policy and repository func (ra *RepJobAPI) List() { var policyID int64 - var repository string + var repository, status string var err error policyIDStr := ra.GetString("policy_id") @@ -70,10 +70,11 @@ func (ra *RepJobAPI) List() { } repository = ra.GetString("repository") + status = ra.GetString("status") - jobs, err := dao.FilterRepJobs(repository, policyID) + jobs, err := dao.FilterRepJobs(policyID, repository, status) if err != nil { - log.Errorf("failed to filter jobs according policy ID %d and repository %s: %v", policyID, repository, err) + log.Errorf("failed to filter jobs according policy ID %d, repository %s, status %s: %v", policyID, repository, status, err) ra.RenderError(http.StatusInternalServerError, "Failed to query job") return } diff --git a/api/search.go b/api/search.go index a6d2a4ce2..4da0068c0 100644 --- a/api/search.go +++ b/api/search.go @@ -68,7 +68,7 @@ func (s *SearchAPI) Get() { } } - projectSorter := &utils.ProjectSorter{Projects: projects} + projectSorter := &models.ProjectSorter{Projects: projects} sort.Sort(projectSorter) projectResult := []map[string]interface{}{} for _, p := range projects { diff --git a/dao/dao_test.go b/dao/dao_test.go index 7742a3dda..e0c8a0fbb 100644 --- a/dao/dao_test.go +++ b/dao/dao_test.go @@ -1141,7 +1141,7 @@ func TestDeleteRepJob(t *testing.T) { } func TestFilterRepJobs(t *testing.T) { - jobs, err := FilterRepJobs("", policyID) + jobs, err := FilterRepJobs(policyID, "", "") if err != nil { log.Errorf("Error occured in FilterRepJobs: %v, policy ID: %d", err, policyID) return diff --git a/dao/replication_job.go b/dao/replication_job.go index 98842db38..f77ce2b9f 100644 --- a/dao/replication_job.go +++ b/dao/replication_job.go @@ -302,29 +302,24 @@ func GetRepJobByPolicy(policyID int64) ([]*models.RepJob, error) { } // FilterRepJobs filters jobs by repo and policy ID -func FilterRepJobs(repo string, policyID int64) ([]*models.RepJob, error) { +func FilterRepJobs(policyID int64, repository, status string) ([]*models.RepJob, error) { o := GetOrmer() - var args []interface{} - - sql := `select * from replication_job ` - - if len(repo) != 0 && policyID != 0 { - sql += `where repository like ? and policy_id = ? ` - args = append(args, "%"+repo+"%") - args = append(args, policyID) - } else if len(repo) != 0 { - sql += `where repository like ? ` - args = append(args, "%"+repo+"%") - } else if policyID != 0 { - sql += `where policy_id = ? ` - args = append(args, policyID) + qs := o.QueryTable(new(models.RepJob)) + if policyID != 0 { + qs = qs.Filter("PolicyID", policyID) } - - sql += `order by creation_time` + if len(repository) != 0 { + qs = qs.Filter("Repository__icontains", repository) + } + if len(status) != 0 { + qs = qs.Filter("Status__icontains", status) + } + qs = qs.OrderBy("CreationTime") var jobs []*models.RepJob - if _, err := o.Raw(sql, args).QueryRows(&jobs); err != nil { + _, err := qs.All(&jobs) + if err != nil { return nil, err } diff --git a/models/project.go b/models/project.go index e16f0ce5f..0105f6a79 100644 --- a/models/project.go +++ b/models/project.go @@ -37,3 +37,23 @@ type Project struct { Role int `json:"current_user_role_id"` RepoCount int `json:"repo_count"` } + +// ProjectSorter holds an array of projects +type ProjectSorter struct { + Projects []Project +} + +// Len returns the length of array in ProjectSorter +func (ps *ProjectSorter) Len() int { + return len(ps.Projects) +} + +// Less defines the comparison rules of project +func (ps *ProjectSorter) Less(i, j int) bool { + return ps.Projects[i].Name < ps.Projects[j].Name +} + +// Swap swaps the position of i and j +func (ps *ProjectSorter) Swap(i, j int) { + ps.Projects[i], ps.Projects[j] = ps.Projects[j], ps.Projects[i] +} diff --git a/models/replication_job.go b/models/replication_job.go index 4203705f1..4c3fc11d4 100644 --- a/models/replication_job.go +++ b/models/replication_job.go @@ -19,6 +19,7 @@ import ( "time" "github.com/astaxie/beego/validation" + "github.com/vmware/harbor/utils" ) const ( @@ -129,6 +130,8 @@ func (r *RepTarget) Valid(v *validation.Validation) { v.SetError("endpoint", "can not be empty") } + r.URL = utils.FormatEndpoint(r.URL) + if len(r.URL) > 64 { v.SetError("endpoint", "max length is 64") } diff --git a/static/resources/css/index.css b/static/resources/css/index.css index e31a3d5b8..ee9605207 100644 --- a/static/resources/css/index.css +++ b/static/resources/css/index.css @@ -32,6 +32,7 @@ body { .container-fluid-custom { background-color: #EFEFEF; width: 100%; + height: 100%; min-width: 1px; overflow: auto; min-height: 1px; diff --git a/static/resources/js/components/element-height/element-height.inspector.js b/static/resources/js/components/element-height/element-height.inspector.js index 2f063f54b..603ac8f24 100644 --- a/static/resources/js/components/element-height/element-height.inspector.js +++ b/static/resources/js/components/element-height/element-height.inspector.js @@ -23,15 +23,13 @@ if(!angular.isDefined(scope.subsHeight)) scope.subsHeight = 110; if(!angular.isDefined(scope.subsSection)) scope.subsSection = 32; if(!angular.isDefined(scope.subsSubPane)) scope.subsSubPane = 226; - if(!angular.isDefined(scope.subsTabPane)) scope.subsTabPane = 66; scope.$watch(scope.getDimension, function(current) { if(current) { - var h = current.h; - element.css({'height' : (h - scope.subsHeight) + 'px'}); + var h = current.h; element.find('.section').css({'height': (h - scope.subsHeight - scope.subsSection) + 'px'}); element.find('.sub-pane').css({'height': (h - scope.subsHeight - scope.subsSubPane) + 'px'}); - element.find('.tab-pane').css({'height': (h - scope.subsHeight - scope.subsTabPane) + 'px'}); + element.find('.tab-pane').css({'height': (h - scope.subsHeight - scope.subsSubPane) + 'px'}); } }, true); diff --git a/static/resources/js/components/replication/list-replication.directive.js b/static/resources/js/components/replication/list-replication.directive.js index 67e80f0ca..a87ba6ad9 100644 --- a/static/resources/js/components/replication/list-replication.directive.js +++ b/static/resources/js/components/replication/list-replication.directive.js @@ -138,7 +138,7 @@ }else{ element.find('#down-pane').css({'height' : (maxDownPaneHeight) + 'px'}); $(document).off('mousemove'); - } + } } function mouseupHandler(e) { $(document).off('mousedown'); @@ -171,7 +171,8 @@ element .find('#upon-pane table>tbody>tr') .css({'background-color': '#FFFFFF'}) - .css({'color': '#000'}); + .css({'color': '#000'}) + .css({'cursor': 'default'}); element .find('#upon-pane table>tbody>tr a') .css({'color': '#337ab7'}); diff --git a/static/resources/js/components/repository/list-repository.directive.html b/static/resources/js/components/repository/list-repository.directive.html index b8d3a6c4a..664fe6dbe 100644 --- a/static/resources/js/components/repository/list-repository.directive.html +++ b/static/resources/js/components/repository/list-repository.directive.html @@ -1,4 +1,4 @@ -
+
@@ -11,6 +11,7 @@

// 'no_repositories' | tr //

+
@@ -25,5 +26,6 @@
+
\ No newline at end of file diff --git a/static/resources/js/components/repository/list-repository.directive.js b/static/resources/js/components/repository/list-repository.directive.js index 2955ece6f..09092b909 100644 --- a/static/resources/js/components/repository/list-repository.directive.js +++ b/static/resources/js/components/repository/list-repository.directive.js @@ -8,6 +8,9 @@ ListRepositoryController.$inject = ['$scope', 'ListRepositoryService', 'DeleteRepositoryService', '$filter', 'trFilter', '$location', 'getParameterByName']; function ListRepositoryController($scope, ListRepositoryService, DeleteRepositoryService, $filter, trFilter, $location, getParameterByName) { + + $scope.subsTabPane = 30; + var vm = this; vm.filterInput = ''; diff --git a/utils/registry/auth/authorizer.go b/utils/registry/auth/authorizer.go index 8dd4ef862..5f81e1e22 100644 --- a/utils/registry/auth/authorizer.go +++ b/utils/registry/auth/authorizer.go @@ -21,7 +21,7 @@ import ( "net/http" au "github.com/docker/distribution/registry/client/auth" - "github.com/vmware/harbor/utils/registry/utils" + "github.com/vmware/harbor/utils" ) // Authorizer authorizes requests according to the schema diff --git a/utils/registry/registry.go b/utils/registry/registry.go index 05ec2c33e..49b2cd124 100644 --- a/utils/registry/registry.go +++ b/utils/registry/registry.go @@ -21,8 +21,8 @@ import ( "net/url" "strings" + "github.com/vmware/harbor/utils" registry_error "github.com/vmware/harbor/utils/registry/error" - "github.com/vmware/harbor/utils/registry/utils" ) // Registry holds information of a registry entity diff --git a/utils/registry/repository.go b/utils/registry/repository.go index c4f48e04a..04a3b6b61 100644 --- a/utils/registry/repository.go +++ b/utils/registry/repository.go @@ -30,8 +30,8 @@ import ( "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" + "github.com/vmware/harbor/utils" registry_error "github.com/vmware/harbor/utils/registry/error" - "github.com/vmware/harbor/utils/registry/utils" ) // Repository holds information of a repository entity diff --git a/utils/registry/utils/utils.go b/utils/registry/utils/utils.go deleted file mode 100644 index dc62c4c13..000000000 --- a/utils/registry/utils/utils.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (c) 2016 VMware, Inc. All Rights Reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - 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. -*/ - -package utils - -import ( - "net/url" - "strings" -) - -// FormatEndpoint formats endpoint -func FormatEndpoint(endpoint string) string { - endpoint = strings.TrimSpace(endpoint) - endpoint = strings.TrimRight(endpoint, "/") - if !strings.HasPrefix(endpoint, "http://") && - !strings.HasPrefix(endpoint, "https://") { - endpoint = "http://" + endpoint - } - - return endpoint -} - -// ParseEndpoint parses endpoint to a URL -func ParseEndpoint(endpoint string) (*url.URL, error) { - endpoint = FormatEndpoint(endpoint) - - u, err := url.Parse(endpoint) - if err != nil { - return nil, err - } - return u, nil -} diff --git a/utils/utils.go b/utils/utils.go index bc2b5a712..653e5409c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -16,9 +16,8 @@ package utils import ( + "net/url" "strings" - - "github.com/vmware/harbor/models" ) // Repository holds information about repository @@ -34,22 +33,25 @@ func (r *Repository) GetProject() string { return r.Name[0:strings.LastIndex(r.Name, "/")] } -// ProjectSorter holds an array of projects -type ProjectSorter struct { - Projects []models.Project +// FormatEndpoint formats endpoint +func FormatEndpoint(endpoint string) string { + endpoint = strings.TrimSpace(endpoint) + endpoint = strings.TrimRight(endpoint, "/") + if !strings.HasPrefix(endpoint, "http://") && + !strings.HasPrefix(endpoint, "https://") { + endpoint = "http://" + endpoint + } + + return endpoint } -// Len returns the length of array in ProjectSorter -func (ps *ProjectSorter) Len() int { - return len(ps.Projects) -} +// ParseEndpoint parses endpoint to a URL +func ParseEndpoint(endpoint string) (*url.URL, error) { + endpoint = FormatEndpoint(endpoint) -// Less defines the comparison rules of project -func (ps *ProjectSorter) Less(i, j int) bool { - return ps.Projects[i].Name < ps.Projects[j].Name -} - -// Swap swaps the position of i and j -func (ps *ProjectSorter) Swap(i, j int) { - ps.Projects[i], ps.Projects[j] = ps.Projects[j], ps.Projects[i] + u, err := url.Parse(endpoint) + if err != nil { + return nil, err + } + return u, nil }