diff --git a/.travis.yml b/.travis.yml
index de8dc13..ea1b929 100644
--- a/.travis.yml
+++ b/.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
diff --git a/README.md b/README.md
index 4a9360d..a69437b 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/app/adapters/application.js b/app/adapters/application.js
index a9c6c0c..65c8c47 100644
--- a/app/adapters/application.js
+++ b/app/adapters/application.js
@@ -9,11 +9,4 @@ export default JSONAPIAdapter.extend(DataAdapterMixin, {
namespace: API_NAMESPACE,
host: API_HOST,
authorizer: 'authorizer:application',
- // DRF-JSON-API returns 400 by default
- handleResponse(status, headers, payload) {
- if (status === 400 && payload.errors) {
- return new DS.InvalidError(payload.errors);
- }
- return this._super(...arguments);
- }
});
diff --git a/app/adapters/datasheet-attachment.js b/app/adapters/datasheet-attachment.js
deleted file mode 100644
index a89c329..0000000
--- a/app/adapters/datasheet-attachment.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import ApplicationAdapter from './application';
-import FileUploadAdapter from 'ccdb-web/mixins/file-upload';
-
-export default ApplicationAdapter.extend(FileUploadAdapter, {
- getFormFields(data) {
- return {
- 'datasheet': data['data']['attributes']['datasheet'],
- 'collection': JSON.stringify(data['data']['relationships']['collection']['data']),
- }
- },
-
- getFormKey(key) {
- return key;
- },
-
- getFormValue(key, value) {
- return value;
- },
-});
diff --git a/app/app.js b/app/app.js
index b3b2bd6..f796e79 100644
--- a/app/app.js
+++ b/app/app.js
@@ -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
diff --git a/app/authenticators/application.js b/app/authenticators/application.js
index 075eeff..3ae0d7d 100644
--- a/app/authenticators/application.js
+++ b/app/authenticators/application.js
@@ -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',
diff --git a/app/authorizers/application.js b/app/authorizers/application.js
index 740f446..b8c154c 100644
--- a/app/authorizers/application.js
+++ b/app/authorizers/application.js
@@ -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');
diff --git a/app/components/action-button.js b/app/components/action-button.js
deleted file mode 100644
index 061b53b..0000000
--- a/app/components/action-button.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
- tagName: 'a',
- classNames: ['btn'],
- classNameBindings: [
- // Styles
- 'isDefault:btn-default',
- 'isPrimary:btn-primary',
- 'isSuccess:btn-success',
- 'isInfo:btn-info',
- 'isWarning:btn-warning',
- 'isDanger:btn-danger',
- 'isLink:btn-link',
- // Sizes
- 'isLarge:btn-lg',
- 'isSmall:btn-sm',
- 'isXSmall:btn-xs',
- ],
-
- // ARGS
- // Styles
- isDefault: false,
- isPrimary: false,
- isSuccess: false,
- isInfo: false,
- isWarning: false,
- isDanger: false,
- isLink: false,
- // Sizes
- isLarge: false,
- isSmall: false,
- isXSmall: false,
-
- label: 'LABEL',
-
- click() {
- this.get('onClick')();
- }
-});
diff --git a/app/components/admin-section-list.js b/app/components/admin-section-list.js
index 5570647..00d6fa3 100644
--- a/app/components/admin-section-list.js
+++ b/app/components/admin-section-list.js
@@ -1,3 +1,5 @@
-import Component from '@ember/component';
+import Ember from 'ember';
+
+const { Component } = Ember;
export default Component.extend({});
diff --git a/app/components/ccdb-filter.js b/app/components/ccdb-filter.js
deleted file mode 100644
index db2ed63..0000000
--- a/app/components/ccdb-filter.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({ });
diff --git a/app/components/ccdb-pagination.js b/app/components/ccdb-pagination.js
index 233ca4c..1ef4a00 100644
--- a/app/components/ccdb-pagination.js
+++ b/app/components/ccdb-pagination.js
@@ -1,41 +1,5 @@
-import Component from '@ember/component';
-import { alias } from '@ember/object/computed';
-import { computed } from '@ember/object';
+import Ember from 'ember';
-export default Component.extend({
- // ARGS
- model: null,
-
- // COMPUTED
- meta: alias('model.meta'),
- links: alias('meta.links'),
-
- currentPage: alias('meta.pagination.page'),
- totalRecords: alias('meta.pagination.count'),
-
- firstLink: alias('links.first'),
- lastLink: alias('links.last'),
- nextLink: alias('links.next'),
- prevLink: alias('links.prev'),
-
- _getPage(link) {
- link = this.get(link);
- if (link === null) {
- return null;
- }
- const url = new URL(link);
- return parseInt(url.searchParams.get('page'));
- },
-
- _notEqual(a, b) {
- return this.get(a) !== this.get(b);
- },
-
- first: computed('firstLink', function() { return this._getPage('firstLink'); }),
- last: computed('lastLink', function() { return this._getPage('lastLink'); }),
- next: computed('nextLink', function() { return this._getPage('nextLink'); }),
- prev: computed('prevLink', function() { return this._getPage('prevLink'); }),
-
- notOnFirst: computed('first', 'currentPage', function() { return this._notEqual('first', 'currentPage'); }),
- notOnLast: computed('last', 'currentPage', function() { return this._notEqual('last', 'currentPage'); }),
+export default Ember.Component.extend({
+ classNames: ['row'],
});
diff --git a/app/components/ccdb-table.js b/app/components/ccdb-table.js
index 8aade24..fce3474 100644
--- a/app/components/ccdb-table.js
+++ b/app/components/ccdb-table.js
@@ -1,13 +1,16 @@
-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,
columns: null,
-
table: null,
- didReceiveAttrs() {
+
+ classNames: ['row'],
+
+ init() {
this._super(...arguments);
const table = new Table(this.get('columns'), this.get('model'));
this.set('table', table);
diff --git a/app/components/collection/create-container.js b/app/components/collection/create-container.js
deleted file mode 100644
index fd599fa..0000000
--- a/app/components/collection/create-container.js
+++ /dev/null
@@ -1,93 +0,0 @@
-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 Changeset from 'ember-changeset';
-import lookupValidator from 'ember-changeset-validations';
-import config from 'ccdb-web/config/environment';
-
-export default Component.extend({
- store: service(),
-
- init() {
- 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['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 });
- });
- changesets['hasMany'][hasMany] = relatedChangesets;
- });
-
- this.set('changesets', changesets);
- this.set('newStudyLocationAdmin', `${config.APP.API_HOST}/admin/locations/studylocation/add/`);
- },
-
- actions: {
- addHasMany(modelName, relatedName) {
- 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 });
- },
-
- deleteHasMany(changesetRecord, relatedName) {
- 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);
- });
- },
-
- 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);
- });
- },
- },
-
- _performSearch(model, payload, resolve, reject) {
- this.get('store').query(model, payload).then((results) => {
- resolve(results);
- }, reject);
- },
-});
diff --git a/app/components/collection/detail-container.js b/app/components/collection/detail-container.js
deleted file mode 100644
index 66f9ba1..0000000
--- a/app/components/collection/detail-container.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
- // ARGS
- model: null,
-
- mainColumns: [
- { label: 'Project', valuePath: 'project.name', },
- { label: 'IACUC', valuePath: 'project.iacucNumber', },
- { label: 'Region', valuePath: 'studyLocation.site.region.name', },
- { label: 'Site', valuePath: 'studyLocation.site.name', },
- { label: 'Study Location', valuePath: 'studyLocation.code', },
- { label: 'Method', valuePath: 'collectionMethod.code', },
- { label: 'Type', valuePath: 'collectionType.name', },
- { label: '# of Traps', valuePath: 'numberOfTraps', },
- { label: 'Start', valuePath: 'startDateTime', },
- { label: 'End', valuePath: 'endDateTime', },
- { label: 'ADFG Permit', valuePath: 'adfgPermit.name', },
- ],
-
- collectionSpeciesColumns: [
- { 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', },
- ],
-});
diff --git a/app/components/collection/list-container.js b/app/components/collection/list-container.js
deleted file mode 100644
index 184a11d..0000000
--- a/app/components/collection/list-container.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
- // ARGS
- model: null,
-
- columns: [
- { label: 'Project', valuePath: 'project.name', },
- { label: 'IACUC', valuePath: 'project.iacucNumber', },
- { label: 'Species', valuePath: 'speciesAndCounts', },
- { label: 'Region', valuePath: 'studyLocation.site.region.name', },
- { label: 'Site', valuePath: 'studyLocation.site.name', },
- { label: 'Study Location', valuePath: 'studyLocation.code', },
- { label: 'Method', valuePath: 'collectionMethod.name', },
- { label: '# of Traps', valuePath: 'numberOfTraps', },
- { label: 'Start', valuePath: 'startDateTime', },
- { label: 'End', valuePath: 'endDateTime', },
- { label: 'ADFG Permit', valuePath: 'adfgPermit.name', },
- ],
-});
diff --git a/app/components/collections-container.js b/app/components/collections-container.js
new file mode 100644
index 0000000..376c977
--- /dev/null
+++ b/app/components/collections-container.js
@@ -0,0 +1,15 @@
+import Ember from 'ember';
+
+const { Component } = Ember;
+
+export default Component.extend({
+ columns: [
+ { label: 'Project', valuePath: 'project.name', },
+ { label: 'Study Location', valuePath: 'studyLocation.code', },
+ { label: 'Method', valuePath: 'collectionMethod.code', },
+ { label: 'Type', valuePath: 'collectionType.name', },
+ { label: '# of Traps', valuePath: 'numberOfTraps', },
+ { label: 'Start', valuePath: 'startDateTime', },
+ { label: 'End', valuePath: 'endDateTime', },
+ ],
+});
diff --git a/app/components/confirm-button.js b/app/components/confirm-button.js
deleted file mode 100644
index 89e921a..0000000
--- a/app/components/confirm-button.js
+++ /dev/null
@@ -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')();
- },
- },
-});
diff --git a/app/components/crud-form.js b/app/components/crud-form.js
deleted file mode 100644
index 889c937..0000000
--- a/app/components/crud-form.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
- // ARGS
- changesets: null,
-});
diff --git a/app/components/filter-collections.js b/app/components/filter-collections.js
new file mode 100644
index 0000000..16e66b5
--- /dev/null
+++ b/app/components/filter-collections.js
@@ -0,0 +1,5 @@
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+ tagName: 'form',
+});
diff --git a/app/components/form-content.js b/app/components/form-content.js
deleted file mode 100644
index 9d2bc5a..0000000
--- a/app/components/form-content.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
- tagName: 'form',
-});
diff --git a/app/components/loading-spinner.js b/app/components/loading-spinner.js
index 8ee064f..f65d12f 100644
--- a/app/components/loading-spinner.js
+++ b/app/components/loading-spinner.js
@@ -1,4 +1,6 @@
-import Component from '@ember/component';
+import Ember from 'ember';
+
+const { Component } = Ember;
export default Component.extend({
classNames: ['spinner'],
diff --git a/app/components/validated-field.js b/app/components/validated-field.js
deleted file mode 100644
index a505dcf..0000000
--- a/app/components/validated-field.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import Component from '@ember/component';
-import { get, computed } from '@ember/object';
-import { isEmpty } from '@ember/utils';
-
-export default Component.extend({
- classNames: ['form-group'],
- classNameBindings: ['isValid::has-error'],
-
- isValid: computed('changeset.error', 'property', function() {
- const changeset = this.get('changeset');
- const property = this.get('property');
- return isEmpty(get(changeset, `error.${property}`));
- }),
-
- hasLabel: computed('label', function() {
- return !isEmpty(get(this, 'label'));
- }),
-});
diff --git a/app/controllers/application.js b/app/controllers/application.js
index 5e8a1e1..59d2822 100644
--- a/app/controllers/application.js
+++ b/app/controllers/application.js
@@ -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'),
diff --git a/app/controllers/collections/create.js b/app/controllers/collections/create.js
deleted file mode 100644
index 9234268..0000000
--- a/app/controllers/collections/create.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import Controller from '@ember/controller';
-import { computed } from '@ember/object';
-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';
-
-export default Controller.extend(ValidationMixin, {
- CollectionValidations,
- CollectionSpeciesValidations,
- DatasheetValidations,
- CollectionMeasurementValidations,
-
- hasMany: ['collectionSpecies', 'datasheets', 'envMeasurements'],
-
- options: computed('projectOptions', 'studyLocationOptions',
- 'collectionTypeOptions', 'collectionMethodOptions',
- 'speciesOptions', 'adfgPermitOptions', 'sexOptions',
- function() {
- return {
- projects: this.get('projectOptions'),
- studyLocations: this.get('studyLocationOptions'),
- collectionTypes: this.get('collectionTypeOptions'),
- 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);
- });
- },
- },
-});
diff --git a/app/controllers/collections/detail/edit.js b/app/controllers/collections/detail/edit.js
deleted file mode 100644
index 6133707..0000000
--- a/app/controllers/collections/detail/edit.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import Controller from '@ember/controller';
-import { computed } from '@ember/object';
-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';
-
-export default Controller.extend(ValidationMixin, {
- CollectionValidations,
- CollectionSpeciesValidations,
- DatasheetValidations,
- CollectionMeasurementValidations,
-
- hasMany: ['collectionSpecies', 'datasheets', 'envMeasurements'],
-
- options: computed('projectOptions', 'studyLocationOptions',
- 'collectionTypeOptions', 'collectionMethodOptions',
- 'speciesOptions', 'adfgPermitOptions', 'sexOptions',
- function() {
- return {
- projects: this.get('projectOptions'),
- studyLocations: this.get('studyLocationOptions'),
- collectionTypes: this.get('collectionTypeOptions'),
- collectionMethods: this.get('collectionMethodOptions'),
- species: this.get('speciesOptions'),
- adfgPermits: this.get('adfgPermitOptions'),
- sexes: this.get('sexOptions'),
- };
- }),
-
- actions: {
- onSave(changesets) {
- const postSave = () => {
- // Use the model's ID here because of the ArrayProxy in the route
- this.transitionToRoute('collections.detail', this.get('model.id'));
- };
- return this.transitionToRoute('loading').then(() => {
- return this.validationSave(changesets, postSave);
- });
- },
- onCancel(changesets) {
- const postCancel = () => {
- // Use the model's ID here because of the ArrayProxy in the route
- return this.transitionToRoute('collections.detail', this.get('model.id'));
- };
- return this.transitionToRoute('loading').then(() => {
- return this.validationCancel(changesets, postCancel);
- });
- },
- },
-});
diff --git a/app/controllers/collections/detail/index.js b/app/controllers/collections/detail/index.js
deleted file mode 100644
index e0bc42c..0000000
--- a/app/controllers/collections/detail/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import Controller from '@ember/controller';
-
-export default Controller.extend({
- actions: {
- editCollection() {
- this.transitionToRoute('collections.detail.edit', this.get('model'));
- },
- deleteCollection() {
- this.get('model')[0].destroyRecord().then(() => {
- this.transitionToRoute('collections');
- });
- },
- },
-});
diff --git a/app/controllers/collections/index.js b/app/controllers/collections/index.js
deleted file mode 100644
index d4a8cdf..0000000
--- a/app/controllers/collections/index.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import Controller from '@ember/controller';
-import { set, get, computed } from '@ember/object';
-
-
-export default Controller.extend({
- queryParams: ['page', 'project', 'region', 'site', 'study_location',
- 'collection_method', 'number_of_traps', 'collection_start_date',
- 'collection_end_date', 'adfg_permit', 'species'],
- page: 1,
- project: [],
- region: [],
- site: [],
- study_location: [],
- collection_method: [],
- adfg_permit: [],
- species: [],
- number_of_traps: '',
- collection_start_date: '',
- collection_end_date: '',
-
- options: computed('projectOptions', 'regionOptions', 'siteOptions',
- 'studyLocationOptions', 'collectionMethodOptions',
- 'adfgPermitOptions', 'speciesOptions', function() {
- return {
- projects: this.get('projectOptions'),
- regions: this.get('regionOptions'),
- sites: this.get('siteOptions'),
- studyLocations: this.get('studyLocationOptions'),
- collectionMethods: this.get('collectionMethodOptions'),
- adfgPermits: this.get('adfgPermitOptions'),
- species: this.get('speciesOptions'),
- };
- }),
-
- _coerceId(model) {
- return +get(model, 'id');
- },
-
- actions: {
- changePage(page) {
- this.set('page', page);
- },
- rowClick(row) {
- this.transitionToRoute('collections.detail', row.get('id'));
- },
- createCollection() {
- this.transitionToRoute('collections.create');
- },
- resetFilter() {
- set(this, 'page', 1);
- ['project', 'region', 'site', 'study_location', 'collection_method',
- 'adfg_permit', 'species'].forEach((field) => {
- set(this, field, []);
- });
- ['number_of_traps', 'collection_start_date', 'collection_end_date'].forEach((field) => {
- set(this, field, '');
- });
- },
- changeFilter(filter) {
- // Need to reset the page so that things don't get weird
- set(this, 'page', 1);
-
- const filterModelFields = ['project', 'region', 'site', 'study_location',
- 'collection_method', 'adfg_permit', 'species'];
-
- filterModelFields.forEach((field) => {
- let fields = get(filter, field);
- fields = fields.map(this._coerceId);
- set(this, field, fields);
- });
-
- set(this, 'number_of_traps', get(filter, 'number_of_traps'));
-
- ['collection_start_date', 'collection_end_date'].forEach((field) => {
- let value = get(filter, field);
- if (value) {
- value = value.toJSON().split('T')[0];
- } else {
- value = '';
- }
- set(this, field, value);
- });
- },
- },
-});
diff --git a/app/controllers/login.js b/app/controllers/login.js
index 7311a02..e5bb9c8 100644
--- a/app/controllers/login.js
+++ b/app/controllers/login.js
@@ -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(),
diff --git a/app/index.html b/app/index.html
index edae105..e01418d 100644
--- a/app/index.html
+++ b/app/index.html
@@ -17,8 +17,8 @@
{{content-for "body"}}
-
-
+
+
{{content-for "body-footer"}}
diff --git a/app/mixins/file-upload.js b/app/mixins/file-upload.js
deleted file mode 100644
index 5117782..0000000
--- a/app/mixins/file-upload.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import Mixin from '@ember/object/mixin';
-import { isArray } from '@ember/array';
-const { keys } = Object;
-
-// Portions borrowed from https://github.com/funtusov/ember-cli-form-data
-// (that project has an MIT license listed, but no copyright holder explicitly identified)
-export default Mixin.create({
- formDataTypes: ['POST', 'PUT', 'PATCH'],
-
- ajaxOptions(url, type, options) {
- let data;
- if (options && 'data' in options) { data = options.data; }
- let hash = this._super.apply(this, arguments);
-
- if (typeof FormData !== 'undefined' && data && this.formDataTypes.indexOf(type) >= 0) {
- hash.processData = false;
- hash.contentType = false;
- hash.data = this._getFormData(data);
- }
- return hash;
- },
-
- getFormFields(data) {
- this._root = this._root || keys(data)[0];
- return data[this._root];
- },
-
- getFormKey(key) {
- return `${this._root}[${key}]`;
- },
-
- getFormValue(key, value) {
- return value;
- },
-
- _getFormData(data) {
- let formData = new FormData();
- const fields = this.getFormFields(data);
-
- keys(fields).forEach((key) => {
- this._appendValue(
- this.getFormValue(key, fields[key]),
- this.getFormKey(key, fields[key]),
- formData);
- });
- return formData;
- },
-
- _appendValue(value, formKey, formData) {
- if (isArray(value)) {
- value.forEach((item) => {
- this._appendValue(item, `${formKey}[]`, formData);
- });
- } else if (value && value.constructor === Object) {
- keys(value).forEach((key) => {
- this._appendValue(value[key], `${formKey}[${key}]`, formData);
- });
- } else if (typeof value !== 'undefined'){
- formData.append(formKey, value === null ? '' : value);
- }
- },
-});
diff --git a/app/mixins/validation.js b/app/mixins/validation.js
deleted file mode 100644
index 7e8c1cf..0000000
--- a/app/mixins/validation.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import Mixin from '@ember/object/mixin';
-import { get } from '@ember/object';
-import RSVP from 'rsvp';
-const { keys } = Object;
-
-export default Mixin.create({
- validationSave(changesets, postSave) {
- let promises = [], changes = [], saves = [], isValid = true;
-
- let modelChangeset = changesets['model'];
-
- // first, delete anything that needs to be removed
- for (const model of changesets['delete']) {
- promises.push(model.destroyRecord());
- }
-
- // second, handle changes on parent model (this is important if new)
- modelChangeset.validate().then(() => {
- if (modelChangeset.get('isValid')) {
- return modelChangeset.save();
- }
- }).then(() => {
- for (const hasMany of keys(changesets['hasMany'])) {
- for (const { changeset } of changesets['hasMany'][hasMany]) {
- promises.push(changeset.validate());
- changes.push(changeset);
- }
- }
- return RSVP.all(promises);
- }).then(() => { // don't need the promises, just that they are done.
- for (let changeset of changes) {
- if (get(changeset, 'isValid')) {
- let saver = changeset.save().catch((error) => {
- /* eslint-disable no-console */
- console.log(error);
- /* eslint-enable no-console */
- // TODO: do something with server-side non-attr errors
- });
- saves.push(saver);
- } else {
- isValid = false;
- }
- }
- return RSVP.all(saves);
- }).then(() => {
- if (isValid) { return postSave(); }
- });
- },
-
- validationCancel(changesets, postCancel) {
- delete changesets['delete'];
- for (const key of keys(changesets)) {
- if (key === 'new') {
- 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) {
- changeset.rollback();
- }
- }
- } else { // single
- const changeset = changesets[key];
- changeset.rollback();
- }
- }
-
- return postCancel();
- },
-});
diff --git a/app/models/adfg-permit.js b/app/models/adfg-permit.js
deleted file mode 100644
index de48a20..0000000
--- a/app/models/adfg-permit.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import DS from 'ember-data';
-
-const { Model, attr, hasMany } = DS;
-
-export default Model.extend({
- name: attr('string'),
- sortOrder: attr('number'),
-
- collection: hasMany('collection'),
-});
diff --git a/app/models/collection-measurement.js b/app/models/collection-measurement.js
deleted file mode 100644
index 41eef75..0000000
--- a/app/models/collection-measurement.js
+++ /dev/null
@@ -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'),
-});
diff --git a/app/models/collection-species.js b/app/models/collection-species.js
deleted file mode 100644
index 5839d7c..0000000
--- a/app/models/collection-species.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import DS from 'ember-data';
-
-const { Model, attr, belongsTo } = DS;
-
-export default Model.extend({
- sex: belongsTo('sex'),
- count: attr('number'),
- countEstimated: attr('boolean', { defaultValue: false }),
-
- collection: belongsTo('collection'),
- species: belongsTo('species'),
-});
diff --git a/app/models/collection.js b/app/models/collection.js
index 05c90fd..c2fc7c9 100644
--- a/app/models/collection.js
+++ b/app/models/collection.js
@@ -1,41 +1,21 @@
-import { mapBy } from '@ember/object/computed';
-import { computed } from '@ember/object';
+import Ember from 'ember';
import DS from 'ember-data';
-const { Model, attr, belongsTo, hasMany } = DS;
+const { computed } = Ember;
+const { Model, attr, belongsTo } = 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'),
- collectionMethod: belongsTo('collection-method'),
- collectionType: belongsTo('collection-type'),
- adfgPermit: belongsTo('adfg-permit'),
-
- collectionSpecies: hasMany('collection-species'),
- datasheets: hasMany('datasheet-attachment'),
- envMeasurements: hasMany('collection-measurement'),
-
- // computed
- species: mapBy('collectionSpecies', 'species'),
-
- speciesNames: mapBy('species', 'commonName'),
-
- counts: mapBy('collectionSpecies', 'count'),
-
- speciesAndCounts: computed('speciesNames', 'counts', function() {
- const speciesNames = this.get('speciesNames');
- let counts = this.get('counts');
- counts = counts.map(c => c !== null ? c : 'No Count');
- return speciesNames.map((n, i) => `${n} (${counts[i]})`).join(', ');
- }),
+ project: belongsTo('project'),
+ studyLocation: belongsTo('study-location'),
+ collectionMethod: belongsTo('collection-method'),
+ collectionType: belongsTo('collection-type'),
startDateTime: computed('collectionStartDate', 'collectionStartTime',
function() { return this._mergeDateTime('Start'); }),
diff --git a/app/models/datasheet-attachment.js b/app/models/datasheet-attachment.js
deleted file mode 100644
index 2c02202..0000000
--- a/app/models/datasheet-attachment.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import DS from 'ember-data';
-
-const { Model, attr, belongsTo } = DS;
-
-export default Model.extend({
- datasheet: attr('file'),
-
- collection: belongsTo('collection'),
-});
diff --git a/app/models/region.js b/app/models/region.js
deleted file mode 100644
index 3530700..0000000
--- a/app/models/region.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import DS from 'ember-data';
-
-const { Model, attr, hasMany } = DS;
-
-export default Model.extend({
- name: attr('string'),
- code: attr('string'),
- sortOrder: attr('number'),
-
- site: hasMany('site'),
-});
diff --git a/app/models/sex.js b/app/models/sex.js
deleted file mode 100644
index 6f3b265..0000000
--- a/app/models/sex.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import DS from 'ember-data';
-
-const { Model, attr } = DS;
-
-export default Model.extend({
- name: attr('string'),
- sortOrder: attr('number'),
-});
diff --git a/app/models/site.js b/app/models/site.js
deleted file mode 100644
index 04402e7..0000000
--- a/app/models/site.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import DS from 'ember-data';
-
-const { Model, attr, hasMany, belongsTo } = DS;
-
-export default Model.extend({
- name: attr('string'),
- code: attr('string'),
- description: attr('string'),
- sortOrder: attr('number'),
-
- region: belongsTo('region'),
- studyLocation: hasMany('study-location'),
-});
diff --git a/app/models/species.js b/app/models/species.js
deleted file mode 100644
index e66c4f9..0000000
--- a/app/models/species.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import DS from 'ember-data';
-
-const { Model, attr } = DS;
-
-export default Model.extend({
- commonName: attr('string'),
- genus: attr('string'),
- species: attr('string'),
- parasite: attr('boolean'),
- sortOrder: attr('number'),
-});
diff --git a/app/models/study-location.js b/app/models/study-location.js
index 28969aa..7568218 100644
--- a/app/models/study-location.js
+++ b/app/models/study-location.js
@@ -1,6 +1,6 @@
import DS from 'ember-data';
-const { Model, attr, belongsTo } = DS;
+const { Model, attr } = DS;
export default Model.extend({
name: attr('string'),
@@ -10,6 +10,4 @@ export default Model.extend({
collectingLocation: attr('string'),
description: attr('string'),
sortOrder: attr('number'),
-
- site: belongsTo('site'),
});
diff --git a/app/router.js b/app/router.js
index af47bd2..03cadfc 100644
--- a/app/router.js
+++ b/app/router.js
@@ -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
});
@@ -10,10 +10,8 @@ Router.map(function() {
this.route('login');
this.route('logout');
this.route('collections', function() {
- this.route('create');
- this.route('detail', { path: '/:collection_id' }, function() {
- this.route('edit');
- });
+ this.route('1');
+ this.route('new');
});
});
diff --git a/app/routes/application.js b/app/routes/application.js
index b83c2c8..38bb6b3 100644
--- a/app/routes/application.js
+++ b/app/routes/application.js
@@ -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, {});
diff --git a/app/routes/collections/1.js b/app/routes/collections/1.js
new file mode 100644
index 0000000..26d9f31
--- /dev/null
+++ b/app/routes/collections/1.js
@@ -0,0 +1,4 @@
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+});
diff --git a/app/routes/collections/create.js b/app/routes/collections/create.js
deleted file mode 100644
index 4c0ba55..0000000
--- a/app/routes/collections/create.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import Route from '@ember/routing/route';
-import RSVP from 'rsvp';
-
-export default Route.extend({
- 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 }),
- collectionTypeOptions: store.findAll('collection-type'),
- collectionMethodOptions: store.findAll('collection-method'),
- speciesOptions: store.query('species', { page_size: 500 }),
- adfgPermitOptions: store.findAll('adfg-permit'),
- sexOptions: store.findAll('sex'),
- });
- },
-
- setupController(controller, models) {
- this._super(...arguments);
- controller.setProperties(models);
- },
-});
diff --git a/app/routes/collections/detail.js b/app/routes/collections/detail.js
deleted file mode 100644
index 354115c..0000000
--- a/app/routes/collections/detail.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Route from '@ember/routing/route';
-import RSVP from 'rsvp';
-
-export default Route.extend({
- model(params) {
- return RSVP.all([
- this.get('store').findRecord('collection', params.collection_id, {
- include: 'collection-species,datasheets,env-measurements',
- })
- ]);
- },
-});
diff --git a/app/routes/collections/detail/edit.js b/app/routes/collections/detail/edit.js
deleted file mode 100644
index 21a6bd4..0000000
--- a/app/routes/collections/detail/edit.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import Route from '@ember/routing/route';
-import RSVP from 'rsvp';
-
-export default Route.extend({
- 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 }),
- collectionTypeOptions: store.findAll('collection-type'),
- collectionMethodOptions: store.findAll('collection-method'),
- speciesOptions: store.query('species', { page_size: 500 }),
- adfgPermitOptions: store.findAll('adfg-permit'),
- sexOptions: store.findAll('sex'),
- });
- },
-
- setupController(controller, models) {
- this._super(...arguments);
- // Unwrap the parent route's listified model
- models.model = models.model[0];
- controller.setProperties(models);
- },
-});
diff --git a/app/routes/collections/index.js b/app/routes/collections/index.js
index 2f65aba..9b3a78a 100644
--- a/app/routes/collections/index.js
+++ b/app/routes/collections/index.js
@@ -1,96 +1,11 @@
-import Route from '@ember/routing/route';
-import RSVP from 'rsvp';
+import Ember from 'ember';
+
+const { Route } = Ember;
export default Route.extend({
- queryParams: {
- // qps are snake_case for the django api
- page: { refreshModel: true },
- project: { refreshModel: true },
- region: { refreshModel: true },
- site: { refreshModel: true },
- study_location: { refreshModel: true },
- collection_method: { refreshModel: true },
- number_of_traps: { refreshModel: true },
- collection_start_date: { refreshModel: true },
- collection_end_date: { refreshModel: true },
- adfg_permit: { refreshModel: true },
- species: { refreshModel: true },
- },
-
- model(params) {
- const store = this.get('store');
- const includes = ['project', 'study-location', 'study-location.site', 'site',
- 'collection-method', 'adfg-permit', 'collection-species', 'collection-species.species'];
- const opts = {
- include: includes.join(','),
- };
-
- return RSVP.hash({
- projectOptions: store.findAll('project'),
- regionOptions: store.findAll('region'),
- siteOptions: store.findAll('site'),
- studyLocationOptions: store.query('study-location', { page_size: 500 }),
- collectionMethodOptions: store.findAll('collection-method'),
- adfgPermitOptions: store.findAll('adfg-permit'),
- speciesOptions: store.query('species', { page_size: 500 }),
- model: store.query('collection', Object.assign(params, opts)),
+ model() {
+ return this.get('store').findAll('collection', {
+ include: 'project,study-location,collection-method,collection-type'
});
- },
-
- setupController(controller, models) {
- this._super(...arguments);
- controller.setProperties(models);
-
- 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');
-
- let filter = {
- project,
- region,
- site,
- study_location: studyLocation,
- collection_method: collectionMethod,
- number_of_traps: numberOfTraps,
- collection_start_date: collectionStartDate,
- collection_end_date: collectionEndDate,
- adfg_permit: adfgPermit,
- species,
- }
- controller.set('filters', filter);
- },
+ }
});
diff --git a/app/routes/collections/new.js b/app/routes/collections/new.js
new file mode 100644
index 0000000..26d9f31
--- /dev/null
+++ b/app/routes/collections/new.js
@@ -0,0 +1,4 @@
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+});
diff --git a/app/routes/index.js b/app/routes/index.js
index 6d9dcb7..ed916b6 100644
--- a/app/routes/index.js
+++ b/app/routes/index.js
@@ -1,8 +1,6 @@
-import Route from '@ember/routing/route';
+import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
-export default Route.extend(AuthenticatedRouteMixin, {
- afterModel() {
- this.transitionTo('collections');
- },
-});
+const { Route } = Ember;
+
+export default Route.extend(AuthenticatedRouteMixin, {});
diff --git a/app/routes/login.js b/app/routes/login.js
index e05233c..a9687fd 100644
--- a/app/routes/login.js
+++ b/app/routes/login.js
@@ -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, {});
diff --git a/app/routes/logout.js b/app/routes/logout.js
index 0056d12..c83dc10 100644
--- a/app/routes/logout.js
+++ b/app/routes/logout.js
@@ -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'),
diff --git a/app/serializers/application.js b/app/serializers/application.js
deleted file mode 100644
index d8d8701..0000000
--- a/app/serializers/application.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { capitalize } from '@ember/string';
-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;
- },
-});
diff --git a/app/styles/app.css b/app/styles/app.css
index 1a2d097..b74ca4b 100644
--- a/app/styles/app.css
+++ b/app/styles/app.css
@@ -1,13 +1,12 @@
-[data-ember-action]:not(:disabled) {
- cursor: pointer;
+.content {
+ padding-left: 40px;
+ padding-right: 40px;
+ padding-top: 20px;
+ padding-bottom: 20px;
}
-.table-nav .pager {
- margin-top: 10px;
-}
-
-.table-stats {
- margin-top: 10px;
+.top-buffer {
+ padding-top: 20px;
}
.form-signin {
@@ -50,10 +49,6 @@
border-top-right-radius: 0;
}
-.top-buffer {
- margin-top: 20px;
-}
-
/* Sidebar */
.sidebar {
position: fixed;
diff --git a/app/templates/application.hbs b/app/templates/application.hbs
index 51cd191..28f30f7 100644
--- a/app/templates/application.hbs
+++ b/app/templates/application.hbs
@@ -3,6 +3,10 @@