Pods, pods, everywhere

This commit is contained in:
Matthew Dillon 2015-06-04 12:18:59 -08:00
parent 33f783bc42
commit e623d52f34
66 changed files with 53 additions and 113 deletions

4
app/pods/about/route.js Normal file
View file

@ -0,0 +1,4 @@
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin);

View file

@ -0,0 +1,3 @@
<div class="about">
<p>This is some information about hymenobacter.info</p>
</div>

View file

@ -0,0 +1,26 @@
import DS from 'ember-data';
import Ember from 'ember';
import config from '../../config/environment';
export default DS.RESTAdapter.extend({
namespace: 'api/' + config.genus,
host: config.apiURL,
coalesceFindRequests: true,
ajaxError: function(jqXHR) {
// http://stackoverflow.com/a/24027443
var error = this._super(jqXHR);
if (jqXHR && jqXHR.status === 422) {
var response = Ember.$.parseJSON(jqXHR.responseText),
errors = {};
if (response.errors !== undefined) {
var jsonErrors = response.errors;
Ember.EnumerableUtils.forEach(Ember.keys(jsonErrors), function(key) {
errors[Ember.String.camelize(key)] = jsonErrors[key];
});
}
return new DS.InvalidError(errors);
} else {
return error;
}
}
});

View file

@ -0,0 +1,17 @@
import Ember from 'ember';
import ApplicationRouteMixin from 'simple-auth/mixins/application-route-mixin';
/* global NProgress */
export default Ember.Route.extend(ApplicationRouteMixin, {
actions: {
loading: function() {
NProgress.start();
this.router.one('didTransition', function() {
return setTimeout((function() {
return NProgress.done();
}), 50);
});
return true;
}
}
});

View file

@ -0,0 +1,46 @@
<div class="flakes-navigation">
{{#link-to 'index' class='logo'}}
<img src="img/logo.png" width="120">
{{/link-to}}
{{#if session.isAuthenticated}}
<ul>
{{#link-to 'species' tagName='li' href=false}}
{{#link-to 'species'}}Species{{/link-to}}
{{/link-to}}
{{#link-to 'strains' tagName='li' href=false}}
{{#link-to 'strains'}}Strains{{/link-to}}
{{/link-to}}
{{#link-to 'characteristics' tagName='li' href=false}}
{{#link-to 'characteristics'}}Characteristics{{/link-to}}
{{/link-to}}
{{#link-to 'about' tagName='li' href=false}}
{{#link-to 'about'}}About{{/link-to}}
{{/link-to}}
</ul>
<p class="foot">
{{session.currentUser.name}}<br>
<a {{ action 'invalidateSession' }}>Logout</a>
</p>
{{else}}
<p class="foot">
{{#link-to 'login' Login}}Login{{/link-to}}
<br>
Sign Up
</p>
{{/if}}
</div>
<div class="flakes-content">
<div class="flakes-mobile-top-bar">
<a href="" class="logo-wrap">
<img src="img/logo.png" height="30px">
</a>
<a href="" class="navigation-expand-target">
<img src="img/navigation-expand-target.png" height="26px">
</a>
</div>
<div class="view-wrap">
{{outlet}}
</div>
</div>

View file

@ -0,0 +1,8 @@
import Ember from 'ember';
export default Ember.View.extend({
classNames: ['flakes-frame'],
didInsertElement: function() {
FlakesFrame.init();
}
});

View file

@ -0,0 +1,5 @@
import SortableController from '../../controllers/sortable';
export default SortableController.extend({
sortBy: 'characteristicName',
});

View file

@ -0,0 +1,8 @@
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function() {
return this.store.findAll('characteristic');
}
});

View file

@ -0,0 +1,19 @@
<h2>{{genus-name}} Characteristics</h2>
<h3>Total characteristics: {{controller.length}}</h3>
<table class="flakes-table">
<thead>
<tr>
<th {{action "setSortBy" "characteristicName"}}>Name</th>
<th {{action "setSortBy" "characteristicType"}}>Type</th>
</tr>
</thead>
<tbody>
{{#each characteristic in controller}}
<tr>
<td>{{characteristic.characteristicName}}</td>
<td>{{characteristic.characteristicType}}</td>
</tr>
{{/each}}
</tbody>
</table>

View file

@ -0,0 +1,3 @@
{{#each error in a}}
<div class="flakes-message error">{{error.message}}</div>
{{/each}}

View file

@ -0,0 +1,7 @@
import Ember from 'ember';
import config from '../../../config/environment';
export default Ember.Component.extend({
tagName: 'em',
genus: config.genus.capitalize(),
});

View file

@ -0,0 +1 @@
{{genus}}

View file

@ -0,0 +1,6 @@
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'tr',
measurement: null, // passed in
});

View file

@ -0,0 +1,5 @@
<td>{{measurement.characteristic}}</td>
<td>{{measurement.computedType}}</td>
<td>{{{measurement.computedValue}}}</td>
<td>{{measurement.notes}}</td>
<td>{{measurement.testMethod}}</td>

View file

@ -0,0 +1,6 @@
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'span',
strain: null, // passed in
});

View file

@ -0,0 +1 @@
<em>{{strain.species.speciesName}}</em> (strain {{strain.strainName}})

View file

@ -0,0 +1,14 @@
import Ember from 'ember';
export default Ember.Component.extend({
classNames: ['grid-1'],
isEditing: false,
actions: {
save: function() {
this.sendAction('save');
},
cancel: function() {
this.sendAction('cancel');
},
}
});

View file

@ -0,0 +1,97 @@
<div class="span-1">
<fieldset {{bind-attr class=":flakes-information-box isEditing"}}>
<legend>
Species
{{#if isEditing}}
{{input value=species.speciesName}}
{{else}}
{{species.speciesName}}
{{/if}}
{{display-errors a=species.errors.speciesName}}
</legend>
{{! ROW 1 }}
<div class="grid-4">
<dl class="span-2">
<dt>Strains</dt>
<dd>
{{#each species.strains as |strain index|}}
{{if index ","}}
{{#link-to 'strains.show' strain.id}}
{{strain.strainName}}
{{/link-to}}
{{/each}}
{{#if (can "edit species" species)}}
{{#if species.isNew}}
PENDING SAVE
{{else}}
<br>
{{#link-to 'strains.new' class="button-gray smaller"}}
Add Strain
{{/link-to}}
{{/if}}
{{/if}}
</dd>
</dl>
<dl class="span-2">
<dt>Type Species?</dt>
<dd>
{{#if isEditing}}
{{input type="checkbox" checked=species.typeSpecies}}
{{/if}}
{{if species.typeSpecies 'Yes' 'No'}}
{{display-errors a=species.errors.typeSpecies}}
</dd>
</dl>
</div>
{{! ROW 2 }}
<div class="grid-4">
<dl class="span-4">
<dt>Etymology</dt>
<dd>
{{#if isEditing}}
{{textarea value=species.etymology cols="70" rows="3"}}
{{else}}
{{species.etymology}}
{{/if}}
{{display-errors a=species.errors.etymology}}
</dd>
</dl>
</div>
{{! ROW 3 }}
<div class="grid-4">
<dl class="span-1">
<dt>Record Created</dt>
<dd>{{null-time species.createdAt 'LL'}}</dd>
</dl>
<dl class="span-1">
<dt>Record Updated</dt>
<dd>{{null-time species.updatedAt 'LL'}}</dd>
</dl>
<dl class="span-1">
<dt>Record Deleted</dt>
<dd>{{null-time species.deletedAt 'LL'}}</dd>
</dl>
<dl class="span-1"></dl>
</div>
{{! ROW 4 }}
{{#if (can "edit species" species)}}
<div class="grid-4">
<div class="span-1">
{{! Does nothing ATM }}
<a {{bind-attr class=":smaller isEditing:button-red:button-gray"}} {{action 'cancel'}}>
{{#if isEditing}}Cancel{{else}}Edit{{/if}}
</a>
{{#if isEditing}}
<a class="button-green smaller" {{action 'save'}}>
Save
</a>
{{/if}}
</div>
</div>
{{/if}}
</fieldset>
</div>

View file

@ -0,0 +1,14 @@
import Ember from 'ember';
export default Ember.Component.extend({
classNames: ['grid-1'],
isEditing: false,
actions: {
save: function() {
this.sendAction('save');
},
cancel: function() {
this.sendAction('cancel');
},
}
});

View file

@ -0,0 +1,135 @@
<div class="span-1">
<fieldset {{bind-attr class=":flakes-information-box isEditing"}}>
<legend>
Strain
{{#if isEditing}}
{{input value=strain.strainName}}
{{else}}
{{strain.strainName}}
{{/if}}
{{display-errors a=strain.errors.strainName}}
</legend>
{{! ROW 1 }}
<div class="grid-4">
<dl class="span-2">
<dt>Species</dt>
<dd>
{{#if isEditing}}
{{
view "select"
content=species
optionValuePath="content.id"
optionLabelPath="content.speciesName"
selection=strain.species
}}
{{else}}
{{#link-to 'species.show' strain.species}}
<em>{{strain.species.speciesName}}</em>
{{/link-to}}
{{/if}}
</dd>
</dl>
<dl class="span-2">
<dt>Type Strain?</dt>
<dd>
{{#if isEditing}}
{{input type="checkbox" checked=strain.typeStrain}}
{{/if}}
{{if strain.typeStrain 'Yes' 'No'}}
{{display-errors a=strain.errors.typeStrain}}
</dd>
</dl>
</div>
{{! ROW 2 }}
<div class="grid-4">
<dl class="span-2">
<dt>Accession Numbers</dt>
<dd>
{{#if isEditing}}
{{input value=strain.accessionNumbers}}
{{else}}
{{strain.accessionNumbers}}
{{/if}}
{{display-errors a=strain.errors.accessionNumbers}}
</dd>
</dl>
<dl class="span-2">
<dt>Genbank</dt>
<dd>
{{#if isEditing}}
{{input value=strain.genbank}}
{{else}}
{{strain.genbank}}
{{/if}}
{{display-errors a=strain.errors.genbank}}
</dd>
</dl>
</div>
{{! ROW 3 }}
<div class="grid-4">
<dl class="span-4">
<dt>Isolated From</dt>
<dd>
{{#if isEditing}}
{{textarea value=strain.isolatedFrom cols="70" rows="3"}}
{{else}}
{{strain.isolatedFrom}}
{{/if}}
{{display-errors a=strain.errors.isolatedFrom}}
</dd>
</dl>
</div>
{{! ROW 4 }}
<div class="grid-4">
<dl class="span-4">
<dt>Notes</dt>
<dd>
{{#if isEditing}}
{{textarea value=strain.notes cols="70" rows="3"}}
{{else}}
{{strain.notes}}
{{/if}}
{{display-errors a=strain.errors.notes}}
</dd>
</dl>
</div>
{{! ROW 5 }}
<div class="grid-4">
<dl class="span-1">
<dt>Record Created</dt>
<dd>{{null-time strain.createdAt 'LL'}}</dd>
</dl>
<dl class="span-1">
<dt>Record Updated</dt>
<dd>{{null-time strain.updatedAt 'LL'}}</dd>
</dl>
<dl class="span-1">
<dt>Record Deleted</dt>
<dd>{{null-time strain.deletedAt 'LL'}}</dd>
</dl>
<dl class="span-1"></dl>
</div>
{{! ROW 6 }}
{{#if (can "edit strain" strain)}}
<div class="grid-4">
<div class="span-1">
{{! Does nothing ATM }}
<a {{bind-attr class=":smaller isEditing:button-red:button-gray"}} {{action 'cancel'}}>
{{#if isEditing}}Cancel{{else}}Edit{{/if}}
</a>
{{#if isEditing}}
<a class="button-green smaller" {{action 'save'}}>
Save
</a>
{{/if}}
</div>
</div>
{{/if}}
</fieldset>
</div>

4
app/pods/index/route.js Normal file
View file

@ -0,0 +1,4 @@
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin);

View file

@ -0,0 +1 @@
Welcome

View file

@ -0,0 +1,21 @@
import Ember from 'ember';
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
export default Ember.Controller.extend(LoginControllerMixin, {
authenticator: 'simple-auth-authenticator:jwt',
loading: false,
actions: {
authenticate: function() {
this.set('errorMessage', null);
var _this = this;
this.set('loading', true);
this._super().then(function() {
_this.set('loading', false);
}, function(error) {
_this.set('loading', false);
var message = error.error;
_this.set('errorMessage', message);
});
}
}
});

7
app/pods/login/route.js Normal file
View file

@ -0,0 +1,7 @@
import Ember from 'ember';
export default Ember.Route.extend({
setupController: function(controller) {
controller.set('errorMessage', null);
}
});

View file

@ -0,0 +1,20 @@
{{#if loggedIn}}
<p>You are already logged in!</p>
{{else}}
{{#if loading}}
<div class="spinner">
<div class="double-bounce1"></div>
<div class="double-bounce2"></div>
</div>
{{else}}
<form {{action "authenticate" on="submit"}}>
<h2>Log In</h2>
{{input value=identification type="text" placeholder="Email"}}
{{input value=password type="password" placeholder="Password"}}
{{input class="button-gray" type="submit" value="Log In"}}
</form>
{{/if}}
{{#if errorMessage}}
<div class="flakes-message error">{{errorMessage}}</div>
{{/if}}
{{/if}}

View file

@ -0,0 +1,5 @@
import SortableController from '../../../controllers/sortable';
export default SortableController.extend({
sortBy: 'speciesName',
});

View file

@ -0,0 +1,8 @@
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function() {
return this.store.findAll('species');
}
});

View file

@ -0,0 +1,37 @@
<h2>{{genus-name}} Species</h2>
<h3>Total species: {{controller.length}}</h3>
{{#if (can "add species")}}
{{! Does nothing ATM }}
{{#link-to 'species.new' class="button-gray smaller"}}
Add Species
{{/link-to}}
{{/if}}
<table class="flakes-table">
<thead>
<tr>
<th {{action "setSortBy" "speciesName"}}>Name</th>
<th {{action "setSortBy" "totalStrains"}}>Strains</th>
</tr>
</thead>
<tbody>
{{#each species in controller}}
<tr>
<td>
{{#link-to 'species.show' species}}
{{species.speciesName}}
{{/link-to}}
</td>
<td>
{{#each species.strains as |strain index|}}
{{if index ","}}
{{#link-to 'strains.show' strain.id}}
{{strain.strainName}}
{{/link-to}}
{{/each}}
</td>
</tr>
{{/each}}
</tbody>
</table>

View file

@ -0,0 +1,21 @@
import Ember from 'ember';
export default Ember.Controller.extend({
isEditing: true,
actions: {
save: function() {
var species = this.get('model');
if (species.get('isDirty')) {
species.save();
}
this.transitionToRoute('species.index');
},
cancel: function() {
var species = this.get('model');
if (species.get('isNew')) {
species.deleteRecord();
}
this.transitionToRoute('species.index');
}
}
});

View file

@ -0,0 +1,12 @@
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.createRecord('species');
},
actions: {
cancelSpecies: function() {
this.transitionTo('species.index');
}
}
});

View file

@ -0,0 +1,7 @@
{{
species-details
species=model
isEditing=true
save="save"
cancel="cancel"
}}

View file

@ -0,0 +1,22 @@
import Ember from 'ember';
export default Ember.Controller.extend({
isEditing: false,
actions: {
save: function() {
var species = this.get('model');
if (species.get('isDirty')) {
species.save();
}
this.toggleProperty('isEditing');
},
cancel: function() {
if (this.get('isEditing')) {
var species = this.get('model');
species.get('errors').clear();
species.rollback();
}
this.toggleProperty('isEditing');
}
}
});

View file

@ -0,0 +1,4 @@
import Ember from 'ember';
export default Ember.Route.extend({
});

View file

@ -0,0 +1,7 @@
{{
species-details
species=model
isEditing=isEditing
save="save"
cancel="cancel"
}}

View file

@ -0,0 +1,8 @@
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function() {
return this.store.findAll('strain');
}
});

View file

@ -0,0 +1,30 @@
<h2>{{genus-name}} Strains</h2>
<h3>Total strains: {{controller.length}}</h3>
{{#if (can "add strain")}}
{{! Does nothing ATM }}
{{#link-to 'strains.new' class="button-gray smaller"}}
Add Strain
{{/link-to}}
{{/if}}
<table class="flakes-table">
<thead>
<tr>
<th {{action "setSortBy" "fullName"}}>Name</th>
<th {{action "setSortBy" "totalMeasurements"}}>Total Measurements</th>
</tr>
</thead>
<tbody>
{{#each strain in controller}}
<tr>
<td>
{{#link-to 'strains.show' strain.id}}
{{scientific-name strain=strain}}
{{/link-to}}
</td>
<td>{{strain.totalMeasurements}}</td>
</tr>
{{/each}}
</tbody>
</table>

View file

@ -0,0 +1,21 @@
import Ember from 'ember';
export default Ember.Controller.extend({
isEditing: true,
actions: {
save: function() {
var strain = this.get('strain');
if (strain.get('isDirty')) {
strain.save();
}
this.transitionToRoute('strains.index');
},
cancel: function() {
var strain = this.get('strain');
if (strain.get('isNew')) {
strain.deleteRecord();
}
this.transitionToRoute('strains.index');
}
}
});

View file

@ -0,0 +1,13 @@
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
strain: this.store.createRecord('strain'),
species: this.store.findAll('species')
});
},
setupController: function(controller, models) {
controller.setProperties(models);
},
});

View file

@ -0,0 +1,8 @@
{{
strain-details
strain=strain
species=species
isEditing=true
save="save"
cancel="cancel"
}}

View file

@ -0,0 +1,19 @@
import Ember from 'ember';
export default Ember.Controller.extend({
isEditing: false,
actions: {
save: function() {
var strain = this.get('strain');
if (strain.get('isDirty')) {
strain.save();
}
this.toggleProperty('isEditing');
},
cancel: function() {
this.get('strain').get('errors').clear();
this.get('strain').rollback();
this.toggleProperty('isEditing');
}
}
});

View file

@ -0,0 +1,13 @@
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return Ember.RSVP.hash({
strain: this.store.find('strain', params.strain_id),
species: this.store.findAll('species')
});
},
setupController: function(controller, models) {
controller.setProperties(models);
},
});

View file

@ -0,0 +1,8 @@
{{
strain-details
strain=strain
species=species
isEditing=isEditing
save="save"
cancel="cancel"
}}

8
app/pods/user/adapter.js Normal file
View file

@ -0,0 +1,8 @@
import DS from 'ember-data';
import config from '../../config/environment';
export default DS.RESTAdapter.extend({
namespace: 'api',
host: config.apiURL,
coalesceFindRequests: true,
});

8
app/pods/users/route.js Normal file
View file

@ -0,0 +1,8 @@
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function() {
return this.store.findAll('user');
}
});

View file

@ -0,0 +1,3 @@
{{#each user in model}}
{{user.email}}<br>
{{/each}}