Commit 9196acfe authored by Bertrand PINEL's avatar Bertrand PINEL
Browse files

add sample application with todo + handling of S3 storage

parent 79c5f91b
......@@ -6,6 +6,8 @@ It also guide you to set up a JSON-API server on top of AWS API Gateway, Lambda
It could also be seen as a starter for setting up Mirage, allowing the developper to build a full working application (using mock data) entirely running on the client. Once the development is over, the persistance can be delegated to an AWS API Gateway using a lambda function storing objects in DynamoDB.
Complete code is available at https://gitlab.ippon.fr/bpinel/ember-aws-ehipster
Installation
------------------------------------------------------------------------------
......
export { default } from 'ember-aws-ehipster/adapters/application';
......@@ -51,7 +51,7 @@ module.exports = {
'\t\t\t\tlabel: "col-form-label",\n\t\t\t\thelp: "small form-text text-danger",'+
'\n\t\t\t\thint: "small form-text text-muted",\n\t\t\t\tcheckbox: "checkbox",\n\t\t\t\tbutton: "btn btn-default",'+
'\n\t\t\t\tsubmit: "btn btn-primary",\n\t\t\t\tloading: "loading",\n\t\t\t\tvalid: "is-valid",'+
'\n\t\t\t\terror: "is-invalid"\n\t\t\t}\n\t\t},\n';
'\n\t\t\t\terror: "is-invalid"\n\t\t\t}\n\t\t},\n\t\tgatewayURL: "",\n';
addLineToFile(this, configPath, /let ENV = {/, validatedFormConfig);
// Add import of ember_aws_ehipster.css to apps.css
......
import DS from 'ember-data';
import config from '../config/environment';
export default DS.JSONAPIAdapter.extend({
headers: {
"Content-Type": "application/json; charset=utf-8"
}
});
},
host: config.gatewayURL
});
\ No newline at end of file
entity User {
login String required minlength(4),
passwordHash String required minlength(8),
firstName String,
lastName String,
email String,
imageUrl String,
activated Boolean,
createdBy String,
createdDate LocalDate,
lastModifiedBy String,
lastModifiedDate Instant
}
entity Authority {
name String required
}
entity Todo {
title String required,
completed Boolean
}
relationship ManyToMany {
User{user(login)} to Authority{authority(name)}
}
relationship OneToMany {
User{user(login)} to Todo{todo}
}
entity User {
login String required,
passwordHash String required minlength(8),
firstName String,
lastName String,
email String,
imageUrl String,
activated Boolean,
createdBy String,
createdDate LocalDate,
lastModifiedBy String,
lastModifiedDate Instant
}
entity Authority {
name String required
}
relationship ManyToMany {
User{user(id)} to Authority{authorityName}
}
export default function(server) {
}
{
"name": "ember-aws-ehipster",
"version": "0.3.26",
"version": "0.4.3",
"description": "Attempt to build a complete web application using serverless architecture on AWS",
"keywords": [
"ember-addon",
......
import Ember from 'ember';
export default Ember.Component.extend({
store: Ember.inject.service(),
tagName: 'li',
editing: false,
classNameBindings: ['todo.completed', 'editing'],
actions: {
startEditing() {
this.get('onStartEdit')();
this.set('editing', true);
Ember.run.scheduleOnce('afterRender', this, 'focusInput');
},
doneEditing(todoTitle) {
if (!this.get('editing')) { return; }
if (Ember.isBlank(todoTitle)) {
this.send('removeTodo');
} else {
this.set('todo.title', todoTitle.trim());
this.set('editing', false);
this.get('onEndEdit')();
this.get('todo').save();
}
},
handleKeydown(e) {
if (e.keyCode === 13) {
e.target.blur();
} else if (e.keyCode === 27) {
this.set('editing', false);
}
},
toggleCompleted(e) {
let todo = this.get('todo');
Ember.set(todo, 'completed', e.target.checked);
todo.save();
},
removeTodo() {
this.get('store').deleteRecord(this.get('todo'));
}
},
focusInput() {
this.element.querySelector('input.edit').focus();
}
});
import Ember from 'ember';
export default Ember.Component.extend({
store: Ember.inject.service(),
tagName: 'section',
elementId: 'main',
canToggle: true,
allCompleted: Ember.computed('todos.@each.completed', function () {
return this.get('todos').isEvery('completed');
}),
actions: {
enableToggle() {
this.set('canToggle', true);
},
disableToggle() {
this.set('canToggle', false);
},
toggleAll() {
let allCompleted = this.get('allCompleted');
this.get('todos').forEach(todo => Ember.set(todo, 'completed', !allCompleted));
this.get('store').save();
}
}
});
import Controller from '@ember/controller';
import { computed } from '@ember/object';
export default Controller.extend({
todos: computed.filterBy('model', 'completed', false)
});
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { isBlank } from '@ember/utils';
export default Controller.extend({
remaining: computed.filterBy('model', 'completed', false),
completed: computed.filterBy('model', 'completed'),
actions: {
createTodo(e) {
if (e.keyCode === 13 && !isBlank(e.target.value)) {
let newEntity = this.store.createRecord('todo',{ title: e.target.value.trim(), completed: false });
newEntity.save().then(() => { e.target.value = ''; });
}
},
clearCompleted() {
this.get('completed').forEach((record) => record.destroyRecord());
}
}
});
import Controller from '@ember/controller';
import { computed } from '@ember/object';
export default Controller.extend({
todos: computed.filterBy('model', 'completed', true)
});
import Controller from '@ember/controller';
export default Controller.extend({
entities: [
'todo',
'authority',
'user',
],
entity: '',
actions: {
selectEntity(entity) {
this.set('entity', entity);
this.transitionToRoute('entity-factory.'+entity);
}
}
});
\ No newline at end of file
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { A } from '@ember/array';
import EmberObject from '@ember/object';
import AuthorityValidations from "../../validations/authority";
import { task } from "ember-concurrency";
export default Controller.extend({
isAddingEntry: false,
newEntry: EmberObject.create({name: '',users: []}),
AuthorityValidations,
userList: computed('users', function() {
this.store.findAll('user');
}),
name: null,
users: null,
authorityTableColumns: computed(function() {
var col = A([
EmberObject.create({
propertyName: "name",
title: "name"
})]);
col.pushObject({
title: 'Delete',
component: 'delete-row'
});
return col; }),
authorityTableContent: computed(function() {
return this.get('authorities');
}),
actions: {
submit() {
console.log("action submit");
},
deleteRecord (record) {
console.log('record is '+ record);
record.destroyRecord();
}
},
submitEntry: task(function*(model) {
yield model.save();
let newEntity = this.store.createRecord('authority',yield model.get('data'));
yield newEntity.save();
console.log("new entry of id "+newEntity.get('id')+" created");
this.set('addEntryModal', false);
})
});
\ No newline at end of file
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { A } from '@ember/array';
import EmberObject from '@ember/object';
import TodoValidations from "../../validations/todo";
import { task } from "ember-concurrency";
export default Controller.extend({
isAddingEntry: false,
newEntry: EmberObject.create({title: '',completed: 'false',user: []}),
TodoValidations,
userList: computed('user', function() {
this.store.findAll('user');
}),
title: null,
completed: null,
user: null,
todoTableColumns: computed(function() {
var col = A([
EmberObject.create({
propertyName: "title",
title: "title"
}),
EmberObject.create({
propertyName: "completed",
title: "completed"
})]);
col.pushObject({
title: 'Delete',
component: 'delete-row'
});
return col; }),
todoTableContent: computed(function() {
return this.get('todos');
}),
actions: {
submit() {
console.log("action submit");
},
deleteRecord (record) {
console.log('record is '+ record);
record.destroyRecord();
}
},
submitEntry: task(function*(model) {
yield model.save();
let newEntity = this.store.createRecord('todo',yield model.get('data'));
yield newEntity.save();
console.log("new entry of id "+newEntity.get('id')+" created");
this.set('addEntryModal', false);
})
});
\ No newline at end of file
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { A } from '@ember/array';
import EmberObject from '@ember/object';
import UserValidations from "../../validations/user";
import { task } from "ember-concurrency";
export default Controller.extend({
isAddingEntry: false,
newEntry: EmberObject.create({login: '',passwordHash: '',firstName: '',lastName: '',email: '',imageUrl: '',activated: 'false',createdBy: '',createdDate: new Date(),lastModifiedBy: '',lastModifiedDate: new Date(),authorities: [],todos: []}),
UserValidations,
authorityList: computed('authorities', function() {
this.store.findAll('authority');
}),
todoList: computed('todos', function() {
this.store.findAll('todo');
}),
login: null,
passwordHash: null,
firstName: null,
lastName: null,
email: null,
imageUrl: null,
activated: null,
createdBy: null,
createdDate: null,
lastModifiedBy: null,
lastModifiedDate: null,
authorities: null,
todos: null,
userTableColumns: computed(function() {
var col = A([
EmberObject.create({
propertyName: "login",
title: "login"
}),
EmberObject.create({
propertyName: "passwordHash",
title: "passwordHash"
}),
EmberObject.create({
propertyName: "firstName",
title: "firstName"
}),
EmberObject.create({
propertyName: "lastName",
title: "lastName"
}),
EmberObject.create({
propertyName: "email",
title: "email"
}),
EmberObject.create({
propertyName: "imageUrl",
title: "imageUrl"
}),
EmberObject.create({
propertyName: "activated",
title: "activated"
}),
EmberObject.create({
propertyName: "createdBy",
title: "createdBy"
}),
EmberObject.create({
propertyName: "createdDate",
title: "createdDate"
}),
EmberObject.create({
propertyName: "lastModifiedBy",
title: "lastModifiedBy"
}),
EmberObject.create({
propertyName: "lastModifiedDate",
title: "lastModifiedDate"
})]);
col.pushObject({
title: 'Delete',
component: 'delete-row'
});
return col; }),
userTableContent: computed(function() {
return this.get('users');
}),
actions: {
submit() {
console.log("action submit");
},
deleteRecord (record) {
console.log('record is '+ record);
record.destroyRecord();
}
},
submitEntry: task(function*(model) {
yield model.save();
let newEntity = this.store.createRecord('user',yield model.get('data'));
yield newEntity.save();
console.log("new entry of id "+newEntity.get('id')+" created");
this.set('addEntryModal', false);
})
});
\ No newline at end of file
import Ember from 'ember';
import { pluralize } from 'ember-inflector';
export function pluralizeHelper([singular, count]/*, hash*/) {
return count === 1 ? singular : pluralize(singular);
}
export default Ember.Helper.helper(pluralizeHelper);
\ No newline at end of file
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
users: DS.hasMany('user')
});
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
completed: DS.attr('boolean'),
user: DS.hasMany('user')
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment