Merge remote-tracking branch 'origin/orgs'
Conflicts: static/partials/repo-admin.html
This commit is contained in:
commit
d7cae4fbca
72 changed files with 18683 additions and 1028 deletions
3
static/partials/create-team-dialog.html
Normal file
3
static/partials/create-team-dialog.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<form name="newteamform" ng-submit="createTeam(); hide()" novalidate>
|
||||
<input id="create-team-box" type="text form-control" placeholder="Team Name" ng-blur="hide()" ng-pattern="/^[a-zA-Z][a-zA-Z0-9]+$/" ng-model="newTeamName" ng-trim="false" ng-minlength="2" required>
|
||||
</form>
|
|
@ -1,7 +1,7 @@
|
|||
<div class="container ready-indicator" data-status="{{ status }}">
|
||||
<div class="alert alert-warning">Warning: Quay requires docker version 0.6.2 or higher to work</div>
|
||||
|
||||
<h2>User guide</h2>
|
||||
<h2>User Guide</h2>
|
||||
<div class="user-guide container">
|
||||
|
||||
<h3>Pulling a repository from Quay</h3>
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a ng-href="/repository/" target="{{ appLinkTarget() }}">Repositories</a></li>
|
||||
<li><a ng-href="/guide/" target="{{ appLinkTarget() }}">User Guide</a></li>
|
||||
<li><a ng-href="/plans/" target="{{ appLinkTarget() }}">Plans & Pricing</a></li>
|
||||
<li><a ng-href="/guide/" target="{{ appLinkTarget() }}">Guide</a></li>
|
||||
<li><a ng-href="/plans/" target="{{ appLinkTarget() }}">Pricing</a></li>
|
||||
<li><a ng-href="/organizations/" target="{{ appLinkTarget() }}">Organizations</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
@ -28,7 +29,7 @@
|
|||
</form>
|
||||
|
||||
<span class="navbar-left user-tools" ng-show="!user.anonymous">
|
||||
<a href="/new/"><i class="fa fa-upload user-tool" title="Create new repository"></i></a>
|
||||
<a href="/new/"><i class="fa fa-upload user-tool" bs-tooltip="tooltip.title" data-placement="bottom" title="Create new repository"></i></a>
|
||||
</span>
|
||||
|
||||
<li class="dropdown" ng-switch-when="false">
|
||||
|
@ -45,6 +46,7 @@
|
|||
<span class="badge user-notification" ng-show="user.askForPassword">1</span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a ng-href="/organizations/" target="{{ appLinkTarget() }}">Organizations</a></li>
|
||||
<li><a href="javascript:void(0)" ng-click="signout()">Sign out</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
</div>
|
||||
|
||||
<!-- Comment -->
|
||||
<blockquote ng-show="image.comment" ng-bind-html-unsafe="getMarkedDown(image.comment)"></blockquote>
|
||||
<blockquote ng-show="image.comment">
|
||||
<span class="markdown-view" content="image.comment"></span>
|
||||
</blockquote>
|
||||
|
||||
<!-- Information -->
|
||||
<dl class="dl-normal">
|
||||
|
|
|
@ -12,22 +12,22 @@
|
|||
<div ng-show="loadingmyrepos">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
<span class="namespace-selector" user="user" namespace="namespace" ng-show="!loadingmyrepos && user.organizations"></span>
|
||||
<div ng-show="!loadingmyrepos && myrepos.length > 0">
|
||||
<h2>Your Top Repositories</h2>
|
||||
<h2>Top Repositories</h2>
|
||||
<div class="repo-listing" ng-repeat="repository in myrepos">
|
||||
<span class="repo-circle no-background" repo="repository"></span>
|
||||
<a ng-href="/repository/{{ repository.namespace }}/{{ repository.name }}">{{repository.namespace}}/{{repository.name}}</a>
|
||||
<div class="description" ng-bind-html-unsafe="getCommentFirstLine(repository.description)"></div>
|
||||
<div class="markdown-view description" content="repository.description" first-line-only="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="!loadingmyrepos && myrepos.length == 0">
|
||||
<div class="sub-message">
|
||||
You don't have any <b>private</b> repositories yet!
|
||||
|
||||
<div class="sub-message" style="margin-top: 20px">
|
||||
<span ng-show="namespace != user.username">You don't have access to any repositories in this organization yet.</span>
|
||||
<span ng-show="namespace == user.username">You don't have any repositories yet!</span>
|
||||
<div class="options">
|
||||
<div class="option"><a href="/guide">Learn how to create a repository</a></div>
|
||||
<div class="or"><span>or</span></div>
|
||||
<div class="option"><a href="/repository">Browse the public repositories</a></div>
|
||||
<a class="btn btn-primary" href="/repository/">Browse all repositories</a>
|
||||
<a class="btn btn-success" href="/new/" ng-show="canCreateRepo(namespace)">Create a new repository</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
102
static/partials/new-organization.html
Normal file
102
static/partials/new-organization.html
Normal file
|
@ -0,0 +1,102 @@
|
|||
<div class="loading" ng-show="loading || creating">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="container create-org" ng-show="!loading && !creating">
|
||||
|
||||
<div class="row header-row">
|
||||
<div class="col-md-8 col-md-offset-1">
|
||||
<h2>Create Organization</h2>
|
||||
|
||||
<div class="steps-container" ng-show="false">
|
||||
<ul class="steps">
|
||||
<li class="step" ng-class="!user || user.anonymous ? 'active' : ''">
|
||||
<i class="fa fa-sign-in"></i>
|
||||
<span class="title">Login with an account</span>
|
||||
</li>
|
||||
<li class="step" ng-class="!user.anonymous && !created ? 'active' : ''">
|
||||
<i class="fa fa-gear"></i>
|
||||
<span class="title">Setup your organization</span>
|
||||
</li>
|
||||
<li class="step" ng-class="!user.anonymous && created ? 'active' : ''">
|
||||
<i class="fa fa-group"></i>
|
||||
<span class="title">Create teams</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 1 -->
|
||||
<div class="row" ng-show="!user || user.anonymous">
|
||||
<div class="col-md-10 col-md-offset-1 page-description">
|
||||
In order to create a new organization, <b>you must first be signed in</b> as the
|
||||
user that <b>will become an admin</b> for the organization. Please sign-in if
|
||||
you already have an account, or <a href="/">sign up</a> on the landing
|
||||
page to create a new account.
|
||||
</div>
|
||||
<div class="col-sm-6 col-sm-offset-3">
|
||||
<div class="step-container" >
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">Sign In</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="signin-form" redirect-url="'/organizations/new'"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 2 -->
|
||||
<div class="row" ng-show="user && !user.anonymous && !created">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-8">
|
||||
<div class="step-container">
|
||||
<h3>Setup the new organization</h3>
|
||||
|
||||
<form method="post" name="newOrgForm" id="newOrgForm" ng-submit="createNewOrg()">
|
||||
<div class="form-group">
|
||||
<label for="orgName">Organization Name</label>
|
||||
<input id="orgName" name="orgName" type="text" class="form-control" placeholder="Organization Name"
|
||||
ng-model="org.name" required autofocus data-trigger="manual" data-content="{{ createError }}"
|
||||
data-placement="right">
|
||||
<span class="description">This will also be the namespace for your repositories</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="orgName">Organization Email</label>
|
||||
<input id="orgEmail" name="orgEmail" type="email" class="form-control" placeholder="Organization Email"
|
||||
ng-model="org.email" required>
|
||||
<span class="description">This address must be different from your account's email</span>
|
||||
</div>
|
||||
|
||||
<!-- Plans Table -->
|
||||
<div class="form-group plan-group">
|
||||
<strong>Choose your organization's plan</strong>
|
||||
<div class="plans-table" plans="plans" current-plan="currentPlan"></div>
|
||||
</div>
|
||||
|
||||
<div class="button-bar">
|
||||
<button class="btn btn-large btn-success" type="submit" ng-disabled="newOrgForm.$invalid || !currentPlan">
|
||||
Create Organization
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3 -->
|
||||
<div class="row" ng-show="user && !user.anonymous && created">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-8">
|
||||
<div class="step-container">
|
||||
<h3>Organization Created</h3>
|
||||
<h4><a href="/organization/{{ org.name }}">Manage Teams Now</a></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -28,17 +28,19 @@
|
|||
<div class="col-md-8">
|
||||
<div class="section">
|
||||
<div class="new-header">
|
||||
<span class="repo-circle no-background" repo="repo"></span>
|
||||
<span style="color: #444;"> {{user.username}}</span> <span style="color: #ccc">/</span> <span class="name-container"><input id="repoName" name="repoName" type="text" class="form-control" placeholder="Repository Name" ng-model="repo.name" required autofocus data-trigger="manual" data-content="{{ createError }}" data-placement="right"></span>
|
||||
<span style="color: #444;">
|
||||
<span class="namespace-selector" user="user" namespace="repo.namespace" require-create="true"></span>
|
||||
<span style="color: #ccc">/</span>
|
||||
<span class="name-container">
|
||||
<input id="repoName" name="repoName" type="text" class="form-control" placeholder="Repository Name" ng-model="repo.name" required autofocus data-trigger="manual" data-content="{{ createError }}" data-placement="right">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<strong>Description:</strong><br>
|
||||
<p class="description lead editable" ng-click="editDescription()">
|
||||
<span class="content" ng-bind-html-unsafe="getMarkedDown(repo.description)"></span>
|
||||
<i class="fa fa-edit"></i>
|
||||
</p>
|
||||
<div class="description markdown-input" content="repo.description" can-write="true"
|
||||
field-title="'repository description'"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,13 +70,19 @@
|
|||
</div>
|
||||
|
||||
<!-- Payment -->
|
||||
<div class="required-plan" ng-show="repo.is_public == '0' && planRequired">
|
||||
<div class="required-plan" ng-show="repo.is_public == '0' && planRequired && isUserNamespace">
|
||||
<div class="alert alert-warning">
|
||||
In order to make this repository private, you’ll need to upgrade your plan from <b>{{ subscribedPlan.title }}</b> to <b>{{ planRequired.title }}</b>. This will cost $<span>{{ planRequired.price / 100 }}</span>/month.
|
||||
</div>
|
||||
<a class="btn btn-primary" ng-click="upgradePlan()" ng-show="!planChanging">Upgrade now</a>
|
||||
<i class="fa fa-spinner fa-spin fa-3x" ng-show="planChanging"></i>
|
||||
</div>
|
||||
|
||||
<div class="required-plan" ng-show="repo.is_public == '0' && planRequired && !isUserNamespace">
|
||||
<div class="alert alert-warning">
|
||||
This organization has reached its private repository limit. Please contact your administrator.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
67
static/partials/org-admin.html
Normal file
67
static/partials/org-admin.html
Normal file
|
@ -0,0 +1,67 @@
|
|||
<div class="loading" ng-show="loading">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="loading" ng-show="!loading && !organization">
|
||||
No matching organization found
|
||||
</div>
|
||||
|
||||
<div class="org-admin container" ng-show="!loading && organization">
|
||||
<div class="organization-header" organization="organization"></div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Side tabs -->
|
||||
<div class="col-md-2">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li class="active"><a href="javascript:void(0)" data-toggle="tab" data-target="#plan">Plan and Usage</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#members" ng-click="loadMembers()">Members</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="col-md-10">
|
||||
<div class="tab-content">
|
||||
<!-- Plans tab -->
|
||||
<div id="plan" class="tab-pane active">
|
||||
<div class="plan-manager" organization="orgname"></div>
|
||||
</div>
|
||||
|
||||
<!-- Members tab -->
|
||||
<div id="members" class="tab-pane">
|
||||
<i class="fa fa-spinner fa-spin fa-3x" ng-show="membersLoading"></i>
|
||||
|
||||
<div ng-show="!membersLoading">
|
||||
<div class="side-controls">
|
||||
<div class="result-count">
|
||||
Showing {{(membersFound | filter:search | limitTo:50).length}} of {{(membersFound | filter:search).length}} matching members
|
||||
</div>
|
||||
<div class="filter-input">
|
||||
<input id="member-filter" class="form-control" placeholder="Filter Members" type="text" ng-model="search.$">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th>User</th>
|
||||
<th>Teams</th>
|
||||
</thead>
|
||||
|
||||
<tr ng-repeat="memberInfo in (membersFound | filter:search | limitTo:50)">
|
||||
<td>
|
||||
<i class="fa fa-user"></i>
|
||||
{{ memberInfo.username }}
|
||||
</td>
|
||||
<td>
|
||||
<span class="team-link" ng-repeat="team in memberInfo.teams">
|
||||
<i class="fa fa-group"></i>
|
||||
<a href="/organization/{{ organization.name }}/teams/{{ team }}">{{ team }}</a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
86
static/partials/org-view.html
Normal file
86
static/partials/org-view.html
Normal file
|
@ -0,0 +1,86 @@
|
|||
<div class="loading" ng-show="loading">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="loading" ng-show="!loading && !organization">
|
||||
No matching organization found
|
||||
</div>
|
||||
|
||||
<div class="org-view container" ng-show="!loading && organization">
|
||||
<div class="organization-header" organization="organization">
|
||||
<div class="header-buttons" ng-show="organization.is_admin">
|
||||
<button class="btn btn-success" data-trigger="click" bs-popover="'static/partials/create-team-dialog.html'" data-placement="bottom" ng-click="createTeamShown()"><i class="fa fa-group"></i> Create Team</button>
|
||||
<a class="btn btn-default" href="/organization/{{ organization.name }}/admin"><i class="fa fa-gear"></i> Settings</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row hidden-xs">
|
||||
<div class="col-md-4 col-md-offset-8 col-sm-5 col-sm-offset-7 header-col" ng-show="organization.is_admin">
|
||||
Team Permissions
|
||||
<i class="info-icon fa fa-info-circle" data-placement="bottom" data-original-title="" title=""
|
||||
data-content="Global permissions for the team and its members<br><br><dl><dt>Member</dt><dd>Permissions are assigned on a per repository basis</dd><dt>Creator</dt><dd>A team can create its own repositories</dd><dt>Admin</dt><dd>A team has full control of the organization</dd></dl>"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="team-listing" ng-repeat="(name, team) in organization.teams">
|
||||
<div id="team-{{name}}" class="row">
|
||||
<div class="col-sm-7 col-md-8">
|
||||
<div class="team-title">
|
||||
<i class="fa fa-group"></i>
|
||||
<span ng-show="team.can_view">
|
||||
<a href="/organization/{{ organization.name }}/teams/{{ team.name }}">{{ team.name }}</a>
|
||||
</span>
|
||||
<span ng-show="!team.can_view">
|
||||
{{ team.name }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="team-description markdown-view" content="team.description" first-line-only="true"></div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-md-4 control-col" ng-show="organization.is_admin">
|
||||
<span class="role-group" current-role="team.role" role-changed="setRole(role, team.name)" roles="teamRoles"></span>
|
||||
<button class="btn btn-sm btn-danger" ng-click="askDeleteTeam(team.name)">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="cannotChangeTeamModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Cannot change team</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<span ng-show="!roleError">You do not have permission to change properties on teams.</span>
|
||||
<span ng-show="roleError">{{ roleError }}</span>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="confirmdeleteModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Delete Team?</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Are you sure you would like to delete this team? This <b>cannot be undone</b>.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" ng-click="deleteTeam()">Delete Team</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
129
static/partials/organizations.html
Normal file
129
static/partials/organizations.html
Normal file
|
@ -0,0 +1,129 @@
|
|||
<div class="container org-list">
|
||||
<div class="loading" ng-show="loading">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="button-bar-right">
|
||||
<a href="/organizations/new/" title="Starts the process to create a new organization" bs-tooltip="tooltip.title">
|
||||
<button class="btn btn-success">
|
||||
<i class="fa fa-plus"></i>
|
||||
Create New Organization
|
||||
</button>
|
||||
</a>
|
||||
<a href="/user/?migrate" ng-show="!user.anonymous" title="Starts the process to convert this account into an organization" bs-tooltip="tooltip.title">
|
||||
<button class="btn btn-primary">
|
||||
<i class="fa fa-caret-square-o-right"></i>
|
||||
Convert account
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Organizations -->
|
||||
<div ng-show="user.organizations.length > 0">
|
||||
<h2>Organizations</h2>
|
||||
|
||||
<div class="organization-listing" ng-repeat="organization in user.organizations">
|
||||
<img class="gravatar" src="//www.gravatar.com/avatar/{{ organization.gravatar }}?s=32&d=identicon">
|
||||
<a class="org-title" href="/organization/{{ organization.name }}">{{ organization.name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Organization Help/Tour -->
|
||||
<div class="product-tour" ng-show="!user.organizations || user.organizations.length == 0">
|
||||
|
||||
<div class="tour-section row">
|
||||
<div class="col-md-12">
|
||||
<div class="tour-section-title">Organizations</div>
|
||||
<div class="tour-section-description">
|
||||
Organizations in Quay provide unique features for businesses and other
|
||||
groups, including team-based sharing and fine-grained permission controls.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tour-section row">
|
||||
<div class="col-md-7"><img src="/static/img/org-repo-list.png" title="Repositories - Quay" data-screenshot-url="https://quay.io/repository/" class="img-responsive"></div>
|
||||
<div class="col-md-5">
|
||||
<div class="tour-section-title">A central collection of repositories</div>
|
||||
<div class="tour-section-description">
|
||||
Your organization is the focal point for all activity that occurs within
|
||||
your public or private repositories. Your repositories are centrally visible
|
||||
and managed within the namespace of your organization. You may share
|
||||
your repositories with as many users and teams as you like, without
|
||||
any additional cost.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tour-section row">
|
||||
<div class="col-md-7 col-md-push-5"><img src="/static/img/org-admin.png" title="buynlarge Admin - Quay" data-screenshot-url="https://quay.io/organization/buynlarge/admin" class="img-responsive"></div>
|
||||
<div class="col-md-5 col-md-pull-7">
|
||||
<div class="tour-section-title">Organization settings at a glance</div>
|
||||
<div class="tour-section-description">
|
||||
Your organization allows you to view your private repository count
|
||||
and manage billing settings in a centralized place.
|
||||
</div>
|
||||
<div class="tour-section-description">
|
||||
You can also see all of the users who have access to your organization
|
||||
and the teams of which they are members. This allows you to audit the
|
||||
access that has been granted in your organization.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tour-section row">
|
||||
<div class="col-md-7"><img src="/static/img/org-teams.png" title="buynlarge - Quay" data-screenshot-url="https://quay.io/organization/buynlarge" class="img-responsive"></div>
|
||||
<div class="col-md-5">
|
||||
<div class="tour-section-title">Teams simplify access controls</div>
|
||||
<div class="tour-section-description">
|
||||
Teams allow your organization to delegate access to your namespace and
|
||||
repositories in a controlled fashion. Each team has permissions that
|
||||
apply across the entire org, and can also be given specific levels of
|
||||
access to specific repositories. A user is switching roles? No problem,
|
||||
change their team membership and their access will be adjusted accordingly.
|
||||
</div>
|
||||
<div class="tour-section-description">
|
||||
Owners of your organization, and members of other teams with
|
||||
administrator privileges, have full permissions to all repositories
|
||||
in the organization, as well as permissions to view and adjust the
|
||||
account settings for the organization. Add users to these teams with
|
||||
caution.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tour-section row">
|
||||
<div class="col-md-7 col-md-push-5"><img src="/static/img/org-repo-admin.png" title="buynlarge/orgrepo - Quay" data-screenshot-url="https://quay.io/repository/buynlarge/orgrepo" class="img-responsive"></div>
|
||||
<div class="col-md-5 col-md-pull-7">
|
||||
<div class="tour-section-title">Fine-grained control of sharing</div>
|
||||
<div class="tour-section-description">
|
||||
Repositories that you create within your organization can be assigned
|
||||
fine-grained permissions just like any other repository. You can also
|
||||
add teams that exist in your organization, or individual users from
|
||||
inside our outside your organization.
|
||||
</div>
|
||||
<div class="tour-section-description">
|
||||
In order to protect your intellectual property, we warn you before
|
||||
you share your repositories with anyone who is not currently a member
|
||||
of a team in your organization.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button-bar-right button-bar-bottom">
|
||||
<a href="/organizations/new/" title="Starts the process to create a new organization" bs-tooltip="tooltip.title">
|
||||
<button class="btn btn-success">
|
||||
<i class="fa fa-plus"></i>
|
||||
Create New Organization
|
||||
</button>
|
||||
</a>
|
||||
<a href="/user/?migrate" ng-show="!user.anonymous" title="Starts the process to convert this account into an organization" bs-tooltip="tooltip.title">
|
||||
<button class="btn btn-primary">
|
||||
<i class="fa fa-caret-square-o-right"></i>
|
||||
Convert account
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -7,15 +7,39 @@
|
|||
All plans include <span class="feature">unlimited public repositories</span> and <span class="feature">unlimited sharing</span>. All paid plans have a <span class="feature">14-day free trial</span>.
|
||||
</div>
|
||||
|
||||
<div class="plans-list">
|
||||
<div class="plan" ng-repeat="plan in plans" ng-class="plan.stripeId">
|
||||
<div class="plan-title">{{ plan.title }}</div>
|
||||
<div class="plan-price">${{ plan.price/100 }}</div>
|
||||
<div class="count"><b>{{ plan.privateRepos }}</b> private repositories</div>
|
||||
<div class="description">{{ plan.audience }}</div>
|
||||
<div class="smaller">SSL secured connections</div>
|
||||
<div class="row plans-list">
|
||||
<div class="col-xs-0 col-lg-1"></div>
|
||||
<div class="col-lg-2 col-xs-4 plan-container" ng-repeat="plan in plans.user">
|
||||
<div class="plan" ng-class="plan.stripeId">
|
||||
<div class="plan-title">{{ plan.title }}</div>
|
||||
<div class="plan-price">${{ plan.price/100 }}</div>
|
||||
<div class="count"><b>{{ plan.privateRepos }}</b> private repositories</div>
|
||||
<div class="description">{{ plan.audience }}</div>
|
||||
<div class="smaller">SSL secured connections</div>
|
||||
<button class="btn btn-primary btn-block" ng-click="buyNow(plan.stripeId)">Sign Up Now</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-block" ng-click="buyNow(plan.stripeId)">Sign Up Now</button>
|
||||
<div class="callout">
|
||||
Business Plan Pricing
|
||||
</div>
|
||||
|
||||
<div class="all-plans">
|
||||
All business plans include all of the personal plan features, plus: <span class="business-feature">organizations</span> and <span class="business-feature">teams</span> with <span class="business-feature">delegated access</span> to the organization. All business plans have a <span class="business-feature">14-day free trial</span>.
|
||||
</div>
|
||||
|
||||
<div class="row plans-list">
|
||||
<div class="col-xs-0 col-lg-1"></div>
|
||||
<div class="col-lg-2 col-xs-4 plan-container" ng-repeat="plan in plans.business">
|
||||
<div class="plan business-plan" ng-class="plan.stripeId">
|
||||
<div class="plan-title">{{ plan.title }}</div>
|
||||
<div class="plan-price">${{ plan.price/100 }}</div>
|
||||
<div class="count"><b>{{ plan.privateRepos }}</b> private repositories</div>
|
||||
<div class="description">{{ plan.audience }}</div>
|
||||
<div class="smaller">SSL secured connections</div>
|
||||
<button class="btn btn-success btn-block" ng-click="createOrg(plan.stripeId)">Sign Up Now</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -20,44 +20,61 @@
|
|||
|
||||
<!-- User Access Permissions -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">User Access Permissions
|
||||
<div class="panel-heading">User <span ng-show="repo.is_organization">and Team</span> Access Permissions
|
||||
|
||||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="Allow any number of users to read, write or administer this repository"></i>
|
||||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="Allow any number of users or teams to read, write or administer this repository"></i>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<table class="permissions">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>User</td>
|
||||
<td>User<span ng-show="repo.is_organization">/Team</span></td>
|
||||
<td>Permissions</td>
|
||||
<td></td>
|
||||
<td style="width: 95px;"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr ng-repeat="(username, permission) in permissions">
|
||||
<td class="user">
|
||||
<!-- Team Permissions -->
|
||||
<tr ng-repeat="(name, permission) in permissions['team']">
|
||||
<td class="team entity">
|
||||
<i class="fa fa-group"></i>
|
||||
<span><a href="/organization/{{ repo.namespace }}/teams/{{ name }}">{{name}}</a></span>
|
||||
</td>
|
||||
<td class="user-permissions">
|
||||
<span class="role-group" current-role="permission.role" role-changed="setRole(role, name, 'team')" roles="roles"></span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-ui" tabindex="0">
|
||||
<span class="delete-ui-button" ng-click="deleteRole(name, 'team')"><button class="btn btn-danger">Delete</button></span>
|
||||
<i class="fa fa-times" bs-tooltip="tooltip.title" data-placement="right" title="Delete Permission"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- User Permissions -->
|
||||
<tr ng-repeat="(name, permission) in permissions['user']">
|
||||
<td class="{{ 'user entity ' + (permission.is_org_member? '' : 'outside') }}">
|
||||
<i class="fa fa-user"></i>
|
||||
<span>{{username}}</span>
|
||||
<span>{{name}}</span>
|
||||
<i class="fa fa-exclamation-triangle" ng-show="permission.is_org_member === false" data-trigger="hover" bs-popover="{'content': 'This user is not a member of the organization'}"></i>
|
||||
</td>
|
||||
<td class="user-permissions">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-default" ng-click="setRole(username, 'read')" ng-class="{read: 'active', write: '', admin: ''}[permission.role]">Read only</button>
|
||||
<button type="button" class="btn btn-default" ng-click="setRole(username, 'write')" ng-class="{read: '', write: 'active', admin: ''}[permission.role]">Write</button>
|
||||
<button type="button" class="btn btn-default" ng-click="setRole(username, 'admin')" ng-class="{read: '', write: '', admin: 'active'}[permission.role]">Admin</button>
|
||||
<span class="role-group" current-role="permission.role" role-changed="setRole(role, name, 'user')" roles="roles"></span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-ui" tabindex="0" title="Delete Permission">
|
||||
<span class="delete-ui-button" ng-click="deleteRole(username)"><button class="btn btn-danger">Delete</button></span>
|
||||
<i class="fa fa-times"></i>
|
||||
<span class="delete-ui-button" ng-click="deleteRole(name, 'user')"><button class="btn btn-danger">Delete</button></span>
|
||||
<i class="fa fa-times" bs-tooltip="tooltip.title" data-placement="right" title="Delete Permission"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<input id="userSearch" class="form-control" placeholder="Add new user...">
|
||||
<span class="entity-search" organization="repo.namespace" input-title="'Add a ' + (repo.is_organization ? 'team or ' : '') + 'user...'" entity-selected="addNewPermission"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -93,9 +110,9 @@
|
|||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-ui" tabindex="0" title="Delete Token">
|
||||
<span class="delete-ui" tabindex="0">
|
||||
<span class="delete-ui-button" ng-click="deleteToken(token.code)"><button class="btn btn-danger" type="button">Delete</button></span>
|
||||
<i class="fa fa-times"></i>
|
||||
<i class="fa fa-times" bs-tooltip="tooltip.title" data-placement="right" title="Delete Token"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -246,7 +263,7 @@
|
|||
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="onlyadminModal">
|
||||
<div class="modal fade" id="channgechangepermModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
@ -254,7 +271,8 @@
|
|||
<h4 class="modal-title">Cannot change permissions</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
The selected permissions could not be changed because the user is the only <b>admin</b> on the repo.
|
||||
<span ng-show="!changePermError">You do not have permission to change the permissions on the repository.</span>
|
||||
<span ng-show="changePermError">{{ changePermError }}</span>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
|
@ -283,4 +301,24 @@
|
|||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="confirmaddoutsideModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Add User?</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
The selected user is outside of your organization. Are you sure you want to grant the user access to this repository?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" ng-click="grantRole()">Yes, I'm sure</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
</div>
|
||||
|
|
|
@ -4,25 +4,41 @@
|
|||
|
||||
<div class="container ready-indicator" ng-show="!loading" data-status="{{ loading ? '' : 'ready' }}">
|
||||
<div class="repo-list" ng-show="!user.anonymous">
|
||||
<a href="/new/">
|
||||
<button class="btn btn-success" style="float: right">
|
||||
<i class="fa fa-upload user-tool" title="Create new repository"></i>
|
||||
Create Repository
|
||||
</button>
|
||||
</a>
|
||||
<div ng-class="user.organizations.length ? 'section-header' : ''">
|
||||
<div class="button-bar-right">
|
||||
<a href="/new/">
|
||||
<button class="btn btn-success">
|
||||
<i class="fa fa-upload user-tool" title="Create new repository"></i>
|
||||
Create Repository
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<a href="/organization/{{ namespace }}" ng-show="namespace != user.username">
|
||||
<button class="btn btn-default">
|
||||
<i class="fa fa-group user-tool"></i>
|
||||
View Organization
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<span class="namespace-selector" user="user" namespace="namespace" ng-show="user.organizations"></span>
|
||||
</div>
|
||||
|
||||
<h3>Your Repositories</h3>
|
||||
<div ng-show="private_repositories.length > 0">
|
||||
<div class="repo-listing" ng-repeat="repository in private_repositories">
|
||||
<h3 ng-show="namespace == user.username">Your Repositories</h3>
|
||||
<h3 ng-show="namespace != user.username">Repositories</h3>
|
||||
|
||||
<div ng-show="user_repositories.length > 0">
|
||||
<div class="repo-listing" ng-repeat="repository in user_repositories">
|
||||
<span class="repo-circle no-background" repo="repository"></span>
|
||||
<a ng-href="/repository/{{repository.namespace}}/{{ repository.name }}">{{repository.namespace}}/{{repository.name}}</a>
|
||||
<div class="description" ng-bind-html-unsafe="getCommentFirstLine(repository.description)"></div>
|
||||
<div class="description markdown-view" content="repository.description" first-line-only="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="private_repositories.length == 0" style="padding:20px;">
|
||||
<div ng-show="user_repositories.length == 0" style="padding:20px;">
|
||||
<div class="alert alert-info">
|
||||
<h4>You don't have any repositories yet!</h4>
|
||||
<h4 ng-show="namespace == user.username">You don't have any repositories yet!</h4>
|
||||
<h4 ng-show="namespace != user.username">This organization doesn't have any repositories, or you have not been provided access.</h4>
|
||||
<a href="/guide"><b>Click here</b> to learn how to create a repository</a>
|
||||
</div>
|
||||
|
||||
|
@ -34,7 +50,7 @@
|
|||
<div class="repo-listing" ng-repeat="repository in public_repositories">
|
||||
<span class="repo-circle no-background" repo="repository"></span>
|
||||
<a ng-href="/repository/{{repository.namespace}}/{{ repository.name }}">{{repository.namespace}}/{{repository.name}}</a>
|
||||
<div class="description" ng-bind-html-unsafe="getCommentFirstLine(repository.description)"></div>
|
||||
<div class="description markdown-view" content="repository.description" first-line-only="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,22 +12,7 @@
|
|||
</div>
|
||||
<div id="collapseSignin" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<form class="form-signin" ng-submit="signin();">
|
||||
<input type="text" class="form-control input-lg" name="username" placeholder="Username" ng-model="user.username" autofocus>
|
||||
<input type="password" class="form-control input-lg" name="password" placeholder="Password" ng-model="user.password">
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign In</button>
|
||||
|
||||
<span class="social-alternate">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span class="inner-text">OR</span>
|
||||
</span>
|
||||
|
||||
<a id='github-signin-link' href="https://github.com/login/oauth/authorize?client_id={{ githubClientId }}&scope=user:email{{ mixpanelDistinctIdClause }}" class="btn btn-primary btn-lg btn-block"><i class="fa fa-github fa-lg"></i> Sign In with GitHub</a>
|
||||
</form>
|
||||
|
||||
<div class="alert alert-danger" ng-show="invalidCredentials">Invalid username or password.</div>
|
||||
|
||||
<div class="alert alert-danger" ng-show="needsEmailVerification">You must verify your email address before you can sign in.</div>
|
||||
<div class="signin-form"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -56,17 +41,3 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <script type="text/javascript">
|
||||
function appendMixpanelId() {
|
||||
if (mixpanel.get_distinct_id !== undefined) {
|
||||
var signinLink = document.getElementById("github-signin-link");
|
||||
signinLink.href += ("&state=" + mixpanel.get_distinct_id());
|
||||
} else {
|
||||
// Mixpanel not yet loaded, try again later
|
||||
window.setTimeout(appendMixpanelId, 200);
|
||||
}
|
||||
};
|
||||
|
||||
appendMixpanelId();
|
||||
</script> -->
|
||||
|
|
79
static/partials/team-view.html
Normal file
79
static/partials/team-view.html
Normal file
|
@ -0,0 +1,79 @@
|
|||
<div class="loading" ng-show="loading">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="loading" ng-show="!loading && !organization">
|
||||
No matching team found
|
||||
</div>
|
||||
|
||||
<div class="team-view container" ng-show="!loading && organization">
|
||||
<div class="organization-header" organization="organization" team-name="teamname"></div>
|
||||
|
||||
<div class="description markdown-input" content="team.description" can-write="organization.is_admin"
|
||||
content-changed="updateForDescription" field-title="'team description'"></div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Team Members
|
||||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="Users that inherit all permissions delegated to this team"></i>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="permissions">
|
||||
<tr ng-repeat="(name, member) in members">
|
||||
<td class="user entity">
|
||||
<i class="fa fa-user"></i>
|
||||
<span>{{ member.username }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-ui" tabindex="0" title="Remove User" ng-show="canEditMembers">
|
||||
<span class="delete-ui-button" ng-click="removeMember(member.username)"><button class="btn btn-danger">Remove</button></span>
|
||||
<i class="fa fa-times"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-show="canEditMembers">
|
||||
<td colspan="2">
|
||||
<span class="entity-search" organization="''" input-title="'Add a user...'" entity-selected="addNewMember"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="cannotChangeTeamModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Cannot change team</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
You do not have permission to change properties of this team.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="cannotChangeMembersModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Cannot change members</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
You do not have permission to change the members of this team.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
|
@ -1,80 +1,181 @@
|
|||
<div class="container user-admin">
|
||||
<div class="loading" ng-show="planLoading || planChanging">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
<div class="row" ng-show="errorMessage">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-danger">{{ errorMessage }}</div>
|
||||
<div class="loading" ng-show="loading">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="loading" ng-show="!loading && !user">
|
||||
No matching user found
|
||||
</div>
|
||||
|
||||
<div class="user-admin container" ng-show="!loading && user">
|
||||
<div class="row">
|
||||
<div class="organization-header-element">
|
||||
<img src="//www.gravatar.com/avatar/{{ user.gravatar }}?s=24&d=identicon">
|
||||
<span class="organization-name">
|
||||
{{ user.username }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-show="askForPassword">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-warning">Your account does not currently have a password. You will need to create a password before you will be able to <strong>push</strong> or <strong>pull</strong> repositories.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" ng-hide="planLoading">
|
||||
<div class="col-md-3" ng-repeat='plan in plans'>
|
||||
<div class="panel" ng-class="{'panel-success': subscription.plan == plan.stripeId, 'panel-default': subscription.plan != plan.stripeId}">
|
||||
<div class="panel-heading">
|
||||
{{ plan.title }}
|
||||
<span class="pull-right" ng-show="subscription.plan == plan.stripeId">
|
||||
<i class="fa fa-ok"></i>
|
||||
Subscribed
|
||||
</span>
|
||||
</div>
|
||||
<div class="panel-body panel-plan">
|
||||
<div class="plan-price">${{ plan.price / 100 }}</div>
|
||||
<div class="plan-description"><b>{{ plan.privateRepos }}</b> Private Repositories</div>
|
||||
<div ng-switch='plan.stripeId'>
|
||||
<div ng-switch-when='free'>
|
||||
<button class="btn button-hidden">Hidden!</button>
|
||||
</div>
|
||||
<div ng-switch-default>
|
||||
<button class="btn btn-primary" ng-show="subscription.plan === 'free'" ng-click="subscribe(plan.stripeId)">Subscribe</button>
|
||||
<button class="btn btn-default" ng-hide="subscription.plan === 'free' || subscription.plan === plan.stripeId" ng-click="changeSubscription(plan.stripeId)">Change</button>
|
||||
<button class="btn btn-danger" ng-show="subscription.plan === plan.stripeId" ng-click="cancelSubscription()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" ng-show="subscription">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Plan Usage
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="used-description">
|
||||
<b>{{ subscription.usedPrivateRepos }}</b> of <b>{{ subscribedPlan.privateRepos }}</b> private repositories used
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div ng-class="'progress-bar ' + (planUsagePercent > 90 ? 'progress-bar-danger' : '')" role="progressbar" aria-valuenow="{{ subscription.usedPrivateRepos }}" aria-valuemin="0" aria-valuemax="{{ subscribedPlan.privateRepos }}" style="width: {{ planUsagePercent }}%;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="loading" ng-show="updatingUser">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
<!-- Side tabs -->
|
||||
<div class="col-md-2">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li class="active"><a href="javascript:void(0)" data-toggle="tab" data-target="#plan">Plan and Usage</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#password">Set Password</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#migrate" id="migrateTab">Convert to Organization</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Change Password
|
||||
|
||||
<!-- Content -->
|
||||
<div class="col-md-10">
|
||||
<div class="tab-content">
|
||||
<!-- Plans tab -->
|
||||
<div id="plan" class="tab-pane active">
|
||||
<div class="plan-manager" user="user.username" ready-for-plan="readyForPlan()"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-change-pw" name="changePasswordForm" ng-submit="changePassword()" data-trigger="manual" data-content="{{ changePasswordError }}" data-placement="right" ng-show="!awaitingConfirmation && !registering">
|
||||
<input type="password" class="form-control" placeholder="Your new password" ng-model="user.password" required>
|
||||
<input type="password" class="form-control" placeholder="Verify your new password" ng-model="user.repeatPassword" match="user.password" required>
|
||||
<button class="btn btn-danger" ng-disabled="changePasswordForm.$invalid" type="submit" analytics-on analytics-event="register">Change Password</button>
|
||||
<span class="help-block" ng-show="changePasswordSuccess">Password changed successfully</span>
|
||||
</form>
|
||||
|
||||
<!-- Change password tab -->
|
||||
<div id="password" class="tab-pane">
|
||||
<div class="loading" ng-show="updatingUser">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
<div class="row">
|
||||
<form class="form-change-pw col-md-6" name="changePasswordForm" ng-submit="changePassword()" data-trigger="manual"
|
||||
data-content="{{ changePasswordError }}" data-placement="right" ng-show="!awaitingConfirmation && !registering">
|
||||
<input type="password" class="form-control" placeholder="Your new password" ng-model="user.password" required>
|
||||
<input type="password" class="form-control" placeholder="Verify your new password" ng-model="user.repeatPassword"
|
||||
match="user.password" required>
|
||||
<button class="btn btn-danger" ng-disabled="changePasswordForm.$invalid" type="submit"
|
||||
analytics-on analytics-event="register">Change Password</button>
|
||||
<span class="help-block" ng-show="changePasswordSuccess">Password changed successfully</span>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Convert to organization tab -->
|
||||
<div id="migrate" class="tab-pane">
|
||||
<!-- Step 0 -->
|
||||
<div class="panel" ng-show="convertStep == 0">
|
||||
<div class="panel-body" ng-show="user.organizations.length > 0">
|
||||
<div class="alert alert-info">
|
||||
Cannot convert this account into an organization, as it is a member of {{user.organizations.length}} other
|
||||
organization{{user.organizations.length > 1 ? 's' : ''}}. Please leave
|
||||
{{user.organizations.length > 1 ? 'those organizations' : 'that organization'}} first.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-body" ng-show="user.organizations.length == 0">
|
||||
<div class="alert alert-danger">
|
||||
Converting a user account into an organization <b>cannot be undone</b>.<br> Here be many fire-breathing dragons!
|
||||
</div>
|
||||
|
||||
<button class="btn btn-danger" ng-click="showConvertForm()">Start conversion process</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 1 -->
|
||||
<div class="convert-form" ng-show="convertStep == 1">
|
||||
<h3>Convert to organization</h3>
|
||||
|
||||
<form method="post" name="convertForm" id="convertForm" ng-submit="convertToOrg()">
|
||||
<div class="form-group">
|
||||
<label for="orgName">Organization Name</label>
|
||||
<div class="existing-data">
|
||||
<img src="//www.gravatar.com/avatar/{{ user.gravatar }}?s=24&d=identicon">
|
||||
{{ user.username }}</div>
|
||||
<span class="description">This will continue to be the namespace for your repositories</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="orgName">Admin User</label>
|
||||
<input id="adminUsername" name="adminUsername" type="text" class="form-control" placeholder="Admin Username"
|
||||
ng-model="org.adminUser" required autofocus>
|
||||
<input id="adminPassword" name="adminPassword" type="password" class="form-control" placeholder="Admin Password"
|
||||
ng-model="org.adminPassword" required>
|
||||
<span class="description">The username and password for an <b>existing account</b> that will become administrator of the organization</span>
|
||||
</div>
|
||||
|
||||
<!-- Plans Table -->
|
||||
<div class="form-group plan-group">
|
||||
<label>Organization Plan</label>
|
||||
<div class="plans-table" plans="orgPlans" current-plan="org.plan"></div>
|
||||
</div>
|
||||
|
||||
<div class="button-bar">
|
||||
<button class="btn btn-large btn-danger" type="submit" ng-disabled="convertForm.$invalid || !org.plan">
|
||||
Convert To Organization
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="cannotconvertModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Cannot convert account</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Your account could not be converted. Please try again in a moment.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="invalidadminModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Username or password invalid</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
The username or password specified for the admin account is not valid.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="reallyconvertModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Convert to organization?</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-danger">You will not be able to login to this account once converted</div>
|
||||
<div>Are you <b>absolutely sure</b> you would like to convert this account to an organization? Once done, there is no going back.</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" ng-click="reallyConvert()">Absolutely: Convert Now</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<span style="color: #aaa;"> {{repo.namespace}}</span> <span style="color: #ccc">/</span> {{repo.name}}
|
||||
|
||||
<span class="settings-cog" ng-show="repo.can_admin" title="Repository Settings">
|
||||
<span class="settings-cog" ng-show="repo.can_admin" title="Repository Settings" bs-tooltip="tooltip.title" data-placement="bottom">
|
||||
<a href="{{ '/repository/' + repo.namespace + '/' + repo.name + '/admin' }}">
|
||||
<i class="fa fa-cog fa-lg"></i>
|
||||
</a>
|
||||
|
@ -52,12 +52,8 @@
|
|||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div class="description">
|
||||
<p ng-class="'lead ' + (repo.can_write ? 'editable' : 'noteditable')" ng-click="editDescription()">
|
||||
<span class="content" ng-bind-html-unsafe="getMarkedDown(repo.description)"></span>
|
||||
<i class="fa fa-edit"></i>
|
||||
</p>
|
||||
</div>
|
||||
<div class="description markdown-input" content="repo.description" can-write="repo.can_write"
|
||||
content-changed="updateForDescription" field-title="'repository description'"></div>
|
||||
|
||||
<!-- Empty message -->
|
||||
<div class="repo-content" ng-show="!currentTag.image && !repo.is_building">
|
||||
|
@ -79,7 +75,7 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<!-- Tag dropdown -->
|
||||
<div class="tag-dropdown dropdown" title="Tags">
|
||||
<div class="tag-dropdown dropdown" title="Tags" bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-tag"><span class="tag-count">{{getTagCount(repo)}}</span></i>
|
||||
<a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">{{currentTag.name}} <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
@ -107,7 +103,7 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<!-- Image dropdown -->
|
||||
<div class="tag-dropdown dropdown" title="Images">
|
||||
<div class="tag-dropdown dropdown" title="Images" bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-archive"><span class="tag-count">{{imageHistory.length}}</span></i>
|
||||
<a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">{{currentImage.id.substr(0, 12)}} <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
@ -122,7 +118,8 @@
|
|||
<div class="panel-body">
|
||||
<div id="current-image">
|
||||
<div ng-show="currentImage.comment">
|
||||
<blockquote style="margin-top: 10px;" ng-bind-html-unsafe="getMarkedDown(currentImage.comment)">
|
||||
<blockquote style="margin-top: 10px;">
|
||||
<span class="markdown-view" content="currentImage.comment"></span>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
|
@ -141,15 +138,18 @@
|
|||
<div class="changes-container small-changes-container"
|
||||
ng-show="currentImageChanges.changed.length || currentImageChanges.added.length || currentImageChanges.removed.length">
|
||||
<div class="changes-count-container accordion-toggle" data-toggle="collapse" data-parent="#accordion" data-target="#collapseChanges">
|
||||
<span class="change-count added" ng-show="currentImageChanges.added.length > 0" title="Files Added">
|
||||
<span class="change-count added" ng-show="currentImageChanges.added.length > 0" title="Files Added"
|
||||
bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-plus-square"></i>
|
||||
<b>{{currentImageChanges.added.length}}</b>
|
||||
</span>
|
||||
<span class="change-count removed" ng-show="currentImageChanges.removed.length > 0" title="Files Removed">
|
||||
<span class="change-count removed" ng-show="currentImageChanges.removed.length > 0" title="Files Removed"
|
||||
bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-minus-square"></i>
|
||||
<b>{{currentImageChanges.removed.length}}</b>
|
||||
</span>
|
||||
<span class="change-count changed" ng-show="currentImageChanges.changed.length > 0" title="Files Changed">
|
||||
<span class="change-count changed" ng-show="currentImageChanges.changed.length > 0" title="Files Changed"
|
||||
bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-pencil-square"></i>
|
||||
<b>{{currentImageChanges.changed.length}}</b>
|
||||
</span>
|
||||
|
@ -182,29 +182,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal edit for the description -->
|
||||
<div class="modal fade" id="editModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Edit Repository Description</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="wmd-panel">
|
||||
<div id="wmd-button-bar-description"></div>
|
||||
<textarea class="wmd-input" id="wmd-input-description" placeholder="Enter description">{{ repo.description }}</textarea>
|
||||
</div>
|
||||
|
||||
<div id="wmd-preview-description" class="wmd-panel wmd-preview"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary" ng-click="saveDescription()">Save changes</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
</div>
|
||||
|
|
Reference in a new issue