File size: 3,670 Bytes
ae32abe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/* app-layout.js - application shell construction for the Bergamo FSR demo */

(function () {
  'use strict';

  var FSR = window.FSR = window.FSR || {};

  FSR.createAppLayout = function (options) {
    var SF = options.SF;
    var app = options.app;
    var panels = {
      map: SF.el('div', { className: 'sf-content' }),
      routes: SF.el('div', { className: 'sf-content', style: { display: 'none' } }),
      data: SF.el('div', { className: 'sf-content', style: { display: 'none' } }),
      api: SF.el('div', { className: 'sf-content', style: { display: 'none' } }),
    };

    var header = SF.createHeader({
      logo: '/sf/img/ouroboros.svg',
      title: options.config.title,
      subtitle: options.config.subtitle,
      tabs: [
        { id: 'map', label: 'Map', icon: 'fa-map-location-dot', active: true },
        { id: 'routes', label: 'Routes', icon: 'fa-list-ol' },
        { id: 'data', label: 'Data', icon: 'fa-table' },
        { id: 'api', label: 'REST API', icon: 'fa-book' },
      ],
      actions: {
        onSolve: options.onSolve,
        onPause: options.onPause,
        onResume: options.onResume,
        onCancel: options.onCancel,
        onAnalyze: options.onAnalyze,
      },
      onTabChange: function (tab) {
        Object.keys(panels).forEach(function (key) {
          panels[key].style.display = key === tab ? '' : 'none';
        });
        if (tab === 'map' && options.onMapTabShown) options.onMapTabShown();
      },
    });

    app.appendChild(header);
    options.statusBar.bindHeader(header);
    app.appendChild(options.statusBar.el);

    var bootstrapNotice = SF.el('div', {
      className: 'sf-content',
      style: {
        display: 'none',
        padding: '12px 16px',
        marginBottom: '12px',
        border: '1px solid #dc2626',
        borderRadius: '8px',
        background: '#fef2f2',
        color: '#991b1b',
      },
    });
    app.appendChild(bootstrapNotice);

    var summaryContainer = SF.el('div', { className: 'fsr-summary' });
    var mapShell = SF.el('div', { className: 'fsr-map-shell' });
    var routeListCard = SF.el('section', { className: 'sf-section fsr-routes-card' });
    var routeCards = SF.el('div', { className: 'fsr-route-list' });
    var mapCard = SF.el('section', { className: 'sf-section fsr-map-card' });
    var mapContainer = SF.el('div', { id: 'fsr-map', className: 'sf-map-container fsr-map' });

    routeListCard.appendChild(SF.el('h3', null, 'Routes'));
    routeListCard.appendChild(routeCards);
    mapCard.appendChild(SF.el('h3', null, 'Map'));
    mapCard.appendChild(mapContainer);
    mapShell.appendChild(routeListCard);
    mapShell.appendChild(mapCard);
    panels.map.appendChild(summaryContainer);
    panels.map.appendChild(mapShell);

    var timelineContainer = SF.el('div');
    var tablesContainer = SF.el('div');
    var apiGuideContainer = SF.el('div');
    panels.routes.appendChild(timelineContainer);
    panels.data.appendChild(tablesContainer);
    panels.api.appendChild(apiGuideContainer);

    app.appendChild(panels.map);
    app.appendChild(panels.routes);
    app.appendChild(panels.data);
    app.appendChild(panels.api);
    app.appendChild(SF.createFooter({
      links: [
        { label: 'SolverForge', url: 'https://www.solverforge.org' },
        { label: 'Docs', url: 'https://www.solverforge.org/docs' },
      ],
    }));

    return {
      apiGuideContainer: apiGuideContainer,
      bootstrapNotice: bootstrapNotice,
      header: header,
      routeCards: routeCards,
      summaryContainer: summaryContainer,
      tablesContainer: tablesContainer,
      timelineContainer: timelineContainer,
    };
  };
})();