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: |   only: | ||||||
|     - master |     - master | ||||||
| node_js: | node_js: | ||||||
|   - "9" |   - '6' | ||||||
| sudo: required | sudo: false | ||||||
| dist: trusty |  | ||||||
| addons: |  | ||||||
|   chrome: stable |  | ||||||
| cache: | cache: | ||||||
|   directories: |   directories: | ||||||
|   - "$HOME/.npm" |   - "$HOME/.npm" | ||||||
| env: |  | ||||||
|   global: |  | ||||||
|     - JOBS=1 |  | ||||||
| before_install: | before_install: | ||||||
|   - npm config set spin false |   - npm config set spin false | ||||||
|   - npm install -g phantomjs-prebuilt |   - 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/) | * [Git](https://git-scm.com/) | ||||||
| * [Node.js](https://nodejs.org/) (with NPM) | * [Node.js](https://nodejs.org/) (with NPM) | ||||||
| * [Ember CLI](https://ember-cli.com/) | * [Ember CLI](https://ember-cli.com/) | ||||||
| * [Google Chrome](https://google.com/chrome/) | * [PhantomJS](http://phantomjs.org/) | ||||||
| 
 | 
 | ||||||
| ## Installation | ## Installation | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,9 +1,11 @@ | ||||||
| import Application from '@ember/application'; | import Ember from 'ember'; | ||||||
| import Resolver from './resolver'; | import Resolver from './resolver'; | ||||||
| import loadInitializers from 'ember-load-initializers'; | import loadInitializers from 'ember-load-initializers'; | ||||||
| import config from './config/environment'; | import config from './config/environment'; | ||||||
| 
 | 
 | ||||||
| const App = Application.extend({ | let App; | ||||||
|  | 
 | ||||||
|  | App = Ember.Application.extend({ | ||||||
|   modulePrefix: config.modulePrefix, |   modulePrefix: config.modulePrefix, | ||||||
|   podModulePrefix: config.podModulePrefix, |   podModulePrefix: config.podModulePrefix, | ||||||
|   Resolver |   Resolver | ||||||
|  |  | ||||||
|  | @ -1,11 +1,9 @@ | ||||||
| import { Promise } from 'rsvp'; | import Ember from 'ember'; | ||||||
| import $ from 'jquery'; |  | ||||||
| import { get } from '@ember/object'; |  | ||||||
| import { isEmpty } from '@ember/utils'; |  | ||||||
| import { run } from '@ember/runloop'; |  | ||||||
| import BaseAuthenticator from 'ember-simple-auth/authenticators/base'; | import BaseAuthenticator from 'ember-simple-auth/authenticators/base'; | ||||||
| import config from '../config/environment'; | import config from '../config/environment'; | ||||||
| 
 | 
 | ||||||
|  | const { RSVP: { Promise }, $, get, isEmpty, run } = Ember; | ||||||
|  | 
 | ||||||
| export default BaseAuthenticator.extend({ | export default BaseAuthenticator.extend({ | ||||||
|   serverTokenEndpoint: `${config.APP.API_HOST}/api/auth/login/`, |   serverTokenEndpoint: `${config.APP.API_HOST}/api/auth/login/`, | ||||||
|   tokenAttributeName: 'data.attributes.auth-token', |   tokenAttributeName: 'data.attributes.auth-token', | ||||||
|  |  | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| import { isEmpty } from '@ember/utils'; | import Ember from 'ember'; | ||||||
| import { get } from '@ember/object'; |  | ||||||
| import BaseAuthorizer from 'ember-simple-auth/authorizers/base'; | import BaseAuthorizer from 'ember-simple-auth/authorizers/base'; | ||||||
| 
 | 
 | ||||||
|  | const { isEmpty, get } = Ember; | ||||||
|  | 
 | ||||||
| export default BaseAuthorizer.extend({ | export default BaseAuthorizer.extend({ | ||||||
|   authorize(data, block) { |   authorize(data, block) { | ||||||
|     const accessToken = get(data, 'data.attributes.auth-token'); |     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({ | export default Component.extend({ | ||||||
|   tagName: 'a', |   tagName: 'a', | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
|  | 
 | ||||||
|  | const { Component } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({}); | export default Component.extend({}); | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
|  | 
 | ||||||
|  | const { Component } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ }); | export default Component.extend({ }); | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
| import { alias } from '@ember/object/computed'; | 
 | ||||||
| import { computed } from '@ember/object'; | const { Component, computed: { alias }, computed } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   // ARGS
 |   // ARGS
 | ||||||
|  | @ -8,7 +8,7 @@ export default Component.extend({ | ||||||
| 
 | 
 | ||||||
|   // COMPUTED
 |   // COMPUTED
 | ||||||
|   meta: alias('model.meta'), |   meta: alias('model.meta'), | ||||||
|   links: alias('meta.links'), |   links: alias('model.links'), | ||||||
| 
 | 
 | ||||||
|   currentPage: alias('meta.pagination.page'), |   currentPage: alias('meta.pagination.page'), | ||||||
|   totalRecords: alias('meta.pagination.count'), |   totalRecords: alias('meta.pagination.count'), | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
| import Table from 'ember-light-table'; | import Table from 'ember-light-table'; | ||||||
| 
 | 
 | ||||||
|  | const { Component } = Ember; | ||||||
|  | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   // ARGS
 |   // ARGS
 | ||||||
|   model: null, |   model: null, | ||||||
|  |  | ||||||
|  | @ -1,11 +1,8 @@ | ||||||
| import { getProperties, set } from '@ember/object'; | import Ember from 'ember'; | ||||||
| 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 Changeset from 'ember-changeset'; | ||||||
| import lookupValidator from 'ember-changeset-validations'; | import lookupValidator from 'ember-changeset-validations'; | ||||||
| import config from 'ccdb-web/config/environment'; | 
 | ||||||
|  | const { Component, inject: { service } } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   store: service(), |   store: service(), | ||||||
|  | @ -14,80 +11,81 @@ export default Component.extend({ | ||||||
|     this._super(...arguments); |     this._super(...arguments); | ||||||
|     const model = this.get('model'); |     const model = this.get('model'); | ||||||
|     const validations = this.get('validations'); |     const validations = this.get('validations'); | ||||||
|     const hasMany = this.get('hasMany'); |  | ||||||
| 
 | 
 | ||||||
|     let changesets = {}; |     let changesets = {}; | ||||||
|     changesets['new'] = []; |     changesets['new'] = []; | ||||||
|     changesets['delete'] = []; |     changesets['delete'] = []; | ||||||
|     changesets['hasMany'] = {}; |     changesets['hasMany'] = []; | ||||||
|     changesets['model'] = new Changeset(model, |     changesets['model'] = new Changeset(model, | ||||||
|                                         lookupValidator(validations['collection']), |                                         lookupValidator(validations['collection']), | ||||||
|                                         validations['collection']); |                                         validations['collection']); | ||||||
| 
 | 
 | ||||||
|     hasMany.forEach((hasMany) => { |     let collectionSpeciesChangesets = []; | ||||||
|       let relatedChangesets = []; |     const collectionSpecies = model.get('collectionSpecies'); | ||||||
|       let validation = validations[hasMany]; |     collectionSpecies.forEach((cs) => { | ||||||
|       const related = model.get(hasMany); |       const changeset = new Changeset(cs, | ||||||
|       related.forEach((r) => { |                                       lookupValidator(validations['collectionSpecies']), | ||||||
|         const changeset = new Changeset(r, lookupValidator(validation), |                                       validations['collectionSpecies']); | ||||||
|                                         validation); |       collectionSpeciesChangesets.push({ model: cs, changeset: changeset }); | ||||||
|         relatedChangesets.push({ model: r, 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('changesets', changesets); | ||||||
|     this.set('newStudyLocationAdmin', `${config.APP.API_HOST}/admin/locations/studylocation/add/`); |  | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   actions: { |   actions: { | ||||||
|     addHasMany(modelName, relatedName) { |     addCollectionSpecies() { | ||||||
|       const store = this.get('store'); |       const store = this.get('store'); | ||||||
|       let changesets = this.get('changesets'); |       let changesets = this.get('changesets'); | ||||||
|       const validations = this.get('validations'); |       const validations = this.get('validations'); | ||||||
|       const validation = validations[relatedName]; |       const collection = this.get('model'); | ||||||
|       const model = this.get('model'); |       const cs = store.createRecord('collection-species', { collection: collection }); | ||||||
|       const related = store.createRecord(modelName, { collection: model }); |       collection.get('collectionSpecies').pushObject(cs); | ||||||
|       model.get(relatedName).pushObject(related); |       changesets['new'].pushObject(cs); | ||||||
|       changesets['new'].pushObject(related); |       const changeset = new Changeset(cs, | ||||||
|       const changeset = new Changeset(related, lookupValidator(validation), validation); |                                       lookupValidator(validations['collectionSpecies']), | ||||||
|       changesets['hasMany'][relatedName].pushObject({ model: related, changeset: changeset }); |                                       validations['collectionSpecies']); | ||||||
|  |       changesets['hasMany']['collectionSpecies'].pushObject({ model: cs, changeset: changeset }); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     deleteHasMany(changesetRecord, relatedName) { |     deleteCollectionSpecies(changesetRecord) { | ||||||
|       let changesets = this.get('changesets'); |       let changesets = this.get('changesets'); | ||||||
|       changesets['delete'].pushObject(changesetRecord.model); |       changesets['delete'].pushObject(changesetRecord.model); | ||||||
|       changesets['hasMany'][relatedName].removeObject(changesetRecord); |       changesets['hasMany']['collectionSpecies'].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) { |     updateDatasheet(changeset, event) { | ||||||
|       changeset.set('datasheet', event.target.files[0]); |       changeset.set('datasheet', event.target.files[0]); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     searchStudyLocation(term) { |     addDatasheet() { | ||||||
|       return new RSVP.Promise((resolve, reject) => { |       const store = this.get('store'); | ||||||
|         debounce(this, this._performSearch, 'study-location', { page_size: 500, code: term }, resolve, reject, 400); |       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 }); | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     deleteDatasheet(changesetRecord) { | ||||||
|  |       let changesets = this.get('changesets'); | ||||||
|  |       changesets['delete'].pushObject(changesetRecord.model); | ||||||
|  |       changesets['hasMany']['datasheets'].removeObject(changesetRecord); | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
| 
 |  | ||||||
|   _performSearch(model, payload, resolve, reject) { |  | ||||||
|     this.get('store').query(model, payload).then((results) => { |  | ||||||
|       resolve(results); |  | ||||||
|     }, reject); |  | ||||||
|   }, |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
|  | 
 | ||||||
|  | const { Component } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   // ARGS
 |   // ARGS
 | ||||||
|  | @ -22,13 +24,6 @@ export default Component.extend({ | ||||||
|     { label: 'Species', valuePath: 'species.commonName' }, |     { label: 'Species', valuePath: 'species.commonName' }, | ||||||
|     { label: 'Count', valuePath: 'count' }, |     { label: 'Count', valuePath: 'count' }, | ||||||
|     { label: 'Count Estimated?', valuePath: 'countEstimated' }, |     { label: 'Count Estimated?', valuePath: 'countEstimated' }, | ||||||
|     { label: 'Sex', valuePath: 'sex.name' }, |     { label: 'Sex', valuePath: 'sex' }, | ||||||
|   ], |  | ||||||
| 
 |  | ||||||
|   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', }, |  | ||||||
|   ], |   ], | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
|  | 
 | ||||||
|  | const { Component } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   // ARGS
 |   // 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({ | export default Component.extend({ | ||||||
|   // ARGS
 |   // ARGS
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
|  | 
 | ||||||
|  | const { Component } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   tagName: 'form', |   tagName: 'form', | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
|  | 
 | ||||||
|  | const { Component } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   classNames: ['spinner'], |   classNames: ['spinner'], | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import Component from '@ember/component'; | import Ember from 'ember'; | ||||||
| import { get, computed } from '@ember/object'; | 
 | ||||||
| import { isEmpty } from '@ember/utils'; | const { Component, computed, get, isEmpty } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Component.extend({ | export default Component.extend({ | ||||||
|   classNames: ['form-group'], |   classNames: ['form-group'], | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import Controller from '@ember/controller'; | import Ember from 'ember'; | ||||||
| import { inject as service } from '@ember/service'; | 
 | ||||||
|  | const { Controller, inject: { service } } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Controller.extend({ | export default Controller.extend({ | ||||||
|   session: service('session'), |   session: service('session'), | ||||||
|  |  | ||||||
|  | @ -1,23 +1,21 @@ | ||||||
| import Controller from '@ember/controller'; | import Ember from 'ember'; | ||||||
| import { computed } from '@ember/object'; |  | ||||||
| import CollectionValidations from 'ccdb-web/validations/collection'; | import CollectionValidations from 'ccdb-web/validations/collection'; | ||||||
| import CollectionSpeciesValidations from 'ccdb-web/validations/collection-species'; | import CollectionSpeciesValidations from 'ccdb-web/validations/collection-species'; | ||||||
| import CollectionMeasurementValidations from 'ccdb-web/validations/collection-measurement'; |  | ||||||
| import DatasheetValidations from 'ccdb-web/validations/datasheet'; | import DatasheetValidations from 'ccdb-web/validations/datasheet'; | ||||||
| import ValidationMixin from 'ccdb-web/mixins/validation'; | import ValidationMixin from 'ccdb-web/mixins/validation'; | ||||||
| 
 | 
 | ||||||
|  | const { Controller, computed } = Ember; | ||||||
|  | 
 | ||||||
| export default Controller.extend(ValidationMixin, { | export default Controller.extend(ValidationMixin, { | ||||||
|   CollectionValidations, |   CollectionValidations, | ||||||
|   CollectionSpeciesValidations, |   CollectionSpeciesValidations, | ||||||
|   DatasheetValidations, |   DatasheetValidations, | ||||||
|   CollectionMeasurementValidations, |  | ||||||
| 
 | 
 | ||||||
|   hasMany: ['collectionSpecies', 'datasheets', 'envMeasurements'], |   hasMany: ['collectionSpecies', 'datasheets'], | ||||||
| 
 | 
 | ||||||
|   options: computed('projectOptions', 'studyLocationOptions', |   options: computed('projectOptions', 'studyLocationOptions', | ||||||
|                     'collectionTypeOptions', 'collectionMethodOptions', |                     'collectionTypeOptions', 'collectionMethodOptions', | ||||||
|                     'speciesOptions', 'adfgPermitOptions', 'sexOptions', |                     'speciesOptions', 'adfgPermitOptions', function() { | ||||||
|                     function() { |  | ||||||
|     return { |     return { | ||||||
|       projects: this.get('projectOptions'), |       projects: this.get('projectOptions'), | ||||||
|       studyLocations: this.get('studyLocationOptions'), |       studyLocations: this.get('studyLocationOptions'), | ||||||
|  | @ -25,22 +23,17 @@ export default Controller.extend(ValidationMixin, { | ||||||
|       collectionMethods: this.get('collectionMethodOptions'), |       collectionMethods: this.get('collectionMethodOptions'), | ||||||
|       species: this.get('speciesOptions'), |       species: this.get('speciesOptions'), | ||||||
|       adfgPermits: this.get('adfgPermitOptions'), |       adfgPermits: this.get('adfgPermitOptions'), | ||||||
|       sexes: this.get('sexOptions'), |  | ||||||
|     }; |     }; | ||||||
|   }), |   }), | ||||||
| 
 | 
 | ||||||
|   actions: { |   actions: { | ||||||
|     onSave(changeset) { |     onSave(changeset) { | ||||||
|       const postSave = () => { this.transitionToRoute('collections.index'); }; |       const postSave = () => { this.transitionToRoute('collections.index'); }; | ||||||
|       return this.transitionToRoute('loading').then(() => { |       return this.validationSave(changeset, postSave); | ||||||
|         return this.validationSave(changeset, postSave); |  | ||||||
|       }); |  | ||||||
|     }, |     }, | ||||||
|     onCancel(changeset) { |     onCancel(changeset) { | ||||||
|       const postCancel = () => { this.transitionToRoute('collections.index'); }; |       const postCancel = () => { this.transitionToRoute('collections.index'); }; | ||||||
|       return this.transitionToRoute('loading').then(() => { |       return this.validationCancel(changeset, postCancel); | ||||||
|         return this.validationCancel(changeset, postCancel); |  | ||||||
|       }); |  | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -1,23 +1,22 @@ | ||||||
| import Controller from '@ember/controller'; | import Ember from 'ember'; | ||||||
| import { computed } from '@ember/object'; |  | ||||||
| import CollectionValidations from 'ccdb-web/validations/collection'; | import CollectionValidations from 'ccdb-web/validations/collection'; | ||||||
| import CollectionSpeciesValidations from 'ccdb-web/validations/collection-species'; | import CollectionSpeciesValidations from 'ccdb-web/validations/collection-species'; | ||||||
| import CollectionMeasurementValidations from 'ccdb-web/validations/collection-measurement'; |  | ||||||
| import DatasheetValidations from 'ccdb-web/validations/datasheet'; | import DatasheetValidations from 'ccdb-web/validations/datasheet'; | ||||||
| import ValidationMixin from 'ccdb-web/mixins/validation'; | import ValidationMixin from 'ccdb-web/mixins/validation'; | ||||||
| 
 | 
 | ||||||
|  | const { Controller, computed } = Ember; | ||||||
|  | 
 | ||||||
| export default Controller.extend(ValidationMixin, { | export default Controller.extend(ValidationMixin, { | ||||||
|   CollectionValidations, |   CollectionValidations, | ||||||
|   CollectionSpeciesValidations, |   CollectionSpeciesValidations, | ||||||
|   DatasheetValidations, |   DatasheetValidations, | ||||||
|   CollectionMeasurementValidations, |  | ||||||
| 
 | 
 | ||||||
|   hasMany: ['collectionSpecies', 'datasheets', 'envMeasurements'], |   hasMany: ['collectionSpecies', 'datasheets'], | ||||||
|  |   safeNavigate: false, | ||||||
| 
 | 
 | ||||||
|   options: computed('projectOptions', 'studyLocationOptions', |   options: computed('projectOptions', 'studyLocationOptions', | ||||||
|                     'collectionTypeOptions', 'collectionMethodOptions', |                     'collectionTypeOptions', 'collectionMethodOptions', | ||||||
|                     'speciesOptions', 'adfgPermitOptions', 'sexOptions', |                     'speciesOptions', 'adfgPermitOptions', function() { | ||||||
|                     function() { |  | ||||||
|     return { |     return { | ||||||
|       projects: this.get('projectOptions'), |       projects: this.get('projectOptions'), | ||||||
|       studyLocations: this.get('studyLocationOptions'), |       studyLocations: this.get('studyLocationOptions'), | ||||||
|  | @ -25,28 +24,29 @@ export default Controller.extend(ValidationMixin, { | ||||||
|       collectionMethods: this.get('collectionMethodOptions'), |       collectionMethods: this.get('collectionMethodOptions'), | ||||||
|       species: this.get('speciesOptions'), |       species: this.get('speciesOptions'), | ||||||
|       adfgPermits: this.get('adfgPermitOptions'), |       adfgPermits: this.get('adfgPermitOptions'), | ||||||
|       sexes: this.get('sexOptions'), |  | ||||||
|     }; |     }; | ||||||
|   }), |   }), | ||||||
| 
 | 
 | ||||||
|   actions: { |   actions: { | ||||||
|     onSave(changesets) { |     onSave(changesets) { | ||||||
|       const postSave = () => { |       const postSave = () => { | ||||||
|  |         this.set('safeNavigate', true); | ||||||
|         // Use the model's ID here because of the ArrayProxy in the route
 |         // Use the model's ID here because of the ArrayProxy in the route
 | ||||||
|         this.transitionToRoute('collections.detail', this.get('model.id')); |         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); | ||||||
|         return this.validationSave(changesets, postSave); |  | ||||||
|       }); |  | ||||||
|     }, |     }, | ||||||
|     onCancel(changesets) { |     onCancel(changesets) { | ||||||
|       const postCancel = () => { |       const postCancel = () => { | ||||||
|  |         this.set('safeNavigate', true); | ||||||
|         // Use the model's ID here because of the ArrayProxy in the route
 |         // 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); | ||||||
|         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({ | export default Controller.extend({ | ||||||
|   actions: { |   actions: { | ||||||
|     editCollection() { |     editCollection() { | ||||||
|       this.transitionToRoute('collections.detail.edit', this.get('model')); |       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 Ember from 'ember'; | ||||||
| import { set, get, computed } from '@ember/object'; | 
 | ||||||
|  | const { Controller, computed, get, set } = Ember; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export default Controller.extend({ | export default Controller.extend({ | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import Controller from '@ember/controller'; | import Ember from 'ember'; | ||||||
| import { inject as service } from '@ember/service'; | 
 | ||||||
|  | const { Controller, inject: { service } } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Controller.extend({ | export default Controller.extend({ | ||||||
|   session: service(), |   session: service(), | ||||||
|  |  | ||||||
|  | @ -17,8 +17,8 @@ | ||||||
|   <body> |   <body> | ||||||
|     {{content-for "body"}} |     {{content-for "body"}} | ||||||
| 
 | 
 | ||||||
|     <script integrity="" src="{{rootURL}}assets/vendor.js"></script> |     <script src="{{rootURL}}assets/vendor.js"></script> | ||||||
|     <script integrity="" src="{{rootURL}}assets/ccdb-web.js"></script> |     <script src="{{rootURL}}assets/ccdb-web.js"></script> | ||||||
| 
 | 
 | ||||||
|     {{content-for "body-footer"}} |     {{content-for "body-footer"}} | ||||||
|   </body> |   </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 Ember from 'ember'; | ||||||
| import { isArray } from '@ember/array'; | 
 | ||||||
|  | const { Mixin, isArray } = Ember; | ||||||
| const { keys } = Object; | const { keys } = Object; | ||||||
| 
 | 
 | ||||||
| // Portions borrowed from https://github.com/funtusov/ember-cli-form-data
 | // Portions borrowed from https://github.com/funtusov/ember-cli-form-data
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| import Mixin from '@ember/object/mixin'; | import Ember from 'ember'; | ||||||
| import { get } from '@ember/object'; | 
 | ||||||
| import RSVP from 'rsvp'; | const { Mixin, get, RSVP } = Ember; | ||||||
| const { keys } = Object; | const { keys } = Object; | ||||||
|  | const { isArray } = Array; | ||||||
| 
 | 
 | ||||||
| export default Mixin.create({ | export default Mixin.create({ | ||||||
|   validationSave(changesets, postSave) { |   validationSave(changesets, postSave) { | ||||||
|  | @ -54,13 +55,9 @@ export default Mixin.create({ | ||||||
|         for (const model of changesets[key]) { |         for (const model of changesets[key]) { | ||||||
|           model.destroyRecord(); |           model.destroyRecord(); | ||||||
|         } |         } | ||||||
|       } else if (key === 'hasMany') { |       } else if (isArray(changesets[key])) {  // hasMany
 | ||||||
|         const hasMany = changesets[key]; |         for (const { changeset } of changesets[key]) { | ||||||
|         for (const hasManyKey of keys(changesets[key])) { |           changeset.rollback(); | ||||||
|           const hasManyChangesets = hasMany[hasManyKey]; |  | ||||||
|           for (const changeset of hasManyChangesets) { |  | ||||||
|             changeset.rollback(); |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|       } else {  // single
 |       } else {  // single
 | ||||||
|         const changeset = changesets[key]; |         const changeset = changesets[key]; | ||||||
|  |  | ||||||
|  | @ -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; | const { Model, attr, belongsTo } = DS; | ||||||
| 
 | 
 | ||||||
| export default Model.extend({ | export default Model.extend({ | ||||||
|   sex:            belongsTo('sex'), |   sex:            attr('string'), | ||||||
|   count:          attr('number'), |   count:          attr('number'), | ||||||
|   countEstimated: attr('boolean', { defaultValue: false }), |   countEstimated: attr('boolean', { defaultValue: false }), | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,17 +1,16 @@ | ||||||
| import { mapBy } from '@ember/object/computed'; | import Ember from 'ember'; | ||||||
| import { computed } from '@ember/object'; |  | ||||||
| import DS from 'ember-data'; | import DS from 'ember-data'; | ||||||
| 
 | 
 | ||||||
|  | const { computed } = Ember; | ||||||
| const { Model, attr, belongsTo, hasMany } = DS; | const { Model, attr, belongsTo, hasMany } = DS; | ||||||
| 
 | 
 | ||||||
| export default Model.extend({ | export default Model.extend({ | ||||||
|   displayName:         attr('string'), |   displayName:         attr('string'), | ||||||
|   numberOfTraps:       attr('number'), |   numberOfTraps:       attr('number'), | ||||||
|   collectionStartDate: attr('ccdb-date'), |   collectionStartDate: attr('string-null-to-empty'), | ||||||
|   collectionStartTime: 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'), |   collectionEndTime:   attr('string-null-to-empty'), | ||||||
|   notes:               attr('string', { defaultValue: '' }), |  | ||||||
| 
 | 
 | ||||||
|   project:           belongsTo('project'), |   project:           belongsTo('project'), | ||||||
|   studyLocation:     belongsTo('study-location'), |   studyLocation:     belongsTo('study-location'), | ||||||
|  | @ -21,14 +20,13 @@ export default Model.extend({ | ||||||
| 
 | 
 | ||||||
|   collectionSpecies: hasMany('collection-species'), |   collectionSpecies: hasMany('collection-species'), | ||||||
|   datasheets:        hasMany('datasheet-attachment'), |   datasheets:        hasMany('datasheet-attachment'), | ||||||
|   envMeasurements:   hasMany('collection-measurement'), |  | ||||||
| 
 | 
 | ||||||
|   // computed
 |   // 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() { |   speciesAndCounts: computed('speciesNames', 'counts', function() { | ||||||
|     const speciesNames = this.get('speciesNames'); |     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'; | import config from './config/environment'; | ||||||
| 
 | 
 | ||||||
| const Router = EmberRouter.extend({ | const Router = Ember.Router.extend({ | ||||||
|   location: config.locationType, |   location: config.locationType, | ||||||
|   rootURL: config.rootURL |   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'; | import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin'; | ||||||
| 
 | 
 | ||||||
|  | const { Route } = Ember; | ||||||
|  | 
 | ||||||
| export default Route.extend(ApplicationRouteMixin, {}); | export default Route.extend(ApplicationRouteMixin, {}); | ||||||
|  |  | ||||||
|  | @ -1,18 +1,19 @@ | ||||||
| import Route from '@ember/routing/route'; | import Ember from 'ember'; | ||||||
| import RSVP from 'rsvp'; | import CleanupFormMixin from 'ccdb-web/mixins/cleanup-form'; | ||||||
| 
 | 
 | ||||||
| export default Route.extend({ | const { Route, RSVP } = Ember; | ||||||
|  | 
 | ||||||
|  | export default Route.extend(CleanupFormMixin, { | ||||||
|   model() { |   model() { | ||||||
|     const store = this.get('store'); |     const store = this.get('store'); | ||||||
|     return RSVP.hash({ |     return RSVP.hash({ | ||||||
|       model: store.createRecord('collection'), |       model: store.createRecord('collection'), | ||||||
|       projectOptions: store.findAll('project'), |       projectOptions: store.findAll('project'), | ||||||
|       studyLocationOptions: store.query('study-location', { page_size: 500 }), |       studyLocationOptions: store.findAll('study-location'), | ||||||
|       collectionTypeOptions: store.findAll('collection-type'), |       collectionTypeOptions: store.findAll('collection-type'), | ||||||
|       collectionMethodOptions: store.findAll('collection-method'), |       collectionMethodOptions: store.findAll('collection-method'), | ||||||
|       speciesOptions: store.query('species', { page_size: 500 }), |       speciesOptions: store.findAll('species'), | ||||||
|       adfgPermitOptions: store.findAll('adfg-permit'), |       adfgPermitOptions: store.findAll('adfg-permit'), | ||||||
|       sexOptions: store.findAll('sex'), |  | ||||||
|     }); |     }); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,11 +1,12 @@ | ||||||
| import Route from '@ember/routing/route'; | import Ember from 'ember'; | ||||||
| import RSVP from 'rsvp'; | 
 | ||||||
|  | const { Route, RSVP } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Route.extend({ | export default Route.extend({ | ||||||
|   model(params) { |   model(params) { | ||||||
|     return RSVP.all([ |     return RSVP.all([ | ||||||
|       this.get('store').findRecord('collection', params.collection_id, { |       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 Ember from 'ember'; | ||||||
| import RSVP from 'rsvp'; | import CleanupFormMixin from 'ccdb-web/mixins/cleanup-form'; | ||||||
| 
 | 
 | ||||||
| export default Route.extend({ | const { Route, RSVP } = Ember; | ||||||
|  | 
 | ||||||
|  | export default Route.extend(CleanupFormMixin, { | ||||||
|   model() { |   model() { | ||||||
|     const store = this.get('store'); |     const store = this.get('store'); | ||||||
|     const model = this.modelFor('collections.detail'); |     const model = this.modelFor('collections.detail'); | ||||||
|     return RSVP.hash({ |     return RSVP.hash({ | ||||||
|       model: model, |       model: model, | ||||||
|       projectOptions: store.findAll('project'), |       projectOptions: store.findAll('project'), | ||||||
|       studyLocationOptions: store.query('study-location', { page_size: 500 }), |       studyLocationOptions: store.findAll('study-location'), | ||||||
|       collectionTypeOptions: store.findAll('collection-type'), |       collectionTypeOptions: store.findAll('collection-type'), | ||||||
|       collectionMethodOptions: store.findAll('collection-method'), |       collectionMethodOptions: store.findAll('collection-method'), | ||||||
|       speciesOptions: store.query('species', { page_size: 500 }), |       speciesOptions: store.findAll('species'), | ||||||
|       adfgPermitOptions: store.findAll('adfg-permit'), |       adfgPermitOptions: store.findAll('adfg-permit'), | ||||||
|       sexOptions: store.findAll('sex'), |  | ||||||
|     }); |     }); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import Route from '@ember/routing/route'; | import Ember from 'ember'; | ||||||
| import RSVP from 'rsvp'; | 
 | ||||||
|  | const { Route, RSVP } = Ember; | ||||||
| 
 | 
 | ||||||
| export default Route.extend({ | export default Route.extend({ | ||||||
|   queryParams: { |   queryParams: { | ||||||
|  | @ -29,10 +30,10 @@ export default Route.extend({ | ||||||
|       projectOptions: store.findAll('project'), |       projectOptions: store.findAll('project'), | ||||||
|       regionOptions: store.findAll('region'), |       regionOptions: store.findAll('region'), | ||||||
|       siteOptions: store.findAll('site'), |       siteOptions: store.findAll('site'), | ||||||
|       studyLocationOptions: store.query('study-location', { page_size: 500 }), |       studyLocationOptions: store.findAll('study-location'), | ||||||
|       collectionMethodOptions: store.findAll('collection-method'), |       collectionMethodOptions: store.findAll('collection-method'), | ||||||
|       adfgPermitOptions: store.findAll('adfg-permit'), |       adfgPermitOptions: store.findAll('adfg-permit'), | ||||||
|       speciesOptions: store.query('species', { page_size: 500 }), |       speciesOptions: store.findAll('species'), | ||||||
|       model: store.query('collection', Object.assign(params, opts)), |       model: store.query('collection', Object.assign(params, opts)), | ||||||
|     }); |     }); | ||||||
|   }, |   }, | ||||||
|  | @ -43,38 +44,27 @@ export default Route.extend({ | ||||||
| 
 | 
 | ||||||
|     const store = this.get('store'); |     const store = this.get('store'); | ||||||
| 
 | 
 | ||||||
|     /* eslint-disable no-console */ |  | ||||||
| 
 |  | ||||||
|     let project = controller.get('project'); |     let project = controller.get('project'); | ||||||
|     console.log('project', project); |  | ||||||
|     project = project.map(id => store.peekRecord('project', id)); |     project = project.map(id => store.peekRecord('project', id)); | ||||||
| 
 | 
 | ||||||
|     let region = controller.get('region'); |     let region = controller.get('region'); | ||||||
|     console.log('region', region); |  | ||||||
|     region = region.map(id => store.peekRecord('region', id)); |     region = region.map(id => store.peekRecord('region', id)); | ||||||
| 
 | 
 | ||||||
|     let site = controller.get('site'); |     let site = controller.get('site'); | ||||||
|     console.log('site', site); |  | ||||||
|     site = site.map(id => store.peekRecord('site', id)); |     site = site.map(id => store.peekRecord('site', id)); | ||||||
| 
 | 
 | ||||||
|     let studyLocation = controller.get('study_location'); |     let studyLocation = controller.get('study_location'); | ||||||
|     console.log('studyLocation', studyLocation); |  | ||||||
|     studyLocation = studyLocation.map(id => store.peekRecord('study-location', id)); |     studyLocation = studyLocation.map(id => store.peekRecord('study-location', id)); | ||||||
| 
 | 
 | ||||||
|     let collectionMethod = controller.get('collection_method'); |     let collectionMethod = controller.get('collection_method'); | ||||||
|     console.log('collectionMethod', collectionMethod); |  | ||||||
|     collectionMethod = collectionMethod.map(id => store.peekRecord('collection-method', id)); |     collectionMethod = collectionMethod.map(id => store.peekRecord('collection-method', id)); | ||||||
| 
 | 
 | ||||||
|     let adfgPermit = controller.get('adfg_permit'); |     let adfgPermit = controller.get('adfg_permit'); | ||||||
|     console.log('adfgPermit', adfgPermit); |  | ||||||
|     adfgPermit = adfgPermit.map(id => store.peekRecord('adfg-permit', id)); |     adfgPermit = adfgPermit.map(id => store.peekRecord('adfg-permit', id)); | ||||||
| 
 | 
 | ||||||
|     let species = controller.get('species'); |     let species = controller.get('species'); | ||||||
|     console.log('species', species); |  | ||||||
|     species = species.map(id => store.peekRecord('species', id)); |     species = species.map(id => store.peekRecord('species', id)); | ||||||
| 
 | 
 | ||||||
|     /* eslint-enable no-console */ |  | ||||||
| 
 |  | ||||||
|     const numberOfTraps = controller.get('number_of_traps'); |     const numberOfTraps = controller.get('number_of_traps'); | ||||||
|     const collectionStartDate = controller.get('collection_start_date'); |     const collectionStartDate = controller.get('collection_start_date'); | ||||||
|     const collectionEndDate = controller.get('collection_end_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'; | import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; | ||||||
| 
 | 
 | ||||||
|  | const { Route } = Ember; | ||||||
|  | 
 | ||||||
| export default Route.extend(AuthenticatedRouteMixin, { | export default Route.extend(AuthenticatedRouteMixin, { | ||||||
|   afterModel() { |   afterModel() { | ||||||
|     this.transitionTo('collections'); |     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'; | import UnauthenticatedRouteMixin from 'ember-simple-auth/mixins/unauthenticated-route-mixin'; | ||||||
| 
 | 
 | ||||||
|  | const { Route } = Ember; | ||||||
|  | 
 | ||||||
| export default Route.extend(UnauthenticatedRouteMixin, {}); | export default Route.extend(UnauthenticatedRouteMixin, {}); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import Route from '@ember/routing/route'; | import Ember from 'ember'; | ||||||
| import { inject as service } from '@ember/service'; | 
 | ||||||
|  | const { Route, inject: { service }} = Ember; | ||||||
| 
 | 
 | ||||||
| export default Route.extend({ | export default Route.extend({ | ||||||
|   session: service('session'), |   session: service('session'), | ||||||
|  |  | ||||||
|  | @ -1,16 +1,10 @@ | ||||||
| import { capitalize } from '@ember/string'; | import Ember from 'ember'; | ||||||
| import DS from 'ember-data'; | import DS from 'ember-data'; | ||||||
| 
 | 
 | ||||||
| const { JSONAPISerializer } = DS; | const { JSONAPISerializer } = DS; | ||||||
| 
 | 
 | ||||||
| export default JSONAPISerializer.extend({ | export default JSONAPISerializer.extend({ | ||||||
|   payloadTypeFromModelName(modelName) { |   payloadTypeFromModelName(modelName) { | ||||||
|     return modelName.split('-').map(key => capitalize(key)).join(''); |     return modelName.split('-').map(key => Ember.String.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; |  | ||||||
|   }, |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -4,10 +4,8 @@ | ||||||
|   validations=(hash |   validations=(hash | ||||||
|     collection=CollectionValidations |     collection=CollectionValidations | ||||||
|     collectionSpecies=CollectionSpeciesValidations |     collectionSpecies=CollectionSpeciesValidations | ||||||
|     envMeasurements=CollectionMeasurementValidations |  | ||||||
|     datasheet=DatasheetValidations) |     datasheet=DatasheetValidations) | ||||||
|   options=options |   options=options | ||||||
|   hasMany=hasMany |  | ||||||
|   onSave=(action 'onSave') |   onSave=(action 'onSave') | ||||||
|   onCancel=(action 'onCancel') |   onCancel=(action 'onCancel') | ||||||
| }} | }} | ||||||
|  |  | ||||||
|  | @ -4,10 +4,8 @@ | ||||||
|   validations=(hash |   validations=(hash | ||||||
|     collection=CollectionValidations |     collection=CollectionValidations | ||||||
|     collectionSpecies=CollectionSpeciesValidations |     collectionSpecies=CollectionSpeciesValidations | ||||||
|     datasheet=DatasheetValidations |     datasheet=DatasheetValidations) | ||||||
|     envMeasurements=CollectionMeasurementValidations) |  | ||||||
|   options=options |   options=options | ||||||
|   hasMany=hasMany |  | ||||||
|   onSave=(action 'onSave') |   onSave=(action 'onSave') | ||||||
|   onCancel=(action 'onCancel') |   onCancel=(action 'onCancel') | ||||||
| }} | }} | ||||||
|  |  | ||||||
|  | @ -2,5 +2,4 @@ | ||||||
|   collection/detail-container |   collection/detail-container | ||||||
|   model=model |   model=model | ||||||
|   editCollection=(action 'editCollection') |   editCollection=(action 'editCollection') | ||||||
|   deleteCollection=(action 'deleteCollection') |  | ||||||
| }} | }} | ||||||
|  |  | ||||||
|  | @ -21,33 +21,27 @@ | ||||||
|             {{/validated-field}} |             {{/validated-field}} | ||||||
| 
 | 
 | ||||||
|             {{#validated-field property='adfgPermit' label='ADFG Permit' changeset=changeset}} |             {{#validated-field property='adfgPermit' label='ADFG Permit' changeset=changeset}} | ||||||
|               {{#power-select-with-create |               {{#power-select | ||||||
|                 options=options.adfgPermits |                 options=options.adfgPermits | ||||||
|                 selected=changeset.adfgPermit |                 selected=changeset.adfgPermit | ||||||
|                 onchange=(action (mut changeset.adfgPermit)) |                 onchange=(action (mut changeset.adfgPermit)) | ||||||
|                 oncreate=(action 'addOption' 'adfg-permit' 'adfgPermits' 'adfgPermit' 'name') |  | ||||||
|                 searchField='name' |                 searchField='name' | ||||||
|                 as |adfgPermit term| |                 as |adfgPermit| | ||||||
|               }} |               }} | ||||||
|                 {{adfgPermit.name}} |                 {{adfgPermit.name}} | ||||||
|               {{/power-select-with-create}} |               {{/power-select}} | ||||||
|             {{/validated-field}} |             {{/validated-field}} | ||||||
| 
 | 
 | ||||||
|             {{#validated-field property='studyLocation' changeset=changeset}} |             {{#validated-field property='studyLocation' label='Study location' changeset=changeset}} | ||||||
|               <label class="control-label"> |                 {{#power-select | ||||||
|                 Study location |                   options=options.studyLocations | ||||||
|                 <a href="{{newStudyLocationAdmin}}" target="_blank">+</a> |                   selected=changeset.studyLocation | ||||||
|               </label> |                   onchange=(action (mut changeset.studyLocation)) | ||||||
|               {{#power-select |                   searchField='name' | ||||||
|                 search=(action 'searchStudyLocation') |                   as |studyLocation| | ||||||
|                 options=options.studyLocations |                 }} | ||||||
|                 selected=changeset.studyLocation |                   {{studyLocation.name}} | ||||||
|                 onchange=(action (mut changeset.studyLocation)) |                 {{/power-select}} | ||||||
|                 searchField='code' |  | ||||||
|                 as |studyLocation| |  | ||||||
|               }} |  | ||||||
|                 {{studyLocation.code}} |  | ||||||
|               {{/power-select}} |  | ||||||
|             {{/validated-field}} |             {{/validated-field}} | ||||||
| 
 | 
 | ||||||
|             {{#validated-field property='collectionType' label='Collection type' changeset=changeset}} |             {{#validated-field property='collectionType' label='Collection type' changeset=changeset}} | ||||||
|  | @ -79,204 +73,114 @@ | ||||||
|             {{/validated-field}} |             {{/validated-field}} | ||||||
| 
 | 
 | ||||||
|             {{#validated-field property='collectionStartDate' label='Collection start date' changeset=changeset}} |             {{#validated-field property='collectionStartDate' label='Collection start date' changeset=changeset}} | ||||||
|               {{ |               {{input value=changeset.collectionStartDate type='date' class='form-control'}} | ||||||
|                 pikaday-input |  | ||||||
|                 onSelection=(action (mut changeset.collectionStartDate)) |  | ||||||
|                 value=changeset.collectionStartDate |  | ||||||
|                 useUTC=true |  | ||||||
|                 placeholder='MM/DD/YYYY' |  | ||||||
|                 format='MM/DD/YYYY' |  | ||||||
|                 class='form-control' |  | ||||||
|               }} |  | ||||||
|             {{/validated-field}} |             {{/validated-field}} | ||||||
| 
 | 
 | ||||||
|             {{#validated-field property='collectionStartTime' label='Collection start time' changeset=changeset}} |             {{#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}} | ||||||
| 
 | 
 | ||||||
|             {{#validated-field property='collectionEndDate' label='Collection end date' changeset=changeset}} |             {{#validated-field property='collectionEndDate' label='Collection end date' changeset=changeset}} | ||||||
|               {{ |               {{input value=changeset.collectionEndDate type='date' class='form-control'}} | ||||||
|                 pikaday-input |  | ||||||
|                 onSelection=(action (mut changeset.collectionEndDate)) |  | ||||||
|                 value=changeset.collectionEndDate |  | ||||||
|                 useUTC=true |  | ||||||
|                 placeholder='MM/DD/YYYY' |  | ||||||
|                 format='MM/DD/YYYY' |  | ||||||
|                 class='form-control' |  | ||||||
|               }} |  | ||||||
|             {{/validated-field}} |             {{/validated-field}} | ||||||
| 
 | 
 | ||||||
|             {{#validated-field property='collectionEndTime' label='Collection end time' changeset=changeset}} |             {{#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}} |             {{/validated-field}} | ||||||
|           {{/with}} |           {{/with}} | ||||||
|         {{/f.content}} |         {{/f.content}} | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|     <div class="col-md-8"> |     <div class="col-md-8"> | ||||||
|       <div class="row"> |       <table class="table"> | ||||||
|         <div class="col-md-12"> |         <caption> | ||||||
|           {{#validated-field property='notes' label='Notes' changeset=changesets.model}} |           Species / Count Info | ||||||
|             {{textarea value=changesets.model.notes class='form-control'}} |           {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addCollectionSpecies')}} | ||||||
|           {{/validated-field}} |         </caption> | ||||||
|         </div> |         <thead> | ||||||
|       </div> |           <tr> | ||||||
|       <div class="row"> |             <th class="col-md-3">Species</th> | ||||||
|         <div class="col-md-12"> |             <th class="col-md-3">Count</th> | ||||||
|           <table class="table"> |             <th class="col-md-3">Count Estimated</th> | ||||||
|             <caption> |             <th class="col-md-3">Sex</th> | ||||||
|               Species / Count Info |             <th class="col-md-1">Delete</th> | ||||||
|               {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'collection-species' 'collectionSpecies')}} |           </tr> | ||||||
|             </caption> |         </thead> | ||||||
|             <thead> |         <tbody> | ||||||
|               <tr> |           {{#each changesets.hasMany.collectionSpecies as |cs|}} | ||||||
|                 <th class="col-md-3">Species</th> |             <tr class="form"> | ||||||
|                 <th class="col-md-3">Count</th> |               <td class="col-md-3"> | ||||||
|                 <th class="col-md-3">Count Estimated</th> |                 {{#validated-field property='species' changeset=cs.changeset}} | ||||||
|                 <th class="col-md-3">Sex</th> |                   {{#power-select | ||||||
|                 <th class="col-md-1">Delete</th> |                     options=options.species | ||||||
|               </tr> |                     selected=cs.changeset.species | ||||||
|             </thead> |                     onchange=(action (mut cs.changeset.species)) | ||||||
|             <tbody> |                     searchField='commonName' | ||||||
|               {{#each changesets.hasMany.collectionSpecies as |cs|}} |                     as |species| | ||||||
|                 <tr class="form"> |                   }} | ||||||
|                   <td class="col-md-3"> |                     {{species.commonName}} | ||||||
|                     {{#validated-field property='species' changeset=cs.changeset}} |                   {{/power-select}} | ||||||
|                       {{#power-select |                 {{/validated-field}} | ||||||
|                         options=options.species |               </td> | ||||||
|                         selected=cs.changeset.species |               <td class="col-md-3"> | ||||||
|                         onchange=(action (mut cs.changeset.species)) |                 {{#validated-field property='count' changeset=cs.changeset}} | ||||||
|                         searchField='commonName' |                   {{input value=cs.changeset.count}} | ||||||
|                         as |species| |                 {{/validated-field}} | ||||||
|                       }} |               </td> | ||||||
|                         {{species.commonName}} |               <td class="col-md-3"> | ||||||
|                       {{/power-select}} |                 {{#validated-field property='countEstimated' changeset=cs.changeset}} | ||||||
|                     {{/validated-field}} |                   {{input checked=cs.changeset.countEstimated type='checkbox'}} | ||||||
|                   </td> |                 {{/validated-field}} | ||||||
|                   <td class="col-md-3"> |               </td> | ||||||
|                     {{#validated-field property='count' changeset=cs.changeset}} |               <td class="col-md-3"> | ||||||
|                       {{input value=cs.changeset.count}} |                 {{#validated-field property='sex' changeset=cs.changeset}} | ||||||
|                     {{/validated-field}} |                   {{input value=cs.changeset.sex}} | ||||||
|                   </td> |                 {{/validated-field}} | ||||||
|                   <td class="col-md-3"> |               </td> | ||||||
|                     {{#validated-field property='countEstimated' changeset=cs.changeset}} |               <td class="col-md-2"> | ||||||
|                       {{input checked=cs.changeset.countEstimated type='checkbox'}} |                 {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteCollectionSpecies' cs)}} | ||||||
|                     {{/validated-field}} |               </td> | ||||||
|                   </td> |             </tr> | ||||||
|                   <td class="col-md-3"> |           {{/each}} | ||||||
|                     {{#validated-field property='sex' changeset=cs.changeset}} |         </tbody> | ||||||
|                       {{#power-select |       </table> | ||||||
|                         options=options.sexes |     </div> | ||||||
|                         selected=cs.changeset.sex |   </div> | ||||||
|                         onchange=(action (mut cs.changeset.sex)) |   <div class="row"> | ||||||
|                         searchField='name' |     <div class="col-md-12"> | ||||||
|                         as |sex| |       <form enctype="multipart/form-data"> | ||||||
|                       }} |       <table class="table"> | ||||||
|                         {{sex.name}} |         <caption> | ||||||
|                       {{/power-select}} |           Attachments | ||||||
|                     {{/validated-field}} |           {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addDatasheet')}} | ||||||
|                   </td> |         </caption> | ||||||
|                   <td class="col-md-2"> |         <thead> | ||||||
|                     {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteHasMany' cs 'collectionSpecies')}} |           <tr> | ||||||
|                   </td> |             <th>File</th> | ||||||
|                 </tr> |             <th>Delete</th> | ||||||
|               {{/each}} |           </tr> | ||||||
|             </tbody> |         </thead> | ||||||
|           </table> |         <tbody> | ||||||
|         </div> |           {{#each changesets.hasMany.datasheets as |d|}} | ||||||
|       </div> |             <tr class="form"> | ||||||
|       <div class="row"> |               <td> | ||||||
|         <div class="col-md-12"> |                 {{#if d.model.isNew}} | ||||||
|           <table class="table"> |                   {{#validated-field property='datasheet' changeset=d.changeset}} | ||||||
|             <caption> |                     <input type="file" onchange={{action 'updateDatasheet' d.changeset}} accept="image/png,image/jpeg,application/pdf"> | ||||||
|               Environmental Measurements |                   {{/validated-field}} | ||||||
|               {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'collection-measurement' 'envMeasurements')}} |                 {{else}} | ||||||
|             </caption> |                   <a href="{{ d.model.datasheet }}">{{ d.model.datasheet }}</a> | ||||||
|             <thead> |                 {{/if}} | ||||||
|               <tr> |               </td> | ||||||
|                 <th class="col-md-3">Date Measured</th> |               <td> | ||||||
|                 <th class="col-md-3">Time Measured</th> |                 {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteDatasheet' d)}} | ||||||
|                 <th class="col-md-3">Water Temperature (deg C)</th> |               </td> | ||||||
|                 <th class="col-md-3">Air Temperature (deg C)</th> |             </tr> | ||||||
|                 <th class="col-md-1">Delete</th> |           {{/each}} | ||||||
|               </tr> |         </tbody> | ||||||
|             </thead> |       </table> | ||||||
|             <tbody> |       </form> | ||||||
|               {{#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')}} |  | ||||||
|                   </td> |  | ||||||
|                 </tr> |  | ||||||
|               {{/each}} |  | ||||||
|             </tbody> |  | ||||||
|           </table> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div class="row"> |  | ||||||
|         <div class="col-md-12"> |  | ||||||
|           <form enctype="multipart/form-data"> |  | ||||||
|             <table class="table"> |  | ||||||
|               <caption> |  | ||||||
|                 Attachments |  | ||||||
|                 {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'datasheet-attachment' 'datasheets')}} |  | ||||||
|               </caption> |  | ||||||
|               <thead> |  | ||||||
|                 <tr> |  | ||||||
|                   <th>File</th> |  | ||||||
|                   <th>Delete</th> |  | ||||||
|                 </tr> |  | ||||||
|               </thead> |  | ||||||
|               <tbody> |  | ||||||
|                 {{#each changesets.hasMany.datasheets as |d|}} |  | ||||||
|                   <tr class="form"> |  | ||||||
|                     <td> |  | ||||||
|                       {{#if d.model.isNew}} |  | ||||||
|                         {{#validated-field property='datasheet' changeset=d.changeset}} |  | ||||||
|                           <input type="file" onchange={{action 'updateDatasheet' d.changeset}} accept="image/png,image/jpeg,application/pdf"> |  | ||||||
|                         {{/validated-field}} |  | ||||||
|                       {{else}} |  | ||||||
|                         <a href="{{ d.model.datasheet }}">{{ d.model.datasheet }}</a> |  | ||||||
|                       {{/if}} |  | ||||||
|                     </td> |  | ||||||
|                     <td> |  | ||||||
|                       {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteHasMany' d 'datasheets')}} |  | ||||||
|                     </td> |  | ||||||
|                   </tr> |  | ||||||
|                 {{/each}} |  | ||||||
|               </tbody> |  | ||||||
|             </table> |  | ||||||
|           </form> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
|   {{f.save}} {{f.cancel}} |   {{f.save}} {{f.cancel}} | ||||||
|  |  | ||||||
|  | @ -5,13 +5,6 @@ | ||||||
|   onClick=(action editCollection) |   onClick=(action editCollection) | ||||||
| }} | }} | ||||||
| 
 | 
 | ||||||
| {{ |  | ||||||
|   confirm-button |  | ||||||
|   initialLabel='Delete Collection' |  | ||||||
|   confirmLabel='Yes, Delete Collection' |  | ||||||
|   onClick=(action deleteCollection) |  | ||||||
| }} |  | ||||||
| 
 |  | ||||||
| <h3>Main Detail</h3> | <h3>Main Detail</h3> | ||||||
| <div class="row"> | <div class="row"> | ||||||
|   <div class="col-md-12"> |   <div class="col-md-12"> | ||||||
|  | @ -40,24 +33,14 @@ | ||||||
| 
 | 
 | ||||||
| <hr> | <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> | <h3>Notes</h3> | ||||||
| <div class="row"> | <div class="row"> | ||||||
|   <div class="col-md-12"> |   <div class="col-md-12"> | ||||||
|     {{model.[0].notes}} |     <ul> | ||||||
|  |       <li>PLACEHOLDER</li> | ||||||
|  |       <li>PLACEHOLDER</li> | ||||||
|  |       <li>PLACEHOLDER</li> | ||||||
|  |     </ul> | ||||||
|   </div> |   </div> | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -102,8 +102,7 @@ | ||||||
|           onSelection=(action (mut filters.collection_start_date)) |           onSelection=(action (mut filters.collection_start_date)) | ||||||
|           value=filters.collection_start_date |           value=filters.collection_start_date | ||||||
|           useUTC=true |           useUTC=true | ||||||
|           placeholder='MM/DD/YYYY' |           format='YYYY-MM-DD' | ||||||
|           format='MM/DD/YYYY' |  | ||||||
|           class='form-control' |           class='form-control' | ||||||
|         }} |         }} | ||||||
|       </div> |       </div> | ||||||
|  | @ -114,8 +113,7 @@ | ||||||
|           onSelection=(action (mut filters.collection_end_date)) |           onSelection=(action (mut filters.collection_end_date)) | ||||||
|           value=filters.collection_end_date |           value=filters.collection_end_date | ||||||
|           useUTC=true |           useUTC=true | ||||||
|           placeholder='MM/DD/YYYY' |           format='YYYY-MM-DD' | ||||||
|           format='MM/DD/YYYY' |  | ||||||
|           class='form-control' |           class='form-control' | ||||||
|         }} |         }} | ||||||
|       </div> |       </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: { |     APP: { | ||||||
|       // Here you can pass flags/options to your application instance
 |       // Here you can pass flags/options to your application instance
 | ||||||
|       // when it is created
 |       // 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') { |   if (environment === 'development') { | ||||||
|     ENV.APP.API_HOST = 'http://localhost:8000'; |     ENV.APP.API_HOST = 'http://localhost:8000'; | ||||||
|     ENV.APP.API_NAMESPACE = 'api/v1'; |     ENV.APP.API_NAMESPACE = 'api/v1'; | ||||||
|     ENV.sentry.development = true; |     ENV.APP.LOG_TRANSITIONS = true; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (environment === 'test') { |   if (environment === 'test') { | ||||||
|  | @ -51,7 +41,7 @@ module.exports = function(environment) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (environment === 'production') { |   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'; |     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": { |   "devDependencies": { | ||||||
|     "broccoli-asset-rev": "^2.4.5", |     "broccoli-asset-rev": "^2.4.5", | ||||||
|     "ember-ajax": "^3.0.0", |     "ember-ajax": "^3.0.0", | ||||||
|     "ember-changeset": "^1.3.0", |     "ember-changeset": "1.3.0", | ||||||
|     "ember-changeset-validations": "^1.2.8", |     "ember-changeset-validations": "1.2.8", | ||||||
|     "ember-cli": "^3.24.0", |     "ember-cli": "~2.14.0", | ||||||
|     "ember-cli-app-version": "^3.0.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-code-coverage": "^0.4.1", | ||||||
|     "ember-cli-dependency-checker": "^2.0.0", |     "ember-cli-dependency-checker": "^1.3.0", | ||||||
|     "ember-cli-eslint": "^4.0.0", |     "ember-cli-eslint": "^3.0.0", | ||||||
|     "ember-cli-flash": "^1.4.3", |     "ember-cli-flash": "1.4.3", | ||||||
|     "ember-cli-htmlbars": "^2.0.1", |     "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-inject-live-reload": "^1.4.1", | ||||||
|     "ember-cli-moment-shim": "^3.5.0", |     "ember-cli-moment-shim": "^3.5.0", | ||||||
|     "ember-cli-qunit": "^4.0.0", |     "ember-cli-qunit": "^4.0.0", | ||||||
|     "ember-cli-sentry": "^3.0.0", |  | ||||||
|     "ember-cli-shims": "^1.1.0", |     "ember-cli-shims": "^1.1.0", | ||||||
|     "ember-cli-sri": "^2.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-composable-helpers": "^2.0.3", | ||||||
|     "ember-data": "~2.16.2", |     "ember-data": "~2.14.3", | ||||||
|     "ember-export-application-global": "^2.0.0", |     "ember-export-application-global": "^2.0.0", | ||||||
|     "ember-inflector": "^2.0.1", |     "ember-inflector": "^2.0.1", | ||||||
|     "ember-light-table": "^1.10.0", |     "ember-light-table": "^1.10.0", | ||||||
|  | @ -44,19 +43,16 @@ | ||||||
|     "ember-moment": "7.3.1", |     "ember-moment": "7.3.1", | ||||||
|     "ember-pikaday": "^2.2.3", |     "ember-pikaday": "^2.2.3", | ||||||
|     "ember-power-select": "^1.8.5", |     "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-resolver": "^4.0.0", | ||||||
|     "ember-responsive": "^2.0.4", |     "ember-responsive": "^2.0.4", | ||||||
|     "ember-simple-auth": "1.4.0", |     "ember-simple-auth": "1.4.0", | ||||||
|     "ember-sinon": "^1.0.0", |     "ember-sinon": "^1.0.0", | ||||||
|     "ember-source": "~2.16.0", |     "ember-source": "~2.14.0", | ||||||
|     "loader.js": "^4.2.3" |     "loader.js": "^4.2.3" | ||||||
|   }, |   }, | ||||||
|   "engines": { |   "engines": { | ||||||
|     "node": "^4.5 || 6.* || >= 7.*" |     "node": "^4.5 || 6.* || >= 7.*" | ||||||
|   }, |   }, | ||||||
|   "private": true, |   "private": true | ||||||
|   "dependencies": { |  | ||||||
|     "npm": "^5.7.1" |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								testem.js
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								testem.js
									
										
									
									
									
								
							|  | @ -3,20 +3,10 @@ module.exports = { | ||||||
|   test_page: 'tests/index.html?hidepassed', |   test_page: 'tests/index.html?hidepassed', | ||||||
|   disable_watching: true, |   disable_watching: true, | ||||||
|   launch_in_ci: [ |   launch_in_ci: [ | ||||||
|     'Chrome' |     'PhantomJS' | ||||||
|   ], |   ], | ||||||
|   launch_in_dev: [ |   launch_in_dev: [ | ||||||
|  |     'PhantomJS', | ||||||
|     'Chrome' |     '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) { | 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'; | 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 { module } from 'qunit'; | ||||||
| import { resolve } from 'rsvp'; | import Ember from 'ember'; | ||||||
| import startApp from '../helpers/start-app'; | import startApp from '../helpers/start-app'; | ||||||
| import destroyApp from '../helpers/destroy-app'; | import destroyApp from '../helpers/destroy-app'; | ||||||
| 
 | 
 | ||||||
|  | const { RSVP: { resolve } } = Ember; | ||||||
|  | 
 | ||||||
| export default function(name, options = {}) { | export default function(name, options = {}) { | ||||||
|   module(name, { |   module(name, { | ||||||
|     beforeEach() { |     beforeEach() { | ||||||
|  |  | ||||||
|  | @ -1,16 +1,17 @@ | ||||||
| import { registerAsyncHelper } from '@ember/test'; | import Ember from 'ember'; | ||||||
| import { A } from '@ember/array'; |  | ||||||
| import { computed } from '@ember/object'; |  | ||||||
| import { classify } from '@ember/string'; |  | ||||||
| import { getOwner } from '@ember/application'; |  | ||||||
| import MediaService from 'ember-responsive/media'; | import MediaService from 'ember-responsive/media'; | ||||||
| 
 | 
 | ||||||
|  | const { | ||||||
|  |   getOwner | ||||||
|  | } = Ember; | ||||||
|  | const { classify } = Ember.String; | ||||||
|  | 
 | ||||||
| MediaService.reopen({ | MediaService.reopen({ | ||||||
|   // Change this if you want a different default breakpoint in tests.
 |   // Change this if you want a different default breakpoint in tests.
 | ||||||
|   _defaultBreakpoint: 'desktop', |   _defaultBreakpoint: 'desktop', | ||||||
| 
 | 
 | ||||||
|   _breakpointArr: computed('breakpoints', function() { |   _breakpointArr: Ember.computed('breakpoints', function() { | ||||||
|     return Object.keys(this.get('breakpoints')) || A([]); |     return Object.keys(this.get('breakpoints')) || Ember.A([]); | ||||||
|   }), |   }), | ||||||
| 
 | 
 | ||||||
|   _forceSetBreakpoint(breakpoint) { |   _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
 |   // this should use getOwner once that's supported
 | ||||||
|   const mediaService = app.__deprecatedInstance__.lookup('service:media'); |   const mediaService = app.__deprecatedInstance__.lookup('service:media'); | ||||||
|   mediaService._forceSetBreakpoint(breakpoint); |   mediaService._forceSetBreakpoint(breakpoint); | ||||||
|  |  | ||||||
|  | @ -1,13 +1,12 @@ | ||||||
|  | import Ember from 'ember'; | ||||||
| import Application from '../../app'; | import Application from '../../app'; | ||||||
| import config from '../../config/environment'; | import config from '../../config/environment'; | ||||||
| import { merge } from '@ember/polyfills'; |  | ||||||
| import { run } from '@ember/runloop'; |  | ||||||
| 
 | 
 | ||||||
| export default function startApp(attrs) { | export default function startApp(attrs) { | ||||||
|   let attributes = merge({}, config.APP); |   let attributes = Ember.merge({}, config.APP); | ||||||
|   attributes = merge(attributes, attrs); // use defaults, but you can override;
 |   attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
 | ||||||
| 
 | 
 | ||||||
|   return run(() => { |   return Ember.run(() => { | ||||||
|     let application = Application.create(attributes); |     let application = Application.create(attributes); | ||||||
|     application.setupForTesting(); |     application.setupForTesting(); | ||||||
|     application.injectTestHelpers(); |     application.injectTestHelpers(); | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import $ from 'jquery'; |  | ||||||
| import { moduleFor, test } from 'ember-qunit'; | import { moduleFor, test } from 'ember-qunit'; | ||||||
| import sinon from 'sinon'; | import sinon from 'sinon'; | ||||||
|  | import Ember from 'ember'; | ||||||
| 
 | 
 | ||||||
| moduleFor('authenticator:application', 'Unit | application', { | moduleFor('authenticator:application', 'Unit | application', { | ||||||
|   unit: true, |   unit: true, | ||||||
|  | @ -35,28 +35,28 @@ test('`invalidate` should invalidate the session', function(assert) { | ||||||
| 
 | 
 | ||||||
| test('`makeRequest` should make a request', function(assert) { | test('`makeRequest` should make a request', function(assert) { | ||||||
|   assert.expect(2); |   assert.expect(2); | ||||||
|   const stub = sinon.stub($, 'ajax'); |   const stub = sinon.stub(Ember.$, 'ajax'); | ||||||
|   stub.resolves(42); |   stub.resolves(42); | ||||||
|   const authenticator = this.subject(); |   const authenticator = this.subject(); | ||||||
|   authenticator.set('serverTokenEndpoint', 'foo') |   authenticator.set('serverTokenEndpoint', 'foo') | ||||||
|   const promise = authenticator.makeRequest({bar: 'baz'}).then((d) => { |   const promise = authenticator.makeRequest({bar: 'baz'}).then((d) => { | ||||||
|     assert.equal(d, 42); |     assert.equal(d, 42); | ||||||
|   }); |   }); | ||||||
|   assert.ok($.ajax.calledWithMatch({url: 'foo', data: {bar: 'baz'}})); |   assert.ok(Ember.$.ajax.calledWithMatch({url: 'foo', data: {bar: 'baz'}})); | ||||||
|   $.ajax.restore(); |   Ember.$.ajax.restore(); | ||||||
|   return promise; |   return promise; | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test('authenticate should craft a nice payload', function(assert) { | test('authenticate should craft a nice payload', function(assert) { | ||||||
|   assert.expect(2); |   assert.expect(2); | ||||||
|   const stub = sinon.stub($, 'ajax'); |   const stub = sinon.stub(Ember.$, 'ajax'); | ||||||
|   stub.resolves(42); |   stub.resolves(42); | ||||||
|   const authenticator = this.subject(); |   const authenticator = this.subject(); | ||||||
|   authenticator.set('serverTokenEndpoint', 'foo') |   authenticator.set('serverTokenEndpoint', 'foo') | ||||||
|   const promise = authenticator.authenticate('myusername', 'mypassword').then((d) => { |   const promise = authenticator.authenticate('myusername', 'mypassword').then((d) => { | ||||||
|     assert.equal(d, 42); |     assert.equal(d, 42); | ||||||
|   }); |   }); | ||||||
|   assert.ok($.ajax.calledWithMatch({url: 'foo', data: {username: 'myusername', password: 'mypassword'}})); |   assert.ok(Ember.$.ajax.calledWithMatch({url: 'foo', data: {username: 'myusername', password: 'mypassword'}})); | ||||||
|   $.ajax.restore(); |   Ember.$.ajax.restore(); | ||||||
|   return promise; |   return promise; | ||||||
| }); | }); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue