Implement new create and manager trigger UI

Implements the new trigger setup user interface, which is now a linear workflow found on its own page, rather than a tiny modal dialog

Fixes #1187
This commit is contained in:
Joseph Schorr 2016-09-27 16:52:34 +02:00
parent 21b09a7451
commit 8e863b8cf5
47 changed files with 1835 additions and 1068 deletions

View file

@ -4,9 +4,7 @@
<!-- Credentials -->
<div ng-repeat="credential in trigger.config.credentials">
<p>
{{ credential.name }}:
<div class="copy-box" value="credential.value"></div>
</p>
{{ credential.name }}:
<div class="copy-box" value="credential.value"></div>
</div>
</div>

View file

@ -0,0 +1,32 @@
<div class="dockerfile-path-select-element">
<div class="dropdown-select" placeholder="'Enter path containing a Dockerfile'"
selected-item="selectedPath"
lookahead-items="paths"
handle-input="setPath(input)"
handle-item-selected="setSelectedPath(datum.value)"
allow-custom-input="true"
hide-dropdown="!supportsFullListing">
<!-- Icons -->
<i class="dropdown-select-icon none-icon fa fa-folder-o fa-lg" ng-show="isUnknownPath"></i>
<i class="dropdown-select-icon none-icon fa fa-folder fa-lg" style="color: black;" ng-show="!isUnknownPath"></i>
<i class="dropdown-select-icon fa fa-folder fa-lg"></i>
<!-- Dropdown menu -->
<ul class="dropdown-select-menu pull-right" role="menu">
<li ng-repeat="path in paths">
<a ng-click="setSelectedPath(path)" ng-if="path">
<i class="fa fa-folder fa-lg"></i> {{ path }}
</a>
</li>
<li class="dropdown-header" role="presentation" ng-show="!paths.length">
No Dockerfiles found in repository
</li>
</ul>
</div>
<div style="padding: 10px">
<div class="co-alert co-alert-danger" ng-show="!isValidPath && currentPath">
Path entered for folder containing Dockerfile is invalid: Must start with a '/'.
</div>
</div>
</div>

View file

@ -0,0 +1,6 @@
<div class="linear-workflow-section-element" ng-show="sectionVisible"
ng-class="isCurrentSection ? 'current-section' : ''">
<form ng-submit="submitSection()">
<div ng-transclude />
</form>
</div>

View file

@ -0,0 +1,31 @@
<div class="linear-workflow-element">
<!-- Contents -->
<div ng-transclude/>
<div class="bottom-controls">
<table class="upcoming-table">
<tr>
<td>
<!-- Next button -->
<button class="btn btn-primary" ng-disabled="!currentSection.valid"
ng-click="nextSection()"
ng-class="{'btn-success': currentSection.index == sections.length - 1, 'btn-lg': currentSection.index == sections.length - 1}">
<span ng-if="currentSection.index != sections.length - 1">Continue</span>
<span ng-if="currentSection.index == sections.length - 1"><i class="fa fa-check-circle"></i>{{ doneTitle }}</span>
</button>
</td>
<td>
<!-- Next sections -->
<div class="upcoming" ng-if="currentSection.index != sections.length - 1">
<b>Next:</b>
<ul>
<li ng-repeat="section in sections" ng-if="section.index > currentSection.index">
{{ section.title }}
</li>
</ul>
</div>
</td>
</tr>
</table>
</div>
</div>

View file

@ -0,0 +1,43 @@
<div class="manage-trigger-custom-git-element manage-trigger-control">
<div class="linear-workflow" workflow-state="currentState" done-title="Create Trigger"
workflow-complete="activateTrigger({'config': config})">
<!-- Section: Repository -->
<div class="linear-workflow-section row"
section-id="repo"
section-title="Git Repository"
section-valid="config.build_source">
<div class="col-lg-7 col-md-7 col-sm-12 main-col">
<h3>Enter repository</h3>
<strong>
Please enter the HTTP or SSH style URL used to clone your git repository:
</strong>
<input class="form-control" type="text" placeholder="git@example.com:namespace/repository.git"
ng-model="config.build_source" ng-pattern="/(((http|https):\/\/)(.+)|\w+@(.+):(.+))/">
</div>
<div class="col-lg-5 col-md-5 hidden-sm hidden-xs help-col">
<p>Custom git triggers support any externally accessible git repository, via either the normal git protocol or HTTP.</p>
<p><b>It is the responsibility of the git repository to invoke a webhook to tell <span class="registry-name" short="true"></span> that a commit has been added.</b></p>
</div>
</div><!-- /Section: Repository -->
<!-- Section: Build context -->
<div class="linear-workflow-section row"
section-id="dockerfile"
section-title="Build context"
section-valid="config.subdir">
<div class="col-lg-7 col-md-7 col-sm-12 main-col">
<h3>Select build context directory</h3>
<strong>Please select the build context directory under the git repository:</strong>
<input class="form-control" type="text" placeholder="/"
ng-model="config.subdir" ng-pattern="/^($|\/|\/.+)/">
</div>
<div class="col-lg-5 col-md-5 hidden-sm hidden-xs help-col">
<p>The build context directory is the path of the directory containing the Dockerfile and any other files to be made available when the build is triggered.</p>
<p>If the Dockerfile is located at the root of the git repository, enter <code>/</code> as the build context directory.</p>
</div>
</div><!-- /Section: Build context -->
</div>

View file

@ -0,0 +1,330 @@
<div class="manage-trigger-githost-element manage-trigger-control">
<div class="linear-workflow" workflow-state="currentState" done-title="Create Trigger"
workflow-complete="createTrigger()">
<!-- Section: Namespace -->
<div class="linear-workflow-section row"
section-id="namespace"
section-title="{{ 'Select ' + namespaceTitle }}"
section-valid="local.selectedNamespace">
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.namespaces">
<h3>Select {{ namespaceTitle }}</h3>
<strong>
Please select the {{ namespaceTitle }} under which the repository lives
</strong>
<div class="co-top-bar">
<div class="co-filter-box">
<span class="page-controls" total-count="local.orderedNamespaces.entries.length" current-page="local.namespaceOptions.page" page-size="namespacesPerPage"></span>
<input class="form-control" type="text" ng-model="local.namespaceOptions.filter" placeholder="Filter {{ namespaceTitle }}s...">
</div>
</div>
<table class="co-table" style="margin-top: 20px;">
<thead>
<td class="checkbox-col"></td>
<td ng-class="TableService.tablePredicateClass('id', local.namespaceOptions.predicate, local.namespaceOptions.reverse)">
<a ng-click="TableService.orderBy('id', local.namespaceOptions)">{{ namespaceTitle }}</a>
</td>
<td ng-class="TableService.tablePredicateClass('score', local.namespaceOptions.predicate, local.namespaceOptions.reverse)"
class="importance-col hidden-xs">
<a ng-click="TableService.orderBy('score', local.namespaceOptions)">Importance</a>
</td>
</thead>
<tr class="co-checkable-row"
ng-repeat="namespace in local.orderedNamespaces.visibleEntries | slice:(namespacesPerPage * local.namespaceOptions.page):(namespacesPerPage * (local.namespaceOptions.page + 1))"
ng-class="local.selectedNamespace == namespace ? 'checked' : ''"
bindonce>
<td>
<input type="radio" ng-model="local.selectedNamespace" ng-value="namespace">
</td>
<td>
<img class="namespace-avatar" ng-src="{{ namespace.avatar_url }}">
<span class="anchor" href="{{ namespace.url }}" is-text-only="!namespace.url">{{ namespace.id }}</span>
</td>
<td class="importance-col hidden-xs">
<span class="strength-indicator" value="::namespace.score" maximum="::local.maxScore"
log-base="10"></span>
</td>
</tr>
</table>
<div class="empty" ng-if="local.namespaces.length && !local.orderedNamespaces.entries.length"
style="margin-top: 20px;">
<div class="empty-primary-msg">No matching {{ namespaceTitle }} found.</div>
<div class="empty-secondary-msg">Try expanding your filtering terms.</div>
</div>
</div>
<div class="col-lg-8 col-md-8 col-sm-12 main-col" ng-show="!local.namespaces">
<span class="cor-loader-inline"></span> Retrieving {{ namespaceTitle }}s
</div>
<div class="col-lg-4 col-md-4 hidden-sm hidden-xs help-col" ng-show="local.namespaces">
<p>
<span class="registry-name"></span> has been granted access to read and view these {{ namespaceTitle }}s.
</p>
<p>
Don't see an expected {{ namespaceTitle }} here? Please make sure third-party access is enabled for <span class="registry-name"></span> under that {{ namespaceTitle }}.
</p>
</div>
</div><!-- /Section: Namespace -->
<!-- Section: Repository -->
<div class="linear-workflow-section row"
section-id="repo"
section-title="Select Repository"
section-valid="local.selectedRepository">
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.repositories">
<h3>Select Repository</h3>
<strong>
Select a repository in
<img class="namespace-avatar" ng-src="{{ local.selectedNamespace.avatar_url }}">
{{ local.selectedNamespace.id }}
</strong>
<div class="co-top-bar">
<div class="co-filter-box">
<span class="page-controls" total-count="local.orderedRepositories.entries.length" current-page="local.repositoryOptions.page" page-size="repositoriesPerPage"></span>
<input class="form-control" type="text" ng-model="local.repositoryOptions.filter" placeholder="Filter repositories...">
<div class="filter-options">
<label><input type="checkbox" ng-model="local.repositoryOptions.hideStale">Hide stale repositories</label>
</div>
</div>
</div>
<table class="co-table" style="margin-top: 20px;">
<thead>
<td class="checkbox-col"></td>
<td ng-class="TableService.tablePredicateClass('name', local.repositoryOptions.predicate, local.repositoryOptions.reverse)" class="nowrap-col">
<a ng-click="TableService.orderBy('name', local.repositoryOptions)">Repository Name</a>
</td>
<td ng-class="TableService.tablePredicateClass('last_updated_datetime', local.repositoryOptions.predicate, local.repositoryOptions.reverse)"
class="last-updated-col nowrap-col">
<a ng-click="TableService.orderBy('last_updated_datetime', local.namespaceOptions)">Last Updated</a>
</td>
<td class="hidden-xs">Description</td>
</thead>
<tr class="co-checkable-row"
ng-repeat="repository in local.orderedRepositories.visibleEntries | slice:(repositoriesPerPage * local.repositoryOptions.page):(repositoriesPerPage * (local.repositoryOptions.page + 1))"
ng-class="local.selectedRepository == repository ? 'checked' : ''"
bindonce>
<td>
<span ng-if="!repository.has_admin_permissions">
<i class="fa fa-exclamation-triangle"
data-title="Admin access is required to add the webhook trigger to this repository" bs-tooltip></i>
</span>
<input type="radio" ng-model="local.selectedRepository" ng-value="repository"
ng-if="repository.has_admin_permissions">
</td>
<td class="nowrap-col">
<i class="service-icon fa {{ getTriggerIcon() }}"></i>
<span class="anchor" href="{{ repository.url }}" is-text-only="!repository.url">{{ repository.name }}</span>
</td>
<td class="last-updated-col nowrap-col">
<span am-time-ago="repository.last_updated_datetime"></span>
</td>
<td class="hidden-xs">
<span ng-if="repository.description">{{ repository.description }}</span>
<span class="empty-description" ng-if="!repository.description">(None)</span>
</td>
</tr>
</table>
<div class="empty" ng-if="local.repositories.length && !local.orderedRepositories.entries.length"
style="margin-top: 20px;">
<div class="empty-primary-msg">No matching repositories found.</div>
<div class="empty-secondary-msg">Try expanding your filtering terms.</div>
</div>
</div>
<div class="col-lg-8 col-md-8 col-sm-12 main-col" ng-show="!local.repositories">
<span class="cor-loader-inline"></span> Retrieving repositories
</div>
<div class="col-lg-4 col-md-4 hidden-sm hidden-xs help-col" ng-show="local.repositories">
<p>
A webhook will be added to the selected repository in order to detect when new commits are made.
</p>
<p>
Don't see an expected repository here? Please make sure you have admin access on that repository.
</p>
</div>
</div><!-- /Section: Repository -->
<!-- Section: Trigger Options -->
<div class="linear-workflow-section row"
section-id="triggeroptions"
section-title="Configure Trigger"
section-valid="local.triggerOptions">
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.repositoryRefs">
<h3>Configure Trigger</h3>
<strong>
Configure trigger options for
<img class="namespace-avatar" ng-src="{{ local.selectedNamespace.avatar_url }}">
{{ local.selectedNamespace.id }}/{{ local.selectedRepository.name }}
</strong>
<div class="radio" style="margin-top: 20px;">
<label>
<input type="radio" name="optionRadio" ng-model="local.triggerOptions.hasBranchTagFilter" ng-value="false">
<div class="title">Trigger for all branches and tags <span class="weak">(default)</span></div>
<div class="description">Build a container image for each commit across all branches and tags</div>
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="optionRadio" ng-model="local.triggerOptions.hasBranchTagFilter" ng-value="true">
<div class="title">Trigger only on branches and tags matching a regular expression</div>
<div class="description">Only build container images for a subset of branches and/or tags.</div>
<div class="extended" ng-if="local.triggerOptions.hasBranchTagFilter">
<table>
<tr>
<td style="white-space: nowrap;">Regular Expression:</td>
<td>
<input type="text" class="form-control" ng-model="local.triggerOptions.branchTagFilter" required>
<div class="description">Examples: heads/master, tags/tagname, heads/.+</div>
<div class="regex-match-view"
items="local.repositoryFullRefs"
regex="local.triggerOptions.branchTagFilter"
ng-if="local.triggerOptions.branchTagFilter"></div>
</td>
</tr>
</table>
</div>
</label>
</div>
</div>
<div class="col-lg-8 col-md-8 col-sm-12 main-col" ng-show="!local.repositoryRefs">
<span class="cor-loader-inline"></span> Retrieving repository refs
</div>
<div class="col-lg-4 col-md-4 hidden-sm hidden-xs help-col">
<p>Do you want to build a new container image for commits across all branches and tags, or limit to a subset?</p>
<p>For example, if you use release branches instead of <code>master</code> for building versions of your software, you can configure the trigger to only build images for these branches.</p>
<p>All images built will be tagged with the name of the branch or tag whose change invoked the trigger</p>
</div>
</div><!-- /Section: Trigger Options -->
<!-- Section: Dockerfile Location -->
<div class="linear-workflow-section row"
section-id="dockerfilelocation"
section-title="Select Dockerfile"
section-valid="local.hasValidDockerfilePath">
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.dockerfileLocations.status == 'error'">
<div class="co-alert co-alert-warning">
{{ local.dockerfileLocations.message }}
</div>
</div>
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.dockerfileLocations.status == 'success'">
<h3>Select Dockerfile</h3>
<strong>
Please select the location of the Dockerfile to build when this trigger is invoked
</strong>
<div class="dockerfile-path-select" current-path="local.dockerfilePath" paths="local.dockerfileLocations.subdir"
supports-full-listing="true" is-valid-path="local.hasValidDockerfilePath"></div>
</div>
<div class="col-lg-8 col-md-8 col-sm-12 main-col" ng-show="!local.dockerfileLocations">
<span class="cor-loader-inline"></span> Retrieving Dockerfile locations
</div>
<div class="col-lg-4 col-md-4 hidden-sm hidden-xs help-col">
<p>Please select the location containing the Dockerfile to be built.</p>
<p>The build context will start at the location selected.</p>
</div>
</div><!-- /Section: Dockerfile Location -->
<!-- Section: Verification and Robot Account -->
<div class="linear-workflow-section row"
section-id="verification"
section-title="Confirm"
section-valid="local.triggerAnalysis.status != 'error' && (local.triggerAnalysis.status != 'requiresrobot' || local.robotAccount != null)">
<!-- Error -->
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.triggerAnalysis.status == 'error'">
<h3 class="error"><i class="fa fa-exclamation-circle"></i> Verification Error</h3>
<strong>
There was an error when verifying the state of <img class="namespace-avatar" ng-src="{{ local.selectedNamespace.avatar_url }}">
{{ local.selectedNamespace.id }}/{{ local.selectedRepository.name }}
</strong>
{{ local.triggerAnalysis.message }}
</div>
<!-- Warning -->
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.triggerAnalysis.status == 'warning'">
<h3 class="warning"><i class="fa fa-exclamation-triangle"></i> Verification Warning</h3>
{{ local.triggerAnalysis.message }}
</div>
<!-- Public base -->
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.triggerAnalysis.status == 'publicbase'">
<h3 class="success"><i class="fa fa-check-circle"></i> Ready to go!</h3>
<strong>Click "Create Trigger" to complete setup of this build trigger</strong>
</div>
<!-- Requires robot and is not admin -->
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.triggerAnalysis.status == 'requiresrobot' && !local.triggerAnalysis.is_admin">
<h3>Robot Account Required</h3>
<p>The selected Dockerfile in the selected repository depends upon a private base image</p>
<p>A robot account with access to the base image is required to setup this trigger, but you are not the administrator of this namespace.</p>
<p>Administrative access is required to continue to ensure security of the robot credentials.</p>
</div>
<!-- Requires robot and is admin -->
<div class="col-lg-7 col-md-7 col-sm-12 main-col" ng-show="local.triggerAnalysis.status == 'requiresrobot' && local.triggerAnalysis.is_admin">
<h3>Select Robot Account</h3>
<strong>
The selected Dockerfile in the selected repository depends upon a private base image. Select a robot account with access:
</strong>
<div class="co-top-bar">
<div class="co-filter-box">
<span class="page-controls" total-count="local.orderedRobotAccounts.entries.length" current-page="local.robotOptions.page" page-size="robotsPerPage"></span>
<input class="form-control" type="text" ng-model="local.robotOptions.filter" placeholder="Filter robot accounts...">
</div>
</div>
<table class="co-table" style="margin-top: 20px;">
<thead>
<td class="checkbox-col"></td>
<td ng-class="TableService.tablePredicateClass('name', local.robotOptions.predicate, local.robotOptions.reverse)">
<a ng-click="TableService.orderBy('name', local.robotOptions)">Robot Account</a>
</td>
<td ng-class="TableService.tablePredicateClass('can_read', local.robotOptions.predicate, local.robotOptions.reverse)">
<a ng-click="TableService.orderBy('can_read', local.robotOptions)">Has Read Access</a>
</td>
</thead>
<tr class="co-checkable-row"
ng-repeat="robot in local.orderedRobotAccounts.visibleEntries | slice:(robotsPerPage * local.namespaceOptions.page):(robotsPerPage * (local.robotOptions.page + 1))"
ng-class="local.robotAccount == robot ? 'checked' : ''"
bindonce>
<td>
<input type="radio" ng-model="local.robotAccount" ng-value="robot">
</td>
<td>
<span class="entity-reference" entity="robot"></span>
</td>
<td>
<span ng-if="robot.can_read" class="success">Can Read</span>
<span ng-if="!robot.can_read">Read access will be added if selected</span>
</td>
</tr>
</table>
<div class="empty" ng-if="local.triggerAnalysis.robots.length && !local.orderedRobotAccounts.entries.length"
style="margin-top: 20px;">
<div class="empty-primary-msg">No matching robot accounts found.</div>
<div class="empty-secondary-msg">Try expanding your filtering terms.</div>
</div>
</div>
<div class="col-lg-4 col-md-4 hidden-sm hidden-xs help-col" ng-if="local.triggerAnalysis.status == 'requiresrobot' && local.triggerAnalysis.is_admin">
<p>The Dockerfile you selected utilizes a private base image.</p>
<p>In order for the <span class="registry-name"></span> to pull the base image during the build process, a robot account with access must be selected.</p>
<p>Robot accounts that already have access to this base image are listed first. If you select a robot account that does not currently have access, read permission will be granted to that robot account on trigger creation.</p>
</div>
</div><!-- /Section: Robot Account -->
</div>

