Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
4875f42152 | |||
7f73046773 |
61 changed files with 390 additions and 22388 deletions
10
.travis.yml
10
.travis.yml
|
@ -3,17 +3,11 @@ branches:
|
|||
only:
|
||||
- master
|
||||
node_js:
|
||||
- "9"
|
||||
sudo: required
|
||||
dist: trusty
|
||||
addons:
|
||||
chrome: stable
|
||||
- '6'
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.npm"
|
||||
env:
|
||||
global:
|
||||
- JOBS=1
|
||||
before_install:
|
||||
- npm config set spin false
|
||||
- npm install -g phantomjs-prebuilt
|
||||
|
|
|
@ -10,7 +10,7 @@ You will need the following things properly installed on your computer.
|
|||
* [Git](https://git-scm.com/)
|
||||
* [Node.js](https://nodejs.org/) (with NPM)
|
||||
* [Ember CLI](https://ember-cli.com/)
|
||||
* [Google Chrome](https://google.com/chrome/)
|
||||
* [PhantomJS](http://phantomjs.org/)
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import Application from '@ember/application';
|
||||
import Ember from 'ember';
|
||||
import Resolver from './resolver';
|
||||
import loadInitializers from 'ember-load-initializers';
|
||||
import config from './config/environment';
|
||||
|
||||
const App = Application.extend({
|
||||
let App;
|
||||
|
||||
App = Ember.Application.extend({
|
||||
modulePrefix: config.modulePrefix,
|
||||
podModulePrefix: config.podModulePrefix,
|
||||
Resolver
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import { Promise } from 'rsvp';
|
||||
import $ from 'jquery';
|
||||
import { get } from '@ember/object';
|
||||
import { isEmpty } from '@ember/utils';
|
||||
import { run } from '@ember/runloop';
|
||||
import Ember from 'ember';
|
||||
import BaseAuthenticator from 'ember-simple-auth/authenticators/base';
|
||||
import config from '../config/environment';
|
||||
|
||||
const { RSVP: { Promise }, $, get, isEmpty, run } = Ember;
|
||||
|
||||
export default BaseAuthenticator.extend({
|
||||
serverTokenEndpoint: `${config.APP.API_HOST}/api/auth/login/`,
|
||||
tokenAttributeName: 'data.attributes.auth-token',
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { isEmpty } from '@ember/utils';
|
||||
import { get } from '@ember/object';
|
||||
import Ember from 'ember';
|
||||
import BaseAuthorizer from 'ember-simple-auth/authorizers/base';
|
||||
|
||||
const { isEmpty, get } = Ember;
|
||||
|
||||
export default BaseAuthorizer.extend({
|
||||
authorize(data, block) {
|
||||
const accessToken = get(data, 'data.attributes.auth-token');
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
tagName: 'a',
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({ });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import { alias } from '@ember/object/computed';
|
||||
import { computed } from '@ember/object';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component, computed: { alias }, computed } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
// ARGS
|
||||
|
@ -8,7 +8,7 @@ export default Component.extend({
|
|||
|
||||
// COMPUTED
|
||||
meta: alias('model.meta'),
|
||||
links: alias('meta.links'),
|
||||
links: alias('model.links'),
|
||||
|
||||
currentPage: alias('meta.pagination.page'),
|
||||
totalRecords: alias('meta.pagination.count'),
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
import Table from 'ember-light-table';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
// ARGS
|
||||
model: null,
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import { getProperties, set } from '@ember/object';
|
||||
import Component from '@ember/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { debounce } from '@ember/runloop';
|
||||
import RSVP from 'rsvp';
|
||||
import Ember from 'ember';
|
||||
import Changeset from 'ember-changeset';
|
||||
import lookupValidator from 'ember-changeset-validations';
|
||||
import config from 'ccdb-web/config/environment';
|
||||
|
||||
const { Component, inject: { service } } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
store: service(),
|
||||
|
@ -14,80 +11,81 @@ export default Component.extend({
|
|||
this._super(...arguments);
|
||||
const model = this.get('model');
|
||||
const validations = this.get('validations');
|
||||
const hasMany = this.get('hasMany');
|
||||
|
||||
let changesets = {};
|
||||
changesets['new'] = [];
|
||||
changesets['delete'] = [];
|
||||
changesets['hasMany'] = {};
|
||||
changesets['hasMany'] = [];
|
||||
changesets['model'] = new Changeset(model,
|
||||
lookupValidator(validations['collection']),
|
||||
validations['collection']);
|
||||
|
||||
hasMany.forEach((hasMany) => {
|
||||
let relatedChangesets = [];
|
||||
let validation = validations[hasMany];
|
||||
const related = model.get(hasMany);
|
||||
related.forEach((r) => {
|
||||
const changeset = new Changeset(r, lookupValidator(validation),
|
||||
validation);
|
||||
relatedChangesets.push({ model: r, changeset: changeset });
|
||||
let collectionSpeciesChangesets = [];
|
||||
const collectionSpecies = model.get('collectionSpecies');
|
||||
collectionSpecies.forEach((cs) => {
|
||||
const changeset = new Changeset(cs,
|
||||
lookupValidator(validations['collectionSpecies']),
|
||||
validations['collectionSpecies']);
|
||||
collectionSpeciesChangesets.push({ model: cs, changeset: changeset });
|
||||
});
|
||||
changesets['hasMany'][hasMany] = relatedChangesets;
|
||||
changesets['hasMany']['collectionSpecies'] = collectionSpeciesChangesets;
|
||||
|
||||
let datasheetsChangesets = [];
|
||||
const datasheets = model.get('datasheets');
|
||||
datasheets.forEach((d) => {
|
||||
const changeset = new Changeset(d,
|
||||
lookupValidator(validations['datasheet']),
|
||||
validations['datasheet']);
|
||||
datasheetsChangesets.push({ model: d, changeset: changeset });
|
||||
});
|
||||
changesets['hasMany']['datasheets'] = datasheetsChangesets;
|
||||
|
||||
this.set('changesets', changesets);
|
||||
this.set('newStudyLocationAdmin', `${config.APP.API_HOST}/admin/locations/studylocation/add/`);
|
||||
},
|
||||
|
||||
actions: {
|
||||
addHasMany(modelName, relatedName) {
|
||||
addCollectionSpecies() {
|
||||
const store = this.get('store');
|
||||
let changesets = this.get('changesets');
|
||||
const validations = this.get('validations');
|
||||
const validation = validations[relatedName];
|
||||
const model = this.get('model');
|
||||
const related = store.createRecord(modelName, { collection: model });
|
||||
model.get(relatedName).pushObject(related);
|
||||
changesets['new'].pushObject(related);
|
||||
const changeset = new Changeset(related, lookupValidator(validation), validation);
|
||||
changesets['hasMany'][relatedName].pushObject({ model: related, changeset: changeset });
|
||||
const collection = this.get('model');
|
||||
const cs = store.createRecord('collection-species', { collection: collection });
|
||||
collection.get('collectionSpecies').pushObject(cs);
|
||||
changesets['new'].pushObject(cs);
|
||||
const changeset = new Changeset(cs,
|
||||
lookupValidator(validations['collectionSpecies']),
|
||||
validations['collectionSpecies']);
|
||||
changesets['hasMany']['collectionSpecies'].pushObject({ model: cs, changeset: changeset });
|
||||
},
|
||||
|
||||
deleteHasMany(changesetRecord, relatedName) {
|
||||
deleteCollectionSpecies(changesetRecord) {
|
||||
let changesets = this.get('changesets');
|
||||
changesets['delete'].pushObject(changesetRecord.model);
|
||||
changesets['hasMany'][relatedName].removeObject(changesetRecord);
|
||||
},
|
||||
|
||||
// Gross, this side-effects by saving immediately. Someday I should clean
|
||||
// this up, but for now, you have been warned.
|
||||
addOption(relatedModelName, optionName, collectionAttrName, relatedAttrName, term) {
|
||||
const props = getProperties(this, 'store', 'options', 'changesets');
|
||||
const { store, options, changesets: { model } } = props;
|
||||
let payload = {};
|
||||
payload[relatedAttrName] = term;
|
||||
const record = store.createRecord(relatedModelName, payload)
|
||||
record.save().then((record) => {
|
||||
set(options, optionName, store.peekAll(relatedModelName));
|
||||
set(model, collectionAttrName, record);
|
||||
});
|
||||
changesets['hasMany']['collectionSpecies'].removeObject(changesetRecord);
|
||||
},
|
||||
|
||||
updateDatasheet(changeset, event) {
|
||||
changeset.set('datasheet', event.target.files[0]);
|
||||
},
|
||||
|
||||
searchStudyLocation(term) {
|
||||
return new RSVP.Promise((resolve, reject) => {
|
||||
debounce(this, this._performSearch, 'study-location', { page_size: 500, code: term }, resolve, reject, 400);
|
||||
});
|
||||
},
|
||||
addDatasheet() {
|
||||
const store = this.get('store');
|
||||
let changesets = this.get('changesets');
|
||||
const validations = this.get('validations');
|
||||
const collection = this.get('model');
|
||||
const d = store.createRecord('datasheet-attachment', { collection: collection });
|
||||
collection.get('datasheets').pushObject(d);
|
||||
changesets['new'].pushObject(d);
|
||||
const changeset = new Changeset(d,
|
||||
lookupValidator(validations['datasheets']),
|
||||
validations['datasheets']);
|
||||
changesets['hasMany']['datasheets'].pushObject({ model: d, changeset: changeset });
|
||||
},
|
||||
|
||||
_performSearch(model, payload, resolve, reject) {
|
||||
this.get('store').query(model, payload).then((results) => {
|
||||
resolve(results);
|
||||
}, reject);
|
||||
deleteDatasheet(changesetRecord) {
|
||||
let changesets = this.get('changesets');
|
||||
changesets['delete'].pushObject(changesetRecord.model);
|
||||
changesets['hasMany']['datasheets'].removeObject(changesetRecord);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
// ARGS
|
||||
|
@ -22,13 +24,6 @@ export default Component.extend({
|
|||
{ label: 'Species', valuePath: 'species.commonName' },
|
||||
{ label: 'Count', valuePath: 'count' },
|
||||
{ label: 'Count Estimated?', valuePath: 'countEstimated' },
|
||||
{ label: 'Sex', valuePath: 'sex.name' },
|
||||
],
|
||||
|
||||
envMeasColumns: [
|
||||
{ label: 'Date Measured', valuePath: 'dateMeasured', },
|
||||
{ label: 'Time Measured', valuePath: 'timeMeasured', },
|
||||
{ label: 'Water Temp (deg C)', valuePath: 'waterTempC', },
|
||||
{ label: 'Air Temp (deg C)', valuePath: 'airTempC', },
|
||||
{ label: 'Sex', valuePath: 'sex' },
|
||||
],
|
||||
});
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
// ARGS
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
tagName: 'span',
|
||||
showConfirm: false,
|
||||
initialLabel: 'LABEL',
|
||||
confirmLabel: 'CONFIRM LABEL',
|
||||
cancelLabel: 'Cancel',
|
||||
|
||||
actions: {
|
||||
initial() {
|
||||
this.set('showConfirm', true);
|
||||
},
|
||||
|
||||
cancel() {
|
||||
this.set('showConfirm', false);
|
||||
},
|
||||
|
||||
confirm() {
|
||||
this.get('onClick')();
|
||||
},
|
||||
},
|
||||
});
|
|
@ -1,4 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
// ARGS
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
tagName: 'form',
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ['spinner'],
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Component from '@ember/component';
|
||||
import { get, computed } from '@ember/object';
|
||||
import { isEmpty } from '@ember/utils';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Component, computed, get, isEmpty } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ['form-group'],
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Controller from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Controller, inject: { service } } = Ember;
|
||||
|
||||
export default Controller.extend({
|
||||
session: service('session'),
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
import Controller from '@ember/controller';
|
||||
import { computed } from '@ember/object';
|
||||
import Ember from 'ember';
|
||||
import CollectionValidations from 'ccdb-web/validations/collection';
|
||||
import CollectionSpeciesValidations from 'ccdb-web/validations/collection-species';
|
||||
import CollectionMeasurementValidations from 'ccdb-web/validations/collection-measurement';
|
||||
import DatasheetValidations from 'ccdb-web/validations/datasheet';
|
||||
import ValidationMixin from 'ccdb-web/mixins/validation';
|
||||
|
||||
const { Controller, computed } = Ember;
|
||||
|
||||
export default Controller.extend(ValidationMixin, {
|
||||
CollectionValidations,
|
||||
CollectionSpeciesValidations,
|
||||
DatasheetValidations,
|
||||
CollectionMeasurementValidations,
|
||||
|
||||
hasMany: ['collectionSpecies', 'datasheets', 'envMeasurements'],
|
||||
hasMany: ['collectionSpecies', 'datasheets'],
|
||||
|
||||
options: computed('projectOptions', 'studyLocationOptions',
|
||||
'collectionTypeOptions', 'collectionMethodOptions',
|
||||
'speciesOptions', 'adfgPermitOptions', 'sexOptions',
|
||||
function() {
|
||||
'speciesOptions', 'adfgPermitOptions', function() {
|
||||
return {
|
||||
projects: this.get('projectOptions'),
|
||||
studyLocations: this.get('studyLocationOptions'),
|
||||
|
@ -25,22 +23,17 @@ export default Controller.extend(ValidationMixin, {
|
|||
collectionMethods: this.get('collectionMethodOptions'),
|
||||
species: this.get('speciesOptions'),
|
||||
adfgPermits: this.get('adfgPermitOptions'),
|
||||
sexes: this.get('sexOptions'),
|
||||
};
|
||||
}),
|
||||
|
||||
actions: {
|
||||
onSave(changeset) {
|
||||
const postSave = () => { this.transitionToRoute('collections.index'); };
|
||||
return this.transitionToRoute('loading').then(() => {
|
||||
return this.validationSave(changeset, postSave);
|
||||
});
|
||||
},
|
||||
onCancel(changeset) {
|
||||
const postCancel = () => { this.transitionToRoute('collections.index'); };
|
||||
return this.transitionToRoute('loading').then(() => {
|
||||
return this.validationCancel(changeset, postCancel);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
import Controller from '@ember/controller';
|
||||
import { computed } from '@ember/object';
|
||||
import Ember from 'ember';
|
||||
import CollectionValidations from 'ccdb-web/validations/collection';
|
||||
import CollectionSpeciesValidations from 'ccdb-web/validations/collection-species';
|
||||
import CollectionMeasurementValidations from 'ccdb-web/validations/collection-measurement';
|
||||
import DatasheetValidations from 'ccdb-web/validations/datasheet';
|
||||
import ValidationMixin from 'ccdb-web/mixins/validation';
|
||||
|
||||
const { Controller, computed } = Ember;
|
||||
|
||||
export default Controller.extend(ValidationMixin, {
|
||||
CollectionValidations,
|
||||
CollectionSpeciesValidations,
|
||||
DatasheetValidations,
|
||||
CollectionMeasurementValidations,
|
||||
|
||||
hasMany: ['collectionSpecies', 'datasheets', 'envMeasurements'],
|
||||
hasMany: ['collectionSpecies', 'datasheets'],
|
||||
safeNavigate: false,
|
||||
|
||||
options: computed('projectOptions', 'studyLocationOptions',
|
||||
'collectionTypeOptions', 'collectionMethodOptions',
|
||||
'speciesOptions', 'adfgPermitOptions', 'sexOptions',
|
||||
function() {
|
||||
'speciesOptions', 'adfgPermitOptions', function() {
|
||||
return {
|
||||
projects: this.get('projectOptions'),
|
||||
studyLocations: this.get('studyLocationOptions'),
|
||||
|
@ -25,28 +24,29 @@ export default Controller.extend(ValidationMixin, {
|
|||
collectionMethods: this.get('collectionMethodOptions'),
|
||||
species: this.get('speciesOptions'),
|
||||
adfgPermits: this.get('adfgPermitOptions'),
|
||||
sexes: this.get('sexOptions'),
|
||||
};
|
||||
}),
|
||||
|
||||
actions: {
|
||||
onSave(changesets) {
|
||||
const postSave = () => {
|
||||
this.set('safeNavigate', true);
|
||||
// Use the model's ID here because of the ArrayProxy in the route
|
||||
this.transitionToRoute('collections.detail', this.get('model.id'));
|
||||
this.set('safeNavigate', false);
|
||||
console.log('save');
|
||||
};
|
||||
return this.transitionToRoute('loading').then(() => {
|
||||
return this.validationSave(changesets, postSave);
|
||||
});
|
||||
},
|
||||
onCancel(changesets) {
|
||||
const postCancel = () => {
|
||||
this.set('safeNavigate', true);
|
||||
// Use the model's ID here because of the ArrayProxy in the route
|
||||
return this.transitionToRoute('collections.detail', this.get('model.id'));
|
||||
this.transitionToRoute('collections.detail', this.get('model.id'));
|
||||
this.set('safeNavigate', false);
|
||||
console.log('cancel');
|
||||
};
|
||||
return this.transitionToRoute('loading').then(() => {
|
||||
return this.validationCancel(changesets, postCancel);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
import Controller from '@ember/controller';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Controller } = Ember;
|
||||
|
||||
export default Controller.extend({
|
||||
actions: {
|
||||
editCollection() {
|
||||
this.transitionToRoute('collections.detail.edit', this.get('model'));
|
||||
},
|
||||
deleteCollection() {
|
||||
this.get('model')[0].destroyRecord().then(() => {
|
||||
this.transitionToRoute('collections');
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Controller from '@ember/controller';
|
||||
import { set, get, computed } from '@ember/object';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Controller, computed, get, set } = Ember;
|
||||
|
||||
|
||||
export default Controller.extend({
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Controller from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Controller, inject: { service } } = Ember;
|
||||
|
||||
export default Controller.extend({
|
||||
session: service(),
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
<body>
|
||||
{{content-for "body"}}
|
||||
|
||||
<script integrity="" src="{{rootURL}}assets/vendor.js"></script>
|
||||
<script integrity="" src="{{rootURL}}assets/ccdb-web.js"></script>
|
||||
<script src="{{rootURL}}assets/vendor.js"></script>
|
||||
<script src="{{rootURL}}assets/ccdb-web.js"></script>
|
||||
|
||||
{{content-for "body-footer"}}
|
||||
</body>
|
||||
|
|
36
app/mixins/cleanup-form.js
Normal file
36
app/mixins/cleanup-form.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
const { Mixin, run: { once } } = Ember;
|
||||
|
||||
export default Mixin.create({
|
||||
actions: {
|
||||
willTransition(transition) {
|
||||
if (!this.get('controller.safeNavigate')) {
|
||||
if (confirm('Any unsaved changes will be discarded.')) {
|
||||
let model = this.get('controller.model');
|
||||
let hasMany = this.get('controller.hasMany');
|
||||
|
||||
hasMany.forEach((relationship) => {
|
||||
model.get(relationship).forEach((r) => {
|
||||
once(this, () => {
|
||||
if (r.get('isNew')) {
|
||||
r.deleteRecord();
|
||||
} else {
|
||||
r.rollbackAttributes();
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
});
|
||||
|
||||
if (model.get('isNew')) {
|
||||
model.deleteRecord();
|
||||
}
|
||||
} else {
|
||||
transition.abort();
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
});
|
|
@ -1,5 +1,6 @@
|
|||
import Mixin from '@ember/object/mixin';
|
||||
import { isArray } from '@ember/array';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Mixin, isArray } = Ember;
|
||||
const { keys } = Object;
|
||||
|
||||
// Portions borrowed from https://github.com/funtusov/ember-cli-form-data
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import Mixin from '@ember/object/mixin';
|
||||
import { get } from '@ember/object';
|
||||
import RSVP from 'rsvp';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Mixin, get, RSVP } = Ember;
|
||||
const { keys } = Object;
|
||||
const { isArray } = Array;
|
||||
|
||||
export default Mixin.create({
|
||||
validationSave(changesets, postSave) {
|
||||
|
@ -54,14 +55,10 @@ export default Mixin.create({
|
|||
for (const model of changesets[key]) {
|
||||
model.destroyRecord();
|
||||
}
|
||||
} else if (key === 'hasMany') {
|
||||
const hasMany = changesets[key];
|
||||
for (const hasManyKey of keys(changesets[key])) {
|
||||
const hasManyChangesets = hasMany[hasManyKey];
|
||||
for (const changeset of hasManyChangesets) {
|
||||
} else if (isArray(changesets[key])) { // hasMany
|
||||
for (const { changeset } of changesets[key]) {
|
||||
changeset.rollback();
|
||||
}
|
||||
}
|
||||
} else { // single
|
||||
const changeset = changesets[key];
|
||||
changeset.rollback();
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
import DS from 'ember-data';
|
||||
|
||||
const { Model, attr, belongsTo } = DS;
|
||||
|
||||
export default Model.extend({
|
||||
dateMeasured: attr('ccdb-date'),
|
||||
timeMeasured: attr('string'),
|
||||
waterTempC: attr('number'),
|
||||
airTempC: attr('number'),
|
||||
|
||||
collection: belongsTo('collection'),
|
||||
});
|
|
@ -3,7 +3,7 @@ import DS from 'ember-data';
|
|||
const { Model, attr, belongsTo } = DS;
|
||||
|
||||
export default Model.extend({
|
||||
sex: belongsTo('sex'),
|
||||
sex: attr('string'),
|
||||
count: attr('number'),
|
||||
countEstimated: attr('boolean', { defaultValue: false }),
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import { mapBy } from '@ember/object/computed';
|
||||
import { computed } from '@ember/object';
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
const { computed } = Ember;
|
||||
const { Model, attr, belongsTo, hasMany } = DS;
|
||||
|
||||
export default Model.extend({
|
||||
displayName: attr('string'),
|
||||
numberOfTraps: attr('number'),
|
||||
collectionStartDate: attr('ccdb-date'),
|
||||
collectionStartDate: attr('string-null-to-empty'),
|
||||
collectionStartTime: attr('string-null-to-empty'),
|
||||
collectionEndDate: attr('ccdb-date'),
|
||||
collectionEndDate: attr('string-null-to-empty'),
|
||||
collectionEndTime: attr('string-null-to-empty'),
|
||||
notes: attr('string', { defaultValue: '' }),
|
||||
|
||||
project: belongsTo('project'),
|
||||
studyLocation: belongsTo('study-location'),
|
||||
|
@ -21,14 +20,13 @@ export default Model.extend({
|
|||
|
||||
collectionSpecies: hasMany('collection-species'),
|
||||
datasheets: hasMany('datasheet-attachment'),
|
||||
envMeasurements: hasMany('collection-measurement'),
|
||||
|
||||
// computed
|
||||
species: mapBy('collectionSpecies', 'species'),
|
||||
species: computed.mapBy('collectionSpecies', 'species'),
|
||||
|
||||
speciesNames: mapBy('species', 'commonName'),
|
||||
speciesNames: computed.mapBy('species', 'commonName'),
|
||||
|
||||
counts: mapBy('collectionSpecies', 'count'),
|
||||
counts: computed.mapBy('collectionSpecies', 'count'),
|
||||
|
||||
speciesAndCounts: computed('speciesNames', 'counts', function() {
|
||||
const speciesNames = this.get('speciesNames');
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import DS from 'ember-data';
|
||||
|
||||
const { Model, attr } = DS;
|
||||
|
||||
export default Model.extend({
|
||||
name: attr('string'),
|
||||
sortOrder: attr('number'),
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
import EmberRouter from '@ember/routing/router';
|
||||
import Ember from 'ember';
|
||||
import config from './config/environment';
|
||||
|
||||
const Router = EmberRouter.extend({
|
||||
const Router = Ember.Router.extend({
|
||||
location: config.locationType,
|
||||
rootURL: config.rootURL
|
||||
});
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import Ember from 'ember';
|
||||
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
|
||||
|
||||
const { Route } = Ember;
|
||||
|
||||
export default Route.extend(ApplicationRouteMixin, {});
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import RSVP from 'rsvp';
|
||||
import Ember from 'ember';
|
||||
import CleanupFormMixin from 'ccdb-web/mixins/cleanup-form';
|
||||
|
||||
export default Route.extend({
|
||||
const { Route, RSVP } = Ember;
|
||||
|
||||
export default Route.extend(CleanupFormMixin, {
|
||||
model() {
|
||||
const store = this.get('store');
|
||||
return RSVP.hash({
|
||||
model: store.createRecord('collection'),
|
||||
projectOptions: store.findAll('project'),
|
||||
studyLocationOptions: store.query('study-location', { page_size: 500 }),
|
||||
studyLocationOptions: store.findAll('study-location'),
|
||||
collectionTypeOptions: store.findAll('collection-type'),
|
||||
collectionMethodOptions: store.findAll('collection-method'),
|
||||
speciesOptions: store.query('species', { page_size: 500 }),
|
||||
speciesOptions: store.findAll('species'),
|
||||
adfgPermitOptions: store.findAll('adfg-permit'),
|
||||
sexOptions: store.findAll('sex'),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import RSVP from 'rsvp';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Route, RSVP } = Ember;
|
||||
|
||||
export default Route.extend({
|
||||
model(params) {
|
||||
return RSVP.all([
|
||||
this.get('store').findRecord('collection', params.collection_id, {
|
||||
include: 'collection-species,datasheets,env-measurements',
|
||||
include: 'collection-species,datasheets',
|
||||
})
|
||||
]);
|
||||
},
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import RSVP from 'rsvp';
|
||||
import Ember from 'ember';
|
||||
import CleanupFormMixin from 'ccdb-web/mixins/cleanup-form';
|
||||
|
||||
export default Route.extend({
|
||||
const { Route, RSVP } = Ember;
|
||||
|
||||
export default Route.extend(CleanupFormMixin, {
|
||||
model() {
|
||||
const store = this.get('store');
|
||||
const model = this.modelFor('collections.detail');
|
||||
return RSVP.hash({
|
||||
model: model,
|
||||
projectOptions: store.findAll('project'),
|
||||
studyLocationOptions: store.query('study-location', { page_size: 500 }),
|
||||
studyLocationOptions: store.findAll('study-location'),
|
||||
collectionTypeOptions: store.findAll('collection-type'),
|
||||
collectionMethodOptions: store.findAll('collection-method'),
|
||||
speciesOptions: store.query('species', { page_size: 500 }),
|
||||
speciesOptions: store.findAll('species'),
|
||||
adfgPermitOptions: store.findAll('adfg-permit'),
|
||||
sexOptions: store.findAll('sex'),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import RSVP from 'rsvp';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Route, RSVP } = Ember;
|
||||
|
||||
export default Route.extend({
|
||||
queryParams: {
|
||||
|
@ -29,10 +30,10 @@ export default Route.extend({
|
|||
projectOptions: store.findAll('project'),
|
||||
regionOptions: store.findAll('region'),
|
||||
siteOptions: store.findAll('site'),
|
||||
studyLocationOptions: store.query('study-location', { page_size: 500 }),
|
||||
studyLocationOptions: store.findAll('study-location'),
|
||||
collectionMethodOptions: store.findAll('collection-method'),
|
||||
adfgPermitOptions: store.findAll('adfg-permit'),
|
||||
speciesOptions: store.query('species', { page_size: 500 }),
|
||||
speciesOptions: store.findAll('species'),
|
||||
model: store.query('collection', Object.assign(params, opts)),
|
||||
});
|
||||
},
|
||||
|
@ -43,38 +44,27 @@ export default Route.extend({
|
|||
|
||||
const store = this.get('store');
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
let project = controller.get('project');
|
||||
console.log('project', project);
|
||||
project = project.map(id => store.peekRecord('project', id));
|
||||
|
||||
let region = controller.get('region');
|
||||
console.log('region', region);
|
||||
region = region.map(id => store.peekRecord('region', id));
|
||||
|
||||
let site = controller.get('site');
|
||||
console.log('site', site);
|
||||
site = site.map(id => store.peekRecord('site', id));
|
||||
|
||||
let studyLocation = controller.get('study_location');
|
||||
console.log('studyLocation', studyLocation);
|
||||
studyLocation = studyLocation.map(id => store.peekRecord('study-location', id));
|
||||
|
||||
let collectionMethod = controller.get('collection_method');
|
||||
console.log('collectionMethod', collectionMethod);
|
||||
collectionMethod = collectionMethod.map(id => store.peekRecord('collection-method', id));
|
||||
|
||||
let adfgPermit = controller.get('adfg_permit');
|
||||
console.log('adfgPermit', adfgPermit);
|
||||
adfgPermit = adfgPermit.map(id => store.peekRecord('adfg-permit', id));
|
||||
|
||||
let species = controller.get('species');
|
||||
console.log('species', species);
|
||||
species = species.map(id => store.peekRecord('species', id));
|
||||
|
||||
/* eslint-enable no-console */
|
||||
|
||||
const numberOfTraps = controller.get('number_of_traps');
|
||||
const collectionStartDate = controller.get('collection_start_date');
|
||||
const collectionEndDate = controller.get('collection_end_date');
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import Ember from 'ember';
|
||||
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||
|
||||
const { Route } = Ember;
|
||||
|
||||
export default Route.extend(AuthenticatedRouteMixin, {
|
||||
afterModel() {
|
||||
this.transitionTo('collections');
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import Ember from 'ember';
|
||||
import UnauthenticatedRouteMixin from 'ember-simple-auth/mixins/unauthenticated-route-mixin';
|
||||
|
||||
const { Route } = Ember;
|
||||
|
||||
export default Route.extend(UnauthenticatedRouteMixin, {});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Ember from 'ember';
|
||||
|
||||
const { Route, inject: { service }} = Ember;
|
||||
|
||||
export default Route.extend({
|
||||
session: service('session'),
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
import { capitalize } from '@ember/string';
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
const { JSONAPISerializer } = DS;
|
||||
|
||||
export default JSONAPISerializer.extend({
|
||||
payloadTypeFromModelName(modelName) {
|
||||
return modelName.split('-').map(key => capitalize(key)).join('');
|
||||
},
|
||||
|
||||
normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) {
|
||||
let normalizedDocument = this._super(store, primaryModelClass, payload, id, requestType);
|
||||
normalizedDocument.meta.links = normalizedDocument.links;
|
||||
return normalizedDocument;
|
||||
},
|
||||
return modelName.split('-').map(key => Ember.String.capitalize(key)).join('');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
validations=(hash
|
||||
collection=CollectionValidations
|
||||
collectionSpecies=CollectionSpeciesValidations
|
||||
envMeasurements=CollectionMeasurementValidations
|
||||
datasheet=DatasheetValidations)
|
||||
options=options
|
||||
hasMany=hasMany
|
||||
onSave=(action 'onSave')
|
||||
onCancel=(action 'onCancel')
|
||||
}}
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
validations=(hash
|
||||
collection=CollectionValidations
|
||||
collectionSpecies=CollectionSpeciesValidations
|
||||
datasheet=DatasheetValidations
|
||||
envMeasurements=CollectionMeasurementValidations)
|
||||
datasheet=DatasheetValidations)
|
||||
options=options
|
||||
hasMany=hasMany
|
||||
onSave=(action 'onSave')
|
||||
onCancel=(action 'onCancel')
|
||||
}}
|
||||
|
|
|
@ -2,5 +2,4 @@
|
|||
collection/detail-container
|
||||
model=model
|
||||
editCollection=(action 'editCollection')
|
||||
deleteCollection=(action 'deleteCollection')
|
||||
}}
|
||||
|
|
|
@ -21,32 +21,26 @@
|
|||
{{/validated-field}}
|
||||
|
||||
{{#validated-field property='adfgPermit' label='ADFG Permit' changeset=changeset}}
|
||||
{{#power-select-with-create
|
||||
{{#power-select
|
||||
options=options.adfgPermits
|
||||
selected=changeset.adfgPermit
|
||||
onchange=(action (mut changeset.adfgPermit))
|
||||
oncreate=(action 'addOption' 'adfg-permit' 'adfgPermits' 'adfgPermit' 'name')
|
||||
searchField='name'
|
||||
as |adfgPermit term|
|
||||
as |adfgPermit|
|
||||
}}
|
||||
{{adfgPermit.name}}
|
||||
{{/power-select-with-create}}
|
||||
{{/power-select}}
|
||||
{{/validated-field}}
|
||||
|
||||
{{#validated-field property='studyLocation' changeset=changeset}}
|
||||
<label class="control-label">
|
||||
Study location
|
||||
<a href="{{newStudyLocationAdmin}}" target="_blank">+</a>
|
||||
</label>
|
||||
{{#validated-field property='studyLocation' label='Study location' changeset=changeset}}
|
||||
{{#power-select
|
||||
search=(action 'searchStudyLocation')
|
||||
options=options.studyLocations
|
||||
selected=changeset.studyLocation
|
||||
onchange=(action (mut changeset.studyLocation))
|
||||
searchField='code'
|
||||
searchField='name'
|
||||
as |studyLocation|
|
||||
}}
|
||||
{{studyLocation.code}}
|
||||
{{studyLocation.name}}
|
||||
{{/power-select}}
|
||||
{{/validated-field}}
|
||||
|
||||
|
@ -79,54 +73,29 @@
|
|||
{{/validated-field}}
|
||||
|
||||
{{#validated-field property='collectionStartDate' label='Collection start date' changeset=changeset}}
|
||||
{{
|
||||
pikaday-input
|
||||
onSelection=(action (mut changeset.collectionStartDate))
|
||||
value=changeset.collectionStartDate
|
||||
useUTC=true
|
||||
placeholder='MM/DD/YYYY'
|
||||
format='MM/DD/YYYY'
|
||||
class='form-control'
|
||||
}}
|
||||
{{input value=changeset.collectionStartDate type='date' class='form-control'}}
|
||||
{{/validated-field}}
|
||||
|
||||
{{#validated-field property='collectionStartTime' label='Collection start time' changeset=changeset}}
|
||||
{{input value=changeset.collectionStartTime type='time' class='form-control' placeholder='HH:MM:SS (24 hour)'}}
|
||||
{{input value=changeset.collectionStartTime type='time' class='form-control'}}
|
||||
{{/validated-field}}
|
||||
|
||||
{{#validated-field property='collectionEndDate' label='Collection end date' changeset=changeset}}
|
||||
{{
|
||||
pikaday-input
|
||||
onSelection=(action (mut changeset.collectionEndDate))
|
||||
value=changeset.collectionEndDate
|
||||
useUTC=true
|
||||
placeholder='MM/DD/YYYY'
|
||||
format='MM/DD/YYYY'
|
||||
class='form-control'
|
||||
}}
|
||||
{{input value=changeset.collectionEndDate type='date' class='form-control'}}
|
||||
{{/validated-field}}
|
||||
|
||||
{{#validated-field property='collectionEndTime' label='Collection end time' changeset=changeset}}
|
||||
{{input value=changeset.collectionEndTime type='time' class='form-control' placeholder='HH:MM:SS (24 hour)'}}
|
||||
{{input value=changeset.collectionEndTime type='time' class='form-control'}}
|
||||
{{/validated-field}}
|
||||
{{/with}}
|
||||
{{/f.content}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{{#validated-field property='notes' label='Notes' changeset=changesets.model}}
|
||||
{{textarea value=changesets.model.notes class='form-control'}}
|
||||
{{/validated-field}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table class="table">
|
||||
<caption>
|
||||
Species / Count Info
|
||||
{{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'collection-species' 'collectionSpecies')}}
|
||||
{{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addCollectionSpecies')}}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -165,75 +134,11 @@
|
|||
</td>
|
||||
<td class="col-md-3">
|
||||
{{#validated-field property='sex' changeset=cs.changeset}}
|
||||
{{#power-select
|
||||
options=options.sexes
|
||||
selected=cs.changeset.sex
|
||||
onchange=(action (mut cs.changeset.sex))
|
||||
searchField='name'
|
||||
as |sex|
|
||||
}}
|
||||
{{sex.name}}
|
||||
{{/power-select}}
|
||||
{{input value=cs.changeset.sex}}
|
||||
{{/validated-field}}
|
||||
</td>
|
||||
<td class="col-md-2">
|
||||
{{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteHasMany' cs 'collectionSpecies')}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table class="table">
|
||||
<caption>
|
||||
Environmental Measurements
|
||||
{{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'collection-measurement' 'envMeasurements')}}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-3">Date Measured</th>
|
||||
<th class="col-md-3">Time Measured</th>
|
||||
<th class="col-md-3">Water Temperature (deg C)</th>
|
||||
<th class="col-md-3">Air Temperature (deg C)</th>
|
||||
<th class="col-md-1">Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each changesets.hasMany.envMeasurements as |cm|}}
|
||||
<tr class="form">
|
||||
<td class="col-md-3">
|
||||
{{#validated-field property='dateMeasured' changeset=cm.changeset}}
|
||||
{{
|
||||
pikaday-input
|
||||
onSelection=(action (mut cm.changeset.dateMeasured))
|
||||
value=cm.changeset.dateMeasured
|
||||
useUTC=true
|
||||
placeholder='MM/DD/YYYY'
|
||||
format='MM/DD/YYYY'
|
||||
class='form-control'
|
||||
}}
|
||||
{{/validated-field}}
|
||||
</td>
|
||||
<td class="col-md-3">
|
||||
{{#validated-field property='timeMeasured' changeset=cm.changeset}}
|
||||
{{input value=cm.changeset.timeMeasured type='time' class='form-control'}}
|
||||
{{/validated-field}}
|
||||
</td>
|
||||
<td class="col-md-3">
|
||||
{{#validated-field property='waterTempC' changeset=cm.changeset}}
|
||||
{{input value=cm.changeset.waterTempC class='form-control'}}
|
||||
{{/validated-field}}
|
||||
</td>
|
||||
<td class="col-md-3">
|
||||
{{#validated-field property='airTempC' changeset=cm.changeset}}
|
||||
{{input value=cm.changeset.airTempC class='form-control'}}
|
||||
{{/validated-field}}
|
||||
</td>
|
||||
<td class="col-md-2">
|
||||
{{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteHasMany' cm 'envMeasurements')}}
|
||||
{{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteCollectionSpecies' cs)}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
@ -247,7 +152,7 @@
|
|||
<table class="table">
|
||||
<caption>
|
||||
Attachments
|
||||
{{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'datasheet-attachment' 'datasheets')}}
|
||||
{{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addDatasheet')}}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -268,15 +173,14 @@
|
|||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
{{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteHasMany' d 'datasheets')}}
|
||||
{{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteDatasheet' d)}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{f.save}} {{f.cancel}}
|
||||
|
|
|
@ -5,13 +5,6 @@
|
|||
onClick=(action editCollection)
|
||||
}}
|
||||
|
||||
{{
|
||||
confirm-button
|
||||
initialLabel='Delete Collection'
|
||||
confirmLabel='Yes, Delete Collection'
|
||||
onClick=(action deleteCollection)
|
||||
}}
|
||||
|
||||
<h3>Main Detail</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
@ -40,24 +33,14 @@
|
|||
|
||||
<hr>
|
||||
|
||||
<h3>Environmental Measurements</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{{#ccdb-table model=model.[0].envMeasurements columns=envMeasColumns as |c|}}
|
||||
{{#c.grid as |g|}}
|
||||
{{g.head}}
|
||||
{{g.body}}
|
||||
{{/c.grid}}
|
||||
{{/ccdb-table}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Notes</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{{model.[0].notes}}
|
||||
<ul>
|
||||
<li>PLACEHOLDER</li>
|
||||
<li>PLACEHOLDER</li>
|
||||
<li>PLACEHOLDER</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -102,8 +102,7 @@
|
|||
onSelection=(action (mut filters.collection_start_date))
|
||||
value=filters.collection_start_date
|
||||
useUTC=true
|
||||
placeholder='MM/DD/YYYY'
|
||||
format='MM/DD/YYYY'
|
||||
format='YYYY-MM-DD'
|
||||
class='form-control'
|
||||
}}
|
||||
</div>
|
||||
|
@ -114,8 +113,7 @@
|
|||
onSelection=(action (mut filters.collection_end_date))
|
||||
value=filters.collection_end_date
|
||||
useUTC=true
|
||||
placeholder='MM/DD/YYYY'
|
||||
format='MM/DD/YYYY'
|
||||
format='YYYY-MM-DD'
|
||||
class='form-control'
|
||||
}}
|
||||
</div>
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{{#if showConfirm}}
|
||||
{{action-button isDanger=true label=cancelLabel onClick=(action 'cancel')}}
|
||||
{{action-button isSuccess=true label=confirmLabel onClick=(action 'confirm')}}
|
||||
{{else}}
|
||||
{{action-button isDanger=true label=initialLabel onClick=(action 'initial')}}
|
||||
{{/if}}
|
|
@ -1,19 +0,0 @@
|
|||
import DS from 'ember-data';
|
||||
|
||||
export default DS.Transform.extend({
|
||||
deserialize(serialized) {
|
||||
return serialized || '';
|
||||
},
|
||||
|
||||
serialize(date) {
|
||||
if (date !== '') {
|
||||
date = new Date(date);
|
||||
const day = date.getUTCDate();
|
||||
const month = date.getUTCMonth() + 1;
|
||||
const year = date.getUTCFullYear();
|
||||
return `${year}-${month}-${day}`;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,12 +0,0 @@
|
|||
import {
|
||||
validatePresence,
|
||||
validateNumber,
|
||||
} from 'ember-changeset-validations/validators';
|
||||
|
||||
export default {
|
||||
dateMeasured: validatePresence(true),
|
||||
timeMeasured: validatePresence(true),
|
||||
waterTempC: validateNumber({ allowBlank: true, integer: false, positive: false }),
|
||||
airTempC: validateNumber({ allowBlank: true, integer: false, positive: false }),
|
||||
collection: validatePresence(true),
|
||||
}
|
|
@ -20,23 +20,13 @@ module.exports = function(environment) {
|
|||
APP: {
|
||||
// Here you can pass flags/options to your application instance
|
||||
// when it is created
|
||||
},
|
||||
|
||||
sentry: {
|
||||
dsn: 'https://fd3c695fa9394de48a7c69b7a322960b@sentry.io/1186914',
|
||||
globalErrorCatching: false,
|
||||
},
|
||||
|
||||
contentSecurityPolicy: {
|
||||
'script-src': "'self' 'unsafe-inline' 'unsafe-eval'",
|
||||
'img-src': 'data: app.getsentry.com',
|
||||
}
|
||||
};
|
||||
|
||||
if (environment === 'development') {
|
||||
ENV.APP.API_HOST = 'http://localhost:8000';
|
||||
ENV.APP.API_NAMESPACE = 'api/v1';
|
||||
ENV.sentry.development = true;
|
||||
ENV.APP.LOG_TRANSITIONS = true;
|
||||
}
|
||||
|
||||
if (environment === 'test') {
|
||||
|
@ -51,7 +41,7 @@ module.exports = function(environment) {
|
|||
}
|
||||
|
||||
if (environment === 'production') {
|
||||
ENV.APP.API_HOST = 'https://ccdb-api.thermokar.st';
|
||||
ENV.APP.API_HOST = 'https://obscure-caverns-99102.herokuapp.com';
|
||||
ENV.APP.API_NAMESPACE = 'api/v1';
|
||||
}
|
||||
|
||||
|
|
21802
package-lock.json
generated
21802
package-lock.json
generated
File diff suppressed because it is too large
Load diff
30
package.json
30
package.json
|
@ -17,26 +17,25 @@
|
|||
"devDependencies": {
|
||||
"broccoli-asset-rev": "^2.4.5",
|
||||
"ember-ajax": "^3.0.0",
|
||||
"ember-changeset": "^1.3.0",
|
||||
"ember-changeset-validations": "^1.2.8",
|
||||
"ember-cli": "^3.24.0",
|
||||
"ember-changeset": "1.3.0",
|
||||
"ember-changeset-validations": "1.2.8",
|
||||
"ember-cli": "~2.14.0",
|
||||
"ember-cli-app-version": "^3.0.0",
|
||||
"ember-cli-babel": "^6.6.0",
|
||||
"ember-cli-babel": "^6.3.0",
|
||||
"ember-cli-code-coverage": "^0.4.1",
|
||||
"ember-cli-dependency-checker": "^2.0.0",
|
||||
"ember-cli-eslint": "^4.0.0",
|
||||
"ember-cli-flash": "^1.4.3",
|
||||
"ember-cli-dependency-checker": "^1.3.0",
|
||||
"ember-cli-eslint": "^3.0.0",
|
||||
"ember-cli-flash": "1.4.3",
|
||||
"ember-cli-htmlbars": "^2.0.1",
|
||||
"ember-cli-htmlbars-inline-precompile": "^1.0.0",
|
||||
"ember-cli-htmlbars-inline-precompile": "^0.4.3",
|
||||
"ember-cli-inject-live-reload": "^1.4.1",
|
||||
"ember-cli-moment-shim": "^3.5.0",
|
||||
"ember-cli-qunit": "^4.0.0",
|
||||
"ember-cli-sentry": "^3.0.0",
|
||||
"ember-cli-shims": "^1.1.0",
|
||||
"ember-cli-sri": "^2.1.0",
|
||||
"ember-cli-uglify": "^2.0.0",
|
||||
"ember-cli-uglify": "^1.2.0",
|
||||
"ember-composable-helpers": "^2.0.3",
|
||||
"ember-data": "~2.16.2",
|
||||
"ember-data": "~2.14.3",
|
||||
"ember-export-application-global": "^2.0.0",
|
||||
"ember-inflector": "^2.0.1",
|
||||
"ember-light-table": "^1.10.0",
|
||||
|
@ -44,19 +43,16 @@
|
|||
"ember-moment": "7.3.1",
|
||||
"ember-pikaday": "^2.2.3",
|
||||
"ember-power-select": "^1.8.5",
|
||||
"ember-power-select-with-create": "^0.4.3",
|
||||
"ember-power-select-with-create": "0.4.3",
|
||||
"ember-resolver": "^4.0.0",
|
||||
"ember-responsive": "^2.0.4",
|
||||
"ember-simple-auth": "1.4.0",
|
||||
"ember-sinon": "^1.0.0",
|
||||
"ember-source": "~2.16.0",
|
||||
"ember-source": "~2.14.0",
|
||||
"loader.js": "^4.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^4.5 || 6.* || >= 7.*"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"npm": "^5.7.1"
|
||||
}
|
||||
"private": true
|
||||
}
|
||||
|
|
14
testem.js
14
testem.js
|
@ -3,20 +3,10 @@ module.exports = {
|
|||
test_page: 'tests/index.html?hidepassed',
|
||||
disable_watching: true,
|
||||
launch_in_ci: [
|
||||
'Chrome'
|
||||
'PhantomJS'
|
||||
],
|
||||
launch_in_dev: [
|
||||
'PhantomJS',
|
||||
'Chrome'
|
||||
],
|
||||
browser_args: {
|
||||
Chrome: {
|
||||
mode: 'ci',
|
||||
args: [
|
||||
'--disable-gpu',
|
||||
'--headless',
|
||||
'--remote-debugging-port=9222',
|
||||
'--window-size=1440,900'
|
||||
]
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import Ember from 'ember';
|
||||
|
||||
export default function destroyApp(application) {
|
||||
run(application, 'destroy');
|
||||
Ember.run(application, 'destroy');
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import Ember from 'ember';
|
||||
import FlashObject from 'ember-cli-flash/flash/object';
|
||||
|
||||
FlashObject.reopen({ init() {} });
|
||||
const { K } = Ember;
|
||||
|
||||
FlashObject.reopen({ init: K });
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { module } from 'qunit';
|
||||
import { resolve } from 'rsvp';
|
||||
import Ember from 'ember';
|
||||
import startApp from '../helpers/start-app';
|
||||
import destroyApp from '../helpers/destroy-app';
|
||||
|
||||
const { RSVP: { resolve } } = Ember;
|
||||
|
||||
export default function(name, options = {}) {
|
||||
module(name, {
|
||||
beforeEach() {
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import { registerAsyncHelper } from '@ember/test';
|
||||
import { A } from '@ember/array';
|
||||
import { computed } from '@ember/object';
|
||||
import { classify } from '@ember/string';
|
||||
import { getOwner } from '@ember/application';
|
||||
import Ember from 'ember';
|
||||
import MediaService from 'ember-responsive/media';
|
||||
|
||||
const {
|
||||
getOwner
|
||||
} = Ember;
|
||||
const { classify } = Ember.String;
|
||||
|
||||
MediaService.reopen({
|
||||
// Change this if you want a different default breakpoint in tests.
|
||||
_defaultBreakpoint: 'desktop',
|
||||
|
||||
_breakpointArr: computed('breakpoints', function() {
|
||||
return Object.keys(this.get('breakpoints')) || A([]);
|
||||
_breakpointArr: Ember.computed('breakpoints', function() {
|
||||
return Object.keys(this.get('breakpoints')) || Ember.A([]);
|
||||
}),
|
||||
|
||||
_forceSetBreakpoint(breakpoint) {
|
||||
|
@ -44,7 +45,7 @@ MediaService.reopen({
|
|||
}
|
||||
});
|
||||
|
||||
export default registerAsyncHelper('setBreakpoint', function(app, breakpoint) {
|
||||
export default Ember.Test.registerAsyncHelper('setBreakpoint', function(app, breakpoint) {
|
||||
// this should use getOwner once that's supported
|
||||
const mediaService = app.__deprecatedInstance__.lookup('service:media');
|
||||
mediaService._forceSetBreakpoint(breakpoint);
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import Ember from 'ember';
|
||||
import Application from '../../app';
|
||||
import config from '../../config/environment';
|
||||
import { merge } from '@ember/polyfills';
|
||||
import { run } from '@ember/runloop';
|
||||
|
||||
export default function startApp(attrs) {
|
||||
let attributes = merge({}, config.APP);
|
||||
attributes = merge(attributes, attrs); // use defaults, but you can override;
|
||||
let attributes = Ember.merge({}, config.APP);
|
||||
attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
|
||||
|
||||
return run(() => {
|
||||
return Ember.run(() => {
|
||||
let application = Application.create(attributes);
|
||||
application.setupForTesting();
|
||||
application.injectTestHelpers();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import $ from 'jquery';
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
import sinon from 'sinon';
|
||||
import Ember from 'ember';
|
||||
|
||||
moduleFor('authenticator:application', 'Unit | application', {
|
||||
unit: true,
|
||||
|
@ -35,28 +35,28 @@ test('`invalidate` should invalidate the session', function(assert) {
|
|||
|
||||
test('`makeRequest` should make a request', function(assert) {
|
||||
assert.expect(2);
|
||||
const stub = sinon.stub($, 'ajax');
|
||||
const stub = sinon.stub(Ember.$, 'ajax');
|
||||
stub.resolves(42);
|
||||
const authenticator = this.subject();
|
||||
authenticator.set('serverTokenEndpoint', 'foo')
|
||||
const promise = authenticator.makeRequest({bar: 'baz'}).then((d) => {
|
||||
assert.equal(d, 42);
|
||||
});
|
||||
assert.ok($.ajax.calledWithMatch({url: 'foo', data: {bar: 'baz'}}));
|
||||
$.ajax.restore();
|
||||
assert.ok(Ember.$.ajax.calledWithMatch({url: 'foo', data: {bar: 'baz'}}));
|
||||
Ember.$.ajax.restore();
|
||||
return promise;
|
||||
});
|
||||
|
||||
test('authenticate should craft a nice payload', function(assert) {
|
||||
assert.expect(2);
|
||||
const stub = sinon.stub($, 'ajax');
|
||||
const stub = sinon.stub(Ember.$, 'ajax');
|
||||
stub.resolves(42);
|
||||
const authenticator = this.subject();
|
||||
authenticator.set('serverTokenEndpoint', 'foo')
|
||||
const promise = authenticator.authenticate('myusername', 'mypassword').then((d) => {
|
||||
assert.equal(d, 42);
|
||||
});
|
||||
assert.ok($.ajax.calledWithMatch({url: 'foo', data: {username: 'myusername', password: 'mypassword'}}));
|
||||
$.ajax.restore();
|
||||
assert.ok(Ember.$.ajax.calledWithMatch({url: 'foo', data: {username: 'myusername', password: 'mypassword'}}));
|
||||
Ember.$.ajax.restore();
|
||||
return promise;
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue