@midscene/visualizer 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/es/component/assets/logo-plain.js +128 -0
  2. package/dist/es/component/assets/logo-plain2.js +128 -0
  3. package/dist/es/component/blackboard.js +5 -1
  4. package/dist/es/component/detail-panel.js +2 -2
  5. package/dist/es/component/detail-side.css +3 -2
  6. package/dist/es/component/detail-side.js +14 -5
  7. package/dist/es/component/global-hover-preview.css +1 -1
  8. package/dist/es/component/global-hover-preview.js +6 -1
  9. package/dist/es/component/sidebar.css +2 -1
  10. package/dist/es/component/sidebar.js +19 -12
  11. package/dist/es/component/store.js +7 -6
  12. package/dist/es/component/timeline.js +2 -2
  13. package/dist/es/index.css +14 -9
  14. package/dist/es/index.js +33 -7
  15. package/dist/lib/component/assets/logo-plain.js +156 -0
  16. package/dist/lib/component/assets/logo-plain2.js +156 -0
  17. package/dist/lib/component/blackboard.js +5 -1
  18. package/dist/lib/component/detail-panel.js +2 -2
  19. package/dist/lib/component/detail-side.css +3 -2
  20. package/dist/lib/component/detail-side.js +14 -5
  21. package/dist/lib/component/global-hover-preview.css +1 -1
  22. package/dist/lib/component/global-hover-preview.js +6 -1
  23. package/dist/lib/component/sidebar.css +2 -1
  24. package/dist/lib/component/sidebar.js +19 -12
  25. package/dist/lib/component/store.js +7 -6
  26. package/dist/lib/component/timeline.js +2 -2
  27. package/dist/lib/index.css +14 -9
  28. package/dist/lib/index.js +37 -7
  29. package/dist/types/component/sidebar.d.ts +4 -1
  30. package/dist/types/component/store.d.ts +2 -1
  31. package/dist/types/index.d.ts +7 -2
  32. package/package.json +9 -4
  33. package/.eslintrc.js +0 -9
  34. package/dist/es/assets/logo-plain.16842bbc.svg +0 -70
  35. package/dist/es/assets/logo-plain2.16842bbc.svg +0 -70
  36. package/dist/lib/assets/logo-plain.16842bbc.svg +0 -70
  37. package/dist/lib/assets/logo-plain2.16842bbc.svg +0 -70
  38. package/docs/index.tsx +0 -6
  39. package/modern.config.ts +0 -15
  40. package/src/component/assets/logo-plain.svg +0 -70
  41. package/src/component/assets/logo-plain2.svg +0 -70
  42. package/src/component/blackboard.less +0 -37
  43. package/src/component/blackboard.tsx +0 -293
  44. package/src/component/color.tsx +0 -34
  45. package/src/component/common.less +0 -21
  46. package/src/component/detail-panel.less +0 -47
  47. package/src/component/detail-panel.tsx +0 -124
  48. package/src/component/detail-side.less +0 -131
  49. package/src/component/detail-side.tsx +0 -361
  50. package/src/component/global-hover-preview.less +0 -23
  51. package/src/component/global-hover-preview.tsx +0 -50
  52. package/src/component/misc.tsx +0 -20
  53. package/src/component/panel-title.less +0 -11
  54. package/src/component/panel-title.tsx +0 -11
  55. package/src/component/side-item.tsx +0 -0
  56. package/src/component/sidebar.less +0 -122
  57. package/src/component/sidebar.tsx +0 -205
  58. package/src/component/store.tsx +0 -151
  59. package/src/component/timeline.less +0 -25
  60. package/src/component/timeline.tsx +0 -486
  61. package/src/global.d.ts +0 -11
  62. package/src/index.less +0 -113
  63. package/src/index.tsx +0 -210
  64. package/src/utils.ts +0 -58
  65. package/tsconfig.json +0 -24
