diff --git a/bower.json b/bower.json index 369998a..dba0329 100644 --- a/bower.json +++ b/bower.json @@ -1,28 +1,30 @@ { "name": "manticore", "version": "0.0.0", "dependencies": { "angular": "1.4.1", "json3": "3.3.1", "es5-shim": "4.1.7", "jquery": "1.11.0", "bootstrap": "~3.1.1", "angular-resource": "1.4.1", "angular-cookies": "1.4.1", "angular-sanitize": "1.4.1", "angular-bootstrap": "0.13.0", "font-awesome": ">=4.1.0", "lodash": "3.9.3", "angular-ui-router": "0.2.15", "angular-file-upload": "1.1.5", "wodo": "http://webodf.org/download/wodocollabtexteditor-0.5.8.preview1.zip", - "angular-file-saver": "~0.0.4" + "angular-file-saver": "~0.0.4", + "angular-smart-table": "~2.1.0", + "angular-moment": "~0.10.1" }, "devDependencies": { "angular-mocks": "1.4.1", "angular-scenario": "1.4.1" }, "resolutions": { "angular": "1.4.1" } } diff --git a/client/app/app.js b/client/app/app.js index 5149bbb..8424b71 100644 --- a/client/app/app.js +++ b/client/app/app.js @@ -1,55 +1,57 @@ 'use strict'; angular.module('manticoreApp', [ 'ngCookies', 'ngResource', 'ngSanitize', 'ui.router', 'ui.bootstrap', 'angularFileUpload', - 'fileSaver' + 'fileSaver', + 'smart-table', + 'angularMoment' ]) .config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) { $urlRouterProvider .otherwise('/'); $locationProvider.html5Mode(true); $httpProvider.interceptors.push('authInterceptor'); }) .factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) { return { // Add authorization token to headers request: function (config) { config.headers = config.headers || {}; if ($cookieStore.get('token')) { config.headers.Authorization = 'Bearer ' + $cookieStore.get('token'); } return config; }, // Intercept 401s and redirect you to login responseError: function(response) { if(response.status === 401) { $location.path('/login'); // remove any stale tokens $cookieStore.remove('token'); return $q.reject(response); } else { return $q.reject(response); } } }; }) .run(function ($rootScope, $location, Auth) { // Redirect to login if route requires auth and you're not logged in $rootScope.$on('$stateChangeStart', function (event, next) { Auth.isLoggedInAsync(function(loggedIn) { if (next.authenticate && !loggedIn) { $location.path('/login'); } }); }); }); diff --git a/client/app/app.styl b/client/app/app.styl index 3337e56..e170c9c 100644 --- a/client/app/app.styl +++ b/client/app/app.styl @@ -1,51 +1,56 @@ @import "font-awesome/css/font-awesome.css" @import "bootstrap/dist/css/bootstrap.css" // // Bootstrap Fonts // @font-face font-family: 'Glyphicons Halflings' src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot') src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); // // Font Awesome Fonts // @font-face font-family: 'FontAwesome' src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?v=4.1.0') src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../bower_components/font-awesome/fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../bower_components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../bower_components/font-awesome/fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg'); font-weight: normal font-style: normal // // App-wide Styles // .browsehappy background #ccc color #000 margin 0.2em 0 padding 0.2em 0 +body + background-color whitesmoke + // Component styles are injected through grunt // injector @import 'account/login/login.styl'; @import 'admin/admin.styl'; @import 'editor/editor.styl'; @import 'main/main.styl'; +@import 'documentList/documentList.styl'; @import 'exportButton/exportButton.styl'; @import 'import/import.styl'; @import 'modal/modal.styl'; +@import 'navbar/navbar.styl'; @import 'titleEditor/titleEditor.styl'; @import 'wodo/editor.styl'; // endinjector diff --git a/client/app/editor/editor.styl b/client/app/editor/editor.styl index e6c6f8b..f85ee8e 100644 --- a/client/app/editor/editor.styl +++ b/client/app/editor/editor.styl @@ -1,13 +1,17 @@ .toolbar border none + background-color white + height 50px + .toolbar-item - display: inline-block; - height: 50px; - float: left; + display inline-block + height 50px + float left #wodoContainer width 100% height calc(100% - 50px) top 50px padding 0 position absolute + background-color white diff --git a/client/app/main/main.controller.js b/client/app/main/main.controller.js index f38ffcd..726afbc 100644 --- a/client/app/main/main.controller.js +++ b/client/app/main/main.controller.js @@ -1,26 +1,6 @@ 'use strict'; angular.module('manticoreApp') .controller('MainCtrl', function ($scope, $http, Auth) { - $scope.documents = []; $scope.isLoggedIn = Auth.isLoggedIn; - - if ($scope.isLoggedIn()) { - $http.get('/api/documents').success(function(documents) { - $scope.documents = documents; - }); - } - - $scope.openDocument = function (document) { - $http.get('/api/documents/snapshot/' + _.last(document.chunks)) - .success(function (data) { - - }).error(function (data) { - console.log(data); - }) - }; - - $scope.deleteDocument = function(document) { - $http.delete('/api/documents/' + document._id); - }; }); diff --git a/client/app/main/main.jade b/client/app/main/main.jade index 485cf88..b328ec9 100644 --- a/client/app/main/main.jade +++ b/client/app/main/main.jade @@ -1,23 +1,16 @@ div(ng-include='"components/navbar/navbar.html"') -header#banner.hero-unit(ng-hide='isLoggedIn() ') +header#banner.hero-unit(ng-if='!isLoggedIn()') .container h1 Manticore p.lead Realtime collaboration for rich office documents. img(src='assets/images/manticore.jpg', alt='Manticore') -.container(ng-hide='!isLoggedIn()') - .row - .col-lg-12 - h1.page-header Documents - ul.col-md-4.col-lg-4.col-sm-6(ng-repeat='document in documents') - li - a(ui-sref='editor({id: document._id})') - | {{document.title}} +document-list(ng-if='isLoggedIn()') //- footer.footer .container p | Manticore = ' | ' a(href='https://github.com/adityab/Manticure/issues?state=open') Issues diff --git a/client/components/documentList/documentList.controller.js b/client/components/documentList/documentList.controller.js new file mode 100644 index 0000000..c429359 --- /dev/null +++ b/client/components/documentList/documentList.controller.js @@ -0,0 +1,9 @@ +'use strict'; + +angular.module('manticoreApp') +.controller('DocumentListCtrl', function ($scope, $http) { + $scope.displayedDocuments = []; + $http.get('/api/documents').success(function (documents) { + $scope.documents = documents; + }); +}); diff --git a/client/components/documentList/documentList.controller.spec.js b/client/components/documentList/documentList.controller.spec.js new file mode 100644 index 0000000..e41d6e3 --- /dev/null +++ b/client/components/documentList/documentList.controller.spec.js @@ -0,0 +1,21 @@ +'use strict'; + +describe('Controller: DocumentListCtrl', function () { + + // load the controller's module + beforeEach(module('manticoreApp')); + + var DocumentListCtrl, scope; + + // Initialize the controller and a mock scope + beforeEach(inject(function ($controller, $rootScope) { + scope = $rootScope.$new(); + DocumentListCtrl = $controller('DocumentListCtrl', { + $scope: scope + }); + })); + + it('should ...', function () { + expect(1).toEqual(1); + }); +}); diff --git a/client/components/documentList/documentList.directive.js b/client/components/documentList/documentList.directive.js new file mode 100644 index 0000000..045c196 --- /dev/null +++ b/client/components/documentList/documentList.directive.js @@ -0,0 +1,10 @@ +'use strict'; + +angular.module('manticoreApp') + .directive('documentList', function () { + return { + templateUrl: 'components/documentList/documentList.html', + restrict: 'E', + controller: 'DocumentListCtrl' + }; + }); diff --git a/client/components/documentList/documentList.jade b/client/components/documentList/documentList.jade new file mode 100644 index 0000000..342b4bf --- /dev/null +++ b/client/components/documentList/documentList.jade @@ -0,0 +1,16 @@ +.container + .no-docs(ng-if='!documents.length') + p.advice No documents yet. Why not add some? + .document-list(ng-if='documents.length') + table.table.table-striped(st-table='displayedDocuments' st-safe-src='documents') + thead + tr + th Title + th Creator + th(st-sort='date' st-sort-default='reverse') Updated + tbody + tr(ng-repeat='document in displayedDocuments') + td.title + a(ui-sref='editor({id: document._id})' target='_blank') {{document.title}} + td {{document.creator.name}} + td {{document.date | amCalendar}} diff --git a/client/components/documentList/documentList.styl b/client/components/documentList/documentList.styl new file mode 100644 index 0000000..0beedd4 --- /dev/null +++ b/client/components/documentList/documentList.styl @@ -0,0 +1,22 @@ +.advice + text-align center +.document-list + height 100% + padding 0 + table + margin 0 + thead + background-color none + tr + th + padding 12px + tbody + border 1px solid lightgray + tr + td + color gray + background-color white !important + padding 12px + &.title a + font-weight bold + color black !important diff --git a/client/components/navbar/navbar.styl b/client/components/navbar/navbar.styl new file mode 100644 index 0000000..d6bd3cc --- /dev/null +++ b/client/components/navbar/navbar.styl @@ -0,0 +1,8 @@ +.navbar-default + background-color maroon +.navbar + & p, & a + color white !important + & li.active, & li.open + a + background-color #4C1313 !important diff --git a/client/index.html b/client/index.html index 8782027..1a25fcc 100644 --- a/client/index.html +++ b/client/index.html @@ -1,82 +1,87 @@