diff --git a/app/controllers/admin/users/view/events/list.js b/app/controllers/admin/users/view/events/list.js index 13b44efb2ba..72f1b5eb8f4 100644 --- a/app/controllers/admin/users/view/events/list.js +++ b/app/controllers/admin/users/view/events/list.js @@ -1,82 +1,121 @@ import Controller from '@ember/controller'; +import { computed, action } from '@ember/object'; +import EmberTableControllerMixin from 'open-event-frontend/mixins/ember-table-controller'; +import { or } from '@ember/object/computed'; -export default Controller.extend({ - columns: [ - { - propertyName : 'name', - template : 'components/ui-table/cell/cell-event', - title : 'Name' - }, - { - propertyName : 'startsAt', - template : 'components/ui-table/cell/cell-event-date', - dateFormat : 'MMMM DD, YYYY - HH:mm A', - title : 'Date And Time' - }, - { - propertyName : 'sessionsByState', - template : 'components/ui-table/cell/cell-sessions', - title : 'Sessions', - disableSorting : true, - disableFiltering : true - }, - { - propertyName : 'eventStatisticsGeneral.speakers', - template : 'components/ui-table/cell/cell-speakers-dashboard', - title : 'Speakers', - disableSorting : true, - disableFiltering : true - }, - { - propertyName : 'tickets', - template : 'components/ui-table/cell/cell-tickets', - title : 'Tickets', - disableSorting : true, - disableFiltering : true - }, - { - propertyName : 'url', - template : 'components/ui-table/cell/cell-link', - title : 'Public URL', - disableSorting : true, - disableFiltering : true - }, - { - template : 'components/ui-table/cell/cell-buttons', - title : 'Actions', - disableSorting : true, - disableFiltering : true - } - ], - actions: { - moveToDetails(id) { - this.transitionToRoute('events.view', id); - }, - editEvent(id) { - this.transitionToRoute('events.view.edit.basic-details', id); - }, - openDeleteEventModal(id, name) { - this.set('isEventDeleteModalOpen', true); - this.set('confirmName', ''); - this.set('eventName', name); - this.set('eventId', id); - }, - deleteEvent() { - this.set('isLoading', true); - this.store.findRecord('event', this.eventId, { backgroundReload: false }).then(function(event) { - event.destroyRecord(); - }) - .then(() => { - this.notify.success(this.l10n.t('Event has been deleted successfully.')); - }) - .catch(() => { - this.notify.error(this.l10n.t('An unexpected error has occurred.')); - }) - .finally(() => { - this.set('isLoading', false); - }); - this.set('isEventDeleteModalOpen', false); +export default class extends Controller.extend(EmberTableControllerMixin) { + + @or('authManager.currentUser.isSuperAdmin', 'authManager.currentUser.isAdmin') hasRestorePrivileges; + + @computed() + get columns() { + return [ + { + name : 'Name', + valuePath : 'id', + extraValuePaths : ['logoUrl', 'name', 'identifier', 'deletedAt'], + isSortable : true, + headerComponent : 'tables/headers/sort', + cellComponent : 'ui-table/cell/cell-event', + options : { + hasRestorePrivileges: this.hasRestorePrivileges + }, + actions: { + moveToDetails : this.moveToDetails.bind(this), + editEvent : this.editEvent.bind(this), + openDeleteEventModal : this.openDeleteEventModal.bind(this), + deleteEvent : this.deleteEvent.bind(this), + restoreEvent : this.restoreEvent.bind(this) + } + }, + { + name : 'Date', + valuePath : 'startsAt', + extraValuePaths : ['endsAt'], + isSortable : true, + headerComponent : 'tables/headers/sort', + cellComponent : 'ui-table/cell/cell-event-date' + + }, + { + name : 'Sessions', + valuePath : 'eventStatisticsGeneral', + width : 80, + isSortable : false, + cellComponent : 'ui-table/cell/cell-sessions-dashboard' + }, + { + name : 'Speakers', + valuePath : 'eventStatisticsGeneral', + cellComponent : 'ui-table/cell/cell-speakers-dashboard', + isSortable : false + + }, + { + name : 'Tickets', + valuePath : 'tickets', + cellComponent : 'ui-table/cell/cell-tickets', + isSortable : false + + }, + { + name : 'Public URL', + valuePath : 'url', + cellComponent : 'ui-table/cell/cell-link', + isSortable : false + } + ]; + } + + @action + moveToDetails(id) { + this.transitionToRoute('events.view', id); + } + + @action + editEvent(id) { + this.transitionToRoute('events.view.edit.basic-details', id); + } + + @action + openDeleteEventModal(id, name) { + this.setProperties({ + isEventDeleteModalOpen : true, + confirmName : '', + eventName : name, + eventId : id + }); + } + + @action + async deleteEvent() { + this.set('isLoading', true); + + try { + const event = this.store.peekRecord('event', this.eventId, { backgroundReload: false }); + await event.destroyRecord(); + this.notify.success(this.l10n.t('Event has been deleted successfully.')); + } catch (e) { + this.notify.error(this.l10n.t('An unexpected error has occurred.')); } + this.setProperties({ + isLoading : false, + isEventDeleteModalOpen : false + }); } -}); + @action + async restoreEvent(event_id) { + this.set('isLoading', true); + try { + let event = this.store.peekRecord('event', event_id, { backgroundReload: false }); + event.set('deletedAt', null); + await event.save({ adapterOptions: { getTrashed: true } }); + this.notify.success(this.l10n.t('Event has been restored successfully.')); + } catch (e) { + console.warn(e); + this.notify.error(this.l10n.t('An unexpected error has occurred.')); + } + this.set('isLoading', false); + } +} diff --git a/app/routes/admin/users/view/events/list.js b/app/routes/admin/users/view/events/list.js index dca4b4c300a..7a345b3d968 100644 --- a/app/routes/admin/users/view/events/list.js +++ b/app/routes/admin/users/view/events/list.js @@ -1,47 +1,46 @@ import Route from '@ember/routing/route'; -import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; import moment from 'moment'; +import EmberTableRouteMixin from 'open-event-frontend/mixins/ember-table-route'; -export default Route.extend(AuthenticatedRouteMixin, { - titleToken() { - switch (this.get('params.event_status')) { - case 'live': - return this.l10n.t('Live'); - case 'draft': - return this.l10n.t('Draft'); - case 'past': - return this.l10n.t('Past'); - } - }, - async model(params) { - this.set('params', params); +export default class extends Route.extend(EmberTableRouteMixin) { + async model(params) { let filterOptions = []; + const searchField = 'name'; if (params.event_status === 'live') { filterOptions = [ { - name : 'state', - op : 'eq', - val : 'published' - }, - { - or: [ + and: [ { - name : 'starts-at', - op : 'ge', - val : moment().toISOString() + name : 'deleted-at', + op : 'eq', + val : null + }, + { + name : 'state', + op : 'eq', + val : 'published' }, { - and: [ + or: [ { name : 'starts-at', - op : 'le', + op : 'ge', val : moment().toISOString() }, { - name : 'ends-at', - op : 'gt', - val : moment().toISOString() + and: [ + { + name : 'starts-at', + op : 'le', + val : moment().toISOString() + }, + { + name : 'ends-at', + op : 'gt', + val : moment().toISOString() + } + ] } ] } @@ -51,42 +50,62 @@ export default Route.extend(AuthenticatedRouteMixin, { } else if (params.event_status === 'past') { filterOptions = [ { - name : 'ends-at', - op : 'lt', - val : moment().toISOString() - }, + and: [ + { + name : 'deleted-at', + op : 'eq', + val : null + }, + { + name : 'ends-at', + op : 'lt', + val : moment().toISOString() + }, + { + name : 'state', + op : 'eq', + val : 'published' + } + ] + } + ]; + } else if (params.event_status === 'draft') { + filterOptions = [ { - name : 'state', - op : 'eq', - val : 'published' + and: + [ + { + name : 'deleted-at', + op : 'eq', + val : null + }, + { + name : 'state', + op : 'eq', + val : 'draft' + } + ] + } ]; - } else { + } else if (params.event_status === 'deleted') { filterOptions = [ { - name : 'state', - op : 'eq', - val : 'draft' + name : 'deleted-at', + op : 'ne', + val : null } ]; } - - let queryObject = { - include : 'tickets,sessions,speakers', - filter : filterOptions, - 'page[size]' : 10 - }; - - const store = this.modelFor('admin.users.view'); - - const data = await store.query('events', queryObject); - - return { - data, - store, - query : queryObject, - objectType : 'events' + filterOptions = this.applySearchFilters(filterOptions, params, searchField); + let queryString = { + get_trashed : true, + include : 'tickets,sessions,speakers', + filter : filterOptions, + 'page[size]' : params.per_page || 10, + 'page[number]' : params.page || 1 }; - + queryString = this.applySortFilters(queryString, params); + return this.asArray(this.modelFor('admin.users.view').query('events', queryString)); } -}); +} diff --git a/app/templates/admin/users/view/events.hbs b/app/templates/admin/users/view/events.hbs index c655dd009e7..4bf3eca83e8 100644 --- a/app/templates/admin/users/view/events.hbs +++ b/app/templates/admin/users/view/events.hbs @@ -11,6 +11,9 @@ {{#link-to 'admin.users.view.events.list' 'past' class='item'}} {{t 'Past'}} {{/link-to}} + {{#link-to 'admin.users.view.events.list' 'deleted' class='item'}} + {{t 'Deleted'}} + {{/link-to}} {{/tabbed-navigation}} diff --git a/app/templates/admin/users/view/events/list.hbs b/app/templates/admin/users/view/events/list.hbs index a21bb469b7b..95eb05da6e2 100644 --- a/app/templates/admin/users/view/events/list.hbs +++ b/app/templates/admin/users/view/events/list.hbs @@ -1,16 +1,15 @@ -{{events/events-table - columns=columns - data=model.data - store=model.store - query=model.query - modelName = model.objectType - useNumericPagination=true - showGlobalFilter=true - showPageSize=true - useFilteringByColumns=true - moveToDetails=(action 'moveToDetails') - editEvent=(action 'editEvent') - openDeleteEventModal=(action 'openDeleteEventModal') +{{tables/default columns=columns + rows=model.data + 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" }} {{modals/event-delete-modal isLoading=isLoading isOpen=isEventDeleteModalOpen confirmName=confirmName eventName=eventName deleteEvent=(action 'deleteEvent')}} diff --git a/app/templates/components/ui-table/cell/cell-event-date.hbs b/app/templates/components/ui-table/cell/cell-event-date.hbs index 302f2e706e4..34d8224a01d 100644 --- a/app/templates/components/ui-table/cell/cell-event-date.hbs +++ b/app/templates/components/ui-table/cell/cell-event-date.hbs @@ -1,19 +1,17 @@ -{{#if record.startsAt}} - {{#if record.endsAt}} +{{#if record}} + {{#if extraRecords.endsAt}}
- {{moment-format record.startsAt 'MMMM DD, YYYY - hh:mm A'}} + {{moment-format record 'MMMM DD, YYYY - hh:mm A'}}
(to)
- {{moment-format record.endsAt 'MMMM DD, YYYY - hh:mm A'}} + {{moment-format extraRecords.endsAt 'MMMM DD, YYYY - hh:mm A'}}
- {{else}} {{t 'No dates available.'}} {{/if}} - {{else}} {{t 'No dates available.'}} diff --git a/app/templates/components/ui-table/cell/cell-sessions-dashboard.hbs b/app/templates/components/ui-table/cell/cell-sessions-dashboard.hbs index 7bc4bcd9a4d..e22bc2d0c0a 100644 --- a/app/templates/components/ui-table/cell/cell-sessions-dashboard.hbs +++ b/app/templates/components/ui-table/cell/cell-sessions-dashboard.hbs @@ -1,7 +1,7 @@
-
{{t 'Submitted'}}: {{record.eventStatisticsGeneral.sessions}}
-
{{t 'Accepted'}}: {{record.eventStatisticsGeneral.sessionsAccepted}}
-
{{t 'Confirmed'}}: {{record.eventStatisticsGeneral.sessionsConfirmed}}
-
{{t 'Pending'}}: {{record.eventStatisticsGeneral.sessionsPending}}
-
{{t 'Rejected'}}: {{record.eventStatisticsGeneral.sessionsRejected}}
+
{{t 'Submitted'}}: {{record.sessions}}
+
{{t 'Accepted'}}: {{record.sessionsAccepted}}
+
{{t 'Confirmed'}}: {{record.sessionsConfirmed}}
+
{{t 'Pending'}}: {{record.sessionsPending}}
+
{{t 'Rejected'}}: {{record.sessionsRejected}}
diff --git a/tests/integration/components/ui-table/cell/admin/reports/system-logs/mail-logs/cell-mail-message-test.js b/tests/integration/components/ui-table/cell/admin/reports/system-logs/mail-logs/cell-mail-message-test.js index 64d10691324..1cfa5cba78a 100644 --- a/tests/integration/components/ui-table/cell/admin/reports/system-logs/mail-logs/cell-mail-message-test.js +++ b/tests/integration/components/ui-table/cell/admin/reports/system-logs/mail-logs/cell-mail-message-test.js @@ -6,11 +6,17 @@ import { render } from '@ember/test-helpers'; module('Integration | Component | ui table/cell/admin/reports/system logs/mail logs/cell mail message', function(hooks) { setupIntegrationTest(hooks); - const record = { message: 'Hello', subject: 'New User' }; + const record = 'Hello'; + const extraRecords = { + subject: 'New User' + }; test('it renders', async function(assert) { - this.set('record', record); - await render(hbs `{{ui-table/cell/admin/reports/system-logs/mail-logs/cell-mail-message record=record}}`); + this.setProperties({ + record, + extraRecords } + ); + await render(hbs `{{ui-table/cell/admin/reports/system-logs/mail-logs/cell-mail-message record=record extraRecords=extraRecords}}`); assert.ok(this.element.innerHTML.trim().includes('Hello')); }); }); diff --git a/tests/integration/components/ui-table/cell/cell-link-test.js b/tests/integration/components/ui-table/cell/cell-link-test.js index bf094dde8b1..759c587f795 100644 --- a/tests/integration/components/ui-table/cell/cell-link-test.js +++ b/tests/integration/components/ui-table/cell/cell-link-test.js @@ -6,10 +6,10 @@ import { render } from '@ember/test-helpers'; module('Integration | Component | ui table/cell/cell link', function(hooks) { setupIntegrationTest(hooks); - const record = { url: 'Event' }; test('it renders', async function(assert) { - this.set('record', record); + this.set('record', 'https://url.test'); await render(hbs `{{ui-table/cell/cell-link record=record}}`); - assert.ok(this.element.innerHTML.trim().includes('Event')); + assert.ok(this.element.innerHTML.trim().includes('https://url.test')); }); }); + diff --git a/tests/integration/components/ui-table/cell/cell-tickets-test.js b/tests/integration/components/ui-table/cell/cell-tickets-test.js index 1734827111b..e90f29fdf68 100644 --- a/tests/integration/components/ui-table/cell/cell-tickets-test.js +++ b/tests/integration/components/ui-table/cell/cell-tickets-test.js @@ -6,7 +6,7 @@ import { render } from '@ember/test-helpers'; module('Integration | Component | ui table/cell/cell tickets', function(hooks) { setupIntegrationTest(hooks); - const record = { tickets: [{ type: 'Premium', order: 12, total: 100 }] }; + const record = [{ type: 'Premium', order: 12, total: 100 }]; test('it renders', async function(assert) { this.set('record', record); await render(hbs `{{ui-table/cell/cell-tickets record=record}}`);