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 @@
- {{#if (or (eq record.state 'rejected')(eq record.state 'pending'))}} + {{#if (or (eq extraRecords.status 'rejected')(eq extraRecords.status 'pending'))}} {{#ui-dropdown class='ui icon right pointing dropdown button'}} {{/ui-dropdown}} {{/if}} - {{#if (eq record.state 'accepted')}} + {{#if (eq extraRecords.status 'accepted')}} {{#ui-dropdown class='ui icon right pointing dropdown button'}} {{/ui-dropdown}} {{/if}} - {{#if (or (eq record.state 'confirmed') (eq record.state 'pending') (eq record.state 'accepted'))}} + {{#if (or (eq extraRecords.status 'confirmed') (eq extraRecords.status 'pending') (eq extraRecords.status 'accepted'))}} {{#ui-dropdown class='ui icon right pointing dropdown button'}} {{/ui-dropdown}} {{/if}} diff --git a/app/templates/components/ui-table/cell/events/view/sessions/cell-is-mail-sent.hbs b/app/templates/components/ui-table/cell/events/view/sessions/cell-is-mail-sent.hbs index ca418decbca..206602a3dfd 100644 --- a/app/templates/components/ui-table/cell/events/view/sessions/cell-is-mail-sent.hbs +++ b/app/templates/components/ui-table/cell/events/view/sessions/cell-is-mail-sent.hbs @@ -1,5 +1,5 @@ - {{#if record.isMailSent}} + {{#if record}} {{t 'Yes'}} {{else}} {{t 'No'}} diff --git a/app/templates/components/ui-table/cell/events/view/sessions/cell-lock-session.hbs b/app/templates/components/ui-table/cell/events/view/sessions/cell-lock-session.hbs index 73a94f4c595..41bdfe04cdb 100644 --- a/app/templates/components/ui-table/cell/events/view/sessions/cell-lock-session.hbs +++ b/app/templates/components/ui-table/cell/events/view/sessions/cell-lock-session.hbs @@ -1,9 +1,9 @@ -{{#if record.isLocked}} - {{#ui-popup content=(t 'Unlock Session') class='ui basic button' click=(action unlockSession record) position='left center'}} +{{#if extraRecords.isLocked}} + {{#ui-popup content=(t 'Unlock Session') class='ui basic button' click=(action props.actions.unlockSession record) position='left center'}} {{/ui-popup}} {{else}} - {{#ui-popup content=(t 'Lock Session') class='ui basic button' click=(action lockSession record) position='left center'}} + {{#ui-popup content=(t 'Lock Session') class='ui basic button' click=(action props.actions.lockSession record) position='left center'}} {{/ui-popup}} {{/if}} \ No newline at end of file diff --git a/app/templates/components/ui-table/cell/events/view/sessions/cell-rating.hbs b/app/templates/components/ui-table/cell/events/view/sessions/cell-rating.hbs index a6df0b704e1..04e92f0c004 100644 --- a/app/templates/components/ui-table/cell/events/view/sessions/cell-rating.hbs +++ b/app/templates/components/ui-table/cell/events/view/sessions/cell-rating.hbs @@ -1,5 +1,19 @@ -{{ui-rating - rating=(if record.averageRating record.averageRating '0') +{{#if (includes props.options.ratedSessions record)}} + {{#each extraRecords.feedbacks as |feedback|}} + {{#if (eq feedback.user.email authManager.currentUser.email)}} + {{ui-rating + initialRating=feedback.rating + rating=feedback.rating + maxRating=5 + onRate=(pipe-action (action (mut feedback.rating)) (action props.actions.updateRating feedback.rating feedback)) + clearable=true}} + {{/if}} + {{/each}} +{{else}} + {{ui-rating + initialRating=0 + rating=extraRecords.rating maxRating=5 - onRate=(pipe-action (action (mut record.averageRating)) (action updateRating record record.averageRating)) + onRate=(pipe-action (action (mut extraRecords.rating)) (action props.actions.addRating extraRecords.rating record)) clearable=true}} +{{/if}} diff --git a/app/templates/components/ui-table/cell/events/view/sessions/cell-session-title.hbs b/app/templates/components/ui-table/cell/events/view/sessions/cell-session-title.hbs index 5fa667fd180..457ea62a59f 100644 --- a/app/templates/components/ui-table/cell/events/view/sessions/cell-session-title.hbs +++ b/app/templates/components/ui-table/cell/events/view/sessions/cell-session-title.hbs @@ -1,15 +1,15 @@ -{{get record column.propertyName}} +{{record}}
- {{#ui-popup content=(t 'View Session') class="{{if device.isMobile 'medium' 'huge'}} ui icon button" click=(action viewSession record.id) position='left center'}} + {{#ui-popup content=(t 'View Session') class="{{if device.isMobile 'medium' 'huge'}} ui icon button" click=(action props.actions.viewSession record) position='left center'}} {{/ui-popup}} - {{#if (not record.isLocked)}} - {{#ui-popup content=(t 'Edit Session') class="{{if device.isMobile 'medium' 'huge'}} ui icon button" click=(action editSession record.id record.event.id) position='left center'}} + {{#if (not extraRecords.isLocked)}} + {{#ui-popup content=(t 'Edit Session') class="{{if device.isMobile 'medium' 'huge'}} ui icon button" click=(action props.actions.editSession record extraRecords.event.id) position='left center'}} {{/ui-popup}} {{/if}} - {{#ui-popup content=(t 'Delete Session') click=(action (confirm (t 'Are you sure you would like to delete this Session?') (action deleteSession record))) class="{{if device.isMobile 'medium' 'huge'}} ui icon button" position='left center'}} + {{#ui-popup content=(t 'Delete Session') click=(action (confirm (t 'Are you sure you would like to delete this Session?') (action props.actions.deleteSession record))) class="{{if device.isMobile 'medium' 'huge'}} ui icon button" position='left center'}} {{/ui-popup}}
diff --git a/app/templates/events/view/sessions/list.hbs b/app/templates/events/view/sessions/list.hbs index e7d37a7e322..a4d8393249a 100644 --- a/app/templates/events/view/sessions/list.hbs +++ b/app/templates/events/view/sessions/list.hbs @@ -1,23 +1,16 @@
- {{events/events-table - columns=columns - data=model.data - store=model.store - query=model.query - isNotStoreQuery = true - modelName = model.objectType - useNumericPagination=true - showGlobalFilter=true - showPageSize=true - lockSession=(action 'lockSession') - unlockSession=(action 'unlockSession') - deleteSession=(action 'deleteSession') - editSession=(action 'editSession') - viewSession=(action 'viewSession') - acceptProposal=(action 'acceptProposal') - rejectProposal=(action 'rejectProposal') - confirmProposal=(action 'confirmProposal') - updateRating=(action 'updateRating') - customGlobalFilter='title' + {{tables/default columns=columns + rows=model.data + feedbacks=model.feedbacks + currentPage=page + pageSize=per_page + searchQuery=search + sortBy=sort_by + sortDir=sort_dir + metaData=model.meta + filterOptions=filterOptions + widthConstraint="eq-container" + resizeMode="fluid" + fillMode="equal-column" }}