Merge branch 'master' into nomenclature
Conflicts: test/data/test.db
This commit is contained in:
commit
f4681f2c18
60 changed files with 1716 additions and 496 deletions
|
@ -19,6 +19,23 @@
|
|||
}
|
||||
}
|
||||
|
||||
.scrollable-menu {
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.dropdown.input-group-addon {
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
background-color: transparent;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropdown.input-group-addon .dropdown-toggle {
|
||||
border-left: 0px;
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
#quay-logo {
|
||||
width: 100px;
|
||||
|
@ -3114,38 +3131,38 @@ p.editable:hover i {
|
|||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
.usage-chart {
|
||||
.usage-chart-element {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.usage-chart .count-text {
|
||||
.usage-chart-element .count-text {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.usage-chart.limit-at path.arc-0 {
|
||||
.usage-chart-element.limit-at path.arc-0 {
|
||||
fill: #c09853;
|
||||
}
|
||||
|
||||
.usage-chart.limit-over path.arc-0 {
|
||||
.usage-chart-element.limit-over path.arc-0 {
|
||||
fill: #b94a48;
|
||||
}
|
||||
|
||||
.usage-chart.limit-near path.arc-0 {
|
||||
.usage-chart-element.limit-near path.arc-0 {
|
||||
fill: #468847;
|
||||
}
|
||||
|
||||
.usage-chart.limit-over path.arc-1 {
|
||||
.usage-chart-element.limit-over path.arc-1 {
|
||||
fill: #fcf8e3;
|
||||
}
|
||||
|
||||
.usage-chart.limit-at path.arc-1 {
|
||||
.usage-chart-element.limit-at path.arc-1 {
|
||||
fill: #f2dede;
|
||||
}
|
||||
|
||||
.usage-chart.limit-near path.arc-1 {
|
||||
.usage-chart-element.limit-near path.arc-1 {
|
||||
fill: #dff0d8;
|
||||
}
|
||||
|
||||
|
@ -4109,20 +4126,37 @@ pre.command:before {
|
|||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .branch-reference.not-match {
|
||||
color: #ccc !important;
|
||||
.trigger-setup-github-element .ref-reference {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .branch-reference.not-match a {
|
||||
color: #ccc !important;
|
||||
.trigger-setup-github-element .ref-reference span {
|
||||
cursor: pointer;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .branch-filter {
|
||||
.trigger-setup-github-element .ref-reference:hover {
|
||||
color: #3276b1;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .ref-reference:hover span {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .ref-reference.match {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .ref-reference.match span {
|
||||
text-decoration: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .ref-filter {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .branch-filter span {
|
||||
.trigger-setup-github-element .ref-filter span {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
@ -4145,19 +4179,37 @@ pre.command:before {
|
|||
padding-left: 6px;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .matching-branches {
|
||||
.trigger-setup-github-element .matching-refs {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
margin-left: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .matching-branches li:before {
|
||||
.trigger-setup-github-element .ref-matches {
|
||||
padding-left: 70px;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .ref-matches .kind {
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .matching-refs.tags li:before {
|
||||
content: "\f02b";
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .matching-refs.branches li:before {
|
||||
content: "\f126";
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
|
||||
.trigger-setup-github-element .matching-branches li {
|
||||
.trigger-setup-github-element .matching-refs li {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
|
@ -4333,11 +4385,14 @@ pre.command:before {
|
|||
}
|
||||
|
||||
.trigger-pull-credentials {
|
||||
margin-top: 4px;
|
||||
padding-left: 26px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.trigger-pull-credentials .entity-reference {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.trigger-pull-credentials .context-tooltip {
|
||||
color: gray;
|
||||
margin-right: 4px;
|
||||
|
@ -4345,7 +4400,8 @@ pre.command:before {
|
|||
|
||||
.trigger-description .trigger-description-subtitle {
|
||||
display: inline-block;
|
||||
margin-right: 34px;
|
||||
width: 100px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.trigger-option-section:not(:first-child) {
|
||||
|
|
|
@ -2,8 +2,15 @@
|
|||
<span ng-if="provider == 'github'">
|
||||
<a href="javascript:void(0)" class="btn btn-primary btn-block" quay-require="['GITHUB_LOGIN']" ng-click="startSignin('github')" style="margin-bottom: 10px" ng-disabled="signingIn">
|
||||
<i class="fa fa-github fa-lg"></i>
|
||||
<span ng-if="action != 'attach'">Sign In with GitHub</span>
|
||||
<span ng-if="action == 'attach'">Attach to GitHub Account</span>
|
||||
<span ng-if="action != 'attach'">
|
||||
Sign In with GitHub
|
||||
<span ng-if="isEnterprise('github')">Enterprise</span>
|
||||
</span>
|
||||
<span ng-if="action == 'attach'">
|
||||
Attach to GitHub
|
||||
<span ng-if="isEnterprise('github')">Enterprise</span>
|
||||
Account
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
</div>
|
||||
|
||||
<!-- Chart -->
|
||||
<div>
|
||||
<div id="repository-usage-chart" class="usage-chart limit-{{limit}}"></div>
|
||||
<span class="usage-caption" ng-show="chart">Repository Usage</span>
|
||||
</div>
|
||||
<div class="usage-chart" total="subscribedPlan.privateRepos || 0"
|
||||
current="subscription.usedPrivateRepos || 0"
|
||||
limit="limit"
|
||||
usage-title="Repository Usage"
|
||||
ng-show="!planLoading"></div>
|
||||
|
||||
<!-- Plans Table -->
|
||||
<table class="table table-hover plans-list-table" ng-show="!planLoading">
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
Push to GitHub repository <a href="https://github.com/{{ trigger.config.build_source }}" target="_new">{{ trigger.config.build_source }}</a>
|
||||
<div style="margin-top: 4px; margin-left: 26px; font-size: 12px; color: gray;" ng-if="!short">
|
||||
<div>
|
||||
<span class="trigger-description-subtitle">Branches:</span>
|
||||
<span ng-if="trigger.config.branch_regex">Matching Regular Expression {{ trigger.config.branch_regex }}</span>
|
||||
<span ng-if="!trigger.config.branch_regex">(All Branches)</span>
|
||||
<span class="trigger-description-subtitle">Branches/Tags:</span>
|
||||
<span ng-if="trigger.config.branchtag_regex">Matching Regular Expression {{ trigger.config.branchtag_regex }}</span>
|
||||
<span ng-if="!trigger.config.branchtag_regex">(All Branches and Tags)</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -2,27 +2,27 @@
|
|||
<!-- Current selected info -->
|
||||
<div class="selected-info" ng-show="nextStepCounter > 0">
|
||||
<table style="width: 100%;">
|
||||
<tr ng-show="currentRepo && nextStepCounter > 0">
|
||||
<tr ng-show="state.currentRepo && nextStepCounter > 0">
|
||||
<td width="200px">
|
||||
Repository:
|
||||
</td>
|
||||
<td>
|
||||
<div class="current-repo">
|
||||
<img class="dropdown-select-icon github-org-icon"
|
||||
ng-src="{{ currentRepo.avatar_url ? currentRepo.avatar_url : '//www.gravatar.com/avatar/' }}">
|
||||
{{ currentRepo.repo }}
|
||||
ng-src="{{ state.currentRepo.avatar_url ? state.currentRepo.avatar_url : '//www.gravatar.com/avatar/' }}">
|
||||
<a ng-href="https://github.com/{{ state.currentRepo.repo }}" target="_blank">{{ state.currentRepo.repo }}</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-show="nextStepCounter > 1">
|
||||
<td>
|
||||
Branches:
|
||||
Branches and Tags:
|
||||
</td>
|
||||
<td>
|
||||
<div class="branch-filter">
|
||||
<span ng-if="!state.hasBranchFilter">(All Branches)</span>
|
||||
<span ng-if="state.hasBranchFilter">Regular Expression: <code>{{ state.branchFilter }}</code></span>
|
||||
<div class="ref-filter">
|
||||
<span ng-if="!state.hasBranchTagFilter">(Build All)</span>
|
||||
<span ng-if="state.hasBranchTagFilter">Regular Expression: <code>{{ state.branchTagFilter }}</code></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -45,18 +45,18 @@
|
|||
<div class="step-view" next-step-counter="nextStepCounter" current-step-valid="currentStepValid"
|
||||
steps-completed="stepsCompleted()">
|
||||
<!-- Repository select -->
|
||||
<div class="step-view-step" complete-condition="currentRepo" load-callback="loadRepositories(callback)"
|
||||
<div class="step-view-step" complete-condition="state.currentRepo" load-callback="loadRepositories(callback)"
|
||||
load-message="Loading Repositories">
|
||||
<div style="margin-bottom: 12px">Please choose the GitHub repository that will trigger the build:</div>
|
||||
<div class="dropdown-select" placeholder="'Select a repository'" selected-item="currentRepo"
|
||||
lookahead-items="repoLookahead">
|
||||
<div class="dropdown-select" placeholder="'Enter or select a repository'" selected-item="state.currentRepo"
|
||||
lookahead-items="repoLookahead" allow-custom-input="true">
|
||||
<!-- Icons -->
|
||||
<i class="dropdown-select-icon none-icon fa fa-github fa-lg"></i>
|
||||
<img class="dropdown-select-icon github-org-icon"
|
||||
ng-src="{{ currentRepo.avatar_url ? currentRepo.avatar_url : '//www.gravatar.com/avatar/' }}">
|
||||
ng-src="{{ state.currentRepo.avatar_url ? state.currentRepo.avatar_url : '//www.gravatar.com/avatar/' }}">
|
||||
|
||||
<!-- Dropdown menu -->
|
||||
<ul class="dropdown-select-menu" role="menu">
|
||||
<ul class="dropdown-select-menu scrollable-menu" role="menu">
|
||||
<li ng-repeat-start="org in orgs" role="presentation" class="dropdown-header github-org-header">
|
||||
<img ng-src="{{ org.info.avatar_url }}" class="github-org-icon">{{ org.info.name }}
|
||||
</li>
|
||||
|
@ -68,45 +68,76 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Branch filter/select -->
|
||||
<div class="step-view-step" complete-condition="!state.hasBranchFilter || state.branchFilter"
|
||||
load-callback="loadBranches(callback)"
|
||||
load-message="Loading Branches">
|
||||
<!-- Branch/Tag filter/select -->
|
||||
<div class="step-view-step" complete-condition="!state.hasBranchTagFilter || state.branchTagFilter"
|
||||
load-callback="loadBranchesAndTags(callback)"
|
||||
load-message="Loading Branches and Tags">
|
||||
|
||||
<div style="margin-bottom: 12px">Please choose the branches to which this trigger will apply:</div>
|
||||
<div style="margin-bottom: 12px">Please choose the branches and tags to which this trigger will apply:</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<div class="btn-group btn-group-sm" style="margin-bottom: 12px">
|
||||
<button type="button" class="btn btn-default"
|
||||
ng-class="state.hasBranchFilter ? '' : 'active btn-info'" ng-click="state.hasBranchFilter = false">
|
||||
All Branches
|
||||
ng-class="state.hasBranchTagFilter ? '' : 'active btn-info'" ng-click="state.hasBranchTagFilter = false">
|
||||
All Branches and Tags
|
||||
</button>
|
||||
<button type="button" class="btn btn-default"
|
||||
ng-class="state.hasBranchFilter ? 'active btn-info' : ''" ng-click="state.hasBranchFilter = true">
|
||||
ng-class="state.hasBranchTagFilter ? 'active btn-info' : ''" ng-click="state.hasBranchTagFilter = true">
|
||||
Matching Regular Expression
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div ng-show="state.hasBranchFilter" style="margin-top: 10px;">
|
||||
<div ng-show="state.hasBranchTagFilter" style="margin-top: 10px;">
|
||||
<form>
|
||||
<input class="form-control" type="text" ng-model="state.branchFilter"
|
||||
placeholder="(Regular expression)" required>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" ng-model="state.branchTagFilter"
|
||||
placeholder="(Regular expression. Examples: heads/branchname, tags/tagname)" required>
|
||||
<div class="dropdown input-group-addon">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<li><a href="javascript:void(0)" ng-click="state.branchTagFilter = 'heads/.+'">
|
||||
<i class="fa fa-code-fork"></i>All Branches</a>
|
||||
</li>
|
||||
<li><a href="javascript:void(0)" ng-click="state.branchTagFilter = 'tags/.+'">
|
||||
<i class="fa fa-tag"></i>All Tags</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<div style="margin-top: 10px">
|
||||
<div ng-if="branchNames.length">
|
||||
Branches:
|
||||
<ul class="matching-branches">
|
||||
<div class="ref-matches" ng-if="branchNames.length">
|
||||
<span class="kind">Branches:</span>
|
||||
<ul class="matching-refs branches">
|
||||
<li ng-repeat="branchName in branchNames | limitTo:20"
|
||||
class="branch-reference"
|
||||
ng-class="isMatchingBranch(branchName, state.branchFilter) ? 'match' : 'not-match'">
|
||||
<a href="https://github.com/{{ currentRepo.repo }}/tree/{{ branchName }}" target="_blank">
|
||||
class="ref-reference"
|
||||
ng-class="isMatching('heads', branchName, state.branchTagFilter) ? 'match' : 'not-match'">
|
||||
<span ng-click="addRef('heads', branchName)" target="_blank">
|
||||
{{ branchName }}
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span ng-if="branchNames.length > 20">...</span>
|
||||
</div>
|
||||
<div ng-if="state.branchFilter && !branchNames.length"
|
||||
<div class="ref-matches" ng-if="tagNames.length" style="margin-bottom: -20px">
|
||||
<span class="kind">Tags:</span>
|
||||
<ul class="matching-refs tags">
|
||||
<li ng-repeat="tagName in tagNames | limitTo:20"
|
||||
class="ref-reference"
|
||||
ng-class="isMatching('tags', tagName, state.branchTagFilter) ? 'match' : 'not-match'">
|
||||
<span ng-click="addRef('tags', tagName)" target="_blank">
|
||||
{{ tagName }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span ng-if="tagNames.length > 20">...</span>
|
||||
</div>
|
||||
<div ng-if="state.branchTagFilter && !branchNames.length"
|
||||
style="margin-top: 10px">
|
||||
<strong>Warning:</strong> No branches found
|
||||
</div>
|
||||
|
@ -147,7 +178,7 @@
|
|||
|
||||
<div class="quay-spinner" ng-show="!locations && !locationError"></div>
|
||||
<div class="alert alert-warning" ng-show="locations && !locations.length">
|
||||
Warning: No Dockerfiles were found in {{ currentRepo.repo }}
|
||||
Warning: No Dockerfiles were found in {{ state.currentRepo.repo }}
|
||||
</div>
|
||||
<div class="alert alert-warning" ng-show="locationError">
|
||||
{{ locationError }}
|
||||
|
|
2
static/directives/usage-chart.html
Normal file
2
static/directives/usage-chart.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
<span id="usage-chart-element" class="usage-chart-element" ng-class="'limit-' + limit" ng-show="total != null"></span>
|
||||
<span class="usage-caption" ng-show="total != null && usageTitle">{{ usageTitle }}</span>
|
260
static/js/app.js
260
static/js/app.js
|
@ -621,7 +621,8 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
}]);
|
||||
|
||||
|
||||
$provide.factory('TriggerService', ['UtilService', '$sanitize', function(UtilService, $sanitize) {
|
||||
$provide.factory('TriggerService', ['UtilService', '$sanitize', 'KeyService',
|
||||
function(UtilService, $sanitize, KeyService) {
|
||||
var triggerService = {};
|
||||
|
||||
var triggerTypes = {
|
||||
|
@ -640,10 +641,29 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
'type': 'option',
|
||||
'name': 'branch_name'
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
'get_redirect_url': function(namespace, repository) {
|
||||
var redirect_uri = KeyService['githubRedirectUri'] + '/trigger/' +
|
||||
namespace + '/' + repository;
|
||||
|
||||
var authorize_url = KeyService['githubTriggerAuthorizeUrl'];
|
||||
var client_id = KeyService['githubTriggerClientId'];
|
||||
|
||||
return authorize_url + 'client_id=' + client_id +
|
||||
'&scope=repo,user:email&redirect_uri=' + redirect_uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
triggerService.getRedirectUrl = function(name, namespace, repository) {
|
||||
var type = triggerTypes[name];
|
||||
if (!type) {
|
||||
return '';
|
||||
}
|
||||
return type['get_redirect_url'](namespace, repository);
|
||||
};
|
||||
|
||||
triggerService.getDescription = function(name, config) {
|
||||
var type = triggerTypes[name];
|
||||
if (!type) {
|
||||
|
@ -1313,29 +1333,37 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
'id': 'repo_push',
|
||||
'title': 'Push to Repository',
|
||||
'icon': 'fa-upload'
|
||||
},
|
||||
{
|
||||
'id': 'build_queued',
|
||||
'title': 'Dockerfile Build Queued',
|
||||
'icon': 'fa-tasks'
|
||||
},
|
||||
{
|
||||
'id': 'build_start',
|
||||
'title': 'Dockerfile Build Started',
|
||||
'icon': 'fa-circle-o-notch'
|
||||
},
|
||||
{
|
||||
'id': 'build_success',
|
||||
'title': 'Dockerfile Build Successfully Completed',
|
||||
'icon': 'fa-check-circle-o'
|
||||
},
|
||||
{
|
||||
'id': 'build_failure',
|
||||
'title': 'Dockerfile Build Failed',
|
||||
'icon': 'fa-times-circle-o'
|
||||
}
|
||||
];
|
||||
|
||||
if (Features.BUILD_SUPPORT) {
|
||||
var buildEvents = [
|
||||
{
|
||||
'id': 'build_queued',
|
||||
'title': 'Dockerfile Build Queued',
|
||||
'icon': 'fa-tasks'
|
||||
},
|
||||
{
|
||||
'id': 'build_start',
|
||||
'title': 'Dockerfile Build Started',
|
||||
'icon': 'fa-circle-o-notch'
|
||||
},
|
||||
{
|
||||
'id': 'build_success',
|
||||
'title': 'Dockerfile Build Successfully Completed',
|
||||
'icon': 'fa-check-circle-o'
|
||||
},
|
||||
{
|
||||
'id': 'build_failure',
|
||||
'title': 'Dockerfile Build Failed',
|
||||
'icon': 'fa-times-circle-o'
|
||||
}];
|
||||
|
||||
for (var i = 0; i < buildEvents.length; ++i) {
|
||||
events.push(buildEvents[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var methods = [
|
||||
{
|
||||
'id': 'quay_notification',
|
||||
|
@ -1538,7 +1566,7 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
if (metadata.updated_tags && Object.getOwnPropertyNames(metadata.updated_tags).length) {
|
||||
return 'Repository {repository} has been pushed with the following tags updated: {updated_tags}';
|
||||
} else {
|
||||
return 'Repository {repository} has been pushed';
|
||||
return 'Repository {repository} fhas been pushed';
|
||||
}
|
||||
},
|
||||
'page': function(metadata) {
|
||||
|
@ -1686,21 +1714,31 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
|
||||
$provide.factory('KeyService', ['$location', 'Config', function($location, Config) {
|
||||
var keyService = {}
|
||||
var oauth = window.__oauth;
|
||||
|
||||
keyService['stripePublishableKey'] = Config['STRIPE_PUBLISHABLE_KEY'];
|
||||
|
||||
keyService['githubClientId'] = Config['GITHUB_CLIENT_ID'];
|
||||
keyService['githubLoginClientId'] = Config['GITHUB_LOGIN_CLIENT_ID'];
|
||||
keyService['githubRedirectUri'] = Config.getUrl('/oauth2/github/callback');
|
||||
keyService['githubTriggerClientId'] = oauth['GITHUB_TRIGGER_CONFIG']['CLIENT_ID'];
|
||||
keyService['githubLoginClientId'] = oauth['GITHUB_LOGIN_CONFIG']['CLIENT_ID'];
|
||||
keyService['googleLoginClientId'] = oauth['GOOGLE_LOGIN_CONFIG']['CLIENT_ID'];
|
||||
|
||||
keyService['googleLoginClientId'] = Config['GOOGLE_LOGIN_CLIENT_ID'];
|
||||
keyService['githubRedirectUri'] = Config.getUrl('/oauth2/github/callback');
|
||||
keyService['googleRedirectUri'] = Config.getUrl('/oauth2/google/callback');
|
||||
|
||||
keyService['googleLoginUrl'] = 'https://accounts.google.com/o/oauth2/auth?response_type=code&';
|
||||
keyService['githubLoginUrl'] = 'https://github.com/login/oauth/authorize?';
|
||||
keyService['githubLoginUrl'] = oauth['GITHUB_LOGIN_CONFIG']['AUTHORIZE_ENDPOINT'];
|
||||
keyService['googleLoginUrl'] = oauth['GOOGLE_LOGIN_CONFIG']['AUTHORIZE_ENDPOINT'];
|
||||
|
||||
keyService['githubEndpoint'] = oauth['GITHUB_LOGIN_CONFIG']['GITHUB_ENDPOINT'];
|
||||
|
||||
keyService['githubTriggerAuthorizeUrl'] = oauth['GITHUB_LOGIN_CONFIG']['AUTHORIZE_ENDPOINT'];
|
||||
|
||||
keyService['googleLoginScope'] = 'openid email';
|
||||
keyService['githubLoginScope'] = 'user:email';
|
||||
keyService['googleLoginScope'] = 'openid email';
|
||||
|
||||
keyService.isEnterprise = function(service) {
|
||||
var isGithubEnterprise = keyService['githubLoginUrl'].indexOf('https://github.com/') < 0;
|
||||
return service == 'github' && isGithubEnterprise;
|
||||
};
|
||||
|
||||
keyService.getExternalLoginUrl = function(service, action) {
|
||||
var state_clause = '';
|
||||
|
@ -2548,7 +2586,10 @@ quayApp.directive('focusablePopoverContent', ['$timeout', '$popover', function (
|
|||
$body = $('body');
|
||||
var hide = function() {
|
||||
$body.off('click');
|
||||
|
||||
if (!scope) { return; }
|
||||
scope.$apply(function() {
|
||||
if (!scope) { return; }
|
||||
scope.$hide();
|
||||
});
|
||||
};
|
||||
|
@ -2645,9 +2686,9 @@ quayApp.directive('userSetup', function () {
|
|||
$scope.errorMessage = '';
|
||||
$scope.sent = true;
|
||||
$scope.sendingRecovery = false;
|
||||
}, function(result) {
|
||||
}, function(resp) {
|
||||
$scope.invalidRecovery = true;
|
||||
$scope.errorMessage = result.data;
|
||||
$scope.errorMessage = ApiService.getErrorMessage(resp, 'Cannot send recovery email');
|
||||
$scope.sent = false;
|
||||
$scope.sendingRecovery = false;
|
||||
});
|
||||
|
@ -2681,6 +2722,8 @@ quayApp.directive('externalLoginButton', function () {
|
|||
},
|
||||
controller: function($scope, $timeout, $interval, ApiService, KeyService, CookieService, Features, Config) {
|
||||
$scope.signingIn = false;
|
||||
$scope.isEnterprise = KeyService.isEnterprise;
|
||||
|
||||
$scope.startSignin = function(service) {
|
||||
$scope.signInStarted({'service': service});
|
||||
|
||||
|
@ -3137,6 +3180,22 @@ quayApp.directive('logsView', function () {
|
|||
'delete_robot': 'Delete Robot Account: {robot}',
|
||||
'create_repo': 'Create Repository: {repo}',
|
||||
'push_repo': 'Push to repository: {repo}',
|
||||
'repo_verb': function(metadata) {
|
||||
var prefix = '';
|
||||
if (metadata.verb == 'squash') {
|
||||
prefix = 'Pull of squashed tag {tag}'
|
||||
}
|
||||
|
||||
if (metadata.token) {
|
||||
prefix += ' via token {token}';
|
||||
} else if (metadata.username) {
|
||||
prefix += ' by {username}';
|
||||
} else {
|
||||
prefix += ' by {_ip}';
|
||||
}
|
||||
|
||||
return prefix;
|
||||
},
|
||||
'pull_repo': function(metadata) {
|
||||
if (metadata.token) {
|
||||
return 'Pull repository {repo} via token {token}';
|
||||
|
@ -3267,6 +3326,7 @@ quayApp.directive('logsView', function () {
|
|||
'delete_robot': 'Delete Robot Account',
|
||||
'create_repo': 'Create Repository',
|
||||
'push_repo': 'Push to repository',
|
||||
'repo_verb': 'Pull Repo Verb',
|
||||
'pull_repo': 'Pull repository',
|
||||
'delete_repo': 'Delete repository',
|
||||
'change_repo_permission': 'Change repository permission',
|
||||
|
@ -3358,7 +3418,6 @@ quayApp.directive('logsView', function () {
|
|||
$scope.logsPath = '/api/v1/' + url;
|
||||
|
||||
if (!$scope.chart) {
|
||||
window.console.log('creating chart');
|
||||
$scope.chart = new LogUsageChart(logKinds);
|
||||
$($scope.chart).bind('filteringChanged', function(e) {
|
||||
$scope.$apply(function() { $scope.kindsAllowed = e.allowed; });
|
||||
|
@ -4541,23 +4600,6 @@ quayApp.directive('planManager', function () {
|
|||
$scope.planChanged({ 'plan': subscribedPlan });
|
||||
}
|
||||
|
||||
if (sub.usedPrivateRepos > $scope.subscribedPlan.privateRepos) {
|
||||
$scope.limit = 'over';
|
||||
} else if (sub.usedPrivateRepos == $scope.subscribedPlan.privateRepos) {
|
||||
$scope.limit = 'at';
|
||||
} else if (sub.usedPrivateRepos >= $scope.subscribedPlan.privateRepos * 0.7) {
|
||||
$scope.limit = 'near';
|
||||
} else {
|
||||
$scope.limit = 'none';
|
||||
}
|
||||
|
||||
if (!$scope.chart) {
|
||||
$scope.chart = new UsageChart();
|
||||
$scope.chart.draw('repository-usage-chart');
|
||||
}
|
||||
|
||||
$scope.chart.update(sub.usedPrivateRepos || 0, $scope.subscribedPlan.privateRepos || 0);
|
||||
|
||||
$scope.planChanging = false;
|
||||
$scope.planLoading = false;
|
||||
});
|
||||
|
@ -4800,11 +4842,14 @@ quayApp.directive('stepView', function ($compile) {
|
|||
|
||||
this.next = function() {
|
||||
if (this.currentStepIndex >= 0) {
|
||||
if (!this.getCurrentStep().scope.completeCondition) {
|
||||
var currentStep = this.getCurrentStep();
|
||||
if (!currentStep || !currentStep.scope) { return; }
|
||||
|
||||
if (!currentStep.scope.completeCondition) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.getCurrentStep().element.hide();
|
||||
currentStep.element.hide();
|
||||
|
||||
if (this.unwatch) {
|
||||
this.unwatch();
|
||||
|
@ -5259,25 +5304,42 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
controller: function($scope, $element, ApiService) {
|
||||
$scope.analyzeCounter = 0;
|
||||
$scope.setupReady = false;
|
||||
|
||||
$scope.refs = null;
|
||||
$scope.branchNames = null;
|
||||
$scope.tagNames = null;
|
||||
|
||||
$scope.state = {
|
||||
'branchFilter': '',
|
||||
'hasBranchFilter': false,
|
||||
'currentRepo': null,
|
||||
'branchTagFilter': '',
|
||||
'hasBranchTagFilter': false,
|
||||
'isInvalidLocation': true,
|
||||
'currentLocation': null
|
||||
};
|
||||
|
||||
$scope.isMatchingBranch = function(branchName, filter) {
|
||||
$scope.isMatching = function(kind, name, filter) {
|
||||
try {
|
||||
var patt = new RegExp(filter);
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var m = branchName.match(patt);
|
||||
return m && m[0].length == branchName.length;
|
||||
var fullname = (kind + '/' + name);
|
||||
var m = fullname.match(patt);
|
||||
return m && m[0].length == fullname.length;
|
||||
}
|
||||
|
||||
$scope.addRef = function(kind, name) {
|
||||
if ($scope.isMatching(kind, name, $scope.state.branchTagFilter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newFilter = kind + '/' + name;
|
||||
var existing = $scope.state.branchTagFilter;
|
||||
if (existing) {
|
||||
$scope.state.branchTagFilter = '(' + existing + ')|(' + newFilter + ')';
|
||||
} else {
|
||||
$scope.state.branchTagFilter = newFilter;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.stepsCompleted = function() {
|
||||
|
@ -5297,17 +5359,29 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
}, ApiService.errorDisplay('Cannot load repositories'));
|
||||
};
|
||||
|
||||
$scope.loadBranches = function(callback) {
|
||||
$scope.loadBranchesAndTags = function(callback) {
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'trigger_uuid': $scope.trigger['id'],
|
||||
'field_name': 'branch_name'
|
||||
'field_name': 'refs'
|
||||
};
|
||||
|
||||
ApiService.listTriggerFieldValues($scope.trigger['config'], params).then(function(resp) {
|
||||
$scope.branchNames = resp['values'];
|
||||
$scope.refs = resp['values'];
|
||||
$scope.branchNames = [];
|
||||
$scope.tagNames = [];
|
||||
|
||||
for (var i = 0; i < $scope.refs.length; ++i) {
|
||||
var ref = $scope.refs[i];
|
||||
if (ref.kind == 'branch') {
|
||||
$scope.branchNames.push(ref.name);
|
||||
} else {
|
||||
$scope.tagNames.push(ref.name);
|
||||
}
|
||||
}
|
||||
|
||||
callback();
|
||||
}, ApiService.errorDisplay('Cannot load branch names'));
|
||||
}, ApiService.errorDisplay('Cannot load branch and tag names'));
|
||||
};
|
||||
|
||||
$scope.loadLocations = function(callback) {
|
||||
|
@ -5357,7 +5431,7 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
};
|
||||
|
||||
$scope.selectRepo = function(repo, org) {
|
||||
$scope.currentRepo = {
|
||||
$scope.state.currentRepo = {
|
||||
'repo': repo,
|
||||
'avatar_url': org['info']['avatar_url'],
|
||||
'toString': function() {
|
||||
|
@ -5408,19 +5482,19 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
$scope.repoLookahead = repos;
|
||||
};
|
||||
|
||||
$scope.$watch('currentRepo', function(repo) {
|
||||
if (repo) {
|
||||
$scope.$watch('state.currentRepo', function(repo) {
|
||||
if (repo) {
|
||||
$scope.selectRepoInternal(repo);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('state.branchFilter', function(bf) {
|
||||
$scope.$watch('state.branchTagFilter', function(bf) {
|
||||
if (!$scope.trigger) { return; }
|
||||
|
||||
if ($scope.state.hasBranchFilter) {
|
||||
$scope.trigger['config']['branch_regex'] = bf;
|
||||
if ($scope.state.hasBranchTagFilter) {
|
||||
$scope.trigger['config']['branchtag_regex'] = bf;
|
||||
} else {
|
||||
delete $scope.trigger['config']['branch_regex'];
|
||||
delete $scope.trigger['config']['branchtag_regex'];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -5901,6 +5975,54 @@ quayApp.directive('notificationsBubble', function () {
|
|||
});
|
||||
|
||||
|
||||
quayApp.directive('usageChart', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/usage-chart.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'current': '=current',
|
||||
'total': '=total',
|
||||
'limit': '=limit',
|
||||
'usageTitle': '@usageTitle'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
$scope.limit = "";
|
||||
|
||||
var chart = null;
|
||||
|
||||
var update = function() {
|
||||
if ($scope.current == null || $scope.total == null) { return; }
|
||||
if (!chart) {
|
||||
chart = new UsageChart();
|
||||
chart.draw('usage-chart-element');
|
||||
}
|
||||
|
||||
var current = $scope.current || 0;
|
||||
var total = $scope.total || 0;
|
||||
if (current > total) {
|
||||
$scope.limit = 'over';
|
||||
} else if (current == total) {
|
||||
$scope.limit = 'at';
|
||||
} else if (current >= total * 0.7) {
|
||||
$scope.limit = 'near';
|
||||
} else {
|
||||
$scope.limit = 'none';
|
||||
}
|
||||
|
||||
chart.update($scope.current, $scope.total);
|
||||
};
|
||||
|
||||
$scope.$watch('current', update);
|
||||
$scope.$watch('total', update);
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('notificationView', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
|
|
|
@ -1330,15 +1330,13 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerServi
|
|||
var name = $routeParams.name;
|
||||
|
||||
$scope.Features = Features;
|
||||
$scope.permissions = {'team': [], 'user': []};
|
||||
$scope.TriggerService = TriggerService;
|
||||
|
||||
$scope.permissions = {'team': [], 'user': [], 'loading': 2};
|
||||
$scope.logsShown = 0;
|
||||
$scope.deleting = false;
|
||||
|
||||
$scope.permissionCache = {};
|
||||
|
||||
$scope.githubRedirectUri = KeyService.githubRedirectUri;
|
||||
$scope.githubClientId = KeyService.githubClientId;
|
||||
|
||||
$scope.showTriggerSetupCounter = 0;
|
||||
|
||||
$scope.getBadgeFormat = function(format, repo) {
|
||||
|
@ -1680,6 +1678,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerServi
|
|||
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/');
|
||||
permissionsFetch.get().then(function(resp) {
|
||||
$scope.permissions[kind] = resp.permissions;
|
||||
$scope.permissions['loading']--;
|
||||
}, function() {
|
||||
$scope.permissions[kind] = null;
|
||||
});
|
||||
|
@ -1739,6 +1738,7 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
|
|||
if (login.service == 'github') {
|
||||
$scope.hasGithubLogin = true;
|
||||
$scope.githubLogin = login.metadata['service_username'];
|
||||
$scope.githubEndpoint = KeyService['githubEndpoint'];
|
||||
}
|
||||
|
||||
if (login.service == 'google') {
|
||||
|
@ -2049,12 +2049,10 @@ function V1Ctrl($scope, $location, UserService) {
|
|||
UserService.updateUserIn($scope);
|
||||
}
|
||||
|
||||
function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService, PlanService, KeyService, Features) {
|
||||
function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService, PlanService, TriggerService, Features) {
|
||||
UserService.updateUserIn($scope);
|
||||
|
||||
$scope.Features = Features;
|
||||
$scope.githubRedirectUri = KeyService.githubRedirectUri;
|
||||
$scope.githubClientId = KeyService.githubClientId;
|
||||
|
||||
$scope.repo = {
|
||||
'is_public': 0,
|
||||
|
@ -2133,9 +2131,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
|
|||
|
||||
// Conduct the Github redirect if applicable.
|
||||
if ($scope.repo.initialize == 'github') {
|
||||
window.location = 'https://github.com/login/oauth/authorize?client_id=' + $scope.githubClientId +
|
||||
'&scope=repo,user:email&redirect_uri=' + $scope.githubRedirectUri + '/trigger/' +
|
||||
repo.namespace + '/' + repo.name;
|
||||
window.location = TriggerService.getRedirectUrl('github', repo.namespace, repo.name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2808,6 +2804,15 @@ function SuperUserAdminCtrl($scope, ApiService, Features, UserService) {
|
|||
$scope.logsCounter = 0;
|
||||
$scope.newUser = {};
|
||||
$scope.createdUsers = [];
|
||||
$scope.systemUsage = null;
|
||||
|
||||
$scope.getUsage = function() {
|
||||
if ($scope.systemUsage) { return; }
|
||||
|
||||
ApiService.getSystemUsage().then(function(resp) {
|
||||
$scope.systemUsage = resp;
|
||||
}, ApiService.errorDisplay('Cannot load system usage. Please contact support.'))
|
||||
}
|
||||
|
||||
$scope.loadLogs = function() {
|
||||
$scope.logsCounter++;
|
||||
|
|
|
@ -377,6 +377,23 @@ ImageHistoryTree.prototype.expandCollapsed_ = function(imageNode) {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the level of the node in the tree. Recursively computes and updates
|
||||
* if necessary.
|
||||
*/
|
||||
ImageHistoryTree.prototype.calculateLevel_ = function(node) {
|
||||
if (node['level'] != null) {
|
||||
return node['level'];
|
||||
}
|
||||
|
||||
if (node['parent'] == null) {
|
||||
return node['level'] = 0;
|
||||
}
|
||||
|
||||
return node['level'] = (this.calculateLevel_(node['parent']) + 1);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Builds the root node for the tree.
|
||||
*/
|
||||
|
@ -392,11 +409,16 @@ ImageHistoryTree.prototype.buildRoot_ = function() {
|
|||
var imageByDockerId = {};
|
||||
for (var i = 0; i < this.images_.length; ++i) {
|
||||
var image = this.images_[i];
|
||||
|
||||
// Skip images that are currently uploading.
|
||||
if (image.uploading) { continue; }
|
||||
|
||||
var imageNode = {
|
||||
"name": image.id.substr(0, 12),
|
||||
"children": [],
|
||||
"image": image,
|
||||
"tags": image.tags
|
||||
"tags": image.tags,
|
||||
"level": null
|
||||
};
|
||||
imageByDockerId[image.id] = imageNode;
|
||||
}
|
||||
|
@ -405,6 +427,7 @@ ImageHistoryTree.prototype.buildRoot_ = function() {
|
|||
// For each node, attach it to its immediate parent. If there is no immediate parent,
|
||||
// then the node is the root.
|
||||
var roots = [];
|
||||
var nodeCountsByLevel = {};
|
||||
for (var i = 0; i < this.images_.length; ++i) {
|
||||
var image = this.images_[i];
|
||||
|
||||
|
@ -420,10 +443,27 @@ ImageHistoryTree.prototype.buildRoot_ = function() {
|
|||
imageNode.parent = parent;
|
||||
parent.children.push(imageNode);
|
||||
} else {
|
||||
imageNode['level'] = 0;
|
||||
roots.push(imageNode);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate each node's level.
|
||||
for (var i = 0; i < this.images_.length; ++i) {
|
||||
var image = this.images_[i];
|
||||
|
||||
// Skip images that are currently uploading.
|
||||
if (image.uploading) { continue; }
|
||||
|
||||
var imageNode = imageByDockerId[image.id];
|
||||
var level = this.calculateLevel_(imageNode);
|
||||
if (nodeCountsByLevel[level] == null) {
|
||||
nodeCountsByLevel[level] = 1;
|
||||
} else {
|
||||
nodeCountsByLevel[level]++;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are multiple root nodes, then there is at least one branch without shared
|
||||
// ancestry and we use the virtual node. Otherwise, we use the root node found.
|
||||
var root = {
|
||||
|
@ -438,16 +478,12 @@ ImageHistoryTree.prototype.buildRoot_ = function() {
|
|||
|
||||
// Determine the maximum number of nodes at a particular level. This is used to size
|
||||
// the width of the tree properly.
|
||||
var maxChildCount = roots.length;
|
||||
for (var i = 0; i < this.images_.length; ++i) {
|
||||
var image = this.images_[i];
|
||||
|
||||
// Skip images that are currently uploading.
|
||||
if (image.uploading) { continue; }
|
||||
|
||||
var imageNode = imageByDockerId[image.id];
|
||||
maxChildCount = Math.max(maxChildCount, this.determineMaximumChildCount_(imageNode));
|
||||
}
|
||||
var maxChildCount = 0;
|
||||
var maxChildHeight = 0;
|
||||
Object.keys(nodeCountsByLevel).forEach(function(key){
|
||||
maxChildCount = Math.max(maxChildCount, nodeCountsByLevel[key]);
|
||||
maxChildHeight = Math.max(maxChildHeight, key);
|
||||
});
|
||||
|
||||
// Compact the graph so that any single chain of three (or more) images becomes a collapsed
|
||||
// section. We only do this if the max width is > 1 (since for a single width tree, no long
|
||||
|
@ -456,22 +492,21 @@ ImageHistoryTree.prototype.buildRoot_ = function() {
|
|||
this.collapseNodes_(root);
|
||||
}
|
||||
|
||||
// Determine the maximum height of the tree.
|
||||
var maxHeight = this.determineMaximumHeight_(root);
|
||||
// Determine the maximum height of the tree, with collapsed nodes.
|
||||
var maxCollapsedHeight = this.determineMaximumHeight_(root);
|
||||
|
||||
// Finally, set the root node and return.
|
||||
this.root_ = root;
|
||||
|
||||
return {
|
||||
'maxWidth': maxChildCount + 1,
|
||||
'maxHeight': maxHeight
|
||||
'maxHeight': maxCollapsedHeight
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Collapses long single chains of nodes (3 or more) into single nodes to make the graph more
|
||||
* compact.
|
||||
* Determines the height of the tree at its longest chain.
|
||||
*/
|
||||
ImageHistoryTree.prototype.determineMaximumHeight_ = function(node) {
|
||||
var maxHeight = 0;
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row" ng-show="Features.BUILD_SUPPORT">
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="section">
|
||||
|
|
|
@ -92,8 +92,9 @@
|
|||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="Allow any number of users, robot accounts or teams to read, write or administer this repository"></i>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<table class="permissions">
|
||||
<!-- Throbber -->
|
||||
<span class="quay-spinner" ng-show="permissions.loading > 0"></span>
|
||||
<table class="permissions" ng-show="permissions.loading <= 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="min-width: 400px;">User<span ng-show="repo.is_organization">/Team</span>/Robot Account</td>
|
||||
|
@ -260,7 +261,7 @@
|
|||
<span class="entity-reference" entity="trigger.pull_robot"></span>
|
||||
</div>
|
||||
</td>
|
||||
<td style="white-space: nowrap;">
|
||||
<td style="white-space: nowrap;" valign="top">
|
||||
<div class="dropdown" style="display: inline-block" ng-visible="trigger.is_active">
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown" data-title="Build History" bs-tooltip="tooltip.title" data-container="body"
|
||||
ng-click="loadTriggerBuildHistory(trigger)">
|
||||
|
@ -305,7 +306,11 @@
|
|||
<b class="caret"></b>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right pull-right">
|
||||
<li><a href="https://github.com/login/oauth/authorize?client_id={{ githubClientId }}&scope=repo,user:email&redirect_uri={{ githubRedirectUri }}/trigger/{{ repo.namespace }}/{{ repo.name }}"><i class="fa fa-github fa-lg"></i>GitHub - Repository Push</a></li>
|
||||
<li>
|
||||
<a href="{{ TriggerService.getRedirectUrl('github', repo.namespace, repo.name) }}">
|
||||
<i class="fa fa-github fa-lg"></i>GitHub - Repository Push
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
<li>
|
||||
<a href="javascript:void(0)" data-toggle="tab" data-target="#create-user">Create User</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" data-toggle="tab" data-target="#usage-counter" ng-click="getUsage()">System Usage</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">System Logs</a>
|
||||
</li>
|
||||
|
@ -27,6 +30,29 @@
|
|||
<div class="logsView" makevisible="logsCounter" all-logs="true"></div>
|
||||
</div>
|
||||
|
||||
<!-- Usage tab -->
|
||||
<div id="usage-counter" class="tab-pane">
|
||||
<div class="quay-spinner" ng-show="systemUsage == null"></div>
|
||||
<div class="usage-chart" total="systemUsage.allowed" limit="systemUsageLimit"
|
||||
current="systemUsage.usage" usage-title="Deployed Repositories"></div>
|
||||
|
||||
<!-- Alerts -->
|
||||
<div class="alert alert-danger" ng-show="systemUsageLimit == 'over' && systemUsage">
|
||||
You have deployed more repositories than your plan allows. Please
|
||||
upgrade your subscription by contacting <a href="mailto:sales@coreos.com">CoreOS Sales</a>.
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning" ng-show="systemUsageLimit == 'at' && systemUsage">
|
||||
You are at your current plan's number of allowed repositories. It might be time to think about
|
||||
upgrading your subscription by contacting <a href="mailto:sales@coreos.com">CoreOS Sales</a>.
|
||||
</div>
|
||||
|
||||
<div class="alert alert-success" ng-show="systemUsageLimit == 'near' && systemUsage">
|
||||
You are nearing the number of allowed deployed repositories. It might be time to think about
|
||||
upgrading your subscription by contacting <a href="mailto:sales@coreos.com">CoreOS Sales</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create user tab -->
|
||||
<div id="create-user" class="tab-pane">
|
||||
<span class="quay-spinner" ng-show="creatingUser"></span>
|
||||
|
|
|
@ -177,7 +177,7 @@
|
|||
<div class="panel-body">
|
||||
<div ng-show="hasGithubLogin && githubLogin" class="lead col-md-8">
|
||||
<i class="fa fa-github fa-lg" style="margin-right: 6px;" data-title="GitHub" bs-tooltip="tooltip.title"></i>
|
||||
<b><a href="https://github.com/{{githubLogin}}" target="_blank">{{githubLogin}}</a></b>
|
||||
<b><a href="{{githubEndpoint}}{{githubLogin}}" target="_blank">{{githubLogin}}</a></b>
|
||||
<span class="delete-ui" button-title="'Detach'" delete-title="'Detach Account'" style="margin-left: 10px"
|
||||
perform-delete="detachExternalLogin('github')"></span>
|
||||
</div>
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
<!-- Content view -->
|
||||
<div class="repo-content" ng-show="currentTag.image_id || currentImage">
|
||||
<!-- Image History -->
|
||||
<div id="image-history" style="max-height: 10px;">
|
||||
<div id="image-history">
|
||||
<div class="row">
|
||||
<!-- Tree View container -->
|
||||
<div class="col-md-8">
|
||||
|
|
Reference in a new issue