View file

@ -0,0 +1,29 @@
<div class="regex-match-view-element">
<div ng-if="filterMatches(regex, items, false) == null">
<i class="fa fa-exclamation-triangle"></i>Invalid Regular Expression!
</div>
<div ng-if="filterMatches(regex, items, false) != null">
<table class="match-table">
<tr>
<td>Matching:</td>
<td>
<ul class="matching match-list">
<li ng-repeat="item in filterMatches(regex, items, true)">
<i class="fa {{ item.icon }}"></i>{{ item.title }}
</li>
</ul>
</td>
</tr>
<tr>
<td>Not Matching:</td>
<td>
<ul class="not-matching match-list">
<li ng-repeat="item in filterMatches(regex, items, false)">
<i class="fa {{ item.icon }}"></i>{{ item.title }}
</li>
</ul>
</td>
</tr>
</table>
</div>
</div>

View file

@ -126,10 +126,8 @@
<tr ng-repeat="trigger in triggers | filter:{'is_active':false}">
<td colspan="5" style="text-align: center">
<span class="cor-loader-inline"></span>
Trigger Setup in progress:
<a ng-click="setupTrigger(trigger)">Resume</a> |
<a ng-click="deleteTrigger(trigger)">Cancel</a>
This build trigger has not had its setup completed:
<a ng-click="deleteTrigger(trigger)">Delete Trigger</a>
</td>
</tr>
@ -185,14 +183,6 @@
build-started="handleBuildStarted(build)">
</div>
<!-- Setup trigger dialog-->
<div class="setup-trigger-dialog"
repository="repository"
trigger="currentSetupTrigger"
canceled="cancelSetupTrigger(trigger)"
counter="showTriggerSetupCounter"
trigger-runner="askRunTrigger(trigger)"></div>
<!-- Manual trigger dialog -->
<div class="manual-trigger-build-dialog"
repository="repository"
@ -201,5 +191,4 @@
build-started="handleBuildStarted(build)"></div>
<!-- /Dialogs -->
</div>

