From 548bbb5e1573f9615058a5883ee3bf1ef294f5a7 Mon Sep 17 00:00:00 2001
From: Markus Grigull
Date: Mon, 27 Jun 2016 23:22:05 +0200
Subject: [PATCH] Add project create, delete and store in user data
Change adapter and serializer to REST api.
Add session-user to get logged-in user in every controller/route
Change models to async relationships, this way the data is only loaded when
requested.
---
app/adapters/application.js | 9 ++++--
app/app.js | 4 +++
app/authenticators/custom.js | 4 +--
app/controllers/project/delete.js | 32 +++++++++++++++++++
app/controllers/project/new.js | 29 +++++++++++++++--
app/models/project.js | 6 ++--
app/models/user.js | 6 ++--
app/routes/application.js | 18 +++++++++++
app/routes/login.js | 3 +-
app/routes/project/delete.js | 6 +++-
app/routes/project/edit.js | 3 +-
app/routes/project/new.js | 3 +-
app/routes/projects.js | 8 ++++-
app/serializers/application.js | 5 +--
app/serializers/project.js | 7 ++++
app/serializers/user.js | 7 ++++
app/services/session-user.js | 25 +++++++++++++++
app/templates/project/delete.hbs | 5 +++
app/templates/project/index.hbs | 4 +--
app/templates/project/new.hbs | 1 +
tests/unit/controllers/project/delete-test.js | 12 +++++++
tests/unit/serializers/project-test.js | 15 +++++++++
tests/unit/serializers/user-test.js | 15 +++++++++
tests/unit/services/session-user-test.js | 12 +++++++
24 files changed, 217 insertions(+), 22 deletions(-)
create mode 100644 app/controllers/project/delete.js
create mode 100644 app/serializers/project.js
create mode 100644 app/serializers/user.js
create mode 100644 app/services/session-user.js
create mode 100644 tests/unit/controllers/project/delete-test.js
create mode 100644 tests/unit/serializers/project-test.js
create mode 100644 tests/unit/serializers/user-test.js
create mode 100644 tests/unit/services/session-user-test.js
diff --git a/app/adapters/application.js b/app/adapters/application.js
index 615bbc0..b24b25b 100644
--- a/app/adapters/application.js
+++ b/app/adapters/application.js
@@ -1,8 +1,11 @@
-import JSONAPIAdapter from 'ember-data/adapters/json-api';
+import RESTAdapter from 'ember-data/adapters/rest';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
-export default JSONAPIAdapter.extend(DataAdapterMixin, {
+export default RESTAdapter.extend(DataAdapterMixin, {
host: 'http://192.168.99.100:3000',
namespace: 'api/v1',
- authorizer: 'authorizer:custom'
+ authorizer: 'authorizer:custom',
+ headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
+
+
});
diff --git a/app/app.js b/app/app.js
index 831ad61..7266b19 100644
--- a/app/app.js
+++ b/app/app.js
@@ -13,6 +13,10 @@ App = Ember.Application.extend({
Resolver
});
+Ember.RSVP.on('error', function(error) {
+ console.error(error.message);
+});
+
loadInitializers(App, config.modulePrefix);
export default App;
diff --git a/app/authenticators/custom.js b/app/authenticators/custom.js
index 5a05fe9..54c6edf 100644
--- a/app/authenticators/custom.js
+++ b/app/authenticators/custom.js
@@ -32,9 +32,9 @@ export default Base.extend({
});
});
}, function(xhr) {
- var response = xhr.responseText;
+ var response = JSON.parse(xhr.responseText);
Ember.run(function() {
- reject(response);
+ reject(response.message);
});
});
});
diff --git a/app/controllers/project/delete.js b/app/controllers/project/delete.js
new file mode 100644
index 0000000..498cd53
--- /dev/null
+++ b/app/controllers/project/delete.js
@@ -0,0 +1,32 @@
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+ sessionUser: Ember.inject.service('session-user'),
+
+ actions: {
+ cancelDelete() {
+ // go back to project view
+ let projectId = this.get('model.id');
+ this.transitionToRoute('/project/' + projectId);
+ },
+
+ confirmDelete() {
+ // get current user object
+ var userId = this.get('sessionUser.user.id');
+ var user = this.store.peekRecord('user', userId);
+
+ // get the project
+ var project = this.get('model');
+ let projectId = project.get('id');
+
+ // delete the project and remove from user projects
+ user.get('projects').removeObject(projectId);
+ user.save();
+
+ project.destroyRecord();
+
+ // go back to project list
+ this.transitionToRoute('/projects');
+ }
+ }
+});
diff --git a/app/controllers/project/new.js b/app/controllers/project/new.js
index 20ff394..01229ab 100644
--- a/app/controllers/project/new.js
+++ b/app/controllers/project/new.js
@@ -1,11 +1,36 @@
import Ember from 'ember';
export default Ember.Controller.extend({
+ sessionUser: Ember.inject.service('session-user'),
+
actions: {
newProject() {
- // create project from form values
- let properties = this.getProperties('name');
+ // get current user object
+ var userId = this.get('sessionUser.user.id');
+ var user = this.store.peekRecord('user', userId);
+
+ // create new project from properties
+ var properties = this.getProperties('name');
+ properties['owner'] = user;
+
var project = this.store.createRecord('project', properties);
+ var controller = this;
+
+ // save the project and user
+ project.save().then(function() {
+ console.log(project.get('id'));
+
+ // add the project to the user
+ user.get('projects').pushObject(project);
+
+ user.save().then(function() {
+ controller.transitionToRoute('/projects');
+ });
+ });
+ },
+
+ cancelNewProject() {
+ this.transitionToRoute('/projects');
}
}
});
diff --git a/app/models/project.js b/app/models/project.js
index 986980a..377d618 100644
--- a/app/models/project.js
+++ b/app/models/project.js
@@ -1,8 +1,8 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
-import belongsTo from 'ember-data/relationships';
+import { belongsTo } from 'ember-data/relationships';
export default Model.extend({
- name: attr('string')/*,
- owner: belongsTo('user')*/
+ name: attr('string'),
+ owner: belongsTo('user', { async: true })
});
diff --git a/app/models/user.js b/app/models/user.js
index 3af5105..e028eff 100644
--- a/app/models/user.js
+++ b/app/models/user.js
@@ -1,10 +1,10 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
-import hasMany from 'ember-data/relationships';
+import { hasMany } from 'ember-data/relationships';
export default Model.extend({
username: attr('string'),
password: attr('string'),
- adminLevel: attr('number')/*,
- projects: hasMany('project')*/
+ adminLevel: attr('number'),
+ projects: hasMany('project', { async: true })
});
diff --git a/app/routes/application.js b/app/routes/application.js
index 4891b23..49d79a7 100644
--- a/app/routes/application.js
+++ b/app/routes/application.js
@@ -1,7 +1,25 @@
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
+const { service } = Ember.inject;
+
export default Ember.Route.extend(ApplicationRouteMixin, {
+ sessionUser: service('session-user'),
+
+ beforeModel() {
+ return this._loadCurrentUser();
+ },
+
+ sessionAuthenticated() {
+ this._loadCurrentUser().then(() => {
+ this.transitionTo('/');
+ }).catch(() => this.get('session').invalidate());
+ },
+
+ _loadCurrentUser() {
+ return this.get('sessionUser').loadCurrentUser();
+ },
+
actions: {
invalidateSession() {
this.get('session').invalidate();
diff --git a/app/routes/login.js b/app/routes/login.js
index 26d9f31..29e193c 100644
--- a/app/routes/login.js
+++ b/app/routes/login.js
@@ -1,4 +1,5 @@
import Ember from 'ember';
+import UnauthenticatedRouteMixin from 'ember-simple-auth/mixins/unauthenticated-route-mixin';
-export default Ember.Route.extend({
+export default Ember.Route.extend(UnauthenticatedRouteMixin, {
});
diff --git a/app/routes/project/delete.js b/app/routes/project/delete.js
index 26d9f31..b603665 100644
--- a/app/routes/project/delete.js
+++ b/app/routes/project/delete.js
@@ -1,4 +1,8 @@
import Ember from 'ember';
+import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
-export default Ember.Route.extend({
+export default Ember.Route.extend(AuthenticatedRouteMixin, {
+ model(params) {
+ return this.store.findRecord('project', params.projectid);
+ }
});
diff --git a/app/routes/project/edit.js b/app/routes/project/edit.js
index 26d9f31..30e4e30 100644
--- a/app/routes/project/edit.js
+++ b/app/routes/project/edit.js
@@ -1,4 +1,5 @@
import Ember from 'ember';
+import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
-export default Ember.Route.extend({
+export default Ember.Route.extend(AuthenticatedRouteMixin, {
});
diff --git a/app/routes/project/new.js b/app/routes/project/new.js
index 26d9f31..30e4e30 100644
--- a/app/routes/project/new.js
+++ b/app/routes/project/new.js
@@ -1,4 +1,5 @@
import Ember from 'ember';
+import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
-export default Ember.Route.extend({
+export default Ember.Route.extend(AuthenticatedRouteMixin, {
});
diff --git a/app/routes/projects.js b/app/routes/projects.js
index ce96e88..c992c7d 100644
--- a/app/routes/projects.js
+++ b/app/routes/projects.js
@@ -2,7 +2,13 @@ import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
+ sessionUser: Ember.inject.service('session-user'),
+
model() {
- return this.store.findAll('project');
+ // get session user
+ var userId = this.get('sessionUser.user.id');
+ let user = this.store.peekRecord('user', userId);
+
+ return user.get('projects');
}
});
diff --git a/app/serializers/application.js b/app/serializers/application.js
index 8c80d9f..74ca08f 100644
--- a/app/serializers/application.js
+++ b/app/serializers/application.js
@@ -1,5 +1,6 @@
-import JSONSerializer from 'ember-data/serializers/json';
+import RESTSerializer from 'ember-data/serializers/rest';
+import DS from 'ember-data';
-export default JSONSerializer.extend({
+export default RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
primaryKey: '_id'
});
diff --git a/app/serializers/project.js b/app/serializers/project.js
new file mode 100644
index 0000000..cf2bb44
--- /dev/null
+++ b/app/serializers/project.js
@@ -0,0 +1,7 @@
+import ApplicationSerializer from './application';
+
+export default ApplicationSerializer.extend({
+ attrs: {
+ owner: { serialize: 'ids' }
+ }
+});
diff --git a/app/serializers/user.js b/app/serializers/user.js
new file mode 100644
index 0000000..9bdf029
--- /dev/null
+++ b/app/serializers/user.js
@@ -0,0 +1,7 @@
+import ApplicationSerializer from './application';
+
+export default ApplicationSerializer.extend({
+ attrs: {
+ projects: { serialize: 'ids' }
+ }
+});
diff --git a/app/services/session-user.js b/app/services/session-user.js
new file mode 100644
index 0000000..86d4cd7
--- /dev/null
+++ b/app/services/session-user.js
@@ -0,0 +1,25 @@
+import Ember from 'ember';
+
+const {
+ inject: { service },
+ RSVP
+} = Ember;
+
+export default Ember.Service.extend({
+ session: service('session'),
+ store: service(),
+
+ loadCurrentUser() {
+ return new RSVP.Promise((resolve, reject) => {
+ const token = this.get('session.data.authenticated.token');
+ if (!Ember.isEmpty(token)) {
+ return this.get('store').findRecord('user', 'me').then((user) => {
+ this.set('user', user);
+ resolve();
+ }, reject);
+ } else {
+ resolve();
+ }
+ });
+ }
+});
diff --git a/app/templates/project/delete.hbs b/app/templates/project/delete.hbs
index b797135..2aa92ae 100644
--- a/app/templates/project/delete.hbs
+++ b/app/templates/project/delete.hbs
@@ -1 +1,6 @@
Delete Project
+
+Are you sure you want to delete the project?
+
+Cancel
+Delete
diff --git a/app/templates/project/index.hbs b/app/templates/project/index.hbs
index aa24e7a..24f0c61 100644
--- a/app/templates/project/index.hbs
+++ b/app/templates/project/index.hbs
@@ -1,4 +1,4 @@
{{model.name}}
-{{#link-to "project.edit" model}}Edit project{{/link-to}}
-{{#link-to "project.delete" model}}Delete project{{/link-to}}
+{{#link-to "project.edit" model.id}}Edit project{{/link-to}}
+{{#link-to "project.delete" model.id}}Delete project{{/link-to}}
diff --git a/app/templates/project/new.hbs b/app/templates/project/new.hbs
index ac591bb..e4989cb 100644
--- a/app/templates/project/new.hbs
+++ b/app/templates/project/new.hbs
@@ -7,6 +7,7 @@
{{input id='name' placeholder='Enter project name' value=name}}
+ Cancel
Create
{{#if errorMessage}}
diff --git a/tests/unit/controllers/project/delete-test.js b/tests/unit/controllers/project/delete-test.js
new file mode 100644
index 0000000..8b10820
--- /dev/null
+++ b/tests/unit/controllers/project/delete-test.js
@@ -0,0 +1,12 @@
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:project/delete', 'Unit | Controller | project/delete', {
+ // Specify the other units that are required for this test.
+ // needs: ['controller:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+ let controller = this.subject();
+ assert.ok(controller);
+});
diff --git a/tests/unit/serializers/project-test.js b/tests/unit/serializers/project-test.js
new file mode 100644
index 0000000..f0131a1
--- /dev/null
+++ b/tests/unit/serializers/project-test.js
@@ -0,0 +1,15 @@
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('project', 'Unit | Serializer | project', {
+ // Specify the other units that are required for this test.
+ needs: ['serializer:project']
+});
+
+// Replace this with your real tests.
+test('it serializes records', function(assert) {
+ let record = this.subject();
+
+ let serializedRecord = record.serialize();
+
+ assert.ok(serializedRecord);
+});
diff --git a/tests/unit/serializers/user-test.js b/tests/unit/serializers/user-test.js
new file mode 100644
index 0000000..19e4a38
--- /dev/null
+++ b/tests/unit/serializers/user-test.js
@@ -0,0 +1,15 @@
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('user', 'Unit | Serializer | user', {
+ // Specify the other units that are required for this test.
+ needs: ['serializer:user']
+});
+
+// Replace this with your real tests.
+test('it serializes records', function(assert) {
+ let record = this.subject();
+
+ let serializedRecord = record.serialize();
+
+ assert.ok(serializedRecord);
+});
diff --git a/tests/unit/services/session-user-test.js b/tests/unit/services/session-user-test.js
new file mode 100644
index 0000000..230acec
--- /dev/null
+++ b/tests/unit/services/session-user-test.js
@@ -0,0 +1,12 @@
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('service:session-user', 'Unit | Service | session user', {
+ // Specify the other units that are required for this test.
+ // needs: ['service:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+ let service = this.subject();
+ assert.ok(service);
+});