Spaces:
Sleeping
Sleeping
| import { buildDeliveryTimelineModel, buildVehicleTimelineModel } from '../models.mjs'; | |
| import { buildApiGuideEndpoints } from './api-guide.mjs'; | |
| import { createSelectField, mountPanel } from './components.mjs'; | |
| export function createLayout({ app, config, statusBar, actions, onTabChange }) { | |
| const panels = {}; | |
| const header = SF.createHeader({ | |
| logo: '/sf/img/ouroboros.svg', | |
| title: config.title, | |
| subtitle: config.subtitle, | |
| tabs: [ | |
| { id: 'overview', label: 'Overview', icon: 'fa-map', active: true }, | |
| { id: 'vehicleTimeline', label: 'By Vehicle', icon: 'fa-truck' }, | |
| { id: 'deliveryTimeline', label: 'By Delivery', icon: 'fa-box' }, | |
| { id: 'data', label: 'Data', icon: 'fa-table' }, | |
| { id: 'api', label: 'REST API', icon: 'fa-book' }, | |
| ], | |
| actions, | |
| onTabChange, | |
| }); | |
| app.appendChild(header); | |
| statusBar.bindHeader(header); | |
| app.appendChild(statusBar.el); | |
| const shell = SF.el('div', { className: 'sf-content deliveries-shell' }); | |
| app.appendChild(shell); | |
| const controls = createControls(shell); | |
| const overview = createOverview(shell, panels); | |
| const timelines = createTimelines(shell, panels); | |
| const data = createDataPanel(shell, panels); | |
| createApiPanel(shell, panels); | |
| return { | |
| ...controls, | |
| ...overview, | |
| ...timelines, | |
| ...data, | |
| panels, | |
| analysisModal: SF.createModal({ title: 'Score Analysis', width: '760px' }), | |
| recommendationModal: SF.createModal({ | |
| title: 'Delivery Insertion Recommendations', | |
| width: '820px', | |
| }), | |
| }; | |
| } | |
| function createControls(shell) { | |
| const controlsCard = SF.el('section', { className: 'deliveries-card' }); | |
| const controlsRow = SF.el('div', { className: 'deliveries-controls' }); | |
| const demoField = createSelectField('Demo Data', [ | |
| { value: 'PHILADELPHIA', label: 'Philadelphia' }, | |
| { value: 'HARTFORD', label: 'Hartford' }, | |
| { value: 'FIRENZE', label: 'Firenze' }, | |
| ]); | |
| demoField.select.value = 'PHILADELPHIA'; | |
| const routingField = createSelectField('Routing Mode', [ | |
| { value: 'road_network', label: 'Road Network' }, | |
| { value: 'straight_line', label: 'Straight Line' }, | |
| ]); | |
| routingField.select.value = 'road_network'; | |
| const reloadButton = SF.createButton({ text: 'Reload Demo', icon: 'fa-rotate-right', variant: 'default' }); | |
| controlsRow.appendChild(demoField.el); | |
| controlsRow.appendChild(routingField.el); | |
| controlsRow.appendChild(reloadButton); | |
| controlsCard.appendChild(controlsRow); | |
| shell.appendChild(controlsCard); | |
| return { demoField, routingField, reloadButton }; | |
| } | |
| function createOverview(shell, panels) { | |
| const overviewPanel = mountPanel(shell, panels, 'overview'); | |
| const overviewGrid = SF.el('div', { className: 'deliveries-grid' }); | |
| overviewPanel.appendChild(overviewGrid); | |
| const leftStack = SF.el('div', { className: 'deliveries-stack' }); | |
| const summaryCard = SF.el('section', { className: 'deliveries-card' }); | |
| const summaryMetrics = SF.el('div', { className: 'deliveries-kpis' }); | |
| const routeListCard = SF.el('section', { className: 'deliveries-card' }); | |
| const routeList = SF.el('div', { className: 'deliveries-list' }); | |
| routeListCard.appendChild(SF.el('h3', null, 'Routes')); | |
| routeListCard.appendChild(routeList); | |
| leftStack.appendChild(summaryCard); | |
| leftStack.appendChild(routeListCard); | |
| overviewGrid.appendChild(leftStack); | |
| const mapCard = SF.el('section', { className: 'deliveries-card deliveries-map-card' }); | |
| mapCard.appendChild(SF.el('h3', null, 'Map')); | |
| const mapEl = SF.el('div', { className: 'deliveries-map', id: 'deliveries-map' }); | |
| mapCard.appendChild(mapEl); | |
| overviewGrid.appendChild(mapCard); | |
| return { summaryCard, summaryMetrics, routeList }; | |
| } | |
| function createTimelines(shell, panels) { | |
| const vehicleTimelinePanel = mountPanel(shell, panels, 'vehicleTimeline'); | |
| const vehicleTimelineCard = SF.el('section', { className: 'deliveries-card' }); | |
| vehicleTimelineCard.appendChild(SF.el('h3', null, 'Schedule By Vehicle')); | |
| vehicleTimelinePanel.appendChild(vehicleTimelineCard); | |
| const deliveryTimelinePanel = mountPanel(shell, panels, 'deliveryTimeline'); | |
| const deliveryTimelineCard = SF.el('section', { className: 'deliveries-card' }); | |
| deliveryTimelineCard.appendChild(SF.el('h3', null, 'Schedule By Delivery')); | |
| deliveryTimelinePanel.appendChild(deliveryTimelineCard); | |
| const vehicleTimeline = SF.rail.createTimeline({ label: 'By vehicle', labelWidth: 260, model: buildVehicleTimelineModel(null) }); | |
| const deliveryTimeline = SF.rail.createTimeline({ label: 'By delivery', labelWidth: 320, model: buildDeliveryTimelineModel(null) }); | |
| vehicleTimelineCard.appendChild(vehicleTimeline.el); | |
| deliveryTimelineCard.appendChild(deliveryTimeline.el); | |
| return { vehicleTimeline, deliveryTimeline }; | |
| } | |
| function createDataPanel(shell, panels) { | |
| const dataPanel = mountPanel(shell, panels, 'data'); | |
| const dataCard = SF.el('section', { className: 'deliveries-card' }); | |
| const dataBody = SF.el('div'); | |
| dataCard.appendChild(SF.el('h3', null, 'Draft Data')); | |
| dataCard.appendChild(dataBody); | |
| dataPanel.appendChild(dataCard); | |
| return { dataBody }; | |
| } | |
| function createApiPanel(shell, panels) { | |
| const apiPanel = mountPanel(shell, panels, 'api'); | |
| apiPanel.appendChild(SF.createApiGuide({ endpoints: buildApiGuideEndpoints() })); | |
| } | |