@fleetbase/storefront-engine 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/addon/components/modals/add-store-to-category.hbs +5 -0
  2. package/addon/components/modals/create-network-category.hbs +28 -28
  3. package/addon/components/modals/share-network.hbs +3 -3
  4. package/addon/components/modals/store-details.hbs +22 -0
  5. package/addon/components/modals/store-form.hbs +22 -0
  6. package/addon/components/modals/store-form.js +21 -0
  7. package/addon/components/network-category-picker.hbs +40 -0
  8. package/addon/components/network-category-picker.js +83 -0
  9. package/addon/components/store-selector.hbs +4 -2
  10. package/addon/components/widget/orders.js +22 -17
  11. package/addon/controllers/networks/index/network/index.js +133 -9
  12. package/addon/controllers/networks/index/network/stores.js +422 -153
  13. package/addon/controllers/networks/index.js +66 -4
  14. package/addon/controllers/products/index/category.js +1 -1
  15. package/addon/controllers/settings/index.js +14 -7
  16. package/addon/controllers/settings/notifications.js +1 -1
  17. package/addon/models/store.js +44 -7
  18. package/addon/routes/networks/index/network/customers.js +4 -1
  19. package/addon/routes/networks/index/network/orders.js +4 -1
  20. package/addon/routes/networks/index/network/stores.js +19 -15
  21. package/addon/serializers/store.js +1 -0
  22. package/addon/templates/customers/index.hbs +0 -11
  23. package/addon/templates/networks/index/network/index.hbs +1 -1
  24. package/addon/templates/networks/index/network/stores.hbs +8 -163
  25. package/addon/templates/networks/index/network.hbs +2 -3
  26. package/addon/utils/create-shareable-link.js +21 -0
  27. package/app/components/modals/add-store-to-category.js +1 -0
  28. package/app/components/modals/store-details.js +1 -0
  29. package/app/components/modals/store-form.js +1 -0
  30. package/app/components/network-category-picker.js +1 -0
  31. package/app/utils/create-shareable-link.js +1 -0
  32. package/package.json +3 -4
@@ -2,53 +2,265 @@ import Controller from '@ember/controller';
2
2
  import { tracked } from '@glimmer/tracking';
3
3
  import { inject as service } from '@ember/service';
4
4
  import { action, set } from '@ember/object';
5
- import consoleUrl from '@fleetbase/console/utils/console-url';
6
- import isEmail from '@fleetbase/console/utils/is-email';
5
+ import { isBlank } from '@ember/utils';
6
+ import { timeout } from 'ember-concurrency';
7
+ import { task } from 'ember-concurrency-decorators';
8
+ import createShareableLink from '../../../../utils/create-shareable-link';
9
+ import isEmail from '@fleetbase/ember-core/utils/is-email';
10
+ import isModel from '@fleetbase/ember-core/utils/is-model';
7
11
 
