summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.meteor/packages7
-rw-r--r--.meteor/versions16
-rw-r--r--client/components/boards/boardBody.jade44
-rw-r--r--client/components/boards/boardBody.js15
-rw-r--r--client/components/boards/boardHeader.jade12
-rw-r--r--client/components/boards/boardList.jade9
-rw-r--r--client/components/boards/router.js58
-rw-r--r--client/components/lists/main.js2
-rw-r--r--client/components/main/header.jade4
-rw-r--r--client/components/main/layouts.jade6
-rw-r--r--client/components/main/layouts.js5
-rw-r--r--client/components/main/router.js5
-rw-r--r--client/components/sidebar/sidebar.js2
-rw-r--r--client/components/sidebar/sidebarArchives.jade2
-rw-r--r--client/components/users/router.js15
-rw-r--r--client/config/accounts.js13
-rw-r--r--client/config/router.js97
-rw-r--r--client/lib/utils.js6
-rw-r--r--collections/boards.js2
-rw-r--r--collections/cards.js2
-rw-r--r--sandstorm.js12
-rw-r--r--server/publications/boards.js4
22 files changed, 139 insertions, 199 deletions
diff --git a/.meteor/packages b/.meteor/packages
index 5547ede0..11594a83 100644
--- a/.meteor/packages
+++ b/.meteor/packages
@@ -14,7 +14,7 @@ kenton:accounts-sandstorm
service-configuration
useraccounts:core
useraccounts:unstyled
-useraccounts:iron-routing
+useraccounts:flow-routing
# Compilers
mquandalle:jade
@@ -32,8 +32,11 @@ reywood:publish-composite
# Utilities
alethes:pages
+arillo:flow-router-helpers
audit-argument-checks
-iron:router
+kadira:blaze-layout
+kadira:flow-router
+meteorhacks:picker
meteorhacks:subs-manager
mquandalle:autofocus
mquandalle:bower
diff --git a/.meteor/versions b/.meteor/versions
index c60462d2..e9be382b 100644
--- a/.meteor/versions
+++ b/.meteor/versions
@@ -3,6 +3,7 @@ accounts-password@1.1.1
aldeed:collection2@2.3.3
aldeed:simple-schema@1.3.3
alethes:pages@1.8.4
+arillo:flow-router-helpers@0.4.3
audit-argument-checks@1.0.3
autoupdate@1.2.1
base64@1.0.3
@@ -30,6 +31,7 @@ cfs:upload-http@0.0.20
cfs:worker@0.1.4
check@1.0.5
coffeescript@1.0.6
+cosmos:browserify@0.5.0
dburles:collection-helpers@1.0.3
ddp@1.1.0
deps@1.0.7
@@ -43,16 +45,10 @@ htmljs@1.0.4
http@1.1.0
id-map@1.0.3
idmontie:migrations@1.0.0
-iron:controller@1.0.8
-iron:core@1.0.8
-iron:dynamic-template@1.0.8
-iron:layout@1.0.8
-iron:location@1.0.9
-iron:middleware-stack@1.0.9
-iron:router@1.0.9
-iron:url@1.0.9
jquery@1.11.3_2
json@1.0.3
+kadira:blaze-layout@2.0.0
+kadira:flow-router@2.3.0
kenton:accounts-sandstorm@0.1.4
launch-screen@1.0.2
less@1.0.14
@@ -65,6 +61,7 @@ meteor@1.1.6
meteor-platform@1.2.2
meteorhacks:aggregate@1.2.1
meteorhacks:collection-utils@1.2.0
+meteorhacks:picker@1.0.3
meteorhacks:subs-manager@1.5.2
meteorspark:util@0.2.0
minifiers@1.1.5
@@ -115,7 +112,8 @@ ui@1.0.6
underscore@1.0.3
url@1.0.4
useraccounts:core@1.12.2
-useraccounts:iron-routing@1.12.2
+useraccounts:flow-routing@1.12.2
useraccounts:unstyled@1.12.2
webapp@1.2.0
webapp-hashing@1.0.3
+zimme:active-route@2.3.1
diff --git a/client/components/boards/boardBody.jade b/client/components/boards/boardBody.jade
index 12fc0e36..3d6667ae 100644
--- a/client/components/boards/boardBody.jade
+++ b/client/components/boards/boardBody.jade
@@ -1,29 +1,25 @@
-//-
- XXX This template can't be transformed into a component because it is
- included by iron-router. That's a bug.
- See https://github.com/peerlibrary/meteor-blaze-components/issues/44
template(name="board")
- +boardComponent
-
-template(name="boardComponent")
- if this
- .board-wrapper(class=colorClass)
- .board-canvas(
- class=sidebarSize
- class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
- class="{{#if draggingActive.get}}is-dragging-active{{/if}}")
- if showOverlay.get
- .board-overlay
- .lists.js-lists
- each lists
- +list(this)
- if currentCardIsInThisList
- +cardDetails(currentCard)
- if currentUser.isBoardMember
- +addListForm
- +sidebar
+ if Template.subscriptionsReady
+ if currentBoard
+ .board-wrapper(class=currentBoard.colorClass)
+ .board-canvas(
+ class=currentBoard.sidebarSize
+ class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
+ class="{{#if draggingActive.get}}is-dragging-active{{/if}}")
+ if showOverlay.get
+ .board-overlay
+ .lists.js-lists
+ each currentBoard.lists
+ +list(this)
+ if currentCardIsInThisList
+ +cardDetails(currentCard)
+ if currentUser.isBoardMember
+ +addListForm
+ +sidebar
+ else
+ +message(label="board-no-found")
else
- +message(label="board-no-found")
+ +spinner
template(name="addListForm")
.list.js-list.list-composer.js-list-composer
diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js
index 876f2cd0..3757eff9 100644
--- a/client/components/boards/boardBody.js
+++ b/client/components/boards/boardBody.js
@@ -1,11 +1,17 @@
+var boardSubsManager = new SubsManager();
+
BlazeComponent.extendComponent({
template: function() {
- return 'boardComponent';
+ return 'board';
},
onCreated: function() {
this.draggingActive = new ReactiveVar(false);
this.showOverlay = new ReactiveVar(false);
+
+ // XXX The boardId should be readed from some sort the component "props",
+ // unfortunatly, Blaze doesn't have this notion.
+ boardSubsManager.subscribe('board', Session.get('currentBoard'));
},
openNewListForm: function() {
@@ -67,7 +73,7 @@ BlazeComponent.extendComponent({
}
};
- if (! Meteor.userId() || ! Meteor.user().isBoardMember())
+ if (! Meteor.user() || ! Meteor.user().isBoardMember())
return;
self.$(lists).sortable({
@@ -101,7 +107,8 @@ BlazeComponent.extendComponent({
// If there is no data in the board (ie, no lists) we autofocus the list
// creation form by clicking on the corresponding element.
- if (self.data().lists().count() === 0) {
+ var currentBoard = Boards.findOne(Session.get('currentBoard'));
+ if (currentBoard.lists().count() === 0) {
this.openNewListForm();
}
},
@@ -121,7 +128,7 @@ BlazeComponent.extendComponent({
}
}];
}
-}).register('boardComponent');
+}).register('board');
BlazeComponent.extendComponent({
template: function() {
diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade
index 3847cd93..9ec79227 100644
--- a/client/components/boards/boardHeader.jade
+++ b/client/components/boards/boardHeader.jade
@@ -1,20 +1,20 @@
template(name="headerBoard")
h1.header-board-menu
a(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}")
- = title
+ = currentBoard.title
.board-header-btns.left
unless isSandstorm
if currentUser
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
- title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
- i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
+ title="{{#if currentBoard.isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
+ i.fa(class="fa-star{{#unless currentBoard.isStarred}}-o{{/unless}}")
if showStarCounter
- span {{_ 'board-nb-stars' stars}}
+ span {{_ 'board-nb-stars' currentBoard.stars}}
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}")
- i.fa(class="{{#if isPublic}}fa-globe{{else}}fa-lock{{/if}}")
- span {{_ permission}}
+ i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
+ span {{_ currentBoard.permission}}
.board-header-btns.right
a.board-header-btn.js-open-filter-view(
diff --git a/client/components/boards/boardList.jade b/client/components/boards/boardList.jade
index e92cad2d..f0dc808f 100644
--- a/client/components/boards/boardList.jade
+++ b/client/components/boards/boardList.jade
@@ -1,16 +1,9 @@
-//-
- XXX This template can't be transformed into a component because it is
- included by iron-router. That's a bug.
- See https://github.com/peerlibrary/meteor-blaze-components/issues/44
-template(name="boards")
- +boardList
-
template(name="boardList")
if boards.count
ul.board-list.clearfix
each boards
li(class="{{#if isStarred}}starred{{/if}}" class=colorClass)
- a.js-open-board(href="{{ pathFor route='Board' boardId=_id }}")
+ a.js-open-board(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
span.board-list-item-name= title
i.fa.fa-star-o.js-star-board(
diff --git a/client/components/boards/router.js b/client/components/boards/router.js
deleted file mode 100644
index 1c485225..00000000
--- a/client/components/boards/router.js
+++ /dev/null
@@ -1,58 +0,0 @@
-Meteor.subscribe('boards');
-
-var boardSubsManager = new SubsManager();
-
-Router.route('/boards', {
- name: 'Boards',
- template: 'boards',
- authenticated: true,
- onBeforeAction: function() {
- Session.set('currentBoard', '');
- Filter.reset();
- this.next();
- }
-});
-
-Router.route('/boards/:_id/:slug', {
- name: 'Board',
- template: 'board',
- onAfterAction: function() {
- // XXX We probably shouldn't rely on Session
- Session.set('sidebarIsOpen', true);
- Session.set('menuWidgetIsOpen', false);
- },
- waitOn: function() {
- var params = this.params;
- Session.set('currentBoard', params._id);
- Session.set('currentCard', null);
-
- return boardSubsManager.subscribe('board', params._id, params.slug);
- },
- data: function() {
- return Boards.findOne(this.params._id);
- }
-});
-
-Router.route('/boards/:boardId/:slug/:cardId', {
- name: 'Card',
- template: 'board',
- noEscapeActions: true,
- onAfterAction: function() {
- Tracker.nonreactive(function() {
- if (! Session.get('currentCard') && Sidebar) {
- Sidebar.hide();
- }
- });
- EscapeActions.executeUpTo('popup');
- var params = this.params;
- Session.set('currentBoard', params.boardId);
- Session.set('currentCard', params.cardId);
- },
- waitOn: function() {
- var params = this.params;
- return boardSubsManager.subscribe('board', params.boardId, params.slug);
- },
- data: function() {
- return Boards.findOne(this.params.boardId);
- }
-});
diff --git a/client/components/lists/main.js b/client/components/lists/main.js
index c4e38c46..e6491f0a 100644
--- a/client/components/lists/main.js
+++ b/client/components/lists/main.js
@@ -21,7 +21,7 @@ BlazeComponent.extendComponent({
// comment below provides further details.
onRendered: function() {
var self = this;
- if (! Meteor.userId() || ! Meteor.user().isBoardMember())
+ if (! Meteor.user() || ! Meteor.user().isBoardMember())
return;
var boardComponent = self.componentParent();
diff --git a/client/components/main/header.jade b/client/components/main/header.jade
index 510ef484..1185da85 100644
--- a/client/components/main/header.jade
+++ b/client/components/main/header.jade
@@ -10,13 +10,13 @@ template(name="header")
#header-quick-access
ul
li
- +linkTo(route="Boards")
+ a(href="{{pathFor 'home'}}")
span.fa.fa-home
| All boards
each currentUser.starredBoards
li.separator -
li(class="{{#if $.Session.equals 'currentBoard' _id}}current{{/if}}")
- +linkTo(route="Board" data=this)
+ a(href="{{pathFor 'board' id=_id slug=slug}}")
= title
else
li.current Star a board to add a shortcut in this bar.
diff --git a/client/components/main/layouts.jade b/client/components/main/layouts.jade
index 8e6ae941..2dd3b2f2 100644
--- a/client/components/main/layouts.jade
+++ b/client/components/main/layouts.jade
@@ -8,15 +8,15 @@ template(name="userFormsLayout")
section.auth-layout
h1.at-form-landing-logo
img(src="/logo.png" title="LibreBoard")
- +yield
+ +Template.dynamic(template=content)
template(name="defaultLayout")
#surface
+header
#content
- +yield
+ +Template.dynamic(template=content)
-template(name="notfound")
+template(name="notFound")
+message(label='page-not-found')
template(name="message")
diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js
new file mode 100644
index 00000000..5dbd8c91
--- /dev/null
+++ b/client/components/main/layouts.js
@@ -0,0 +1,5 @@
+Meteor.subscribe('boards');
+
+Template.userFormsLayout.onRendered(function() {
+ EscapeActions.executeAll();
+});
diff --git a/client/components/main/router.js b/client/components/main/router.js
deleted file mode 100644
index bae832e8..00000000
--- a/client/components/main/router.js
+++ /dev/null
@@ -1,5 +0,0 @@
-Router.route('/', {
- name: 'Home',
- redirectLoggedInUsers: true,
- authenticated: true
-});
diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js
index e4937bec..701e176b 100644
--- a/client/components/sidebar/sidebar.js
+++ b/client/components/sidebar/sidebar.js
@@ -162,7 +162,7 @@ Template.labelsWidget.events({
// fields of the current board document.
var draggableMembersLabelsWidgets = function() {
var self = this;
- if (! Meteor.userId() || ! Meteor.user().isBoardMember())
+ if (! Meteor.user() || ! Meteor.user().isBoardMember())
return;
self.autorun(function() {
diff --git a/client/components/sidebar/sidebarArchives.jade b/client/components/sidebar/sidebarArchives.jade
index d2bd5d7b..2e42de6a 100644
--- a/client/components/sidebar/sidebarArchives.jade
+++ b/client/components/sidebar/sidebarArchives.jade
@@ -10,7 +10,7 @@ template(name="archivesSidebar")
| -
a.js-delete-card Delete
if cardIsInArchivedList
- p.quiet.small (warning: this card is in an archived list) <br>
+ p.quiet.small (warning: this card is in an archived list)
else
p.no-items-message No archived cards.
diff --git a/client/components/users/router.js b/client/components/users/router.js
deleted file mode 100644
index 955f0494..00000000
--- a/client/components/users/router.js
+++ /dev/null
@@ -1,15 +0,0 @@
-Router.route('/profile/:username', {
- name: 'Profile',
- template: 'profile',
- waitOn: function() {
- return Meteor.subscribe('profile', this.params.username);
- },
- data: function() {
- var params = this.params;
- return {
- profile: function() {
- return Users.findOne({ username: params.username });
- }
- };
- }
-});
diff --git a/client/config/accounts.js b/client/config/accounts.js
index e12dd8bc..3852e580 100644
--- a/client/config/accounts.js
+++ b/client/config/accounts.js
@@ -9,20 +9,25 @@ AccountsTemplates.addFields([{
}, emailField, passwordField]);
AccountsTemplates.configure({
+ defaultLayout: 'userFormsLayout',
+ defaultContentRegion: 'content',
confirmPassword: false,
enablePasswordChange: true,
sendVerificationEmail: true,
showForgotPasswordLink: true,
onLogoutHook: function() {
- Router.go('Home');
+ var homePage = 'home';
+ if (FlowRouter.getRouteName() === homePage) {
+ FlowRouter.reload();
+ } else {
+ FlowRouter.go(homePage);
+ }
}
});
_.each(['signIn', 'signUp', 'resetPwd', 'forgotPwd', 'enrollAccount'],
function(routeName) {
- AccountsTemplates.configureRoute(routeName, {
- layoutTemplate: 'userFormsLayout'
- });
+ AccountsTemplates.configureRoute(routeName);
});
// We display the form to change the password in a popup window that already
diff --git a/client/config/router.js b/client/config/router.js
index 97871e23..e251aea0 100644
--- a/client/config/router.js
+++ b/client/config/router.js
@@ -1,44 +1,57 @@
-// XXX Switch to Flow-Router?
-var previousRoute;
-
-Router.configure({
- loadingTemplate: 'spinner',
- notFoundTemplate: 'notfound',
- layoutTemplate: 'defaultLayout',
-
- onBeforeAction: function() {
- var options = this.route.options;
-
- var loggedIn = Tracker.nonreactive(function() {
- return !! Meteor.userId();
- });
-
- // Redirect logged in users to Boards view when they try to open Login or
- // signup views.
- if (loggedIn && options.redirectLoggedInUsers) {
- return this.redirect('Boards');
- }
-
- // Authenticated
- if (! loggedIn && options.authenticated) {
- return this.redirect('atSignIn');
- }
-
- // We want to execute our EscapeActions.executeUpTo method any time the
- // route is changed, but not if the stays the same but only the parameters
- // change (eg when a user is navigation from a card A to a card B). Iron-
- // Router onBeforeAction is a reactive context (which is a bad desig choice
- // as explained in
- // https://github.com/meteorhacks/flow-router#routercurrent-is-evil) so we
- // need to use Tracker.nonreactive
- Tracker.nonreactive(function() {
- if (! options.noEscapeActions &&
- ! (previousRoute && previousRoute.options.noEscapeActions))
- EscapeActions.executeAll();
- });
-
- previousRoute = this.route;
-
- this.next();
+FlowRouter.route('/', {
+ name: 'home',
+ triggersEnter: [AccountsTemplates.ensureSignedIn],
+ action: function() {
+ EscapeActions.executeAll();
+ Filter.reset();
+
+ Session.set('currentBoard', '');
+
+ BlazeLayout.render('defaultLayout', { content: 'boardList' });
+ }
+});
+
+FlowRouter.route('/b/:id/:slug', {
+ name: 'board',
+ action: function(params) {
+ EscapeActions.executeAll();
+
+ Session.set('currentBoard', params.id);
+ Session.set('currentCard', null);
+
+ BlazeLayout.render('defaultLayout', { content: 'board' });
+ }
+});
+
+FlowRouter.route('/b/:boardId/:slug/:cardId', {
+ name: 'card',
+ action: function(params) {
+ Session.set('currentBoard', params.boardId);
+ Session.set('currentCard', params.cardId);
+ EscapeActions.executeUpTo('popup');
+
+ BlazeLayout.render('defaultLayout', { content: 'board' });
+ }
+});
+
+FlowRouter.notFound = {
+ action: function() {
+ BlazeLayout.render('defaultLayout', { content: 'notFound' });
}
+}
+
+// We maintain a list of redirections to ensure that we don't break old URLs
+// when we change our routing scheme.
+var redirections = {
+ '/boards': '/',
+ '/boards/:id/:slug': '/b/:id/:slug',
+ '/boards/:id/:slug/:cardId': '/b/:id/:slug/:cardId'
+};
+
+_.each(redirections, function(newPath, oldPath) {
+ FlowRouter.route(oldPath, {
+ triggersEnter: [function(context, redirect) {
+ redirect(FlowRouter.path(newPath, context.params));
+ }]
+ });
});
diff --git a/client/lib/utils.js b/client/lib/utils.js
index 121b3c2b..c6a9adc5 100644
--- a/client/lib/utils.js
+++ b/client/lib/utils.js
@@ -2,8 +2,8 @@ Utils = {
// XXX We should remove these two methods
goBoardId: function(_id) {
var board = Boards.findOne(_id);
- return board && Router.go('Board', {
- _id: board._id,
+ return board && FlowRouter.go('board', {
+ id: board._id,
slug: board.slug
});
},
@@ -11,7 +11,7 @@ Utils = {
goCardId: function(_id) {
var card = Cards.findOne(_id);
var board = Boards.findOne(card.boardId);
- return board && Router.go('Card', {
+ return board && FlowRouter.go('card', {
cardId: card._id,
boardId: board._id,
slug: board.slug
diff --git a/collections/boards.js b/collections/boards.js
index d0507dc4..ade70466 100644
--- a/collections/boards.js
+++ b/collections/boards.js
@@ -131,7 +131,7 @@ Boards.helpers({
return Activities.find({ boardId: this._id }, { sort: { createdAt: -1 }});
},
absoluteUrl: function() {
- return Router.path('Board', { boardId: this._id, slug: this.slug });
+ return FlowRouter.path('board', { id: this._id, slug: this.slug });
},
colorClass: function() {
return 'board-color-' + this.color;
diff --git a/collections/cards.js b/collections/cards.js
index 92a3f618..d9f1bf6e 100644
--- a/collections/cards.js
+++ b/collections/cards.js
@@ -143,7 +143,7 @@ Cards.helpers({
},
absoluteUrl: function() {
var board = this.board();
- return Router.path('Card', {
+ return FlowRouter.path('card', {
boardId: board._id,
slug: board.slug,
cardId: this._id
diff --git a/sandstorm.js b/sandstorm.js
index b2b4d88b..d565df62 100644
--- a/sandstorm.js
+++ b/sandstorm.js
@@ -30,23 +30,23 @@ if (isSandstorm && Meteor.isServer) {
// Redirect the user to the hard-coded board. On the first launch the user
// will be redirected to the board before its creation. But that’s not a
// problem thanks to the reactive board publication. We used to do this
- // redirection on the client side but that was sometime visible on loading,
+ // redirection on the client side but that was sometimes visible on loading,
// and the home page was accessible by pressing the back button of the
// browser, a server-side redirection solves both of these issues.
//
// XXX Maybe sandstorm manifest could provide some kind of "home url"?
- Router.route('/', function() {
- var base = this.request.headers['x-sandstorm-base-path'];
+ Picker.route('/', function(params, request, response) {
+ var base = request.headers['x-sandstorm-base-path'];
// XXX If this routing scheme changes, this will break. We should generation
// the location url using the router, but at the time of writting, the
// router is only accessible on the client.
var path = '/boards/' + sandstormBoard._id + '/' + sandstormBoard.slug;
- this.response.writeHead(301, {
+ response.writeHead(301, {
Location: base + path
});
- this.response.end();
- }, { where: 'server' });
+ response.end();
+ });
// On the first launch of the instance a user is automatically created thanks
// to the `accounts-sandstorm` package. After its creation we insert the
diff --git a/server/publications/boards.js b/server/publications/boards.js
index 103e9080..15825952 100644
--- a/server/publications/boards.js
+++ b/server/publications/boards.js
@@ -30,14 +30,12 @@ Meteor.publish('boards', function() {
});
});
-Meteor.publishComposite('board', function(boardId, slug) {
+Meteor.publishComposite('board', function(boardId) {
check(boardId, String);
- check(slug, String);
return {
find: function() {
return Boards.find({
_id: boardId,
- slug: slug,
archived: false,
// If the board is not public the user has to be a member of it to see
// it.