mirror of
https://github.com/semaphoreui/semaphore.git
synced 2025-01-20 15:29:28 +01:00
Improve UI, add Names to things
- Document some more - Add names to Repository/environment/inventory - UI for new Template
This commit is contained in:
parent
a9011c3c64
commit
990f1e7f90
3
database/sql_migrations/v1.3.0.sql
Normal file
3
database/sql_migrations/v1.3.0.sql
Normal file
@ -0,0 +1,3 @@
|
||||
alter table project__environment add `name` varchar(255) not null;
|
||||
alter table project__inventory add `name` varchar(255) not null;
|
||||
alter table project__repository add `name` varchar(255) not null;
|
@ -57,5 +57,7 @@ func init() {
|
||||
{},
|
||||
{Major: 1},
|
||||
{Major: 1, Minor: 1},
|
||||
{Major: 1, Minor: 2},
|
||||
{Major: 1, Minor: 3},
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,10 @@ import "github.com/ansible-semaphore/semaphore/database"
|
||||
|
||||
type Environment struct {
|
||||
ID int `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name" binding:"required"`
|
||||
ProjectID int `db:"project_id" json:"project_id"`
|
||||
Password *string `db:"password" json:"password"`
|
||||
JSON string `db:"json" json:"json"`
|
||||
JSON string `db:"json" json:"json" binding:"required"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -4,6 +4,7 @@ import "github.com/ansible-semaphore/semaphore/database"
|
||||
|
||||
type Inventory struct {
|
||||
ID int `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name" binding:"required"`
|
||||
ProjectID int `db:"project_id" json:"project_id"`
|
||||
Inventory string `db:"inventory" json:"inventory"`
|
||||
|
||||
|
@ -4,6 +4,7 @@ import "github.com/ansible-semaphore/semaphore/database"
|
||||
|
||||
type Repository struct {
|
||||
ID int `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name" binding:"required"`
|
||||
ProjectID int `db:"project_id" json:"project_id"`
|
||||
GitUrl string `db:"git_url" json:"git_url" binding:"required"`
|
||||
SshKeyID int `db:"ssh_key_id" json:"ssh_key_id" binding:"required"`
|
||||
|
@ -17,8 +17,8 @@ html(lang="en" ng-app="semaphore")
|
||||
ul.nav.navbar-nav
|
||||
li(ng-class="{ active: $state.includes('dashboard') }")
|
||||
a(ui-sref="dashboard") Dashboard
|
||||
li(ng-class="{ active: $state.includes('keys') }")
|
||||
a(ui-sref="keys") Key Store
|
||||
//- li(ng-class="{ active: $state.includes('keys') }")
|
||||
//- a(ui-sref="keys") Key Store
|
||||
li(ng-class="{ active: $state.includes('users') }")
|
||||
a(ui-sref="users") Users
|
||||
|
||||
|
@ -2,4 +2,4 @@ h3 Environment
|
||||
|
||||
table.table
|
||||
tbody: tr(ng-repeat="env in environment")
|
||||
td {{ env.id }}
|
||||
td {{ env.name }}
|
@ -2,4 +2,4 @@ h3 Inventory
|
||||
|
||||
table.table
|
||||
tbody: tr(ng-repeat="inv in inventory")
|
||||
td {{ inv.id }} - {{ inv.type }}
|
||||
td {{ inv.name }} - {{ inv.type }}
|
@ -1,12 +1,12 @@
|
||||
h3 Keys
|
||||
button.btn.btn-default.pull-right(ng-click="add()") Create Key
|
||||
button.btn.btn-success.btn-xs.pull-right(ng-click="add()") Create Key
|
||||
|
||||
table.table
|
||||
thead: tr
|
||||
th Name
|
||||
th Type
|
||||
th Key
|
||||
th.col-sm-2 Name
|
||||
th.col-sm-2 Type
|
||||
th.col-sm-8 Key
|
||||
tbody: tr(ng-repeat="key in keys")
|
||||
td {{ key.name }}
|
||||
td {{ key.type }}
|
||||
td {{ key.key }}
|
||||
td: code {{ key.type }}
|
||||
td: pre: code {{ key.key }}
|
@ -1,5 +0,0 @@
|
||||
h3 Repositories
|
||||
|
||||
table.table
|
||||
tbody: tr(ng-repeat="repo in repositories")
|
||||
td {{ repo.id }} - {{ repo.git_url }}
|
20
public/html/projects/repositories/add.jade
Normal file
20
public/html/projects/repositories/add.jade
Normal file
@ -0,0 +1,20 @@
|
||||
.modal-header
|
||||
h4.modal-title Create Repository
|
||||
.modal-body
|
||||
form.form-horizontal
|
||||
.form-group
|
||||
label.control-label.col-sm-4 Name
|
||||
.col-sm-6
|
||||
input.form-control(type="text" ng-model="repo.name" placeholder="Friendly Repository Name")
|
||||
.form-group
|
||||
label.control-label.col-sm-4 Repository
|
||||
.col-sm-6
|
||||
input.form-control(type="text" ng-model="repo.git_url" placeholder="git@github.com:user/repo.git")
|
||||
.form-group
|
||||
label.control-label.col-sm-4 SSH Key
|
||||
.col-sm-6
|
||||
select.form-control(ng-model="repo.ssh_key_id" ng-options="key.id as key.name for key in keys")
|
||||
option(value="") -- Select SSH Key --
|
||||
.modal-footer
|
||||
button.btn.btn-default.pull-left(ng-click="$dismiss()") Dismiss
|
||||
button.btn.btn-success(ng-click="$close(repo)") Create
|
14
public/html/projects/repositories/list.jade
Normal file
14
public/html/projects/repositories/list.jade
Normal file
@ -0,0 +1,14 @@
|
||||
h3 Repositories
|
||||
button.btn.btn-success.btn-xs.pull-right(ng-click="add()") Create Repository
|
||||
|
||||
table.table
|
||||
thead: tr
|
||||
th Name
|
||||
th Git URL
|
||||
th SSH Key
|
||||
th
|
||||
tbody: tr(ng-repeat="repo in repositories")
|
||||
td {{ repo.name }}
|
||||
td {{ repo.git_url }}
|
||||
td {{ repo.ssh_key_id }}
|
||||
td: button.btn.btn-danger.btn-xs.pull-right(ng-click="remove(repo)") delete
|
@ -1,5 +0,0 @@
|
||||
h3 Task Templates
|
||||
|
||||
table.table
|
||||
tbody: tr(ng-repeat="tpl in templates")
|
||||
td {{ tpl.id }} - {{ tpl.playbook }}
|
45
public/html/projects/templates/add.jade
Normal file
45
public/html/projects/templates/add.jade
Normal file
@ -0,0 +1,45 @@
|
||||
.modal-header
|
||||
h4.modal-title New Template
|
||||
.modal-body
|
||||
form.form-horizontal
|
||||
.form-group
|
||||
label.control-label.col-sm-4 Playbook Name
|
||||
.col-sm-6
|
||||
input.form-control(type="text" placeholder="play.yml" ng-model="tpl.playbook")
|
||||
|
||||
.form-group
|
||||
label.control-label.col-sm-4 SSH Key
|
||||
.col-sm-6
|
||||
select.form-control(ng-model="tpl.ssh_key_id" ng-options="key.id as key.name for key in keys")
|
||||
option(value="") -- Select SSH Key --
|
||||
.form-group
|
||||
label.control-label.col-sm-4 Inventory
|
||||
.col-sm-6
|
||||
select.form-control(ng-model="tpl.inventory_id" ng-options="inv.id as inv.name for inv in inventory")
|
||||
option(value="") -- Select Inventory --
|
||||
.form-group
|
||||
label.control-label.col-sm-4 Playbook Repository
|
||||
.col-sm-6
|
||||
select.form-control(ng-model="tpl.repository_id" ng-options="repo.id as repo.name for repo in repositories")
|
||||
option(value="") -- Select Playbook Repository --
|
||||
.form-group
|
||||
label.control-label.col-sm-4 Environment
|
||||
.col-sm-6
|
||||
select.form-control(ng-model="tpl.environment_id" ng-options="env.id as env.name for env in environment")
|
||||
option(value="") -- Select Task Environment --
|
||||
|
||||
hr
|
||||
.form-group
|
||||
label.control-label.col-sm-4 Extra CLI Arguments
|
||||
.col-sm-6
|
||||
textarea.form-control(placeholder='*MUST* be a JSON array! Each argument must be an element of the array, for example: ["-i", "@myinventory.sh", "--private-key=/there/id_rsa", "-vvvv"]' ng-model="tpl.arguments" rows="5")
|
||||
|
||||
.form-group
|
||||
.col-sm-6.col-sm-offset-4
|
||||
.checkbox: label
|
||||
input(type="checkbox" ng-model="user.admin")
|
||||
| Override semaphore arguments
|
||||
p.help-block Usually semaphore prepends arguments like `--private-key=/location/id_rsa` to make sure everything goes smoothly. This option is for special needs, where semaphore conflicts with one of your arguments.
|
||||
.modal-footer
|
||||
button.btn.btn-default.pull-left(ng-click="$dismiss()") Dismiss
|
||||
button.btn.btn-success(ng-click="$close(user)") Create
|
16
public/html/projects/templates/list.jade
Normal file
16
public/html/projects/templates/list.jade
Normal file
@ -0,0 +1,16 @@
|
||||
h3 Task Templates
|
||||
button.btn.btn-success.btn-xs.pull-right(ng-click="add()") New Template
|
||||
|
||||
table.table
|
||||
thead: tr
|
||||
th Playbook
|
||||
th SSH Key
|
||||
th Inventory
|
||||
th Environment
|
||||
th Repository
|
||||
tbody: tr(ng-repeat="tpl in templates")
|
||||
td {{ tpl.playbook }}
|
||||
td {{ sshKeysAssoc[tpl.ssh_key_id].name }}
|
||||
td {{ inventoryAssoc[tpl.inventory_id].name }}
|
||||
td {{ environmentAssoc[tpl.environment_id].name }}
|
||||
td {{ reposAssoc[tpl.repository_id].name }}
|
@ -1,8 +1,8 @@
|
||||
define(function () {
|
||||
app.registerController('ProjectRepositoriesCtrl', ['$scope', '$http', '$uibModal', 'Project', function ($scope, $http, $modal, Project) {
|
||||
app.registerController('ProjectRepositoriesCtrl', ['$scope', '$http', 'Project', '$uibModal', '$rootScope', function ($scope, $http, Project, $modal, $rootScope) {
|
||||
$scope.reload = function () {
|
||||
$http.get(Project.getURL() + '/repositories').success(function (repositories) {
|
||||
$scope.repositories = repositories;
|
||||
$http.get(Project.getURL() + '/repositories').success(function (repos) {
|
||||
$scope.repositories = repos;
|
||||
});
|
||||
}
|
||||
|
||||
@ -14,6 +14,25 @@ define(function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.add = function () {
|
||||
$http.get(Project.getURL() + '/keys?type=ssh').success(function (keys) {
|
||||
var scope = $rootScope.$new();
|
||||
scope.keys = keys;
|
||||
|
||||
$modal.open({
|
||||
templateUrl: '/tpl/projects/repositories/add.html',
|
||||
scope: scope
|
||||
}).result.then(function (repo) {
|
||||
$http.post(Project.getURL() + '/repositories', repo)
|
||||
.success(function () {
|
||||
$scope.reload();
|
||||
}).error(function (_, status) {
|
||||
swal('Erorr', 'Repository not added: ' + status, 'error');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.reload();
|
||||
}]);
|
||||
});
|
@ -1,5 +1,38 @@
|
||||
define(function () {
|
||||
app.registerController('ProjectTemplatesCtrl', ['$scope', '$http', '$uibModal', 'Project', function ($scope, $http, $modal, Project) {
|
||||
app.registerController('ProjectTemplatesCtrl', ['$scope', '$http', '$uibModal', 'Project', '$rootScope', function ($scope, $http, $modal, Project, $rootScope) {
|
||||
$http.get(Project.getURL() + '/keys?type=ssh').success(function (keys) {
|
||||
$scope.sshKeys = keys;
|
||||
|
||||
$scope.sshKeysAssoc = {};
|
||||
keys.forEach(function (k) {
|
||||
$scope.sshKeysAssoc[k.id] = k;
|
||||
});
|
||||
});
|
||||
$http.get(Project.getURL() + '/inventory').success(function (inv) {
|
||||
$scope.inventory = inv;
|
||||
|
||||
$scope.inventoryAssoc = {};
|
||||
inv.forEach(function (i) {
|
||||
$scope.inventoryAssoc[i.id] = i;
|
||||
});
|
||||
});
|
||||
$http.get(Project.getURL() + '/repositories').success(function (repos) {
|
||||
$scope.repos = repos;
|
||||
|
||||
$scope.reposAssoc = {};
|
||||
repos.forEach(function (i) {
|
||||
$scope.reposAssoc[i.id] = i;
|
||||
});
|
||||
});
|
||||
$http.get(Project.getURL() + '/environment').success(function (env) {
|
||||
$scope.environment = env;
|
||||
|
||||
$scope.environmentAssoc = {};
|
||||
env.forEach(function (i) {
|
||||
$scope.environmentAssoc[i.id] = i;
|
||||
});
|
||||
});
|
||||
|
||||
$scope.reload = function () {
|
||||
$http.get(Project.getURL() + '/templates').success(function (templates) {
|
||||
$scope.templates = templates;
|
||||
@ -14,6 +47,25 @@ define(function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.add = function () {
|
||||
var scope = $rootScope.$new();
|
||||
scope.keys = $scope.sshKeys;
|
||||
scope.inventory = $scope.inventory;
|
||||
scope.repositories = $scope.repos;
|
||||
scope.environment = $scope.environment;
|
||||
|
||||
$modal.open({
|
||||
templateUrl: '/tpl/projects/templates/add.html',
|
||||
scope: scope
|
||||
}).result.then(function (tpl) {
|
||||
$http.post(Project.getURL() + '/templates', tpl).success(function () {
|
||||
$scope.reload();
|
||||
}).error(function (_, status) {
|
||||
swal('error', 'could not add template:' + status, 'error');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.reload();
|
||||
}]);
|
||||
});
|
@ -45,7 +45,7 @@ app.config(function ($stateProvider, $couchPotatoProvider) {
|
||||
.state('project.templates', {
|
||||
url: '/templates',
|
||||
pageTitle: 'Templates',
|
||||
templateUrl: '/tpl/projects/templates.html',
|
||||
templateUrl: '/tpl/projects/templates/list.html',
|
||||
controller: 'ProjectTemplatesCtrl',
|
||||
resolve: {
|
||||
$d: $couchPotatoProvider.resolveDependencies(['controllers/projects/templates'])
|
||||
@ -85,7 +85,7 @@ app.config(function ($stateProvider, $couchPotatoProvider) {
|
||||
.state('project.repositories', {
|
||||
url: '/repositories',
|
||||
pageTitle: 'Repositories',
|
||||
templateUrl: '/tpl/projects/repositories.html',
|
||||
templateUrl: '/tpl/projects/repositories/list.html',
|
||||
controller: 'ProjectRepositoriesCtrl',
|
||||
resolve: {
|
||||
$d: $couchPotatoProvider.resolveDependencies(['controllers/projects/repositories'])
|
||||
|
@ -50,7 +50,10 @@ func GetRepositories(c *gin.Context) {
|
||||
func AddRepository(c *gin.Context) {
|
||||
project := c.MustGet("project").(models.Project)
|
||||
|
||||
var repository models.Repository
|
||||
var repository struct {
|
||||
GitUrl string `json:"git_url" binding:"required"`
|
||||
SshKeyID int `json:"ssh_key_id" binding:"required"`
|
||||
}
|
||||
if err := c.Bind(&repository); err != nil {
|
||||
return
|
||||
}
|
||||
|
13
swagger.yml
13
swagger.yml
@ -95,6 +95,8 @@ definitions:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
project_id:
|
||||
type: integer
|
||||
password:
|
||||
@ -106,6 +108,8 @@ definitions:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
project_id:
|
||||
type: integer
|
||||
inventory:
|
||||
@ -121,6 +125,8 @@ definitions:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
project_id:
|
||||
type: integer
|
||||
git_url:
|
||||
@ -430,6 +436,13 @@ paths:
|
||||
tags:
|
||||
- project
|
||||
summary: Get access keys linked to project
|
||||
parameters:
|
||||
- name: Key type
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
format: ssh/aws/gcloud/do
|
||||
description: Filter by key type
|
||||
responses:
|
||||
200:
|
||||
description: Access Keys
|
||||
|
Loading…
Reference in New Issue
Block a user