• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jumpinjackie / mapguide-react-layout / 25110262545

29 Apr 2026 12:59PM UTC coverage: 60.446% (-0.07%) from 60.517%
25110262545

push

github

web-flow
Replace remaining bp3-* CSS classes with IElementContext abstractions and improve storybook component docs (#1637)

* feat: replace remaining bp3-* CSS classes with IElementContext abstractions

Agent-Logs-Url: https://github.com/jumpinjackie/mapguide-react-layout/sessions/5fe0aa1b-8e24-406a-b3a6-701d9f209a34

Co-authored-by: jumpinjackie <563860+jumpinjackie@users.noreply.github.com>

* fix: add radix to parseInt in onViewSizeUnitsChanged

Agent-Logs-Url: https://github.com/jumpinjackie/mapguide-react-layout/sessions/5fe0aa1b-8e24-406a-b3a6-701d9f209a34

Co-authored-by: jumpinjackie <563860+jumpinjackie@users.noreply.github.com>

* feat: enhance Storybook setup with custom docs and markdown support

* Fix TS error (using unsupported ES2018 API based on our current target)

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jumpinjackie <563860+jumpinjackie@users.noreply.github.com>
Co-authored-by: Jackie Ng <jumpinjackie@gmail.com>
Co-authored-by: Copilot <copilot@github.com>

3092 of 3738 branches covered (82.72%)

83 of 87 new or added lines in 14 files covered. (95.4%)

4 existing lines in 1 file now uncovered.

15216 of 25173 relevant lines covered (60.45%)

11.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.38
/src/containers/quick-plot.tsx
1
import * as React from "react";
1✔
2
import { getFusionRoot } from "../api/runtime";
1✔
3
import { tr as xlate, tr } from "../api/i18n";
1✔
4
import { RuntimeMap } from "../api/contracts/runtime-map";
5
import {
1✔
6
    GenericEvent,
7
    IMapView,
8
    IConfigurationReducerState,
9
    IExternalBaseLayer,
10
    IMapViewer,
11
    Size,
12
    isVisualBaseLayer
13
} from "../api/common";
14
import { MapCapturerContext, IMapCapturerContextCallback } from "./map-capturer-context";
1✔
15
import { useActiveMapName, useActiveMapView, useActiveMapExternalBaseLayers, useViewerLocale, useAvailableMaps, usePrevious } from './hooks';
1✔
16
import { setViewRotation, setViewRotationEnabled } from '../actions/map';
1✔
17
import { debug } from '../utils/logger';
1✔
18
import { useActiveMapState } from './hooks-mapguide';
1✔
19
import { useMapProviderContext, useReduxDispatch } from "../components/map-providers/context";
1✔
20
import { TypedSelect, useElementContext } from "../components/elements/element-context";
1✔
21
import { IMapProviderContext } from "../components/map-providers/base";
22

23
const PAPER_SIZES = [
1✔
24
    { value: "210.0,297.0,A4", label: "A4 (210x297 mm; 8.27x11.69 In) " },
1✔
25
    { value: "297.0,420.0,A3", label: "A3 (297x420 mm; 11.69x16.54 In) " },
1✔
26
    { value: "148.0,210.0,A5", label: "A5 (148x210 mm; 5.83x8.27 in) " },
1✔
27
    { value: "216.0,279.0,Letter", label: "Letter (216x279 mm; 8.50x11.00 In) " },
1✔
28
    { value: "216.0,356.0,Legal", label: "Legal (216x356 mm; 8.50x14.00 In) " }
1✔
29
];
1✔
30

31
const DPIS = [
1✔
32
    { value: "96", label: "96" },
1✔
33
    { value: "150", label: "150" },
1✔
34
    { value: "300", label: "300" },
1✔
35
    { value: "600", label: "600" }
1✔
36
];
1✔
37

38
const SCALES = [
1✔
39
    { value: "500", label: "1: 500" },
1✔
40
    { value: "1000", label: "1: 1000" },
1✔
41
    { value: "2500", label: "1: 2500" },
1✔
42
    { value: "5000", label: "1: 5000" }
1✔
43
]
1✔
44

45
function getMargin() {
8✔
46
    /*
47
    var widget = getParent().Fusion.getWidgetsByType("QuickPlot")[0];
48
    var margin;
49
    
50
    if(!!widget.margin){
51
         margin = widget.margin;
52
    }else{
53
        //the default margin
54
        margin = {top: 25.4, buttom: 12.7, left: 12.7, right: 12.7};
55
    }
56
    return margin;
57
    */
58
    return { top: 25.4, buttom: 12.7, left: 12.7, right: 12.7 };
8✔
59
}
8✔
60

61
function getPrintSize(viewer: IMapViewer, showAdvanced: boolean, paperSize: string, orientation: Orientation): Size {
8✔
62
    const value = paperSize.split(",");
8✔
63
    let size: Size;
8✔
64
    if (orientation === "P") {
8✔
65
        size = { w: parseFloat(value[0]), h: parseFloat(value[1]) };
8✔
66
    } else {
8!
UNCOV
67
        size = { w: parseFloat(value[1]), h: parseFloat(value[0]) };
×
UNCOV
68
    }
×
69

70
    if (!showAdvanced) {
8!
71
        // Calculate the paper size to make sure it has a same ratio with the viweport
72
        const paperRatio = size.w / size.h;
×
73
        var viewSize = viewer.getSize();
×
74
        let vs: Size | undefined;
×
75
        if (orientation === "P") {
×
76
            vs = {
×
77
                w: viewSize[1],
×
78
                h: viewSize[0]
×
79
            };
×
80
        } else {
×
81
            vs = {
×
82
                w: viewSize[0],
×
83
                h: viewSize[1]
×
84
            };
×
85
        }
×
86
        if (vs) {
×
87
            const viewRatio = vs.w / vs.h;
×
88
            if (paperRatio > viewRatio) {
×
89
                size.w = size.h * viewRatio;
×
90
            } else {
×
91
                size.h = size.w / viewRatio;
×
92
            }
×
93
        }
×
94
    }
×
95

96
    const margins = getMargin();
8✔
97
    size.h = size.h - margins.top - margins.buttom;
8✔
98
    size.w = size.w - margins.left - margins.right;
8✔
99

100
    return size;
8✔
101
}
8✔
102

103
const _mapCapturers: MapCapturerContext[] = [];
1✔
104

105
function getActiveCapturer(viewer: IMapViewer, mapNames: string[], activeMapName: string): MapCapturerContext | undefined {
10✔
106
    let activeCapturer: MapCapturerContext | undefined;
10✔
107
    if (_mapCapturers.length == 0) {
10✔
108
        if (mapNames.length) {
1✔
109
            for (const mapName of mapNames) {
1✔
110
                const context = new MapCapturerContext(viewer, mapName);
1✔
111
                _mapCapturers.push(context);
1✔
112
                if (activeMapName == mapName) {
1✔
113
                    activeCapturer = context;
1✔
114
                }
1✔
115
            }
1✔
116
        }
1✔
117
    } else {
10✔
118
        activeCapturer = _mapCapturers.filter(m => m.getMapName() === activeMapName)[0];
9✔
119
    }
9✔
120
    return activeCapturer;
10✔
121
}
10✔
122

123
function toggleMapCapturerLayer(locale: string,
4✔
124
    viewer: IMapProviderContext,
4✔
125
    mapNames: string[] | undefined,
4✔
126
    activeMapName: string,
4✔
127
    showAdvanced: boolean,
4✔
128
    paperSize: string,
4✔
129
    orientation: Orientation,
4✔
130
    scale: string,
4✔
131
    rotation: number,
4✔
132
    updateBoxCoords: (box: string, normalizedBox: string) => void,
4✔
133
    setViewRotationEnabled: (flag: boolean) => void,
4✔
134
    setViewRotation: (rot: number) => void) {
4✔
135
    const bVisible: boolean = showAdvanced;
4✔
136
    if (viewer.isReady() && mapNames) {
4✔
137
        const activeCapturer = getActiveCapturer(viewer, mapNames, activeMapName);
4✔
138
        if (activeCapturer) {
4✔
139
            if (bVisible) {
4✔
140
                const ppSize = getPrintSize(viewer, showAdvanced, paperSize, orientation);
4✔
141
                const cb: IMapCapturerContextCallback = {
4✔
142
                    updateBoxCoords
4✔
143
                }
4✔
144
                activeCapturer.activate(cb, ppSize, parseFloat(scale), rotation);
4✔
145
                //For simplicity, reset rotation to 0 and prevent the ability to rotate while the map capture box
146
                //is active
147
                setViewRotationEnabled(false);
4✔
148
                setViewRotation(0);
4✔
149
                viewer.toastPrimary("info-sign", tr("QUICKPLOT_BOX_INFO", locale));
4✔
150
            } else {
4!
151
                activeCapturer.deactivate();
×
152
                setViewRotationEnabled(true);
×
153
            }
×
154
        }
4✔
155
    }
4✔
156
}
4✔
157

158
export interface IQuickPlotContainerOwnProps {
159

160
}
161

162
export interface IQuickPlotContainerConnectedState {
163
    config: IConfigurationReducerState;
164
    map: RuntimeMap;
165
    view: IMapView;
166
    externalBaseLayers: IExternalBaseLayer[];
167
    mapNames: string[];
168
}
169

170
export interface IQuickPlotContainerDispatch {
171
    setViewRotation: (rotation: number) => void;
172
    setViewRotationEnabled: (enabled: boolean) => void;
173
}
174

175
/**
176
 * @since 0.15
177
 */
178
export type Orientation = "L" | "P";
179

180
export interface IQuickPlotContainerState {
181
    title: string;
182
    subTitle: string;
183
    showLegend: boolean;
184
    showNorthBar: boolean;
185
    showCoordinates: boolean;
186
    showScaleBar: boolean;
187
    showDisclaimer: boolean;
188
    showAdvanced: boolean;
189
    orientation: Orientation;
190
    paperSize: string;
191
    scale: string;
192
    dpi: string;
193
    rotation: number;
194
    box: string;
195
    normalizedBox: string;
196
}
197

198
export const QuickPlotContainer = () => {
1✔
199
    const { Slider, Callout, Button, Select, FormGroup, InputGroup, Checkbox } = useElementContext();
14✔
200
    const [title, setTitle] = React.useState(""); ``
14✔
201
    const [subTitle, setSubTitle] = React.useState("");
14✔
202
    const [showLegend, setShowLegend] = React.useState(false);
14✔
203
    const [showNorthBar, setShowNorthBar] = React.useState(false);
14✔
204
    const [showCoordinates, setShowCoordinates] = React.useState(false);
14✔
205
    const [showScaleBar, setShowScaleBar] = React.useState(false);
14✔
206
    const [showDisclaimer, setShowDisclaimer] = React.useState(false);
14✔
207
    const [showAdvanced, setShowAdvanced] = React.useState(false);
14✔
208
    const [orientation, setOrientation] = React.useState<Orientation>("P");
14✔
209
    const [paperSize, setPaperSize] = React.useState("210.0,297.0,A4");
14✔
210
    const [scale, setScale] = React.useState("5000");
14✔
211
    const [dpi, setDpi] = React.useState("96");
14✔
212
    const [rotation, setRotation] = React.useState(0);
14✔
213
    const [box, setBox] = React.useState("");
14✔
214
    const [normalizedBox, setNormalizedBox] = React.useState("");
14✔
215

216
    const viewer = useMapProviderContext();
14✔
217
    const locale = useViewerLocale();
14✔
218
    const activeMapName = useActiveMapName();
14✔
219
    const mapNames = useAvailableMaps()?.map(m => m.value);
14✔
220
    const map = useActiveMapState();
14✔
221
    const view = useActiveMapView();
14✔
222
    const externalBaseLayers = useActiveMapExternalBaseLayers()?.filter(ebl => isVisualBaseLayer(ebl));
14✔
223
    const dispatch = useReduxDispatch();
14✔
224
    const setViewRotationAction = (rotation: number) => dispatch(setViewRotation(rotation));
14✔
225
    const setViewRotationEnabledAction = (enabled: boolean) => dispatch(setViewRotationEnabled(enabled));
14✔
226

227
    const onTitleChanged = (e: GenericEvent) => {
14✔
228
        setTitle(e.target.value);
1✔
229
    };
1✔
230
    const onSubTitleChanged = (e: GenericEvent) => {
14✔
231
        setSubTitle(e.target.value);
1✔
232
    };
1✔
233
    const onShowLegendChanged = () => {
14✔
234
        setShowLegend(!showLegend);
1✔
235
    };
1✔
236
    const onShowNorthArrowChanged = () => {
14✔
237
        setShowNorthBar(!showNorthBar);
1✔
238
    };
1✔
239
    const onShowCoordinatesChanged = () => {
14✔
240
        setShowCoordinates(!showCoordinates);
1✔
241
    };
1✔
242
    const onShowScaleBarChanged = () => {
14✔
243
        setShowScaleBar(!showScaleBar);
1✔
244
    };
1✔
245
    const onShowDisclaimerChanged = () => {
14✔
246
        setShowDisclaimer(!showDisclaimer);
1✔
247
    };
1✔
248
    const onAdvancedOptionsChanged = () => {
14✔
249
        setShowAdvanced(!showAdvanced);
2✔
250
    };
2✔
251
    const onRotationChanged = (value: number) => {
14✔
252
        setRotation(value);
1✔
253
    };
1✔
254
    const onGeneratePlot = () => { };
14✔
255
    const updateBoxCoords = (box: string, normalizedBox: string): void => {
14✔
256
        setBox(box);
×
257
        setNormalizedBox(normalizedBox);
×
258
    };
×
259
    //Side-effect that emulates the old componentWillUnmount lifecyle method to tear down
260
    //the active map capturer
261
    React.useEffect(() => {
14✔
262
        return () => {
3✔
263
            //Tear down all active capture box layers
264
            if (viewer.isReady() && mapNames) {
3✔
265
                for (const activeMapName of mapNames) {
2✔
266
                    const activeCapturer = getActiveCapturer(viewer, mapNames, activeMapName);
2✔
267
                    if (activeCapturer) {
2✔
268
                        debug(`De-activating map capturer for: ${activeMapName}`);
2✔
269
                        activeCapturer.deactivate();
2✔
270
                    }
2✔
271
                }
2✔
272
            }
2✔
273
        };
3✔
274
    }, []);
14✔
275
    //Although the dep array arg of React.useEffect() has effectively rendered the need to
276
    //track previous values obsolete, we still need to track the previous advanced flag to
277
    //verify that the flag is amongst the actual values in the dep array that has changed
278
    const prevShowAdvanced = usePrevious(showAdvanced);
14✔
279
    //Side-effect that toggles/updates associated map capturers
280
    React.useEffect(() => {
14✔
281
        if (activeMapName && mapNames) {
14✔
282
            if (showAdvanced != prevShowAdvanced) {
14✔
283
                toggleMapCapturerLayer(locale,
4✔
284
                    viewer,
4✔
285
                    mapNames,
4✔
286
                    activeMapName,
4✔
287
                    showAdvanced,
4✔
288
                    paperSize,
4✔
289
                    orientation,
4✔
290
                    scale,
4✔
291
                    rotation,
4✔
292
                    updateBoxCoords,
4✔
293
                    setViewRotationEnabledAction,
4✔
294
                    setViewRotationAction);
4✔
295
            }
4✔
296
            if (showAdvanced) {
14✔
297
                if (viewer.isReady()) {
4✔
298
                    const capturer = getActiveCapturer(viewer, mapNames, activeMapName);
4✔
299
                    if (capturer) {
4✔
300
                        const ppSize = getPrintSize(viewer, showAdvanced, paperSize, orientation);
4✔
301
                        debug(`Updating map capturer for: ${activeMapName}`);
4✔
302
                        capturer.updateBox(ppSize, parseFloat(scale), rotation);
4✔
303
                    }
4✔
304
                }
4✔
305
            }
4✔
306
        }
14✔
307
    }, [mapNames, activeMapName, showAdvanced, scale, paperSize, orientation, rotation, locale]);
14✔
308
    if (!viewer.isReady() || !map || !view) {
14✔
309
        return <noscript />;
1✔
310
    }
1✔
311
    let hasExternalBaseLayers = false;
13✔
312
    if (externalBaseLayers) {
13✔
313
        hasExternalBaseLayers = externalBaseLayers.length > 0;
13✔
314
    }
13✔
315
    let normBox = normalizedBox;
13✔
316
    let theBox = box;
13✔
317
    if (!showAdvanced) {
14✔
318
        const extent = viewer.getCurrentExtent();
9✔
319
        theBox = `${extent[0]}, ${extent[1]}, ${extent[2]}, ${extent[1]}, ${extent[2]}, ${extent[3]}, ${extent[0]}, ${extent[3]}, ${extent[0]}, ${extent[1]}`;
9✔
320
        normBox = theBox;
9✔
321
    }
9✔
322
    let ppSize: string;
13✔
323
    let prSize: string;
13✔
324
    const tokens = paperSize.split(",");
13✔
325
    if (orientation === "L") {
14!
UNCOV
326
        prSize = `${tokens[1]},${tokens[0]}`;
×
UNCOV
327
        ppSize = `${prSize},${tokens[2]}`;
×
328
    } else { // P
14✔
329
        prSize = `${tokens[0]},${tokens[1]}`;
13✔
330
        ppSize = `${prSize},${tokens[2]}`;
13✔
331
    }
13✔
332
    const url = `${getFusionRoot()}/widgets/QuickPlot/PlotAsPDF.php`;
13✔
333
    const ORIENTATIONS = [
13✔
334
        { value: "P" as Orientation, label: xlate("QUICKPLOT_ORIENTATION_P", locale) },
13✔
335
        { value: "L" as Orientation, label: xlate("QUICKPLOT_ORIENTATION_L", locale) }
13✔
336
    ];
13✔
337
    return <div className="component-quick-plot">
13✔
338
        <form id="Form1" name="Form1" target="_blank" method="post" action={url}>
13✔
339
            <input type="hidden" id="printId" name="printId" value={`${Math.random() * 1000}`} />
13✔
340
            <div className="Title FixWidth">{xlate("QUICKPLOT_HEADER", locale)}</div>
13✔
341
            <FormGroup label={xlate("QUICKPLOT_TITLE", locale)}>
13✔
342
                <InputGroup name="{field:title}" id="title" value={title} onChange={onTitleChanged} />
13✔
343
            </FormGroup>
13✔
344
            <FormGroup label={xlate("QUICKPLOT_SUBTITLE", locale)}>
13✔
345
                <InputGroup name="{field:sub_title}" id="subtitle" value={subTitle} onChange={onSubTitleChanged} />
13✔
346
            </FormGroup>
13✔
347
            <FormGroup label={xlate("QUICKPLOT_PAPER_SIZE", locale)}>
13✔
348
                {/*
349
                    The pre-defined paper size list. The value for each "option" item is in this format: [width,height]. The unit is in millimeter.
350
                    We can change the html code to add more paper size or remove some ones.
351
                */}
352
                <TypedSelect<string, false> fill
13✔
353
                    id="paperSizeSelect"
13✔
354
                    name="paperSizeSelect"
13✔
355
                    value={paperSize}
13✔
356
                    onChange={e => setPaperSize(e)}
13✔
357
                    items={PAPER_SIZES} />
13✔
358
            </FormGroup>
13✔
359
            <FormGroup label={xlate("QUICKPLOT_ORIENTATION", locale)}>
13✔
360
                {/*
361
                    The pre-defined paper orientations
362
                */}
363
                <TypedSelect<Orientation, false>
13✔
364
                    fill
13✔
365
                    id="orientation"
13✔
366
                    name="orientation"
13✔
367
                    value={orientation}
13✔
368
                    onChange={e => setOrientation(e)}
13✔
369
                    items={ORIENTATIONS} />
13✔
370
            </FormGroup>
13✔
371
            <input type="hidden" id="paperSize" name="paperSize" value={ppSize} />
13✔
372
            <input type="hidden" id="printSize" name="printSize" value={prSize} />
13✔
373
            <fieldset>
13✔
374
                <legend>{xlate("QUICKPLOT_SHOWELEMENTS", locale)}</legend>
13✔
375
                <Checkbox id="ShowLegendCheckBox" name="ShowLegend" checked={showLegend} onChange={onShowLegendChanged} label={xlate("QUICKPLOT_SHOWLEGEND", locale)} />
13✔
376
                <Checkbox id="ShowNorthArrowCheckBox" name="ShowNorthArrow" checked={showNorthBar} onChange={onShowNorthArrowChanged} label={xlate("QUICKPLOT_SHOWNORTHARROW", locale)} />
13✔
377
                <Checkbox id="ShowCoordinatesCheckBox" name="ShowCoordinates" checked={showCoordinates} onChange={onShowCoordinatesChanged} label={xlate("QUICKPLOT_SHOWCOORDINTES", locale)} />
13✔
378
                <Checkbox id="ShowScaleBarCheckBox" name="ShowScaleBar" checked={showScaleBar} onChange={onShowScaleBarChanged} label={xlate("QUICKPLOT_SHOWSCALEBAR", locale)} />
13✔
379
                <Checkbox id="ShowDisclaimerCheckBox" name="ShowDisclaimer" checked={showDisclaimer} onChange={onShowDisclaimerChanged} label={xlate("QUICKPLOT_SHOWDISCLAIMER", locale)} />
13✔
380
            </fieldset>
13✔
381
            <div className="HPlaceholder5px"></div>
13✔
382
            <div>
13✔
383
                <Checkbox id="AdvancedOptionsCheckBox" onChange={onAdvancedOptionsChanged} label={xlate("QUICKPLOT_ADVANCED_OPTIONS", locale)} />
13✔
384
            </div>
13✔
385
            {(() => {
13✔
386
                if (showAdvanced) {
13✔
387
                    return <div>
4✔
388
                        <FormGroup label={xlate("QUICKPLOT_SCALING", locale)}>
4✔
389
                            {/*
390
                                The pre-defined scales. The value for each "option" item is the scale denominator.
391
                                We can change the html code to extend the pre-defined scales
392
                            */}
393
                            <TypedSelect<string, false> fill
4✔
394
                                id="scaleDenominator"
4✔
395
                                name="scaleDenominator"
4✔
396
                                value={scale}
4✔
397
                                onChange={e => setScale(e)}
4✔
398
                                items={SCALES} />
4✔
399
                        </FormGroup>
4✔
400
                        <FormGroup label={xlate("QUICKPLOT_DPI", locale)}>
4✔
401
                            {/*
402
                                The pre-defined print DPI.
403
                                We can change the html code to extend the pre-defined values
404
                            */}
405
                            <TypedSelect<string, false> fill
4✔
406
                                id="dpi"
4✔
407
                                name="dpi"
4✔
408
                                onChange={e => setDpi(e)}
4✔
409
                                items={DPIS} />
4✔
410
                        </FormGroup>
4✔
411
                        <FormGroup label={xlate("QUICKPLOT_BOX_ROTATION", locale)}>
4✔
412
                            <div style={{ paddingLeft: 16, paddingRight: 16 }}>
4✔
413
                                <Slider min={0} max={360} labelStepSize={90} stepSize={1} value={rotation} onChange={onRotationChanged} />
4✔
414
                            </div>
4✔
415
                        </FormGroup>
4✔
416
                    </div>;
4✔
417
                } else {
13✔
418
                    return <div>
9✔
419
                        <input type="hidden" id="scaleDenominator" name="scaleDenominator" value={`${view.scale}`} />
9✔
420
                        <input type="hidden" id="dpi" name="dpi" value={dpi} />
9✔
421
                    </div>;
9✔
422
                }
9✔
423
            })()}
13✔
424
            <div className="HPlaceholder5px"></div>
13✔
425
            {(() => {
13✔
426
                if (hasExternalBaseLayers) {
13✔
427
                    return <Callout variant="primary" icon="info-sign">
2✔
428
                        {xlate("QUICKPLOT_COMMERCIAL_LAYER_WARNING", locale)}
2✔
429
                    </Callout>;
2✔
430
                }
2✔
431
            })()}
13✔
432
            <div className="ButtonContainer FixWidth">
13✔
433
                <Button type="submit" variant="primary" icon="print" onClick={onGeneratePlot}>{xlate("QUICKPLOT_GENERATE", locale)}</Button>
13✔
434
            </div>
13✔
435
            <input type="hidden" id="margin" name="margin" />
13✔
436
            <input type="hidden" id="normalizedBox" name="normalizedBox" value={normBox} />
13✔
437
            <input type="hidden" id="rotation" name="rotation" value={-(rotation || 0)} />
14✔
438
            <input type="hidden" id="sessionId" name="sessionId" value={map.SessionId} />
14✔
439
            <input type="hidden" id="mapName" name="mapName" value={map.Name} />
14✔
440
            <input type="hidden" id="box" name="box" value={theBox} />
14✔
441
            <input type="hidden" id="legalNotice" name="legalNotice" />
14✔
442
        </form>
14✔
443
    </div>;
14✔
444
}
14✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc