@fleetbase/storefront-engine 0.0.1

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 (296) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +32 -0
  3. package/addon/adapters/addon-category.js +1 -0
  4. package/addon/adapters/customer.js +1 -0
  5. package/addon/adapters/gateway.js +1 -0
  6. package/addon/adapters/network.js +1 -0
  7. package/addon/adapters/notification-channel.js +1 -0
  8. package/addon/adapters/product-addon-category.js +1 -0
  9. package/addon/adapters/product-addon.js +1 -0
  10. package/addon/adapters/product-hour.js +1 -0
  11. package/addon/adapters/product-store-location.js +1 -0
  12. package/addon/adapters/product-variant-option.js +1 -0
  13. package/addon/adapters/product-variant.js +1 -0
  14. package/addon/adapters/product.js +1 -0
  15. package/addon/adapters/store-hour.js +1 -0
  16. package/addon/adapters/store-location.js +1 -0
  17. package/addon/adapters/store.js +1 -0
  18. package/addon/adapters/storefront.js +5 -0
  19. package/addon/components/file-record.hbs +22 -0
  20. package/addon/components/file-record.js +43 -0
  21. package/addon/components/modals/add-store-hours.hbs +8 -0
  22. package/addon/components/modals/add-stores-to-network.hbs +5 -0
  23. package/addon/components/modals/assign-driver.hbs +25 -0
  24. package/addon/components/modals/create-first-store.hbs +21 -0
  25. package/addon/components/modals/create-gateway.hbs +35 -0
  26. package/addon/components/modals/create-network-category.hbs +50 -0
  27. package/addon/components/modals/create-network.hbs +20 -0
  28. package/addon/components/modals/create-new-variant.hbs +15 -0
  29. package/addon/components/modals/create-notification-channel.hbs +45 -0
  30. package/addon/components/modals/create-product-category.hbs +30 -0
  31. package/addon/components/modals/create-store.hbs +9 -0
  32. package/addon/components/modals/edit-network.hbs +1 -0
  33. package/addon/components/modals/import-products.hbs +97 -0
  34. package/addon/components/modals/incoming-order.hbs +242 -0
  35. package/addon/components/modals/manage-addons.hbs +50 -0
  36. package/addon/components/modals/manage-addons.js +86 -0
  37. package/addon/components/modals/order-ready-assign-driver.hbs +36 -0
  38. package/addon/components/modals/select-addon-category.hbs +5 -0
  39. package/addon/components/modals/share-network.hbs +35 -0
  40. package/addon/components/modals/store-location-form.hbs +30 -0
  41. package/addon/components/order-card.hbs +1 -0
  42. package/addon/components/order-card.js +3 -0
  43. package/addon/components/schedule-manager.hbs +22 -0
  44. package/addon/components/schedule-manager.js +73 -0
  45. package/addon/components/settings-container.hbs +7 -0
  46. package/addon/components/store-selector.hbs +21 -0
  47. package/addon/components/store-selector.js +20 -0
  48. package/addon/components/widget/customers.hbs +44 -0
  49. package/addon/components/widget/customers.js +53 -0
  50. package/addon/components/widget/orders.hbs +111 -0
  51. package/addon/components/widget/orders.js +248 -0
  52. package/addon/components/widget/storefront-metrics.hbs +54 -0
  53. package/addon/components/widget/storefront-metrics.js +61 -0
  54. package/addon/controllers/application.js +33 -0
  55. package/addon/controllers/customers/index.js +267 -0
  56. package/addon/controllers/home.js +3 -0
  57. package/addon/controllers/networks/index/network/customers.js +3 -0
  58. package/addon/controllers/networks/index/network/index.js +147 -0
  59. package/addon/controllers/networks/index/network/orders.js +3 -0
  60. package/addon/controllers/networks/index/network/stores.js +370 -0
  61. package/addon/controllers/networks/index/network.js +29 -0
  62. package/addon/controllers/networks/index.js +138 -0
  63. package/addon/controllers/orders/index.js +331 -0
  64. package/addon/controllers/products/index/category/edit.js +62 -0
  65. package/addon/controllers/products/index/category/new.js +287 -0
  66. package/addon/controllers/products/index/category.js +163 -0
  67. package/addon/controllers/products/index/index/edit.js +1 -0
  68. package/addon/controllers/products/index/index.js +136 -0
  69. package/addon/controllers/products/index.js +203 -0
  70. package/addon/controllers/settings/api.js +3 -0
  71. package/addon/controllers/settings/gateways.js +110 -0
  72. package/addon/controllers/settings/index.js +102 -0
  73. package/addon/controllers/settings/locations.js +186 -0
  74. package/addon/controllers/settings/notifications.js +102 -0
  75. package/addon/engine.js +19 -0
  76. package/addon/helpers/get-tip-amount.js +5 -0
  77. package/addon/models/addon-category.js +6 -0
  78. package/addon/models/gateway.js +46 -0
  79. package/addon/models/network.js +166 -0
  80. package/addon/models/notification-channel.js +47 -0
  81. package/addon/models/product-addon-category.js +41 -0
  82. package/addon/models/product-addon.js +41 -0
  83. package/addon/models/product-hour.js +72 -0
  84. package/addon/models/product-store-location.js +41 -0
  85. package/addon/models/product-variant-option.js +39 -0
  86. package/addon/models/product-variant.js +44 -0
  87. package/addon/models/product.js +208 -0
  88. package/addon/models/store-hour.js +72 -0
  89. package/addon/models/store-location.js +93 -0
  90. package/addon/models/store.js +100 -0
  91. package/addon/routes/application.js +47 -0
  92. package/addon/routes/customers/index/edit.js +3 -0
  93. package/addon/routes/customers/index.js +25 -0
  94. package/addon/routes/home.js +3 -0
  95. package/addon/routes/networks/index/network/customers.js +3 -0
  96. package/addon/routes/networks/index/network/index.js +15 -0
  97. package/addon/routes/networks/index/network/orders.js +3 -0
  98. package/addon/routes/networks/index/network/stores.js +28 -0
  99. package/addon/routes/networks/index/network.js +10 -0
  100. package/addon/routes/networks/index.js +19 -0
  101. package/addon/routes/orders/index/edit.js +3 -0
  102. package/addon/routes/orders/index/new.js +3 -0
  103. package/addon/routes/orders/index/view.js +3 -0
  104. package/addon/routes/orders/index.js +29 -0
  105. package/addon/routes/products/index/category/edit.js +15 -0
  106. package/addon/routes/products/index/category/new.js +7 -0
  107. package/addon/routes/products/index/category.js +54 -0
  108. package/addon/routes/products/index/index/edit.js +1 -0
  109. package/addon/routes/products/index/index.js +22 -0
  110. package/addon/routes/products/index.js +21 -0
  111. package/addon/routes/settings/api.js +10 -0
  112. package/addon/routes/settings/gateways.js +11 -0
  113. package/addon/routes/settings/index.js +16 -0
  114. package/addon/routes/settings/locations.js +14 -0
  115. package/addon/routes/settings/notifications.js +11 -0
  116. package/addon/routes.js +48 -0
  117. package/addon/serializers/addon-category.js +15 -0
  118. package/addon/serializers/network.js +19 -0
  119. package/addon/serializers/notification-channel.js +15 -0
  120. package/addon/serializers/product-addon-category.js +15 -0
  121. package/addon/serializers/product-variant.js +15 -0
  122. package/addon/serializers/product.js +20 -0
  123. package/addon/serializers/store-location.js +17 -0
  124. package/addon/serializers/store.js +19 -0
  125. package/addon/services/storefront.js +208 -0
  126. package/addon/templates/application.hbs +16 -0
  127. package/addon/templates/customers/index/edit.hbs +2 -0
  128. package/addon/templates/customers/index.hbs +22 -0
  129. package/addon/templates/home.hbs +7 -0
  130. package/addon/templates/networks/index/network/customers.hbs +2 -0
  131. package/addon/templates/networks/index/network/index.hbs +254 -0
  132. package/addon/templates/networks/index/network/orders.hbs +2 -0
  133. package/addon/templates/networks/index/network/stores.hbs +164 -0
  134. package/addon/templates/networks/index/network.hbs +38 -0
  135. package/addon/templates/networks/index.hbs +60 -0
  136. package/addon/templates/orders/index/edit.hbs +2 -0
  137. package/addon/templates/orders/index/new.hbs +2 -0
  138. package/addon/templates/orders/index/view.hbs +2 -0
  139. package/addon/templates/orders/index.hbs +22 -0
  140. package/addon/templates/products/index/category/edit.hbs +1 -0
  141. package/addon/templates/products/index/category/new.hbs +248 -0
  142. package/addon/templates/products/index/category.hbs +41 -0
  143. package/addon/templates/products/index/index/edit.hbs +1 -0
  144. package/addon/templates/products/index/index.hbs +40 -0
  145. package/addon/templates/products/index.hbs +22 -0
  146. package/addon/templates/settings/api.hbs +18 -0
  147. package/addon/templates/settings/gateways.hbs +48 -0
  148. package/addon/templates/settings/index.hbs +229 -0
  149. package/addon/templates/settings/locations.hbs +39 -0
  150. package/addon/templates/settings/notifications.hbs +35 -0
  151. package/addon/templates/settings.hbs +30 -0
  152. package/addon/utils/get-gateway-schemas.js +34 -0
  153. package/addon/utils/get-notification-schemas.js +18 -0
  154. package/app/adapters/addon-category.js +1 -0
  155. package/app/adapters/gateway.js +1 -0
  156. package/app/adapters/network.js +1 -0
  157. package/app/adapters/notification-channel.js +1 -0
  158. package/app/adapters/product-addon-category.js +1 -0
  159. package/app/adapters/product-addon.js +1 -0
  160. package/app/adapters/product-hour.js +1 -0
  161. package/app/adapters/product-store-location.js +1 -0
  162. package/app/adapters/product-variant-option.js +1 -0
  163. package/app/adapters/product-variant.js +1 -0
  164. package/app/adapters/product.js +1 -0
  165. package/app/adapters/store-hour.js +1 -0
  166. package/app/adapters/store-location.js +1 -0
  167. package/app/adapters/store.js +1 -0
  168. package/app/adapters/storefront.js +1 -0
  169. package/app/components/file-record.js +1 -0
  170. package/app/components/modals/add-store-hours.js +1 -0
  171. package/app/components/modals/add-stores-to-network.js +1 -0
  172. package/app/components/modals/assign-driver.js +1 -0
  173. package/app/components/modals/create-first-store.js +1 -0
  174. package/app/components/modals/create-gateway.js +1 -0
  175. package/app/components/modals/create-network-category.js +1 -0
  176. package/app/components/modals/create-network.js +1 -0
  177. package/app/components/modals/create-new-variant.js +1 -0
  178. package/app/components/modals/create-notification-channel.js +1 -0
  179. package/app/components/modals/create-product-category.js +1 -0
  180. package/app/components/modals/create-store.js +1 -0
  181. package/app/components/modals/edit-network.js +1 -0
  182. package/app/components/modals/import-products.js +1 -0
  183. package/app/components/modals/incoming-order.js +1 -0
  184. package/app/components/modals/manage-addons.js +1 -0
  185. package/app/components/modals/order-ready-assign-driver.js +1 -0
  186. package/app/components/modals/select-addon-category.js +1 -0
  187. package/app/components/modals/share-network.js +1 -0
  188. package/app/components/modals/store-location-form.js +1 -0
  189. package/app/components/order-card.js +1 -0
  190. package/app/components/schedule-manager.js +1 -0
  191. package/app/components/settings-container.js +1 -0
  192. package/app/components/store-selector.js +1 -0
  193. package/app/components/widget/customers.js +1 -0
  194. package/app/components/widget/orders.js +1 -0
  195. package/app/components/widget/storefront-metrics.js +1 -0
  196. package/app/controllers/application.js +1 -0
  197. package/app/controllers/customers/index.js +1 -0
  198. package/app/controllers/home.js +1 -0
  199. package/app/controllers/networks/index/network/customers.js +1 -0
  200. package/app/controllers/networks/index/network/index.js +1 -0
  201. package/app/controllers/networks/index/network/orders.js +1 -0
  202. package/app/controllers/networks/index/network/stores.js +1 -0
  203. package/app/controllers/networks/index/network.js +1 -0
  204. package/app/controllers/networks/index.js +1 -0
  205. package/app/controllers/orders/index.js +1 -0
  206. package/app/controllers/products/index/category/edit.js +1 -0
  207. package/app/controllers/products/index/category/new.js +1 -0
  208. package/app/controllers/products/index/category.js +1 -0
  209. package/app/controllers/products/index/index/edit.js +1 -0
  210. package/app/controllers/products/index/index.js +1 -0
  211. package/app/controllers/products/index.js +1 -0
  212. package/app/controllers/settings/api.js +1 -0
  213. package/app/controllers/settings/gateways.js +1 -0
  214. package/app/controllers/settings/index.js +1 -0
  215. package/app/controllers/settings/locations.js +1 -0
  216. package/app/controllers/settings/notifications.js +1 -0
  217. package/app/helpers/get-tip-amount.js +1 -0
  218. package/app/models/addon-category.js +1 -0
  219. package/app/models/gateway.js +1 -0
  220. package/app/models/network.js +1 -0
  221. package/app/models/notification-channel.js +1 -0
  222. package/app/models/product-addon-category.js +1 -0
  223. package/app/models/product-addon.js +1 -0
  224. package/app/models/product-hour.js +1 -0
  225. package/app/models/product-store-location.js +1 -0
  226. package/app/models/product-variant-option.js +1 -0
  227. package/app/models/product-variant.js +1 -0
  228. package/app/models/product.js +1 -0
  229. package/app/models/store-hour.js +1 -0
  230. package/app/models/store-location.js +1 -0
  231. package/app/models/store.js +1 -0
  232. package/app/routes/application.js +1 -0
  233. package/app/routes/customers/index/edit.js +1 -0
  234. package/app/routes/customers/index.js +1 -0
  235. package/app/routes/home.js +1 -0
  236. package/app/routes/networks/index/network/customers.js +1 -0
  237. package/app/routes/networks/index/network/index.js +1 -0
  238. package/app/routes/networks/index/network/orders.js +1 -0
  239. package/app/routes/networks/index/network/stores.js +1 -0
  240. package/app/routes/networks/index/network.js +1 -0
  241. package/app/routes/networks/index.js +1 -0
  242. package/app/routes/orders/index/edit.js +1 -0
  243. package/app/routes/orders/index/new.js +1 -0
  244. package/app/routes/orders/index/view.js +1 -0
  245. package/app/routes/orders/index.js +1 -0
  246. package/app/routes/products/index/category/edit.js +1 -0
  247. package/app/routes/products/index/category/new.js +1 -0
  248. package/app/routes/products/index/category.js +1 -0
  249. package/app/routes/products/index/index/edit.js +1 -0
  250. package/app/routes/products/index/index.js +1 -0
  251. package/app/routes/products/index.js +1 -0
  252. package/app/routes/settings/api.js +1 -0
  253. package/app/routes/settings/gateways.js +1 -0
  254. package/app/routes/settings/index.js +1 -0
  255. package/app/routes/settings/locations.js +1 -0
  256. package/app/routes/settings/notifications.js +1 -0
  257. package/app/serializers/addon-category.js +1 -0
  258. package/app/serializers/network.js +1 -0
  259. package/app/serializers/notification-channel.js +1 -0
  260. package/app/serializers/product-addon-category.js +1 -0
  261. package/app/serializers/product-variant.js +1 -0
  262. package/app/serializers/product.js +1 -0
  263. package/app/serializers/store-location.js +1 -0
  264. package/app/serializers/store.js +1 -0
  265. package/app/services/storefront.js +1 -0
  266. package/app/templates/customers/index/edit.js +1 -0
  267. package/app/templates/customers/index.js +1 -0
  268. package/app/templates/home.js +1 -0
  269. package/app/templates/networks/index/network/customers.js +1 -0
  270. package/app/templates/networks/index/network/index.js +1 -0
  271. package/app/templates/networks/index/network/orders.js +1 -0
  272. package/app/templates/networks/index/network/stores.js +1 -0
  273. package/app/templates/networks/index/network.js +1 -0
  274. package/app/templates/networks/index.js +1 -0
  275. package/app/templates/orders/index/edit.js +1 -0
  276. package/app/templates/orders/index/new.js +1 -0
  277. package/app/templates/orders/index/view.js +1 -0
  278. package/app/templates/orders/index.js +1 -0
  279. package/app/templates/products/index/category/edit.js +1 -0
  280. package/app/templates/products/index/category/new.js +1 -0
  281. package/app/templates/products/index/category.js +1 -0
  282. package/app/templates/products/index/index/edit.js +1 -0
  283. package/app/templates/products/index/index.js +1 -0
  284. package/app/templates/products/index.js +1 -0
  285. package/app/templates/settings/api.js +1 -0
  286. package/app/templates/settings/gateways.js +1 -0
  287. package/app/templates/settings/index.js +1 -0
  288. package/app/templates/settings/locations.js +1 -0
  289. package/app/templates/settings/notifications.js +1 -0
  290. package/app/templates/settings.js +1 -0
  291. package/app/utils/get-gateway-schemas.js +1 -0
  292. package/app/utils/get-notification-schemas.js +1 -0
  293. package/config/environment.js +21 -0
  294. package/index.js +22 -0
  295. package/package.json +123 -0
  296. package/pnpm-lock.yaml +12509 -0
