Skip to content

Commit c9c20ad

Browse files
author
DIVYAM TAYAL
authored
Merge branch 'development' into validate-email-5277
2 parents 0d225ea + c874482 commit c9c20ad

File tree

21 files changed

+211
-86
lines changed

21 files changed

+211
-86
lines changed

app/components/footer-main.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,20 @@ import classic from 'ember-classic-decorator';
22
import { classNames, tagName } from '@ember-decorators/component';
33
import { action, computed } from '@ember/object';
44
import Component from '@ember/component';
5+
import { filterBy } from '@ember/object/computed';
6+
import { inject as service } from '@ember/service';
7+
import { sortBy } from 'lodash-es';
58

69
@classic
710
@tagName('footer')
811
@classNames('ui', 'inverted', 'vertical', 'footer', 'segment')
912
export default class FooterMain extends Component {
13+
14+
@service cache;
15+
16+
@filterBy('pages', 'place', 'footer')
17+
footerPages;
18+
1019
@computed
1120
get currentLocale() {
1221
return this.l10n.getLocale();
@@ -17,17 +26,7 @@ export default class FooterMain extends Component {
1726
this.l10n.switchLanguage(locale);
1827
}
1928

20-
didInsertElement() {
21-
this.set('eventLocations', this.eventLocations.sortBy('name'));
22-
23-
const eventTypes = this.eventTypes.sortBy('name').toArray();
24-
eventTypes.forEach(eventType => {
25-
if (eventType.name === 'Other') {
26-
const other = eventType;
27-
eventTypes.splice(eventTypes.indexOf(eventType), 1);
28-
eventTypes.push(other);
29-
}
30-
});
31-
this.set('eventTypes', eventTypes);
29+
async didInsertElement() {
30+
this.set('pages', sortBy(await this.cache.findAll('page'), 'index'));
3231
}
3332
}

app/components/forms/orders/order-form.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ export default Component.extend(FormMixin, {
5454
run.later(() => {
5555
const currentTime = moment();
5656
const diff = moment.duration(willExpireAt.diff(currentTime));
57-
this.set('getRemainingTime', moment.utc(diff.asMilliseconds()).format('mm:ss'));
5857
if (diff > 0) {
58+
this.set('getRemainingTime', moment.utc(diff.asMilliseconds()).format('mm:ss'));
5959
this.timer(willExpireAt, orderIdentifier);
6060
} else {
61+
this.set('getRemainingTime', '00:00');
62+
this.data.set('status', 'expired');
6163
this.data.reload();
6264
this.router.transitionTo('orders.expired', orderIdentifier);
6365
}

app/components/forms/wizard/attendee-step.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,12 @@ export default Component.extend(FormMixin, EventWizardMixin, {
1717

1818
showEditColumn: computed('editableFields.@each', function() {
1919
return this.editableFields?.some(field => field.isComplex);
20-
})
20+
}),
21+
22+
actions: {
23+
removeField(field) {
24+
this.data.customForms.removeObject(field);
25+
}
26+
}
2127
});
28+

app/components/forms/wizard/custom-forms/table.hbs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@
7171
<button class="ui compact icon positive circular button" data-tooltip="{{t 'Edit'}}" {{action @updateField field}}>
7272
<i class="pencil icon"></i>
7373
</button>
74-
{{!-- Hiding till implemented --}}
75-
<button class="ui compact icon negative circular button hidden-item" data-tooltip="{{t 'Delete'}}">
74+
<button class="ui compact icon negative circular button" data-tooltip="{{t 'Delete'}}" {{action (confirm (t "Are you sure you want to delete this?") (action @removeField field))}}>
7675
<i class="trash icon"></i>
7776
</button>
7877
{{/if}}

app/components/forms/wizard/custom-forms/table.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import Component from '@glimmer/component';
22

3-
43
interface CustomForm { isComplex: boolean }
54

65
interface Args {
76
fields: CustomForm[],
8-
updateField: (field: CustomForm) => void
9-
}
7+
removeField: (field: any) => void,
8+
updateField: (field: any) => void
9+
}
1010

1111
export default class CustomFormTable extends Component<Args> {
1212
get editColumn(): boolean {

app/controllers/application.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ export default class ApplicationController extends Controller {
2020
@filterBy('model.notifications', 'isRead', false)
2121
unreadNotifications;
2222

23-
@filterBy('model.pages', 'place', 'footer')
24-
footerPages;
25-
2623
getCookieSeen(write) {
2724
const cookieName = 'seen-cookie-message';
2825
const cookie = this.cookies.read(cookieName);

app/controllers/events/view/tickets/orders/list.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ export default class extends Controller.extend(EmberTableControllerMixin) {
2020
}
2121
},
2222
{
23-
name : 'First Name',
24-
valuePath : 'user.firstName',
25-
width : 50
23+
name : 'First Name',
24+
valuePath : 'user.firstName',
25+
width : 50
2626
},
2727
{
28-
name : 'Last Name',
29-
valuePath : 'user.lastName',
30-
width : 50
28+
name : 'Last Name',
29+
valuePath : 'user.lastName',
30+
width : 50
3131
},
3232
{
3333
name : 'Date and Time',

app/routes/application.js

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { inject as service } from '@ember/service';
44
import Route from '@ember/routing/route';
55
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
66
import { merge, values, isEmpty } from 'lodash-es';
7+
import { hash } from 'rsvp';
78

89
@classic
910
export default class ApplicationRoute extends Route.extend(ApplicationRouteMixin) {
@@ -13,6 +14,9 @@ export default class ApplicationRoute extends Route.extend(ApplicationRouteMixin
1314
@service
1415
currentUser;
1516

17+
@service
18+
cache;
19+
1620
title(tokens) {
1721
if (!tokens) {
1822
tokens = [];
@@ -36,10 +40,10 @@ export default class ApplicationRoute extends Route.extend(ApplicationRouteMixin
3640
}
3741

3842
async model() {
39-
let notificationsPromise = Promise.resolve([]);
43+
let notifications = Promise.resolve([]);
4044
if (this.session.isAuthenticated) {
4145
try {
42-
notificationsPromise = this.authManager.currentUser.query('notifications', {
46+
notifications = this.authManager.currentUser.query('notifications', {
4347
filter: [
4448
{
4549
name : 'is-read',
@@ -55,30 +59,15 @@ export default class ApplicationRoute extends Route.extend(ApplicationRouteMixin
5559
}
5660
}
5761

58-
const pagesPromise = this.store.query('page', {
59-
sort: 'index'
60-
});
61-
62-
const settingsPromise = this.store.queryRecord('setting', {});
63-
const eventTypesPromise = this.store.findAll('event-type');
64-
const eventLocationsPromise = this.store.findAll('event-location');
65-
66-
const [notifications, pages, settings, eventTypes, eventLocations] = await Promise.all([
67-
notificationsPromise,
68-
pagesPromise,
69-
settingsPromise,
70-
eventTypesPromise,
71-
eventLocationsPromise]);
62+
const pages = this.cache.findAll('page');
7263

73-
return {
64+
return hash({
7465
notifications,
7566
pages,
76-
cookiePolicy : settings.cookiePolicy,
77-
cookiePolicyLink : settings.cookiePolicyLink,
78-
socialLinks : settings,
79-
eventTypes,
80-
eventLocations
81-
};
67+
cookiePolicy : this.settings.cookiePolicy,
68+
cookiePolicyLink : this.settings.cookiePolicyLink,
69+
socialLinks : this.settings
70+
});
8271
}
8372

8473
sessionInvalidated() {

app/services/auth-manager.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export default class AuthManagerService extends Service {
1919
@service
2020
bugTracker;
2121

22+
@service
23+
cache;
24+
2225
@computed('session.data.currentUserFallback.id', 'currentUserModel')
2326
get currentUser() {
2427
if (this.currentUserModel) {
@@ -64,6 +67,7 @@ export default class AuthManagerService extends Service {
6467
this.session.invalidate();
6568
this.set('currentUserModel', null);
6669
this.session.set('data.currentUserFallback', null);
70+
this.cache.clear();
6771
}
6872

6973
identify() {

app/services/cache.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/* eslint-disable no-console, prefer-rest-params */
2+
import Service, { inject as service } from '@ember/service';
3+
import DS from 'ember-data';
4+
5+
function pushToStore(store: DS.Store, data: any): any[] | any {
6+
const parsed = data?.value;
7+
if (Array.isArray(parsed)) {
8+
const items = []
9+
for (const item of parsed) {
10+
store.pushPayload(item);
11+
items.push(store.peekRecord(item.data.type, item.data.id));
12+
}
13+
return items;
14+
} else {
15+
store.pushPayload(parsed);
16+
17+
return store.peekRecord(parsed.data.type, parsed.data.id);
18+
}
19+
}
20+
21+
function saveToStorage(key: string, value: any | null) {
22+
if (!value) {return}
23+
let serialized = null;
24+
if (Array.isArray(value.content)) {
25+
serialized = value.map((v: any) => v.serialize({ includeId: true }));
26+
} else {
27+
serialized = value.serialize({ includeId: true });
28+
}
29+
30+
localStorage.setItem(key, JSON.stringify({
31+
time : Date.now(),
32+
value : serialized
33+
}));
34+
}
35+
36+
export default class Cache extends Service.extend({
37+
// anything which *must* be merged to prototype here
38+
}) {
39+
version = 'v1';
40+
41+
@service store!: DS.Store;
42+
43+
get prefix(): string {
44+
return 'cache:' + this.version + ':';
45+
}
46+
47+
isExpired(data: { time: number, value: any} | null): boolean {
48+
// Item expired after 15 seconds
49+
return Boolean(data?.time && (Date.now() - data?.time) > 60 * 1000)
50+
}
51+
52+
async passThrough(key: string, callable: () => any): Promise<any> {
53+
const value = await callable();
54+
saveToStorage(key, value);
55+
56+
return value;
57+
}
58+
59+
async cacheData(key: string, callable: () => any): Promise<any | null> {
60+
key = this.prefix + key;
61+
const stored = localStorage.getItem(key);
62+
try {
63+
if (stored) {
64+
const data = JSON.parse(stored);
65+
66+
if (!data.time) {
67+
// Invalid data structure
68+
return this.passThrough(key, callable);
69+
}
70+
71+
const expired = this.isExpired(data);
72+
const item = pushToStore(this.store, data);
73+
74+
if (expired) {
75+
// Revalidate resource while serving stale
76+
console.info('Item expired. Revalidating...', key);
77+
this.passThrough(key, callable);
78+
}
79+
80+
return item;
81+
} else {
82+
return this.passThrough(key, callable);
83+
}
84+
} catch (e) {
85+
console.error('Error while loading value from cache using key: ' + key, e);
86+
87+
return callable();
88+
}
89+
}
90+
91+
async findAll(model: string, options: any | null): Promise<any> {
92+
const saved = await this.cacheData(model, () => this.store.findAll(model, options));
93+
if (saved) {return saved;}
94+
return this.store.peekAll(model);
95+
}
96+
97+
async queryRecord(key: string, model: string, options: any | null): Promise<any> {
98+
const saved = await this.cacheData(key, () => this.store.queryRecord(model, options));
99+
if (saved) {return saved;}
100+
return this.store.peekRecord(model, 1);
101+
}
102+
103+
clear(): void {
104+
for (const key of Object.keys(localStorage)) {
105+
if (key.startsWith(this.prefix)) {
106+
console.info('Clearing cache entry:', key);
107+
localStorage.removeItem(key);
108+
}
109+
}
110+
}
111+
112+
constructor() {
113+
super(...arguments);
114+
for (const key of Object.keys(localStorage)) {
115+
if (key.startsWith('cache:')) {
116+
if (!key.startsWith(this.prefix)) {
117+
console.info('Removing previous cache entry:', key);
118+
localStorage.removeItem(key);
119+
}
120+
}
121+
}
122+
}
123+
}
124+
125+
// DO NOT DELETE: this is how TypeScript knows how to look up your services.
126+
declare module '@ember/service' {
127+
interface Registry {
128+
'cache': Cache;
129+
}
130+
}

app/services/settings.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { observer } from '@ember/object';
33

44
export default Service.extend({
55

6+
cache : service(),
67
store : service(),
78
session : service(),
89
authManager : service(),
@@ -25,7 +26,7 @@ export default Service.extend({
2526
* @private
2627
*/
2728
async _loadSettings() {
28-
const settingsModel = await this.store.queryRecord('setting', {});
29+
const settingsModel = await this.cache.queryRecord('settings', 'setting', {});
2930
this.store.modelFor('setting').eachAttribute(attributeName => {
3031
this.set(attributeName, settingsModel.get(attributeName));
3132
});

app/templates/application.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
</div>
2222

2323

24-
<FooterMain @eventTypes={{this.model.eventTypes}} @eventLocations={{this.model.eventLocations}} @socialLinks={{this.model.socialLinks}} @footerPages={{this.footerPages}} />
24+
<FooterMain @socialLinks={{this.model.socialLinks}} />
2525

2626
</div>
2727
</SideBar>

app/templates/components/forms/orders/order-form.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</div>
1919
<div class="ui padded segment">
2020
<h4 class="ui horizontal divider header">
21-
<i class="ticket icon"></i>
21+
<i class="dollar icon"></i>
2222
{{t 'Ticket Buyer'}}
2323
</h4>
2424
<div class="field {{if this.buyerHasFirstName 'disabled'}}">

app/templates/components/forms/wizard/attendee-step.hbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@
4949
<div class="column">
5050
<Forms::Wizard::CustomForms::Table
5151
@fields={{this.editableFields}}
52-
@updateField={{action (mut this.field)}} />
52+
@removeField={{action "removeField"}}
53+
@updateField={{action (mut this.field)}}
54+
/>
5355
</div>
5456
</div>
5557
<Forms::Wizard::CustomFormInput

0 commit comments

Comments
 (0)