@fleetbase/storefront-engine 0.3.5 → 0.3.6

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 (83) hide show
  1. package/addon/components/context-panel.hbs +5 -0
  2. package/addon/components/context-panel.js +6 -0
  3. package/addon/components/customer-panel/details.hbs +34 -0
  4. package/addon/components/customer-panel/details.js +3 -0
  5. package/addon/components/customer-panel/orders.hbs +140 -0
  6. package/addon/components/customer-panel/orders.js +78 -0
  7. package/addon/components/customer-panel.hbs +70 -0
  8. package/addon/components/customer-panel.js +171 -0
  9. package/addon/components/display-place.hbs +52 -0
  10. package/addon/components/display-place.js +11 -0
  11. package/addon/components/modals/manage-addons.hbs +15 -52
  12. package/addon/components/modals/manage-addons.js +93 -43
  13. package/addon/components/modals/select-addon-category.hbs +1 -1
  14. package/addon/components/order-panel/details.hbs +245 -0
  15. package/addon/components/order-panel/details.js +189 -0
  16. package/addon/components/order-panel.hbs +1 -0
  17. package/addon/components/order-panel.js +38 -0
  18. package/addon/components/storefront-order-summary.hbs +9 -2
  19. package/addon/components/widget/customers.hbs +3 -1
  20. package/addon/components/widget/customers.js +5 -0
  21. package/addon/components/widget/orders.js +8 -146
  22. package/addon/controllers/customers/index/view.js +43 -0
  23. package/addon/controllers/customers/index.js +10 -6
  24. package/addon/controllers/networks/index/network/customers.js +68 -2
  25. package/addon/controllers/networks/index/network/orders.js +324 -1
  26. package/addon/controllers/networks/index/network/stores.js +0 -2
  27. package/addon/controllers/orders/index/view.js +13 -0
  28. package/addon/controllers/orders/index.js +10 -7
  29. package/addon/controllers/products/index/category/edit.js +12 -16
  30. package/addon/controllers/products/index/category/new.js +40 -45
  31. package/addon/controllers/products/index.js +8 -2
  32. package/addon/helpers/avatar-url.js +9 -0
  33. package/addon/models/product-variant-option.js +8 -1
  34. package/addon/models/product-variant.js +12 -2
  35. package/addon/models/product.js +62 -0
  36. package/addon/routes/customers/index/view.js +14 -0
  37. package/addon/routes/networks/index/network/customers.js +29 -0
  38. package/addon/routes/networks/index/network/orders.js +5 -0
  39. package/addon/routes/networks/index.js +1 -1
  40. package/addon/routes/orders/index/view.js +22 -1
  41. package/addon/routes/products/index/category/edit.js +6 -0
  42. package/addon/routes/products/index/category/new.js +3 -1
  43. package/addon/routes.js +1 -0
  44. package/addon/serializers/product-variant-option.js +14 -0
  45. package/addon/serializers/product-variant.js +27 -0
  46. package/addon/serializers/product.js +26 -4
  47. package/addon/services/context-panel.js +210 -0
  48. package/addon/styles/storefront-engine.css +6 -0
  49. package/addon/templates/application.hbs +3 -1
  50. package/addon/templates/customers/index/view.hbs +1 -0
  51. package/addon/templates/networks/index/network/customers.hbs +18 -1
  52. package/addon/templates/networks/index/network/orders.hbs +18 -1
  53. package/addon/templates/networks/index/network.hbs +1 -1
  54. package/addon/templates/orders/index/view.hbs +1 -1
  55. package/addon/templates/products/index/category/new.hbs +12 -67
  56. package/app/components/context-panel.js +1 -0
  57. package/app/components/customer-panel/details.js +1 -0
  58. package/app/components/customer-panel/orders.js +1 -0
  59. package/app/components/customer-panel.js +1 -0
  60. package/app/components/display-place.js +1 -0
  61. package/app/components/order-panel/details.js +1 -0
  62. package/app/components/order-panel.js +1 -0
  63. package/app/controllers/customers/index/view.js +1 -0
  64. package/app/controllers/orders/index/view.js +1 -0
  65. package/app/helpers/avatar-url.js +1 -0
  66. package/app/routes/customers/index/view.js +1 -0
  67. package/app/serializers/product-variant-option.js +1 -0
  68. package/app/services/context-panel.js +1 -0
  69. package/app/templates/customers/index/view.js +1 -0
  70. package/composer.json +3 -3
  71. package/extension.json +1 -1
  72. package/package.json +9 -3
  73. package/server/src/Http/Controllers/AddonCategoryController.php +90 -0
  74. package/server/src/Http/Controllers/v1/ReviewController.php +43 -52
  75. package/server/src/Http/Resources/Network.php +34 -32
  76. package/server/src/Http/Resources/NotificationChannel.php +32 -0
  77. package/server/src/Http/Resources/Product.php +10 -8
  78. package/server/src/Models/AddonCategory.php +37 -0
  79. package/server/src/Models/Product.php +6 -7
  80. package/server/src/Models/ProductAddon.php +3 -0
  81. package/server/src/Models/ProductAddonCategory.php +12 -2
  82. package/server/src/Providers/StorefrontServiceProvider.php +1 -1
  83. package/translations/en-us.yaml +101 -39
