mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-19 23:28:20 +01:00
Merge branch 'job-service' into new-ui-with-sync-image
This commit is contained in:
commit
91eacb895c
55
.travis.yml
55
.travis.yml
@ -1,3 +1,5 @@
|
|||||||
|
sudo: true
|
||||||
|
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
@ -5,10 +7,32 @@ go:
|
|||||||
|
|
||||||
go_import_path: github.com/vmware/harbor
|
go_import_path: github.com/vmware/harbor
|
||||||
|
|
||||||
#service:
|
services:
|
||||||
# - mysql
|
- docker
|
||||||
|
- mysql
|
||||||
|
|
||||||
env: DB_HOST=127.0.0.1 DB_PORT=3306 DB_USR=root DB_PWD=
|
dist: trusty
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- mysql-server-5.6
|
||||||
|
- mysql-client-core-5.6
|
||||||
|
- mysql-client-5.6
|
||||||
|
|
||||||
|
env:
|
||||||
|
DB_HOST: 127.0.0.1
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_USR: root
|
||||||
|
DB_PWD:
|
||||||
|
DOCKER_COMPOSE_VERSION: 1.7.1
|
||||||
|
HARBOR_ADMIN: admin
|
||||||
|
HARBOR_ADMIN_PASSWD: Harbor12345
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- ./tests/hostcfg.sh
|
||||||
|
- cd Deploy
|
||||||
|
- ./prepare
|
||||||
|
- cd ..
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- sudo apt-get update && sudo apt-get install -y libldap2-dev
|
- sudo apt-get update && sudo apt-get install -y libldap2-dev
|
||||||
@ -29,12 +53,29 @@ install:
|
|||||||
- go get -d github.com/go-sql-driver/mysql
|
- go get -d github.com/go-sql-driver/mysql
|
||||||
- go get github.com/golang/lint/golint
|
- go get github.com/golang/lint/golint
|
||||||
- go get github.com/GeertJohan/fgt
|
- go get github.com/GeertJohan/fgt
|
||||||
|
- sudo apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" docker-engine=1.11.1-0~trusty
|
||||||
|
- sudo rm /usr/local/bin/docker-compose
|
||||||
|
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
|
||||||
|
- chmod +x docker-compose
|
||||||
|
- sudo mv docker-compose /usr/local/bin
|
||||||
|
- go get github.com/dghubble/sling
|
||||||
|
- go get github.com/stretchr/testify
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
# create tables and load data
|
# create tables and load data
|
||||||
- mysql < ./Deploy/db/registry.sql -uroot --verbose
|
- mysql < ./Deploy/db/registry.sql -uroot --verbose
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- go list ./... | grep -v /vendor/ | xargs -L1 fgt golint
|
- go list ./... | grep -v 'tests' | grep -v /vendor/ | xargs -L1 fgt golint
|
||||||
- go list ./... | grep -v 'vendor' | xargs -L1 go vet
|
- go list ./... | grep -v 'tests' | grep -v 'vendor' | xargs -L1 go vet
|
||||||
- go list ./... | grep -v 'vendor' | xargs -L1 go test -v
|
- go list ./... | grep -v 'tests' | grep -v 'vendor' | xargs -L1 go test -v
|
||||||
|
|
||||||
|
- docker-compose -f Deploy/docker-compose.yml up -d
|
||||||
|
|
||||||
|
- docker ps
|
||||||
|
- go run tests/startuptest.go http://localhost/
|
||||||
|
- go run tests/userlogintest.go -name ${HARBOR_ADMIN} -passwd ${HARBOR_ADMIN_PASSWD}
|
||||||
|
|
||||||
|
|
||||||
|
# test for API
|
||||||
|
- go test -v ./tests/apitests
|
||||||
|
@ -33,7 +33,7 @@ type ProjectMemberAPI struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type memberReq struct {
|
type memberReq struct {
|
||||||
Username string `json:"user_name"`
|
Username string `json:"username"`
|
||||||
UserID int `json:"user_id"`
|
UserID int `json:"user_id"`
|
||||||
Roles []int `json:"roles"`
|
Roles []int `json:"roles"`
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ func (pma *ProjectMemberAPI) Get() {
|
|||||||
log.Errorf("Error occurred in GetUser, error: %v", err)
|
log.Errorf("Error occurred in GetUser, error: %v", err)
|
||||||
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||||
}
|
}
|
||||||
result["user_name"] = user.Username
|
result["username"] = user.Username
|
||||||
result["user_id"] = pma.memberID
|
result["user_id"] = pma.memberID
|
||||||
result["roles"] = roleList
|
result["roles"] = roleList
|
||||||
pma.Data["json"] = result
|
pma.Data["json"] = result
|
||||||
|
@ -14,8 +14,6 @@ import (
|
|||||||
// RepPolicyAPI handles /api/replicationPolicies /api/replicationPolicies/:id/enablement
|
// RepPolicyAPI handles /api/replicationPolicies /api/replicationPolicies/:id/enablement
|
||||||
type RepPolicyAPI struct {
|
type RepPolicyAPI struct {
|
||||||
BaseAPI
|
BaseAPI
|
||||||
policyID int64
|
|
||||||
policy *models.RepPolicy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare validates whether the user has system admin role
|
// Prepare validates whether the user has system admin role
|
||||||
@ -214,11 +212,11 @@ func (pa *RepPolicyAPI) UpdateEnablement() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pa.policy.Enabled == e.Enabled {
|
if policy.Enabled == e.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dao.UpdateRepPolicyEnablement(pa.policyID, e.Enabled); err != nil {
|
if err := dao.UpdateRepPolicyEnablement(id, e.Enabled); err != nil {
|
||||||
log.Errorf("Failed to update policy enablement in DB, error: %v", err)
|
log.Errorf("Failed to update policy enablement in DB, error: %v", err)
|
||||||
pa.RenderError(http.StatusInternalServerError, "Internal Error")
|
pa.RenderError(http.StatusInternalServerError, "Internal Error")
|
||||||
return
|
return
|
||||||
@ -226,18 +224,18 @@ func (pa *RepPolicyAPI) UpdateEnablement() {
|
|||||||
|
|
||||||
if e.Enabled == 1 {
|
if e.Enabled == 1 {
|
||||||
go func() {
|
go func() {
|
||||||
if err := TriggerReplication(pa.policyID, "", nil, models.RepOpTransfer); err != nil {
|
if err := TriggerReplication(id, "", nil, models.RepOpTransfer); err != nil {
|
||||||
log.Errorf("failed to trigger replication of %d: %v", pa.policyID, err)
|
log.Errorf("failed to trigger replication of %d: %v", id, err)
|
||||||
} else {
|
} else {
|
||||||
log.Infof("replication of %d triggered", pa.policyID)
|
log.Infof("replication of %d triggered", id)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
go func() {
|
go func() {
|
||||||
if err := postReplicationAction(pa.policyID, "stop"); err != nil {
|
if err := postReplicationAction(id, "stop"); err != nil {
|
||||||
log.Errorf("failed to stop replication of %d: %v", pa.policyID, err)
|
log.Errorf("failed to stop replication of %d: %v", id, err)
|
||||||
} else {
|
} else {
|
||||||
log.Infof("try to stop replication of %d", pa.policyID)
|
log.Infof("try to stop replication of %d", id)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ swagger: '2.0'
|
|||||||
info:
|
info:
|
||||||
title: Harbor API
|
title: Harbor API
|
||||||
description: These APIs provide services for manipulating Harbor project.
|
description: These APIs provide services for manipulating Harbor project.
|
||||||
version: "0.1.0"
|
version: "0.1.1"
|
||||||
# the domain of the service
|
# the domain of the service
|
||||||
host: localhost
|
host: localhost
|
||||||
# array of all schemes that your API supports
|
# array of all schemes that your API supports
|
||||||
@ -167,7 +167,7 @@ paths:
|
|||||||
- name: access_log
|
- name: access_log
|
||||||
in: body
|
in: body
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/AccessLog'
|
$ref: '#/definitions/AccessLogFilter'
|
||||||
description: Search results of access logs.
|
description: Search results of access logs.
|
||||||
tags:
|
tags:
|
||||||
- Products
|
- Products
|
||||||
@ -204,7 +204,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/Role'
|
$ref: '#/definitions/User'
|
||||||
400:
|
400:
|
||||||
description: Illegal format of provided ID value.
|
description: Illegal format of provided ID value.
|
||||||
401:
|
401:
|
||||||
@ -567,7 +567,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/Repository'
|
type: string
|
||||||
400:
|
400:
|
||||||
description: Invalid project ID.
|
description: Invalid project ID.
|
||||||
403:
|
403:
|
||||||
@ -719,12 +719,41 @@ definitions:
|
|||||||
description: Search results of the projects that matched the filter keywords.
|
description: Search results of the projects that matched the filter keywords.
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/Project'
|
$ref: '#/definitions/SearchProject'
|
||||||
repositories:
|
repositories:
|
||||||
description: Search results of the repositories that matched the filter keywords.
|
description: Search results of the repositories that matched the filter keywords.
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/Repository'
|
$ref: '#/definitions/SearchRepository'
|
||||||
|
SearchProject:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: The ID of project
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: The name of the project
|
||||||
|
public:
|
||||||
|
type: integer
|
||||||
|
format: int
|
||||||
|
description: The flag to indicate the publicity of the project (1 is public, 0 is non-public)
|
||||||
|
SearchRepository:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
repository_name:
|
||||||
|
type: string
|
||||||
|
description: The name of the repository
|
||||||
|
project_name:
|
||||||
|
type: string
|
||||||
|
description: The name of the project that the repository belongs to
|
||||||
|
project_id:
|
||||||
|
type: integer
|
||||||
|
description: The ID of the project that the repository belongs to
|
||||||
|
project_public:
|
||||||
|
type: integer
|
||||||
|
description: The flag to indicate the publicity of the project that the repository belongs to (1 is public, 0 is not)
|
||||||
Project:
|
Project:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -736,30 +765,39 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
description: The owner ID of the project always means the creator of the project.
|
description: The owner ID of the project always means the creator of the project.
|
||||||
project_name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
description: The name of the project.
|
description: The name of the project.
|
||||||
creation_time:
|
creation_time:
|
||||||
type: string
|
type: string
|
||||||
description: The creation time of the project.
|
description: The creation time of the project.
|
||||||
|
update_time:
|
||||||
|
type: string
|
||||||
|
description: The update time of the project.
|
||||||
deleted:
|
deleted:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
description: A deletion mark of the project.
|
description: A deletion mark of the project (1 means it's deleted, 0 is not)
|
||||||
user_id:
|
user_id:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
description: A relation field to the user table.
|
description: A relation field to the user table.
|
||||||
owner_name:
|
owner_name:
|
||||||
type: string
|
type: string
|
||||||
description: The owner name of tthe project always means the creator of the project.
|
description: The owner name of the project.
|
||||||
public:
|
public:
|
||||||
type: boolean
|
type: boolean
|
||||||
format: boolean
|
format: boolean
|
||||||
description: The public status of the project.
|
description: The public status of the project.
|
||||||
togglable:
|
togglable:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: Correspond to the UI about showing the public status of the project.
|
description: Correspond to the UI about whether the project's publicity is updatable (for UI)
|
||||||
|
current_user_role_id:
|
||||||
|
type: integer
|
||||||
|
description: The role ID of the current user who triggered the API (for UI)
|
||||||
|
repo_count:
|
||||||
|
type: integer
|
||||||
|
description: The number of the repositories under this project.
|
||||||
Repository:
|
Repository:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -794,6 +832,7 @@ definitions:
|
|||||||
user_id:
|
user_id:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
|
description: The ID of the user.
|
||||||
username:
|
username:
|
||||||
type: string
|
type: string
|
||||||
email:
|
email:
|
||||||
@ -816,7 +855,7 @@ definitions:
|
|||||||
new_password:
|
new_password:
|
||||||
type: string
|
type: string
|
||||||
description: New password for marking as to be updated.
|
description: New password for marking as to be updated.
|
||||||
AccessLog:
|
AccessLogFilter:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
username:
|
username:
|
||||||
@ -825,14 +864,32 @@ definitions:
|
|||||||
keywords:
|
keywords:
|
||||||
type: string
|
type: string
|
||||||
description: Operation name specified when project created.
|
description: Operation name specified when project created.
|
||||||
beginTimestamp:
|
begin_timestamp:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int64
|
||||||
description: Begin timestamp for querying access logs.
|
description: Begin timestamp for querying access logs.
|
||||||
endTimestamp:
|
end_timestamp:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int64
|
||||||
description: End timestamp for querying accessl logs.
|
description: End timestamp for querying accessl logs.
|
||||||
|
AccessLog:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
log_id:
|
||||||
|
type: integer
|
||||||
|
description: The ID of the log entry.
|
||||||
|
repo_name:
|
||||||
|
type: string
|
||||||
|
description: Name of the repository in this log entry.
|
||||||
|
repo_tag:
|
||||||
|
type: string
|
||||||
|
description: Tag of the repository in this log entry.
|
||||||
|
operation:
|
||||||
|
type: string
|
||||||
|
description: The operation against the repository in this log entry.
|
||||||
|
op_time:
|
||||||
|
type: time
|
||||||
|
description: The time when this operation is triggered.
|
||||||
Role:
|
Role:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -855,7 +912,7 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
description: Role ID for updating project role member.
|
description: Role ID for updating project role member.
|
||||||
user_name:
|
username:
|
||||||
type: string
|
type: string
|
||||||
description: Username relevant to a project role member.
|
description: Username relevant to a project role member.
|
||||||
TopRepo:
|
TopRepo:
|
||||||
|
@ -21,19 +21,18 @@ import (
|
|||||||
|
|
||||||
// AccessLog holds information about logs which are used to record the actions that user take to the resourses.
|
// AccessLog holds information about logs which are used to record the actions that user take to the resourses.
|
||||||
type AccessLog struct {
|
type AccessLog struct {
|
||||||
LogID int `orm:"pk;column(log_id)" json:"LogId"`
|
LogID int `orm:"column(log_id)" json:"log_id"`
|
||||||
UserID int `orm:"column(user_id)" json:"UserId"`
|
UserID int `orm:"column(user_id)" json:"user_id"`
|
||||||
ProjectID int64 `orm:"column(project_id)" json:"ProjectId"`
|
ProjectID int64 `orm:"column(project_id)" json:"project_id"`
|
||||||
RepoName string `orm:"column(repo_name)"`
|
RepoName string `orm:"column(repo_name)" json:"repo_name"`
|
||||||
RepoTag string `orm:"column(repo_tag)"`
|
RepoTag string `orm:"column(repo_tag)" json:"repo_tag"`
|
||||||
GUID string `orm:"column(GUID)" json:"Guid"`
|
GUID string `orm:"column(GUID)" json:"guid"`
|
||||||
Operation string `orm:"column(operation)"`
|
Operation string `orm:"column(operation)" json:"operation"`
|
||||||
OpTime time.Time `orm:"column(op_time)"`
|
OpTime time.Time `orm:"column(op_time)" json:"op_time"`
|
||||||
Username string
|
Username string `json:"username"`
|
||||||
Keywords string
|
Keywords string `json:"keywords"`
|
||||||
|
|
||||||
BeginTime time.Time
|
BeginTime time.Time
|
||||||
BeginTimestamp int64
|
BeginTimestamp int64 `json:"begin_timestamp"`
|
||||||
EndTime time.Time
|
EndTime time.Time
|
||||||
EndTimestamp int64
|
EndTimestamp int64 `json:"end_timestamp"`
|
||||||
}
|
}
|
||||||
|
@ -21,19 +21,19 @@ import (
|
|||||||
|
|
||||||
// Project holds the details of a project.
|
// Project holds the details of a project.
|
||||||
type Project struct {
|
type Project struct {
|
||||||
ProjectID int64 `orm:"pk;column(project_id)" json:"ProjectId"`
|
ProjectID int64 `orm:"column(project_id)" json:"project_id"`
|
||||||
OwnerID int `orm:"column(owner_id)" json:"OwnerId"`
|
OwnerID int `orm:"column(owner_id)" json:"owner_id"`
|
||||||
Name string `orm:"column(name)"`
|
Name string `orm:"column(name)" json:"name"`
|
||||||
CreationTime time.Time `orm:"column(creation_time)"`
|
CreationTime time.Time `orm:"column(creation_time)" json:"creation_time"`
|
||||||
CreationTimeStr string
|
CreationTimeStr string `json:"creation_time_str"`
|
||||||
Deleted int `orm:"column(deleted)"`
|
Deleted int `orm:"column(deleted)" json:"deleted"`
|
||||||
UserID int `json:"UserId"`
|
//UserID int `json:"UserId"`
|
||||||
OwnerName string
|
OwnerName string `json:"owner_name"`
|
||||||
Public int `orm:"column(public)"`
|
Public int `orm:"column(public)" json:"public"`
|
||||||
//This field does not have correspondent column in DB, this is just for UI to disable button
|
//This field does not have correspondent column in DB, this is just for UI to disable button
|
||||||
Togglable bool
|
Togglable bool
|
||||||
|
|
||||||
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
||||||
Role int `json:"role_id"`
|
Role int `json:"current_user_role_id"`
|
||||||
RepoCount int `json:"repo_count"`
|
RepoCount int `json:"repo_count"`
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,19 @@ import (
|
|||||||
|
|
||||||
// User holds the details of a user.
|
// User holds the details of a user.
|
||||||
type User struct {
|
type User struct {
|
||||||
UserID int `orm:"pk;column(user_id)" json:"UserId"`
|
UserID int `orm:"column(user_id)" json:"user_id"`
|
||||||
Username string `orm:"column(username)" json:"username"`
|
Username string `orm:"column(username)" json:"username"`
|
||||||
Email string `orm:"column(email)" json:"email"`
|
Email string `orm:"column(email)" json:"email"`
|
||||||
Password string `orm:"column(password)" json:"password"`
|
Password string `orm:"column(password)" json:"password"`
|
||||||
Realname string `orm:"column(realname)" json:"realname"`
|
Realname string `orm:"column(realname)" json:"realname"`
|
||||||
Comment string `orm:"column(comment)" json:"comment"`
|
Comment string `orm:"column(comment)" json:"comment"`
|
||||||
Deleted int `orm:"column(deleted)"`
|
Deleted int `orm:"column(deleted)" json:"deleted"`
|
||||||
Rolename string
|
Rolename string `json:"role_name"`
|
||||||
RoleID int `json:"RoleId"`
|
RoleID int `json:"role_id"`
|
||||||
RoleList []*Role `orm:"rel(m2m)"`
|
// RoleList []Role `json:"role_list"`
|
||||||
HasAdminRole int `orm:"column(sysadmin_flag)"`
|
HasAdminRole int `orm:"column(sysadmin_flag)" json:"has_admin_role"`
|
||||||
ResetUUID string `orm:"column(reset_uuid)" json:"ResetUuid"`
|
ResetUUID string `orm:"column(reset_uuid)" json:"reset_uuid"`
|
||||||
Salt string `orm:"column(salt)"`
|
Salt string `orm:"column(salt)"`
|
||||||
|
|
||||||
CreationTime time.Time `orm:"creation_time" json:"creation_time"`
|
CreationTime time.Time `orm:"creation_time" json:"creation_time"`
|
||||||
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
.footer {
|
.footer {
|
||||||
margin-top: 60px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/* Set the fixed height of the footer here */
|
/* Set the fixed height of the footer here */
|
||||||
height: 60px;
|
height: 60px;
|
||||||
|
@ -24,7 +24,7 @@ jQuery(function(){
|
|||||||
error: function(jqXhr){
|
error: function(jqXhr){
|
||||||
if(jqXhr && jqXhr.status == 401){
|
if(jqXhr && jqXhr.status == 401){
|
||||||
document.location = "/signIn";
|
document.location = "/signIn";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).exec();
|
}).exec();
|
||||||
|
|
||||||
@ -36,12 +36,12 @@ jQuery(function(){
|
|||||||
function bindEnterKey(){
|
function bindEnterKey(){
|
||||||
$(document).on("keydown", function(e){
|
$(document).on("keydown", function(e){
|
||||||
if(e.keyCode == 13){
|
if(e.keyCode == 13){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if($("#txtCommonSearch").is(":focus")){
|
if($("#txtCommonSearch").is(":focus")){
|
||||||
document.location = "/search?q=" + $("#txtCommonSearch").val();
|
document.location = "/search?q=" + $("#txtCommonSearch").val();
|
||||||
}else{
|
}else{
|
||||||
$("#btnSubmit").trigger("click");
|
$("#btnSubmit").trigger("click");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -61,35 +61,35 @@ jQuery(function(){
|
|||||||
type: "put",
|
type: "put",
|
||||||
data: {"old_password": oldPassword, "new_password" : password},
|
data: {"old_password": oldPassword, "new_password" : password},
|
||||||
beforeSend: function(e){
|
beforeSend: function(e){
|
||||||
unbindEnterKey();
|
unbindEnterKey();
|
||||||
$("h1").append(spinner.el);
|
$("h1").append(spinner.el);
|
||||||
$("#btnSubmit").prop("disabled", true);
|
$("#btnSubmit").prop("disabled", true);
|
||||||
},
|
},
|
||||||
complete: function(xhr, status){
|
complete: function(xhr, status){
|
||||||
spinner.stop();
|
spinner.stop();
|
||||||
$("#btnSubmit").prop("disabled", false);
|
$("#btnSubmit").prop("disabled", false);
|
||||||
if(xhr && xhr.status == 200){
|
if(xhr && xhr.status == 200){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_change_password"),
|
"title": i18n.getMessage("title_change_password"),
|
||||||
"content": i18n.getMessage("change_password_successfully"),
|
"content": i18n.getMessage("change_password_successfully"),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(jqXhr, status, error){
|
error: function(jqXhr, status, error){
|
||||||
if(jqXhr && jqXhr.responseText.length){
|
if(jqXhr && jqXhr.responseText.length){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_change_password"),
|
"title": i18n.getMessage("title_change_password"),
|
||||||
"content": i18n.getMessage(jqXhr.responseText),
|
"content": i18n.getMessage(jqXhr.responseText),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
bindEnterKey();
|
bindEnterKey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).exec();
|
}).exec();
|
||||||
|
@ -12,8 +12,9 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var AjaxUtil = function(params){
|
var AjaxUtil = function(params){
|
||||||
|
|
||||||
this.url = params.url;
|
this.url = params.url;
|
||||||
this.data = params.data;
|
this.data = params.data;
|
||||||
this.dataRaw = params.dataRaw;
|
this.dataRaw = params.dataRaw;
|
||||||
@ -31,39 +32,39 @@ AjaxUtil.prototype.exec = function(){
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
url: self.url,
|
url: self.url,
|
||||||
contentType: (self.dataRaw ? "application/x-www-form-urlencoded; charset=UTF-8" : "application/json; charset=utf-8"),
|
contentType: (self.dataRaw ? "application/x-www-form-urlencoded; charset=UTF-8" : "application/json; charset=utf-8"),
|
||||||
data: JSON.stringify(self.data) || self.dataRaw,
|
data: JSON.stringify(self.data) || self.dataRaw,
|
||||||
type: self.type,
|
type: self.type,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data, status, xhr){
|
success: function(data, status, xhr){
|
||||||
if(self.success != null){
|
if(self.success != null){
|
||||||
self.success(data, status, xhr);
|
self.success(data, status, xhr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
complete: function(jqXhr, status) {
|
complete: function(jqXhr, status) {
|
||||||
if(self.complete != null){
|
if(self.complete != null){
|
||||||
self.complete(jqXhr, status);
|
self.complete(jqXhr, status);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(jqXhr){
|
error: function(jqXhr){
|
||||||
if(self.error != null){
|
if(self.error != null){
|
||||||
self.error(jqXhr);
|
self.error(jqXhr);
|
||||||
}else{
|
}else{
|
||||||
var errorMessage = self.errors[jqXhr.status] || jqXhr.responseText;
|
var errorMessage = self.errors[jqXhr.status] || jqXhr.responseText;
|
||||||
if(jqXhr.status == 401){
|
if(jqXhr.status == 401){
|
||||||
var lastUri = location.pathname + location.search;
|
var lastUri = location.pathname + location.search;
|
||||||
if(lastUri != ""){
|
if(lastUri != ""){
|
||||||
document.location = "/signIn?uri=" + encodeURIComponent(lastUri);
|
document.location = "/signIn?uri=" + encodeURIComponent(lastUri);
|
||||||
}else{
|
}else{
|
||||||
document.location = "/signIn";
|
document.location = "/signIn";
|
||||||
|
}
|
||||||
|
}else if($.trim(errorMessage).length > 0){
|
||||||
|
$("#dlgModal").dialogModal({"title": i18n.getMessage("operation_failed"), "content": errorMessage});
|
||||||
}
|
}
|
||||||
}else if($.trim(errorMessage).length > 0){
|
|
||||||
$("#dlgModal").dialogModal({"title": i18n.getMessage("operation_failed"), "content": errorMessage});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var SUPPORT_LANGUAGES = {
|
var SUPPORT_LANGUAGES = {
|
||||||
@ -134,7 +135,7 @@ jQuery(function(){
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
$("#dlgLabel", self).text(settings.title);
|
$("#dlgLabel", self).text(settings.title);
|
||||||
|
|
||||||
if(options.text){
|
if(options.text){
|
||||||
$("#dlgBody", self).html(settings.content);
|
$("#dlgBody", self).html(settings.content);
|
||||||
}else if(typeof settings.content == "object"){
|
}else if(typeof settings.content == "object"){
|
||||||
@ -142,9 +143,9 @@ jQuery(function(){
|
|||||||
var lines = ['<form class="form-horizontal">'];
|
var lines = ['<form class="form-horizontal">'];
|
||||||
for(var item in settings.content){
|
for(var item in settings.content){
|
||||||
lines.push('<div class="form-group">'+
|
lines.push('<div class="form-group">'+
|
||||||
'<label class="col-sm-2 control-label">'+ item +'</label>' +
|
'<label class="col-sm-2 control-label">'+ item +'</label>' +
|
||||||
'<div class="col-sm-10"><p class="form-control-static">' + settings.content[item] + '</p></div>' +
|
'<div class="col-sm-10"><p class="form-control-static">' + settings.content[item] + '</p></div>' +
|
||||||
'</div>');
|
'</div>');
|
||||||
}
|
}
|
||||||
lines.push('</form>');
|
lines.push('</form>');
|
||||||
$("#dlgBody", self).html(lines.join(""));
|
$("#dlgBody", self).html(lines.join(""));
|
||||||
@ -154,8 +155,13 @@ jQuery(function(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(settings.callback != null){
|
if(settings.callback != null){
|
||||||
$("#dlgConfirm").on("click", function(){
|
var hasEntered = false;
|
||||||
settings.callback();
|
$("#dlgConfirm").on("click", function(e){
|
||||||
|
if(!hasEntered) {
|
||||||
|
hasEntered = true;
|
||||||
|
settings.callback();
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$(self).modal('show');
|
$(self).modal('show');
|
||||||
|
@ -13,26 +13,26 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
jQuery(function(){
|
jQuery(function(){
|
||||||
|
|
||||||
$("#divErrMsg").css({"display": "none"});
|
$("#divErrMsg").css({"display": "none"});
|
||||||
|
|
||||||
validateOptions.Items = ["#EmailF"];
|
validateOptions.Items = ["#EmailF"];
|
||||||
function bindEnterKey(){
|
function bindEnterKey(){
|
||||||
$(document).on("keydown", function(e){
|
$(document).on("keydown", function(e){
|
||||||
if(e.keyCode == 13){
|
if(e.keyCode == 13){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if($("#txtCommonSearch").is(":focus")){
|
if($("#txtCommonSearch").is(":focus")){
|
||||||
document.location = "/search?q=" + $("#txtCommonSearch").val();
|
document.location = "/search?q=" + $("#txtCommonSearch").val();
|
||||||
}else{
|
}else{
|
||||||
$("#btnSubmit").trigger("click");
|
$("#btnSubmit").trigger("click");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function unbindEnterKey(){
|
function unbindEnterKey(){
|
||||||
$(document).off("keydown");
|
$(document).off("keydown");
|
||||||
}
|
}
|
||||||
bindEnterKey();
|
bindEnterKey();
|
||||||
var spinner = new Spinner({scale:1}).spin();
|
var spinner = new Spinner({scale:1}).spin();
|
||||||
|
|
||||||
$("#btnSubmit").on("click", function(){
|
$("#btnSubmit").on("click", function(){
|
||||||
@ -44,20 +44,20 @@ jQuery(function(){
|
|||||||
"type": "get",
|
"type": "get",
|
||||||
"data": {"username": username, "email": email},
|
"data": {"username": username, "email": email},
|
||||||
"beforeSend": function(e){
|
"beforeSend": function(e){
|
||||||
unbindEnterKey();
|
unbindEnterKey();
|
||||||
$("h1").append(spinner.el);
|
$("h1").append(spinner.el);
|
||||||
$("#btnSubmit").prop("disabled", true);
|
$("#btnSubmit").prop("disabled", true);
|
||||||
},
|
},
|
||||||
"success": function(data, status, xhr){
|
"success": function(data, status, xhr){
|
||||||
if(xhr && xhr.status == 200){
|
if(xhr && xhr.status == 200){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_forgot_password"),
|
"title": i18n.getMessage("title_forgot_password"),
|
||||||
"content": i18n.getMessage("email_has_been_sent"),
|
"content": i18n.getMessage("email_has_been_sent"),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
document.location="/";
|
document.location="/";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -68,14 +68,14 @@ jQuery(function(){
|
|||||||
"error": function(jqXhr, status, error){
|
"error": function(jqXhr, status, error){
|
||||||
if(jqXhr){
|
if(jqXhr){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_forgot_password"),
|
"title": i18n.getMessage("title_forgot_password"),
|
||||||
"content": i18n.getMessage(jqXhr.responseText),
|
"content": i18n.getMessage(jqXhr.responseText),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
bindEnterKey();
|
bindEnterKey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -13,20 +13,20 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
jQuery(function(){
|
jQuery(function(){
|
||||||
$("#btnSignUp").css({"visibility": "visible"});
|
$("#btnSignUp").css({"visibility": "visible"});
|
||||||
|
|
||||||
$(document).on("keydown", function(e){
|
$(document).on("keydown", function(e){
|
||||||
if(e.keyCode == 13){
|
if(e.keyCode == 13){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if($("#txtCommonSearch").is(":focus")){
|
if($("#txtCommonSearch").is(":focus")){
|
||||||
document.location = "/search?q=" + $("#txtCommonSearch").val();
|
document.location = "/search?q=" + $("#txtCommonSearch").val();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$("#btnSignIn").on("click", function(){
|
$("#btnSignIn").on("click", function(){
|
||||||
document.location = "/signIn";
|
document.location = "/signIn";
|
||||||
});
|
});
|
||||||
$("#btnSignUp").on("click", function(){
|
$("#btnSignUp").on("click", function(){
|
||||||
document.location = "/register";
|
document.location = "/register";
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -23,461 +23,451 @@ jQuery(function(){
|
|||||||
if(jqXhr.status == 403){
|
if(jqXhr.status == 403){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).exec()
|
}).exec()
|
||||||
).then(function(){
|
).then(function(){
|
||||||
noNeedToLoginCallback();
|
noNeedToLoginCallback();
|
||||||
needToLoginCallback();
|
needToLoginCallback();
|
||||||
}).fail(function(){
|
}).fail(function(){
|
||||||
noNeedToLoginCallback();
|
noNeedToLoginCallback();
|
||||||
});
|
});
|
||||||
|
|
||||||
function noNeedToLoginCallback(){
|
|
||||||
|
|
||||||
$("#tabItemDetail a:first").tab("show");
|
|
||||||
$("#btnFilterOption button:first").addClass("active");
|
|
||||||
$("#divErrMsg").hide();
|
|
||||||
|
|
||||||
if($("#public").val() == 1){
|
|
||||||
$("#tabItemDetail li:eq(1)").hide();
|
|
||||||
$("#tabItemDetail li:eq(2)").hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
listRepo($("#repoName").val());
|
|
||||||
|
|
||||||
function listRepo(repoName){
|
|
||||||
|
|
||||||
|
function noNeedToLoginCallback(){
|
||||||
|
|
||||||
|
$("#tabItemDetail a:first").tab("show");
|
||||||
|
$("#btnFilterOption button:first").addClass("active");
|
||||||
$("#divErrMsg").hide();
|
$("#divErrMsg").hide();
|
||||||
|
|
||||||
|
if($("#public").val() == 1){
|
||||||
|
$("#tabItemDetail li:eq(1)").hide();
|
||||||
|
$("#tabItemDetail li:eq(2)").hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
listRepo($("#repoName").val());
|
||||||
|
|
||||||
|
function listRepo(repoName){
|
||||||
|
|
||||||
|
$("#divErrMsg").hide();
|
||||||
|
|
||||||
new AjaxUtil({
|
new AjaxUtil({
|
||||||
url: "/api/repositories?project_id=" + $("#projectId").val() + "&q=" + repoName,
|
url: "/api/repositories?project_id=" + $("#projectId").val() + "&q=" + repoName,
|
||||||
type: "get",
|
type: "get",
|
||||||
success: function(data, status, xhr){
|
success: function(data, status, xhr){
|
||||||
if(xhr && xhr.status == 200){
|
if(xhr && xhr.status == 200){
|
||||||
$("#accordionRepo").children().remove();
|
$("#accordionRepo").children().remove();
|
||||||
if(data == null){
|
if(data == null){
|
||||||
$("#divErrMsg").show();
|
$("#divErrMsg").show();
|
||||||
$("#divErrMsg center").html(i18n.getMessage("no_repo_exists"));
|
$("#divErrMsg center").html(i18n.getMessage("no_repo_exists"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.each(data, function(i, e){
|
$.each(data, function(i, e){
|
||||||
var targetId = e.replace(/\//g, "------").replace(/\./g, "---");
|
var targetId = e.replace(/\//g, "------").replace(/\./g, "---");
|
||||||
var row = '<div class="panel panel-default" targetId="' + targetId + '">' +
|
var row = '<div class="panel panel-default" targetId="' + targetId + '">' +
|
||||||
'<div class="panel-heading" role="tab" id="heading' + i + '"+ >' +
|
'<div class="panel-heading" role="tab" id="heading' + i + '"+ >' +
|
||||||
'<h4 class="panel-title">' +
|
'<h4 class="panel-title">' +
|
||||||
'<a data-toggle="collapse" data-parent="#accordion" href="#collapse'+ i + '" aria-expanded="true" aria-controls="collapse' + i + '">' +
|
'<a data-toggle="collapse" data-parent="#accordion" href="#collapse'+ i + '" aria-expanded="true" aria-controls="collapse' + i + '">' +
|
||||||
'<span class="list-group-item-heading"> <span class="glyphicon glyphicon-book blue"></span> ' + e + ' </span>' +
|
'<span class="list-group-item-heading"> <span class="glyphicon glyphicon-book blue"></span> ' + e + ' </span>' +
|
||||||
'</a>' +
|
'</a>' +
|
||||||
'</h4>' +
|
'</h4>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="collapse' + i + '" targetId="' + targetId + '" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading' + i + '">' +
|
'<div id="collapse' + i + '" targetId="' + targetId + '" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading' + i + '">' +
|
||||||
'<div class="panel-body" id="' + targetId + '">' +
|
'<div class="panel-body" id="' + targetId + '">' +
|
||||||
'<div class="table-responsive" style="height: auto;">' +
|
'<div class="table-responsive" style="height: auto;">' +
|
||||||
'<table class="table table-striped table-bordered table-condensed">' +
|
'<table class="table table-striped table-bordered table-condensed">' +
|
||||||
'<thead>' +
|
'<thead>' +
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<th class="st-sort-ascent" st-sort="name" st-sort-default=""><span class="glyphicon glyphicon-tag blue"></span> ' + i18n.getMessage("tag")+ ' </th>' +
|
'<th class="st-sort-ascent" st-sort="name" st-sort-default=""><span class="glyphicon glyphicon-tag blue"></span> ' + i18n.getMessage("tag")+ ' </th>' +
|
||||||
'<th class="st-sort-ascent" st-sort="name" st-sort-default=""><span class="glyphicon glyphicon-tag blue"></span> ' + i18n.getMessage("pull_command") + ' </th>' +
|
'<th class="st-sort-ascent" st-sort="name" st-sort-default=""><span class="glyphicon glyphicon-tag blue"></span> ' + i18n.getMessage("pull_command") + ' </th>' +
|
||||||
'</tr>' +
|
'</tr>' +
|
||||||
'</thead>' +
|
'</thead>' +
|
||||||
'<tbody>' +
|
'<tbody>' +
|
||||||
'</tbody>' +
|
'</tbody>' +
|
||||||
'</table>'
|
'</table>'
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
$("#accordionRepo").append(row);
|
$("#accordionRepo").append(row);
|
||||||
});
|
});
|
||||||
if(repoName != ""){
|
if(repoName != ""){
|
||||||
$("#txtRepoName").val(repoName);
|
$("#txtRepoName").val(repoName);
|
||||||
$("#accordionRepo #heading0 a").trigger("click");
|
$("#accordionRepo #heading0 a").trigger("click");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}).exec();
|
|
||||||
}
|
|
||||||
$("#btnSearchRepo").on("click", function(){
|
|
||||||
listRepo($.trim($("#txtRepoName").val()));
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#accordionRepo').on('show.bs.collapse', function (e) {
|
|
||||||
$('#accordionRepo .in').collapse('hide');
|
|
||||||
var targetId = $(e.target).attr("targetId");
|
|
||||||
var repoName = targetId.replace(/[-]{6}/g, "/").replace(/[-]{3}/g, '.');
|
|
||||||
new AjaxUtil({
|
|
||||||
url: "/api/repositories/tags?repo_name=" + repoName,
|
|
||||||
type: "get",
|
|
||||||
success: function(data, status, xhr){
|
|
||||||
$('#' + targetId +' table tbody tr').remove();
|
|
||||||
var row = [];
|
|
||||||
for(var i in data){
|
|
||||||
var tagName = data[i];
|
|
||||||
row.push('<tr><td><a href="#" imageId="' + tagName + '" repoName="' + repoName + '">' + tagName + '</a></td><td><input type="text" style="width:100%" readonly value=" docker pull '+ $("#harborRegUrl").val() +'/'+ repoName + ':' + tagName +'"></td></tr>');
|
|
||||||
}
|
|
||||||
$('#' + targetId +' table tbody').append(row.join(""));
|
|
||||||
$('#' + targetId +' table tbody tr a').on("click", function(e){
|
|
||||||
var imageId = $(this).attr("imageId");
|
|
||||||
var repoName = $(this).attr("repoName");
|
|
||||||
new AjaxUtil({
|
|
||||||
url: "/api/repositories/manifests?repo_name=" + repoName + "&tag=" + imageId,
|
|
||||||
type: "get",
|
|
||||||
success: function(data, status, xhr){
|
|
||||||
if(data){
|
|
||||||
for(var i in data){
|
|
||||||
if(data[i] == ""){
|
|
||||||
data[i] = "N/A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data.Created = moment(new Date(data.Created)).format("YYYY-MM-DD HH:mm:ss");
|
|
||||||
|
|
||||||
$("#dlgModal").dialogModal({"title": i18n.getMessage("image_details"), "content": data});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).exec();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).exec();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function needToLoginCallback(){
|
|
||||||
|
|
||||||
var hasAuthorization = false;
|
|
||||||
|
|
||||||
$.when(
|
|
||||||
new AjaxUtil({
|
|
||||||
url: "/api/projects/" + $("#projectId").val() + "/members/current",
|
|
||||||
type: "get",
|
|
||||||
success: function(data, status, xhr){
|
|
||||||
if(xhr && xhr.status == 200 && data.roles != null && data.roles.length > 0){
|
|
||||||
hasAuthorization = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).exec())
|
|
||||||
.done(function(){
|
|
||||||
|
|
||||||
if(!hasAuthorization) return false;
|
|
||||||
|
|
||||||
$("#tabItemDetail a:eq(1)").css({"visibility": "visible"});
|
|
||||||
$("#tabItemDetail a:eq(2)").css({"visibility": "visible"});
|
|
||||||
|
|
||||||
$(".glyphicon .glyphicon-pencil", "#tblUser").on("click", function(e){
|
|
||||||
$("#txtUserName").hide();
|
|
||||||
$("#lblUserName").show();
|
|
||||||
$("#dlgUserTitle").text(i18n.getMessage("edit_members"));
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#btnAddUser").on("click", function(){
|
|
||||||
$("#operationType").val("add");
|
|
||||||
$("#spnSearch").show();
|
|
||||||
$("#txtUserName").prop("disabled", false)
|
|
||||||
$("#txtUserName").val("");
|
|
||||||
$("#lstRole input[name=chooseRole]:radio").prop("checked", false);
|
|
||||||
$("#dlgUserTitle").text(i18n.getMessage("add_members"));
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#btnSave").on("click", function(){
|
|
||||||
|
|
||||||
var username = $("#txtUserName").val();
|
|
||||||
if($.trim(username).length == 0){
|
|
||||||
$("#dlgModal").dialogModal({"title": i18n.getMessage("add_member_failed"), "content": i18n.getMessage("please_input_username")});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var projectId = $("#projectId").val();
|
|
||||||
var operationType = $("#operationType").val();
|
|
||||||
var userId = $("#editUserId").val();
|
|
||||||
|
|
||||||
var checkedRole = $("#lstRole input[name='chooseRole']:checked")
|
|
||||||
if(checkedRole.length == 0){
|
|
||||||
$("#dlgModal").dialogModal({"title": i18n.getMessage("add_member_failed"), "content": i18n.getMessage("please_assign_a_role_to_user")});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var checkedRoleItemList = [];
|
|
||||||
$.each(checkedRole, function(i, e){
|
|
||||||
checkedRoleItemList.push(new Number($(this).val()));
|
|
||||||
});
|
|
||||||
|
|
||||||
var ajaxOpts = {};
|
|
||||||
if(operationType == "add"){
|
|
||||||
ajaxOpts.url = "/api/projects/" + projectId + "/members/";
|
|
||||||
ajaxOpts.type = "post";
|
|
||||||
ajaxOpts.data = {"roles" : checkedRoleItemList, "user_name": username};
|
|
||||||
}else if(operationType == "edit"){
|
|
||||||
ajaxOpts.url = "/api/projects/" + projectId + "/members/" + userId;
|
|
||||||
ajaxOpts.type = "put";
|
|
||||||
ajaxOpts.data = {"roles" : checkedRoleItemList};
|
|
||||||
}
|
|
||||||
|
|
||||||
new AjaxUtil({
|
|
||||||
url: ajaxOpts.url,
|
|
||||||
data: ajaxOpts.data,
|
|
||||||
type: ajaxOpts.type,
|
|
||||||
complete: function(jqXhr, status){
|
|
||||||
if(jqXhr && jqXhr.status == 200){
|
|
||||||
$("#btnCancel").trigger("click");
|
|
||||||
listUser(null);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
404: i18n.getMessage("user_id_does_not_exist"),
|
|
||||||
409: i18n.getMessage("user_id_exists"),
|
|
||||||
403: i18n.getMessage("insufficient_privileges")
|
|
||||||
}
|
|
||||||
}).exec();
|
|
||||||
});
|
|
||||||
|
|
||||||
var name_mapping = {
|
|
||||||
"projectAdmin": "Project Admin",
|
|
||||||
"developer": "Developer",
|
|
||||||
"guest": "Guest"
|
|
||||||
}
|
|
||||||
|
|
||||||
function listUserByProjectCallback(userList){
|
|
||||||
var loginedUserId = $("#userId").val();
|
|
||||||
var loginedUserRoleId = $("#roleId").val();
|
|
||||||
var ownerId = $("#ownerId").val();
|
|
||||||
|
|
||||||
$("#tblUser tbody tr").remove();
|
|
||||||
for(var i = 0; i < userList.length; ){
|
|
||||||
|
|
||||||
var userId = userList[i].UserId;
|
|
||||||
var roleId = userList[i].RoleId;
|
|
||||||
var username = userList[i].username;
|
|
||||||
var roleNameList = [];
|
|
||||||
|
|
||||||
for(var j = i; j < userList.length; i++, j++){
|
|
||||||
if(userList[j].UserId == userId){
|
|
||||||
roleNameList.push(name_mapping[userList[j].Rolename]);
|
|
||||||
}else{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var row = '<tr>' +
|
|
||||||
'<td>' + username + '</td>' +
|
|
||||||
'<td>' + roleNameList.join(",") + '</td>' +
|
|
||||||
'<td>';
|
|
||||||
var isShowOperations = true;
|
|
||||||
if(loginedUserRoleId >= 3 /*role: developer guest*/){
|
|
||||||
isShowOperations = false;
|
|
||||||
}else if(ownerId == userId){
|
|
||||||
isShowOperations = false;
|
|
||||||
}else if (loginedUserId == userId){
|
|
||||||
isShowOperations = false;
|
|
||||||
}
|
|
||||||
if(isShowOperations){
|
|
||||||
row += '<a href="#" userid="' + userId + '" class="glyphicon glyphicon-pencil" data-toggle="modal" data-target="#dlgUser"></a> ' +
|
|
||||||
'<a href="#" userid="' + userId + '" roleid="' + roleId + '" class="glyphicon glyphicon-trash"></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
row += '</td></tr>';
|
|
||||||
$("#tblUser tbody").append(row);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function searchAccessLogCallback(LogList){
|
|
||||||
$("#tabOperationLog tbody tr").remove();
|
|
||||||
$.each(LogList || [], function(i, e){
|
|
||||||
$("#tabOperationLog tbody").append(
|
|
||||||
'<tr>' +
|
|
||||||
'<td>' + e.Username + '</td>' +
|
|
||||||
'<td>' + e.RepoName + '</td>' +
|
|
||||||
'<td>' + e.RepoTag + '</td>' +
|
|
||||||
'<td>' + e.Operation + '</td>' +
|
|
||||||
'<td>' + moment(new Date(e.OpTime)).format("YYYY-MM-DD HH:mm:ss") + '</td>' +
|
|
||||||
'</tr>');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getUserRoleCallback(userId){
|
|
||||||
new AjaxUtil({
|
|
||||||
url: "/api/projects/" + $("#projectId").val() + "/members/" + userId,
|
|
||||||
type: "get",
|
|
||||||
success: function(data, status, xhr){
|
|
||||||
var user = data;
|
|
||||||
$("#operationType").val("edit");
|
|
||||||
$("#editUserId").val(user.user_id);
|
|
||||||
$("#spnSearch").hide();
|
|
||||||
$("#txtUserName").val(user.user_name);
|
|
||||||
$("#txtUserName").prop("disabled", true);
|
|
||||||
$("#btnSave").removeClass("disabled");
|
|
||||||
$("#dlgUserTitle").text(i18n.getMessage("edit_members"));
|
|
||||||
$("#lstRole input[name=chooseRole]:radio").not('[value=' + user.role_id + ']').prop("checked", false)
|
|
||||||
$.each(user.roles, function(i, e){
|
|
||||||
$("#lstRole input[name=chooseRole]:radio").filter('[value=' + e.role_id + ']').prop("checked", "checked");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).exec();
|
}).exec();
|
||||||
}
|
}
|
||||||
function listUser(username){
|
$("#btnSearchRepo").on("click", function(){
|
||||||
$.when(
|
listRepo($.trim($("#txtRepoName").val()));
|
||||||
new AjaxUtil({
|
|
||||||
url: "/api/projects/" + $("#projectId").val() + "/members?username=" + (username == null ? "" : username),
|
|
||||||
type: "get",
|
|
||||||
errors: {
|
|
||||||
403: ""
|
|
||||||
},
|
|
||||||
success: function(data, status, xhr){
|
|
||||||
return data || [];
|
|
||||||
}
|
|
||||||
}).exec()
|
|
||||||
).done(function(userList){
|
|
||||||
listUserByProjectCallback(userList || []);
|
|
||||||
$("#tblUser .glyphicon-pencil").on("click", function(e){
|
|
||||||
var userId = $(this).attr("userid")
|
|
||||||
getUserRoleCallback(userId);
|
|
||||||
});
|
|
||||||
$("#tblUser .glyphicon-trash").on("click", function(){
|
|
||||||
var userId = $(this).attr("userid");
|
|
||||||
new AjaxUtil({
|
|
||||||
url: "/api/projects/" + $("#projectId").val() + "/members/" + userId,
|
|
||||||
type: "delete",
|
|
||||||
complete: function(jqXhr, status){
|
|
||||||
if(jqXhr && jqXhr.status == 200){
|
|
||||||
listUser(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).exec();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
listUser(null);
|
|
||||||
listOperationLogs();
|
|
||||||
|
|
||||||
function listOperationLogs(){
|
|
||||||
var projectId = $("#projectId").val();
|
|
||||||
|
|
||||||
$.when(
|
|
||||||
new AjaxUtil({
|
|
||||||
url : "/api/projects/" + projectId + "/logs/filter",
|
|
||||||
data: {},
|
|
||||||
type: "post",
|
|
||||||
success: function(data){
|
|
||||||
return data || [];
|
|
||||||
}
|
|
||||||
}).exec()
|
|
||||||
).done(function(operationLogs){
|
|
||||||
searchAccessLogCallback(operationLogs);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#btnSearchUser").on("click", function(){
|
|
||||||
var username = $("#txtSearchUser").val();
|
|
||||||
if($.trim(username).length == 0){
|
|
||||||
username = null;
|
|
||||||
}
|
|
||||||
listUser(username);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function toUTCSeconds(date, hour, min, sec) {
|
$('#accordionRepo').on('show.bs.collapse', function (e) {
|
||||||
var t = new Date(date);
|
$('#accordionRepo .in').collapse('hide');
|
||||||
t.setHours(hour);
|
var targetId = $(e.target).attr("targetId");
|
||||||
t.setMinutes(min);
|
var repoName = targetId.replace(/[-]{6}/g, "/").replace(/[-]{3}/g, ".");
|
||||||
t.setSeconds(sec);
|
new AjaxUtil({
|
||||||
var utcTime = new Date(t.getUTCFullYear(),
|
url: "/api/repositories/tags?repo_name=" + repoName,
|
||||||
|
type: "get",
|
||||||
|
success: function(data, status, xhr){
|
||||||
|
$('#' + targetId +' table tbody tr').remove();
|
||||||
|
var row = [];
|
||||||
|
for(var i in data){
|
||||||
|
var tagName = data[i]
|
||||||
|
row.push('<tr><td><a href="#" imageId="' + tagName + '" repoName="' + repoName + '">' + tagName + '</a></td><td><input type="text" style="width:100%" readonly value=" docker pull '+ $("#harborRegUrl").val() +'/'+ repoName + ':' + tagName +'"></td></tr>');
|
||||||
|
}
|
||||||
|
$('#' + targetId +' table tbody').append(row.join(""));
|
||||||
|
$('#' + targetId +' table tbody tr a').on("click", function(e){
|
||||||
|
var imageId = $(this).attr("imageId");
|
||||||
|
var repoName = $(this).attr("repoName");
|
||||||
|
new AjaxUtil({
|
||||||
|
url: "/api/repositories/manifests?repo_name=" + repoName + "&tag=" + imageId,
|
||||||
|
type: "get",
|
||||||
|
success: function(data, status, xhr){
|
||||||
|
if(data){
|
||||||
|
for(var i in data){
|
||||||
|
if(data[i] == ""){
|
||||||
|
data[i] = "N/A";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.Created = moment(new Date(data.Created)).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
$("#dlgModal").dialogModal({"title": i18n.getMessage("image_details"), "content": data});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function needToLoginCallback(){
|
||||||
|
|
||||||
|
var hasAuthorization = false;
|
||||||
|
|
||||||
|
$.when(
|
||||||
|
new AjaxUtil({
|
||||||
|
url: "/api/projects/" + $("#projectId").val() + "/members/current",
|
||||||
|
type: "get",
|
||||||
|
success: function(data, status, xhr){
|
||||||
|
if(xhr && xhr.status == 200 && data.roles != null && data.roles.length > 0){
|
||||||
|
hasAuthorization = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).exec())
|
||||||
|
.done(function(){
|
||||||
|
|
||||||
|
if(!hasAuthorization) return false;
|
||||||
|
|
||||||
|
$("#tabItemDetail a:eq(1)").css({"visibility": "visible"});
|
||||||
|
$("#tabItemDetail a:eq(2)").css({"visibility": "visible"});
|
||||||
|
|
||||||
|
$(".glyphicon .glyphicon-pencil", "#tblUser").on("click", function(e){
|
||||||
|
$("#txtUserName").hide();
|
||||||
|
$("#lblUserName").show();
|
||||||
|
$("#dlgUserTitle").text(i18n.getMessage("edit_members"));
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#btnAddUser").on("click", function(){
|
||||||
|
$("#operationType").val("add");
|
||||||
|
$("#spnSearch").show();
|
||||||
|
$("#txtUserName").prop("disabled", false)
|
||||||
|
$("#txtUserName").val("");
|
||||||
|
$("#lstRole input[name=chooseRole]:radio").prop("checked", false);
|
||||||
|
$("#dlgUserTitle").text(i18n.getMessage("add_members"));
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#btnSave").on("click", function(){
|
||||||
|
|
||||||
|
var username = $("#txtUserName").val();
|
||||||
|
if($.trim(username).length == 0){
|
||||||
|
$("#dlgModal").dialogModal({"title": i18n.getMessage("add_member_failed"), "content": i18n.getMessage("please_input_username")});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var projectId = $("#projectId").val();
|
||||||
|
var operationType = $("#operationType").val();
|
||||||
|
var userId = $("#editUserId").val();
|
||||||
|
|
||||||
|
var checkedRole = $("#lstRole input[name='chooseRole']:checked")
|
||||||
|
if(checkedRole.length == 0){
|
||||||
|
$("#dlgModal").dialogModal({"title": i18n.getMessage("add_member_failed"), "content": i18n.getMessage("please_assign_a_role_to_user")});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkedRoleItemList = [];
|
||||||
|
$.each(checkedRole, function(i, e){
|
||||||
|
checkedRoleItemList.push(new Number($(this).val()));
|
||||||
|
});
|
||||||
|
|
||||||
|
var ajaxOpts = {};
|
||||||
|
if(operationType == "add"){
|
||||||
|
ajaxOpts.url = "/api/projects/" + projectId + "/members/";
|
||||||
|
ajaxOpts.type = "post";
|
||||||
|
ajaxOpts.data = {"roles" : checkedRoleItemList, "username": username};
|
||||||
|
}else if(operationType == "edit"){
|
||||||
|
ajaxOpts.url = "/api/projects/" + projectId + "/members/" + userId;
|
||||||
|
ajaxOpts.type = "put";
|
||||||
|
ajaxOpts.data = {"roles" : checkedRoleItemList};
|
||||||
|
}
|
||||||
|
|
||||||
|
new AjaxUtil({
|
||||||
|
url: ajaxOpts.url,
|
||||||
|
data: ajaxOpts.data,
|
||||||
|
type: ajaxOpts.type,
|
||||||
|
complete: function(jqXhr, status){
|
||||||
|
if(jqXhr && jqXhr.status == 200){
|
||||||
|
$("#btnCancel").trigger("click");
|
||||||
|
listUser(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
404: i18n.getMessage("user_id_does_not_exist"),
|
||||||
|
409: i18n.getMessage("user_id_exists"),
|
||||||
|
403: i18n.getMessage("insufficient_privileges")
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
});
|
||||||
|
|
||||||
|
var name_mapping = {
|
||||||
|
"projectAdmin": "Project Admin",
|
||||||
|
"developer": "Developer",
|
||||||
|
"guest": "Guest"
|
||||||
|
}
|
||||||
|
|
||||||
|
function listUserByProjectCallback(userList){
|
||||||
|
var loginedUserId = $("#userId").val();
|
||||||
|
var loginedUserRoleId = $("#roleId").val();
|
||||||
|
var ownerId = $("#ownerId").val();
|
||||||
|
|
||||||
|
$("#tblUser tbody tr").remove();
|
||||||
|
for(var i = 0; i < userList.length; i++){
|
||||||
|
|
||||||
|
var userId = userList[i].user_id;
|
||||||
|
var roleId = userList[i].role_id;
|
||||||
|
var username = userList[i].username;
|
||||||
|
|
||||||
|
var row = '<tr>' +
|
||||||
|
'<td>' + username + '</td>' +
|
||||||
|
'<td>' + name_mapping[userList[i].role_name] + '</td>' +
|
||||||
|
'<td>';
|
||||||
|
var isShowOperations = true;
|
||||||
|
if(loginedUserRoleId >= 3 /*role: developer guest*/){
|
||||||
|
isShowOperations = false;
|
||||||
|
}else if(ownerId == userId){
|
||||||
|
isShowOperations = false;
|
||||||
|
}else if (loginedUserId == userId){
|
||||||
|
isShowOperations = false;
|
||||||
|
}
|
||||||
|
if(isShowOperations){
|
||||||
|
row += '<a href="#" userid="' + userId + '" class="glyphicon glyphicon-pencil" data-toggle="modal" data-target="#dlgUser"></a> ' +
|
||||||
|
'<a href="#" userid="' + userId + '" roleid="' + roleId + '" class="glyphicon glyphicon-trash"></a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
row += '</td></tr>';
|
||||||
|
$("#tblUser tbody").append(row);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchAccessLogCallback(LogList){
|
||||||
|
$("#tabOperationLog tbody tr").remove();
|
||||||
|
$.each(LogList || [], function(i, e){
|
||||||
|
$("#tabOperationLog tbody").append(
|
||||||
|
'<tr>' +
|
||||||
|
'<td>' + e.username + '</td>' +
|
||||||
|
'<td>' + e.repo_name + '</td>' +
|
||||||
|
'<td>' + e.repo_tag + '</td>' +
|
||||||
|
'<td>' + e.operation + '</td>' +
|
||||||
|
'<td>' + moment(new Date(e.op_time)).format("YYYY-MM-DD HH:mm:ss") + '</td>' +
|
||||||
|
'</tr>');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUserRoleCallback(userId){
|
||||||
|
new AjaxUtil({
|
||||||
|
url: "/api/projects/" + $("#projectId").val() + "/members/" + userId,
|
||||||
|
type: "get",
|
||||||
|
success: function(data, status, xhr){
|
||||||
|
var user = data;
|
||||||
|
$("#operationType").val("edit");
|
||||||
|
$("#editUserId").val(user.user_id);
|
||||||
|
$("#spnSearch").hide();
|
||||||
|
$("#txtUserName").val(user.username);
|
||||||
|
$("#txtUserName").prop("disabled", true);
|
||||||
|
$("#btnSave").removeClass("disabled");
|
||||||
|
$("#dlgUserTitle").text(i18n.getMessage("edit_members"));
|
||||||
|
$("#lstRole input[name=chooseRole]:radio").not('[value=' + user.role_id + ']').prop("checked", false)
|
||||||
|
$.each(user.roles, function(i, e){
|
||||||
|
$("#lstRole input[name=chooseRole]:radio").filter('[value=' + e.role_id + ']').prop("checked", "checked");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
}
|
||||||
|
function listUser(username){
|
||||||
|
$.when(
|
||||||
|
new AjaxUtil({
|
||||||
|
url: "/api/projects/" + $("#projectId").val() + "/members?username=" + (username == null ? "" : username),
|
||||||
|
type: "get",
|
||||||
|
errors: {
|
||||||
|
403: ""
|
||||||
|
},
|
||||||
|
success: function(data, status, xhr){
|
||||||
|
return data || [];
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
).done(function(userList){
|
||||||
|
listUserByProjectCallback(userList || []);
|
||||||
|
$("#tblUser .glyphicon-pencil").on("click", function(e){
|
||||||
|
var userId = $(this).attr("userid")
|
||||||
|
getUserRoleCallback(userId);
|
||||||
|
});
|
||||||
|
$("#tblUser .glyphicon-trash").on("click", function(){
|
||||||
|
var userId = $(this).attr("userid");
|
||||||
|
new AjaxUtil({
|
||||||
|
url: "/api/projects/" + $("#projectId").val() + "/members/" + userId,
|
||||||
|
type: "delete",
|
||||||
|
complete: function(jqXhr, status){
|
||||||
|
if(jqXhr && jqXhr.status == 200){
|
||||||
|
listUser(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
listUser(null);
|
||||||
|
listOperationLogs();
|
||||||
|
|
||||||
|
function listOperationLogs(){
|
||||||
|
var projectId = $("#projectId").val();
|
||||||
|
|
||||||
|
$.when(
|
||||||
|
new AjaxUtil({
|
||||||
|
url : "/api/projects/" + projectId + "/logs/filter",
|
||||||
|
data: {},
|
||||||
|
type: "post",
|
||||||
|
success: function(data){
|
||||||
|
return data || [];
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
).done(function(operationLogs){
|
||||||
|
searchAccessLogCallback(operationLogs);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#btnSearchUser").on("click", function(){
|
||||||
|
var username = $("#txtSearchUser").val();
|
||||||
|
if($.trim(username).length == 0){
|
||||||
|
username = null;
|
||||||
|
}
|
||||||
|
listUser(username);
|
||||||
|
});
|
||||||
|
|
||||||
|
function toUTCSeconds(date, hour, min, sec) {
|
||||||
|
var t = new Date(date);
|
||||||
|
t.setHours(hour);
|
||||||
|
t.setMinutes(min);
|
||||||
|
t.setSeconds(sec);
|
||||||
|
var utcTime = new Date(t.getUTCFullYear(),
|
||||||
t.getUTCMonth(),
|
t.getUTCMonth(),
|
||||||
t.getUTCDate(),
|
t.getUTCDate(),
|
||||||
t.getUTCHours(),
|
t.getUTCHours(),
|
||||||
t.getUTCMinutes(),
|
t.getUTCMinutes(),
|
||||||
t.getUTCSeconds());
|
t.getUTCSeconds());
|
||||||
return utcTime.getTime() / 1000;
|
return utcTime.getTime() / 1000;
|
||||||
}
|
|
||||||
|
|
||||||
$("#btnFilterLog").on("click", function(){
|
|
||||||
|
|
||||||
var projectId = $("#projectId").val();
|
|
||||||
var username = $("#txtSearchUserName").val();
|
|
||||||
|
|
||||||
var beginTimestamp = 0;
|
|
||||||
var endTimestamp = 0;
|
|
||||||
|
|
||||||
if($("#begindatepicker").val() != ""){
|
|
||||||
beginTimestamp = toUTCSeconds($("#begindatepicker").val(), 0, 0, 0);
|
|
||||||
}
|
|
||||||
if($("#enddatepicker").val() != ""){
|
|
||||||
endTimestamp = toUTCSeconds($("#enddatepicker").val(), 23, 59, 59);
|
|
||||||
}
|
|
||||||
|
|
||||||
new AjaxUtil({
|
|
||||||
url: "/api/projects/" + projectId + "/logs/filter",
|
|
||||||
data:{"username":username, "project_id" : projectId, "keywords" : getKeyWords() , "beginTimestamp" : beginTimestamp, "endTimestamp" : endTimestamp},
|
|
||||||
type: "post",
|
|
||||||
success: function(data, status, xhr){
|
|
||||||
if(xhr && xhr.status == 200){
|
|
||||||
searchAccessLogCallback(data);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}).exec();
|
$("#btnFilterLog").on("click", function(){
|
||||||
});
|
|
||||||
|
var projectId = $("#projectId").val();
|
||||||
$("#spnFilterOption input[name=chkAll]").on("click", function(){
|
var username = $("#txtSearchUserName").val();
|
||||||
$("#spnFilterOption input[name=chkOperation]").prop("checked", $(this).prop("checked"));
|
|
||||||
});
|
var beginTimestamp = 0;
|
||||||
|
var endTimestamp = 0;
|
||||||
$("#spnFilterOption input[name=chkOperation]").on("click", function(){
|
|
||||||
if(!$(this).prop("checked")){
|
if($("#begindatepicker").val() != ""){
|
||||||
$("#spnFilterOption input[name=chkAll]").prop("checked", false);
|
beginTimestamp = toUTCSeconds($("#begindatepicker").val(), 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
if($("#enddatepicker").val() != ""){
|
||||||
var selectedAll = true;
|
endTimestamp = toUTCSeconds($("#enddatepicker").val(), 23, 59, 59);
|
||||||
|
}
|
||||||
$("#spnFilterOption input[name=chkOperation]").each(function(i, e){
|
|
||||||
if(!$(e).prop("checked")){
|
new AjaxUtil({
|
||||||
selectedAll = false;
|
url: "/api/projects/" + projectId + "/logs/filter",
|
||||||
}
|
data:{"username":username, "project_id" : Number(projectId), "keywords" : getKeyWords() , "begin_timestamp" : beginTimestamp, "end_timestamp" : endTimestamp},
|
||||||
});
|
type: "post",
|
||||||
|
success: function(data, status, xhr){
|
||||||
if(selectedAll){
|
if(xhr && xhr.status == 200){
|
||||||
$("#spnFilterOption input[name=chkAll]").prop("checked", true);
|
searchAccessLogCallback(data);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}).exec();
|
||||||
function getKeyWords(){
|
});
|
||||||
var keywords = "";
|
|
||||||
var checkedItemList=$("#spnFilterOption input[name=chkOperation]:checked");
|
$("#spnFilterOption input[name=chkAll]").on("click", function(){
|
||||||
var keywords = [];
|
$("#spnFilterOption input[name=chkOperation]").prop("checked", $(this).prop("checked"));
|
||||||
$.each(checkedItemList, function(i, e){
|
});
|
||||||
var itemValue = $(e).val();
|
|
||||||
if(itemValue == "others" && $.trim($("#txtOthers").val()).length > 0){
|
$("#spnFilterOption input[name=chkOperation]").on("click", function(){
|
||||||
keywords.push($("#txtOthers").val());
|
if(!$(this).prop("checked")){
|
||||||
}else{
|
$("#spnFilterOption input[name=chkAll]").prop("checked", false);
|
||||||
keywords.push($(e).val());
|
}
|
||||||
}
|
|
||||||
});
|
var selectedAll = true;
|
||||||
return keywords.join("/");
|
|
||||||
}
|
$("#spnFilterOption input[name=chkOperation]").each(function(i, e){
|
||||||
|
if(!$(e).prop("checked")){
|
||||||
$('#datetimepicker1').datetimepicker({
|
selectedAll = false;
|
||||||
locale: i18n.getLocale(),
|
}
|
||||||
ignoreReadonly: true,
|
});
|
||||||
format: 'L',
|
|
||||||
showClear: true
|
if(selectedAll){
|
||||||
});
|
$("#spnFilterOption input[name=chkAll]").prop("checked", true);
|
||||||
$('#datetimepicker2').datetimepicker({
|
}
|
||||||
locale: i18n.getLocale(),
|
});
|
||||||
ignoreReadonly: true,
|
|
||||||
format: 'L',
|
function getKeyWords(){
|
||||||
showClear: true
|
var keywords = "";
|
||||||
});
|
var checkedItemList=$("#spnFilterOption input[name=chkOperation]:checked");
|
||||||
});
|
var keywords = [];
|
||||||
}
|
$.each(checkedItemList, function(i, e){
|
||||||
|
var itemValue = $(e).val();
|
||||||
$(document).on("keydown", function(e){
|
if(itemValue == "others" && $.trim($("#txtOthers").val()).length > 0){
|
||||||
if(e.keyCode == 13){
|
keywords.push($("#txtOthers").val());
|
||||||
e.preventDefault();
|
}else{
|
||||||
if($("#tabItemDetail li:eq(0)").is(":focus") || $("#txtRepoName").is(":focus")){
|
keywords.push($(e).val());
|
||||||
$("#btnSearchRepo").trigger("click");
|
}
|
||||||
}else if($("#tabItemDetail li:eq(1)").is(":focus") || $("#txtSearchUser").is(":focus")){
|
});
|
||||||
$("#btnSearchUser").trigger("click");
|
return keywords.join("/");
|
||||||
}else if($("#tabItemDetail li:eq(2)").is(":focus") || $("#txtSearchUserName").is(":focus")){
|
}
|
||||||
$("#btnFilterLog").trigger("click");
|
|
||||||
}else if($("#txtUserName").is(":focus") || $("#lstRole :radio").is(":focus")){
|
$('#datetimepicker1').datetimepicker({
|
||||||
$("#btnSave").trigger("click");
|
locale: i18n.getLocale(),
|
||||||
}
|
ignoreReadonly: true,
|
||||||
|
format: 'L',
|
||||||
|
showClear: true
|
||||||
|
});
|
||||||
|
$('#datetimepicker2').datetimepicker({
|
||||||
|
locale: i18n.getLocale(),
|
||||||
|
ignoreReadonly: true,
|
||||||
|
format: 'L',
|
||||||
|
showClear: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on("keydown", function(e){
|
||||||
|
if(e.keyCode == 13){
|
||||||
|
e.preventDefault();
|
||||||
|
if($("#tabItemDetail li:eq(0)").is(":focus") || $("#txtRepoName").is(":focus")){
|
||||||
|
$("#btnSearchRepo").trigger("click");
|
||||||
|
}else if($("#tabItemDetail li:eq(1)").is(":focus") || $("#txtSearchUser").is(":focus")){
|
||||||
|
$("#btnSearchUser").trigger("click");
|
||||||
|
}else if($("#tabItemDetail li:eq(2)").is(":focus") || $("#txtSearchUserName").is(":focus")){
|
||||||
|
$("#btnFilterLog").trigger("click");
|
||||||
|
}else if($("#txtUserName").is(":focus") || $("#lstRole :radio").is(":focus")){
|
||||||
|
$("#btnSave").trigger("click");
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
})
|
});
|
||||||
|
})
|
@ -24,7 +24,7 @@ jQuery(function(){
|
|||||||
},
|
},
|
||||||
error: function(jqXhr){
|
error: function(jqXhr){
|
||||||
if(jqXhr.status == 401)
|
if(jqXhr.status == 401)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}).exec();
|
}).exec();
|
||||||
|
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
jQuery(function(){
|
jQuery(function(){
|
||||||
|
|
||||||
new AjaxUtil({
|
new AjaxUtil({
|
||||||
url: "/api/users/current",
|
url: "/api/users/current",
|
||||||
type: "get",
|
type: "get",
|
||||||
success: function(data, status, xhr){
|
success: function(data, status, xhr){
|
||||||
if(xhr && xhr.status == 200){
|
if(xhr && xhr.status == 200){
|
||||||
if(data.HasAdminRole == 1) {
|
if(data.has_admin_role == 1) {
|
||||||
renderForAdminRole();
|
renderForAdminRole();
|
||||||
}
|
}
|
||||||
renderForAnyRole();
|
renderForAnyRole();
|
||||||
@ -29,57 +29,57 @@ jQuery(function(){
|
|||||||
|
|
||||||
function renderForAnyRole(){
|
function renderForAnyRole(){
|
||||||
$("#tabProject a:first").tab("show");
|
$("#tabProject a:first").tab("show");
|
||||||
|
|
||||||
$(document).on("keydown", function(e){
|
$(document).on("keydown", function(e){
|
||||||
if(e.keyCode == 13){
|
if(e.keyCode == 13){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if($("#tabProject li:eq(0)").is(":focus") || $("#txtSearchProject").is(":focus")){
|
if($("#tabProject li:eq(0)").is(":focus") || $("#txtSearchProject").is(":focus")){
|
||||||
$("#btnSearch").trigger("click");
|
$("#btnSearch").trigger("click");
|
||||||
}else if($("#tabProject li:eq(1)").is(":focus") || $("#txtSearchPublicProjects").is(":focus")){
|
}else if($("#tabProject li:eq(1)").is(":focus") || $("#txtSearchPublicProjects").is(":focus")){
|
||||||
$("#btnSearchPublicProjects").trigger("click");
|
$("#btnSearchPublicProjects").trigger("click");
|
||||||
}else if($("#tabProject li:eq(1)").is(":focus") || $("#txtSearchUsername").is(":focus")){
|
}else if($("#tabProject li:eq(1)").is(":focus") || $("#txtSearchUsername").is(":focus")){
|
||||||
$("#btnSearchUsername").trigger("click");
|
$("#btnSearchUsername").trigger("click");
|
||||||
}else if($("#dlgAddProject").is(":focus") || $("#projectName").is(":focus")){
|
}else if($("#dlgAddProject").is(":focus") || $("#projectName").is(":focus")){
|
||||||
$("#btnSave").trigger("click");
|
$("#btnSave").trigger("click");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function listProject(projectName, isPublic){
|
function listProject(projectName, isPublic){
|
||||||
currentPublic = isPublic;
|
currentPublic = isPublic;
|
||||||
$.when(
|
$.when(
|
||||||
new AjaxUtil({
|
new AjaxUtil({
|
||||||
url: "/api/projects?is_public=" + isPublic + "&project_name=" + (projectName == null ? "" : projectName) + "×tamp=" + new Date().getTime(),
|
url: "/api/projects?is_public=" + isPublic + "&project_name=" + (projectName == null ? "" : projectName) + "×tamp=" + new Date().getTime(),
|
||||||
type: "get",
|
type: "get",
|
||||||
success: function(data, status, xhr){
|
success: function(data, status, xhr){
|
||||||
$("#tblProject tbody tr").remove();
|
$("#tblProject tbody tr").remove();
|
||||||
$.each(data || [], function(i, e){
|
$.each(data || [], function(i, e){
|
||||||
var row = '<tr>' +
|
var row = '<tr>' +
|
||||||
'<td style="vertical-align: middle;"><a href="/registry/detail?project_id=' + e.ProjectId + '">' + e.Name + '</a></td>' +
|
'<td style="vertical-align: middle;"><a href="/registry/detail?project_id=' + e.project_id + '">' + e.name + '</a></td>' +
|
||||||
'<td style="vertical-align: middle;">' + moment(new Date(e.CreationTime)).format("YYYY-MM-DD HH:mm:ss") + '</td>';
|
'<td style="vertical-align: middle;">' + moment(new Date(e.creation_time)).format("YYYY-MM-DD HH:mm:ss") + '</td>';
|
||||||
if(e.Public == 1 && e.Togglable){
|
if(e.public == 1 && e.Togglable){
|
||||||
row += '<td><button type="button" class="btn btn-success" projectid="' + e.ProjectId + '">' + i18n.getMessage("button_on")+ '</button></td>'
|
row += '<td><button type="button" class="btn btn-success" projectid="' + e.project_id + '">' + i18n.getMessage("button_on")+ '</button></td>'
|
||||||
} else if (e.Public == 1) {
|
} else if (e.public == 1) {
|
||||||
row += '<td><button type="button" class="btn btn-success" projectid="' + e.ProjectId + '" disabled>' + i18n.getMessage("button_on")+ '</button></td>';
|
row += '<td><button type="button" class="btn btn-success" projectid="' + e.project_id + '" disabled>' + i18n.getMessage("button_on")+ '</button></td>';
|
||||||
} else if (e.Public == 0 && e.Togglable) {
|
} else if (e.public == 0 && e.Togglable) {
|
||||||
row += '<td><button type="button" class="btn btn-danger" projectid="' + e.ProjectId + '">' + i18n.getMessage("button_off")+ '</button></td>';
|
row += '<td><button type="button" class="btn btn-danger" projectid="' + e.project_id + '">' + i18n.getMessage("button_off")+ '</button></td>';
|
||||||
} else if (e.Public == 0) {
|
} else if (e.public == 0) {
|
||||||
row += '<td><button type="button" class="btn btn-danger" projectid="' + e.ProjectId + '" disabled>' + i18n.getMessage("button_off")+ '</button></td>';
|
row += '<td><button type="button" class="btn btn-danger" projectid="' + e.project_id + '" disabled>' + i18n.getMessage("button_off")+ '</button></td>';
|
||||||
row += '</tr>';
|
row += '</tr>';
|
||||||
}
|
}
|
||||||
$("#tblProject tbody").append(row);
|
$("#tblProject tbody").append(row);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).exec())
|
}).exec())
|
||||||
.done(function() {
|
.done(function() {
|
||||||
$("#tblProject tbody tr :button").on("click", function(){
|
$("#tblProject tbody tr :button").on("click", function(){
|
||||||
var projectId = $(this).attr("projectid");
|
var projectId = $(this).attr("projectid");
|
||||||
var self = this;
|
var self = this;
|
||||||
new AjaxUtil({
|
new AjaxUtil({
|
||||||
url: "/api/projects/" + projectId,
|
url: "/api/projects/" + projectId,
|
||||||
data: {"public": ($(self).hasClass("btn-success") ? false : true)},
|
data: {"public": ($(self).hasClass("btn-success") ? false : true)},
|
||||||
type: "put",
|
type: "put",
|
||||||
complete: function(jqXhr, status) {
|
complete: function(jqXhr, status) {
|
||||||
if($(self).hasClass("btn-success")){
|
if($(self).hasClass("btn-success")){
|
||||||
$(self).removeClass("btn-success").addClass("btn-danger");
|
$(self).removeClass("btn-success").addClass("btn-danger");
|
||||||
$(self).html(i18n.getMessage("button_off"));
|
$(self).html(i18n.getMessage("button_off"));
|
||||||
@ -88,9 +88,9 @@ jQuery(function(){
|
|||||||
$(self).html(i18n.getMessage("button_on"));
|
$(self).html(i18n.getMessage("button_on"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).exec();
|
}).exec();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
listProject(null, 0);
|
listProject(null, 0);
|
||||||
var currentPublic = 0;
|
var currentPublic = 0;
|
||||||
@ -119,7 +119,7 @@ jQuery(function(){
|
|||||||
$("#projectName").val("");
|
$("#projectName").val("");
|
||||||
$("#projectName").parent().addClass("has-feedback");
|
$("#projectName").parent().addClass("has-feedback");
|
||||||
$("#projectName").siblings("span").removeClass("glyphicon-warning-sign").removeClass("glyphicon-ok");
|
$("#projectName").siblings("span").removeClass("glyphicon-warning-sign").removeClass("glyphicon-ok");
|
||||||
$("#isPublic").prop('checked', false);
|
$("#isPublic").prop('checked', false);
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#btnSave").on("click", function(){
|
$("#btnSave").on("click", function(){
|
||||||
@ -161,52 +161,52 @@ jQuery(function(){
|
|||||||
$("#tblUser tbody tr").remove();
|
$("#tblUser tbody tr").remove();
|
||||||
$.each(data || [], function(i, e){
|
$.each(data || [], function(i, e){
|
||||||
var row = '<tr>' +
|
var row = '<tr>' +
|
||||||
'<td style="vertical-align: middle;">' + e.username + '</td>' +
|
'<td style="vertical-align: middle;">' + e.username + '</td>' +
|
||||||
'<td style="vertical-align: middle;">' + e.email + '</td>';
|
'<td style="vertical-align: middle;">' + e.email + '</td>';
|
||||||
if(e.HasAdminRole == 1){
|
if(e.has_admin_role == 1){
|
||||||
row += '<td style="padding-left: 30px;"><button type="button" class="btn btn-success" userid="' + e.UserId + '">' + i18n.getMessage("button_on") + '</button></td>';
|
row += '<td style="padding-left: 30px;"><button type="button" class="btn btn-success" userid="' + e.user_id + '">' + i18n.getMessage("button_on") + '</button></td>';
|
||||||
} else {
|
} else {
|
||||||
row += '<td style="padding-left: 30px;"><button type="button" class="btn btn-danger" userid="' + e.UserId + '">' + i18n.getMessage("button_off") + '</button></td>';
|
row += '<td style="padding-left: 30px;"><button type="button" class="btn btn-danger" userid="' + e.user_id + '">' + i18n.getMessage("button_off") + '</button></td>';
|
||||||
}
|
}
|
||||||
row += '<td style="padding-left: 30px; vertical-align: middle;"><a href="#" style="visibility: hidden;" class="tdDeleteUser" userid="' + e.UserId + '" username="' + e.Username + '"><span class="glyphicon glyphicon-trash"></span></a></td>';
|
row += '<td style="padding-left: 30px; vertical-align: middle;"><a href="#" style="visibility: hidden;" class="tdDeleteUser" userid="' + e.user_id + '" username="' + e.username + '"><span class="glyphicon glyphicon-trash"></span></a></td>';
|
||||||
row += '</tr>';
|
row += '</tr>';
|
||||||
$("#tblUser tbody").append(row);
|
$("#tblUser tbody").append(row);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).exec()
|
}).exec()
|
||||||
).done(function(){
|
).done(function(){
|
||||||
$("#tblUser tbody tr :button").on("click",function(){
|
$("#tblUser tbody tr :button").on("click",function(){
|
||||||
var userId = $(this).attr("userid");
|
var userId = $(this).attr("userid");
|
||||||
var self = this;
|
var self = this;
|
||||||
new AjaxUtil({
|
new AjaxUtil({
|
||||||
url: "/api/users/" + userId,
|
url: "/api/users/" + userId,
|
||||||
type: "put",
|
type: "put",
|
||||||
complete: function(jqXhr, status){
|
complete: function(jqXhr, status){
|
||||||
if(jqXhr && jqXhr.status == 200){
|
if(jqXhr && jqXhr.status == 200){
|
||||||
if($(self).hasClass("btn-success")){
|
if($(self).hasClass("btn-success")){
|
||||||
$(self).removeClass("btn-success").addClass("btn-danger");
|
$(self).removeClass("btn-success").addClass("btn-danger");
|
||||||
$(self).html(i18n.getMessage("button_off"));
|
$(self).html(i18n.getMessage("button_off"));
|
||||||
}else{
|
}else{
|
||||||
$(self).removeClass("btn-danger").addClass("btn-success");
|
$(self).removeClass("btn-danger").addClass("btn-success");
|
||||||
$(self).html(i18n.getMessage("button_on"));
|
$(self).html(i18n.getMessage("button_on"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).exec();
|
}).exec();
|
||||||
});
|
});
|
||||||
$("#tblUser tbody tr").on("mouseover", function(){
|
$("#tblUser tbody tr").on("mouseover", function(e){
|
||||||
$(".tdDeleteUser", this).css({"visibility":"visible"});
|
$(".tdDeleteUser", this).css({"visibility":"visible"});
|
||||||
}).on("mouseout", function(){
|
}).on("mouseout", function(e){
|
||||||
$(".tdDeleteUser", this).css({"visibility":"hidden"});
|
$(".tdDeleteUser", this).css({"visibility":"hidden"});
|
||||||
});
|
});
|
||||||
$("#tblUser tbody tr .tdDeleteUser").on("click", function(){
|
$("#tblUser tbody tr .tdDeleteUser").on("click", function(e){
|
||||||
var userId = $(this).attr("userid");
|
var userId = $(this).attr("userid");
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("delete_user"),
|
"title": i18n.getMessage("delete_user"),
|
||||||
"content": i18n.getMessage("are_you_sure_to_delete_user") + $(this).attr("username") + " ?",
|
"content": i18n.getMessage("are_you_sure_to_delete_user") + $(this).attr("username") + " ?",
|
||||||
"enableCancel": true,
|
"enableCancel": true,
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
new AjaxUtil({
|
new AjaxUtil({
|
||||||
url: "/api/users/" + userId,
|
url: "/api/users/" + userId,
|
||||||
type: "delete",
|
type: "delete",
|
||||||
@ -218,17 +218,18 @@ jQuery(function(){
|
|||||||
error: function(jqXhr){}
|
error: function(jqXhr){}
|
||||||
}).exec();
|
}).exec();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
listUserAdminRole(null);
|
||||||
|
$("#btnSearchUsername").on("click", function(){
|
||||||
|
var username = $("#txtSearchUsername").val();
|
||||||
|
if($.trim(username).length == 0){
|
||||||
|
username = null;
|
||||||
|
}
|
||||||
|
listUserAdminRole(username);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
listUserAdminRole(null);
|
})
|
||||||
$("#btnSearchUsername").on("click", function(){
|
|
||||||
var username = $("#txtSearchUsername").val();
|
|
||||||
if($.trim(username).length == 0){
|
|
||||||
username = null;
|
|
||||||
}
|
|
||||||
listUserAdminRole(username);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
@ -30,14 +30,14 @@ jQuery(function(){
|
|||||||
|
|
||||||
$("#btnPageSignUp").on("click", function(){
|
$("#btnPageSignUp").on("click", function(){
|
||||||
validateOptions.Validate(function() {
|
validateOptions.Validate(function() {
|
||||||
var username = $.trim($("#Username").val());
|
var username = $.trim($("#Username").val());
|
||||||
var email = $.trim($("#Email").val());
|
var email = $.trim($("#Email").val());
|
||||||
var password = $.trim($("#Password").val());
|
var password = $.trim($("#Password").val());
|
||||||
var confirmedPassword = $.trim($("#ConfirmedPassword").val());
|
var confirmedPassword = $.trim($("#ConfirmedPassword").val());
|
||||||
var realname = $.trim($("#Realname").val());
|
var realname = $.trim($("#Realname").val());
|
||||||
var comment = $.trim($("#Comment").val());
|
var comment = $.trim($("#Comment").val());
|
||||||
var isAdmin = $("#isAdmin").val();
|
var isAdmin = $("#isAdmin").val();
|
||||||
|
|
||||||
new AjaxUtil({
|
new AjaxUtil({
|
||||||
url : "/api/users",
|
url : "/api/users",
|
||||||
data: {"username": username, "password": password, "realname": realname, "comment": comment, "email": email},
|
data: {"username": username, "password": password, "realname": realname, "comment": comment, "email": email},
|
||||||
@ -47,29 +47,29 @@ jQuery(function(){
|
|||||||
},
|
},
|
||||||
error:function(jqxhr, status, error){
|
error:function(jqxhr, status, error){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_sign_up"),
|
"title": i18n.getMessage("title_sign_up"),
|
||||||
"content": i18n.getMessage("internal_error"),
|
"content": i18n.getMessage("internal_error"),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
complete: function(xhr, status){
|
complete: function(xhr, status){
|
||||||
$("#btnPageSignUp").prop("disabled", false);
|
$("#btnPageSignUp").prop("disabled", false);
|
||||||
if(xhr && xhr.status == 201){
|
if(xhr && xhr.status == 201){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": isAdmin == "true" ? i18n.getMessage("title_add_user") : i18n.getMessage("title_sign_up"),
|
"title": isAdmin == "true" ? i18n.getMessage("title_add_user") : i18n.getMessage("title_sign_up"),
|
||||||
"content": isAdmin == "true" ? i18n.getMessage("added_user_successfully") : i18n.getMessage("registered_successfully"),
|
"content": isAdmin == "true" ? i18n.getMessage("added_user_successfully") : i18n.getMessage("registered_successfully"),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
if(isAdmin == "true") {
|
if(isAdmin == "true") {
|
||||||
document.location = "/registry/project";
|
document.location = "/registry/project";
|
||||||
}else{
|
}else{
|
||||||
document.location = "/signIn";
|
document.location = "/signIn";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).exec();
|
}).exec();
|
||||||
|
@ -17,11 +17,11 @@ jQuery(function(){
|
|||||||
|
|
||||||
$("#Password,#ConfirmedPassword").on("blur", validateCallback);
|
$("#Password,#ConfirmedPassword").on("blur", validateCallback);
|
||||||
validateOptions.Items = ["#Password", "#ConfirmedPassword"];
|
validateOptions.Items = ["#Password", "#ConfirmedPassword"];
|
||||||
function bindEnterKey(){
|
function bindEnterKey(){
|
||||||
$(document).on("keydown", function(e){
|
$(document).on("keydown", function(e){
|
||||||
if(e.keyCode == 13){
|
if(e.keyCode == 13){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$("#btnSubmit").trigger("click");
|
$("#btnSubmit").trigger("click");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -30,7 +30,6 @@ jQuery(function(){
|
|||||||
}
|
}
|
||||||
bindEnterKey();
|
bindEnterKey();
|
||||||
|
|
||||||
|
|
||||||
var spinner = new Spinner({scale:1}).spin();
|
var spinner = new Spinner({scale:1}).spin();
|
||||||
|
|
||||||
$("#btnSubmit").on("click", function(){
|
$("#btnSubmit").on("click", function(){
|
||||||
@ -42,20 +41,20 @@ jQuery(function(){
|
|||||||
"type": "post",
|
"type": "post",
|
||||||
"data": {"reset_uuid": resetUuid, "password": password},
|
"data": {"reset_uuid": resetUuid, "password": password},
|
||||||
"beforeSend": function(e){
|
"beforeSend": function(e){
|
||||||
unbindEnterKey();
|
unbindEnterKey();
|
||||||
$("h1").append(spinner.el);
|
$("h1").append(spinner.el);
|
||||||
$("#btnSubmit").prop("disabled", true);
|
$("#btnSubmit").prop("disabled", true);
|
||||||
},
|
},
|
||||||
"success": function(data, status, xhr){
|
"success": function(data, status, xhr){
|
||||||
if(xhr && xhr.status == 200){
|
if(xhr && xhr.status == 200){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_reset_password"),
|
"title": i18n.getMessage("title_reset_password"),
|
||||||
"content": i18n.getMessage("reset_password_successfully"),
|
"content": i18n.getMessage("reset_password_successfully"),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
document.location="/signIn";
|
document.location="/signIn";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -66,14 +65,14 @@ jQuery(function(){
|
|||||||
"error": function(jqXhr, status, error){
|
"error": function(jqXhr, status, error){
|
||||||
if(jqXhr){
|
if(jqXhr){
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_reset_password"),
|
"title": i18n.getMessage("title_reset_password"),
|
||||||
"content": i18n.getMessage(jqXhr.responseText),
|
"content": i18n.getMessage(jqXhr.responseText),
|
||||||
"callback": function(){
|
"callback": function(){
|
||||||
bindEnterKey();
|
bindEnterKey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -60,12 +60,12 @@ jQuery(function(){
|
|||||||
$.each(data, function(i, e){
|
$.each(data, function(i, e){
|
||||||
var project, description, repoName;
|
var project, description, repoName;
|
||||||
switch(discriminator){
|
switch(discriminator){
|
||||||
case "project":
|
case "project":
|
||||||
project = new Project(e.id, e.name, e.public);
|
project = new Project(e.id, e.name, e.public);
|
||||||
description = project.name;
|
description = project.name;
|
||||||
repoName = "";
|
repoName = "";
|
||||||
break;
|
break;
|
||||||
case "repository":
|
case "repository":
|
||||||
project = new Project(e.project_id, e.project_name, e.project_public);
|
project = new Project(e.project_id, e.project_name, e.project_public);
|
||||||
description = e.repository_name;
|
description = e.repository_name;
|
||||||
repoName = e.repository_name.substring(e.repository_name.lastIndexOf("/") + 1);
|
repoName = e.repository_name.substring(e.repository_name.lastIndexOf("/") + 1);
|
||||||
|
@ -56,7 +56,7 @@ jQuery(function(){
|
|||||||
success: function(jqXhr, status){
|
success: function(jqXhr, status){
|
||||||
var lastUri = location.search;
|
var lastUri = location.search;
|
||||||
if(lastUri != "" && lastUri.indexOf("=") > 0){
|
if(lastUri != "" && lastUri.indexOf("=") > 0){
|
||||||
document.location = decodeURIComponent(lastUri.split("=")[1]);
|
document.location = decodeURIComponent(lastUri.split("=")[1]);
|
||||||
}else{
|
}else{
|
||||||
document.location = "/registry/project";
|
document.location = "/registry/project";
|
||||||
}
|
}
|
||||||
@ -69,10 +69,10 @@ jQuery(function(){
|
|||||||
i18nKey = "check_your_username_or_password"
|
i18nKey = "check_your_username_or_password"
|
||||||
}
|
}
|
||||||
$("#dlgModal")
|
$("#dlgModal")
|
||||||
.dialogModal({
|
.dialogModal({
|
||||||
"title": i18n.getMessage("title_login_failed"),
|
"title": i18n.getMessage("title_login_failed"),
|
||||||
"content": i18n.getMessage(i18nKey)
|
"content": i18n.getMessage(i18nKey)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -26,18 +26,18 @@ var validateOptions = {
|
|||||||
"Username" :{
|
"Username" :{
|
||||||
"Required": { "value" : true, "errMsg" : i18n.getMessage("username_is_required")},
|
"Required": { "value" : true, "errMsg" : i18n.getMessage("username_is_required")},
|
||||||
"CheckExist": { "value" : function(value){
|
"CheckExist": { "value" : function(value){
|
||||||
var result = true;
|
var result = true;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/userExists",
|
url: "/userExists",
|
||||||
data: {"target": "username", "value" : value},
|
data: {"target": "username", "value" : value},
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
type: "post",
|
type: "post",
|
||||||
async: false,
|
async: false,
|
||||||
success: function(data){
|
success: function(data){
|
||||||
result = data;
|
result = data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}, "errMsg" : i18n.getMessage("username_has_been_taken")},
|
}, "errMsg" : i18n.getMessage("username_has_been_taken")},
|
||||||
"MaxLength": {"value" : 20, "errMsg" : i18n.getMessage("username_is_too_long")},
|
"MaxLength": {"value" : 20, "errMsg" : i18n.getMessage("username_is_too_long")},
|
||||||
"IllegalChar": {"value": [",","~","#", "$", "%"] , "errMsg": i18n.getMessage("username_contains_illegal_chars")}
|
"IllegalChar": {"value": [",","~","#", "$", "%"] , "errMsg": i18n.getMessage("username_contains_illegal_chars")}
|
||||||
@ -45,40 +45,40 @@ var validateOptions = {
|
|||||||
"Email" :{
|
"Email" :{
|
||||||
"Required": { "value" : true, "errMsg" : i18n.getMessage("email_is_required")},
|
"Required": { "value" : true, "errMsg" : i18n.getMessage("email_is_required")},
|
||||||
"RegExp": {"value": /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
"RegExp": {"value": /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
||||||
"errMsg": i18n.getMessage("email_contains_illegal_chars")},
|
"errMsg": i18n.getMessage("email_contains_illegal_chars")},
|
||||||
"CheckExist": { "value" : function(value){
|
"CheckExist": { "value" : function(value){
|
||||||
var result = true;
|
var result = true;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/userExists",
|
url: "/userExists",
|
||||||
data: {"target": "email", "value": value},
|
data: {"target": "email", "value": value},
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
type: "post",
|
type: "post",
|
||||||
async: false,
|
async: false,
|
||||||
success: function(data){
|
success: function(data){
|
||||||
result = data;
|
result = data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}, "errMsg" : i18n.getMessage("email_has_been_taken")}
|
}, "errMsg" : i18n.getMessage("email_has_been_taken")}
|
||||||
},
|
},
|
||||||
"EmailF" :{
|
"EmailF" :{
|
||||||
"Required": { "value" : true, "errMsg" : i18n.getMessage("email_is_required")},
|
"Required": { "value" : true, "errMsg" : i18n.getMessage("email_is_required")},
|
||||||
"RegExp": {"value": /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
"RegExp": {"value": /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
||||||
"errMsg": i18n.getMessage("email_content_illegal")},
|
"errMsg": i18n.getMessage("email_content_illegal")},
|
||||||
"CheckIfNotExist": { "value" : function(value){
|
"CheckIfNotExist": { "value" : function(value){
|
||||||
var result = true;
|
var result = true;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/userExists",
|
url: "/userExists",
|
||||||
data: {"target": "email", "value": value},
|
data: {"target": "email", "value": value},
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
type: "post",
|
type: "post",
|
||||||
async: false,
|
async: false,
|
||||||
success: function(data){
|
success: function(data){
|
||||||
result = data;
|
result = data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}, "errMsg" : i18n.getMessage("email_does_not_exist")}
|
}, "errMsg" : i18n.getMessage("email_does_not_exist")}
|
||||||
},
|
},
|
||||||
"Realname" :{
|
"Realname" :{
|
||||||
"Required": { "value" : true, "errMsg" : i18n.getMessage("realname_is_required")},
|
"Required": { "value" : true, "errMsg" : i18n.getMessage("realname_is_required")},
|
||||||
@ -119,7 +119,7 @@ function validateCallback(target){
|
|||||||
var currentId = $(target).attr("id");
|
var currentId = $(target).attr("id");
|
||||||
var validateItem = validateOptions[currentId];
|
var validateItem = validateOptions[currentId];
|
||||||
|
|
||||||
var errMsg = "";
|
var errMsg = "";
|
||||||
|
|
||||||
for(var checkTitle in validateItem){
|
for(var checkTitle in validateItem){
|
||||||
|
|
||||||
|
23
tests/apitests/apilib/accesslog.go
Normal file
23
tests/apitests/apilib/accesslog.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
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 HarborAPI
|
||||||
|
|
||||||
|
type AccessLog struct {
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
Keywords string `json:"keywords,omitempty"`
|
||||||
|
BeginTimestamp int32 `json:"beginTimestamp,omitempty"`
|
||||||
|
EndTimestamp int32 `json:"endTimestamp,omitempty"`
|
||||||
|
}
|
113
tests/apitests/apilib/harborapi.go
Normal file
113
tests/apitests/apilib/harborapi.go
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//Package HarborAPI
|
||||||
|
//These APIs provide services for manipulating Harbor project.
|
||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
//"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dghubble/sling"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HarborAPI struct {
|
||||||
|
basePath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHarborAPI() *HarborAPI {
|
||||||
|
return &HarborAPI{
|
||||||
|
basePath: "http://localhost",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHarborAPIWithBasePath(basePath string) *HarborAPI {
|
||||||
|
return &HarborAPI{
|
||||||
|
basePath: basePath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UsrInfo struct {
|
||||||
|
Name string
|
||||||
|
Passwd string
|
||||||
|
}
|
||||||
|
|
||||||
|
//Search for projects and repositories
|
||||||
|
//Implementation Notes
|
||||||
|
//The Search endpoint returns information about the projects and repositories
|
||||||
|
//offered at public status or related to the current logged in user.
|
||||||
|
//The response includes the project and repository list in a proper display order.
|
||||||
|
//@param q Search parameter for project and repository name.
|
||||||
|
//@return []Search
|
||||||
|
//func (a HarborAPI) SearchGet (q string) (Search, error) {
|
||||||
|
func (a HarborAPI) SearchGet(q string) (Search, error) {
|
||||||
|
|
||||||
|
_sling := sling.New().Get(a.basePath)
|
||||||
|
|
||||||
|
// create path and map variables
|
||||||
|
path := "/api/search"
|
||||||
|
|
||||||
|
_sling = _sling.Path(path)
|
||||||
|
|
||||||
|
type QueryParams struct {
|
||||||
|
Query string `url:"q"`
|
||||||
|
}
|
||||||
|
|
||||||
|
_sling = _sling.QueryStruct(&QueryParams{q})
|
||||||
|
|
||||||
|
// accept header
|
||||||
|
accepts := []string{"application/json", "text/plain"}
|
||||||
|
for key := range accepts {
|
||||||
|
_sling = _sling.Set("Accept", accepts[key])
|
||||||
|
break // only use the first Accept
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := _sling.Request()
|
||||||
|
client := &http.Client{}
|
||||||
|
httpResponse, err := client.Do(req)
|
||||||
|
defer httpResponse.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(httpResponse.Body)
|
||||||
|
if err != nil {
|
||||||
|
// handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
var successPayload = new(Search)
|
||||||
|
err = json.Unmarshal(body, &successPayload)
|
||||||
|
return *successPayload, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create a new project.
|
||||||
|
//Implementation Notes
|
||||||
|
//This endpoint is for user to create a new project.
|
||||||
|
//@param project New created project.
|
||||||
|
//@return void
|
||||||
|
//func (a HarborAPI) ProjectsPost (prjUsr UsrInfo, project Project) (int, error) {
|
||||||
|
func (a HarborAPI) ProjectsPost(prjUsr UsrInfo, project Project) (int, error) {
|
||||||
|
|
||||||
|
_sling := sling.New().Post(a.basePath)
|
||||||
|
|
||||||
|
// create path and map variables
|
||||||
|
path := "/api/projects"
|
||||||
|
|
||||||
|
_sling = _sling.Path(path)
|
||||||
|
|
||||||
|
// accept header
|
||||||
|
accepts := []string{"application/json", "text/plain"}
|
||||||
|
for key := range accepts {
|
||||||
|
_sling = _sling.Set("Accept", accepts[key])
|
||||||
|
break // only use the first Accept
|
||||||
|
}
|
||||||
|
|
||||||
|
// body params
|
||||||
|
_sling = _sling.BodyJSON(project)
|
||||||
|
|
||||||
|
req, err := _sling.Request()
|
||||||
|
req.SetBasicAuth(prjUsr.Name, prjUsr.Passwd)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
httpResponse, err := client.Do(req)
|
||||||
|
defer httpResponse.Body.Close()
|
||||||
|
|
||||||
|
return httpResponse.StatusCode, err
|
||||||
|
}
|
15
tests/apitests/apilib/harborlogout.go
Normal file
15
tests/apitests/apilib/harborlogout.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// HarborLogout.go
|
||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a HarborAPI) HarborLogout() (int, error) {
|
||||||
|
|
||||||
|
response, err := http.Get(a.basePath + "/logout")
|
||||||
|
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
return response.StatusCode, err
|
||||||
|
}
|
28
tests/apitests/apilib/harlogin.go
Normal file
28
tests/apitests/apilib/harlogin.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// HarborLogon.go
|
||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a HarborAPI) HarborLogin(user UsrInfo) (int, error) {
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("principal", user.Name)
|
||||||
|
v.Set("password", user.Passwd)
|
||||||
|
|
||||||
|
body := ioutil.NopCloser(strings.NewReader(v.Encode())) //endode v:[body struce]
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
reqest, err := http.NewRequest("POST", a.basePath+"/login", body)
|
||||||
|
|
||||||
|
reqest.Header.Set("Content-Type", "application/x-www-form-urlencoded;param=value") //setting post head
|
||||||
|
|
||||||
|
resp, err := client.Do(reqest)
|
||||||
|
defer resp.Body.Close() //close resp.Body
|
||||||
|
|
||||||
|
return resp.StatusCode, err
|
||||||
|
}
|
15
tests/apitests/apilib/project.go
Normal file
15
tests/apitests/apilib/project.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
import ()
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
ProjectId int32 `json:"id,omitempty"`
|
||||||
|
OwnerId int32 `json:"owner_id,omitempty"`
|
||||||
|
ProjectName string `json:"project_name,omitempty"`
|
||||||
|
CreationTime string `json:"creation_time,omitempty"`
|
||||||
|
Deleted int32 `json:"deleted,omitempty"`
|
||||||
|
UserId int32 `json:"user_id,omitempty"`
|
||||||
|
OwnerName string `json:"owner_name,omitempty"`
|
||||||
|
Public bool `json:"public,omitempty"`
|
||||||
|
Togglable bool `json:"togglable,omitempty"`
|
||||||
|
}
|
9
tests/apitests/apilib/projecttemp4search.go
Normal file
9
tests/apitests/apilib/projecttemp4search.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
import ()
|
||||||
|
|
||||||
|
type Project4Search struct {
|
||||||
|
ProjectId int32 `json:"id,omitempty"`
|
||||||
|
ProjectName string `json:"name,omitempty"`
|
||||||
|
Public int32 `json:"public,omitempty"`
|
||||||
|
}
|
16
tests/apitests/apilib/repository.go
Normal file
16
tests/apitests/apilib/repository.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
Parent string `json:"parent,omitempty"`
|
||||||
|
Created time.Time `json:"created,omitempty"`
|
||||||
|
DurationDays string `json:"duration_days,omitempty"`
|
||||||
|
Author string `json:"author,omitempty"`
|
||||||
|
Architecture string `json:"architecture,omitempty"`
|
||||||
|
DockerVersion string `json:"docker_version,omitempty"`
|
||||||
|
Os string `json:"os,omitempty"`
|
||||||
|
}
|
9
tests/apitests/apilib/repositorytemp4search.go
Normal file
9
tests/apitests/apilib/repositorytemp4search.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
type Repository4Search struct {
|
||||||
|
ProjectId int32 `json:"project_id,omitempty"`
|
||||||
|
ProjectName string `json:"project_name,omitempty"`
|
||||||
|
ProjectPublic int32 `json:"project_public,omitempty"`
|
||||||
|
RepoName string `json:"repository_name,omitempty"`
|
||||||
|
}
|
||||||
|
|
7
tests/apitests/apilib/role.go
Normal file
7
tests/apitests/apilib/role.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
type Role struct {
|
||||||
|
RoleId int32 `json:"role_id,omitempty"`
|
||||||
|
RoleCode string `json:"role_code,omitempty"`
|
||||||
|
RoleName string `json:"role_name,omitempty"`
|
||||||
|
}
|
6
tests/apitests/apilib/roleparam.go
Normal file
6
tests/apitests/apilib/roleparam.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
type RoleParam struct {
|
||||||
|
Roles []int32 `json:"roles,omitempty"`
|
||||||
|
UserName string `json:"user_name,omitempty"`
|
||||||
|
}
|
8
tests/apitests/apilib/search.go
Normal file
8
tests/apitests/apilib/search.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
import ()
|
||||||
|
|
||||||
|
type Search struct {
|
||||||
|
Projects []Project4Search `json:"project,omitempty"`
|
||||||
|
Repositories []Repository4Search `json:"repository,omitempty"`
|
||||||
|
}
|
11
tests/apitests/apilib/user.go
Normal file
11
tests/apitests/apilib/user.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package HarborAPI
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
UserId int32 `json:"user_id,omitempty"`
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
Realname string `json:"realname,omitempty"`
|
||||||
|
Comment string `json:"comment,omitempty"`
|
||||||
|
Deleted int32 `json:"deleted,omitempty"`
|
||||||
|
}
|
95
tests/apitests/hbapiaddprj_test.go
Normal file
95
tests/apitests/hbapiaddprj_test.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package HarborAPItest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/apilib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAddProject(t *testing.T) {
|
||||||
|
|
||||||
|
fmt.Println("Test for Project Add (ProjectsPost) API\n")
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
apiTest := HarborAPI.NewHarborAPI()
|
||||||
|
|
||||||
|
//prepare for test
|
||||||
|
adminEr := &HarborAPI.UsrInfo{"admin", "Harbor1234"}
|
||||||
|
admin := &HarborAPI.UsrInfo{"admin", "Harbor12345"}
|
||||||
|
|
||||||
|
prjUsr := &HarborAPI.UsrInfo{"unknown", "unknown"}
|
||||||
|
|
||||||
|
var project HarborAPI.Project
|
||||||
|
project.ProjectName = "testProject"
|
||||||
|
project.Public = true
|
||||||
|
|
||||||
|
//case 1: admin login fail, expect project creation fail.
|
||||||
|
fmt.Println("case 1: admin login fail, expect project creation fail.")
|
||||||
|
resault, err := apiTest.HarborLogin(*adminEr)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error while admin login", err.Error())
|
||||||
|
t.Log(err)
|
||||||
|
} else {
|
||||||
|
assert.Equal(resault, int(401), "Admin login status should be 401")
|
||||||
|
//t.Log(resault)
|
||||||
|
}
|
||||||
|
|
||||||
|
resault, err = apiTest.ProjectsPost(*prjUsr, project)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error while creat project", err.Error())
|
||||||
|
t.Log(err)
|
||||||
|
} else {
|
||||||
|
assert.Equal(resault, int(401), "Case 1: Project creation status should be 401")
|
||||||
|
//t.Log(resault)
|
||||||
|
}
|
||||||
|
|
||||||
|
//case 2: admin successful login, expect project creation success.
|
||||||
|
fmt.Println("case 2: admin successful login, expect project creation success.")
|
||||||
|
resault, err = apiTest.HarborLogin(*admin)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error while admin login", err.Error())
|
||||||
|
t.Log(err)
|
||||||
|
} else {
|
||||||
|
assert.Equal(resault, int(200), "Admin login status should be 200")
|
||||||
|
//t.Log(resault)
|
||||||
|
}
|
||||||
|
if resault != 200 {
|
||||||
|
t.Log(resault)
|
||||||
|
} else {
|
||||||
|
prjUsr = admin
|
||||||
|
}
|
||||||
|
|
||||||
|
resault, err = apiTest.ProjectsPost(*prjUsr, project)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error while creat project", err.Error())
|
||||||
|
t.Log(err)
|
||||||
|
} else {
|
||||||
|
assert.Equal(resault, int(201), "Case 2: Project creation status should be 201")
|
||||||
|
//t.Log(resault)
|
||||||
|
}
|
||||||
|
|
||||||
|
//case 3: duplicate project name, create project fail
|
||||||
|
fmt.Println("case 3: duplicate project name, create project fail")
|
||||||
|
resault, err = apiTest.ProjectsPost(*prjUsr, project)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error while creat project", err.Error())
|
||||||
|
t.Log(err)
|
||||||
|
} else {
|
||||||
|
assert.Equal(resault, int(409), "Case 3: Project creation status should be 409")
|
||||||
|
//t.Log(resault)
|
||||||
|
}
|
||||||
|
|
||||||
|
//resault1, err := apiTest.HarborLogout()
|
||||||
|
//if err != nil {
|
||||||
|
// t.Error("Error while admin logout", err.Error())
|
||||||
|
// t.Log(err)
|
||||||
|
//} else {
|
||||||
|
// assert.Equal(resault1, int(200), "Admin logout status")
|
||||||
|
// //t.Log(resault)
|
||||||
|
//}
|
||||||
|
//if resault1 != 200 {
|
||||||
|
// t.Log(resault)
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
31
tests/apitests/hbapisearch_test.go
Normal file
31
tests/apitests/hbapisearch_test.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package HarborAPItest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/apilib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSearch(t *testing.T) {
|
||||||
|
fmt.Println("Test for Search (SearchGet) API\n")
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
apiTest := HarborAPI.NewHarborAPI()
|
||||||
|
var resault HarborAPI.Search
|
||||||
|
resault, err := apiTest.SearchGet("library")
|
||||||
|
//fmt.Printf("%+v\n", resault)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error while search project or repository", err.Error())
|
||||||
|
t.Log(err)
|
||||||
|
} else {
|
||||||
|
assert.Equal(resault.Projects[0].ProjectId, int32(1), "Project id should be equal")
|
||||||
|
assert.Equal(resault.Projects[0].ProjectName, "library", "Project name should be library")
|
||||||
|
assert.Equal(resault.Projects[0].Public, int32(1), "Project public status should be 1 (true)")
|
||||||
|
//t.Log(resault)
|
||||||
|
}
|
||||||
|
//if resault.Response.StatusCode != 200 {
|
||||||
|
// t.Log(resault.Response)
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
4
tests/hostcfg.sh
Executable file
4
tests/hostcfg.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
IP=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'`
|
||||||
|
#echo $IP
|
||||||
|
sed "s/reg.mydomain.com/$IP/" -i Deploy/harbor.cfg
|
36
tests/startuptest.go
Normal file
36
tests/startuptest.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Fetch prints the content found at a URL.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
time.Sleep(60*time.Second)
|
||||||
|
for _, url := range os.Args[1:] {
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// fmt.Printf("%s", b)
|
||||||
|
if strings.Contains(string(b), "Harbor") {
|
||||||
|
fmt.Printf("sucess!\n")
|
||||||
|
} else {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
11
tests/testprepare.sh
Executable file
11
tests/testprepare.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
IP=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'`
|
||||||
|
#echo $IP
|
||||||
|
docker pull hello-world
|
||||||
|
docker pull docker
|
||||||
|
#docker login -u admin -p Harbor12345 $IP
|
||||||
|
|
||||||
|
docker tag hello-world $IP/library/hello-world
|
||||||
|
docker push $IP/library/hello-world
|
||||||
|
|
||||||
|
docker tag docker $IP/library/docker
|
||||||
|
docker push $IP/library/docker
|
55
tests/userlogintest.go
Normal file
55
tests/userlogintest.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"flag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
usrNamePtr := flag.String("name","anaymous","user name")
|
||||||
|
usrPasswdPtr := flag.String("passwd","anaymous","user password")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("principal", *usrNamePtr)
|
||||||
|
v.Set("password", *usrPasswdPtr)
|
||||||
|
|
||||||
|
body := ioutil.NopCloser(strings.NewReader(v.Encode())) //endode v:[body struce]
|
||||||
|
fmt.Println(v)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
reqest, err := http.NewRequest("POST", "http://localhost/login", body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Fatal error ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
reqest.Header.Set("Content-Type", "application/x-www-form-urlencoded;param=value") //setting post head
|
||||||
|
|
||||||
|
resp, err := client.Do(reqest)
|
||||||
|
defer resp.Body.Close() //close resp.Body
|
||||||
|
|
||||||
|
fmt.Println("login status: ", resp.StatusCode) //print status code
|
||||||
|
|
||||||
|
//content_post, err := ioutil.ReadAll(resp.Body)
|
||||||
|
//if err != nil {
|
||||||
|
// fmt.Println("Fatal error ", err.Error())
|
||||||
|
//}
|
||||||
|
|
||||||
|
//fmt.Println(string(content_post)) //print reply
|
||||||
|
|
||||||
|
response, err := http.Get("http://localhost/api/logout")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Fatal error ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
fmt.Println("logout status: ", resp.StatusCode) //print status code
|
||||||
|
//content_get, err := ioutil.ReadAll(response.Body)
|
||||||
|
//fmt.Println(string(content_get))
|
||||||
|
|
||||||
|
}
|
@ -16,32 +16,32 @@
|
|||||||
<div class="col-sm-4"></div>
|
<div class="col-sm-4"></div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>{{i18n .Lang "title_change_password"}}</h1>
|
<h1>{{i18n .Lang "title_change_password"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<form class="form">
|
<form class="form">
|
||||||
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="OldPassword" class="control-label">{{i18n .Lang "old_password"}}</label>
|
<label for="OldPassword" class="control-label">{{i18n .Lang "old_password"}}</label>
|
||||||
<input type="password" class="form-control" id="OldPassword">
|
<input type="password" class="form-control" id="OldPassword">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="Password" class="control-label">{{i18n .Lang "new_password"}}</label>
|
<label for="Password" class="control-label">{{i18n .Lang "new_password"}}</label>
|
||||||
<input type="password" class="form-control" id="Password">
|
<input type="password" class="form-control" id="Password">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "password_description"}}</h6>
|
<h6>{{i18n .Lang "password_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="ConfirmedPassword" class="control-label">{{i18n .Lang "confirm_password"}}</label>
|
<label for="ConfirmedPassword" class="control-label">{{i18n .Lang "confirm_password"}}</label>
|
||||||
<input type="password" class="form-control" id="ConfirmedPassword">
|
<input type="password" class="form-control" id="ConfirmedPassword">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "password_description"}}</h6>
|
<h6>{{i18n .Lang "password_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button type="button" class="btn btn-default" id="btnSubmit">{{i18n .Lang "button_submit"}}</button>
|
<button type="button" class="btn btn-default" id="btnSubmit">{{i18n .Lang "button_submit"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4"></div>
|
<div class="col-sm-4"></div>
|
||||||
|
@ -19,19 +19,19 @@
|
|||||||
<h1>{{i18n .Lang "title_forgot_password"}}</h1>
|
<h1>{{i18n .Lang "title_forgot_password"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<form class="form">
|
<form class="form">
|
||||||
<div id="waiting1" class="waiting-nonfluid"></div>
|
<div id="waiting1" class="waiting-nonfluid"></div>
|
||||||
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="EmailF" class="control-label">{{i18n .Lang "email"}}</label>
|
<label for="EmailF" class="control-label">{{i18n .Lang "email"}}</label>
|
||||||
<input type="email" class="form-control" id="EmailF">
|
<input type="email" class="form-control" id="EmailF">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "forgot_password_description"}}</h6>
|
<h6>{{i18n .Lang "forgot_password_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button type="button" class="btn btn-default" id="btnSubmit">{{i18n .Lang "button_submit"}}</button>
|
<button type="button" class="btn btn-default" id="btnSubmit">{{i18n .Lang "button_submit"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4"></div>
|
<div class="col-sm-4"></div>
|
||||||
|
@ -13,25 +13,25 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<!-- Main jumbotron for a primary marketing message or call to action -->
|
<!-- Main jumbotron for a primary marketing message or call to action -->
|
||||||
<div class="jumbotron">
|
<div class="jumbotron">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<img class="pull-left" src="static/resources/image/Harbor_Logo_rec.png" alt="Harbor's Logo" height="180" width="360"/>
|
<img class="pull-left" src="static/resources/image/Harbor_Logo_rec.png" alt="Harbor's Logo" height="180" width="360"/>
|
||||||
<p class="pull-left" style="margin-top: 85px; color: #245580; font-size: 30pt; text-align: center; width: 60%;">{{i18n .Lang "index_title"}}</p>
|
<p class="pull-left" style="margin-top: 85px; color: #245580; font-size: 30pt; text-align: center; width: 60%;">{{i18n .Lang "index_title"}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<!-- Example row of columns -->
|
<!-- Example row of columns -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<p>{{i18n .Lang "index_desc"}}</p>
|
<p>{{i18n .Lang "index_desc"}}</p>
|
||||||
<p>{{i18n .Lang "index_desc_0"}}</p>
|
<p>{{i18n .Lang "index_desc_0"}}</p>
|
||||||
<p>{{i18n .Lang "index_desc_1"}}</p>
|
<p>{{i18n .Lang "index_desc_1"}}</p>
|
||||||
<p>{{i18n .Lang "index_desc_2"}}</p>
|
<p>{{i18n .Lang "index_desc_2"}}</p>
|
||||||
<p>{{i18n .Lang "index_desc_3"}}</p>
|
<p>{{i18n .Lang "index_desc_3"}}</p>
|
||||||
<p>{{i18n .Lang "index_desc_4"}}</p>
|
<p>{{i18n .Lang "index_desc_4"}}</p>
|
||||||
<p>{{i18n .Lang "index_desc_5"}}</p>
|
<p>{{i18n .Lang "index_desc_5"}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
<script src="static/resources/js/login.js"></script>
|
<script src="static/resources/js/login.js"></script>
|
@ -18,7 +18,7 @@
|
|||||||
<li>{{.ProjectName}}</li>
|
<li>{{.ProjectName}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
<div class="page-header" style="margin-top: -10px;">
|
<div class="page-header" style="margin-top: -10px;">
|
||||||
<h2>{{.ProjectName}} </h2></h4>{{i18n .Lang "owner"}}: {{.OwnerName}}</h4>
|
<h2>{{.ProjectName}} </h2><h4>{{i18n .Lang "owner"}}: {{.OwnerName}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div row="tabpanel">
|
<div row="tabpanel">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -29,152 +29,150 @@
|
|||||||
<li role="presentation" style="visibility: hidden;"><a href="#tabOperationLog" aria-controls="tabOperationLog" role="tab" data-toggle="tab">{{i18n .Lang "logs"}}</a></li>
|
<li role="presentation" style="visibility: hidden;"><a href="#tabOperationLog" aria-controls="tabOperationLog" role="tab" data-toggle="tab">{{i18n .Lang "logs"}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<input type="hidden" id="projectId" value="{{.ProjectId}}">
|
<input type="hidden" id="projectId" value="{{.ProjectId}}">
|
||||||
<input type="hidden" id="projectName" value="{{.ProjectName}}">
|
<input type="hidden" id="projectName" value="{{.ProjectName}}">
|
||||||
<input type="hidden" id="userId" value="{{.UserId}}">
|
<input type="hidden" id="userId" value="{{.UserId}}">
|
||||||
<input type="hidden" id="ownerId" value="{{.OwnerId}}">
|
<input type="hidden" id="ownerId" value="{{.OwnerId}}">
|
||||||
<input type="hidden" id="roleId" value="{{.RoleId}}">
|
<input type="hidden" id="roleId" value="{{.RoleId}}">
|
||||||
<input type="hidden" id="harborRegUrl" value="{{.HarborRegUrl}}">
|
<input type="hidden" id="harborRegUrl" value="{{.HarborRegUrl}}">
|
||||||
<input type="hidden" id="public" value="{{.Public}}">
|
<input type="hidden" id="public" value="{{.Public}}">
|
||||||
<input type="hidden" id="repoName" value="{{.RepoName}}">
|
<input type="hidden" id="repoName" value="{{.RepoName}}">
|
||||||
<!-- tab panes -->
|
<!-- tab panes -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div role="tabpanel" class="tab-pane" id="tabRepoInfo">
|
<div role="tabpanel" class="tab-pane" id="tabRepoInfo">
|
||||||
<form class="form-inline">
|
<form class="form-inline">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="sr-only" for="txtRepoName">{{i18n .Lang "repo_name"}}:</label>
|
<label class="sr-only" for="txtRepoName">{{i18n .Lang "repo_name"}}:</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-addon">{{i18n .Lang "repo_name"}}:</div>
|
<div class="input-group-addon">{{i18n .Lang "repo_name"}}:</div>
|
||||||
<input type="text" class="form-control" id="txtRepoName">
|
<input type="text" class="form-control" id="txtRepoName">
|
||||||
<span class="input-group-btn">
|
|
||||||
<button id="btnSearchRepo" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<p>
|
|
||||||
<div class="table-responsive div-height">
|
|
||||||
<div class="alert alert-danger" role="alert" id="divErrMsg"><center></center></div>
|
|
||||||
<div class="panel-group" id="accordionRepo" role="tablist" aria-multiselectable="true">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div role="tabpanel" class="tab-pane" id="tabUserInfo">
|
|
||||||
<form class="form-inline">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<label class="sr-only" for="txtSearchUser">{{i18n .Lang "username"}}:</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-addon">{{i18n .Lang "username"}}:</div>
|
|
||||||
<input type="text" class="form-control" id="txtSearchUser">
|
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button id="btnSearchUser" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
<button id="btnSearchRepo" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
|
<p/>
|
||||||
|
<div class="table-responsive div-height">
|
||||||
|
<div class="alert alert-danger" role="alert" id="divErrMsg"><center></center></div>
|
||||||
|
<div class="panel-group" id="accordionRepo" role="tablist" aria-multiselectable="true">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#dlgUser" id="btnAddUser">{{i18n .Lang "add_members"}}</button>
|
|
||||||
</form>
|
|
||||||
<p>
|
|
||||||
<div class="table-responsive div-height">
|
|
||||||
<table id="tblUser" class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>{{i18n .Lang "username"}}</th>
|
|
||||||
<th>{{i18n .Lang "role"}}</th>
|
|
||||||
<th>{{i18n .Lang "operation"}}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div role="tabpanel" class="tab-pane" id="tabUserInfo">
|
||||||
<div role="tabpanel" class="tab-pane" id="tabOperationLog">
|
<form class="form-inline">
|
||||||
<form class="form-inline">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="txtUserName" class="sr-only">{{i18n .Lang "username"}}:</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-addon">{{i18n .Lang "username"}}:</div>
|
|
||||||
<input type="text" class="form-control" id="txtSearchUserName">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button id="btnFilterLog" type="button" class="btn btn-primary" data-toggle="modal" data-target="#dlgSearch"><span class="glyphicon glyphicon-search"></span></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseAdvance" aria-expanded="false" aria-controls="collapseAdvance">{{i18n .Lang "advance"}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form>
|
|
||||||
<p></p>
|
|
||||||
<div class="collapse" id="collapseAdvance">
|
|
||||||
<form class="form">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="txtUserName" class="sr-only">{{i18n .Lang "operation"}}:</label>
|
<div class="input-group">
|
||||||
|
<label class="sr-only" for="txtSearchUser">{{i18n .Lang "username"}}:</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-addon">{{i18n .Lang "username"}}:</div>
|
||||||
|
<input type="text" class="form-control" id="txtSearchUser">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button id="btnSearchUser" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#dlgUser" id="btnAddUser">{{i18n .Lang "add_members"}}</button>
|
||||||
|
</form>
|
||||||
|
<p/>
|
||||||
|
<div class="table-responsive div-height">
|
||||||
|
<table id="tblUser" class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n .Lang "username"}}</th>
|
||||||
|
<th>{{i18n .Lang "role"}}</th>
|
||||||
|
<th>{{i18n .Lang "operation"}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div role="tabpanel" class="tab-pane" id="tabOperationLog">
|
||||||
|
<form class="form-inline">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="txtUserName" class="sr-only">{{i18n .Lang "username"}}:</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-addon">{{i18n .Lang "operation"}}:</div>
|
<div class="input-group-addon">{{i18n .Lang "username"}}:</div>
|
||||||
<span class="input-group-addon" id="spnFilterOption">
|
<input type="text" class="form-control" id="txtSearchUserName">
|
||||||
<input type="checkbox" name="chkAll" value="0"> {{i18n .Lang "all"}}
|
<span class="input-group-btn">
|
||||||
<input type="checkbox" name="chkOperation" value="create"> Create
|
<button id="btnFilterLog" type="button" class="btn btn-primary" data-toggle="modal" data-target="#dlgSearch"><span class="glyphicon glyphicon-search"></span></button>
|
||||||
<input type="checkbox" name="chkOperation" value="pull"> Pull
|
|
||||||
<input type="checkbox" name="chkOperation" value="push"> Push
|
|
||||||
<input type="checkbox" name="chkOperation" value="delete"> Delete
|
|
||||||
<input type="checkbox" name="chkOperation" value="others"> {{i18n .Lang "others"}}:
|
|
||||||
<input type="text" id="txtOthers" size="10">
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p></p>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="begindatepicker" class="sr-only">{{i18n .Lang "start_date"}}:</label>
|
<div class="input-group">
|
||||||
<div class="input-group">
|
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseAdvance" aria-expanded="false" aria-controls="collapseAdvance">{{i18n .Lang "advance"}}</button>
|
||||||
<div class="input-group-addon">{{i18n .Lang "start_date"}}:</div>
|
|
||||||
<div class="input-group date" id="datetimepicker1">
|
|
||||||
<input type="text" class="form-control" id="begindatepicker" readonly="readonly">
|
|
||||||
<span class="input-group-addon">
|
|
||||||
<span class="glyphicon glyphicon-calendar"></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<p/>
|
||||||
<div class="input-group">
|
<div class="collapse" id="collapseAdvance">
|
||||||
<div class="input-group-addon">{{i18n .Lang "end_date"}}:</div>
|
<form class="form">
|
||||||
<div class="input-group date" id="datetimepicker2">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" id="enddatepicker" readonly="readonly">
|
<label for="txtUserName" class="sr-only">{{i18n .Lang "operation"}}:</label>
|
||||||
<span class="input-group-addon">
|
<div class="input-group">
|
||||||
<span class="glyphicon glyphicon-calendar"></span>
|
<div class="input-group-addon">{{i18n .Lang "operation"}}:</div>
|
||||||
</span>
|
<span class="input-group-addon" id="spnFilterOption">
|
||||||
</div>
|
<input type="checkbox" name="chkAll" value="0"> {{i18n .Lang "all"}}
|
||||||
</div>
|
<input type="checkbox" name="chkOperation" value="create"> Create
|
||||||
|
<input type="checkbox" name="chkOperation" value="pull"> Pull
|
||||||
</div>
|
<input type="checkbox" name="chkOperation" value="push"> Push
|
||||||
</form>
|
<input type="checkbox" name="chkOperation" value="delete"> Delete
|
||||||
</div>
|
<input type="checkbox" name="chkOperation" value="others"> {{i18n .Lang "others"}}:
|
||||||
<div class="table-responsive div-height">
|
<input type="text" id="txtOthers" size="10">
|
||||||
<table id="tblAccessLog" class="table table-hover" >
|
</span>
|
||||||
<thead>
|
</div>
|
||||||
<tr>
|
</div>
|
||||||
<th width="15%">{{i18n .Lang "username"}}</th>
|
<p></p>
|
||||||
<th width="30%">{{i18n .Lang "repo_name"}}</th>
|
<div class="form-group">
|
||||||
<th width="15%">{{i18n .Lang "repo_tag"}}</th>
|
<label for="begindatepicker" class="sr-only">{{i18n .Lang "start_date"}}:</label>
|
||||||
<th width="15%">{{i18n .Lang "operation"}}</th>
|
<div class="input-group">
|
||||||
<th width="15%">{{i18n .Lang "timestamp"}}</th>
|
<div class="input-group-addon">{{i18n .Lang "start_date"}}:</div>
|
||||||
</tr>
|
<div class="input-group date" id="datetimepicker1">
|
||||||
</thead>
|
<input type="text" class="form-control" id="begindatepicker" readonly="readonly">
|
||||||
<tbody>
|
<span class="input-group-addon">
|
||||||
</tbody>
|
<span class="glyphicon glyphicon-calendar"></span>
|
||||||
</table>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-addon">{{i18n .Lang "end_date"}}:</div>
|
||||||
|
<div class="input-group date" id="datetimepicker2">
|
||||||
|
<input type="text" class="form-control" id="enddatepicker" readonly="readonly">
|
||||||
|
<span class="input-group-addon">
|
||||||
|
<span class="glyphicon glyphicon-calendar"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive div-height">
|
||||||
|
<table id="tblAccessLog" class="table table-hover" >
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="15%">{{i18n .Lang "username"}}</th>
|
||||||
|
<th width="30%">{{i18n .Lang "repo_name"}}</th>
|
||||||
|
<th width="15%">{{i18n .Lang "repo_tag"}}</th>
|
||||||
|
<th width="15%">{{i18n .Lang "operation"}}</th>
|
||||||
|
<th width="15%">{{i18n .Lang "timestamp"}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="modal fade" id="dlgUser" tabindex="-1" role="dialog" aria-labelledby="User" aria-hidden="true">
|
<div class="modal fade" id="dlgUser" tabindex="-1" role="dialog" aria-labelledby="User" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
@ -25,24 +25,24 @@
|
|||||||
<!-- tab panes -->
|
<!-- tab panes -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div role="tabpanel" class="tab-pane" id="tabMyProject" style="margin-top: 15px;">
|
<div role="tabpanel" class="tab-pane" id="tabMyProject" style="margin-top: 15px;">
|
||||||
<form class="form-inline">
|
<form class="form-inline">
|
||||||
<label class="sr-only" for="txtProjectName">{{i18n .Lang "project_name"}}:</label>
|
<label class="sr-only" for="txtProjectName">{{i18n .Lang "project_name"}}:</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-addon">{{i18n .Lang "project_name"}}:</div>
|
<div class="input-group-addon">{{i18n .Lang "project_name"}}:</div>
|
||||||
<input type="text" class="form-control" id="txtSearchProject">
|
<input type="text" class="form-control" id="txtSearchProject">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button id="btnSearch" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
<button id="btnSearch" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#dlgAddProject" id="btnAddProject">{{i18n .Lang "add_project"}}</button>
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#dlgAddProject" id="btnAddProject">{{i18n .Lang "add_project"}}</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="table-responsive div-height">
|
<div class="table-responsive div-height">
|
||||||
<table id="tblProject" class="table table-hover">
|
<table id="tblProject" class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="35%">{{i18n .Lang "project_name"}}</th>
|
<th width="35%">{{i18n .Lang "project_name"}}</th>
|
||||||
<th width="45%">{{i18n .Lang "creation_time"}}</th>
|
<th width="45%">{{i18n .Lang "creation_time"}}</th>
|
||||||
<th width="20%">{{i18n .Lang "publicity"}}</th>
|
<th width="20%">{{i18n .Lang "publicity"}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -51,65 +51,65 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabAdminOption" style="visibility: hidden; margin-top: 15px;">
|
<div role="tabpanel" class="tab-pane" id="tabAdminOption" style="visibility: hidden; margin-top: 15px;">
|
||||||
<form class="form-inline">
|
<form class="form-inline">
|
||||||
<label class="sr-only" for="txtProjectName">{{i18n .Lang "username"}}:</label>
|
<label class="sr-only" for="txtProjectName">{{i18n .Lang "username"}}:</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-addon">{{i18n .Lang "username"}}:</div>
|
<div class="input-group-addon">{{i18n .Lang "username"}}:</div>
|
||||||
<input type="text" class="form-control" id="txtSearchUsername">
|
<input type="text" class="form-control" id="txtSearchUsername">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button id="btnSearchUsername" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
<button id="btnSearchUsername" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div class="table-responsive div-height">
|
|
||||||
<table id="tblUser" class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th width="35%">{{i18n .Lang "username"}}</th>
|
|
||||||
<th width="45%">{{i18n .Lang "email"}}</th>
|
|
||||||
<th width="20%">{{i18n .Lang "system_admin"}}</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
<div class="table-responsive div-height">
|
||||||
</div>
|
<table id="tblUser" class="table table-hover">
|
||||||
</div>
|
<thead>
|
||||||
<div class="modal fade" id="dlgAddProject" tabindex="-1" role="dialog" aria-labelledby="Add Project" aria-hidden="true">
|
<tr>
|
||||||
<div class="modal-dialog">
|
<th width="35%">{{i18n .Lang "username"}}</th>
|
||||||
<div class="modal-content">
|
<th width="45%">{{i18n .Lang "email"}}</th>
|
||||||
<div class="modal-header">
|
<th width="20%">{{i18n .Lang "system_admin"}}</th>
|
||||||
<a type="button" class="close" data-dismiss="modal" aria-label="Close" id="btnCancel">
|
<th></th>
|
||||||
<span aria-hidden="true">×</span>
|
</tr>
|
||||||
</a>
|
</thead>
|
||||||
<h4 class="modal-title" id="dlgAddProjectTitle">{{i18n .Lang "add_project"}}</h4>
|
<tbody>
|
||||||
</div>
|
</tbody>
|
||||||
<div class="modal-body">
|
</table>
|
||||||
<form role="form">
|
|
||||||
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
|
||||||
<div class="form-group has-feedback">
|
|
||||||
<label for="projectName" class="control-label">{{i18n .Lang "project_name"}}:</label>
|
|
||||||
<input type="text" class="form-control" id="projectName">
|
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" id="isPublic" checked=false> {{i18n .Lang "check_for_publicity"}}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-primary" id="btnSave">{{i18n .Lang "button_save"}}</button>
|
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{i18n .Lang "button_cancel"}}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal fade" id="dlgAddProject" tabindex="-1" role="dialog" aria-labelledby="Add Project" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<a type="button" class="close" data-dismiss="modal" aria-label="Close" id="btnCancel">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</a>
|
||||||
|
<h4 class="modal-title" id="dlgAddProjectTitle">{{i18n .Lang "add_project"}}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form role="form">
|
||||||
|
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
||||||
|
<div class="form-group has-feedback">
|
||||||
|
<label for="projectName" class="control-label">{{i18n .Lang "project_name"}}:</label>
|
||||||
|
<input type="text" class="form-control" id="projectName">
|
||||||
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="isPublic" checked=false> {{i18n .Lang "check_for_publicity"}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" id="btnSave">{{i18n .Lang "button_save"}}</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{i18n .Lang "button_cancel"}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script src="static/resources/js/validate-options.js"></script>
|
<script src="static/resources/js/validate-options.js"></script>
|
||||||
<script src="static/resources/js/project.js"></script>
|
<script src="static/resources/js/project.js"></script>
|
||||||
|
@ -16,65 +16,65 @@
|
|||||||
<div class="col-sm-4"></div>
|
<div class="col-sm-4"></div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
{{ if eq .IsAdmin true }}
|
{{ if eq .IsAdmin true }}
|
||||||
<h1>{{i18n .Lang "add_user" }}</h1>
|
<h1>{{i18n .Lang "add_user" }}</h1>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<h1>{{i18n .Lang "registration"}}</h1>
|
<h1>{{i18n .Lang "registration"}}</h1>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<form class="form">
|
<form class="form">
|
||||||
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="username" class="control-label">{{i18n .Lang "username"}}</label>
|
<label for="username" class="control-label">{{i18n .Lang "username"}}</label>
|
||||||
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
||||||
<input type="text" class="form-control" id="Username">
|
<input type="text" class="form-control" id="Username">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "username_description"}}</h6>
|
<h6>{{i18n .Lang "username_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="Email" class="control-label">{{i18n .Lang "email"}}</label>
|
<label for="Email" class="control-label">{{i18n .Lang "email"}}</label>
|
||||||
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
||||||
<input type="email" class="form-control" id="Email">
|
<input type="email" class="form-control" id="Email">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "email_description"}}</h6>
|
<h6>{{i18n .Lang "email_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="Realname" class="control-label">{{i18n .Lang "full_name"}}</label>
|
<label for="Realname" class="control-label">{{i18n .Lang "full_name"}}</label>
|
||||||
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
||||||
<input type="text" class="form-control" id="Realname">
|
<input type="text" class="form-control" id="Realname">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "full_name_description"}}</h6>
|
<h6>{{i18n .Lang "full_name_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="Password" class="control-label">{{i18n .Lang "password"}}</label>
|
<label for="Password" class="control-label">{{i18n .Lang "password"}}</label>
|
||||||
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
||||||
<input type="password" class="form-control" id="Password">
|
<input type="password" class="form-control" id="Password">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "password_description"}}</h6>
|
<h6>{{i18n .Lang "password_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="ConfirmedPassword" class="control-label">{{i18n .Lang "confirm_password"}}</label>
|
<label for="ConfirmedPassword" class="control-label">{{i18n .Lang "confirm_password"}}</label>
|
||||||
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
<p style="display:inline; color: red; font-size: 12pt;">*</p>
|
||||||
<input type="password" class="form-control" id="ConfirmedPassword">
|
<input type="password" class="form-control" id="ConfirmedPassword">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "password_description"}}</h6>
|
<h6>{{i18n .Lang "password_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="Comment" class="control-label">{{i18n .Lang "note_to_the_admin"}}</label>
|
<label for="Comment" class="control-label">{{i18n .Lang "note_to_the_admin"}}</label>
|
||||||
<input type="text" class="form-control" id="Comment">
|
<input type="text" class="form-control" id="Comment">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button type="button" class="btn btn-default" id="btnPageSignUp">
|
<button type="button" class="btn btn-default" id="btnPageSignUp">
|
||||||
{{ if eq .IsAdmin true }}
|
{{ if eq .IsAdmin true }}
|
||||||
{{i18n .Lang "add_user" }}
|
{{i18n .Lang "add_user" }}
|
||||||
{{ else }}
|
{{ else }}
|
||||||
{{i18n .Lang "sign_up"}}
|
{{i18n .Lang "sign_up"}}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4"></div>
|
<div class="col-sm-4"></div>
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
-->
|
-->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<p>{{.Hint}}:</p>
|
<p>{{.Hint}}:</p>
|
||||||
<a href="{{.URL}}/resetPassword?reset_uuid={{.UUID}}">{{.URL}}/resetPassword?reset_uuid={{.UUID}}</a>
|
<a href="{{.URL}}/resetPassword?reset_uuid={{.UUID}}">{{.URL}}/resetPassword?reset_uuid={{.UUID}}</a>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -17,27 +17,27 @@
|
|||||||
<div class="col-sm-4"></div>
|
<div class="col-sm-4"></div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>{{i18n .Lang "title_reset_password"}}</h1>
|
<h1>{{i18n .Lang "title_reset_password"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<form class="form">
|
<form class="form">
|
||||||
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="Password" class="control-label">{{i18n .Lang "password"}}</label>
|
<label for="Password" class="control-label">{{i18n .Lang "password"}}</label>
|
||||||
<input type="password" class="form-control" id="Password">
|
<input type="password" class="form-control" id="Password">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "password_description"}}</h6>
|
<h6>{{i18n .Lang "password_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<label for="ConfirmedPassword" class="control-label">{{i18n .Lang "confirm_password"}}</label>
|
<label for="ConfirmedPassword" class="control-label">{{i18n .Lang "confirm_password"}}</label>
|
||||||
<input type="password" class="form-control" id="ConfirmedPassword">
|
<input type="password" class="form-control" id="ConfirmedPassword">
|
||||||
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
|
||||||
<h6>{{i18n .Lang "password_description"}}</h6>
|
<h6>{{i18n .Lang "password_description"}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback">
|
<div class="form-group has-feedback">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button type="button" class="btn btn-default" id="btnSubmit">{{i18n .Lang "button_submit"}}</button>
|
<button type="button" class="btn btn-default" id="btnSubmit">{{i18n .Lang "button_submit"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4"></div>
|
<div class="col-sm-4"></div>
|
||||||
|
@ -18,15 +18,15 @@
|
|||||||
<li><a href="/">{{i18n .Lang "home"}}</a></li>
|
<li><a href="/">{{i18n .Lang "home"}}</a></li>
|
||||||
<li>{{i18n .Lang "search"}}</li>
|
<li>{{i18n .Lang "search"}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading" id="panelCommonSearchProjectsHeader">{{i18n .Lang "projects"}}</div>
|
<div class="panel-heading" id="panelCommonSearchProjectsHeader">{{i18n .Lang "projects"}}</div>
|
||||||
<div class="panel-body" id="panelCommonSearchProjectsBody">
|
<div class="panel-body" id="panelCommonSearchProjectsBody">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading" id="panelCommonSearchRepositoriesHeader">{{i18n .Lang "repositories"}}</div>
|
<div class="panel-heading" id="panelCommonSearchRepositoriesHeader">{{i18n .Lang "repositories"}}</div>
|
||||||
<div class="panel-body" id="panelCommonSearchRepositoriesBody">
|
<div class="panel-body" id="panelCommonSearchRepositoriesBody">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="static/resources/js/search.js"></script>
|
<script src="static/resources/js/search.js"></script>
|
@ -14,15 +14,15 @@
|
|||||||
-->
|
-->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
{{.HeaderInc}}
|
{{.HeaderInc}}
|
||||||
<title>{{.PageTitle}}</title>
|
<title>{{.PageTitle}}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{.HeaderContent}}
|
{{.HeaderContent}}
|
||||||
{{.BodyContent}}
|
{{.BodyContent}}
|
||||||
{{.FooterInc}}
|
{{.FooterInc}}
|
||||||
{{.ModalDialog}}
|
{{.ModalDialog}}
|
||||||
{{.FootContent}}
|
{{.FootContent}}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -13,11 +13,11 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-5 col-md-offset-4">
|
<div class="col-md-5 col-md-offset-4">
|
||||||
<p class="text-muted">{{i18n .Lang "copyright"}} © 2015-2016 VMware, Inc. {{i18n .Lang "all_rights_reserved"}}</p>
|
<p class="text-muted">{{i18n .Lang "copyright"}} © 2015-2016 VMware, Inc. {{i18n .Lang "all_rights_reserved"}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
@ -11,80 +11,83 @@
|
|||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<input type="hidden" id="currentLanguage" value="{{.Lang}}">
|
<input type="hidden" id="currentLanguage" value="{{.Lang}}">
|
||||||
<input type="hidden" id="isAdmin" value="{{.IsAdmin}}">
|
<input type="hidden" id="isAdmin" value="{{.IsAdmin}}">
|
||||||
<nav class="navbar navbar-default" role="navigation" style="margin-bottom: 0;">
|
<nav class="navbar navbar-default" role="navigation" style="margin-bottom: 0;">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button aria-controls="navbar" aria-expanded="false" data-target="#navbar" data-toggle="collapse" class="navbar-toggle collapsed" type="button">
|
<button aria-controls="navbar" aria-expanded="false" data-target="#navbar" data-toggle="collapse" class="navbar-toggle collapsed" type="button">
|
||||||
<span class="sr-only">Toggle navigation</span>
|
<span class="sr-only">Toggle navigation</span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="/"><img src="static/resources/image/Harbor_Logo_rec.png" height="40px" width="80px"/></a>
|
<a class="navbar-brand" href="/"><img src="static/resources/image/Harbor_Logo_rec.png" height="40px" width="80px"/></a>
|
||||||
</div>
|
</div>
|
||||||
<div id="navbar" class="navbar-collapse collapse">
|
<div id="navbar" class="navbar-collapse collapse">
|
||||||
<form class="navbar-form navbar-right">
|
<form class="navbar-form navbar-right">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
|
||||||
<span class="glyphicon glyphicon-globe"></span>
|
<span class="glyphicon glyphicon-globe"></span>
|
||||||
{{i18n .Lang "language"}}
|
{{i18n .Lang "language"}}
|
||||||
<span class="caret"></span></a>
|
<span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="/language?lang=en-US">{{i18n .Lang "language_en-US"}}</a></li>
|
<li><a href="/language?lang=en-US">{{i18n .Lang "language_en-US"}}</a></li>
|
||||||
<li><a href="/language?lang=zh-CN">{{i18n .Lang "language_zh-CN"}}</a></li>
|
<li><a href="/language?lang=zh-CN">{{i18n .Lang "language_zh-CN"}}</a></li>
|
||||||
<li><a href="/language?lang=de-DE">{{i18n .Lang "language_de-DE"}}</a></li>
|
<li><a href="/language?lang=de-DE">{{i18n .Lang "language_de-DE"}}</a></li>
|
||||||
<li><a href="/language?lang=ru-RU">{{i18n .Lang "language_ru-RU"}}</a></li>
|
<li><a href="/language?lang=ru-RU">{{i18n .Lang "language_ru-RU"}}</a></li>
|
||||||
<li><a href="/language?lang=ja-JP">{{i18n .Lang "language_ja-JP"}}</a></li>
|
<li><a href="/language?lang=ja-JP">{{i18n .Lang "language_ja-JP"}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group" >
|
|
||||||
<span class="input-group-addon"><span class="input-group glyphicon glyphicon-search"></span></span>
|
|
||||||
<input type="text" class="form-control" id="txtCommonSearch" size="50" placeholder="{{i18n .Lang "search_placeholder"}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ if .Username }}
|
|
||||||
<div class="input-group">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-user"></span> {{.Username}}<span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
{{ if eq .AuthMode "db_auth" }}
|
|
||||||
<li><a id="aChangePassword" href="/changePassword" target="_blank"><span class="glyphicon glyphicon-pencil"></span> {{i18n .Lang "change_password"}}</a></li>
|
|
||||||
<li role="separator" class="divider"></li>
|
|
||||||
{{ end }}
|
|
||||||
{{ if eq .IsLdapAdminUser true }}
|
|
||||||
<li><a id="aChangePassword" href="/changePassword" target="_blank"><span class="glyphicon glyphicon-pencil"></span> {{i18n .Lang "change_password"}}</a></li>
|
|
||||||
<li role="separator" class="divider"></li>
|
|
||||||
{{ end }}
|
|
||||||
{{ if eq .AuthMode "db_auth" }}
|
|
||||||
{{ if eq .IsAdmin true }}
|
|
||||||
<li><a id="aAddUser" href="/addUser" target="_blank"><span class="glyphicon glyphicon-plus"></span> {{i18n .Lang "add_user"}}</a></li>
|
|
||||||
{{ end }}
|
|
||||||
{{ end}}
|
|
||||||
<li><a id="aLogout" href="#"><span class="glyphicon glyphicon-log-in"></span> {{i18n .Lang "log_out"}}</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
|
||||||
</div>
|
<div class="input-group" >
|
||||||
{{ else if eq .AuthMode "db_auth" }}
|
<span class="input-group-addon"><span class="input-group glyphicon glyphicon-search"></span></span>
|
||||||
<div class="input-group">
|
<input type="text" class="form-control" id="txtCommonSearch" size="50" placeholder="{{i18n .Lang "search_placeholder"}}">
|
||||||
<button type="button" class="btn btn-default" id="btnSignIn">{{i18n .Lang "sign_in"}}</button>
|
</div>
|
||||||
{{ if eq .SelfRegistration true }}
|
</div>
|
||||||
<button type="button" class="btn btn-success" id="btnSignUp">{{i18n .Lang "sign_up"}}</button>
|
{{ if .Username }}
|
||||||
|
<div class="input-group">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-user"></span> {{.Username}}<span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{{ if eq .AuthMode "db_auth" }}
|
||||||
|
<li><a id="aChangePassword" href="/changePassword" target="_blank"><span class="glyphicon glyphicon-pencil"></span> {{i18n .Lang "change_password"}}</a></li>
|
||||||
|
<li role="separator" class="divider"></li>
|
||||||
|
{{ end }}
|
||||||
|
{{ if eq .IsLdapAdminUser true }}
|
||||||
|
<li><a id="aChangePassword" href="/changePassword" target="_blank"><span class="glyphicon glyphicon-pencil"></span> {{i18n .Lang "change_password"}}</a></li>
|
||||||
|
<li role="separator" class="divider"></li>
|
||||||
|
{{ end }}
|
||||||
|
{{ if eq .AuthMode "db_auth" }}
|
||||||
|
{{ if eq .IsAdmin true }}
|
||||||
|
<li><a id="aAddUser" href="/addUser" target="_blank"><span class="glyphicon glyphicon-plus"></span> {{i18n .Lang "add_user"}}</a></li>
|
||||||
|
{{ end }}
|
||||||
|
{{ end}}
|
||||||
|
<li><a id="aLogout" href="#"><span class="glyphicon glyphicon-log-in"></span> {{i18n .Lang "log_out"}}</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{ else if eq .AuthMode "db_auth" }}
|
||||||
|
<div class="input-group">
|
||||||
|
<button type="button" class="btn btn-default" id="btnSignIn">{{i18n .Lang "sign_in"}}</button>
|
||||||
|
{{ if eq .SelfRegistration true }}
|
||||||
|
<button type="button" class="btn btn-success" id="btnSignUp">{{i18n .Lang "sign_up"}}</button>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ else }}
|
||||||
|
<div class="input-group">
|
||||||
|
<button type="button" class="btn btn-default" id="btnSignIn">{{i18n .Lang "sign_in"}}</button>
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</form>
|
||||||
{{ else }}
|
</div>
|
||||||
<div class="input-group">
|
</nav>
|
||||||
<button type="button" class="btn btn-default" id="btnSignIn">{{i18n .Lang "sign_in"}}</button>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
@ -13,26 +13,26 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<style>
|
<style>
|
||||||
.center {
|
.center {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
top: 10%;
|
top: 10%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<!-- Modal -->
|
<!-- Modal -->
|
||||||
<div class="center modal fade" id="dlgModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
<div class="center modal fade" id="dlgModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="dlgLabel"></h4>
|
<h4 class="modal-title" id="dlgLabel"></h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body" id="dlgBody">
|
<div class="modal-body" id="dlgBody">
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-primary" id="dlgConfirm" data-dismiss="modal">{{i18n .Lang "dlg_button_ok"}}</button>
|
<button type="button" class="btn btn-primary" id="dlgConfirm" data-dismiss="modal">{{i18n .Lang "dlg_button_ok"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="dlgCancel" data-dismiss="modal" style="display: none;">{{i18n .Lang "dlg_button_cancel"}}</button>
|
<button type="button" class="btn btn-primary" id="dlgCancel" data-dismiss="modal" style="display: none;">{{i18n .Lang "dlg_button_cancel"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -13,28 +13,28 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<form class="form-signin form-horizontal">
|
<form class="form-signin form-horizontal">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="Principal" class="col-md-4 control-label">{{i18n .Lang "username_email"}}</label>
|
<label for="Principal" class="col-md-4 control-label">{{i18n .Lang "username_email"}}</label>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<input type="text" id="Principal" class="form-control" placeholder="{{i18n .Lang "username_email"}}">
|
<input type="text" id="Principal" class="form-control" placeholder="{{i18n .Lang "username_email"}}">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label for="Password" class="col-md-4 control-label">{{i18n .Lang "password"}}</label>
|
||||||
<label for="Password" class="col-md-4 control-label">{{i18n .Lang "password"}}</label>
|
<div class="col-md-8">
|
||||||
<div class="col-md-8">
|
<input type="password" id="Password" class="form-control" placeholder="{{i18n .Lang "password"}}">
|
||||||
<input type="password" id="Password" class="form-control" placeholder="{{i18n .Lang "password"}}">
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<button class="btn btn-lg btn-primary btn-block" type="button" id="btnPageSignIn">{{i18n .Lang "sign_in"}}</button>
|
||||||
<button class="btn btn-lg btn-primary btn-block" type="button" id="btnPageSignIn">{{i18n .Lang "sign_in"}}</button>
|
{{ if eq .AuthMode "db_auth" }}
|
||||||
{{ if eq .AuthMode "db_auth" }}
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<div class="col-md-12">
|
||||||
<div class="col-md-12">
|
<button type="button" class="btn btn-link pull-right" id="btnForgot">{{i18n .Lang "forgot_password"}}</button>
|
||||||
<button type="button" class="btn btn-link pull-right" id="btnForgot">{{i18n .Lang "forgot_password"}}</button>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{ end }}
|
||||||
{{ end }}
|
</form>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
<link href="static/resources/css/sign-in.css" type="text/css" rel="stylesheet">
|
<link href="static/resources/css/sign-in.css" type="text/css" rel="stylesheet">
|
||||||
<script src="static/resources/js/sign-in.js"></script>
|
<script src="static/resources/js/sign-in.js"></script>
|
Loading…
Reference in New Issue
Block a user