View file

@ -1,133 +0,0 @@
<div class="setup-trigger-directive-element">
<!-- Modal message dialog -->
<div class="modal fade" id="setupTriggerModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Setup new build trigger</h4>
</div>
<div class="modal-body loading" ng-show="currentView == 'activating'">
<span class="cor-loader-inline"></span> Setting up trigger...
</div>
<div class="modal-body" ng-show="currentView != 'activating'">
<!-- Trigger-specific setup -->
<div class="trigger-description-element trigger-option-section" ng-switch on="trigger.service">
<div ng-switch-when="custom-git">
<div class="trigger-setup-custom" repository="repository" trigger="trigger"
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
analyze="checkAnalyze(isValid)"></div>
</div>
<div ng-switch-default>
<div class="trigger-setup-githost" repository="repository" trigger="trigger"
kind="{{ trigger.service }}"
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
analyze="checkAnalyze(isValid)"></div>
</div>
</div>
<!-- Loading pull information -->
<div ng-show="currentView == 'analyzing'" class="loading">
<span class="cor-loader-inline"></span> Checking pull credential requirements...
</div>
<!-- Pull information -->
<div class="trigger-option-section" ng-show="currentView == 'analyzed'">
<!-- Messaging -->
<div ng-switch on="pullInfo.analysis.status">
<div ng-switch-when="error" class="alert alert-danger">{{ pullInfo.analysis.message }}</div>
<div ng-switch-when="warning" class="alert alert-warning">{{ pullInfo.analysis.message }}</div>
<div ng-switch-when="notimplemented" class="alert alert-warning">
<p>For {{ TriggerService.getTitle(trigger.service) }} triggers, we are unable to determine dependencies automatically.</p>
<p>If the git repository being built depends on a private base image, you must manually select a robot account with the proper permissions.</p>
</div>
</div>
<div class="dockerfile-found" ng-if="pullInfo.analysis.is_public === false">
<div class="dockerfile-found-content">
A robot account is <strong>required</strong> for this build trigger because the
Dockerfile found
pulls from the private <span class="registry-name"></span> repository
<a href="/repository/{{ pullInfo.analysis.namespace }}/{{ pullInfo.analysis.name }}" ng-safenewtab>
{{ pullInfo.analysis.namespace }}/{{ pullInfo.analysis.name }}
</a>
</div>
</div>
<div style="margin-bottom: 12px">
Please select the credentials to use when pulling the base image:
</div>
<div ng-if="!isNamespaceAdmin(repository.namespace)" style="color: #aaa;">
<strong>Note:</strong> In order to set pull credentials for a build trigger, you must be an
Administrator of the namespace <strong>{{ repository.namespace }}</strong>
</div>
<!-- Namespace admin -->
<div ng-show="isNamespaceAdmin(repository.namespace)">
<!-- Select credentials -->
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default"
ng-class="pullInfo.is_public ? 'active btn-info' : ''"
ng-click="pullInfo.is_public = true">
None
</button>
<button type="button" class="btn btn-default"
ng-class="pullInfo.is_public ? '' : 'active btn-info'"
ng-click="pullInfo.is_public = false">
<i class="fa ci-robot"></i>
Robot account
</button>
</div>
<!-- Robot Select -->
<div ng-show="!pullInfo.is_public" style="margin-top: 10px">
<div class="entity-search" namespace="repository.namespace"
placeholder="'Select robot account for pulling...'"
current-entity="pullInfo.pull_entity"
allowed-entities="['robot']"></div>
<div ng-if="pullInfo.analysis.robots.length" style="margin-top: 20px; margin-bottom: 0px;">
<strong>Note</strong>: We've automatically selected robot account
<span class="entity-reference" entity="pullInfo.analysis.robots[0]"></span>,
since it has access to the private repository.
</div>
<div ng-if="!pullInfo.analysis.robots.length && pullInfo.analysis.name"
style="margin-top: 20px; margin-bottom: 0px;">
<strong>Note</strong>: No robot account currently has access to the private repository. Please create one and/or assign access in the
<a href="/repository/{{ pullInfo.analysis.namespace }}/{{ pullInfo.analysis.name }}/admin" ng-safenewtab>
repository's admin panel.
</a>
</div>
</div>
</div>
</div>
<div class="trigger-option-section" ng-show="currentView == 'postActivation'">
<div ng-if="trigger.config.credentials" class="credentials" trigger="trigger"></div>
<div ng-if="!trigger.config.credentials">
<div class="alert alert-success">The trigger has been successfully created.</div>
</div>
</div>
</div>
<div class="modal-footer" ng-show="currentView != 'activating'">
<button type="button" class="btn btn-primary" ng-disabled="!state.stepValid"
ng-click="nextStepCounter = nextStepCounter + 1"
ng-show="currentView == 'config'">Next</button>
<button type="button" class="btn btn-primary"
ng-disabled="!trigger.$ready || (!pullInfo['is_public'] && !pullInfo['pull_entity'])"
ng-click="activate()"
ng-show="currentView == 'analyzed'">Create Trigger</button>
<button type="button" class="btn btn-success" ng-click="runTriggerNow()"
ng-if="currentView == 'postActivation'">Run Trigger Now</button>
<button type="button" class="btn btn-default" data-dismiss="modal">{{ currentView == 'postActivation' ? 'Done' : 'Cancel' }}</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div>