@@ -1,4 +1,6 @@
1
1
  import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
2
+ import ProductAddonCategoryModel from './product-addon-category';
3
+ import AddonCategoryModel from './addon-category';
2
4
  import { tracked } from '@glimmer/tracking';
3
5
  import { getOwner } from '@ember/application';
4
6
  import { setProperties } from '@ember/object';
@@ -237,4 +239,64 @@ export default class ProductModel extends Model {
237
239
  });
238
240
  });
239
241
  }
242
+
243
+ createAddonCategory(category) {
244
+ const owner = getOwner(this);
245
+ const store = owner.lookup('service:store');
246
+ if (store) {
247
+ const productAddonCategory = store.createRecord('product-addon-category', {
248
+ product_uuid: this.id,
249
+ category_uuid: category.id,
250
+ name: category.name,
251
+ excluded_addons: [],
252
+ category,
253
+ });
254
+
255
+ this.addon_categories.pushObject(productAddonCategory);
256
+ }
257
+ }
258
+
259
+ doesProductAddonCategoryExist(category) {
260
+ const productAddonCategories = this.addon_categories;
261
+ return productAddonCategories.find((_) => _.category_uuid === category.id) !== undefined;
262
+ }
263
+
264
+ isProductAddonCategory(_) {
265
+ return _ instanceof ProductAddonCategoryModel;
266
+ }
267
+
268
+ isAddonCategory(_) {
269
+ return _ instanceof AddonCategoryModel;
270
+ }
271
+
272
+ incomingCategoriesIsMissingExistingAddonCategory(incomingAddonCategories = [], existingProductAddonCategory) {
273
+ const existingProductCategoryFromIncoming = incomingAddonCategories.find((addonCategory) => {
274
+ if (this.isAddonCategory(addonCategory)) {
275
+ return addonCategory.id === existingProductAddonCategory.category_uuid;
276
+ }
277
+ return addonCategory.category_uuid === existingProductAddonCategory.category_uuid;
278
+ });
279
+ return existingProductCategoryFromIncoming === undefined;
280
+ }
281
+
282
+ syncProductAddonCategories(incomingAddonCategories = []) {
283
+ // remove old categories first
284
+ const productAddonCategories = this.addon_categories;
285
+ for (let i = 0; i < productAddonCategories.length; i++) {
286
+ const productAddonCategory = productAddonCategories[i];
287
+ if (this.incomingCategoriesIsMissingExistingAddonCategory(incomingAddonCategories, productAddonCategory)) {
288
+ this.addon_categories = productAddonCategories.filter((_) => _.id !== productAddonCategory.id);
289
+ productAddonCategory.destroyRecord();
290
+ }
291
+ }
292
+
293
+ // add incoming non existing addon categories
294
+ for (let i = 0; i < incomingAddonCategories.length; i++) {
295
+ const incomingAddonCategory = incomingAddonCategories[i];
296
+ if (this.isProductAddonCategory(incomingAddonCategory) || this.doesProductAddonCategoryExist(incomingAddonCategory)) {
297
+ continue;
298
+ }
299
+ this.createAddonCategory(incomingAddonCategory);
300
+ }
301
+ }
240
302
  }
@@ -0,0 +1,14 @@
1
+ import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
3
+
4
+ export default class CustomersIndexViewRoute extends Route {
5
+ @service store;
6
+
7
+ queryParams = {
8
+ view: { refreshModel: false },
9
+ };
10
+
11
+ model({ public_id }) {
12
+ return this.store.findRecord('contact', public_id);
13
+ }
14
+ }
@@ -1,6 +1,35 @@
1
1
  import Route from '@ember/routing/route';
2
2
  import { inject as service } from '@ember/service';
3
+ import { action, set } from '@ember/object';
4
+ import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route-transition';
3
5
 
4
6
  export default class NetworksIndexNetworkCustomersRoute extends Route {
5
7
  @service store;
8
+ @service storefront;
9
+
10
+ queryParams = {
11
+ page: { refreshModel: true, as: 'n_page' },
12
+ limit: { refreshModel: true, as: 'n_limit' },
13
+ sort: { refreshModel: true, as: 'n_sort' },
14
+ query: { refreshModel: true, as: 'n_query' },
15
+ status: { refreshModel: true, as: 'n_status' },
16
+ phone: { refreshModel: true },
17
+ email: { refreshModel: true },
18
+ address: { refreshModel: true },
19
+ public_id: { refreshModel: true },
20
+ internal_id: { refreshModel: true },
21
+ created_at: { refreshModel: true, as: 'n_created_at' },
22
+ updated_at: { refreshModel: true, as: 'n_updated_at' },
23
+ };
24
+
25
+ @action willTransition(transition) {
26
+ if (isNestedRouteTransition(transition)) {
27
+ set(this.queryParams, 'page.refreshModel', false);
28
+ set(this.queryParams, 'sort.refreshModel', false);
29
+ }
30
+ }
31
+
32
+ model(params) {
33
+ return this.store.query('customer', { ...params, storefront: this.storefront.getActiveStore('public_id') });
34
+ }
6
35
  }
@@ -3,4 +3,9 @@ import { inject as service } from '@ember/service';
3
3
 
4
4
  export default class NetworksIndexNetworkOrdersRoute extends Route {
5
5
  @service store;
6
+ @service storefront;
7
+
8
+ model(params) {
9
+ return this.store.query('order', { ...params, storefront: this.storefront.getActiveStore('public_id') });
10
+ }
6
11
  }
@@ -23,6 +23,6 @@ export default class NetworksIndexRoute extends Route {
23
23
  }
24
24
 
25
25
  model(params) {
26
- return this.store.query('network', params);
26
+ return this.store.query('network', { with_gateways: 1, with_notification_channels: 1, ...params });
27
27
  }
28
28
  }
@@ -1,3 +1,24 @@
1
1
  import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
3
+ import { action } from '@ember/object';
2
4
 
3
- export default class OrdersIndexViewRoute extends Route {}
5
+ export default class OrdersIndexViewRoute extends Route {
6
+ @service currentUser;
7
+ @service notifications;
8
+ @service store;
9
+ @service socket;
10
+
11
+ @action error(error) {
12
+ this.notifications.serverError(error);
13
+ }
14
+
15
+ model({ public_id }) {
16
+ const order = this.store.queryRecord('order', {
17
+ public_id,
18
+ single: true,
19
+ with: ['payload', 'driverAssigned', 'orderConfig', 'customer', 'facilitator', 'trackingStatuses', 'trackingNumber', 'purchaseRate', 'comments', 'files'],
20
+ });
21
+
22
+ return order;
23
+ }
24
+ }
@@ -1,5 +1,6 @@
1
1
  import Route from '@ember/routing/route';
