@fleetbase/fleetops-engine 0.1.9 → 0.2.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.
@@ -0,0 +1,19 @@
1
+ <div class="order-board-container">
2
+ <div class="flex flex-row items-center justify-between px-6 py-3">
3
+ <div></div>
4
+ <div>
5
+ <DropdownButton @icon="layer-group" @text={{concat "Order Type: " this.type.name}} @type="magic" @size="sm" @contentClass="dropdown-menu" @disabled={{not this.orderTypes}} as |dd|>
6
+ <div class="next-dd-menu mt-2 mx-0">
7
+ {{#each this.orderTypes as |type|}}
8
+ <div class="px-1">
9
+ <a href="#" class=" next-dd-item" {{on "click" (dropdown-fn dd this.selectOrderType type)}}>
10
+ {{type.name}}
11
+ </a>
12
+ </div>
13
+ {{/each}}
14
+ </div>
15
+ </DropdownButton>
16
+ </div>
17
+ </div>
18
+ <Kanban @columns={{this.columns}} />
19
+ </div>
@@ -0,0 +1,81 @@
1
+ import Component from '@glimmer/component';
2
+ import { inject as service } from '@ember/service';
3
+ import { tracked } from '@glimmer/tracking';
4
+ import { action } from '@ember/object';
5
+
6
+ export default class OrderBoardComponent extends Component {
7
+ /**
8
+ * Inject the `fetch` service
9
+ *
10
+ * @var {Service}
11
+ */
12
+ @service fetch;
13
+
14
+ @tracked type;
15
+ @tracked orderTypes = [];
16
+ @tracked columns = [];
17
+
18
+ constructor() {
19
+ super(...arguments);
20
+ this.loadOrderTypes();
21
+ }
22
+
23
+ /**
24
+ * Fetches the available order types from the server and updates the
25
+ * `orderTypes` property with the retrieved data. If the `type` query
26
+ * parameter is set (bound to `this.type`), it also finds and sets the
27
+ * corresponding selected order type in `selectedOrderType`.
28
+ *
29
+ * @action
30
+ * @returns {Promise} A promise that resolves when the order types have been loaded
31
+ */
32
+ @action loadOrderTypes() {
33
+ return this.fetch.get('orders/types').then((types) => {
34
+ this.orderTypes = types;
35
+
36
+ if (typeof this.args.onTypesLoaded === 'function') {
37
+ this.args.onTypesLoaded(types);
38
+ }
39
+
40
+ if (typeof this.args.type === 'string') {
41
+ const selectedType = types.find(({ key }) => key === this.args.type);
42
+
43
+ if (selectedType) {
44
+ this.selectOrderType(selectedType);
45
+ }
46
+ }
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Selectes the order type.
52
+ *
53
+ * @action
54
+ * @param {Object} type
55
+ * @memberof OrderBoardComponent
56
+ */
57
+ @action selectOrderType(type) {
58
+ this.type = type;
59
+ this.setColumnsFromOrderType(type);
60
+
61
+ if (typeof this.args.onOrderTypeChanged === 'function') {
62
+ this.args.onOrderTypeChanged(type);
63
+ }
64
+ }
65
+
66
+ @action setColumnsFromOrderType(type) {
67
+ const columns = [];
68
+
69
+ for (let event in type.meta.flow) {
70
+ if (!event.includes('|')) {
71
+ columns.push(event);
72
+ }
73
+ }
74
+
75
+ columns.push('canceled');
76
+ columns.push('completed');
77
+
78
+ this.columns = columns;
79
+ return this.columns;
80
+ }
81
+ }
@@ -102,6 +102,8 @@ export default class OperationsOrdersIndexController extends Controller {
102
102
  'created_by',
103
103
  'updated_by',
104
104
  'status',
105
+ 'type',
106
+ 'layout',
105
107
  ];
106
108
 
107
109
  /**
@@ -209,13 +211,74 @@ export default class OperationsOrdersIndexController extends Controller {
209
211
  */
210
212
  @tracked status;
211
213
 
214
+ /**
215
+ * The filterable param `type` - Filter by order type
216
+ *
217
+ * @var {String}
218
+ */
219
+ @tracked type;
220
+
221
+ /**
222
+ * Flag to determine if the search is visible
223
+ *
224
+ * @type {Boolean}
225
+ */
212
226
  @tracked isSearchVisible = false;
227
+
228
+ /**
229
+ * Flag to determine if the orders panel is visible
230
+ *
231
+ * @type {Boolean}
232
+ */
213
233
  @tracked isOrdersPanelVisible = false;
234
+
235
+ /**
236
+ * Count of active orders
237
+ *
238
+ * @type {Number}
239
+ */
214
240
  @tracked activeOrdersCount = 0;
241
+
242
+ /**
243
+ * Reference to the leaflet map object
244
+ *
245
+ * @type {Object}
246
+ */
215
247
  @tracked leafletMap;
248
+
249
+ /**
250
+ * Current layout type (e.g., 'map', 'table', 'kanban', 'analytics')
251
+ *
252
+ * @type {String}
253
+ */
216
254
  @tracked layout = 'map';
255
+
256
+ /**
257
+ * Flag to determine if the layout is 'map'
258
+ *
259
+ * @type {Boolean}
260
+ */
217
261
  @equal('layout', 'map') isMapLayout;
262
+
263
+ /**
264
+ * Flag to determine if the layout is 'table'
265
+ *
266
+ * @type {Boolean}
267
+ */
218
268
  @equal('layout', 'table') isTableLayout;
269
+
270
+ /**
271
+ * Flag to determine if the view is 'kanban'
272
+ *
273
+ * @type {Boolean}
274
+ */
275
+ @equal('layout', 'kanban') isKanbanView;
276
+
277
+ /**
278
+ * Flag to determine if the layout is 'analytics'
279
+ *
280
+ * @type {Boolean}
281
+ */
219
282
  @equal('layout', 'analytics') isAnalyticsLayout;
220
283
 
221
284
  /**
@@ -293,8 +356,10 @@ export default class OperationsOrdersIndexController extends Controller {
293
356
  sortable: true,
294
357
  filterable: true,
295
358
  filterComponent: 'filter/model',
359
+ filterOptionLabel: 'address',
296
360
  filterComponentPlaceholder: 'Select order pickup location',
297
361
  filterParam: 'pickup',
362
+ modelNamePath: 'address',
298
363
  model: 'place',
299
364
  },
300
365
  {
@@ -308,6 +373,7 @@ export default class OperationsOrdersIndexController extends Controller {
308
373
  filterComponent: 'filter/model',
309
374
  filterComponentPlaceholder: 'Select order dropoff location',
310
375
  filterParam: 'dropoff',
376
+ modelNamePath: 'address',
311
377
  model: 'place',
312
378
  },
313
379
  {
@@ -369,6 +435,12 @@ export default class OperationsOrdersIndexController extends Controller {
369
435
  resizable: true,
370
436
  hidden: true,
371
437
  sortable: true,
438
+ filterable: true,
439
+ filterComponent: 'filter/select',
440
+ filterOptions: this.orderTypes,
441
+ filterOptionLabel: 'name',
442
+ filterOptionValue: 'key',
443
+ filterComponentPlaceholder: 'Filter by order type',
372
444
  },
373
445
  {
374
446
  label: 'Status',
package/addon/engine.js CHANGED
@@ -16,7 +16,7 @@ export default class FleetOpsEngine extends Engine {
16
16
  };
17
17
  setupExtension = function (app, engine, universe) {
18
18
  // register menu item in header
19
- universe.registerHeaderMenuItem('Fleet Ops', 'console.fleet-ops', { icon: 'route', priority: 0 });
19
+ universe.registerHeaderMenuItem('Fleet-Ops', 'console.fleet-ops', { icon: 'route', priority: 0 });
20
20
  };
21
21
  }
22
22
 
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
3
3
 
4
4
  export default class ManagementDriversIndexRoute extends Route {
5
5
  @service store;
6
+ @service intl;
6
7
 
7
8
  queryParams = {
8
9
  page: { refreshModel: true },
@@ -27,6 +28,10 @@ export default class ManagementDriversIndexRoute extends Route {
27
28
  'within[where]': { refreshModel: true, replace: true },
28
29
  };
29
30
 
31
+ beforeModel() {
32
+ this.intl.setLocale(['en-us']);
33
+ }
34
+
30
35
  model(params) {
31
36
  return this.store.query('driver', { ...params });
32
37
  }
@@ -23,6 +23,8 @@ export default class OperationsOrdersIndexRoute extends Route {
23
23
  dropoff: { refreshModel: true },
24
24
  after: { refreshModel: true },
25
25
  before: { refreshModel: true },
26
+ type: { refreshModel: true },
27
+ layout: { refreshModel: false },
26
28
  };
27
29
 
28
30
  @action willTransition(transition) {
@@ -1,4 +1,4 @@
1
- <Layout::Section::Header @title="Drivers" @searchQuery={{this.query}} @onSearch={{perform this.search}}>
1
+ <Layout::Section::Header @title={{t "fleet-ops.management.drivers.index.title"}} @searchPlaceholder={{t "fleet-ops.management.drivers.index.fields.search.placeholder"}} @searchQuery={{this.query}} @onSearch={{perform this.search}}>
2
2
  <Button @icon="grip-horizontal" @prefix="fas" @onClick={{fn this.changeLayout "grid"}} @disabled={{this.isGridLayout}} class="mr-2" />
3
3
  <Button @icon="table" @prefix="fas" @onClick={{fn this.changeLayout "table"}} @disabled={{this.isTableLayout}} class="mr-2" />
4
4
  <FiltersPicker @columns={{this.columns}} @onApply={{fn this.filters.apply this}} @onClear={{fn this.filters.reset this}} @onFilterClear={{this.filters.clear}} @onChange={{this.filters.set}} @buttonWrapperClass="mr-2" />
@@ -4,8 +4,9 @@
4
4
  <button type="button" class="{{if this.isMapLayout 'active'}}" {{on "click" (fn this.setLayoutMode "map")}}>Map</button>
5
5
  <button type="button" class="{{if this.isTableLayout 'active'}} flex flex-row items-center relative" {{on "click" (fn this.setLayoutMode "table")}}>
6
6
  <div class="mr-1.5">Table</div>
7
- <Badge class="flex items-center justify-center -mr-4" @spanClass="rounded-full px-1 py-0i" @hideStatusDot={{true}} @status="info">{{@model.meta.total}}</Badge>
7
+ <Badge class="flex items-center justify-center -mr-4" @spanClass="rounded-full items-center justify-center h-4 w-4" @hideStatusDot={{true}} @status="info">{{@model.meta.total}}</Badge>
8
8
  </button>
9
+ {{!-- <button type="button" class="{{if this.isKanbanView 'active'}}" {{on "click" (fn this.setLayoutMode "kanban")}}>Board</button> --}}
9
10
  </MapContainer::ViewSwitch>
10
11
  </MapContainer::Topbar>
11
12
 
@@ -45,4 +46,16 @@
45
46
  </Layout::Section::Body>
46
47
  {{/if}}
47
48
 
49
+ {{#if this.isKanbanView}}
50
+ <Layout::Section::Header @title="Orders" @onSearch={{perform this.search}}>
51
+ <Button @icon="cogs" @text="Config" class="mr-2" @onClick={{fn (transition-to "operations.orders.index.config")}} />
52
+ <FiltersPicker @columns={{this.columns}} @onApply={{fn this.filters.apply this}} @onClear={{fn this.filters.reset this}} @onFilterClear={{this.filters.clear}} @onChange={{this.filters.set}} @buttonWrapperClass="mr-2" />
53
+ <Button @type="primary" @icon="plus" @iconPrefix="fas" @text="New" @wrapperClass="mr-2" @onClick={{fn (transition-to "operations.orders.index.new")}} />
54
+ <Button @icon="long-arrow-up" @iconClass="rotate-icon-45" @text="Export" @onClick={{this.exportOrders}} />
55
+ </Layout::Section::Header>
56
+ <Layout::Section::Body>
57
+ <OrderBoard @type={{this.type}} />
58
+ </Layout::Section::Body>
59
+ {{/if}}
60
+
48
61
  {{outlet}}
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/order-board';
package/index.js CHANGED
@@ -9,6 +9,16 @@ const path = require('path');
9
9
  module.exports = buildEngine({
10
10
  name,
11
11
 
12
+ postprocessTree(type, tree) {
13
+ if (type === 'css') {
14
+ tree = new Funnel(tree, {
15
+ exclude: ['**/@fleetbase/ember-ui/**/*.css'],
16
+ });
17
+ }
18
+
19
+ return tree;
20
+ },
21
+
12
22
  lazyLoading: {
13
23
  enabled: true,
14
24
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/fleetops-engine",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "description": "Fleetbase Fleet-Ops extension provides a fleet management and last mile delivery operations system module.",
5
5
  "fleetbase": {
6
6
  "route": "fleet-ops",
@@ -34,11 +34,13 @@
34
34
  "start": "ember serve",
35
35
  "test": "npm-run-all lint test:*",
36
36
  "test:ember": "ember test",
37
- "test:ember-compatibility": "ember try:each"
37
+ "test:ember-compatibility": "ember try:each",
38
+ "publish:npm": "npm config set registry https://registry.npmjs.org/ && npm publish",
39
+ "publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
38
40
  },
39
41
  "dependencies": {
40
- "@fleetbase/ember-core": "^0.1.0",
41
- "@fleetbase/ember-ui": "^0.1.3",
42
+ "@fleetbase/ember-core": "^0.1.1",
43
+ "@fleetbase/ember-ui": "^0.1.7",
42
44
  "@fleetbase/fleetops-data": "^0.0.6",
43
45
  "@fleetbase/leaflet-routing-machine": "^3.2.16",
44
46
  "@fortawesome/ember-fontawesome": "^0.4.1",
@@ -48,6 +50,7 @@
48
50
  "@zestia/ember-dragula": "^12.0.0",
49
51
  "broccoli-funnel": "^3.0.8",
50
52
  "broccoli-merge-trees": "^4.2.0",
53
+ "ember-intl": "^6.0.0-beta.6",
51
54
  "ember-cli-babel": "^7.26.11",
52
55
  "ember-cli-es6-transform": "^1.0.0",
53
56
  "ember-cli-htmlbars": "^6.1.0",
@@ -0,0 +1,9 @@
1
+ fleet-ops:
2
+ extension-name: Fleet-Ops
3
+ management:
4
+ drivers:
5
+ index:
6
+ title: Drivers
7
+ fields:
8
+ search:
9
+ placeholder: Search Drivers