From bfae4422f4946231b15d7ad62b43ffcdef41791f Mon Sep 17 00:00:00 2001 From: Matthew Dillon <matthewrdillon@gmail.com> Date: Sun, 19 Nov 2017 17:15:47 -0700 Subject: [PATCH] ENH: Species and counts (#44) Fixes #31 --- app/components/collection/list-container.js | 1 + app/controllers/collections/index.js | 11 +++++---- app/models/collection-species.js | 12 ++++++++++ app/models/collection.js | 24 ++++++++++++++----- app/models/species.js | 11 +++++++++ app/routes/collections/index.js | 10 +++++++- app/templates/components/ccdb-table.hbs | 10 ++++---- .../components/collection/list-container.hbs | 16 +++++++++++-- 8 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 app/models/collection-species.js create mode 100644 app/models/species.js diff --git a/app/components/collection/list-container.js b/app/components/collection/list-container.js index 1f5c3a5..2ca08c1 100644 --- a/app/components/collection/list-container.js +++ b/app/components/collection/list-container.js @@ -9,6 +9,7 @@ export default Component.extend({ 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', }, diff --git a/app/controllers/collections/index.js b/app/controllers/collections/index.js index 77a2a93..fb40f9a 100644 --- a/app/controllers/collections/index.js +++ b/app/controllers/collections/index.js @@ -6,7 +6,7 @@ const { Controller, computed, get, set } = Ember; export default Controller.extend({ queryParams: ['page', 'project', 'region', 'site', 'study_location', 'collection_method', 'number_of_traps', 'collection_start_date', - 'collection_end_date', 'adfg_permit'], + 'collection_end_date', 'adfg_permit', 'species'], page: 1, project: [], region: [], @@ -14,13 +14,14 @@ export default Controller.extend({ study_location: [], collection_method: [], adfg_permit: [], + species: [], number_of_traps: '', collection_start_date: '', collection_end_date: '', options: computed('projectOptions', 'regionOptions', 'siteOptions', 'studyLocationOptions', 'collectionMethodOptions', - 'adfgPermitOptions', function() { + 'adfgPermitOptions', 'speciesOptions', function() { return { projects: this.get('projectOptions'), regions: this.get('regionOptions'), @@ -28,6 +29,7 @@ export default Controller.extend({ studyLocations: this.get('studyLocationOptions'), collectionMethods: this.get('collectionMethodOptions'), adfgPermits: this.get('adfgPermitOptions'), + species: this.get('speciesOptions'), }; }), @@ -47,7 +49,8 @@ export default Controller.extend({ }, resetFilter() { set(this, 'page', 1); - ['project', 'region', 'site', 'study_location', 'collection_method', 'adfg_permit'].forEach((field) => { + ['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) => { @@ -59,7 +62,7 @@ export default Controller.extend({ set(this, 'page', 1); const filterModelFields = ['project', 'region', 'site', 'study_location', - 'collection_method', 'adfg_permit']; + 'collection_method', 'adfg_permit', 'species']; filterModelFields.forEach((field) => { let fields = get(filter, field); diff --git a/app/models/collection-species.js b/app/models/collection-species.js new file mode 100644 index 0000000..6352890 --- /dev/null +++ b/app/models/collection-species.js @@ -0,0 +1,12 @@ +import DS from 'ember-data'; + +const { Model, attr, belongsTo } = DS; + +export default Model.extend({ + sex: attr('string'), + count: attr('number'), + countEstimated: attr('boolean'), + + collection: belongsTo('collection'), + species: belongsTo('species'), +}); diff --git a/app/models/collection.js b/app/models/collection.js index cd7c707..1db8bfc 100644 --- a/app/models/collection.js +++ b/app/models/collection.js @@ -2,7 +2,7 @@ import Ember from 'ember'; import DS from 'ember-data'; const { computed } = Ember; -const { Model, attr, belongsTo } = DS; +const { Model, attr, belongsTo, hasMany } = DS; export const schema = { displayName: attr('string'), @@ -12,11 +12,23 @@ export const schema = { collectionEndDate: attr('string-null-to-empty'), collectionEndTime: attr('string-null-to-empty'), - project: belongsTo('project'), - studyLocation: belongsTo('study-location'), - collectionMethod: belongsTo('collection-method'), - collectionType: belongsTo('collection-type'), - adfgPermit: belongsTo('adfg-permit'), + project: belongsTo('project'), + studyLocation: belongsTo('study-location'), + collectionMethod: belongsTo('collection-method'), + collectionType: belongsTo('collection-type'), + adfgPermit: belongsTo('adfg-permit'), + + collectionSpecies: hasMany('collection-species', { async: false }), + + species: computed.mapBy('collectionSpecies', 'species'), + speciesNames: computed.mapBy('species', 'commonName'), + counts: computed.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(', '); + }), }; export default Model.extend(Object.assign({}, schema, { diff --git a/app/models/species.js b/app/models/species.js new file mode 100644 index 0000000..e66c4f9 --- /dev/null +++ b/app/models/species.js @@ -0,0 +1,11 @@ +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/routes/collections/index.js b/app/routes/collections/index.js index 37d72f5..179e389 100644 --- a/app/routes/collections/index.js +++ b/app/routes/collections/index.js @@ -15,12 +15,15 @@ export default Route.extend({ 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: 'project,study-location,study-location.site,site,collection-method,adfg-permit', + include: includes.join(','), }; return RSVP.hash({ @@ -30,6 +33,7 @@ export default Route.extend({ studyLocationOptions: store.findAll('study-location'), collectionMethodOptions: store.findAll('collection-method'), adfgPermitOptions: store.findAll('adfg-permit'), + speciesOptions: store.findAll('species'), model: store.query('collection', Object.assign(params, opts)), }); }, @@ -58,6 +62,9 @@ export default Route.extend({ let adfgPermit = controller.get('adfg_permit'); adfgPermit = adfgPermit.map(id => store.peekRecord('adfg-permit', id)); + let species = controller.get('species'); + species = species.map(id => store.peekRecord('species', id)); + const numberOfTraps = controller.get('number_of_traps'); const collectionStartDate = controller.get('collection_start_date'); const collectionEndDate = controller.get('collection_end_date'); @@ -72,6 +79,7 @@ export default Route.extend({ collection_start_date: collectionStartDate, collection_end_date: collectionEndDate, adfg_permit: adfgPermit, + species, } controller.set('filters', filter); }, diff --git a/app/templates/components/ccdb-table.hbs b/app/templates/components/ccdb-table.hbs index 7f1cdfd..0ca9434 100644 --- a/app/templates/components/ccdb-table.hbs +++ b/app/templates/components/ccdb-table.hbs @@ -5,8 +5,10 @@ )}} {{else}} {{ccdb-pagination model=model changePage=(action (optional changePage))}} - {{#light-table table tableClassNames="table table-striped" as |t|}} - {{t.head}} - {{t.body onRowClick=(action (optional onRowClick))}} - {{/light-table}} + <div class="table-responsive"> + {{#light-table table tableClassNames="table table-striped" as |t|}} + {{t.head}} + {{t.body onRowClick=(action (optional onRowClick))}} + {{/light-table}} + </div> {{/if}} diff --git a/app/templates/components/collection/list-container.hbs b/app/templates/components/collection/list-container.hbs index 5d8f481..8377e1e 100644 --- a/app/templates/components/collection/list-container.hbs +++ b/app/templates/components/collection/list-container.hbs @@ -95,7 +95,7 @@ </div> <div class="row"> - <div class="col-md-6"> + <div class="col-md-4"> <label>Start Date</label> {{ pikaday-input @@ -106,7 +106,7 @@ class='form-control' }} </div> - <div class="col-md-6"> + <div class="col-md-4"> <label>End Date</label> {{ pikaday-input @@ -117,6 +117,18 @@ class='form-control' }} </div> + <div class="col-md-4"> + <label>Species</label> + {{#power-select-multiple + options=options.species + selected=filters.species + onchange=(action (mut filters.species)) + searchField='commonName' + as |species| + }} + {{species.commonName}} + {{/power-select-multiple}} + </div> </div> <div class="row top-buffer">