@@ -1,486 +0,0 @@
1
- /* eslint-disable max-lines */
2
- import { useEffect, useMemo, useRef, useState } from 'react';
3
- import * as PIXI from 'pixi.js';
4
-
5
- import './timeline.less';
6
- import { ExecutionRecorderItem, ExecutionTask } from '@midscene/core';
7
- import { useAllCurrentTasks, useExecutionDump } from './store';
8
-
9
- interface TimelineItem {
10
- id: string;
11
- img: string;
12
- timeOffset: number;
13
- x?: number;
14
- y?: number;
15
- width?: number;
16
- height?: number;
17
- }
18
-
19
- interface HighlightParam {
20
- mouseX: number;
21
- mouseY: number;
22
- item: TimelineItem;
23
- }
24
-
25
- interface HighlightMask {
26
- startMs: number;
27
- endMs: number;
28
- }
29
-
30
- // Function to clone a sprite
31
- function cloneSprite(sprite: PIXI.Sprite) {
32
- const clonedSprite = new PIXI.Sprite(sprite.texture);
33
-
34
- // Copy properties
35
- clonedSprite.position.copyFrom(sprite.position);
36
- clonedSprite.scale.copyFrom(sprite.scale);
37
- clonedSprite.rotation = sprite.rotation;
38
- clonedSprite.alpha = sprite.alpha;
39
- clonedSprite.visible = sprite.visible;
40
-
41
- return clonedSprite;
42
- }
43
-
44
- const TimelineWidget = (props: {
45
- screenshots: TimelineItem[];
46
- onHighlight?: (param: HighlightParam) => any;
47
- onUnhighlight?: () => any;
48
- onTap?: (param: TimelineItem) => any;
49
- highlightMask?: HighlightMask;
50
- hoverMask?: HighlightMask;
51
- }): JSX.Element => {
52
- const domRef = useRef<HTMLDivElement>(null); // Should be HTMLDivElement not HTMLInputElement
53
- const app = useMemo<PIXI.Application>(() => new PIXI.Application(), []);
54
-
55
- const gridsContainer = useMemo(() => new PIXI.Container(), []);
56
- const screenshotsContainer = useMemo(() => new PIXI.Container(), []);
57
- const highlightMaskContainer = useMemo(() => new PIXI.Container(), []);
58
- const containerUpdaterRef = useRef(
59
- // eslint-disable-next-line @typescript-eslint/no-empty-function
60
- (_s: number | undefined, _e: number | undefined, _hs: number | undefined, _he: number | undefined) => {},
61
- );
62
- const indicatorContainer = useMemo(() => new PIXI.Container(), []);
63
-
64
- const allScreenshots = props.screenshots || [];
65
- const maxTime = allScreenshots[allScreenshots.length - 1].timeOffset;
66
-
67
- const sizeRatio = 2;
68
-
69
- const titleBg = 0xdddddd; // @title-bg
70
- const sideBg = 0xececec;
71
- const gridTextColor = 0;
72
- const shotBorderColor = 0x777777;
73
- const gridLineColor = 0xcccccc; // @border-color
74
- const gridHighlightColor = 0x06b1ab; // @main-blue
75
- const timeContentFontSize = 20;
76
- const commonPadding = 12;
77
- const timeTextTop = commonPadding;
78
- const timeTitleBottom = timeTextTop * 2 + timeContentFontSize;
79
- const highlightMaskAlpha = 0.6;
80
- const hoverMaskAlpha = 0.3;
81
-
82
- const closestScreenshotItemOnXY = (x: number, _y: number) => {
83
- // find out the screenshot that is closest to the mouse on the left
84
- let closestScreenshot: TimelineItem | undefined; // already sorted
85
- let closestIndex = -1;
86
- for (let i = 0; i < allScreenshots.length; i++) {
87
- const shot = allScreenshots[i];
88
- if (shot.x! <= x) {
89
- closestScreenshot = allScreenshots[i];
90
- closestIndex = i;
91
- } else {
92
- break;
93
- }
94
- }
95
- return {
96
- closestScreenshot,
97
- closestIndex,
98
- };
99
- };
100
-
101
- useMemo(() => {
102
- const { startMs, endMs } = props.highlightMask || {};
103
- const { startMs: hoverStartMs, endMs: hoverEndMs } = props.hoverMask || {};
104
- const fn = containerUpdaterRef.current;
105
- fn(startMs, endMs, hoverStartMs, hoverEndMs);
106
- }, [
107
- props.highlightMask?.startMs,
108
- props.highlightMask?.endMs,
109
- props.hoverMask?.startMs,
110
- props.hoverMask?.endMs,
111
- ]);
112
-
113
- useEffect(() => {
114
- Promise.resolve(
115
- (async () => {
116
- if (!domRef.current) {
117
- return;
118
- }
119
-
120
- // width of domRef
121
- const { clientWidth, clientHeight } = domRef.current;
122
- const canvasWidth = clientWidth * sizeRatio;
123
- const canvasHeight = clientHeight * sizeRatio;
124
-
125
- let singleGridWidth = 100 * sizeRatio;
126
- let gridCount = Math.floor(canvasWidth / singleGridWidth);
127
- const stepCandidate = [
128
- 50, 100, 200, 300, 500, 1000, 2000, 3000, 5000, 6000, 8000, 9000, 10000, 20000, 30000, 40000, 60000,
129
- 90000, 12000, 300000,
130
- ];
131
- let timeStep = stepCandidate[0];
132
- for (let i = stepCandidate.length - 1; i >= 0; i--) {
133
- if (gridCount * stepCandidate[i] >= maxTime) {
134
- timeStep = stepCandidate[i];
135
- }
136
- }
137
- const gridRatio = maxTime / (gridCount * timeStep);
138
- if (gridRatio <= 0.8) {
139
- singleGridWidth = Math.floor(singleGridWidth * (1 / gridRatio) * 0.9);
140
- gridCount = Math.floor(canvasWidth / singleGridWidth);
141
- }
142
-
143
- const leftForTimeOffset = (timeOffset: number) => {
144
- return Math.floor((singleGridWidth * timeOffset) / timeStep);
145
- };
146
- const timeOffsetForLeft = (left: number) => {
147
- return Math.floor((left * timeStep) / singleGridWidth);
148
- };
149
-
150
- await app.init({
151
- width: canvasWidth,
152
- height: canvasHeight,
153
- backgroundColor: sideBg,
154
- });
155
- if (!domRef.current) {
156
- app.destroy();
157
- return;
158
- }
159
- domRef.current.replaceChildren(app.canvas);
160
-
161
- const pixiTextForNumber = (num: number) => {
162
- const textContent = `${num}ms`;
163
- const text = new PIXI.Text(`${textContent}`, {
164
- fontSize: timeContentFontSize,
165
- fill: gridTextColor,
166
- });
167
- return text;
168
- };
169
-
170
- // drawing vertical grids, texts, title bg
171
- gridsContainer.removeChildren();
172
- const titleBgSection = new PIXI.Graphics();
173
- titleBgSection.beginFill(titleBg);
174
- titleBgSection.drawRect(0, 0, canvasWidth, timeTitleBottom);
175
- titleBgSection.endFill();
176
- gridsContainer.addChild(titleBgSection);
177
-
178
- const gridHeight = canvasHeight;
179
- for (let i = 1; i <= gridCount; i++) {
180
- const gridLine = new PIXI.Graphics();
181
- const gridLineLeft = leftForTimeOffset(i * timeStep);
182
- gridLine.beginFill(gridLineColor);
183
- gridLine.drawRect(gridLineLeft, 0, sizeRatio, gridHeight);
184
- gridLine.endFill();
185
- gridsContainer.addChild(gridLine);
186
-
187
- // mark text at the left of each line
188
- const text = pixiTextForNumber(i * timeStep); // `${i * timeStep}ms`;
189
- // measure text width
190
- const textLeft = gridLineLeft - text.width - commonPadding;
191
-
192
- text.x = textLeft;
193
- text.y = timeTextTop;
194
-
195
- gridsContainer.addChild(text);
196
- }
197
- app.stage.addChild(gridsContainer);
198
-
199
- if (!allScreenshots.length) {
200
- console.warn('No screenshots found');
201
- return;
202
- }
203
-
204
- const shotContainers: PIXI.Container[] = [];
205
-
206
- // draw all screenshots
207
- screenshotsContainer.removeChildren();
208
- const screenshotTop = timeTitleBottom + commonPadding * 1.5;
209
- const screenshotMaxHeight = canvasHeight - screenshotTop - commonPadding * 1.5;
210
- allScreenshots.forEach((screenshot, index) => {
211
- const container = new PIXI.Container();
212
- shotContainers.push(container);
213
- app.stage.addChild(container);
214
- const img = new Image();
215
- img.src = screenshot.img;
216
- img.onload = () => {
217
- const screenshotTexture = PIXI.Texture.from(img);
218
- const screenshotSprite = new PIXI.Sprite(screenshotTexture);
219
-
220
- // get width / height of img
221
- const originalWidth = img.width;
222
- const originalHeight = img.height;
223
-
224
- const screenshotHeight = screenshotMaxHeight;
225
- const screenshotWidth = Math.floor((screenshotHeight / originalHeight) * originalWidth);
226
-
227
- const screenshotX = leftForTimeOffset(screenshot.timeOffset);
228
- allScreenshots[index].x = screenshotX;
229
- allScreenshots[index].y = screenshotTop;
230
- allScreenshots[index].width = screenshotWidth;
231
- allScreenshots[index].height = screenshotMaxHeight;
232
-
233
- const border = new PIXI.Graphics();
234
- border.lineStyle(sizeRatio, shotBorderColor, 1);
235
- border.drawRect(screenshotX, screenshotTop, screenshotWidth, screenshotMaxHeight);
236
- border.endFill();
237
- container.addChild(border);
238
-
239
- screenshotSprite.x = screenshotX;
240
- screenshotSprite.y = screenshotTop;
241
- screenshotSprite.width = screenshotWidth;
242
- screenshotSprite.height = screenshotMaxHeight;
243
- container.addChild(screenshotSprite);
244
- };
245
- });
246
-
247
- const highlightMaskUpdater = (
248
- start: number | undefined,
249
- end: number | undefined,
250
- hoverStart: number | undefined,
251
- hoverEnd: number | undefined,
252
- ) => {
253
- highlightMaskContainer.removeChildren();
254
-
255
- const mask = (start: number | undefined, end: number | undefined, alpha: number) => {
256
- if (typeof start === 'undefined' || typeof end === 'undefined' || end === 0) {
257
- return;
258
- }
259
- const leftBorder = new PIXI.Graphics();
260
- leftBorder.beginFill(gridHighlightColor, 1);
261
- leftBorder.drawRect(leftForTimeOffset(start), 0, sizeRatio, canvasHeight);
262
- leftBorder.endFill();
263
- highlightMaskContainer.addChild(leftBorder);
264
-
265
- const rightBorder = new PIXI.Graphics();
266
- rightBorder.beginFill(gridHighlightColor, 1);
267
- rightBorder.drawRect(leftForTimeOffset(end), 0, sizeRatio, canvasHeight);
268
- rightBorder.endFill();
269
- highlightMaskContainer.addChild(rightBorder);
270
-
271
- const mask = new PIXI.Graphics();
272
- mask.beginFill(gridHighlightColor, alpha);
273
- mask.drawRect(
274
- leftForTimeOffset(start),
275
- 0,
276
- leftForTimeOffset(end) - leftForTimeOffset(start),
277
- canvasHeight,
278
- );
279
- mask.endFill();
280
- highlightMaskContainer.addChild(mask);
281
- };
282
-
283
- mask(start, end, highlightMaskAlpha);
284
- mask(hoverStart, hoverEnd, hoverMaskAlpha);
285
- };
286
- highlightMaskUpdater(props.highlightMask?.startMs, props.highlightMask?.endMs, 0, 0);
287
- containerUpdaterRef.current = highlightMaskUpdater;
288
-
289
- // keep tracking the position of the mouse moving above the canvas
290
- app.stage.interactive = true;
291
- const onPointerMove = (event: PointerEvent) => {
292
- const x = event.offsetX * sizeRatio;
293
- const y = event.offsetY * sizeRatio;
294
- indicatorContainer.removeChildren();
295
-
296
- // find out the screenshot that is closest to the mouse on the left
297
- const { closestScreenshot, closestIndex } = closestScreenshotItemOnXY(x, y);
298
- if (closestIndex < 0) {
299
- props.onUnhighlight?.();
300
- return;
301
- }
302
- const closestContainer = shotContainers[closestIndex];
303
-
304
- // highlight the items in closestContainer
305
- closestContainer.children.forEach((child) => {
306
- if (child instanceof PIXI.Sprite) {
307
- // border
308
- const newSpirit = new PIXI.Graphics();
309
- newSpirit.lineStyle(2, gridHighlightColor, 1);
310
- newSpirit.drawRect(
311
- x, // follow mouse
312
- closestScreenshot!.y!,
313
- closestScreenshot!.width!,
314
- closestScreenshot!.height!,
315
- );
316
- newSpirit.endFill();
317
- indicatorContainer.addChild(newSpirit);
318
-
319
- const screenshotSpirit = cloneSprite(child);
320
- screenshotSpirit.x = x;
321
- indicatorContainer.addChild(screenshotSpirit);
322
- }
323
- });
324
-
325
- // cursor line
326
- const indicator = new PIXI.Graphics();
327
- indicator.beginFill(gridHighlightColor, 1);
328
- indicator.drawRect(x - 1, 0, 3, canvasHeight);
329
- indicator.endFill();
330
- indicatorContainer.addChild(indicator);
331
-
332
- // time string
333
- const text = pixiTextForNumber(timeOffsetForLeft(x));
334
- text.x = x + 5;
335
- text.y = timeTextTop;
336
- const textBg = new PIXI.Graphics();
337
- textBg.beginFill(titleBg, 1);
338
- textBg.drawRect(text.x, text.y, text.width + 10, text.height);
339
- textBg.endFill();
340
-
341
- indicatorContainer.addChild(textBg);
342
- indicatorContainer.addChild(text);
343
-
344
- props.onHighlight?.({
345
- mouseX: x / sizeRatio,
346
- mouseY: y / sizeRatio,
347
- item: closestScreenshot!,
348
- });
349
- };
350
- // app.stage.on('pointermove', onPointerMove);
351
- // on pointer move out
352
- const onPointerOut = () => {
353
- indicatorContainer.removeChildren();
354
- props.onUnhighlight?.();
355
- };
356
-
357
- const onPointerTap = (event: PointerEvent) => {
358
- const x = event.offsetX * sizeRatio;
359
- const y = event.offsetY * sizeRatio;
360
- const { closestScreenshot } = closestScreenshotItemOnXY(x, y);
361
- if (closestScreenshot) {
362
- props.onTap?.(closestScreenshot);
363
- }
364
- };
365
-
366
- app.stage.addChild(screenshotsContainer);
367
- app.stage.addChild(highlightMaskContainer);
368
- app.stage.addChild(indicatorContainer);
369
-
370
- const canvas = app.view;
371
- canvas.addEventListener('pointermove', onPointerMove);
372
- canvas.addEventListener('pointerout', onPointerOut);
373
- canvas.addEventListener('pointerdown', onPointerTap);
374
- })(),
375
- );
376
- }, []);
377
-
378
- return <div className="timeline-canvas-wrapper" ref={domRef}></div>;
379
- };
380
-
381
- const Timeline = () => {
382
- const allTasks = useAllCurrentTasks();
383
- const wrapper = useRef<HTMLDivElement>(null);
384
- const setActiveTask = useExecutionDump((store) => store.setActiveTask);
385
- const activeTask = useExecutionDump((store) => store.activeTask);
386
- const hoverTask = useExecutionDump((store) => store.hoverTask);
387
- const setHoverTask = useExecutionDump((store) => store.setHoverTask);
388
- const setHoverPreviewConfig = useExecutionDump((store) => store.setHoverPreviewConfig);
389
-
390
- // should be first task time ?
391
- let startingTime = -1;
392
- let idCount = 1;
393
- const idTaskMap: Record<string, ExecutionTask> = {};
394
- const allScreenshots: TimelineItem[] = allTasks
395
- .reduce<(ExecutionRecorderItem & { id: string })[]>((acc, current) => {
396
- const recorders = current.recorder || [];
397
- recorders.forEach((item) => {
398
- if (startingTime === -1 || startingTime > item.ts) {
399
- startingTime = item.ts;
400
- }
401
- });
402
- if (current.timing?.start && (startingTime === -1 || startingTime > current.timing.start)) {
403
- startingTime = current.timing.start;
404
- }
405
- const recorderItemWithId = recorders.map((item) => {
406
- const idStr = `id_${idCount++}`;
407
- idTaskMap[idStr] = current;
408
- return {
409
- ...item,
410
- id: idStr,
411
- };
412
- });
413
- return acc.concat(recorderItemWithId || []);
414
- }, [])
415
- .filter((item) => {
416
- return item.screenshot;
417
- })
418
- .map((recorderItem) => {
419
- return {
420
- id: recorderItem.id,
421
- img: recorderItem.screenshot!,
422
- timeOffset: recorderItem.ts - startingTime,
423
- };
424
- })
425
- .sort((a, b) => a.timeOffset - b.timeOffset);
426
-
427
- const itemOnTap = (item: TimelineItem) => {
428
- const task = idTaskMap[item.id];
429
- if (task) {
430
- setActiveTask(task);
431
- }
432
- };
433
-
434
- const onHighlightItem = (param: HighlightParam) => {
435
- const { mouseX, item } = param;
436
- const refBounding = wrapper.current?.getBoundingClientRect();
437
- const task = idTaskMap[item.id];
438
- if (task) {
439
- setHoverTask(task);
440
- setHoverPreviewConfig({
441
- x: mouseX + (refBounding?.left || 0),
442
- y: (refBounding?.bottom || 1) - 1,
443
- });
444
- } else {
445
- setHoverTask(null);
446
- setHoverPreviewConfig(null);
447
- }
448
- };
449
-
450
- const unhighlight = () => {
451
- setHoverTask(null);
452
- setHoverPreviewConfig(null);
453
- };
454
-
455
- // overall left of wrapper
456
-
457
- const maskConfigForTask = (task?: ExecutionTask | null): HighlightMask | undefined => {
458
- if (!task) {
459
- return undefined;
460
- }
461
- return task.timing?.start && task.timing?.end
462
- ? {
463
- startMs: task.timing.start - startingTime || 0,
464
- endMs: task.timing.end - startingTime || 0,
465
- }
466
- : undefined;
467
- };
468
-
469
- const highlightMaskConfig = maskConfigForTask(activeTask);
470
- const hoverMaskConfig = maskConfigForTask(hoverTask);
471
-
472
- return (
473
- <div className="timeline-wrapper" ref={wrapper}>
474
- <TimelineWidget
475
- // key={dimensions.width}
476
- screenshots={allScreenshots}
477
- onTap={itemOnTap}
478
- onHighlight={onHighlightItem}
479
- onUnhighlight={unhighlight}
480
- highlightMask={highlightMaskConfig}
481
- hoverMask={hoverMaskConfig}
482
- />
483
- </div>
484
- );
485
- };
486
- export default Timeline;
package/src/global.d.ts DELETED
@@ -1,11 +0,0 @@
1
- declare module '*.svg' {
2
- export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
3
-
4
- const content: string;
5
- export default content;
6
- }
7
-
8
- declare module '*.svg?react' {
9
- const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
10
- export default ReactComponent;
11
- }
package/src/index.less DELETED
@@ -1,113 +0,0 @@
1
- @import './component/common.less';
2
-
3
- @layout-space: 22px;
4
-
5
- html,
6
- body {
7
- padding: 0;
8
- margin: 0;
9
- font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
10
- font-size: 14px;
11
- }
12
-
13
- // local debug
14
-
15
- :root {
16
- --modern-sidebar-width: 0 !important;
17
- --modern-aside-width: 0 !important;
18
- --modern-preview-padding:0 !important;
19
- }
20
-
21
- .modern-doc-layout,
22
- .modern-doc {
23
- width: 100% !important;
24
- margin: 0 !important;
25
- padding: 0 !important;
26
- height: 100vh;
27
- }
28
-
29
- .modern-sidebar,
30
- header.w-full {
31
- display: none !important;
32
- }
33
- .modern-doc-container{
34
- padding: 0 !important;
35
- }
36
-
37
- footer.mt-8{
38
- display: none;
39
- }
40
- // ----------
41
-
42
- .page-container {
43
- display: flex;
44
- flex-direction: column;
45
- height: 100%;
46
- color: #000;
47
- }
48
-
49
- .ant-layout {
50
- flex-grow: 1;
51
- height: 100%;
52
- }
53
-
54
- .main-right {
55
- display: flex;
56
- flex-direction: column;
57
- width: 100%;
58
- height: 100%;
59
- box-sizing: border-box;
60
- // padding: @layout-space;
61
-
62
- .main-content{
63
- display: flex;
64
- flex-direction: row;
65
- flex-grow: 1;
66
- overflow: hidden;
67
- background: @side-bg;
68
- }
69
-
70
- &.uploader-wrapper {
71
- box-sizing: border-box;
72
- margin: auto;
73
- max-width: 800px;
74
- flex-direction: column;
75
- justify-content: center;
76
-
77
- .uploader {
78
- width: 100%;
79
- }
80
-
81
- .demo-loader {
82
- width: 100%;
83
- text-align: center;
84
- margin-top: 10px;
85
- }
86
- }
87
-
88
- .main-canvas-container {
89
- flex-grow: 1;
90
- height: 100%;
91
- background: #F5F5F5;
92
- overflow-x: hidden;
93
- overflow-y: scroll;
94
- border-left: 1px solid @border-color;
95
- }
96
-
97
- .main-side {
98
- box-sizing: border-box;
99
- // margin-left: @layout-space;
100
- // margin: calc(@layout-space/2);
101
- // padding-left: @layout-padding;
102
- overflow-y: scroll;
103
-
104
- // flex-basis: 380px; /* Set the fixed width */
105
- // flex-grow: 0; /* Prevent it from growing */
106
- // flex-shrink: 0; /* Prevent it from shrinking */
107
- }
108
-
109
- .json-content {
110
- word-wrap: break-word;
111
- white-space: pre-wrap;
112
- }
113
- }