File size: 5,301 Bytes
f6213fc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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() }));
}