@@ -0,0 +1,102 @@
1
+ import Controller from '@ember/controller';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { alias } from '@ember/object/computed';
5
+ import { action } from '@ember/object';
6
+ import { isArray } from '@ember/array';
7
+ import getPodMethods from '@fleetbase/console/utils/get-pod-methods';
8
+
9
+ export default class SettingsIndexController extends Controller {
10
+ @service notifications;
11
+ @service fetch;
12
+ @service storefront;
13
+
14
+ @alias('storefront.activeStore') activeStore;
15
+ @tracked podMethods = getPodMethods();
16
+ @tracked isLoading = false;
17
+ @tracked uploadQueue = [];
18
+ @tracked uploadedFiles = [];
19
+
20
+ @action addTag(tag) {
21
+ if (!isArray(this.model.tags)) {
22
+ this.model.tags = [];
23
+ }
24
+
25
+ this.model.tags?.pushObject(tag);
26
+ }
27
+
28
+ @action removeTag(index) {
29
+ this.model.tags?.removeAt(index);
30
+ }
31
+
32
+ @action saveSettings() {
33
+ this.isLoading = true;
34
+
35
+ this.model.save().then(() => {
36
+ this.notifications.success('Changes saved');
37
+ this.isLoading = false;
38
+ });
39
+ }
40
+
41
+ @action uploadFile(type, file) {
42
+ const prefix = type.replace('storefront_', '');
43
+
44
+ this.fetch.uploadFile.perform(
45
+ file,
46
+ {
47
+ path: `uploads/storefront/${this.activeStore.id}/${type}`,
48
+ key_uuid: this.activeStore.id,
49
+ key_type: `store:storefront`,
50
+ type,
51
+ },
52
+ (uploadedFile) => {
53
+ this.model.setProperties({
54
+ [`${prefix}_uuid`]: uploadedFile.id,
55
+ [`${prefix}_url`]: uploadedFile.s3url,
56
+ [prefix]: uploadedFile,
57
+ });
58
+ }
59
+ );
60
+ }
61
+
62
+ @action queueFile(file) {
63
+ this.uploadQueue.pushObject(file);
64
+ this.fetch.uploadFile.perform(
65
+ file,
66
+ {
67
+ path: `uploads/storefront/${this.activeStore.id}/media`,
68
+ key_uuid: this.activeStore.id,
69
+ key_type: `store:storefront`,
70
+ type: `storefront_store_media`,
71
+ },
72
+ (uploadedFile) => {
73
+ this.model.files.pushObject(uploadedFile);
74
+ this.uploadQueue.removeObject(file);
75
+ },
76
+ () => {
77
+ this.uploadQueue.removeObject(file);
78
+ }
79
+ );
80
+ }
81
+
82
+ @action removeFile(file) {
83
+ if (file.queue) {
84
+ file.queue.remove(file);
85
+ }
86
+
87
+ if (file.model) {
88
+ this.uploadedFiles.removeObject(file.model);
89
+ file.model.destroyRecord();
90
+ }
91
+
92
+ this.uploadQueue.removeObject(file);
93
+ }
94
+
95
+ @action makeAlertable(reason, models) {
96
+ if (!this.model.alertable || !this.model.alertable?.length) {
97
+ this.model.set('alertable', {});
98
+ }
99
+
100
+ this.model.set(`alertable.${reason}`, models);
101
+ }
102
+ }
@@ -0,0 +1,186 @@
1
+ import Controller from '@ember/controller';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { alias } from '@ember/object/computed';
5
+ import { action } from '@ember/object';
6
+ import Point from '@fleetbase/fleetops-data/utils/geojson/point';
7
+
8
+ export default class SettingsLocationsController extends Controller {
9
+ /**
10
+ * Inject the `notifications` service
11
+ *
12
+ * @var {Service}
13
+ */
14
+ @service notifications;
15
+
16
+ /**
17
+ * Inject the `modals-manager` service
18
+ *
19
+ * @var {Service}
20
+ */
21
+ @service modalsManager;
22
+
23
+ /**
24
+ * Inject the `crud` service
25
+ *
26
+ * @var {Service}
27
+ */
28
+ @service crud;
29
+
30
+ /**
31
+ * Inject the `store` service
32
+ *
33
+ * @var {Service}
34
+ */
35
+ @service store;
36
+
37
+ /**
38
+ * Inject the `hostRouter` service
39
+ *
40
+ * @var {Service}
41
+ */
42
+ @service hostRouter;
43
+
44
+ /**
45
+ * Inject the `storefront` service
46
+ *
47
+ * @var {Service}
48
+ */
49
+ @service storefront;
50
+
51
+ @alias('storefront.activeStore') activeStore;
52
+
53
+ daysOfTheWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
54
+
55
+ /**
56
+ * Create a new store location
57
+ *
58
+ * @void
59
+ */
60
+ @action createNewLocation() {
61
+ const place = this.store.createRecord('place');
62
+ const storeLocation = this.store.createRecord('store-location', {
63
+ store_uuid: this.activeStore.id,
64
+ place,
65
+ });
66
+
67
+ return this.editStoreLocation(storeLocation, {
68
+ title: 'New store location',
69
+ acceptButtonText: 'Add new Location',
70
+ acceptButtonIcon: 'save',
71
+ });
72
+ }
73
+
74
+ @action async editStoreLocation(storeLocation, options = {}) {
75
+ await storeLocation.loadPlace();
76
+
77
+ let { place } = storeLocation;
78
+
79
+ if (!place) {
80
+ place = this.store.createRecord('place', {
81
+ name: storeLocation.name,
82
+ });
83
+ }
84
+
85
+ this.modalsManager.show('modals/store-location-form', {
86
+ title: 'Edit store location',
87
+ acceptButtonText: 'Save Changes',
88
+ acceptButtonIcon: 'save',
89
+ place,
90
+ autocomplete: (selected) => {
91
+ const coordinatesInputComponent = this.modalsManager.getOption('coordinatesInputComponent');
92
+
93
+ place.setProperties({ ...selected });
94
+
95
+ if (coordinatesInputComponent) {
96
+ const [longitude, latitude] = selected.location.coordinates;
97
+ coordinatesInputComponent.updateCoordinates(latitude, longitude);
98
+ }
99
+ },
100
+ setCoordinatesInput: (coordinatesInputComponent) => {
101
+ this.modalsManager.setOption('coordinatesInputComponent', coordinatesInputComponent);
102
+ },
103
+ updatePlaceCoordinates: ({ latitude, longitude }) => {
104
+ const location = new Point(longitude, latitude);
105
+
106
+ place.setProperties({ location });
107
+ },
108
+ confirm: (modal) => {
109
+ modal.startLoading();
110
+
111
+ return place.save().then((place) => {
112
+ storeLocation.setProperties({
113
+ place_uuid: place.id,
114
+ name: place.name,
115
+ });
116
+
117
+ return storeLocation
118
+ .save()
119
+ .then((storeLocation) => {
120
+ storeLocation.setProperties({
121
+ place,
122
+ });
123
+ this.notifications.success(`${place.get('name') || place.get('street1')} store location saved.`);
124
+ return this.hostRouter.refresh();
125
+ })
126
+ .catch((error) => {
127
+ modal.stopLoading();
128
+ this.notifications.serverError(error);
129
+ });
130
+ });
131
+ },
132
+ ...options,
133
+ });
134
+ }
135
+
136
+ @action removeStoreLocation(storeLocation) {
137
+ this.modalsManager.confirm({
138
+ title: 'Are you sure you wish to remove this store location?',
139
+ body: 'All products that are solely assosciated with this location will no longer be accessible.',
140
+ confirm: (modal) => {
141
+ modal.startLoading();
142
+
143
+ return storeLocation.destroyRecord();
144
+ },
145
+ });
146
+ }
147
+
148
+ /**
149
+ * Create a new store location
150
+ *
151
+ * @void
152
+ */
153
+ @action addHours(storeLocation, day) {
154
+ const storeHours = this.store.createRecord('store-hour', {
155
+ store_location_uuid: storeLocation.id,
156
+ day_of_week: day,
157
+ });
158
+
159
+ this.modalsManager.show('modals/add-store-hours', {
160
+ title: `Add new store hours for ${day}`,
161
+ acceptButtonText: 'Add hours',
162
+ acceptButtonIcon: 'save',
163
+ storeHours,
164
+ confirm: (modal) => {
165
+ modal.startLoading();
166
+
167
+ return storeHours.save().then((storeHours) => {
168
+ storeLocation.hours.pushObject(storeHours);
169
+ this.notifications.success(`New store hours added for ${day}`);
170
+ });
171
+ },
172
+ });
173
+ }
174
+
175
+ @action removeHours(storeHours) {
176
+ this.modalsManager.confirm({
177
+ title: 'Are you sure you wish to remove these hours?',
178
+ body: 'By removing these operation hours, your store may become inactive according to the updated schedule for this location..',
179
+ confirm: (modal) => {
180
+ modal.startLoading();
181
+
182
+ return storeHours.destroyRecord();
183
+ },
184
+ });
185
+ }
186
+ }
@@ -0,0 +1,102 @@
1
+ import Controller from '@ember/controller';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { alias } from '@ember/object/computed';
5
+ import { action, set } from '@ember/object';
6
+ import { capitalize } from '@ember/string';
7
+ import getNotificationSchemas from '../../utils/get-notification-schemas';
8
+
9
+ export default class SettingsNotificationsController extends Controller {
10
+ @service notifications;
11
+ @service modalsManager;
12
+ @service store;
13
+ @service crud;
14
+ @service storefront;
15
+ @alias('storefront.activeStore') activeStore;
16
+ @tracked channels = [];
17
+
18
+ @action createChannel() {
19
+ const channel = this.store.createRecord('notification-channel', {
20
+ owner_uuid: this.activeStore.id,
21
+ owner_type: 'store:storefront',
22
+ });
23
+
24
+ this.editChannel(channel, {
25
+ title: `Create a new notification channel`,
26
+ acceptButtonText: 'Create Notification Channel',
27
+ decline: (modal) => {
28
+ channel.destroyRecord();
29
+ modal.done();
30
+ },
31
+ });
32
+ }
33
+
34
+ @action editChannel(channel, options = {}) {
35
+ const schemas = getNotificationSchemas();
36
+ const schemaOptions = [
37
+ { name: 'Apple Push Notification Service (APN)', value: 'apn' },
38
+ { name: 'Firebase Cloud Messaging (FCM)', value: 'fcm' },
39
+ ];
40
+
41
+ this.modalsManager.show('modals/create-notification-channel', {
42
+ title: `Edit notification channel`,
43
+ acceptButtonText: 'Save Changes',
44
+ schema: channel.id ? channel.config : null,
45
+ schemas,
46
+ schemaOptions,
47
+ selectSchema: (schema) => {
48
+ this.modalsManager.setOption('schema', schemas[schema]);
49
+
50
+ channel.setProperties({
51
+ name: `${capitalize(schema)} Notification Channel`,
52
+ scheme: schema,
53
+ config: schemas[schema],
54
+ });
55
+ },
56
+ setConfigKey: (key, value) => {
57
+ // eslint-disable-next-line no-undef
58
+ if (value instanceof Event) {
59
+ const eventValue = value.target.value;
60
+
61
+ set(channel.config, key, eventValue);
62
+ return;
63
+ }
64
+
65
+ set(channel.config, key, value);
66
+ },
67
+ channel,
68
+ confirm: (modal) => {
69
+ modal.startLoading();
70
+
71
+ return channel
72
+ .save()
73
+ .then((channel) => {
74
+ this.notifications.success(`New notification channel added`);
75
+ this.channels.pushObject(channel);
76
+ })
77
+ .catch((error) => {
78
+ // gateway.rollbackAttributes();
79
+ modal.stopLoading();
80
+ this.notifications.serverError(error);
81
+ });
82
+ },
83
+ ...options,
84
+ });
85
+ }
86
+
87
+ @action deleteChannel(channel) {
88
+ this.modalsManager.confirm({
89
+ title: 'Are you sure you wish to remove this notification channel?',
90
+ body: 'All applications and websites utilizing this channel in configuration could be disrupted if channel is not replaced beforehand',
91
+ confirm: (modal) => {
92
+ modal.startLoading();
93
+
94
+ return channel.destroyRecord().then(() => {
95
+ // justincase
96
+ this.channels.removeObject(channel);
97
+ modal.stopLoading();
98
+ });
99
+ },
100
+ });
101
+ }
102
+ }
@@ -0,0 +1,19 @@
1
+ import Engine from '@ember/engine';
2
+ import loadInitializers from 'ember-load-initializers';
3
+ import Resolver from 'ember-resolver';
4
+ import config from './config/environment';
5
+ import services from '@fleetbase/ember-core/exports/services';
6
+
7
+ const { modulePrefix } = config;
8
+ const externalRoutes = ['console', 'extensions'];
9
+
10
+ export default class StorefrontEngine extends Engine {
11
+ modulePrefix = modulePrefix;
12
+ Resolver = Resolver;
13
+ dependencies = {
14
+ services,
15
+ externalRoutes,
16
+ };
17
+ }
18
+
19
+ loadInitializers(StorefrontEngine, modulePrefix);
@@ -0,0 +1,5 @@
1
+ import { helper } from '@ember/component/helper';
2
+
3
+ export default helper(function getTipAmount(positional /*, named*/) {
4
+ return positional;
5
+ });
@@ -0,0 +1,6 @@
1
+ import CategoryModel from '@fleetbase/console/models/category';
2
+ import { hasMany } from '@ember-data/model';
3
+
4
+ export default class AddonCategoryModel extends CategoryModel {
5
+ @hasMany('product-addon') addons;
6
+ }
@@ -0,0 +1,46 @@
1
+ import Model, { attr } from '@ember-data/model';
2
+ import { format, formatDistanceToNow } from 'date-fns';
3
+
4
+ export default class GatewayModel extends Model {
5
+ /** @ids */
6
+ @attr('string') created_by_uuid;
7
+ @attr('string') company_uuid;
8
+ @attr('string') owner_uuid;
9
+
10
+ /** @attributes */
11
+ @attr('string', { defaultValue: 'storefront:store' }) owner_type;
12
+ @attr('string', { defaultValue: '' }) name;
13
+ @attr('string', { defaultValue: '' }) code;
14
+ @attr('string') type;
15
+ @attr('boolean') sandbox;
16
+ @attr('raw') meta;
17
+ @attr('raw') config;
18
+ @attr('string') return_url;
19
+ @attr('string') callback_url;
20
+
21
+ /** @dates */
22
+ @attr('date') created_at;
23
+ @attr('date') updated_at;
24
+
25
+ /** @methods */
26
+ toJSON() {
27
+ return this.serialize();
28
+ }
29
+
30
+ /** @computed */
31
+ get updatedAgo() {
32
+ return formatDistanceToNow(this.updated_at);
33
+ }
34
+
35
+ get updatedAt() {
36
+ return format(this.updated_at, 'PPP');
37
+ }
38
+
39
+ get createdAgo() {
40
+ return formatDistanceToNow(this.created_at);
41
+ }
42
+
43
+ get createdAt() {
44
+ return format(this.created_at, 'PPP p');
45
+ }
46
+ }
@@ -0,0 +1,166 @@
1
+ import Model, { attr, hasMany, belongsTo } from '@ember-data/model';
2
+ import { format, formatDistanceToNow } from 'date-fns';
3
+ import { getOwner } from '@ember/application';
4
+ import isEmail from '@fleetbase/console/utils/is-email';
5
+ import Store from './store';
6
+
7
+ export default class NetworkModel extends Model {
8
+ /** @ids */
9
+ @attr('string') created_by_uuid;
10
+ @attr('string') company_uuid;
11
+ @attr('string') logo_uuid;
12
+ @attr('string') backdrop_uuid;
13
+
14
+ /** @relationships */
15
+ @hasMany('store') stores;
16
+ @hasMany('notification-channel') notification_channels;
17
+ @hasMany('gateway') gateways;
18
+ @hasMany('store') stores;
19
+ @belongsTo('file') logo;
20
+ @belongsTo('file') backdrop;
21
+
22
+ /** @attributes */
23
+ @attr('string', { defaultValue: '' }) name;
24
+ @attr('string', { defaultValue: '' }) description;
25
+ @attr('string', { defaultValue: '' }) website;
26
+ @attr('string', { defaultValue: '' }) email;
27
+ @attr('string', { defaultValue: '' }) phone;
28
+ @attr('string', { defaultValue: '' }) facebook;
29
+ @attr('string', { defaultValue: '' }) instagram;
30
+ @attr('string', { defaultValue: '' }) twitter;
31
+ @attr('raw') tags;
32
+ @attr('raw') translations;
33
+ @attr('raw') alertable;
34
+ @attr('string') public_id;
35
+ @attr('string') key;
36
+ @attr('string') currency;
37
+ @attr('string') timezone;
38
+ @attr('boolean') online;
39
+ @attr('number') stores_count;
40
+ @attr('object') options;
41
+ @attr('string') logo_url;
42
+ @attr('string') backdrop_url;
43
+ @attr('string') slug;
44
+
45
+ /** @dates */
46
+ @attr('date') created_at;
47
+ @attr('date') updated_at;
48
+
49
+ /** @computed */
50
+ get updatedAgo() {
51
+ return formatDistanceToNow(this.updated_at);
52
+ }
53
+
54
+ get updatedAt() {
55
+ return format(this.updated_at, 'PPP');
56
+ }
57
+
58
+ get createdAgo() {
59
+ return formatDistanceToNow(this.created_at);
60
+ }
61
+
62
+ get createdAt() {
63
+ return format(this.created_at, 'PPP p');
64
+ }
65
+
66
+ /** @methods */
67
+ toJSON() {
68
+ return this.serialize();
69
+ }
70
+
71
+ loadNotificationChannels() {
72
+ const owner = getOwner(this);
73
+ const store = owner.lookup(`service:store`);
74
+
75
+ return new Promise((resolve, reject) => {
76
+ return store
77
+ .query('notification-channel', { owner_uuid: this.id })
78
+ .then((notificationChannels) => {
79
+ this.notification_channels = notificationChannels.toArray();
80
+
81
+ resolve(notificationChannels);
82
+ })
83
+ .catch(reject);
84
+ });
85
+ }
86
+
87
+ loadPaymentGateways() {
88
+ const owner = getOwner(this);
89
+ const store = owner.lookup(`service:store`);
90
+
91
+ return new Promise((resolve, reject) => {
92
+ return store
93
+ .query('gateway', { owner_uuid: this.id })
94
+ .then((gateways) => {
95
+ this.gateways = gateways.toArray();
96
+
97
+ resolve(gateways);
98
+ })
99
+ .catch(reject);
100
+ });
101
+ }
102
+
103
+ loadStores() {
104
+ const owner = getOwner(this);
105
+ const store = owner.lookup(`service:store`);
106
+
107
+ return new Promise((resolve, reject) => {
108
+ return store
109
+ .query('store', { network: this.id })
110
+ .then((stores) => {
111
+ this.stores = stores.toArray();
112
+
113
+ resolve(stores);
114
+ })
115
+ .catch(reject);
116
+ });
117
+ }
118
+
119
+ addStores(stores = [], remove = []) {
120
+ const owner = getOwner(this);
121
+ const fetch = owner.lookup(`service:fetch`);
122
+
123
+ stores = stores.map((store) => {
124
+ if (store instanceof Store) {
125
+ return store.id;
126
+ }
127
+
128
+ return store;
129
+ });
130
+
131
+ remove = remove.map((store) => {
132
+ if (store instanceof Store) {
133
+ return store.id;
134
+ }
135
+
136
+ return store;
137
+ });
138
+
139
+ return fetch.post(`networks/${this.id}/add-stores`, { stores, remove }, { namespace: 'storefront/int/v1' });
140
+ }
141
+
142
+ removeStores(stores = []) {
143
+ const owner = getOwner(this);
144
+ const fetch = owner.lookup(`service:fetch`);
145
+
146
+ stores = stores.map((store) => {
147
+ if (store instanceof Store) {
148
+ return store.id;
149
+ }
150
+
151
+ return store;
152
+ });
153
+
154
+ return fetch.post(`networks/${this.id}/remove-stores`, { stores }, { namespace: 'storefront/int/v1' });
155
+ }
156
+
157
+ sendInvites(recipients = []) {
158
+ const owner = getOwner(this);
159
+ const fetch = owner.lookup(`service:fetch`);
160
+
161
+ // only send to valid recipients
162
+ recipients = recipients.filter((email) => isEmail(email));
163
+
164
+ return fetch.post(`networks/${this.id}/invite`, { recipients }, { namespace: 'storefront/int/v1' });
165
+ }
166
+ }
@@ -0,0 +1,47 @@
1
+ import Model, { attr, belongsTo } from '@ember-data/model';
2
+ import { format, formatDistanceToNow } from 'date-fns';
3
+
4
+ export default class NotificationChannelModel extends Model {
5
+ /** @ids */
6
+ @attr('string') created_by_uuid;
7
+ @attr('string') company_uuid;
8
+ @attr('string') owner_uuid;
9
+ @attr('string') certificate_uuid;
10
+
11
+ /** @relationships */
12
+ @belongsTo('file') certificate;
13
+
14
+ /** @attributes */
15
+ @attr('string', { defaultValue: '' }) name;
16
+ @attr('string') scheme;
17
+ @attr('string') app_key;
18
+ @attr('string') owner_type;
19
+ @attr('object') config;
20
+ @attr('object') options;
21
+
22
+ /** @dates */
23
+ @attr('date') created_at;
24
+ @attr('date') updated_at;
25
+
26
+ /** @methods */
27
+ toJSON() {
28
+ return this.serialize();
29
+ }
30
+
31
+ /** @computed */
32
+ get updatedAgo() {
33
+ return formatDistanceToNow(this.updated_at);
34
+ }
35
+
36
+ get updatedAt() {
37
+ return format(this.updated_at, 'PPP');
38
+ }
39
+
40
+ get createdAgo() {
41
+ return formatDistanceToNow(this.created_at);
42
+ }
43
+
44
+ get createdAt() {
45
+ return format(this.created_at, 'PPP p');
46
+ }
47
+ }