View file

@ -1,9 +0,0 @@
<div class="step-view-step-content">
<div ng-show="!loading">
<div ng-transclude></div>
</div>
<div ng-show="loading" class="loading-message">
<span class="cor-loader-inline"></span>
{{ loadMessage }}
</div>
</div>

View file

@ -1,3 +0,0 @@
<div class="step-view-element">
<div class="transcluded" ng-transclude>
</div>

View file

@ -1,40 +0,0 @@
<div class="trigger-setup-custom-element">
<div class="selected-info" ng-show="nextStepCounter > 0">
<table style="width: 100%;">
<tr ng-show="nextStepCounter > 0">
<td width="200px">Repository</td>
<td>{{ state.build_source }}</td>
</tr>
<tr ng-show="nextStepCounter > 1">
<td>Dockerfile Location:</td>
<td>
<div class="dockerfile-location">
<i class="fa fa-folder fa-lg"></i> {{ state.subdir || '/' }}
</div>
</td>
</table>
</div>
<!-- Step view -->
<div class="step-view" next-step-counter="nextStepCounter" current-step-valid="currentStepValid"
steps-completed="stepsCompleted()">
<!-- Git URL Input -->
<!-- TODO(jschorr): make nopLoad(callback) no longer required -->
<div class="step-view-step" complete-condition="trigger['config']['build_source']" load-callback="nopLoad(callback)"
load-message="Loading Git URL Input">
<div style="margin-bottom: 12px;">Please enter an HTTP or SSH style URL used to clone your git repository:</div>
<input class="form-control" type="text" placeholder="git@example.com:namespace/repository.git" style="width: 100%;"
ng-model="state.build_source" ng-pattern="/(((http|https):\/\/)(.+)|\w+@(.+):(.+))/">
</div>
<!-- Dockerfile folder select -->
<div class="step-view-step" complete-condition="trigger.$ready" load-callback="nopLoad(callback)"
load-message="Loading Folder Input">
<div style="margin-bottom: 12px">Dockerfile Location:</div>
<input class="form-control" type="text" placeholder="/" style="width: 100%;"
ng-model="state.subdir" ng-pattern="/^($|\/|\/.+)/">
</div>
</div>
</div>

