Add custom fields
This commit is contained in:
Родитель
a4df8183d9
Коммит
f5e5f04c4a
|
@ -283,6 +283,18 @@
|
|||
"message": "Done",
|
||||
"description": "Done"
|
||||
},
|
||||
"custom_fields": {
|
||||
"message": "Custom Fields",
|
||||
"description": "Custom fields"
|
||||
},
|
||||
"general": {
|
||||
"message": "General",
|
||||
"description": "Custom fields"
|
||||
},
|
||||
"value": {
|
||||
"message": "Value",
|
||||
"description": "Custom fields"
|
||||
},
|
||||
"list": {
|
||||
"message": "List",
|
||||
"description": "List"
|
||||
|
|
|
@ -78,7 +78,8 @@ input:focus, select.input-md:focus {
|
|||
|
||||
select.input-md {
|
||||
background-color: #fff;
|
||||
cursor: pointer; }
|
||||
cursor: pointer;
|
||||
margin-top: -3px; }
|
||||
|
||||
/* LABEL ======================================= */
|
||||
.group label {
|
||||
|
@ -101,6 +102,14 @@ select.ng-valid:not(.ng-empty) ~ label {
|
|||
font-size: 14px;
|
||||
color: #1565c0; }
|
||||
|
||||
.col33 {
|
||||
width: 29%;
|
||||
float: left; }
|
||||
.col33:first-child {
|
||||
padding-right: 10px; }
|
||||
.col33:not(:first-child) {
|
||||
padding-left: 10px; }
|
||||
|
||||
/* BOTTOM BARS ================================= */
|
||||
.bar {
|
||||
position: relative;
|
||||
|
@ -138,7 +147,7 @@ input:focus ~ .bar:before, input:focus ~ .bar:after {
|
|||
pointer-events: none;
|
||||
opacity: 0.5; }
|
||||
|
||||
.group .mdi-content-copy, .pwField .mdi {
|
||||
.group .mdi-content-copy, .pwField .mdi, .group .mdi-delete {
|
||||
/*position: absolute;
|
||||
right: 0;*/
|
||||
margin-top: 5px;
|
||||
|
@ -157,7 +166,7 @@ input:focus ~ .bar:before, input:focus ~ .bar:after {
|
|||
border-bottom-right-radius: 16px;
|
||||
border-bottom-left-radius: 16px;
|
||||
border-top-left-radius: 16px; }
|
||||
.group .mdi-content-copy:hover, .pwField .mdi:hover {
|
||||
.group .mdi-content-copy:hover, .pwField .mdi:hover, .group .mdi-delete:hover {
|
||||
text-decoration: none;
|
||||
background-color: #e4e4e4; }
|
||||
|
||||
|
@ -167,9 +176,15 @@ input:focus ~ .bar:before, input:focus ~ .bar:after {
|
|||
.mdi-content-copy ~ input {
|
||||
width: calc(100% - 32px); }
|
||||
|
||||
.mdi-delete ~ input {
|
||||
width: calc(100% - 32px); }
|
||||
|
||||
.mdi-content-copy ~ .bar {
|
||||
width: calc(100% - 32px); }
|
||||
|
||||
.mdi-delete ~ .bar {
|
||||
width: calc(100% - 32px); }
|
||||
|
||||
/* active state */
|
||||
input:focus ~ .highlight, select.input-md ~ .highlight {
|
||||
-webkit-animation: inputHighlighter 0.3s ease;
|
||||
|
@ -431,6 +446,75 @@ input:focus ~ .highlight, select.input-md ~ .highlight {
|
|||
.md-btn.red:hover, .btn.red:focus {
|
||||
background-color: #f4511e; }
|
||||
|
||||
.tab-wrap {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
/*position: absolute;*/ }
|
||||
.tab-wrap label:not(.ng-binding) {
|
||||
cursor: pointer;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 56px;
|
||||
transition: color 0.2s ease;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #c9c9c9; }
|
||||
.tab-wrap .slide {
|
||||
background: #1565c0;
|
||||
width: calc(100% / 2);
|
||||
height: 4px;
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 52px;
|
||||
transition: left 0.3s ease-out; }
|
||||
.tab-wrap .tab-label-content {
|
||||
width: calc(100% / 2);
|
||||
float: left; }
|
||||
.tab-wrap .tab-label-content .tab-content {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 16px;
|
||||
line-height: 130%;
|
||||
display: none;
|
||||
width: 100%;
|
||||
padding-right: 20px; }
|
||||
.tab-wrap .tab-label-content .tab-content .custom_field {
|
||||
float: left;
|
||||
margin-bottom: 15px; }
|
||||
.tab-wrap .tab-label-content .tab-content .custom_field .field {
|
||||
float: left;
|
||||
width: 50%; }
|
||||
.tab-wrap .tab-label-content .tab-content .custom_field .field:first-child {
|
||||
padding-right: 10px; }
|
||||
.tab-wrap .tab-label-content .tab-content .custom_field .field:not(:first-child) {
|
||||
padding-left: 10px; }
|
||||
@media screen and (max-width: 800px) {
|
||||
.tab-wrap h1 {
|
||||
padding: 40px 0 90px 10%; }
|
||||
.tab-wrap .tab-wrap {
|
||||
width: 80%;
|
||||
margin-left: 10%;
|
||||
top: -106px; } }
|
||||
|
||||
input[type="radio"][name="tabs"] {
|
||||
position: absolute;
|
||||
z-index: -1; }
|
||||
input[type="radio"][name="tabs"]:checked + .tab-label-content label:not(.ng-binding) {
|
||||
color: rgba(0, 0, 0, 0.8); }
|
||||
input[type="radio"][name="tabs"]:checked + .tab-label-content .tab-content {
|
||||
display: block;
|
||||
margin-top: 40px; }
|
||||
input[type="radio"][name="tabs"]:nth-of-type(1):checked ~ .slide {
|
||||
left: calc((100% / 2) * 0); }
|
||||
input[type="radio"][name="tabs"]:nth-of-type(2):checked ~ .slide {
|
||||
left: calc((100% / 2) * 1); }
|
||||
input[type="radio"][name="tabs"]:first-of-type:checked ~ .slide {
|
||||
left: 0; }
|
||||
|
||||
body {
|
||||
width: 450px;
|
||||
min-height: 350px;
|
||||
|
@ -485,7 +569,7 @@ body.toggled {
|
|||
overflow-y: auto; }
|
||||
|
||||
#wrapper.toggled #page-content-wrapper {
|
||||
position: absolute;
|
||||
/*position: absolute;*/
|
||||
margin-right: -250px;
|
||||
/* width: calc(100% - 250px);*/ }
|
||||
|
||||
|
@ -499,7 +583,8 @@ body.toggled {
|
|||
width: 250px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none; }
|
||||
list-style: none;
|
||||
height: 100%; }
|
||||
.sidebar-nav li {
|
||||
line-height: 55px; }
|
||||
.sidebar-nav li a {
|
||||
|
@ -517,17 +602,28 @@ body.toggled {
|
|||
background-color: #e4e4e4; }
|
||||
.sidebar-nav li a:active, .sidebar-nav li a:focus {
|
||||
text-decoration: none; }
|
||||
.sidebar-nav li.bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
line-height: 0; }
|
||||
.sidebar-nav > .sidebar-brand {
|
||||
height: 50px;
|
||||
font-size: 18px;
|
||||
line-height: 50px;
|
||||
text-indent: 20px;
|
||||
text-align: center;
|
||||
background-color: #1565c0;
|
||||
border-right: 1px solid #104d92; }
|
||||
.sidebar-nav > .sidebar-brand span {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: #fff; }
|
||||
.sidebar-nav > .sidebar-brand span img {
|
||||
height: 32px;
|
||||
margin-right: 10px; }
|
||||
.sidebar-nav > .sidebar-brand span:hover {
|
||||
color: #fff;
|
||||
background: none; }
|
||||
|
@ -542,9 +638,10 @@ body.toggled {
|
|||
position: absolute;
|
||||
background-color: transparent;
|
||||
width: calc(100% - 250px);
|
||||
height: 350px;
|
||||
height: 100%;
|
||||
z-index: 9999999;
|
||||
right: 0; }
|
||||
right: 0;
|
||||
top: 0; }
|
||||
|
||||
.edit_credential {
|
||||
padding-top: 30px;
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<ul class="sidebar-nav">
|
||||
<li class="sidebar-brand">
|
||||
<span>
|
||||
Passman
|
||||
<img src="/icons/icon_white.svg" /> Passman
|
||||
<i class="mdi mdi-close" ng-click="toggleMenu()"></i>
|
||||
</span>
|
||||
</li>
|
||||
|
@ -81,6 +81,7 @@
|
|||
title="{{'donate_button_title' | translate}}"
|
||||
rel="nofollow noopener noreferrer"><i class="mdi mdi-credit-card"></i> Donate</a>
|
||||
</li>
|
||||
<li class="bottom">{{'credentials_in_db' | translate:credential_amount}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /#sidebar-wrapper -->
|
||||
|
|
|
@ -1,48 +1,139 @@
|
|||
<div class="tab-wrap">
|
||||
|
||||
<input type="radio" name="tabs" id="tab1" checked>
|
||||
<div class="tab-label-content" id="tab1-content">
|
||||
<label for="tab1">General</label>
|
||||
<div class="tab-content">
|
||||
<div class="group">
|
||||
<copy-text text="credential.label"></copy-text>
|
||||
<input type="text" ng-model="credential.label" required>
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'label' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<copy-text text="credential.username"></copy-text>
|
||||
<input type="text" ng-model="credential.username">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'username' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<copy-text text="credential.email"></copy-text>
|
||||
<input type="text" ng-model="credential.email">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{ 'email' | translate}}</label>
|
||||
</div>
|
||||
<div class="group pwField">
|
||||
<copy-text text="credential.password"></copy-text>
|
||||
<i class="mdi mdi-refresh pointer" ng-click="generatePassword()"></i>
|
||||
<i class="pointer mdi" ng-class="{'mdi-eye': !pwFieldShown, 'mdi-eye-off': pwFieldShown}"
|
||||
ng-click="togglePwField()"></i>
|
||||
<input type="text" ng-model="credential.password" ng-if="pwFieldShown">
|
||||
<input type="password" ng-model="credential.password" ng-if="!pwFieldShown">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'password' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<input type="password" ng-model="credential.password_repeat">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'password_repeat' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<copy-text text="credential.url"></copy-text>
|
||||
<input type="text" ng-model="credential.url">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'url' | translate}}</label>
|
||||
</div>
|
||||
<div style="margin-left: -15px;" ng-include="'save_btn.html'"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="radio" name="tabs" id="tab2">
|
||||
<div class="tab-label-content" id="tab2-content">
|
||||
<label for="tab2">Custom fields</label>
|
||||
<div class="tab-content">
|
||||
<div class="custom_field" ng-repeat="custom_field in credential.custom_fields" ng-if="custom_field.field_type !== 'file'">
|
||||
<div class="field">
|
||||
<div class="group">
|
||||
<input type="text" ng-model="custom_field.label">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="group">
|
||||
<i class="mdi mdi-delete"></i>
|
||||
<input type="password" ng-model="custom_field.value" ng-if="custom_field.field_type === 'password'">
|
||||
<input type="text" ng-model="custom_field.value" ng-if="custom_field.field_type === 'text'">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4 style="margin-left: 5px; margin-bottom: 30px;">Add custom field</h4>
|
||||
<div class="col33" style="padding-left: 0">
|
||||
<div class="group">
|
||||
<input type="text" ng-model="new_custom_field.label" placeholder="Label">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'label' | translate}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col33">
|
||||
<div class="group">
|
||||
<input type="password" ng-model="new_custom_field.value" ng-if="new_custom_field.field_type === 'password'">
|
||||
<input type="text" ng-model="new_custom_field.value" ng-if="new_custom_field.field_type === 'text'" placeholder="Value">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'value' | translate}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col33">
|
||||
<div class="group">
|
||||
<select class="input-md" name="type" ng-model="new_custom_field.field_type">
|
||||
<option value="text">Text</option>
|
||||
<option value="password">Password</option>
|
||||
</select>
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span><i class="mdi mdi-plus" style="font-size: 30px; padding-top: 10px; display: inline-block; float: left; padding-left: 25px;" ng-click="addCustomField(new_custom_field)"></i></span>
|
||||
|
||||
<div class="clearfix" style="margin-bottom: 30px;"></div>
|
||||
<div style="margin-left: -15px;" ng-include="'save_btn.html'"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="slide"></div>
|
||||
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<script type="text/ng-template" id="save_btn.html">
|
||||
<button class="md-btn default" ng-click="saveCredential()" ng-disabled="saving">
|
||||
<span>
|
||||
<i ng-show="saving"
|
||||
ng-class="{'fa-spinner fa-spin': saving}"
|
||||
class="fa"></i>
|
||||
{{'save' | translate}}
|
||||
</span>
|
||||
</button>
|
||||
<button class="md-btn" ng-click="cancel()">
|
||||
<span>{{'cancel' | translate}}</span>
|
||||
</button>
|
||||
</script>
|
||||
<!--
|
||||
<div class="edit_credential">
|
||||
<div class="group">
|
||||
<copy-text text="credential.label"></copy-text>
|
||||
<input type="text" ng-model="credential.label" required>
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'label' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<copy-text text="credential.username"></copy-text>
|
||||
<input type="text" ng-model="credential.username">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'username' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<copy-text text="credential.email"></copy-text>
|
||||
<input type="text" ng-model="credential.email">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{ 'email' | translate}}</label>
|
||||
</div>
|
||||
<div class="group pwField">
|
||||
<copy-text text="credential.password"></copy-text>
|
||||
<i class="mdi mdi-refresh pointer" ng-click="generatePassword()"></i>
|
||||
<i class="pointer mdi" ng-class="{'mdi-eye': !pwFieldShown, 'mdi-eye-off': pwFieldShown}" ng-click="togglePwField()"></i>
|
||||
<input type="text" ng-model="credential.password" ng-if="pwFieldShown">
|
||||
<input type="password" ng-model="credential.password" ng-if="!pwFieldShown">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'password' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<input type="password" ng-model="credential.password_repeat">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'password_repeat' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<copy-text text="credential.url"></copy-text>
|
||||
<input type="text" ng-model="credential.url">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'url' | translate}}</label>
|
||||
</div>
|
||||
|
||||
<button class="md-btn default" ng-click="saveCredential()" ng-disabled="saving">
|
||||
<span>{{'save' | translate}}</span>
|
||||
</button>
|
||||
|
@ -107,26 +198,7 @@
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>Add custom field</h4>
|
||||
<div class="col-xs-3 pad5">
|
||||
<input class="form-control" type="text" ng-model="new_custom_field.label" placeholder="Label">
|
||||
</div>
|
||||
<div class="col-xs-3 pad5">
|
||||
<input class="form-control" type="password" ng-model="new_custom_field.value" ng-if="new_custom_field.field_type === 'password'">
|
||||
<input class="form-control" type="text" ng-model="new_custom_field.value" ng-if="new_custom_field.field_type === 'text'" placeholder="Value">
|
||||
</div>
|
||||
<div class="col-xs-3 pad5">
|
||||
<select class="form-control" name="type" ng-model="new_custom_field.field_type">
|
||||
<option value="text">Text</option>
|
||||
<option value="password">Password</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-xs-3 pad5">
|
||||
<button class="btn btn-default" ng-click="addCustomField(new_custom_field)">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
|
||||
<button class="btn btn-success" ng-click="saveCredential()" ng-disabled="saving">{{'save' |
|
||||
translate}}
|
||||
|
|
|
@ -34,6 +34,13 @@
|
|||
<span class="bar"></span>
|
||||
<label>{{'vault_password' | translate}}</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<input type="text" ng-model="settings.refreshTime"
|
||||
required ng-debounce="1000">
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>{{'refresh_timer' | translate}}</label>
|
||||
</div>
|
||||
<div class="ignored_sites">
|
||||
<label>{{'ignored_sites' | translate}}</label>
|
||||
<ul class="ignored_sites">
|
||||
|
@ -88,6 +95,9 @@
|
|||
<button class="md-btn" ng-click="cancel()">
|
||||
<span>{{'cancel' | translate}}</span>
|
||||
</button>
|
||||
<div class="version">
|
||||
{{extension}}
|
||||
</div>
|
||||
<!--
|
||||
<h4 align="center">{{'please_enter_nextcloud_credentials' | translate}}:</h4>
|
||||
<div class="alerts alert alert-warning" ng-if="errors.length > 0">
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 68 68" enable-background="new 0 0 68 68" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M0,34c0,21.9,30,34,34,34c4,0,34-12.1,34-34V0H0V34z M45.4,50.3H22.6v-6.5h22.8V50.3z M21.6,16.2
|
||||
c0,0,6.5,2.4,9.2,4.1c-0.6-2.6-1.2-10-1.2-10h8.6c0,0-0.6,7.8-1.2,10c1.2-0.6,9.4-4.1,9.4-4.1l2.7,8.3c0,0-7.5,1.8-10.1,1.9
|
||||
c1.8,1.4,6.7,7.4,6.7,7.4l-7,5.3c0,0-3.8-6.3-5-8.9c-1.2,2.9-5,8.9-5,8.9l-7.2-5.3c0,0,5.7-6.3,7.1-7.4c-1.4-0.1-9.9-1.9-9.9-1.9
|
||||
L21.6,16.2z"/>
|
||||
</g>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 850 B |
|
@ -35,27 +35,12 @@
|
|||
angular.module('passmanExtension')
|
||||
.controller('ListCtrl', ['$scope', 'Settings', '$location', '$rootScope', function ($scope, Settings, $window, $rootScope) {
|
||||
$scope.app = 'passman';
|
||||
var port = API.runtime.connect(null, {
|
||||
name: "PassmanCommunication"
|
||||
});
|
||||
|
||||
var messageParser = function (message) {
|
||||
var e = message.split(':');
|
||||
|
||||
switch (e[0]) {
|
||||
case "credential_amount":
|
||||
$scope.credential_amount = e[1];
|
||||
$scope.refreshing_credentials = false;
|
||||
}
|
||||
|
||||
$scope.$apply();
|
||||
};
|
||||
|
||||
/**
|
||||
* Connect to the background service
|
||||
*/
|
||||
var initApp = function () {
|
||||
port.onMessage.addListener(messageParser);
|
||||
API.runtime.sendMessage(API.runtime.id, {method: "getMasterPasswordSet"}).then(function (isPasswordSet) {
|
||||
//First check attributes
|
||||
if (!isPasswordSet) {
|
||||
|
@ -63,22 +48,10 @@
|
|||
}
|
||||
|
||||
getActiveTab();
|
||||
$scope.refreshing_credentials = true;
|
||||
setTimeout(function () {
|
||||
port.postMessage("credential_amount");
|
||||
}, 500);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.refreshing_credentials = false;
|
||||
$scope.refresh = function () {
|
||||
$scope.refreshing_credentials = true;
|
||||
API.runtime.sendMessage(API.runtime.id, {method: "getCredentials"}).then(function () {
|
||||
setTimeout(function () {
|
||||
port.postMessage("credential_amount");
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var getActiveTab = function () {
|
||||
API.tabs.query({currentWindow: true, active: true}).then(function (tab) {
|
||||
|
|
|
@ -35,6 +35,49 @@
|
|||
angular.module('passmanExtension')
|
||||
.controller('MainCtrl', ['$scope', 'Settings', '$location', '$rootScope', '$timeout', function ($scope, Settings, $window, $rootScope, $timeout) {
|
||||
|
||||
var port = API.runtime.connect(null, {
|
||||
name: "PassmanCommunication"
|
||||
});
|
||||
|
||||
var messageParser = function (message) {
|
||||
var e = message.split(':');
|
||||
|
||||
switch (e[0]) {
|
||||
case "credential_amount":
|
||||
$scope.credential_amount = e[1];
|
||||
$scope.refreshing_credentials = false;
|
||||
}
|
||||
|
||||
$scope.$apply();
|
||||
};
|
||||
|
||||
/**
|
||||
* Connect to the background service
|
||||
*/
|
||||
var initApp = function () {
|
||||
port.onMessage.addListener(messageParser);
|
||||
API.runtime.sendMessage(API.runtime.id, {method: "getMasterPasswordSet"}).then(function (isPasswordSet) {
|
||||
//First check attributes
|
||||
if (!isPasswordSet) {
|
||||
return;
|
||||
}
|
||||
$scope.refreshing_credentials = true;
|
||||
setTimeout(function () {
|
||||
port.postMessage("credential_amount");
|
||||
}, 500);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.refreshing_credentials = false;
|
||||
$scope.refresh = function () {
|
||||
$scope.refreshing_credentials = true;
|
||||
API.runtime.sendMessage(API.runtime.id, {method: "getCredentials"}).then(function () {
|
||||
setTimeout(function () {
|
||||
port.postMessage("credential_amount");
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.menuIsOpen = false;
|
||||
$scope.bodyOverflow = false;
|
||||
|
@ -65,7 +108,7 @@
|
|||
} else if (settings.hasOwnProperty('isInstalled')) {
|
||||
window.location = '#!/locked';
|
||||
} else {
|
||||
// initApp();
|
||||
initApp();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
@import "partials/material-switch";
|
||||
@import "partials/material-checkbox";
|
||||
@import "partials/material-buttons";
|
||||
@import "partials/material-tabs";
|
||||
|
||||
$sidebarWidth: 250px;
|
||||
body {
|
||||
|
@ -71,7 +72,7 @@ body.toggled {
|
|||
}
|
||||
|
||||
#wrapper.toggled #page-content-wrapper {
|
||||
position: absolute;
|
||||
/*position: absolute;*/
|
||||
margin-right: -$sidebarWidth;
|
||||
/* width: calc(100% - 250px);*/
|
||||
}
|
||||
|
@ -89,6 +90,7 @@ body.toggled {
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
height: 100%;
|
||||
li {
|
||||
line-height: 55px;
|
||||
a {
|
||||
|
@ -112,19 +114,31 @@ body.toggled {
|
|||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
&.bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
line-height: 0;
|
||||
}
|
||||
}
|
||||
> .sidebar-brand {
|
||||
height: 50px;
|
||||
font-size: 18px;
|
||||
line-height: 50px;
|
||||
text-indent: 20px;
|
||||
text-align: center;
|
||||
background-color: #1565c0;
|
||||
border-right: 1px solid darken(#1565c0, 10%);
|
||||
span {
|
||||
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
img {
|
||||
height: 32px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background: none;
|
||||
|
@ -144,9 +158,10 @@ body.toggled {
|
|||
position: absolute;
|
||||
background-color: transparent;
|
||||
width: calc(100% - 250px);
|
||||
height: 350px;
|
||||
height: 100%;
|
||||
z-index: 9999999;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.edit_credential {
|
||||
|
@ -189,26 +204,30 @@ label, .switch-label, label:not(.input-checkbox):not(.label) {
|
|||
margin-bottom: 45px;
|
||||
}
|
||||
}
|
||||
.invisible{
|
||||
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
.master_pw_warning{
|
||||
|
||||
.master_pw_warning {
|
||||
padding-left: 6px;
|
||||
font-size: 10px;
|
||||
color: #a94442;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.master_pw_warning.big{
|
||||
|
||||
.master_pw_warning.big {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
.unlock {
|
||||
width: 350px;
|
||||
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
|
||||
margin: -20px auto 10px;
|
||||
padding: 20px;
|
||||
.group{
|
||||
.group {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
img {
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
.tab-wrap {
|
||||
width: 50%;
|
||||
margin-left: 20%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
top: -106px; }
|
||||
.tab-wrap label {
|
||||
cursor: pointer;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
background-color: #00bcd4;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 56px;
|
||||
transition: color 0.2s ease;
|
||||
width: 100%; }
|
||||
.tab-wrap .slide {
|
||||
background: #ffeb3b;
|
||||
width: calc(100% / 4);
|
||||
height: 4px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: calc(100% - 4px);
|
||||
transition: left 0.3s ease-out; }
|
||||
.tab-wrap .tab-label-content {
|
||||
width: 100%; }
|
||||
.tab-wrap .tab-label-content .tab-content {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 16px;
|
||||
line-height: 130%;
|
||||
display: none; }
|
||||
@media screen and (max-width: 800px) {
|
||||
.tab-wrap h1 {
|
||||
padding: 40px 0 90px 10%; }
|
||||
.tab-wrap .tab-wrap {
|
||||
width: 80%;
|
||||
margin-left: 10%;
|
||||
top: -106px; } }
|
||||
|
||||
input[type="radio"][name="tabs"] {
|
||||
position: absolute;
|
||||
z-index: -1; }
|
||||
input[type="radio"][name="tabs"]:checked + .tab-label-content label {
|
||||
color: white; }
|
||||
input[type="radio"][name="tabs"]:checked + .tab-label-content .tab-content {
|
||||
display: block; }
|
||||
input[type="radio"][name="tabs"]:nth-of-type(1):checked ~ .slide {
|
||||
left: calc((100% / 4) * 0); }
|
||||
input[type="radio"][name="tabs"]:nth-of-type(2):checked ~ .slide {
|
||||
left: calc((100% / 4) * 1); }
|
||||
input[type="radio"][name="tabs"]:nth-of-type(3):checked ~ .slide {
|
||||
left: calc((100% / 4) * 2); }
|
||||
input[type="radio"][name="tabs"]:nth-of-type(4):checked ~ .slide {
|
||||
left: calc((100% / 4) * 3); }
|
||||
input[type="radio"][name="tabs"]:first-of-type:checked ~ .slide {
|
||||
left: 0; }
|
|
@ -27,6 +27,7 @@ input:focus, select.input-md:focus {
|
|||
select.input-md{
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
margin-top: -3px;
|
||||
}
|
||||
/* LABEL ======================================= */
|
||||
.group label {
|
||||
|
@ -51,7 +52,16 @@ select.ng-valid:not(.ng-empty) ~ label {
|
|||
font-size: 14px;
|
||||
color: #1565c0;
|
||||
}
|
||||
|
||||
.col33{
|
||||
width: 29%;
|
||||
float: left;
|
||||
&:first-child{
|
||||
padding-right: 10px;
|
||||
}
|
||||
&:not(:first-child){
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
/* BOTTOM BARS ================================= */
|
||||
.bar {
|
||||
position: relative;
|
||||
|
@ -95,7 +105,7 @@ input:focus ~ .bar:before, input:focus ~ .bar:after {
|
|||
opacity: 0.5;
|
||||
|
||||
}
|
||||
.group .mdi-content-copy, .pwField .mdi{
|
||||
.group .mdi-content-copy, .pwField .mdi, .group .mdi-delete{
|
||||
/*position: absolute;
|
||||
right: 0;*/
|
||||
margin-top:5px;
|
||||
|
@ -128,9 +138,15 @@ input:focus ~ .bar:before, input:focus ~ .bar:after {
|
|||
.mdi-content-copy ~ input{
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
.mdi-delete ~ input{
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
.mdi-content-copy ~ .bar{
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
.mdi-delete ~ .bar{
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
/* active state */
|
||||
input:focus ~ .highlight, select.input-md ~ .highlight {
|
||||
-webkit-animation: inputHighlighter 0.3s ease;
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
$headerBgColor: #fff;
|
||||
$sliderColor: #1565c0;
|
||||
$grey: #9e9e9e;
|
||||
|
||||
$num-of-tabs: 2;
|
||||
|
||||
@mixin tabs {
|
||||
@for $i from 1 through $num-of-tabs {
|
||||
&:nth-of-type(#{$i}) {
|
||||
&:checked {
|
||||
~ .slide {
|
||||
left: calc((100% / #{$num-of-tabs}) * #{$i - 1});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-wrap {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
/*position: absolute;*/
|
||||
label:not(.ng-binding) {
|
||||
cursor: pointer;
|
||||
color: rgba(0,0,0,0.8);
|
||||
background-color: $headerBgColor;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 56px;
|
||||
transition: color 0.2s ease;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #c9c9c9;
|
||||
}
|
||||
|
||||
.slide {
|
||||
background: $sliderColor;
|
||||
width: calc(100% / #{$num-of-tabs});
|
||||
height: 4px;
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 52px;
|
||||
transition: left 0.3s ease-out;
|
||||
}
|
||||
|
||||
.tab-label-content {
|
||||
width: calc(100% / #{$num-of-tabs});
|
||||
float: left;
|
||||
.tab-content {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 16px;
|
||||
line-height: 130%;
|
||||
display: none;
|
||||
width: 100%;
|
||||
padding-right: 20px;
|
||||
.custom_field{
|
||||
.field{
|
||||
&:first-child{
|
||||
padding-right: 10px;
|
||||
}
|
||||
&:not(:first-child){
|
||||
padding-left: 10px;
|
||||
}
|
||||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
float: left;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
h1 {
|
||||
padding: 40px 0 90px 10%;
|
||||
}
|
||||
.tab-wrap {
|
||||
width: 80%;
|
||||
margin-left: 10%;
|
||||
top: -106px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type="radio"][name="tabs"] {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
&:checked {
|
||||
+ .tab-label-content {
|
||||
label:not(.ng-binding) {
|
||||
color: rgba(0,0,0,0.8);
|
||||
}
|
||||
.tab-content {
|
||||
display: block;
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@include tabs;
|
||||
&:first-of-type {
|
||||
&:checked {
|
||||
~ .slide {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче