1
0
mirror of https://github.com/bitwarden/web synced 2026-01-08 03:23:29 +00:00

Update 2017-05-03T14:30:05.647Z

This commit is contained in:
Kyle Spearrin
2017-05-03 10:30:11 -04:00
parent 2d7f83905b
commit db7ff13f2e
52 changed files with 5931 additions and 1296 deletions

View File

@@ -0,0 +1,161 @@
<section class="content-header">
<h1>
Billing
<small>manage your payments</small>
</h1>
</section>
<section class="content">
<div class="callout callout-warning" ng-if="subscription && subscription.cancelled">
<h4><i class="fa fa-warning"></i> Cancelled</h4>
The subscription to this organization has been canceled.
</div>
<div class="callout callout-warning" ng-if="subscription && subscription.markedForCancel">
<h4><i class="fa fa-warning"></i> Pending Cancellation</h4>
<p>
The subscription to this organization has been marked for cancellation at the end of the
current billing period.
</p>
<button type="button" class="btn btn-default btn-flat" ng-click="reinstate()">
Reinstate Plan
</button>
</div>
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Plan</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-sm-6">
<dl>
<dt>Name</dt>
<dd>{{plan.name || '-'}}</dd>
<dt>Total Seats</dt>
<dd>{{plan.seats || '-'}}</dd>
</dl>
</div>
<div class="col-sm-6">
<dl>
<dt>Status</dt>
<dd style="text-transform: capitalize;">{{(subscription && subscription.status) || '-'}}</dd>
<dt>Next Charge</dt>
<dd>{{nextInvoice ? ((nextInvoice.date | date: format: mediumDate) + ', ' + (nextInvoice.amount | currency:'$')) : '-'}}</dd>
</dl>
</div>
</div>
<div class="row" ng-if="!noSubscription">
<div class="col-md-6">
<strong>Details</strong>
<div ng-show="loading">
Loading...
</div>
<div class="table-responsive" style="margin: 0;" ng-show="!loading">
<table class="table" style="margin: 0;">
<tbody>
<tr ng-repeat="item in subscription.items">
<td>
{{item.name}} {{item.qty > 1 ? '&times;' + item.qty : ''}}
@ {{item.amount | currency:'$'}} /{{item.interval}}
</td>
<td class="text-right">{{(item.qty * item.amount) | currency:'$'}} /{{item.interval}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="box-footer">
<button type="button" class="btn btn-default btn-flat" ng-click="changePlan()">
Change Plan
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="cancel()"
ng-if="!noSubscription && !subscription.cancelled && !subscription.markedForCancel">
Cancel Plan
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="reinstate()"
ng-if="!noSubscription && subscription.markedForCancel">
Reinstate Plan
</button>
</div>
</div>
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">User Seats</h3>
</div>
<div class="box-body">
<div ng-show="loading">
Loading...
</div>
<div ng-show="!loading">
You plan currently has a total of <b>{{plan.seats}}</b> seats.
</div>
</div>
<div class="box-footer" ng-if="!noSubscription">
<button type="button" class="btn btn-default btn-flat" ng-click="adjustSeats(true)">
Add Seats
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="adjustSeats(false)">
Remove Seats
</button>
</div>
</div>
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Payment Method</h3>
</div>
<div class="box-body">
<div ng-show="loading">
Loading...
</div>
<div ng-show="!loading && !paymentSource">
<i class="fa fa-credit-card"></i> No payment method on file.
</div>
<div ng-show="!loading && paymentSource">
<i class="fa" ng-class="{'fa-credit-card': paymentSource.type === 0,
'fa-university': paymentSource.type === 1}"></i>
{{paymentSource.description}}
</div>
</div>
<div class="box-footer">
<button type="button" class="btn btn-default btn-flat" ng-click="changePayment()">
{{ paymentSource ? 'Change Payment Method' : 'Add Payment Method' }}
</button>
</div>
</div>
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Charges</h3>
</div>
<div class="box-body">
<div ng-show="loading">
Loading...
</div>
<div ng-show="!loading && !charges.length">
No charges.
</div>
<div class="table-responsive" ng-show="charges.length">
<table class="table">
<tbody>
<tr ng-repeat="charge in charges">
<td style="width: 200px">
{{charge.date | date: format: mediumDate}}
</td>
<td>
{{charge.paymentSource}}
</td>
<td style="width: 150px; text-transform: capitalize;">
{{charge.status}}
</td>
<td class="text-right" style="width: 150px;">
{{charge.amount | currency:'$'}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="box-footer">
Note: Any charges will appears on your credit card statement as <b>BITWARDEN</b>.
</div>
</div>
</section>

View File

@@ -0,0 +1,46 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">
<i class="fa fa-users"></i>
{{add ? 'Add Seats' : 'Remove Seats'}}
</h4>
</div>
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
<div class="modal-body">
<div class="callout callout-default" ng-show="add">
<h4><i class="fa fa-dollar"></i> Note About Charges</h4>
<p>
Adding seats to your plan will result in adjustments to your billing totals and immediately charge your
payment method on file. The first charge will be prorated for the remainder of the current billing cycle.
</p>
</div>
<div class="callout callout-default" ng-show="!add">
<h4><i class="fa fa-dollar"></i> Note About Charges</h4>
<p>
Removing seats will result in adjustments to your billing totals that will be prorated as credits
to your next billing charge.
</p>
</div>
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in form.$errors">{{e}}</li>
</ul>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="seats">{{add ? 'Seats To Add' : 'Seats To Remove'}}</label>
<input type="number" id="seats" name="SeatAdjustment" ng-model="seatAdjustment" class="form-control"
required min="0" />
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Submit
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,364 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">
<i class="fa fa-credit-card"></i>
{{existingPaymentMethod ? 'Change Payment Method' : 'Add Payment Method'}}
</h4>
</div>
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
<div class="modal-body">
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in form.$errors">{{e}}</li>
</ul>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group" show-errors>
<label for="card_number">Card Number</label>
<input type="text" id="card_number" name="card_number" ng-model="card.number"
class="form-control" cc-number required api-field />
</div>
</div>
</div>
<ul class="list-inline">
<li><div class="cc visa"></div></li>
<li><div class="cc mastercard"></div></li>
<li><div class="cc amex"></div></li>
<li><div class="cc discover"></div></li>
<li><div class="cc diners"></div></li>
<li><div class="cc jcb"></div></li>
</ul>
<div class="row">
<div class="col-sm-4">
<div class="form-group" show-errors>
<label for="exp_month">Expiration Month</label>
<select id="exp_month" class="form-control" ng-model="card.exp_month" required cc-exp-month
name="exp_month" api-field>
<option value="">-- Select --</option>
<option value="01">01 - January</option>
<option value="02">02 - February</option>
<option value="03">03 - March</option>
<option value="04">04 - April</option>
<option value="05">05 - May</option>
<option value="06">06 - June</option>
<option value="07">07 - July</option>
<option value="08">08 - August</option>
<option value="09">09 - September</option>
<option value="10">10 - October</option>
<option value="11">11 - November</option>
<option value="12">12 - December</option>
</select>
</div>
</div>
<div class="col-sm-4">
<div class="form-group" show-errors>
<label for="exp_year">Expiration Year</label>
<select id="exp_year" class="form-control" ng-model="card.exp_year" required cc-exp-year
name="exp_year" api-field>
<option value="">-- Select --</option>
<option value="17">2017</option>
<option value="18">2018</option>
<option value="19">2019</option>
<option value="20">2020</option>
<option value="21">2021</option>
<option value="22">2022</option>
<option value="23">2023</option>
<option value="24">2024</option>
<option value="25">2025</option>
<option value="26">2026</option>
</select>
</div>
</div>
<div class="col-sm-4">
<div class="form-group" show-errors>
<label for="cvc">
CVC
<a href="https://www.cvvnumber.com/cvv.html" target="_blank" title="What is this?"
rel="noopener noreferrer">
<i class="fa fa-question-circle"></i>
</a>
</label>
<input type="text" id="cvc" ng-model="card.cvc" class="form-control" name="cvc"
cc-type="number.$ccType" cc-cvc required api-field />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group" show-errors>
<label for="address_country">Country</label>
<select id="address_country" class="form-control" ng-model="card.address_country"
required name="address_country" api-field>
<option value="">-- Select --</option>
<option value="US">United States</option>
<option value="CN">China</option>
<option value="FR">France</option>
<option value="DE">Germany</option>
<option value="CA">Canada</option>
<option value="GB">United Kingdom</option>
<option value="AU">Australia</option>
<option value="IN">India</option>
<option value="-" disabled></option>
<option value="AF">Afghanistan</option>
<option value="AX">Åland Islands</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
<option value="AS">American Samoa</option>
<option value="AD">Andorra</option>
<option value="AO">Angola</option>
<option value="AI">Anguilla</option>
<option value="AQ">Antarctica</option>
<option value="AG">Antigua and Barbuda</option>
<option value="AR">Argentina</option>
<option value="AM">Armenia</option>
<option value="AW">Aruba</option>
<option value="AT">Austria</option>
<option value="AZ">Azerbaijan</option>
<option value="BS">Bahamas</option>
<option value="BH">Bahrain</option>
<option value="BD">Bangladesh</option>
<option value="BB">Barbados</option>
<option value="BY">Belarus</option>
<option value="BE">Belgium</option>
<option value="BZ">Belize</option>
<option value="BJ">Benin</option>
<option value="BM">Bermuda</option>
<option value="BT">Bhutan</option>
<option value="BO">Bolivia, Plurinational State of</option>
<option value="BQ">Bonaire, Sint Eustatius and Saba</option>
<option value="BA">Bosnia and Herzegovina</option>
<option value="BW">Botswana</option>
<option value="BV">Bouvet Island</option>
<option value="BR">Brazil</option>
<option value="IO">British Indian Ocean Territory</option>
<option value="BN">Brunei Darussalam</option>
<option value="BG">Bulgaria</option>
<option value="BF">Burkina Faso</option>
<option value="BI">Burundi</option>
<option value="KH">Cambodia</option>
<option value="CM">Cameroon</option>
<option value="CV">Cape Verde</option>
<option value="KY">Cayman Islands</option>
<option value="CF">Central African Republic</option>
<option value="TD">Chad</option>
<option value="CL">Chile</option>
<option value="CX">Christmas Island</option>
<option value="CC">Cocos (Keeling) Islands</option>
<option value="CO">Colombia</option>
<option value="KM">Comoros</option>
<option value="CG">Congo</option>
<option value="CD">Congo, the Democratic Republic of the</option>
<option value="CK">Cook Islands</option>
<option value="CR">Costa Rica</option>
<option value="CI">Côte d'Ivoire</option>
<option value="HR">Croatia</option>
<option value="CU">Cuba</option>
<option value="CW">Curaçao</option>
<option value="CY">Cyprus</option>
<option value="CZ">Czech Republic</option>
<option value="DK">Denmark</option>
<option value="DJ">Djibouti</option>
<option value="DM">Dominica</option>
<option value="DO">Dominican Republic</option>
<option value="EC">Ecuador</option>
<option value="EG">Egypt</option>
<option value="SV">El Salvador</option>
<option value="GQ">Equatorial Guinea</option>
<option value="ER">Eritrea</option>
<option value="EE">Estonia</option>
<option value="ET">Ethiopia</option>
<option value="FK">Falkland Islands (Malvinas)</option>
<option value="FO">Faroe Islands</option>
<option value="FJ">Fiji</option>
<option value="FI">Finland</option>
<option value="GF">French Guiana</option>
<option value="PF">French Polynesia</option>
<option value="TF">French Southern Territories</option>
<option value="GA">Gabon</option>
<option value="GM">Gambia</option>
<option value="GE">Georgia</option>
<option value="GH">Ghana</option>
<option value="GI">Gibraltar</option>
<option value="GR">Greece</option>
<option value="GL">Greenland</option>
<option value="GD">Grenada</option>
<option value="GP">Guadeloupe</option>
<option value="GU">Guam</option>
<option value="GT">Guatemala</option>
<option value="GG">Guernsey</option>
<option value="GN">Guinea</option>
<option value="GW">Guinea-Bissau</option>
<option value="GY">Guyana</option>
<option value="HT">Haiti</option>
<option value="HM">Heard Island and McDonald Islands</option>
<option value="VA">Holy See (Vatican City State)</option>
<option value="HN">Honduras</option>
<option value="HK">Hong Kong</option>
<option value="HU">Hungary</option>
<option value="IS">Iceland</option>
<option value="ID">Indonesia</option>
<option value="IR">Iran, Islamic Republic of</option>
<option value="IQ">Iraq</option>
<option value="IE">Ireland</option>
<option value="IM">Isle of Man</option>
<option value="IL">Israel</option>
<option value="IT">Italy</option>
<option value="JM">Jamaica</option>
<option value="JP">Japan</option>
<option value="JE">Jersey</option>
<option value="JO">Jordan</option>
<option value="KZ">Kazakhstan</option>
<option value="KE">Kenya</option>
<option value="KI">Kiribati</option>
<option value="KP">Korea, Democratic People's Republic of</option>
<option value="KR">Korea, Republic of</option>
<option value="KW">Kuwait</option>
<option value="KG">Kyrgyzstan</option>
<option value="LA">Lao People's Democratic Republic</option>
<option value="LV">Latvia</option>
<option value="LB">Lebanon</option>
<option value="LS">Lesotho</option>
<option value="LR">Liberia</option>
<option value="LY">Libya</option>
<option value="LI">Liechtenstein</option>
<option value="LT">Lithuania</option>
<option value="LU">Luxembourg</option>
<option value="MO">Macao</option>
<option value="MK">Macedonia, the former Yugoslav Republic of</option>
<option value="MG">Madagascar</option>
<option value="MW">Malawi</option>
<option value="MY">Malaysia</option>
<option value="MV">Maldives</option>
<option value="ML">Mali</option>
<option value="MT">Malta</option>
<option value="MH">Marshall Islands</option>
<option value="MQ">Martinique</option>
<option value="MR">Mauritania</option>
<option value="MU">Mauritius</option>
<option value="YT">Mayotte</option>
<option value="MX">Mexico</option>
<option value="FM">Micronesia, Federated States of</option>
<option value="MD">Moldova, Republic of</option>
<option value="MC">Monaco</option>
<option value="MN">Mongolia</option>
<option value="ME">Montenegro</option>
<option value="MS">Montserrat</option>
<option value="MA">Morocco</option>
<option value="MZ">Mozambique</option>
<option value="MM">Myanmar</option>
<option value="NA">Namibia</option>
<option value="NR">Nauru</option>
<option value="NP">Nepal</option>
<option value="NL">Netherlands</option>
<option value="NC">New Caledonia</option>
<option value="NZ">New Zealand</option>
<option value="NI">Nicaragua</option>
<option value="NE">Niger</option>
<option value="NG">Nigeria</option>
<option value="NU">Niue</option>
<option value="NF">Norfolk Island</option>
<option value="MP">Northern Mariana Islands</option>
<option value="NO">Norway</option>
<option value="OM">Oman</option>
<option value="PK">Pakistan</option>
<option value="PW">Palau</option>
<option value="PS">Palestinian Territory, Occupied</option>
<option value="PA">Panama</option>
<option value="PG">Papua New Guinea</option>
<option value="PY">Paraguay</option>
<option value="PE">Peru</option>
<option value="PH">Philippines</option>
<option value="PN">Pitcairn</option>
<option value="PL">Poland</option>
<option value="PT">Portugal</option>
<option value="PR">Puerto Rico</option>
<option value="QA">Qatar</option>
<option value="RE">Réunion</option>
<option value="RO">Romania</option>
<option value="RU">Russian Federation</option>
<option value="RW">Rwanda</option>
<option value="BL">Saint Barthélemy</option>
<option value="SH">Saint Helena, Ascension and Tristan da Cunha</option>
<option value="KN">Saint Kitts and Nevis</option>
<option value="LC">Saint Lucia</option>
<option value="MF">Saint Martin (French part)</option>
<option value="PM">Saint Pierre and Miquelon</option>
<option value="VC">Saint Vincent and the Grenadines</option>
<option value="WS">Samoa</option>
<option value="SM">San Marino</option>
<option value="ST">Sao Tome and Principe</option>
<option value="SA">Saudi Arabia</option>
<option value="SN">Senegal</option>
<option value="RS">Serbia</option>
<option value="SC">Seychelles</option>
<option value="SL">Sierra Leone</option>
<option value="SG">Singapore</option>
<option value="SX">Sint Maarten (Dutch part)</option>
<option value="SK">Slovakia</option>
<option value="SI">Slovenia</option>
<option value="SB">Solomon Islands</option>
<option value="SO">Somalia</option>
<option value="ZA">South Africa</option>
<option value="GS">South Georgia and the South Sandwich Islands</option>
<option value="SS">South Sudan</option>
<option value="ES">Spain</option>
<option value="LK">Sri Lanka</option>
<option value="SD">Sudan</option>
<option value="SR">Suriname</option>
<option value="SJ">Svalbard and Jan Mayen</option>
<option value="SZ">Swaziland</option>
<option value="SE">Sweden</option>
<option value="CH">Switzerland</option>
<option value="SY">Syrian Arab Republic</option>
<option value="TW">Taiwan, Province of China</option>
<option value="TJ">Tajikistan</option>
<option value="TZ">Tanzania, United Republic of</option>
<option value="TH">Thailand</option>
<option value="TL">Timor-Leste</option>
<option value="TG">Togo</option>
<option value="TK">Tokelau</option>
<option value="TO">Tonga</option>
<option value="TT">Trinidad and Tobago</option>
<option value="TN">Tunisia</option>
<option value="TR">Turkey</option>
<option value="TM">Turkmenistan</option>
<option value="TC">Turks and Caicos Islands</option>
<option value="TV">Tuvalu</option>
<option value="UG">Uganda</option>
<option value="UA">Ukraine</option>
<option value="AE">United Arab Emirates</option>
<option value="UM">United States Minor Outlying Islands</option>
<option value="UY">Uruguay</option>
<option value="UZ">Uzbekistan</option>
<option value="VU">Vanuatu</option>
<option value="VE">Venezuela, Bolivarian Republic of</option>
<option value="VN">Viet Nam</option>
<option value="VG">Virgin Islands, British</option>
<option value="VI">Virgin Islands, U.S.</option>
<option value="WF">Wallis and Futuna</option>
<option value="EH">Western Sahara</option>
<option value="YE">Yemen</option>
<option value="ZM">Zambia</option>
<option value="ZW">Zimbabwe</option>
</select>
</div>
</div>
<div class="col-sm-6">
<div class="form-group" show-errors>
<label for="address_zip"
ng-bind="card.address_country === 'US' ? 'Zip Code' : 'Postal Code'"></label>
<input type="text" id="address_zip" ng-model="card.address_zip"
class="form-control" required name="address_zip" api-field />
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Submit
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,13 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-file-text-o"></i> Change Plan</h4>
</div>
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
<div class="modal-body">
Coming soon. In the meantime, please <a href="https://bitwarden.com/contact/" target="_blank">contact us</a>
if you would like to change your plan.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,75 @@
<section class="content-header">
<h1>
Collections
<small>control what you share</small>
</h1>
</section>
<section class="content">
<div class="box">
<div class="box-header with-border">
&nbsp;
<div class="box-filters hidden-xs">
<div class="form-group form-group-sm has-feedback has-feedback-left">
<input type="text" id="search" class="form-control" placeholder="Search collections..."
style="width: 200px;" ng-model="filterSearch">
<span class="fa fa-search form-control-feedback text-muted" aria-hidden="true"></span>
</div>
</div>
<div class="box-tools">
<button type="button" class="btn btn-primary btn-sm btn-flat" ng-click="add()">
<i class="fa fa-fw fa-plus-circle"></i> New Collection
</button>
</div>
</div>
<div class="box-body" ng-class="{'no-padding': filteredCollections.length}">
<div ng-show="loading && !collections.length">
Loading...
</div>
<div ng-show="!filteredCollections.length && filterSearch">
No collections to list.
</div>
<div ng-show="!loading && !collections.length">
<p>There are no collections yet for your organization.</p>
<button type="button" ng-click="add()" class="btn btn-default btn-flat">Add a Collection</button>
</div>
<div class="table-responsive" ng-show="collections.length">
<table class="table table-striped table-hover table-vmiddle">
<tbody>
<tr ng-repeat="collection in filteredCollections = (collections | filter: (filterSearch || '') |
orderBy: ['name']) track by collection.id">
<td style="width: 70px;">
<div class="btn-group" data-append-to="body">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-cog"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0)" ng-click="users(collection)">
<i class="fa fa-fw fa-users"></i> Users
</a>
</li>
<li>
<a href="javascript:void(0)" ng-click="groups(collection)">
<i class="fa fa-fw fa-sitemap"></i> Groups
</a>
</li>
<li>
<a href="javascript:void(0)" ng-click="delete(collection)" class="text-red">
<i class="fa fa-fw fa-trash"></i> Delete
</a>
</li>
</ul>
</div>
</td>
<td valign="middle">
<a href="javascript:void(0)" ng-click="edit(collection)">
{{collection.name}}
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,34 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-cubes"></i> Add New Collection</h4>
</div>
<form name="form" ng-submit="form.$valid && submit(model)" api-form="submitPromise">
<div class="modal-body">
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in form.$errors">{{e}}</li>
</ul>
</div>
<div class="form-group" show-errors>
<label for="email">Name</label>
<input type="text" id="name" name="Name" ng-model="model.name" class="form-control" required api-field />
</div>
<div class="callout callout-default">
<h4><i class="fa fa-info-circle"></i> Note</h4>
<p>
After creating the collection, you can associate a user to it by selecting a specific user on the "People" page.
</p>
<p>
You can associate new logins to the collection from your organization's "Vault" or by sharing an existing
login from "My vault".
</p>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Submit
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,35 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-cubes"></i> Edit Collection</h4>
</div>
<form name="form" ng-submit="form.$valid && submit(collection)" api-form="submitPromise">
<div class="modal-body">
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in form.$errors">{{e}}</li>
</ul>
</div>
<div class="form-group" show-errors>
<label for="email">Name</label>
<input type="text" id="name" name="Name" ng-model="collection.name" class="form-control" required api-field />
</div>
<div class="callout callout-default">
<h4><i class="fa fa-info-circle"></i> Note</h4>
<p>
Select "Users" from the listing options to manage existing users for this collection. Associate new users by
editing the user's access on the "People" page.
</p>
<p>
You can associate new logins to the collection from your organization's "Vault" or by sharing an existing
login from "My vault".
</p>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Submit
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,10 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-sitemap"></i> Groups <small>{{collection.name}}</small></h4>
</div>
<div class="modal-body">
Groups are coming soon to bitwarden Enterprise organizations.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>

