diff --git a/Gruntfile.js b/Gruntfile.js index aa2b4c1d..60cfed19 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -10,12 +10,12 @@ module.exports = function (grunt) { quoteChar: '\'', useStrict: true, htmlmin: { - collapseBooleanAttributes: true, + collapseBooleanAttributes: false, collapseWhitespace: true, removeAttributeQuotes: false, removeComments: true, removeEmptyAttributes: false, - removeRedundantAttributes: true, + removeRedundantAttributes: false, removeScriptTypeAttributes: false, removeStyleLinkTypeAttributes: false } @@ -43,7 +43,7 @@ module.exports = function (grunt) { //@TODO JSHint, comile sass watch: { scripts: { - files: ['Gruntfile.js', 'views/*.html'], + files: ['Gruntfile.js', 'templates/views/*.html','sass/*','sass/partials/*'], tasks: ['html2js','sass'], options: { spawn: false, diff --git a/appinfo/routes.php b/appinfo/routes.php index b00c4098..3e7df09a 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -22,7 +22,7 @@ return [ ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], //Vault - ['name' => 'vault#index', 'url' => '/api/v1/vaults', 'verb' => 'GET'], + ['name' => 'vault#listVaults', 'url' => '/api/v1/vaults', 'verb' => 'GET'], ['name' => 'vault#create', 'url' => '/api/v1/vaults', 'verb' => 'POST'], ['name' => 'vault#get', 'url' => '/api/v1/vaults/{vault_id}', 'verb' => 'GET'], ['name' => 'vault#update', 'url' => '/api/v1/vaults/{vault_id}', 'verb' => 'PATCH'], diff --git a/controller/credentialcontroller.php b/controller/credentialcontroller.php index 873bcd52..bb9ea218 100644 --- a/controller/credentialcontroller.php +++ b/controller/credentialcontroller.php @@ -17,8 +17,9 @@ use OCA\Passman\Credential; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\ApiController; +use OCP\AppFramework\Controller; -class CredentialController extends ApiController { +class CredentialController extends Controller { private $userId; diff --git a/controller/vaultcontroller.php b/controller/vaultcontroller.php index 9a283abc..335273a6 100644 --- a/controller/vaultcontroller.php +++ b/controller/vaultcontroller.php @@ -13,12 +13,11 @@ namespace OCA\Passman\Controller; use OCP\IRequest; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\ApiController; class VaultController extends ApiController { - - private $userId; public function __construct($AppName, IRequest $request, $UserId) { @@ -26,6 +25,40 @@ class VaultController extends ApiController { $this->userId = $UserId; } + /** + * @NoAdminRequired + */ + public function listVaults() { + + $vaults = [ + array( + 'vault_id' => uniqid(), + 'name' => 'Vault ' . rand(1, 20), + 'created' => time(), + 'last_access' => time() + ), + array( + 'id' => uniqid(), + 'name' => 'Vault ' . rand(1, 20), + 'created' => time(), + 'last_access' => time() + ), + array( + 'id' => uniqid(), + 'name' => 'Vault ' . rand(1, 20), + 'created' => time(), + 'last_access' => time() + ), + array( + 'id' => uniqid(), + 'name' => 'Vault ' . rand(1, 20), + 'created' => time(), + 'last_access' => time() + ) + ]; + return new JSONResponse($vaults); + } + /** * @NoAdminRequired */ diff --git a/css/app.css b/css/app.css index 1361c8e2..a2755964 100644 --- a/css/app.css +++ b/css/app.css @@ -1,3 +1,57 @@ +.button-geen { + background: #37ce02; + color: #fff; } +.button-geen:hover { + background: #3ad802; + color: #fff; } + +.button-red { + background: #ce3702; + color: #fff; } + +.button-red:hover { + background: #d83a02; + color: #fff; } + +.vault_wrapper { + margin: 0 auto; + margin-top: 20px; + width: 100%; + max-width: 420px; + -webkit-border-radius: 5px; + border-radius: 5px; + background-clip: padding-box; + /* stops bg color from leaking outside the border: */ + box-shadow: 0 1px 1px #777; + background: #eee; + display: block; } + .vault_wrapper .vaultlist { + z-index: 500; } + .vault_wrapper .vaultlist li, .vault_wrapper .vaultlist div, .vault_wrapper .vaultlist span, .vault_wrapper .vaultlist small { + cursor: pointer; } + .vault_wrapper .vaultlist small { + color: #8e8e8e; } + .vault_wrapper .vaultlist li.selected { + background-color: #0082c9 !important; + color: #ddd; } + .vault_wrapper .vaultlist li { + border-bottom: 1px solid #8e8e8e; + padding: 16px; } + .vault_wrapper .vaultlist li:hover { + background-color: #f7f7f7; } + .vault_wrapper .login_form { + padding: 16px; } + .vault_wrapper .login_form input[type="password"], .vault_wrapper .login_form input[type="text"] { + width: 100%; + -webkit-border-radius: 5px; + border-radius: 5px; + background-clip: padding-box; + /* stops bg color from leaking outside the border: */ } + .vault_wrapper .login_form .button_wrapper .button { + width: 45%; + display: inline-block; } + .vault_wrapper .login_form .button { + margin-top: 10px; } /*# sourceMappingURL=app.css.map */ diff --git a/css/app.css.map b/css/app.css.map index 08ecccf3..9e7366d8 100644 --- a/css/app.css.map +++ b/css/app.css.map @@ -1,7 +1,7 @@ { "version": 3, -"mappings": "", -"sources": [], +"mappings": "AAAA,YAAY;EACV,UAAU,EAAE,OAAO;EACnB,KAAK,EAAE,IAAI;;AAEb,kBAAkB;EAChB,UAAU,EAAE,OAAoB;EAChC,KAAK,EAAE,IAAI;;AAGb,WAAW;EACT,UAAU,EAAE,OAAO;EACnB,KAAK,EAAE,IAAI;;AAEb,iBAAiB;EACf,UAAU,EAAE,OAAoB;EAChC,KAAK,EAAE,IAAI;;ACdb,cAAc;EACZ,MAAM,EAAE,MAAM;EACd,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,IAAI;EACX,SAAS,EAAE,KAAK;ECMhB,qBAAqB,EDLE,GAAG;ECM1B,aAAa,EDNU,GAAG;ECO1B,eAAe,EAAE,WAAW;EAAG,qDAAqD;EDNpF,UAAU,EAAE,cAAc;EAC1B,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,KAAK;EACd,yBAAU;IAER,OAAO,EAAE,GAAG;IACZ,4HAAiB;MACf,MAAM,EAAE,OAAO;IAEjB,+BAAK;MACH,KAAK,EAAE,OAAO;IAEhB,qCAAW;MACT,gBAAgB,EAAE,kBAAkB;MACpC,KAAK,EAAE,IAAI;IAEb,4BAAE;MACA,aAAa,EAAE,iBAAiB;MAChC,OAAO,EAAE,IAAI;IAEf,kCAAQ;MACN,gBAAgB,EAAE,OAAO;EAG7B,0BAAW;IACT,OAAO,EAAE,IAAI;IACb,gGAA0C;MACxC,KAAK,EAAE,IAAI;MCvBf,qBAAqB,EDwBM,GAAG;MCvB9B,aAAa,EDuBc,GAAG;MCtB9B,eAAe,EAAE,WAAW;MAAG,qDAAqD;IDyBhF,kDAAO;MACL,KAAK,EAAE,GAAG;MACV,OAAO,EAAE,YAAY;IAGzB,kCAAO;MACL,UAAU,EAAE,IAAI", +"sources": ["../sass/partials/button.scss","../sass/vaults.scss","../sass/mixins.scss"], "names": [], "file": "app.css" } diff --git a/js/app/app.js b/js/app/app.js index 96f3f301..cc686d5a 100644 --- a/js/app/app.js +++ b/js/app/app.js @@ -21,9 +21,8 @@ angular .config(function ($routeProvider) { $routeProvider .when('/', { - templateUrl: 'views/main.html', - controller: 'MainCtrl', - controllerAs: 'main' + templateUrl: 'views/vaults.html', + controller: 'VaultCtrl' }) .otherwise({ redirectTo: '/' diff --git a/js/app/controllers/main.js b/js/app/controllers/main.js index 334f34f9..36bf48a9 100644 --- a/js/app/controllers/main.js +++ b/js/app/controllers/main.js @@ -8,10 +8,6 @@ * Controller of the passmanApp */ angular.module('passmanApp') - .controller('MainCtrl', function () { - this.awesomeThings = [ - 'HTML5 Boilerplate', - 'AngularJS', - 'Karma' - ]; - }); + .controller('MainCtrl', ['$scope', 'VaultService', function ($scope, VaultService) { + $scope.selectedVault = false; + }]); diff --git a/js/app/controllers/menu.js b/js/app/controllers/menu.js new file mode 100644 index 00000000..e4be032b --- /dev/null +++ b/js/app/controllers/menu.js @@ -0,0 +1,17 @@ +'use strict'; + +/** + * @ngdoc function + * @name passmanApp.controller:MenuCtrl + * @description + * # MenuCtrl + * Controller of the passmanApp + */ +angular.module('passmanApp') + .controller('MenuCtrl', function () { + this.awesomeThings = [ + 'HTML5 Boilerplate', + 'AngularJS', + 'Karma' + ]; + }); diff --git a/js/app/controllers/vault.js b/js/app/controllers/vault.js new file mode 100644 index 00000000..1a501132 --- /dev/null +++ b/js/app/controllers/vault.js @@ -0,0 +1,34 @@ +'use strict'; + +/** + * @ngdoc function + * @name passmanApp.controller:MainCtrl + * @description + * # MainCtrl + * Controller of the passmanApp + */ +angular.module('passmanApp') + .controller('VaultCtrl', ['$scope', 'VaultService', function ($scope, VaultService) { + VaultService.getVaults().then(function (vaults) { + $scope.vaults = vaults; + }); + + + $scope.default_vault = false; + $scope.remember_vault_password = false; + + $scope.list_selected_vault = false; + + $scope.clearState = function () { + $scope.list_selected_vault = false; + $scope.creating_vault = false; + }; + + $scope.selectVault = function(vault){ + $scope.list_selected_vault = vault; + } + + $scope.newVault = function(){ + $scope.creating_vault = true; + } + }]); diff --git a/js/app/filters/propsfilter.js b/js/app/filters/propsfilter.js new file mode 100644 index 00000000..404c6b53 --- /dev/null +++ b/js/app/filters/propsfilter.js @@ -0,0 +1,42 @@ +'use strict'; + +/** + * @ngdoc filter + * @name passmanApp.filter:propsFilter + * @function + * @description + * # propsFilter + * Filter in the passmanApp. + */ +angular.module('passmanApp') + .filter('propsFilter', function () { + return function (items, props) { + var out = []; + + if (angular.isArray(items)) { + var keys = Object.keys(props); + + items.forEach(function (item) { + var itemMatches = false; + + for (var i = 0; i < keys.length; i++) { + var prop = keys[i]; + var text = props[prop].toLowerCase(); + if (item[prop].toString().toLowerCase().indexOf(text) !== -1) { + itemMatches = true; + break; + } + } + + if (itemMatches) { + out.push(item); + } + }); + } else { + // Let the output be the input untouched + out = items; + } + + return out; + }; + }); diff --git a/js/app/services/cacheservice.js b/js/app/services/cacheservice.js new file mode 100644 index 00000000..4e9fc830 --- /dev/null +++ b/js/app/services/cacheservice.js @@ -0,0 +1,13 @@ +'use strict'; + +/** + * @ngdoc service + * @name passmanApp.VaultService + * @description + * # VaultService + * Service in the passmanApp. + */ +angular.module('passmanApp') + .service('CacheService', [function () { + // AngularJS will instantiate a singleton by calling "new" on this function + }]); diff --git a/js/app/services/credentialservice.js b/js/app/services/credentialservice.js new file mode 100644 index 00000000..abbba1f8 --- /dev/null +++ b/js/app/services/credentialservice.js @@ -0,0 +1,13 @@ +'use strict'; + +/** + * @ngdoc service + * @name passmanApp.CredentialService + * @description + * # CredentialService + * Service in the passmanApp. + */ +angular.module('passmanApp') + .service('CredentialService', function () { + // AngularJS will instantiate a singleton by calling "new" on this function + }); diff --git a/js/app/services/vaultservice.js b/js/app/services/vaultservice.js new file mode 100644 index 00000000..ad29a76c --- /dev/null +++ b/js/app/services/vaultservice.js @@ -0,0 +1,28 @@ +'use strict'; + +/** + * @ngdoc service + * @name passmanApp.VaultService + * @description + * # VaultService + * Service in the passmanApp. + */ +angular.module('passmanApp') + .service('VaultService', ['$http', 'CacheService', function ($http, CacheService) { + // AngularJS will instantiate a singleton by calling "new" on this function + return { + getVaults: function(){ + var queryUrl = OC.generateUrl('apps/passman/api/v1/vaults'); + return $http.get(queryUrl).then(function (response) { + if(response.data){ + return response.data; + } else { + return response; + } + }); + }, + createVault: function (vault) { + + } + } + }]); diff --git a/js/templates.js b/js/templates.js index eb52c98b..4f8e7cc2 100644 --- a/js/templates.js +++ b/js/templates.js @@ -1,7 +1,7 @@ -angular.module('templates-main', ['views/main.html']); +angular.module('templates-main', ['views/vaults.html']); -angular.module('views/main.html', []).run(['$templateCache', function($templateCache) { +angular.module('views/vaults.html', []).run(['$templateCache', function($templateCache) { 'use strict'; - $templateCache.put('views/main.html', - 'Hello world!'); + $templateCache.put('views/vaults.html', + '
  • + Create a new vault
  • {{vault.name}}
    Created: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | Last accessed: {{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
  • Go back to vaults
'); }]); diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index b2cb4101..23e87a3d 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -46,8 +46,8 @@ class Application extends App { return [ 'id' => $c->getAppName(), 'order' => 10, - 'name' => $c->query(IL10N::class)->t('Password'), - 'href' => $server->getURLGenerator()->linkToRoute('passman.PageController.index'), + 'name' => $c->query(IL10N::class)->t('Passwords'), + 'href' => $server->getURLGenerator()->linkToRoute('passman.page.index'), 'icon' => $server->getURLGenerator()->imagePath($c->getAppName(), 'app.svg'), ]; }; diff --git a/sass/app.scss b/sass/app.scss index 2fb8ba92..8f5427a9 100644 --- a/sass/app.scss +++ b/sass/app.scss @@ -1,3 +1,6 @@ @import 'container'; +@import 'mixins'; +@import 'partials/button'; +@import 'vaults'; @import 'menu'; \ No newline at end of file diff --git a/sass/mixins.scss b/sass/mixins.scss new file mode 100644 index 00000000..f0f38391 --- /dev/null +++ b/sass/mixins.scss @@ -0,0 +1,63 @@ +@mixin clearfix() { + &:before, + &:after { + content: ""; + display: table; + } + &:after { + clear: both; + } +} +@mixin border-radius($radius) { + -webkit-border-radius: $radius; + border-radius: $radius; + background-clip: padding-box; /* stops bg color from leaking outside the border: */ +} + +// Single side border-radius + +@mixin border-top-radius($radius) { + -webkit-border-top-right-radius: $radius; + border-top-right-radius: $radius; + -webkit-border-top-left-radius: $radius; + border-top-left-radius: $radius; + background-clip: padding-box; +} +@mixin border-right-radius($radius) { + -webkit-border-bottom-right-radius: $radius; + border-bottom-right-radius: $radius; + -webkit-border-top-right-radius: $radius; + border-top-right-radius: $radius; + background-clip: padding-box; +} +@mixin border-bottom-radius($radius) { + -webkit-border-bottom-right-radius: $radius; + border-bottom-right-radius: $radius; + -webkit-border-bottom-left-radius: $radius; + border-bottom-left-radius: $radius; + background-clip: padding-box; +} +@mixin border-left-radius($radius) { + -webkit-border-bottom-left-radius: $radius; + border-bottom-left-radius: $radius; + -webkit-border-top-left-radius: $radius; + border-top-left-radius: $radius; + background-clip: padding-box; +} + +@mixin opacity($opacity) { + opacity: $opacity; + $opacity-ie: $opacity * 100; + filter: alpha(opacity=$opacity-ie); //IE8 +} + +@mixin center-block { + display: block; + margin-left: auto; + margin-right: auto; +} + +@mixin font-size($sizeValue: 12 ){ + font-size: $sizeValue + px; //fallback for old browsers + font-size: (0.125 * $sizeValue) + rem; +} \ No newline at end of file diff --git a/sass/partials/button.scss b/sass/partials/button.scss new file mode 100644 index 00000000..5339a8a6 --- /dev/null +++ b/sass/partials/button.scss @@ -0,0 +1,17 @@ +.button-geen{ + background: #37ce02; + color: #fff; +} +.button-geen:hover{ + background: lighten(#37ce02, 2%); + color: #fff; +} + +.button-red{ + background: #ce3702; + color: #fff; +} +.button-red:hover{ + background: lighten(#ce3702, 2%); + color: #fff; +} \ No newline at end of file diff --git a/sass/vaults.scss b/sass/vaults.scss new file mode 100644 index 00000000..c083d259 --- /dev/null +++ b/sass/vaults.scss @@ -0,0 +1,48 @@ + +.vault_wrapper{ + margin: 0 auto; + margin-top: 20px; + width: 100%; + max-width: 420px; + @include border-radius(5px); + box-shadow: 0 1px 1px #777; + background: #eee; + display: block; + .vaultlist{ + + z-index: 500; + li,div,span,small{ + cursor: pointer; + } + small{ + color: #8e8e8e; + } + li.selected{ + background-color: #0082c9 !important; + color: #ddd; + } + li{ + border-bottom: 1px solid #8e8e8e; + padding: 16px; + } + li:hover{ + background-color: #f7f7f7; + } + } + .login_form{ + padding: 16px; + input[type="password"], input[type="text"]{ + width: 100%; + @include border-radius(5px); + } + .button_wrapper{ + .button{ + width: 45%; + display: inline-block; + } + } + .button{ + margin-top: 10px; + } + } +} \ No newline at end of file diff --git a/templates/main.php b/templates/main.php index d1f4da75..40af5798 100644 --- a/templates/main.php +++ b/templates/main.php @@ -14,6 +14,11 @@ script('passman', 'vendor/angular-touch/angular-touch.min'); script('passman', 'app/app'); script('passman', 'templates'); script('passman', 'app/controllers/main'); +script('passman', 'app/controllers/vault'); +script('passman', 'app/filters/propsfilter'); +script('passman', 'app/services/cacheservice'); +script('passman', 'app/services/vaultservice'); +script('passman', 'app/services/credentialservice'); /* @@ -22,8 +27,8 @@ script('passman', 'app/controllers/main'); style('passman', 'app'); ?> -
-
+
+
  • First level entry
  • diff --git a/templates/views/main.html b/templates/views/main.html deleted file mode 100644 index 6769dd60..00000000 --- a/templates/views/main.html +++ /dev/null @@ -1 +0,0 @@ -Hello world! \ No newline at end of file diff --git a/templates/views/vaults.html b/templates/views/vaults.html new file mode 100644 index 00000000..bd9e1848 --- /dev/null +++ b/templates/views/vaults.html @@ -0,0 +1,75 @@ +
    +
    +
    +
      +
    • + Create a new vault
    • +
    • +
      + +
      {{vault.name}}
      + + Created: {{vault.created * 1000 | date:'dd-MM-yyyy @ HH:mm:ss'}} + | + Last accessed: {{vault.last_access * 1000 | date:'dd-MM-yyyy @ HH:mm:ss'}} + +
      +
      +
    • +
    + +
    +
    + +
    + +
    + +
    +
    +
      +
    • Go back to vaults
    • +
    +
    + +
    + +
    \ No newline at end of file