8
12
  export default class NetworksIndexNetworkStoresController extends Controller {
13
+ /**
14
+ * Inject the `notifications` service
15
+ *
16
+ * @var {Service}
17
+ * @memberof NetworksIndexNetworkStoresController
18
+ */
9
19
  @service notifications;
20
+
21
+ /**
22
+ * Inject the `modals-manager` service
23
+ *
24
+ * @var {Service}
25
+ * @memberof NetworksIndexNetworkStoresController
26
+ */
10
27
  @service modalsManager;
28
+
29
+ /**
30
+ * Inject the `crud` service
31
+ *
32
+ * @var {Service}
33
+ * @memberof NetworksIndexNetworkStoresController
34
+ */
35
+ @service crud;
36
+
37
+ /**
38
+ * Inject the `fetch` service
39
+ *
40
+ * @var {Service}
41
+ * @memberof NetworksIndexNetworkStoresController
42
+ */
11
43
  @service fetch;
44
+
45
+ /**
46
+ * Inject the `store` service
47
+ *
48
+ * @var {Service}
49
+ * @memberof NetworksIndexNetworkStoresController
50
+ */
12
51
  @service store;
13
- @tracked network;
52
+
53
+ /**
54
+ * Inject the `hostRouter` service
55
+ *
56
+ * @var {Service}
57
+ * @memberof NetworksIndexNetworkStoresController
58
+ */
59
+ @service hostRouter;
60
+
61
+ /**
62
+ * Queryable parameters for this controller's model
63
+ *
64
+ * @var {Array}
65
+ * @memberof NetworksIndexNetworkStoresController
66
+ */
67
+ queryParams = ['category', 'status', 'storeQuery'];
68
+
69
+ /**
70
+ * The current page of data being viewed
71
+ *
72
+ * @var {Integer}
73
+ * @memberof NetworksIndexNetworkStoresController
74
+ */
75
+ @tracked page = 1;
76
+
77
+ /**
78
+ * The maximum number of items to show per page
79
+ *
80
+ * @var {Integer}
81
+ */
82
+ @tracked limit;
83
+
84
+ /**
85
+ * The search query
86
+ *
87
+ * @var {String}
88
+ * @memberof NetworksIndexNetworkStoresController
89
+ */
90
+ @tracked storeQuery;
91
+
92
+ /**
93
+ * The param to sort the data on, the param with prepended `-` is descending
94
+ *
95
+ * @var {String}
96
+ * @memberof NetworksIndexNetworkStoresController
97
+ */
98
+ @tracked sort;
99
+
100
+ /**
101
+ * The param to filter stores by category.
102
+ *
103
+ * @var {String}
104
+ * @memberof NetworksIndexNetworkStoresController
105
+ */
14
106
  @tracked category;
107
+
108
+ /**
109
+ * The current network.
110
+ *
111
+ * @var {NetworkModel}
112
+ * @memberof NetworksIndexNetworkStoresController
113
+ */
114
+ @tracked network;
115
+
116
+ /**
117
+ * The loading state.
118
+ *
119
+ * @var {Boolean}
120
+ * @memberof NetworksIndexNetworkStoresController
121
+ */
15
122
  @tracked isLoading = false;
16
- @tracked categories = [];
17
- @tracked subCategories = [];
18
- @tracked stores = [];
19
-
20
- dragulaConfig = {
21
- isContainer: (el) => el.classList.contains('dragula-container'),
22
- moves: (el) => el.classList.contains('network-store'),
23
- accepts: (el) => el.classList.contains('network-store'),
24
- revertOnSpill: true,
25
- };
26
-
27
- @action dropdownAction(dd, action, ...params) {
28
- if (dd.actions && typeof dd.actions.close === 'function') {
29
- dd.actions.close();
123
+
124
+ /**
125
+ * All columns applicable for network stores
126
+ *
127
+ * @var {Array}
128
+ */
129
+ @tracked columns = [
130
+ {
131
+ label: 'Store',
132
+ valuePath: 'name',
133
+ width: '130px',
134
+ resizable: true,
135
+ sortable: true,
136
+ filterable: true,
137
+ filterComponent: 'filter/string',
138
+ showOnlineIndicator: true,
139
+ },
140
+ {
141
+ label: 'ID',
142
+ valuePath: 'public_id',
143
+ cellComponent: 'click-to-copy',
144
+ width: '120px',
145
+ resizable: true,
146
+ sortable: true,
147
+ filterable: true,
148
+ filterComponent: 'filter/string',
149
+ },
150
+ {
151
+ label: 'Category',
152
+ valuePath: 'category.name',
153
+ cellComponent: 'table/cell/base',
154
+ width: '100px',
155
+ resizable: true,
156
+ sortable: true,
157
+ filterable: true,
158
+ filterComponent: 'filter/string',
159
+ },
160
+ {
161
+ label: 'Currency',
162
+ valuePath: 'currency',
163
+ cellComponent: 'table/cell/base',
164
+ width: '100px',
165
+ resizable: true,
166
+ sortable: true,
167
+ filterable: true,
168
+ filterComponent: 'filter/string',
169
+ },
170
+ {
171
+ label: 'Created At',
172
+ valuePath: 'createdAtShort',
173
+ sortParam: 'created_at',
174
+ width: '100px',
175
+ resizable: true,
176
+ sortable: true,
177
+ filterable: true,
178
+ filterComponent: 'filter/date',
179
+ },
180
+ {
181
+ label: '',
182
+ cellComponent: 'table/cell/dropdown',
183
+ ddButtonText: false,
184
+ ddButtonIcon: 'ellipsis-h',
185
+ ddButtonIconPrefix: 'fas',
186
+ ddMenuLabel: 'Store Actions',
187
+ cellClassNames: 'overflow-visible',
188
+ wrapperClass: 'flex items-center justify-end mx-2',
189
+ width: '50px',
190
+ actions: [
191
+ {
192
+ label: 'View Store Details',
193
+ fn: this.viewStoreDetails,
194
+ },
195
+ {
196
+ label: 'Edit Store',
197
+ fn: this.editStore,
198
+ },
199
+ {
200
+ label: 'Assign Category',
201
+ fn: this.assignStoreToCategory,
202
+ },
203
+ {
204
+ separator: true,
205
+ },
206
+ {
207
+ label: 'Remove Store from Network',
208
+ fn: this.removeStore,
209
+ },
210
+ ],
211
+ sortable: false,
212
+ filterable: false,
213
+ resizable: false,
214
+ searchable: false,
215
+ },
216
+ ];
217
+
218
+ /**
219
+ * The search task.
220
+ *
221
+ * @void
222
+ */
223
+ @task({ restartable: true }) *search({ target: { value } }) {
224
+ // if no query don't search
225
+ if (isBlank(value)) {
226
+ this.storeQuery = null;
227
+ return;
30
228
  }
31
229
 
32
- if (typeof this[action] === 'function') {
33
- this[action](...params);
230
+ // timeout for typing
231
+ yield timeout(250);
232
+
233
+ // reset page for results
234
+ if (this.page > 1) {
235
+ this.page = 1;
34
236
  }
35
- }
36
237
 
37
- @action enterCategory(category) {
38
- this.category = category;
39
- this.fetchStores(category);
40
- this.fetchSubcategories(category);
238
+ // update the query param
239
+ this.storeQuery = value;
41
240
  }
42
241
 
43
- @action leaveCategory(parentCategory) {
44
- if (parentCategory) {
45
- return this.enterCategory(parentCategory);
242
+ /**
243
+ * Selects a category and assigns its ID to the current category property.
244
+ * If the selected category is null, the category property is set to null.
245
+ *
246
+ * @action
247
+ * @param {CategoryModel|null} selectedCategory - The selected category object containing the ID.
248
+ */
249
+ @action selectCategory(selectedCategory) {
250
+ if (selectedCategory) {
251
+ this.category = selectedCategory.id;
252
+ } else {
253
+ this.category = null;
46
254
  }
47
-
48
- this.category = null;
49
- this.fetchStores();
50
255
  }
51
256
 
257
+ /**
258
+ * Deletes a specified category and moves all stores inside to the top level.
259
+ * A confirmation modal is displayed before deletion.
260
+ *
261
+ * @action
262
+ * @param {CategoryModel} category - The category object containing the ID to be deleted.
263
+ */
52
264
  @action deleteCategory(category) {
53
265
  this.modalsManager.confirm({
54
266
  title: 'Delete network category?',
@@ -65,74 +277,61 @@ export default class NetworksIndexNetworkStoresController extends Controller {
65
277
  });
66
278
  }
67
279
 
68
- @action fetchSubcategories(parentCategory) {
69
- this.store
70
- .query('category', { parent_uuid: parentCategory.id })
71
- .then((subCategories) => {
72
- this.subCategories = subCategories.toArray().map((category) => {
73
- category.parent_category = parentCategory;
280
+ /**
281
+ * Displays a modal to assign a store to a category or create a new category.
282
+ * Allows the user to select a category, create a new one, or confirm the assignment.
283
+ *
284
+ * @action
285
+ * @param {StoreModel} store - The store object to be assigned to a category.
286
+ * @param {Object} [options={}] - Additional options for the modal.
287
+ */
288
+ @action assignStoreToCategory(store, options = {}) {
289
+ this.modalsManager.show('modals/add-store-to-category', {
290
+ title: 'Add store to category',
291
+ acceptButtonText: 'Save Changes',
292
+ acceptButtonIcon: 'save',
293
+ selectedCategory: null,
294
+ network: this.network,
295
+ onSelectCategory: (category) => {
296
+ this.modalsManager.setOption('selectedCategory', category);
297
+ },
298
+ createNewCategory: (networkCategoriesPicker, parentCategory) => {
299
+ this.modalsManager.done();
74
300
 
75
- return category;
301
+ return this.createNewCategory(networkCategoriesPicker, parentCategory, {
302
+ onFinish: () => {
303
+ return this.assignStoreToCategory(store);
304
+ },
76
305
  });
77
- this.isLoading = false;
78
- })
79
- .finally(() => {
80
- this.isLoading = false;
81
- });
82
- }
83
-
84
- @action fetchStores(category) {
85
- const params = {
86
- network: this.network.id,
87
- };
88
-
89
- if (category) {
90
- params.category = category.id;
91
- } else {
92
- params.without_category = true;
93
- }
94
-
95
- this.isLoading = true;
96
-
97
- this.store
98
- .query('store', params)
99
- .then((stores) => {
100
- this.stores = stores.toArray();
101
- this.isLoading = false;
102
- })
103
- .finally(() => {
104
- this.isLoading = false;
105
- });
106
- }
306
+ },
307
+ confirm: (modal) => {
308
+ modal.startLoading();
309
+ const selectedCategory = this.modalsManager.getOption('selectedCategory');
107
310
 
108
- @action setDragulaInstance(dragula) {
109
- dragula
110
- .on('over', (el, container) => {
111
- // console.log('over()', el, container);
112
- if (container.classList.contains('network-folder')) {
113
- container.classList.add('hovering');
311
+ if (selectedCategory) {
312
+ return this.addStoreToCategory(store, selectedCategory).then(() => {
313
+ this.notifications.success(`${store.name} category was changed to ${selectedCategory.name}`);
314
+ this.hostRouter.refresh();
315
+ });
114
316
  }
115
- })
116
- .on('drop', (el, target) => {
117
- // console.log('drop()', el, target);
118
- const storeId = el?.dataset?.store;
119
- const categoryId = target?.dataset?.category;
120
-
121
- Array.from(dragula.containers).forEach((container) => {
122
- container.classList.remove('hovering');
123
- });
124
317
 
125
- if (categoryId) {
126
- const store = this.store.peekRecord('store', storeId);
127
- const category = this.store.peekRecord('category', categoryId);
128
-
129
- this.addStoreToCategory(store, category);
130
- }
131
- });
318
+ modal.done();
319
+ },
320
+ ...options,
321
+ });
132
322
  }
133
323
 
324
+ /**
325
+ * Sends a POST request to assign a store to a specified category.
326
+ * The category and store IDs are sent in the request body.
327
+ *
328
+ * @action
329
+ * @param {StoreModel} store - The store object containing the ID.
330
+ * @param {CategoryModel} category - The category object containing the ID.
331
+ * @returns {Promise} A promise that resolves when the request is complete.
332
+ */
134
333
  @action addStoreToCategory(store, category) {
135
- this.fetch.post(
334
+ return this.fetch.post(
136
335
  `networks/${this.network.id}/set-store-category`,
137
336
  {
138
337
  category: category.id,
@@ -142,58 +341,80 @@ export default class NetworksIndexNetworkStoresController extends Controller {
142
341
  );
143
342
  }
144
343
 
145
- @action createNewCategory(network) {
146
- const category = this.store.createRecord('category', {
147
- owner_uuid: network.id,
148
- owner_type: 'network:storefront',
344
+ /**
345
+ * Creates a new category with specified attributes and displays a modal for editing.
346
+ * Allows the user to confirm the creation and save the category.
347
+ *
348
+ * @action
349
+ * @param {NetworkCategoryPickerComponent} networkCategoriesPicker - Picker for network categories.
350
+ * @param {ParentCategory} parentCategory - The parent category object, if any.
351
+ * @param {Object} [options={}] - Additional options for the modal.
352
+ * @returns {Promise} A promise that resolves when the category is created.
353
+ */
354
+ @action createNewCategory(networkCategoriesPicker, parentCategory, options = {}) {
355
+ const categoryAttrs = {
356
+ owner_uuid: this.network.id,
357
+ owner_type: 'storefront:network',
149
358
  for: 'storefront_network',
150
- });
151
-
152
- return this.editCategory(category, {
153
- title: 'Add new network category',
154
- acceptButtonIcon: 'check',
155
- category,
156
- confirm: (modal) => {
157
- modal.startLoading();
359
+ };
158
360
 
159
- return category.save().then((category) => {
160
- this.notifications.success('New network category created.');
161
- this.categories.pushObject(category);
162
- });
163
- },
164
- });
165
- }
361
+ if (isModel(parentCategory)) {
362
+ categoryAttrs.parent_uuid = parentCategory.id;
363
+ categoryAttrs.owner_uuid = parentCategory.owner_uuid;
364
+ }
166
365
 
167
- @action createNewSubCategory(parentCategory) {
168
- const category = this.store.createRecord('category', {
169
- parent_uuid: parentCategory.id,
170
- owner_uuid: parentCategory.owner_uuid,
171
- owner_type: 'network:storefront',
172
- for: 'storefront_network',
173
- });
366
+ const category = this.store.createRecord('category', categoryAttrs);
174
367
 
175
368
  return this.editCategory(category, {
176
369
  title: 'Add new network category',
177
370
  acceptButtonIcon: 'check',
371
+ acceptButtonText: 'Create new category',
372
+ successMessage: 'New category created.',
373
+ parentCategory,
178
374
  category,
179
375
  confirm: (modal) => {
180
376
  modal.startLoading();
181
377
 
182
- return category.save().then((category) => {
183
- this.notifications.success('New network category created.');
184
- this.subCategories.pushObject(category);
185
- });
378
+ category
379
+ .save()
380
+ .then((category) => {
381
+ this.notifications.success('New network category created.');
382
+ networkCategoriesPicker.categories.pushObject(category);
383
+ modal.done();
384
+ })
385
+ .catch((error) => {
386
+ this.notifications.serverError(error);
387
+ });
186
388
  },
389
+ ...options,
187
390
  });
188
391
  }
189
392
 
393
+ /**
394
+ * Displays a modal to edit a specified category.
395
+ * Allows the user to set or clear the parent category, upload an icon, and confirm the changes.
396
+ *
397
+ * @action
398
+ * @param {CategoryModel} category - The category object to be edited.
399
+ * @param {Object} [options={}] - Additional options for the modal.
400
+ */
190
401
  @action editCategory(category, options = {}) {
191
402
  this.modalsManager.show('modals/create-network-category', {
192
403
  title: `Edit category (${category.name})`,
193
404
  acceptButtonText: 'Save Changes',
194
405
  acceptButtonIcon: 'save',
195
406
  iconType: category.icon_file_uuid ? 'image' : 'svg',
407
+ network: this.network,
196
408
  category,
409
+ parentCategory: null,
410
+ setParentCategory: (parentCategory) => {
411
+ this.modalsManager.setOption('parentCategory', parentCategory);
412
+
413
+ // update on category
414
+ category.setProperties({
415
+ parent_uuid: parentCategory.id,
416
+ });
417
+ },
197
418
  clearImage: () => {
198
419
  category.setProperties({
199
420
  icon_file_uuid: null,
@@ -213,7 +434,7 @@ export default class NetworksIndexNetworkStoresController extends Controller {
213
434
  (uploadedFile) => {
214
435
  category.setProperties({
215
436
  icon_file_uuid: uploadedFile.id,
216
- icon_url: uploadedFile.s3url,
437
+ icon_url: uploadedFile.url,
217
438
  icon_file: uploadedFile,
218
439
  });
219
440
  }
@@ -223,16 +444,24 @@ export default class NetworksIndexNetworkStoresController extends Controller {
223
444
  modal.startLoading();
224
445
 
225
446
  return category.save().then(() => {
226
- this.notifications.success('Network category changes saved.');
447
+ this.notifications.success(options.successMessage ?? 'Category changes saved.');
227
448
  });
228
449
  },
229
450
  ...options,
230
451
  });
231
452
  }
232
453
 
233
- @action async addStores(network) {
454
+ /**
455
+ * Displays a loader and shows a modal to add stores to the network.
456
+ * Allows the user to select stores, update the selection, and confirm the addition.
457
+ *
458
+ * @action
459
+ * @returns {Promise} A promise that resolves when the stores are added.
460
+ */
461
+ @action async addStores() {
234
462
  this.modalsManager.displayLoader();
235
463
 
464
+ const { network } = this;
236
465
  const stores = await this.store.findAll('store');
237
466
  const members = await network.loadStores();
238
467
 
@@ -255,16 +484,25 @@ export default class NetworksIndexNetworkStoresController extends Controller {
255
484
  const remove = allStores.filter((store) => !stores.includes(store)); // stores to be removed
256
485
 
257
486
  return network.addStores(stores, remove).then(() => {
258
- this.updateNetworkStores(stores, remove);
487
+ return this.hostRouter.refresh().then(() => {
488
+ this.notifications.success('Network stores updated.');
489
+ });
259
490
  });
260
491
  },
261
492
  });
262
493
  });
263
494
  }
264
495
 
265
- @action async removeStore(store, network) {
496
+ /**
497
+ * Displays a confirmation modal to remove a specified store from the network.
498
+ * Allows the user to confirm the removal.
499
+ *
500
+ * @action
501
+ * @param {StoreModel} store - The store object to be removed.
502
+ */
503
+ @action async removeStore(store) {
266
504
  this.modalsManager.confirm({
267
- title: `Remove this store (${store.name}) from this network (${network.name})?`,
505
+ title: `Remove this store (${store.name}) from this network (${this.network.name})?`,
268
506
  body: 'Are you sure you wish to remove this store from this network? It will no longer be findable by this network.',
269
507
  acceptButtonIcon: 'check',
270
508
  acceptButtonIconPrefix: 'fas',
@@ -287,34 +525,65 @@ export default class NetworksIndexNetworkStoresController extends Controller {
287
525
  });
288
526
  }
289
527
 
290
- @action updateNetworkStores(added = [], removed = []) {
291
- const updatedStores = [];
292
-
293
- for (let index = 0; index < this.stores.length; index++) {
294
- const store = this.stores.objectAt(index);
295
-
296
- if (removed.includes(store)) {
297
- continue;
298
- }
299
-
300
- updatedStores.push(store);
301
- }
302
-
303
- for (let index = 0; index < added.length; index++) {
304
- const addedStore = added.objectAt(index);
528
+ /**
529
+ * Displays a modal to view the details of a specified store.
530
+ * The modal includes the store's name and a "Done" button.
531
+ *
532
+ * @action
533
+ * @param {StoreModel} store - The store object whose details are to be viewed.
534
+ * @param {Object} [options={}] - Additional options for the modal.
535
+ */
536
+ @action viewStoreDetails(store, options = {}) {
537
+ this.modalsManager.show('modals/store-details', {
538
+ title: `Viewing ${store.name} storefront`,
539
+ acceptButtonText: 'Done',
540
+ hideDeclineButton: true,
541
+ store,
542
+ ...options,
543
+ });
544
+ }
305
545
 
306
- if (updatedStores.includes(addedStore)) {
307
- continue;
308
- }
546
+ /**
547
+ * Displays a modal to edit a specified store's details.
548
+ * Allows the user to make changes and confirm to save them.
549
+ *
550
+ * @action
551
+ * @param {StoreModel} store - The store object to be edited.
552
+ * @param {Object} [options={}] - Additional options for the modal.
553
+ */
554
+ @action editStore(store, options = {}) {
555
+ this.modalsManager.show('modals/store-form', {
556
+ title: `Editing ${store.name} storefront`,
557
+ acceptButtonText: 'Save Changes',
558
+ hideDeclineButton: true,
559
+ store,
560
+ confirm: (modal) => {
561
+ modal.startLoading();
309
562
 
310
- updatedStores.push(addedStore);
311
- }
563
+ console.log('saving store', store);
312
564
 
313
- this.stores = updatedStores.filter(Boolean).uniq();
565
+ return store
566
+ .save()
567
+ .then(() => {
568
+ this.notifications.success(`Changes to ${store.name} saved.`);
569
+ })
570
+ .catch((error) => {
571
+ console.error(error);
572
+ this.notifications.serverError(error);
573
+ });
574
+ },
575
+ ...options,
576
+ });
314
577
  }
315
578
 
316
- @action invite(network) {
317
- const shareableLink = consoleUrl(`join/network/${network.public_id}`);
579
+ /**
580
+ * Displays a modal to invite stores to the network via shareable link or email invitations.
581
+ * Allows the user to add or remove recipients, toggle the shareable link, and confirm the invitations.
582
+ *
583
+ * @action
584
+ */
585
+ @action invite() {
586
+ const shareableLink = createShareableLink(`join/network/${this.network.public_id}`);
318
587
 
319
588
  this.modalsManager.show('modals/share-network', {
320
589
  title: 'Add stores to network',
@@ -323,7 +592,7 @@ export default class NetworksIndexNetworkStoresController extends Controller {
323
592
  acceptButtonDisabled: true,
324
593
  shareableLink,
325
594
  recipients: [],
326
- network,
595
+ network: this.network,
327
596
  addRecipient: (email) => {
328
597
  const recipients = this.modalsManager.getOption('recipients');
329
598
  recipients.pushObject(email);
@@ -345,8 +614,8 @@ export default class NetworksIndexNetworkStoresController extends Controller {
345
614
  }
346
615
  },
347
616
  toggleShareableLink: (enabled) => {
348
- set(network, 'options.shareable_link_enabled', enabled);
349
- network.save();
617
+ set(this.network, 'options.shareable_link_enabled', enabled);
618
+ this.network.save();
350
619
  },
351
620
  confirm: (modal) => {
352
621
  modal.startLoading();
@@ -360,7 +629,7 @@ export default class NetworksIndexNetworkStoresController extends Controller {
360
629
  return this.notifications.error('Invalid emails provided!');
361
630
  }
362
631
 
363
- return network.sendInvites(recipients).then(() => {
632
+ return this.network.sendInvites(recipients).then(() => {
364
633
  modal.stopLoading();
365
634
  this.notifications.success('Invitations sent to recipients!');
366
635
  });