2
2
  import { inject as service } from '@ember/service';
3
+ import { filterHasManyForNewRecords } from '../../../../serializers/product';
3
4
 
4
5
  export default class ProductsIndexCategoryEditRoute extends Route {
5
6
  @service store;
@@ -12,4 +13,9 @@ export default class ProductsIndexCategoryEditRoute extends Route {
12
13
  with: ['addonCategories', 'variants', 'files', 'hours'],
13
14
  });
14
15
  }
16
+
17
+ setupController(controller, model) {
18
+ super.setupController(...arguments);
19
+ controller.product = filterHasManyForNewRecords(model, ['variants', 'addon_categories', 'hours']);
20
+ }
15
21
  }
@@ -2,6 +2,8 @@ import Route from '@ember/routing/route';
2
2
 
3
3
  export default class ProductsIndexCategoryNewRoute extends Route {
4
4
  didTransition() {
5
- this.controller?.reset();
5
+ if (this.controller) {
6
+ this.controller.reset();
7
+ }
6
8
  }
7
9
  }
package/addon/routes.js CHANGED
@@ -16,6 +16,7 @@ export default buildRoutes(function () {
16
16
  this.route('customers', function () {
17
17
  this.route('index', { path: '/' }, function () {
18
18
  this.route('edit', { path: '/:public_id' });
19
+ this.route('view', { path: '/:public_id' });
19
20
  });
20
21
  });
21
22
  this.route('orders', function () {
@@ -0,0 +1,14 @@
1
+ import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
2
+
3
+ export default class ProductVariantOptionSerializer extends ApplicationSerializer {
4
+ serialize(snapshot) {
5
+ return {
6
+ uuid: snapshot.record.get('id'),
7
+ product_variant_uuid: snapshot.record.get('product_variant_uuid'),
8
+ name: snapshot.record.get('name'),
9
+ description: snapshot.record.get('description'),
10
+ additional_cost: snapshot.record.get('additional_cost'),
11
+ translations: snapshot.record.get('additional_cost'),
12
+ };
13
+ }
14
+ }
@@ -1,5 +1,6 @@
1
1
  import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
2
2
  import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
3
+ import { isArray } from '@ember/array';
3
4
 
4
5
  export default class ProductVariantSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
5
6
  /**
@@ -12,4 +13,30 @@ export default class ProductVariantSerializer extends ApplicationSerializer.exte
12
13
  options: { embedded: 'always' },
13
14
  };
14
15
  }
16
+
17
+ serialize(snapshot) {
18
+ const options = snapshot.record.get('options');
19
+ return {
20
+ uuid: snapshot.record.get('id'),
21
+ product_uuid: snapshot.record.get('product_uuid'),
22
+ name: snapshot.record.get('name'),
23
+ description: snapshot.record.get('description'),
24
+ is_multiselect: snapshot.record.get('is_multiselect'),
25
+ is_required: snapshot.record.get('is_required'),
26
+ translations: snapshot.record.get('translations'),
27
+ options: isArray(options) ? Array.from(options) : [],
28
+ };
29
+ }
30
+
31
+ serializeHasMany(snapshot, json, relationship) {
32
+ let key = relationship.key;
33
+
34
+ if (key === 'options') {
35
+ const options = snapshot.record.get('options');
36
+ json.options = isArray(options) ? Array.from(options) : [];
37
+ console.log('[ProductVariantSerializer #json.options]', json.options);
38
+ }
39
+
40
+ return super.serializeHasMany(...arguments);
41
+ }
15
42
  }
@@ -2,6 +2,27 @@ import ApplicationSerializer from '@fleetbase/ember-core/serializers/application
2
2
  import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
3
3
  import { isArray } from '@ember/array';
4
4
 
5
+ export function filterHasManyForNewRecords(model, relations = []) {
6
+ for (let i = 0; i < relations.length; i++) {
7
+ let relationKey = relations[i];
8
+ let data = model[relationKey];
9
+ if (isArray(data)) {
10
+ data = data.filter((_) => {
11
+ if (relationKey === 'variants') {
12
+ _ = filterHasManyForNewRecords(_, ['options']);
13
+ }
14
+ return !_.isNew;
15
+ });
16
+ } else {
17
+ data = [];
18
+ }
19
+
20
+ model.set(relationKey, data);
21
+ }
22
+
23
+ return model;
24
+ }
25
+
5
26
  export default class ProductSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
6
27
  /**
7
28
  * Embedded relationship attributes
@@ -24,11 +45,12 @@ export default class ProductSerializer extends ApplicationSerializer.extend(Embe
24
45
 
25
46
  if (key === 'addon_categories') {
26
47
  const addonCategories = snapshot.record.get('addon_categories');
48
+ json.addon_categories = isArray(addonCategories) ? Array.from(addonCategories) : [];
49
+ }
27
50
 
28
- if (isArray(addonCategories)) {
29
- json.addon_categories = addonCategories;
30
- }
31
- return;
51
+ if (key === 'variants') {
52
+ const variants = snapshot.record.get('variants');
53
+ json.variants = isArray(variants) ? Array.from(variants) : [];
32
54
  }
33
55
 
34
56
  return super.serializeHasMany(...arguments);
@@ -0,0 +1,210 @@
1
+ import Service from '@ember/service';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+ import { camelize } from '@ember/string';
5
+ import getModelName from '@fleetbase/ember-core/utils/get-model-name';
6
+ import getWithDefault from '@fleetbase/ember-core/utils/get-with-default';
7
+ import isObject from '@fleetbase/ember-core/utils/is-object';
8
+
9
+ /**
10
+ * Service for managing the state and interactions of the context panel.
11
+ *
12
+ * @class ContextPanelService
13
+ * @memberof @fleetbase/storefront
14
+ * @extends Service
15
+ */
16
+ export default class ContextPanelService extends Service {
17
+ /**
18
+ * Registry mapping model names to their corresponding component details.
19
+ * @type {Object}
20
+ */
21
+ registry = {
22
+ customer: {
23
+ viewing: {
24
+ component: 'customer-panel',
25
+ componentArguments: [{ isResizable: true }, { width: '500px' }],
26
+ },
27
+ },
28
+ order: {
29
+ viewing: {
30
+ component: 'order-panel',
31
+ componentArguments: [{ isResizable: true }, { width: '500px' }],
32
+ },
33
+ },
34
+ };
35
+
36
+ /**
37
+ * The current context or model object.
38
+ * @type {Object}
39
+ * @tracked
40
+ */
41
+ @tracked currentContext;
42
+
43
+ /**
44
+ * The current registry configuration for the current context.
45
+ * @type {Object}
46
+ * @tracked
47
+ */
48
+ @tracked currentContextRegistry;
49
+
50
+ /**
51
+ * Arguments for the current context component.
52
+ * @type {Object}
53
+ * @tracked
54
+ */
55
+ @tracked currentContextComponentArguments = {};
56
+
57
+ /**
58
+ * Additional options for controlling the context.
59
+ * @type {Object}
60
+ * @tracked
61
+ */
62
+ @tracked contextOptions = {};
63
+
64
+ /**
65
+ * Focuses on a given model and intent.
66
+ *
67
+ * @method
68
+ * @param {Object} model - The model to focus on.
69
+ * @param {String} [intent='viewing'] - The type of intent ('viewing' or 'editing').
70
+ * @action
71
+ */
72
+ @action focus(model, intent = 'viewing', options = {}) {
73
+ // handle focus which is not based on a model resource
74
+ // this is purely intent
75
+ if (typeof model === 'string') {
76
+ if (isObject(intent)) {
77
+ options = intent;
78
+ }
79
+
80
+ const registry = this.registry[model];
81
+ const dynamicArgs = getWithDefault(options, 'args', {});
82
+ if (registry) {
83
+ this.currentContext = null;
84
+ this.currentContextRegistry = registry;
85
+ this.currentContextComponentArguments = this.createDynamicArgsFromRegistry(registry, model, dynamicArgs);
86
+ this.contextOptions = options;
87
+
88
+ return this;
89
+ }
90
+
91
+ throw new Error(`Unable to focus selected context: ${model}`);
92
+ }
93
+
94
+ const modelName = getModelName(model);
95
+ const registry = this.getRegistryFromModelName(modelName);
96
+ const dynamicArgs = getWithDefault(options, 'args', {});
97
+ if (registry && registry[intent]) {
98
+ this.currentContext = model;
99
+ this.currentContextRegistry = registry[intent];
100
+ this.currentContextComponentArguments = this.createDynamicArgsFromRegistry(registry[intent], model, dynamicArgs);
101
+ this.contextOptions = options;
102
+ return this;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Get the correct registry from the modelName provided.
108
+ *
109
+ * @param {string} modelName
110
+ * @return {object}
111
+ * @memberof ContextPanelService
112
+ */
113
+ getRegistryFromModelName(modelName) {
114
+ if (typeof modelName === 'string' && modelName.includes('-')) {
115
+ modelName = camelize(modelName);
116
+ }
117
+ return this.registry[modelName];
118
+ }
119
+
120
+ /**
121
+ * Clears the current context and associated details.
122
+ *
123
+ * @method
124
+ * @action
125
+ */
126
+ @action clear() {
127
+ this.currentContext = null;
128
+ this.currentContextRegistry = null;
129
+ this.currentContextComponentArguments = {};
130
+ this.contextOptions = {};
131
+ }
132
+
133
+ /**
134
+ * Changes the intent for the current context.
135
+ *
136
+ * @method
137
+ * @param {String} intent - The new intent.
138
+ * @action
139
+ */
140
+ @action changeIntent(intent) {
141
+ if (this.currentContext) {
142
+ return this.focus(this.currentContext, intent);
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Sets an option key-value pair.
148
+ *
149
+ * @method
150
+ * @param {String} key - The option key.
151
+ * @param {*} value - The option value.
152
+ */
153
+ setOption(key, value) {
154
+ this.contextOptions = {
155
+ ...this.contextOptions,
156
+ [key]: value,
157
+ };
158
+ }
159
+
160
+ /**
161
+ * Retrieves the value of an option key.
162
+ *
163
+ * @method
164
+ * @param {String} key - The option key.
165
+ * @param {*} [defaultValue=null] - The default value to return if the key is not found.
166
+ * @returns {*}
167
+ */
168
+ getOption(key, defaultValue = null) {
169
+ const value = this.contextOptions[key];
170
+
171
+ if (value === undefined) {
172
+ return defaultValue;
173
+ }
174
+
175
+ return value;
176
+ }
177
+
178
+ /**
179
+ * Generates dynamic arguments for a given registry and model.
180
+ *
181
+ * @method
182
+ * @param {Object} registry - The registry details for a given model.
183
+ * @param {Object} model - The model object.
184
+ * @returns {Object} The dynamic arguments.
185
+ */
186
+ createDynamicArgsFromRegistry(registry, model, additionalArgs = {}) {
187
+ // Generate dynamic arguments object
188
+ const dynamicArgs = {
189
+ [camelize(getModelName(model))]: model,
190
+ };
191
+
192
+ const componentArguments = registry.componentArguments || [];
193
+
194
+ componentArguments.forEach((arg, index) => {
195
+ if (typeof arg === 'string') {
196
+ dynamicArgs[arg] = model[arg]; // Map string arguments to model properties
197
+ } else if (typeof arg === 'object' && arg !== null) {
198
+ Object.assign(dynamicArgs, arg);
199
+ } else {
200
+ // Handle other types of arguments as needed
201
+ dynamicArgs[`arg${index}`] = arg;
202
+ }
203
+ });
204
+
205
+ // Merge additional args
206
+ Object.assign(dynamicArgs, additionalArgs);
207
+
208
+ return dynamicArgs;
209
+ }
210
+ }
@@ -0,0 +1,6 @@
1
+ .ui-combo-box .options-list a.combo-box-option.selected,
2
+ .ui-combo-box .selected-list a.combo-box-option.selected,
3
+ .ui-combo-box .options-list a.combo-box-option.selected:hover,
4
+ .ui-combo-box .selected-list a.combo-box-option.selected:hover {
5
+ background-color: #76a9fa !important;
6
+ }
@@ -13,4 +13,6 @@
13
13
 
14
14
  <Layout::Section::Container>
15
15
  {{outlet}}
16
- </Layout::Section::Container>
16
+ </Layout::Section::Container>
17
+
18
+ <ContextPanel />
@@ -0,0 +1 @@
1
+ <CustomerPanel @customer={{@model}} @tab={{this.view}} @onTabChanged={{this.onTabChanged}} @onPressCancel={{this.transitionBack}} @onEdit={{this.onEdit}} />
@@ -1 +1,18 @@
1
- {{outlet}}
1
+ <Layout::Section::Header @title={{t "storefront.common.customers"}} @searchQuery={{this.query}} @onSearch={{perform this.search}} />
2
+
3
+ <Layout::Section::Body>
4
+ <Table
5
+ @wrapperClass="overscroll-y-none"
6
+ @rows={{@model}}
7
+ @columns={{this.columns}}
8
+ @selectable={{false}}
9
+ @canSelectAll={{false}}
10
+ @onSetup={{fn (mut this.table)}}
11
+ @pagination={{true}}
12
+ @paginationMeta={{@model.meta}}
13
+ @page={{this.page}}
14
+ @onPageChange={{fn (mut this.page)}}
15
+ @tfootVerticalOffset="53"
16
+ @tfootVerticalOffsetElements=".next-view-section-subheader"
17
+ />
18
+ </Layout::Section::Body>
@@ -1 +1,18 @@
1
- {{outlet}}
1
+ <Layout::Section::Header @title={{t "storefront.common.orders"}} @searchQuery={{this.query}} @onSearch={{perform this.search}} />
2
+
3
+ <Layout::Section::Body>
4
+ <Table
5
+ @wrapperClass="overscroll-y-none"
6
+ @rows={{@model}}
7
+ @columns={{this.columns}}
8
+ @selectable={{true}}
9
+ @canSelectAll={{true}}
10
+ @onSetup={{fn (mut this.table)}}
11
+ @pagination={{true}}
12
+ @paginationMeta={{@model.meta}}
13
+ @page={{this.page}}
14
+ @onPageChange={{fn (mut this.page)}}
15
+ @tfootVerticalOffset="53"
16
+ @tfootVerticalOffsetElements=".next-view-section-subheader"
17
+ />
18
+ </Layout::Section::Body>
@@ -1,4 +1,4 @@
1
- <Overlay @position="right" @isResizable={{true}} @noBackdrop={{true}} @width="570px" @minResizeWidth={{570}} @fullHeight={{true}}>
1
+ <Overlay @position="right" @isResizable={{true}} @noBackdrop={{true}} @width="900px" @minResizeWidth={{570}} @fullHeight={{true}}>
2
2
  <Overlay::Header @title={{t "storefront.networks.index.network.manage-network"}} @onPressCancel={{this.transitionBack}} />
3
3
  <Overlay::Body class="p-0i" @increaseInnerBodyHeightBy="0" @wrapperClass="space-y-4 pt-4">
4
4
  <div class="flex flex-col">
@@ -1 +1 @@
1
- {{outlet}}
1
+ <OrderPanel::Details @order={{@model}} @onPressCancel={{this.transitionBack}} />