View File

@@ -0,0 +1,64 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-users"></i> User Access <small>{{collection.name}}</small></h4>
</div>
<div class="modal-body">
<div ng-show="loading && !users.length">
Loading...
</div>
<div ng-show="!loading && !users.length">
<p>
No users for this collection. You can associate a new user to this collection by
selecting a specific user on the "People" page.
</p>
</div>
<div class="table-responsive" ng-show="users.length" style="margin: 0;">
<table class="table table-striped table-hover table-vmiddle" style="margin: 0;">
<tbody>
<tr ng-repeat="user in users | orderBy: ['email']">
<td style="width: 70px;">
<div class="btn-group" data-append-to=".modal">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-cog"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-show="user.id">
<a href="javascript:void(0)" ng-click="remove(user)" class="text-red">
<i class="fa fa-fw fa-remove"></i> Remove
</a>
</li>
<li ng-show="!user.id">
<a href="javascript:void(0)">
No options...
</a>
</li>
</ul>
</div>
</td>
<td style="width: 45px;">
<letter-avatar data="{{user.name || user.email}}"></letter-avatar>
</td>
<td>
{{user.email}}
<div ng-if="user.name"><small class="text-muted">{{user.name}}</small></div>
</td>
<td style="width: 60px;" class="text-right">
<i class="fa fa-unlock" ng-show="user.accessAll" title="Can Access All Items"></i>
<i class="fa fa-pencil-square-o" ng-show="!user.readOnly" title="Can Edit"></i>
</td>
<td style="width: 100px;">
{{user.type | enumName: 'OrgUserType'}}
</td>
<td style="width: 120px;">
<span class="label {{user.status | enumLabelClass: 'OrgUserStatus'}}">
{{user.status | enumName: 'OrgUserStatus'}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>

View File

@@ -0,0 +1,32 @@
<section class="content-header">
<h1>
Dashboard
<small>{{orgProfile.name}}</small>
</h1>
</section>
<section class="content">
<div class="callout callout-warning" ng-if="!orgProfile.enabled">
<h4><i class="fa fa-warning"></i> Organization Disabled</h4>
<p>
This organization is currently disabled. Users will not see your shared logins or collections.
Contact us if you would like to reinstate this organization.
</p>
<a class="btn btn-default btn-flat" href="https://bitwarden.com/contact/" target="_blank">
Contact Us
</a>
</div>
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Let's Get Started!</h3>
</div>
<div class="box-body">
<p>Dashboard features are coming soon. Get started by inviting users and creating your collections.</p>
<a class="btn btn-default btn-flat" ui-sref="backend.org.people({orgId: orgProfile.id})">
Invite Users
</a>
<a class="btn btn-default btn-flat" ui-sref="backend.org.collections({orgId: orgProfile.id})">
Manage Collections
</a>
</div>
</div>
</section>

View File

@@ -0,0 +1,34 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-trash"></i> Delete Organization</h4>
</div>
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
<div class="modal-body">
<p>
Continue below to delete this organization and all associated data. This data includes any collections and
their associated logins. Individual user accounts will remain, though they will not be associated to this
organization anymore.
</p>
<div class="callout callout-warning">
<h4><i class="fa fa-warning"></i> Warning</h4>
Deleting this organization is permanent. It cannot be undone.
</div>
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in form.$errors">{{e}}</li>
</ul>
</div>
<div class="form-group" show-errors>
<label for="masterPassword">Master Password</label>
<input type="password" id="masterPassword" name="MasterPasswordHash" ng-model="masterPassword" class="form-control"
required api-field />
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Delete
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,16 @@
<section class="content-header">
<h1>
Groups
<small>organize your users</small>
</h1>
</section>
<section class="content">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Coming soon...</h3>
</div>
<div class="box-body">
<p>Groups are coming soon to bitwarden Enterprise organizations.</p>
</div>
</div>
</section>

View File

@@ -0,0 +1,85 @@
<section class="content-header">
<h1>
People
<small>users for your organization</small>
</h1>
</section>
<section class="content">
<div class="box">
<div class="box-header with-border">
&nbsp;
<div class="box-filters hidden-xs">
<div class="form-group form-group-sm has-feedback has-feedback-left">
<input type="text" id="search" class="form-control" placeholder="Search people..."
style="width: 200px;" ng-model="filterSearch">
<span class="fa fa-search form-control-feedback text-muted" aria-hidden="true"></span>
</div>
</div>
<div class="box-tools">
<button type="button" class="btn btn-primary btn-sm btn-flat" ng-click="invite()">
<i class="fa fa-fw fa-plus-circle"></i> Invite User
</button>
</div>
</div>
<div class="box-body" ng-class="{'no-padding': filteredUsers.length}">
<div ng-show="!filteredUsers.length && !filterSearch">
Loading...
</div>
<div class="table-responsive" ng-show="filteredUsers.length">
<table class="table table-striped table-hover table-vmiddle">
<tbody>
<tr ng-repeat="user in filteredUsers = (users | filter: (filterSearch || '') |
orderBy: ['type', 'name', 'email']) track by user.id">
<td style="width: 70px;">
<div class="btn-group" data-append-to="body">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-cog"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0)" ng-click="edit(user.id)">
<i class="fa fa-fw fa-pencil"></i> Edit
</a>
</li>
<li ng-show="user.status === 1">
<a href="javascript:void(0)" ng-click="confirm(user)">
<i class="fa fa-fw fa-check"></i> Confirm
</a>
</li>
<li ng-show="user.status === 0">
<a href="javascript:void(0)" ng-click="reinvite(user)">
<i class="fa fa-fw fa-envelope-o"></i> Re-send Invitation
</a>
</li>
<li>
<a href="javascript:void(0)" ng-click="delete(user)" class="text-red">
<i class="fa fa-fw fa-remove"></i> Remove
</a>
</li>
</ul>
</div>
</td>
<td style="width: 45px;">
<letter-avatar data="{{user.name || user.email}}"></letter-avatar>
</td>
<td>
<a href="javascript:void(0)" ng-click="edit(user.id)">{{user.email}}</a>
<i class="fa fa-unlock text-muted" ng-show="user.accessAll"
title="Can Access All Items"></i>
<div ng-if="user.name"><small class="text-muted">{{user.name}}</small></div>
</td>
<td style="width: 100px;">
{{user.type | enumName: 'OrgUserType'}}
</td>
<td style="width: 120px;">
<span class="label {{user.status | enumLabelClass: 'OrgUserStatus'}}">
{{user.status | enumName: 'OrgUserStatus'}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,101 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-user"></i> Edit User <small>{{email}}</small></h4>
</div>
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
<div class="modal-body">
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in form.$errors">{{e}}</li>
</ul>
</div>
<h4>User Type</h4>
<div class="form-group">
<div class="radio">
<label>
<input type="radio" id="user-type" ng-model="type" name="Type" value="2" ng-checked="type === 2">
<strong>User</strong> - A regular user with access to your organization's collections.
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="type" name="Type" value="1" ng-checked="type === 1">
<strong>Admin</strong> - Admins can manage collections and users for your organization.
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="type" name="Type" value="0" ng-checked="type === 0">
<strong>Owner</strong> - The highest access user that can manage all aspects of your organization.
</label>
</div>
</div>
<h4>Access</h4>
<div class="radio">
<label>
<input type="radio" ng-model="accessAll" name="AccessAll"
ng-value="true" ng-checked="accessAll">
This user can access and modify <u>all items</u>.
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="accessAll" name="AccessAll"
ng-value="false" ng-checked="!accessAll">
This user can access only the selected collections.
</label>
</div>
<div ng-show="!accessAll">
<div ng-show="loading && !collections.length">
Loading collections...
</div>
<div ng-show="!loading && !collections.length">
<p>No collections for your organization.</p>
</div>
<div class="table-responsive" ng-show="collections.length" style="margin: 0;">
<table class="table table-striped table-hover" style="margin: 0;">
<thead>
<tr>
<th style="width: 40px;">
<input type="checkbox"
ng-checked="allSelected()"
ng-click="toggleCollectionSelectionAll($event)">
</th>
<th>Name</th>
<th style="width: 100px; text-align: center;">Read Only</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="collection in collections | orderBy: ['name']">
<td valign="middle">
<input type="checkbox"
name="selectedCollections[]"
value="{{collection.id}}"
ng-checked="collectionSelected(collection)"
ng-click="toggleCollectionSelection(collection.id)">
</td>
<td valign="middle">
{{collection.name}}
</td>
<td style="text-align: center;" valign="middle">
<input type="checkbox"
name="selectedCollectionsReadonly[]"
value="{{collection.id}}"
ng-disabled="!collectionSelected(collection)"
ng-checked="collectionSelected(collection) && selectedCollections[collection.id].readOnly"
ng-click="toggleCollectionReadOnlySelection(collection.id)">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Submit
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,109 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-user"></i> Invite User</h4>
</div>
<form name="inviteForm" ng-submit="inviteForm.$valid && submit(model)" api-form="submitPromise">
<div class="modal-body">
<p>
Invite a new user to your organization by entering their bitwarden account email address below. If they do not have
a bitwarden account already, they will be prompted to create a new account.
</p>
<div class="callout callout-danger validation-errors" ng-show="inviteForm.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in inviteForm.$errors">{{e}}</li>
</ul>
</div>
<div class="form-group" show-errors>
<label for="email">Email</label>
<input type="email" id="email" name="Email" ng-model="model.email" class="form-control" required api-field />
</div>
<h4>User Type</h4>
<div class="form-group">
<div class="radio">
<label>
<input type="radio" id="user-type" ng-model="model.type" name="Type" value="User">
<strong>User</strong> - A regular user with access to your organization's collections.
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="model.type" name="Type" value="Admin">
<strong>Admin</strong> - Admins can manage collections and users for your organization.
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="model.type" name="Type" value="Owner">
<strong>Owner</strong> - The highest access user that can manage all aspects of your organization.
</label>
</div>
</div>
<h4>Access</h4>
<div class="radio">
<label>
<input type="radio" ng-model="model.accessAll" name="AccessAll"
ng-value="true" ng-checked="model.accessAll">
This user can access and modify <u>all items</u>.
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="model.accessAll" name="AccessAll"
ng-value="false" ng-checked="!model.accessAll">
This user can access only the selected collections.
</label>
</div>
<div ng-show="!model.accessAll">
<div ng-show="loading && !collections.length">
Loading collections...
</div>
<div ng-show="!loading && !collections.length">
<p>No collections for your organization.</p>
</div>
<div class="table-responsive" ng-show="collections.length" style="margin: 0;">
<table class="table table-striped table-hover" style="margin: 0;">
<thead>
<tr>
<th style="width: 40px;">
<input type="checkbox"
ng-checked="allSelected()"
ng-click="toggleCollectionSelectionAll($event)">
</th>
<th>Name</th>
<th style="width: 100px; text-align: center;">Read Only</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="collection in collections | orderBy: ['name'] track by collection.id">
<td style="width: 40px;" valign="middle">
<input type="checkbox"
name="selectedCollections[]"
value="{{collection.id}}"
ng-checked="collectionSelected(collection)"
ng-click="toggleCollectionSelection(collection.id)">
</td>
<td valign="middle">
{{collection.name}}
</td>
<td style="width: 100px; text-align: center;" valign="middle">
<input type="checkbox"
name="selectedCollectionsReadonly[]"
value="{{collection.id}}"
ng-disabled="!collectionSelected(collection)"
ng-checked="collectionSelected(collection) && selectedCollections[collection.id].readOnly"
ng-click="toggleCollectionReadOnlySelection(collection.id)">
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="inviteForm.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="inviteForm.$loading"></i>Send Invite
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>

View File

@@ -0,0 +1,65 @@
<section class="content-header">
<h1>
Settings
<small>manage your organization</small>
</h1>
</section>
<section class="content">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">General</h3>
</div>
<form role="form" name="generalForm" ng-submit="generalForm.$valid && generalSave()" api-form="generalPromise">
<div class="box-body">
<div class="row">
<div class="col-sm-9">
<div class="callout callout-danger validation-errors" ng-show="generalForm.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in generalForm.$errors">{{e}}</li>
</ul>
</div>
<div class="form-group" show-errors>
<label for="name">Organization Name</label>
<input type="text" id="name" name="Name" ng-model="model.name" class="form-control"
required api-field />
</div>
<div class="form-group" show-errors>
<label for="name">Business Name</label>
<input type="text" id="businessName" name="BusinessName" ng-model="model.businessName"
class="form-control" api-field />
</div>
<div class="form-group" show-errors>
<label for="name">Billing Email</label>
<input type="email" id="billingEmail" name="BillingEmail" ng-model="model.billingEmail"
class="form-control" required api-field />
</div>
</div>
<div class="col-sm-3 settings-photo">
<letter-avatar data="{{model.name}}" round="false"
avclass="img-responsive img-rounded" avwidth="200" avheight="200"
fontsize="90"></letter-avatar>
</div>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="generalForm.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="generalForm.$loading"></i>Save
</button>
</div>
</form>
</div>
<div class="box box-danger">
<div class="box-header with-border">
<h3 class="box-title">Danger Zone</h3>
</div>
<div class="box-body">
Careful, these actions are not reversible!
</div>
<div class="box-footer">
<button type="submit" class="btn btn-default btn-flat" ng-click="delete()">
Delete Organization
</button>
</div>
</div>
</section>

View File

@@ -0,0 +1,78 @@
<section class="content-header">
<h1>
Org<span class="hidden-xs">anization</span> Vault
<small>
<span ng-pluralize
count="collections.length > 0 ? collections.length - 1 : 0"
when="{'1': '{} collection', 'other': '{} collections'}"></span>,
<span ng-pluralize count="logins.length" when="{'1': '{} login', 'other': '{} logins'}"></span>
</small>
</h1>
</section>
<section class="content">
<p ng-show="loading && !collections.length">Loading...</p>
<div class="box" ng-class="{'collapsed-box': collection.collapsed}" ng-repeat="collection in collections |
orderBy: collectionSort track by collection.id"
ng-show="collections.length && (!main.searchVaultText || collectionLogins.length)">
<div class="box-header with-border">
<h3 class="box-title">
<i class="fa" ng-class="{'fa-cubes': collection.id, 'fa-sitemap': !collection.id}"></i>
{{collection.name}}
<small ng-pluralize count="collectionLogins.length" when="{'1': '{} login', 'other': '{} logins'}"></small>
</h3>
<div class="box-tools">
<button type="button" class="btn btn-box-tool" data-widget="collapse" title="Collapse/Expand"
ng-click="collapseExpand(collection)">
<i class="fa" ng-class="{'fa-minus': !collection.collapsed, 'fa-plus': collection.collapsed}"></i>
</button>
</div>
</div>
<div class="box-body" ng-class="{'no-padding': collectionLogins.length}">
<div ng-show="!collectionLogins.length && collection.id">No logins in this collection.</div>
<div ng-show="!collectionLogins.length && !collection.id">No unassigned logins.</div>
<div class="table-responsive" ng-show="collectionLogins.length">
<table class="table table-striped table-hover table-vmiddle">
<tbody>
<tr ng-repeat="login in collectionLogins = (logins | filter: filterByCollection(collection) |
filter: (main.searchVaultText || '') | orderBy: ['name', 'username']) track by login.id">
<td style="width: 70px;">
<div class="btn-group" data-append-to="body">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-cog"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0)" ng-click="editLogin(login)">
<i class="fa fa-fw fa-pencil"></i> Edit
</a>
</li>
<li>
<a href="javascript:void(0)" ng-click="editCollections(login)">
<i class="fa fa-fw fa-cubes"></i> Collections
</a>
</li>
<li>
<a href="javascript:void(0)" ng-click="removeLogin(login, collection)" class="text-red"
ng-if="collection.id">
<i class="fa fa-fw fa-remove"></i> Remove
</a>
</li>
<li>
<a href="javascript:void(0)" ng-click="deleteLogin(login)" class="text-red">
<i class="fa fa-fw fa-trash"></i> Delete
</a>
</li>
</ul>
</div>
</td>
<td>
<a href="javascript:void(0)" ng-click="editLogin(login)">{{login.name}}</a>
<div class="text-sm text-muted">{{login.username}}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,52 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-cubes"></i> Collections <small>{{cipher.name}}</small></h4>
</div>
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
<div class="modal-body">
<p>Edit the collections that this login is being shared with.</p>
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in form.$errors">{{e}}</li>
</ul>
</div>
<div ng-show="!collections.length" class="callout callout-default">
<p>There are no collections yet for your organization.</p>
</div>
<div class="table-responsive" ng-show="collections.length" style="margin: 0;">
<table class="table table-striped table-hover" style="margin: 0;">
<thead>
<tr>
<th style="width: 40px;">
<input type="checkbox"
ng-checked="allSelected()"
ng-click="toggleCollectionSelectionAll($event)">
</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="collection in collections | orderBy: ['name'] track by collection.id">
<td valign="middle">
<input type="checkbox"
name="selectedCollections[]"
value="{{collection.id}}"
ng-checked="collectionSelected(collection)"
ng-click="toggleCollectionSelection(collection.id)">
</td>
<td valign="middle" ng-click="toggleCollectionSelection(collection.id)">
{{collection.name}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading" ng-show="collections.length">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Save
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>
</form>