@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,163 @@
1
+ import Controller from '@ember/controller';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { action, computed } from '@ember/object';
5
+ import { dasherize } from '@ember/string';
6
+ import { isBlank } from '@ember/utils';
7
+ import { timeout } from 'ember-concurrency';
8
+ import { task } from 'ember-concurrency-decorators';
9
+
10
+ export default class ProductsIndexCategoryController extends Controller {
11
+ @service modalsManager;
12
+ @service fetch;
13
+ @service hostRouter;
14
+ @tracked category;
15
+
16
+ /**
17
+ * The current page of data being viewed
18
+ *
19
+ * @var {Integer}
20
+ */
21
+ @tracked page = 1;
22
+
23
+ /**
24
+ * The maximum number of items to show per page
25
+ *
26
+ * @var {Integer}
27
+ */
28
+ @tracked limit;
29
+
30
+ /**
31
+ * The param to query with.
32
+ *
33
+ * @var {String}
34
+ */
35
+ @tracked query;
36
+
37
+ /**
38
+ * The param to sort the data on, the param with prepended `-` is descending
39
+ *
40
+ * @var {String}
41
+ */
42
+ @tracked sort;
43
+
44
+ /**
45
+ * The filterable param `public_id`
46
+ *
47
+ * @var {String}
48
+ */
49
+ @tracked public_id;
50
+
51
+ /**
52
+ * The filterable param `drivers_license_number`
53
+ *
54
+ * @var {String}
55
+ */
56
+ @tracked sku;
57
+
58
+ /**
59
+ * The filterable param `created_at`
60
+ *
61
+ * @var {String}
62
+ */
63
+ @tracked created_at;
64
+
65
+ /**
66
+ * The filterable param `updated_at`
67
+ *
68
+ * @var {String}
69
+ */
70
+ @tracked updated_at;
71
+
72
+ /**
73
+ * The search task.
74
+ *
75
+ * @void
76
+ */
77
+ @task({ restartable: true }) *search({ target: { value } }) {
78
+ // if no query don't search
79
+ if (isBlank(value)) {
80
+ this.query = null;
81
+ return;
82
+ }
83
+
84
+ // timeout for typing
85
+ yield timeout(250);
86
+
87
+ // reset page for results
88
+ if (this.page > 1) {
89
+ this.page = 1;
90
+ }
91
+
92
+ // update the query param
93
+ this.query = value;
94
+ }
95
+
96
+ @action deleteCategory() {
97
+ if (!this.category) {
98
+ return;
99
+ }
100
+
101
+ this.modalsManager.confirm({
102
+ title: 'Are you sure you wish to delete this category?',
103
+ body: 'Warning! Deleting this category will also remove all products listed under this category.',
104
+ confirm: (modal) => {
105
+ modal.startLoading();
106
+
107
+ return this.category.destroyRecord().then(() => {
108
+ return this.transitionToRoute('products.index');
109
+ });
110
+ },
111
+ });
112
+ }
113
+
114
+ @action editCategory(category) {
115
+ this.modalsManager.show('modals/create-product-category', {
116
+ title: `Edit category: ${category.name}`,
117
+ acceptButtonText: 'Save Changes',
118
+ acceptButtonIcon: 'save',
119
+ declineButtonIcon: 'times',
120
+ declineButtonIconPrefix: 'fas',
121
+ category,
122
+ uploadNewPhoto: (file) => {
123
+ this.fetch.uploadFile.perform(
124
+ file,
125
+ {
126
+ path: `uploads/${category.company_uuid}/product-category-icon/${dasherize(category.name ?? this.currentUser.companyId)}`,
127
+ subject_uuid: category.id,
128
+ subject_type: `category`,
129
+ type: `category_icon`,
130
+ },
131
+ (uploadedFile) => {
132
+ category.setProperties({
133
+ icon_file_uuid: uploadedFile.id,
134
+ icon_url: uploadedFile.s3url,
135
+ icon: uploadedFile,
136
+ });
137
+ }
138
+ );
139
+ },
140
+ confirm: (modal) => {
141
+ modal.startLoading();
142
+
143
+ return category.save().then((category) => {
144
+ this.notifications.success('Category changes saved.');
145
+ });
146
+ },
147
+ });
148
+ }
149
+
150
+ @action deleteProduct(product) {
151
+ this.modalsManager.confirm({
152
+ title: 'Are you sure you wish to delete this product?',
153
+ body: 'Warning! Once this product is deleted it will no longer be accessible.',
154
+ confirm: (modal) => {
155
+ modal.startLoading();
156
+
157
+ return product.destroyRecord().then(() => {
158
+ return this.hostRouter.refresh();
159
+ });
160
+ },
161
+ });
162
+ }
163
+ }
@@ -0,0 +1 @@
1
+ export { default } from '../category/edit';
@@ -0,0 +1,136 @@
1
+ import Controller from '@ember/controller';
2
+ import { inject as service } from '@ember/service';
3
+ import { tracked } from '@glimmer/tracking';
4
+ import { action } from '@ember/object';
5
+ import { equal } from '@ember/object/computed';
6
+ import { isBlank } from '@ember/utils';
7
+ import { timeout } from 'ember-concurrency';
8
+ import { task } from 'ember-concurrency-decorators';
9
+
10
+ export default class ProductsIndexIndexController extends Controller {
11
+ /**
12
+ * Inject the `filters` service
13
+ *
14
+ * @var {Service}
15
+ */
16
+ @service filters;
17
+
18
+ /**
19
+ * Inject the `currentUser` service
20
+ *
21
+ * @var {Service}
22
+ */
23
+ @service currentUser;
24
+
25
+ /**
26
+ * Inject the `currentUser` service
27
+ *
28
+ * @var {Service}
29
+ */
30
+ @service modalsManager;
31
+
32
+ /**
33
+ * Queryable parameters for this controller's model
34
+ *
35
+ * @var {Array}
36
+ */
37
+ queryParams = ['page', 'limit', 'sort', 'query', 'public_id', 'sku', 'created_at', 'updated_at'];
38
+
39
+ /**
40
+ * The current page of data being viewed
41
+ *
42
+ * @var {Integer}
43
+ */
44
+ @tracked page = 1;
45
+
46
+ /**
47
+ * The maximum number of items to show per page
48
+ *
49
+ * @var {Integer}
50
+ */
51
+ @tracked limit;
52
+
53
+ /**
54
+ * The param to query with.
55
+ *
56
+ * @var {String}
57
+ */
58
+ @tracked query;
59
+
60
+ /**
61
+ * The param to sort the data on, the param with prepended `-` is descending
62
+ *
63
+ * @var {String}
64
+ */
65
+ @tracked sort;
66
+
67
+ /**
68
+ * The filterable param `public_id`
69
+ *
70
+ * @var {String}
71
+ */
72
+ @tracked public_id;
73
+
74
+ /**
75
+ * The filterable param `drivers_license_number`
76
+ *
77
+ * @var {String}
78
+ */
79
+ @tracked sku;
80
+
81
+ /**
82
+ * The filterable param `created_at`
83
+ *
84
+ * @var {String}
85
+ */
86
+ @tracked created_at;
87
+
88
+ /**
89
+ * The filterable param `updated_at`
90
+ *
91
+ * @var {String}
92
+ */
93
+ @tracked updated_at;
94
+
95
+ /**
96
+ * The search task.
97
+ *
98
+ * @void
99
+ */
100
+ @task({ restartable: true }) *search({ target: { value } }) {
101
+ // if no query don't search
102
+ if (isBlank(value)) {
103
+ this.query = null;
104
+ return;
105
+ }
106
+
107
+ // timeout for typing
108
+ yield timeout(250);
109
+
110
+ // reset page for results
111
+ if (this.page > 1) {
112
+ this.page = 1;
113
+ }
114
+
115
+ // update the query param
116
+ this.query = value;
117
+ }
118
+
119
+ @action viewProduct(product) {
120
+ return this.transitionToRoute('products.index.category.edit', product);
121
+ }
122
+
123
+ @action deleteProduct(product) {
124
+ this.modalsManager.confirm({
125
+ title: 'Are you sure you wish to delete this product?',
126
+ body: 'Warning! Once this product is deleted it will no longer be accessible.',
127
+ confirm: (modal) => {
128
+ modal.startLoading();
129
+
130
+ return product.destroyRecord().then(() => {
131
+ return this.hostRouter.refresh();
132
+ });
133
+ },
134
+ });
135
+ }
136
+ }
@@ -0,0 +1,203 @@
1
+ import Controller from '@ember/controller';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { action } from '@ember/object';
5
+ import { alias } from '@ember/object/computed';
6
+ import { dasherize } from '@ember/string';
7
+ import { timeout } from 'ember-concurrency';
8
+ import { task } from 'ember-concurrency-decorators';
9
+
10
+ export default class ProductsIndexController extends Controller {
11
+ @service store;
12
+ @service modalsManager;
13
+ @service currentUser;
14
+ @service modalsManager;
15
+ @service notifications;
16
+ @service fetch;
17
+ @service hostRouter;
18
+ @service storefront;
19
+
20
+ /**
21
+ * the current storefront store session.
22
+ *
23
+ * @memberof ProductsIndexController
24
+ */
25
+ @alias('storefront.activeStore') activeStore;
26
+
27
+ /**
28
+ * The current category.
29
+ *
30
+ * @var {CategoryModel}
31
+ */
32
+ @tracked category;
33
+
34
+ @action createNewProduct() {
35
+ return this.transitionToRoute('products.index.category.new');
36
+ }
37
+
38
+ @action manageAddons() {
39
+ this.modalsManager.show('modals/manage-addons', {
40
+ title: 'Manage Addons',
41
+ modalClass: 'modal-lg',
42
+ acceptButtonText: 'Done',
43
+ store: this.activeStore,
44
+ });
45
+ }
46
+
47
+ @action viewAllProducts() {
48
+ this.category = null;
49
+ this.transitionToRoute('products.index');
50
+ }
51
+
52
+ @action switchCategory(category) {
53
+ this.category = category;
54
+ this.transitionToRoute('products.index.category', category.slug);
55
+ }
56
+
57
+ @action createNewProductCategory() {
58
+ const category = this.store.createRecord('category', {
59
+ company_uuid: this.currentUser.companyId,
60
+ owner_uuid: this.currentUser.getOption('activeStorefront'),
61
+ owner_type: 'storefront:store',
62
+ for: 'storefront_product'
63
+ });
64
+
65
+ this.modalsManager.show('modals/create-product-category', {
66
+ title: 'Create a new product category',
67
+ acceptButtonIcon: 'check',
68
+ acceptButtonIconPrefix: 'fas',
69
+ declineButtonIcon: 'times',
70
+ declineButtonIconPrefix: 'fas',
71
+ category,
72
+ uploadNewPhoto: (file) => {
73
+ this.fetch.uploadFile.perform(
74
+ file,
75
+ {
76
+ path: `uploads/${category.company_uuid}/product-category-icon/${dasherize(category.name ?? this.currentUser.companyId)}`,
77
+ subject_uuid: category.id,
78
+ subject_type: `category`,
79
+ type: `category_icon`,
80
+ },
81
+ (uploadedFile) => {
82
+ category.setProperties({
83
+ icon_file_uuid: uploadedFile.id,
84
+ icon_url: uploadedFile.url,
85
+ icon: uploadedFile,
86
+ });
87
+ }
88
+ );
89
+ },
90
+ confirm: (modal) => {
91
+ modal.startLoading();
92
+
93
+ return category.save().then((category) => {
94
+ this.notifications.success('New product category created.');
95
+ return this.hostRouter.refresh();
96
+ });
97
+ },
98
+ });
99
+ }
100
+
101
+ @action importProducts() {
102
+ const checkQueue = () => {
103
+ const uploadQueue = this.modalsManager.getOption('uploadQueue');
104
+
105
+ if (uploadQueue.length) {
106
+ this.modalsManager.setOption('acceptButtonDisabled', false);
107
+ } else {
108
+ this.modalsManager.setOption('acceptButtonDisabled', true);
109
+ }
110
+ };
111
+
112
+ this.modalsManager.show('modals/import-products', {
113
+ title: 'Import products via spreadsheets',
114
+ acceptButtonText: 'Start Upload',
115
+ acceptButtonScheme: 'magic',
116
+ acceptButtonIcon: 'upload',
117
+ acceptButtonDisabled: true,
118
+ isProcessing: false,
119
+ uploadQueue: [],
120
+ selectedCategory: null,
121
+ store: this.activeStore,
122
+ fileQueueColumns: [
123
+ { name: 'Type', valuePath: 'extension', key: 'type' },
124
+ { name: 'File Name', valuePath: 'name', key: 'fileName' },
125
+ { name: 'File Size', valuePath: 'size', key: 'fileSize' },
126
+ { name: 'Upload Date', valuePath: 'blob.lastModifiedDate', key: 'uploadDate' },
127
+ { name: '', valuePath: '', key: 'delete' },
128
+ ],
129
+ acceptedFileTypes: ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/csv'],
130
+ queueFile: (file) => {
131
+ const uploadQueue = this.modalsManager.getOption('uploadQueue');
132
+
133
+ uploadQueue.pushObject(file);
134
+ checkQueue();
135
+ },
136
+ removeFile: (file) => {
137
+ const { queue } = file;
138
+ const uploadQueue = this.modalsManager.getOption('uploadQueue');
139
+
140
+ uploadQueue.removeObject(file);
141
+ queue.remove(file);
142
+ checkQueue();
143
+ },
144
+ confirm: async (modal) => {
145
+ const selectedCategory = this.modalsManager.getOption('selectedCategory');
146
+ const uploadQueue = this.modalsManager.getOption('uploadQueue');
147
+ const uploadedFiles = [];
148
+ const uploadTask = (file) => {
149
+ return new Promise((resolve) => {
150
+ this.fetch.uploadFile.perform(
151
+ file,
152
+ {
153
+ path: `uploads/storefront-product-imports/${this.currentUser.companyId}`,
154
+ type: `storefront_order_import`,
155
+ },
156
+ (uploadedFile) => {
157
+ uploadedFiles.pushObject(uploadedFile);
158
+
159
+ resolve(uploadedFile);
160
+ }
161
+ );
162
+ });
163
+ };
164
+
165
+ if (!uploadQueue.length) {
166
+ return this.notifications.warning('No files in queue to upload!');
167
+ }
168
+
169
+ modal.startLoading();
170
+ modal.setOption('acceptButtonText', 'Uploading...');
171
+
172
+ for (let i = 0; i < uploadQueue.length; i++) {
173
+ const file = uploadQueue.objectAt(i);
174
+
175
+ await uploadTask(file);
176
+ }
177
+
178
+ this.modalsManager.setOption('acceptButtonText', 'Processing...');
179
+ this.modalsManager.setOption('isProcessing', true);
180
+
181
+ const files = uploadedFiles.map((file) => file.id);
182
+ const results = await this.fetch
183
+ .post('products/process-imports', { files, category: selectedCategory?.id, store: this.activeStore.id }, { namespace: 'storefront/int/v1' })
184
+ .catch((error) => {
185
+ this.notifications.serverError(error);
186
+ });
187
+
188
+ modal.done().then(() => {
189
+ if (results?.length) {
190
+ this.notifications.success(`Successfully imported ${results.length} products...`);
191
+ return this.hostRouter.refresh();
192
+ }
193
+ });
194
+ },
195
+ decline: (modal) => {
196
+ this.modalsManager.setOption('uploadQueue', []);
197
+ this.fileQueue?.flush();
198
+
199
+ modal.done();
200
+ },
201
+ });
202
+ }
203
+ }
@@ -0,0 +1,3 @@
1
+ import Controller from '@ember/controller';
2
+
3
+ export default class SettingsApiController extends Controller {}
@@ -0,0 +1,110 @@
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 getGatewaySchemas from '../../utils/get-gateway-schemas';
8
+
9
+ export default class SettingsGatewaysController extends Controller {
10
+ @service notifications;
11
+ @service modalsManager;
12
+ @service store;
13
+ @service crud;
14
+ @service storefront;
15
+ @alias('storefront.activeStore') activeStore;
16
+
17
+ @action createGateway() {
18
+ const gateway = this.store.createRecord('gateway', {
19
+ owner_uuid: this.activeStore.id,
20
+ owner_type: 'storefront:store',
21
+ });
22
+
23
+ this.editGateway(gateway, {
24
+ title: `Create a new payment gateway`,
25
+ acceptButtonText: 'Save Gateway',
26
+ decline: (modal) => {
27
+ gateway.destroyRecord();
28
+ modal.done();
29
+ },
30
+ successNotification: (gateway) => `New gateway (${gateway.name}) created.`,
31
+ onConfirm: () => {
32
+ if (gateway.get('isNew')) {
33
+ return;
34
+ }
35
+
36
+ this.gateways.pushObject(gateway);
37
+ },
38
+ });
39
+ }
40
+
41
+ @action editGateway(gateway, options = {}) {
42
+ const schemas = getGatewaySchemas();
43
+ const schemaOptions = Object.keys(schemas);
44
+
45
+ this.modalsManager.show('modals/create-gateway', {
46
+ title: `Edit payment gateway`,
47
+ acceptButtonText: 'Save Changes',
48
+ schema: null,
49
+ schemas,
50
+ schemaOptions,
51
+ gateway,
52
+ selectSchema: (schema) => {
53
+ this.modalsManager.setOption('schema', schemas[schema]);
54
+
55
+ gateway.setProperties({
56
+ name: `${capitalize(schema)} Gateway`,
57
+ code: schema,
58
+ config: schemas[schema],
59
+ type: schema,
60
+ });
61
+ },
62
+ setConfigKey: (key, value) => {
63
+ // eslint-disable-next-line no-undef
64
+ if (value instanceof Event) {
65
+ const eventValue = value.target.value;
66
+
67
+ set(gateway.config, key, eventValue);
68
+ return;
69
+ }
70
+
71
+ set(gateway.config, key, value);
72
+ },
73
+ confirm: (modal, done) => {
74
+ modal.startLoading();
75
+
76
+ gateway
77
+ .save()
78
+ .then((gateway) => {
79
+ if (typeof options.successNotification === 'function') {
80
+ this.notifications.success(options.successNotification(gateway));
81
+ } else {
82
+ this.notifications.success(options.successNotification || `${gateway.name} details updated.`);
83
+ }
84
+
85
+ done();
86
+ })
87
+ .catch((error) => {
88
+ // gateway.rollbackAttributes();
89
+ modal.stopLoading();
90
+ this.notifications.serverError(error);
91
+ });
92
+ },
93
+ ...options,
94
+ });
95
+ }
96
+
97
+ @action deleteGateway(gateway) {
98
+ this.modalsManager.confirm({
99
+ title: 'Are you sure you wish to remove this gateway?',
100
+ body: 'All applications and websites utilizing this gateway in configuration could be disrupted if gateway is not replaced beforehand',
101
+ confirm: (modal) => {
102
+ modal.startLoading();
103
+
104
+ return gateway.destroyRecord().then(() => {
105
+ modal.stopLoading();
106
+ });
107
+ },
108
+ });
109
+ }
110
+ }