@fleetbase/fleetops-engine
Version:
Fleet & Transport Management Extension for Fleetbase
136 lines (118 loc) • 5.19 kB
JavaScript
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { isArray } from '@ember/array';
import { debug } from '@ember/debug';
import { task } from 'ember-concurrency';
import titleize from 'ember-cli-string-helpers/utils/titleize';
import smartHumanize from '@fleetbase/ember-ui/utils/smart-humanize';
import isUuid from '@fleetbase/ember-core/utils/is-uuid';
export default class OrderKanbanComponent extends Component {
fetch;
notifications;
intl;
statuses = [];
orders = this.args.orders ?? [];
orderConfig = this.args.orderConfig ?? null;
#defaultStatuses = {
start: ['created', 'dispatched', 'started'],
end: ['completed', 'canceled'],
};
get columns() {
const start = this.#defaultStatuses.start ?? [];
const end = this.#defaultStatuses.end ?? [];
const loaded = isArray(this.statuses) ? this.statuses : [];
const startSet = new Set(start);
const endSet = new Set(end);
// Middle = loaded statuses that are NOT in start/end, preserving their order & uniqueness
const seen = new Set(start); // we've already included start
const middle = [];
for (const s of loaded) {
if (!s) continue; // skip falsy
if (startSet.has(s)) continue; // skip if belongs to start block
if (endSet.has(s)) continue; // skip if belongs to end block (we’ll add end later in fixed order)
if (!seen.has(s)) {
seen.add(s);
middle.push(s);
}
}
// Build final ordered list: start → middle → end (deduped, in fixed end order)
const final = [...start, ...middle];
for (const s of end) {
if (!final.includes(s)) final.push(s);
}
return final.map((status, index) => ({
id: status,
title: titleize(smartHumanize(status)),
position: index,
cards: this.#getOrdersByStatus(status, this.orders),
}));
}
constructor() {
super(...arguments);
this.loadStatuses.perform();
}
/* eslint-disable no-unused-vars */
async handleCardMove(card, targetColumnId, targetPosition, sourceColumnId) {
// work against the array the UI renders from
const order = this.orders.find((o) => o.id === card.id);
if (!order) {
console.error('Order not found in this.orders:', card.id);
return;
}
const prevStatus = order.status;
// First check avaiilable activities, if the `targetColumnId` is one, update the order activity.
// If it's not an available status, show an error notification
try {
const nextActivities = await this.fetch.get(`orders/next-activity/${order.id}`);
if (isArray(nextActivities)) {
const activity = nextActivities.find((activity) => activity.code === targetColumnId);
if (activity) {
try {
await this.fetch.patch(`orders/update-activity/${order.id}`, { activity });
this.notifications.success(this.intl.t('order.kanban.status-updated', { status: targetColumnId }));
order.status = targetColumnId;
// replace the tracked array to notify Glimmer
// (this keeps the *same* object reference, which is fine)
this.orders = this.orders.slice();
} catch (err) {
this.notifications.serverError(err);
}
} else {
this.notifications.warning(this.intl.t('order.kanban.cannot-update-status', { status: targetColumnId }));
}
}
} catch (err) {
this.notifications.warning(this.intl.t('order.kanban.cannot-update-status', { status: targetColumnId }));
}
}
handleArgsChange(el, [orderConfig, orders = []]) {
if (isArray(orders)) {
this.orders = orders;
}
if (isUuid(orderConfig)) {
this.orderConfig = orderConfig;
} else {
this.orderConfig = null;
}
this.loadStatuses.perform();
}
#getOrdersByStatus(status, orders = []) {
let filteredOrders = orders.filter((order) => order.status === status);
if (this.orderConfig) {
filteredOrders = filteredOrders.filter((order) => order.order_config_uuid === this.orderConfig);
}
return filteredOrders;
}
*loadStatuses() {
const params = {};
if (this.orderConfig) params.order_config_uuid = this.orderConfig;
try {
const statuses = yield this.fetch.get('orders/statuses', params);
this.statuses = isArray(statuses) ? statuses : [];
} catch (err) {
debug('Unable to load order statuses: ' + err.message);
}
}
}