View file

@ -1,201 +0,0 @@
<div class="trigger-setup-githost-element">
<!-- Current selected info -->
<div class="selected-info" ng-show="nextStepCounter > 0">
<table style="width: 100%;">
<tr ng-show="state.currentRepo && nextStepCounter > 0">
<td width="200px">
Repository:
</td>
<td>
<div class="current-repo">
<i class="dropdown-select-icon org-icon fa" ng-class="scmIcon(kind)"
ng-show="!state.currentRepo.avatar_url"></i>
<img class="dropdown-select-icon org-icon"
ng-src="{{ state.currentRepo.avatar_url ? state.currentRepo.avatar_url : '/static/img/empty.png' }}"
ng-show="state.currentRepo.avatar_url">
{{ state.currentRepo.repo }}
</div>
</td>
</tr>
<tr ng-show="nextStepCounter > 1">
<td>
Branches and Tags:
</td>
<td>
<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>
<tr ng-show="nextStepCounter > 2">
<td>
Dockerfile Location:
</td>
<td>
<div class="dockerfile-location">
<i class="fa fa-folder fa-lg"></i> {{ state.currentLocation || '(Repository Root)' }}
</div>
</td>
</tr>
</table>
</div>
<!-- Step view -->
<div class="step-view" next-step-counter="nextStepCounter" current-step-valid="currentStepValid"
steps-completed="stepsCompleted()">
<!-- Repository select -->
<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 repository that will trigger the build:</div>
<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-lg" ng-class="scmIcon(kind)"></i>
<img class="dropdown-select-icon org-icon"
ng-show="state.currentRepo.avatar_url"
ng-src="{{ state.currentRepo.avatar_url ? state.currentRepo.avatar_url : '/static/img/empty.png' }}">
<i class="dropdown-select-icon org-icon fa fa-lg" ng-class="scmIcon(kind)"
ng-show="!state.currentRepo.avatar_url"></i>
<!-- Dropdown menu -->
<ul class="dropdown-select-menu scrollable-menu" role="menu">
<li ng-repeat-start="org in orgs" role="presentation" class="dropdown-header org-header">
<img ng-src="{{ org.info.avatar_url }}" class="org-icon">{{ org.info.name }}
</li>
<li ng-repeat="repo in org.repos" class="trigger-repo-listing">
<a ng-click="selectRepo(repo, org)">
<i class="fa fa-lg" ng-class="scmIcon(kind)"></i> {{ repo }}
</a>
</li>
<li role="presentation" class="divider" ng-repeat-end ng-show="$index < orgs.length - 1"></li>
</ul>
</div>
</div>
<!-- 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 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.hasBranchTagFilter ? '' : 'active btn-info'" ng-click="state.hasBranchTagFilter = false">
All Branches and Tags
</button>
<button type="button" class="btn btn-default"
ng-class="state.hasBranchTagFilter ? 'active btn-info' : ''" ng-click="state.hasBranchTagFilter = true">
Matching Regular Expression
</button>
</div>
<div ng-show="state.hasBranchTagFilter" style="margin-top: 10px;">
<form>
<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 ng-click="state.branchTagFilter = 'heads/.+'">
<i class="fa fa-code-fork"></i>All Branches</a>
</li>
<li><a 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 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="ref-reference"
ng-class="isMatching('heads', branchName, state.branchTagFilter) ? 'match' : 'not-match'">
<span ng-click="addRef('heads', branchName)" ng-safenewtab>
{{ branchName }}
</span>
</li>
</ul>
<span ng-if="branchNames.length > 20">...</span>
</div>
<div class="ref-matches" ng-if="tagNames.length">
<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)" ng-safenewtab>
{{ 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>
</div>
</div>
</div>
</div>
<!-- Dockerfile folder select -->
<div class="step-view-step" complete-condition="trigger.$ready" load-callback="loadLocations(callback)"
load-message="Loading Folders">
<div style="margin-bottom: 12px">Dockerfile Location:</div>
<div class="dropdown-select" placeholder="'(Repository Root)'" selected-item="state.currentLocation"
lookahead-items="locations" handle-input="handleLocationInput(input)"
handle-item-selected="handleLocationSelected(datum)"
allow-custom-input="true"
hide-dropdown="!supportsFullListing">
<!-- Icons -->
<i class="dropdown-select-icon none-icon fa fa-folder-o fa-lg" ng-show="state.isInvalidLocation"></i>
<i class="dropdown-select-icon none-icon fa fa-folder fa-lg" style="color: black;" ng-show="!state.isInvalidLocation"></i>
<i class="dropdown-select-icon fa fa-folder fa-lg"></i>
<!-- Dropdown menu -->
<ul class="dropdown-select-menu" role="menu">
<li ng-repeat="location in locations">
<a ng-click="setLocation(location)" ng-if="!location">
<i class="fa fa-github fa-lg"></i> Repository Root
</a>
<a ng-click="setLocation(location)" ng-if="location">
<i class="fa fa-folder fa-lg"></i> {{ location }}
</a>
</li>
<li class="dropdown-header" role="presentation" ng-show="!locations.length">
No Dockerfiles found in repository
</li>
</ul>
</div>
<div class="cor-loader" ng-show="!locations && !locationError"></div>
<div class="alert alert-warning" ng-show="locationError">
{{ locationError }}
</div>
<div class="alert alert-warning" ng-show="locations && !locations.length && supportsFullListing">
Warning: No Dockerfiles were found in {{ state.currentRepo.repo }}
</div>
<div class="alert alert-info" ng-show="locations.length && state.isInvalidLocation && supportsFullListing">
Note: The folder does not currently exist or contain a Dockerfile
</div>
</div>
<!-- /step-view -->
</div>
</div>

View file

@ -1,4 +1,4 @@
<span>
<i class="fa fa-git-square fa-lg" style="margin-right: 6px;" data-title="git" bs-tooltip="tooltip.title"></i>
Push to {{ trigger.config.build_source }}
Push to repository {{ trigger.config.build_source }}
</span>