diff --git a/app/controllers/events/view/sessions/list.js b/app/controllers/events/view/sessions/list.js index 3397673038b..80a6a8f0193 100644 --- a/app/controllers/events/view/sessions/list.js +++ b/app/controllers/events/view/sessions/list.js @@ -1,204 +1,269 @@ import Controller from '@ember/controller'; +import { computed, action } from '@ember/object'; +import { mapBy } from '@ember/object/computed'; +import EmberTableControllerMixin from 'open-event-frontend/mixins/ember-table-controller'; -export default Controller.extend({ - columns: [ - { - propertyName : 'state', - title : 'State', - disableSorting : true, - template : 'components/ui-table/cell/events/view/sessions/cell-session-state' - }, - { - propertyName : 'title', - title : 'Title', - disableSorting : true, - template : 'components/ui-table/cell/events/view/sessions/cell-session-title' - }, - { - propertyName : 'speakers', - template : 'components/ui-table/cell/cell-speakers', - title : 'Speakers', - disableSorting : true - }, - { - propertyName : 'average_rating', - template : 'components/ui-table/cell/events/view/sessions/cell-rating', - title : 'Rating', - disableSorting : false - }, - { - propertyName : 'track.name', - title : 'Track' - }, - { - propertyName : 'sessionType.name', - title : 'Type' - }, - { - propertyName : 'submittedAt', - template : 'components/ui-table/cell/cell-simple-date', - dateFormat : 'MMMM DD, YYYY - HH:mm A', - title : 'Submission Date' - }, - { - propertyName : 'lastModifiedAt', - template : 'components/ui-table/cell/cell-simple-date', - dateFormat : 'MMMM DD, YYYY - HH:mm A', - title : 'Last Modified' - }, - { - propertyName : 'is-mail-sent', - title : 'Email Sent', - template : 'components/ui-table/cell/events/view/sessions/cell-is-mail-sent', - disableSorting : true - }, - { - template : 'components/ui-table/cell/events/view/sessions/cell-buttons', - title : 'Actions', - disableSorting : true, - disableFiltering : true - }, - { - template : 'components/ui-table/cell/events/view/sessions/cell-lock-session', - title : 'Lock Session', - disableSorting : true, - disableFiltering : true +export default class extends Controller.extend(EmberTableControllerMixin) { + @mapBy('model.feedbacks', 'session.id') ratedSessions; + + @computed() + get columns() { + return [ + { + name : 'State', + valuePath : 'status', + isSortable : true, + headerComponent : 'tables/headers/sort', + cellComponent : 'ui-table/cell/events/view/sessions/cell-session-state' + }, + { + name : 'Title', + valuePath : 'title', + extraValuePaths : ['event', 'isLocked'], + isSortable : true, + headerComponent : 'tables/headers/sort', + cellComponent : 'ui-table/cell/events/view/sessions/cell-session-title', + width : 160, + actions : { + viewSession : this.viewSession.bind(this), + editSession : this.editSession.bind(this), + deleteSession : this.deleteSession.bind(this) + } + }, + { + name : 'Speakers', + valuePath : 'speakers', + cellComponent : 'ui-table/cell/cell-speakers' + }, + { + name : 'Rating', + valuePath : 'id', + extraValuePaths : ['rating', 'feedbacks'], + cellComponent : 'ui-table/cell/events/view/sessions/cell-rating', + options : { + ratedSessions: this.ratedSessions + }, + actions: { + updateRating : this.updateRating.bind(this), + addRating : this.addRating.bind(this) + } + }, + { + name : 'Avg Rating', + valuePath : 'averageRating', + isSortable : true, + headerComponent : 'tables/headers/sort' + }, + { + name : 'No. of ratings', + valuePath : 'feedbacks.length', + isSortable : true, + headerComponent : 'tables/headers/sort' + }, + { + name : 'Track', + valuePath : 'track.name' + }, + { + name : 'Type', + valuePath : 'sessionType.name' + }, + { + name : 'Submission Date', + valuePath : 'submittedAt', + cellComponent : 'ui-table/cell/cell-simple-date', + width : 60, + options : { + dateFormat: 'MMMM DD, YYYY - HH:mm A' + } + }, + { + name : 'Last Modified', + valuePath : 'lastModifiedAt', + cellComponent : 'ui-table/cell/cell-simple-date', + width : 60, + options : { + dateFormat: 'MMMM DD, YYYY - HH:mm A' + } + }, + { + name : 'Email Sent', + valuePath : 'isMailSent', + cellComponent : 'ui-table/cell/events/view/sessions/cell-is-mail-sent' + }, + { + name : 'Actions', + cellComponent : 'ui-table/cell/events/view/sessions/cell-buttons', + valuePath : 'id', + extraValuePaths : ['status'], + actions : { + acceptProposal : this.acceptProposal.bind(this), + confirmProposal : this.confirmProposal.bind(this), + rejectProposal : this.rejectProposal.bind(this) + } + }, + { + name : 'Lock Session', + valuePath : 'id', + extraValuePaths : ['isLocked'], + cellComponent : 'ui-table/cell/events/view/sessions/cell-lock-session', + actions : { + unlockSession : this.unlockSession.bind(this), + lockSession : this.lockSession.bind(this) + } + } + ]; + } + + @action + async deleteSession(session_id) { + this.set('isLoading', true); + try { + let session = this.store.peekRecord('session', session_id, { backgroundReload: false }); + await session.destroyRecord(); + this.notify.success(this.l10n.t('Session has been deleted successfully.')); + } catch (e) { + console.warn(e); + this.notify.error(this.l10n.t('An unexpected error has occurred.')); } - ], - actions: { - deleteSession(session) { - this.set('isLoading', true); - session.destroyRecord() - .then(() => { - this.notify.success(this.l10n.t('Session has been deleted successfully.')); - }) - .catch(() => { - this.notify.error(this.l10n.t('An unexpected error has occurred.')); - }) - .finally(() => { - this.set('isLoading', false); - }); - }, - editSession(id) { - this.transitionToRoute('events.view.sessions.edit', id); - }, - viewSession(id) { - this.transitionToRoute('events.view.sessions.edit', id); - }, - lockSession(session) { + this.set('isLoading', false); + } + + @action + editSession(session_id, event_id) { + this.transitionToRoute('events.view.sessions.edit', event_id, session_id); + } + + @action + viewSession(id) { + this.transitionToRoute('my-sessions.view', id); + } + + @action + async lockSession(session_id) { + try { + let session = this.store.peekRecord('session', session_id, { backgroundReload: false }); session.set('isLocked', true); this.set('isLoading', true); - session.save() - .then(() => { - this.notify.success(this.l10n.t('Session has been locked successfully.')); - this.send('refreshRoute'); - }) - .catch(() => { - this.notify.error(this.l10n.t('An unexpected error has occurred.')); - }) - .finally(() => { - this.set('isLoading', false); - }); - }, - unlockSession(session) { + await session.save(); + this.notify.success(this.l10n.t('Session has been locked successfully.')); + } catch (error) { + this.notify.error(this.l10n.t(error.message)); + } + this.send('refreshRoute'); + this.set('isLoading', false); + } + + @action + async unlockSession(session_id) { + try { + let session = this.store.peekRecord('session', session_id, { backgroundReload: false }); session.set('isLocked', false); this.set('isLoading', true); - session.save() - .then(() => { - this.notify.success(this.l10n.t('Session has been unlocked successfully.')); - this.send('refreshRoute'); - }) - .catch(() => { - this.notify.error(this.l10n.t('An unexpected error has occurred.')); - }) - .finally(() => { - this.set('isLoading', false); - }); - }, - acceptProposal(session, sendEmail) { - session.set('sendEmail', sendEmail); - session.set('state', 'accepted'); - session.set('isMailSent', sendEmail); + await session.save(); + this.notify.success(this.l10n.t('Session has been unlocked successfully.')); + } catch (error) { + this.notify.error(this.l10n.t(error.message)); + } + this.send('refreshRoute'); + this.set('isLoading', false); + } + + @action + async acceptProposal(session_id, sendEmail) { + try { + let session = this.store.peekRecord('session', session_id, { backgroundReload: false }); + session.setProperties({ + sendEmail, + 'state' : 'accepted', + 'isMailSent' : sendEmail + }); this.set('isLoading', true); - session.save() - .then(() => { - sendEmail ? this.notify.success(this.l10n.t('Session has been accepted and speaker has been notified via email.')) - : this.notify.success(this.l10n.t('Session has been accepted')); - this.send('refreshRoute'); - }) - .catch(() => { - this.notify.error(this.l10n.t('An unexpected error has occurred.')); - }) - .finally(() => { - this.set('isLoading', false); - }); - }, - confirmProposal(session, sendEmail) { - session.set('sendEmail', sendEmail); - session.set('state', 'confirmed'); - session.set('isMailSent', sendEmail); + await session.save(); + sendEmail ? this.notify.success(this.l10n.t('Session has been accepted and speaker has been notified via email.')) + : this.notify.success(this.l10n.t('Session has been accepted')); + } catch (error) { + this.notify.error(this.l10n.t(error.message)); + } + this.send('refreshRoute'); + this.set('isLoading', false); + } + + @action + async confirmProposal(session_id, sendEmail) { + try { + let session = this.store.peekRecord('session', session_id, { backgroundReload: false }); + session.setProperties({ + sendEmail, + 'state' : 'confirmed', + 'isMailSent' : sendEmail + }); this.set('isLoading', true); - session.save() - .then(() => { - sendEmail ? this.notify.success(this.l10n.t('Session has been confirmed and speaker has been notified via email.')) - : this.notify.success(this.l10n.t('Session has been confirmed')); - this.send('refreshRoute'); - }) - .catch(() => { - this.notify.error(this.l10n.t('An unexpected error has occurred.')); - }) - .finally(() => { - this.set('isLoading', false); - }); - }, - rejectProposal(session, sendEmail) { - session.set('sendEmail', sendEmail); - session.set('state', 'rejected'); - session.set('isMailSent', sendEmail); + await session.save(); + sendEmail ? this.notify.success(this.l10n.t('Session has been confirmed and speaker has been notified via email.')) + : this.notify.success(this.l10n.t('Session has been confirmed')); + } catch (error) { + this.notify.error(this.l10n.t(error.message)); + } + this.send('refreshRoute'); + this.set('isLoading', false); + } + + @action + async rejectProposal(session_id, sendEmail) { + try { + let session = this.store.peekRecord('session', session_id, { backgroundReload: false }); + session.setProperties({ + sendEmail, + 'state' : 'rejected', + 'isMailSent' : sendEmail + }); this.set('isLoading', true); - session.save() - .then(() => { - sendEmail ? this.notify.success(this.l10n.t('Session has been rejected and speaker has been notified via email.')) - : this.notify.success(this.l10n.t('Session has been rejected')); - this.send('refreshRoute'); - }) - .catch(() => { - this.notify.error(this.l10n.t('An unexpected error has occurred.')); - }) - .finally(() => { - this.set('isLoading', false); - }); - }, - async updateRating(session, rating) { - try { - if (session.feedbacks.length) { - this.set('isLoading', true); - const user = this.authManager.currentUser; - let feedback = session.feedbacks.firstObject; - feedback.setProperties({ - user, - rating - }); - await feedback.save(); - this.notify.success(this.l10n.t('Session feedback has been updated successfully.')); - } else { - this.set('isLoading', true); - const user = this.authManager.currentUser; - const comment = ''; - let feedback = await this.store.createRecord('feedback', { - rating, - comment, - session, - user - }); - await feedback.save(); - this.notify.success(this.l10n.t('Session feedback has been created successfully.')); - } - } catch (error) { - this.notify.error(this.l10n.t(error.message)); + await session.save(); + sendEmail ? this.notify.success(this.l10n.t('Session has been rejected and speaker has been notified via email.')) + : this.notify.success(this.l10n.t('Session has been rejected')); + } catch (error) { + this.notify.error(this.l10n.t(error.message)); + } + this.send('refreshRoute'); + this.set('isLoading', false); + } + + @action + async updateRating(rating, feedback) { + try { + this.set('isLoading', true); + if (rating) { + feedback.set('rating', rating); + await feedback.save(); + } else { + await feedback.destroyRecord(); } - this.send('refreshRoute'); - this.set('isLoading', false); + this.notify.success(this.l10n.t('Session feedback has been updated successfully.')); + } catch (error) { + this.notify.error(this.l10n.t(error.message)); + } + this.send('refreshRoute'); + this.set('isLoading', false); + } + + @action + async addRating(rating, session_id) { + try { + let session = this.store.peekRecord('session', session_id, { backgroundReload: false }); + this.set('isLoading', true); + let feedback = await this.store.createRecord('feedback', { + rating, + session, + comment : '', + user : this.authManager.currentUser + }); + await feedback.save(); + this.notify.success(this.l10n.t('Session feedback has been created successfully.')); + } catch (error) { + this.notify.error(this.l10n.t(error.message)); } + this.send('refreshRoute'); + this.set('isLoading', false); } -}); \ No newline at end of file +} diff --git a/app/models/user.js b/app/models/user.js index 9340fc7fb92..8baa1cf5c0c 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -83,6 +83,7 @@ export default ModelBase.extend({ orders : hasMany('order'), events : hasMany('event', { inverse: 'user' }), sessions : hasMany('session'), + feedbacks : hasMany('feedback'), invoice : hasMany('event-invoice'), attendees : hasMany('attendee'), speakers : hasMany('speaker'), diff --git a/app/routes/events/view/sessions/list.js b/app/routes/events/view/sessions/list.js index 02c808d4620..4ce14a9cd92 100644 --- a/app/routes/events/view/sessions/list.js +++ b/app/routes/events/view/sessions/list.js @@ -56,6 +56,8 @@ export default class extends Route.extend(EmberTableRouteMixin) { } else { filterOptions = []; } + + let store = this.modelFor('events.view'); filterOptions = this.applySearchFilters(filterOptions, params, searchField); let queryString = { include : 'speakers,feedbacks', @@ -64,17 +66,35 @@ export default class extends Route.extend(EmberTableRouteMixin) { 'page[number]' : params.page || 1 }; queryString = this.applySortFilters(queryString, params); + let data = (await store.query('sessions', queryString)).toArray(); - let store = this.modelFor('events.view'); - + let queryObject = { + include : 'session', + filter : [ + { + name : 'session', + op : 'has', + val : { + name : 'event', + op : 'has', + val : { + name : 'identifier', + op : 'eq', + val : store.id + } + } + } + ] + }; + let feedbacks = await this.authManager.currentUser.query('feedbacks', queryObject); return { - data: await store.query('sessions', queryString) + data, + feedbacks }; } - @action + @action refreshRoute() { this.refresh(); } - } diff --git a/app/templates/components/ui-table/cell/events/view/sessions/cell-buttons.hbs b/app/templates/components/ui-table/cell/events/view/sessions/cell-buttons.hbs index 493a7734420..e5ae550cd29 100644 --- a/app/templates/components/ui-table/cell/events/view/sessions/cell-buttons.hbs +++ b/app/templates/components/ui-table/cell/events/view/sessions/cell-buttons.hbs @@ -1,28 +1,28 @@