canvas_erd 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +3 -1
- data/lib/canvas_erd/cli.rb +4 -1
- data/lib/canvas_erd/highlighter.rb +57 -0
- data/lib/canvas_erd/model_details.rb +105 -0
- data/lib/canvas_erd/server.rb +69 -3
- data/lib/canvas_erd/source_files.rb +70 -0
- data/lib/canvas_erd/version.rb +1 -1
- data/lib/canvas_erd/web/app.js +595 -24
- data/lib/canvas_erd/web/document.js +131 -0
- data/lib/canvas_erd/web/index.html +62 -0
- data/lib/canvas_erd/web/styles.css +89 -2
- data/lib/canvas_erd.rb +3 -0
- metadata +26 -3
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
paragraph: Object.freeze({ fontFamily: "Arial", fontSize: 15, fontWeight: "normal", lineHeight: 1.25 }),
|
|
26
26
|
code: Object.freeze({ fontFamily: "Courier New", fontSize: 14, fontWeight: "normal", lineHeight: 1.2 })
|
|
27
27
|
});
|
|
28
|
+
const CODE_FONT_SIZES = Object.freeze({ small: 12, medium: 14, large: 18 });
|
|
28
29
|
const DEFAULT_TABLE_HEADER_COLOR = "#243b63";
|
|
29
30
|
const DEFAULT_TABLE_HEADER_COLORS = DEFAULT_FOREGROUND_COLORS;
|
|
30
31
|
const DEFAULT_ARROW_FORMATTING = Object.freeze({
|
|
@@ -305,6 +306,115 @@
|
|
|
305
306
|
};
|
|
306
307
|
}
|
|
307
308
|
|
|
309
|
+
function codeFontSize(block) {
|
|
310
|
+
return CODE_FONT_SIZES[block.size] || CODE_FONT_SIZES.medium;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function codeCanvasGeometry(block) {
|
|
314
|
+
const style = NOTE_PARAGRAPH_STYLES.code;
|
|
315
|
+
return {
|
|
316
|
+
left: block.x,
|
|
317
|
+
top: block.y,
|
|
318
|
+
width: block.width,
|
|
319
|
+
angle: block.angle ?? 0,
|
|
320
|
+
fontFamily: style.fontFamily,
|
|
321
|
+
fontSize: codeFontSize(block),
|
|
322
|
+
lineHeight: style.lineHeight
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function codeStateGeometry(object) {
|
|
327
|
+
return {
|
|
328
|
+
x: object.left,
|
|
329
|
+
y: object.top,
|
|
330
|
+
width: object.width * object.scaleX,
|
|
331
|
+
angle: object.angle,
|
|
332
|
+
code: object.text
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function codeTokenStyles(runs) {
|
|
337
|
+
const styles = {};
|
|
338
|
+
let line = 0;
|
|
339
|
+
let character = 0;
|
|
340
|
+
runs.forEach(([text, style]) => {
|
|
341
|
+
text.split("\n").forEach((segment, index) => {
|
|
342
|
+
if (index > 0) {
|
|
343
|
+
line += 1;
|
|
344
|
+
character = 0;
|
|
345
|
+
}
|
|
346
|
+
Array.from(segment).forEach(() => {
|
|
347
|
+
styles[line] = styles[line] || {};
|
|
348
|
+
styles[line][character] = { ...style };
|
|
349
|
+
character += 1;
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
return styles;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function sourceFromFields(path, startLine, endLine) {
|
|
357
|
+
const trimmed = String(path || "").trim();
|
|
358
|
+
if (!trimmed) return null;
|
|
359
|
+
const lineNumber = (value) => {
|
|
360
|
+
const number = Number.parseInt(value, 10);
|
|
361
|
+
return number > 0 ? number : null;
|
|
362
|
+
};
|
|
363
|
+
return { path: trimmed, startLine: lineNumber(startLine), endLine: lineNumber(endLine) };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function codeLineLabels(block, lineCount) {
|
|
367
|
+
if (block.source?.model) {
|
|
368
|
+
return Array.from({ length: lineCount }, (_, index) => block.lineNumbers?.[index] ?? null);
|
|
369
|
+
}
|
|
370
|
+
const first = block.source?.startLine || 1;
|
|
371
|
+
return Array.from({ length: lineCount }, (_, index) => first + index);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function codeGutterWidth(labels, fontSize) {
|
|
375
|
+
const digits = Math.max(1, ...labels.filter((label) => label !== null).map((label) => String(label).length));
|
|
376
|
+
return (digits + 2) * fontSize * 0.6;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function codeRowAt(rowHeights, y) {
|
|
380
|
+
let top = 0;
|
|
381
|
+
for (let index = 0; index < rowHeights.length; index += 1) {
|
|
382
|
+
if (y >= top && y < top + rowHeights[index]) return index;
|
|
383
|
+
top += rowHeights[index];
|
|
384
|
+
}
|
|
385
|
+
return -1;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function toggleHighlightedLine(lines = [], label) {
|
|
389
|
+
if (lines.includes(label)) return lines.filter((line) => line !== label);
|
|
390
|
+
return [...lines, label].sort((first, second) => first - second);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function highlightLineRange(lines = [], labels, anchor, label) {
|
|
394
|
+
const start = labels.indexOf(anchor);
|
|
395
|
+
const end = labels.indexOf(label);
|
|
396
|
+
if (start < 0 || end < 0) return toggleHighlightedLine(lines, label);
|
|
397
|
+
|
|
398
|
+
const range = labels.slice(Math.min(start, end), Math.max(start, end) + 1).filter((line) => line !== null);
|
|
399
|
+
if (!lines.includes(anchor)) return lines.filter((line) => !range.includes(line));
|
|
400
|
+
return [...new Set([...lines, ...range])].sort((first, second) => first - second);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function modelDetailBlock(codeBlocks, entityId, detail) {
|
|
404
|
+
return codeBlocks.find((block) => block.source?.model === entityId && block.source.detail === detail) || null;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function modelDetailOrigin(tablePosition) {
|
|
408
|
+
return { x: tablePosition.x + CARD_WIDTH + 80, y: tablePosition.y };
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function sourceReferenceLabel(source) {
|
|
412
|
+
if (source.model) return `${source.model} ${source.detail}`;
|
|
413
|
+
if (!source.startLine && !source.endLine) return source.path;
|
|
414
|
+
if (source.startLine === source.endLine) return `${source.path}:${source.startLine}`;
|
|
415
|
+
return `${source.path}:${source.startLine || 1}-${source.endLine || "end"}`;
|
|
416
|
+
}
|
|
417
|
+
|
|
308
418
|
function erdFilename(value) {
|
|
309
419
|
const basename = String(value).trim().replace(/(?:\.erd)?\.png$/i, "");
|
|
310
420
|
return `${basename || "diagram"}.erd.png`;
|
|
@@ -330,6 +440,7 @@
|
|
|
330
440
|
|
|
331
441
|
return {
|
|
332
442
|
n: "addNote",
|
|
443
|
+
c: "addCode",
|
|
333
444
|
a: "arrow",
|
|
334
445
|
t: "toggleTables",
|
|
335
446
|
l: "layoutTables",
|
|
@@ -398,6 +509,7 @@
|
|
|
398
509
|
function arrowAttachment(target) {
|
|
399
510
|
if (target?.canvasErdType === "entity") return { type: "entity", id: target.entityId };
|
|
400
511
|
if (target?.canvasErdType === "note") return { type: "note", id: target.noteId };
|
|
512
|
+
if (target?.canvasErdType === "code") return { type: "code", id: target.codeBlockId };
|
|
401
513
|
return null;
|
|
402
514
|
}
|
|
403
515
|
|
|
@@ -482,6 +594,7 @@
|
|
|
482
594
|
tableHeaderColors: {},
|
|
483
595
|
frames: [],
|
|
484
596
|
notes: [],
|
|
597
|
+
codeBlocks: [],
|
|
485
598
|
arrows: []
|
|
486
599
|
};
|
|
487
600
|
}
|
|
@@ -544,6 +657,10 @@
|
|
|
544
657
|
tableHeaderColors: { ...(state.tableHeaderColors || {}) },
|
|
545
658
|
frames: (state.frames || []).map((frame) => ({ ...frame })),
|
|
546
659
|
notes: state.notes.map((note) => ({ ...note })),
|
|
660
|
+
codeBlocks: (state.codeBlocks || []).map((block) => ({
|
|
661
|
+
...block,
|
|
662
|
+
source: block.source ? { ...block.source } : null
|
|
663
|
+
})),
|
|
547
664
|
arrows: (state.arrows || []).map((arrow) => ({
|
|
548
665
|
...arrow,
|
|
549
666
|
start: { ...arrow.start, attachment: arrow.start.attachment ? { ...arrow.start.attachment } : null },
|
|
@@ -834,6 +951,20 @@
|
|
|
834
951
|
frameLabelCanvasStyle,
|
|
835
952
|
noteCanvasGeometry,
|
|
836
953
|
noteStateGeometry,
|
|
954
|
+
CODE_FONT_SIZES,
|
|
955
|
+
codeFontSize,
|
|
956
|
+
codeCanvasGeometry,
|
|
957
|
+
codeStateGeometry,
|
|
958
|
+
codeTokenStyles,
|
|
959
|
+
sourceFromFields,
|
|
960
|
+
sourceReferenceLabel,
|
|
961
|
+
codeLineLabels,
|
|
962
|
+
codeGutterWidth,
|
|
963
|
+
codeRowAt,
|
|
964
|
+
toggleHighlightedLine,
|
|
965
|
+
highlightLineRange,
|
|
966
|
+
modelDetailBlock,
|
|
967
|
+
modelDetailOrigin,
|
|
837
968
|
erdFilename,
|
|
838
969
|
diagramName,
|
|
839
970
|
confirmDiscardChanges,
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
<div><dt>New</dt><dd><kbd>⌘/Ctrl</kbd> <kbd>N</kbd></dd></div>
|
|
67
67
|
<div><dt>Save</dt><dd><kbd>⌘/Ctrl</kbd> <kbd>S</kbd></dd></div>
|
|
68
68
|
<div><dt>Add note at cursor</dt><dd><kbd>N</kbd></dd></div>
|
|
69
|
+
<div><dt>Add code at cursor</dt><dd><kbd>C</kbd></dd></div>
|
|
69
70
|
<div><dt>Bold note</dt><dd><kbd>⌘/Ctrl</kbd> <kbd>B</kbd></dd></div>
|
|
70
71
|
<div><dt>Italic note</dt><dd><kbd>⌘/Ctrl</kbd> <kbd>I</kbd></dd></div>
|
|
71
72
|
<div><dt>Underline note</dt><dd><kbd>⌘/Ctrl</kbd> <kbd>U</kbd></dd></div>
|
|
@@ -225,6 +226,61 @@
|
|
|
225
226
|
</select>
|
|
226
227
|
</label>
|
|
227
228
|
</div>
|
|
229
|
+
<div id="code-formatting" class="code-formatting" role="toolbar" aria-label="Code formatting" hidden>
|
|
230
|
+
<label class="note-format-field">
|
|
231
|
+
<span>Language</span>
|
|
232
|
+
<select id="code-language" aria-label="Code language"></select>
|
|
233
|
+
</label>
|
|
234
|
+
<label class="note-format-field">
|
|
235
|
+
<span>Size</span>
|
|
236
|
+
<select id="code-size" aria-label="Code font size">
|
|
237
|
+
<option value="small">Small</option>
|
|
238
|
+
<option value="medium" selected>Medium</option>
|
|
239
|
+
<option value="large">Large</option>
|
|
240
|
+
</select>
|
|
241
|
+
</label>
|
|
242
|
+
<button id="code-line-numbers"class="format-button" type="button" aria-label="Line numbers" title="Line numbers" aria-pressed="false">#</button>
|
|
243
|
+
<span id="code-source" class="code-source" hidden></span>
|
|
244
|
+
<div id="code-source-fields" class="code-source-fields" hidden>
|
|
245
|
+
<label class="note-format-field">
|
|
246
|
+
<span>Path</span>
|
|
247
|
+
<input id="code-source-path" class="source-path-input" type="text" list="source-file-paths" autocomplete="off" aria-label="Source file path">
|
|
248
|
+
</label>
|
|
249
|
+
<label class="note-format-field">
|
|
250
|
+
<span>Lines</span>
|
|
251
|
+
<input id="code-source-start" class="line-input" type="number" min="1" placeholder="1" aria-label="Start line">
|
|
252
|
+
</label>
|
|
253
|
+
<label class="note-format-field">
|
|
254
|
+
<span>to</span>
|
|
255
|
+
<input id="code-source-end" class="line-input" type="number" min="1" placeholder="end" aria-label="End line">
|
|
256
|
+
</label>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
<datalist id="source-file-paths"></datalist>
|
|
260
|
+
<dialog id="source-dialog" class="source-dialog" aria-labelledby="source-dialog-title">
|
|
261
|
+
<form id="source-form">
|
|
262
|
+
<h2 id="source-dialog-title">Add source file</h2>
|
|
263
|
+
<label class="source-field">
|
|
264
|
+
<span>Path</span>
|
|
265
|
+
<input id="source-path" class="source-path-input" type="text" list="source-file-paths" autocomplete="off" placeholder="app/models/book.rb" required>
|
|
266
|
+
</label>
|
|
267
|
+
<div class="source-lines">
|
|
268
|
+
<label class="source-field">
|
|
269
|
+
<span>Start line</span>
|
|
270
|
+
<input id="source-start" class="line-input" type="number" min="1" placeholder="1">
|
|
271
|
+
</label>
|
|
272
|
+
<label class="source-field">
|
|
273
|
+
<span>End line</span>
|
|
274
|
+
<input id="source-end" class="line-input" type="number" min="1" placeholder="end">
|
|
275
|
+
</label>
|
|
276
|
+
</div>
|
|
277
|
+
<p id="source-error" class="source-error" role="alert" hidden></p>
|
|
278
|
+
<div class="source-actions">
|
|
279
|
+
<button id="source-cancel" type="button">Cancel</button>
|
|
280
|
+
<button id="source-submit" type="submit">Add</button>
|
|
281
|
+
</div>
|
|
282
|
+
</form>
|
|
283
|
+
</dialog>
|
|
228
284
|
<div class="canvas-tools" aria-label="Canvas tools">
|
|
229
285
|
<button id="toggle-tables" class="icon-button" type="button" aria-label="Show tables" title="Show tables (T)" aria-expanded="false">
|
|
230
286
|
<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" color="#000000" aria-hidden="true" focusable="false"><path d="M3 20.4V3.6C3 3.26863 3.26863 3 3.6 3H20.4C20.7314 3 21 3.26863 21 3.6V20.4C21 20.7314 20.7314 21 20.4 21H3.6C3.26863 21 3 20.7314 3 20.4Z" stroke="#000000" stroke-width="1.5"></path><path d="M3 16.5H21" stroke="#000000" stroke-width="1.5"></path><path d="M3 12H21" stroke="#000000" stroke-width="1.5"></path><path d="M21 7.5H3" stroke="#000000" stroke-width="1.5"></path><path d="M12 21V3" stroke="#000000" stroke-width="1.5"></path></svg>
|
|
@@ -238,6 +294,12 @@
|
|
|
238
294
|
<button id="add-note" class="icon-button" type="button" aria-label="Add note" title="Add note (N)">
|
|
239
295
|
<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" color="#000000" aria-hidden="true" focusable="false"><path d="M12 8L12 16M12 8H8M12 8H16" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M21 13.5V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V13.5M21 10.5V5C21 3.89543 20.1046 3 19 3H5C3.89543 3 3 3.89543 3 5V10.5" stroke="#000000" stroke-width="1.5" stroke-linejoin="round"></path><path d="M19.5 13.5V10.5H22.5V13.5H19.5Z" stroke="#000000" stroke-width="1.5" stroke-linejoin="round"></path><path d="M1.5 13.5V10.5H4.5V13.5H1.5Z" stroke="#000000" stroke-width="1.5" stroke-linejoin="round"></path></svg>
|
|
240
296
|
</button>
|
|
297
|
+
<button id="add-code" class="icon-button" type="button" aria-label="Add code" title="Add code (C)">
|
|
298
|
+
<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" color="#000000" aria-hidden="true" focusable="false"><path d="M13.5 6L10 18.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M6.5 8.5L3 12L6.5 15.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M17.5 8.5L21 12L17.5 15.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
|
299
|
+
</button>
|
|
300
|
+
<button id="add-source" class="icon-button" type="button" aria-label="Add source file" title="Add source file">
|
|
301
|
+
<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" color="#000000" aria-hidden="true" focusable="false"><path d="M4 21.4V2.6C4 2.26863 4.26863 2 4.6 2H16.2515C16.4106 2 16.5632 2.06321 16.6757 2.17574L19.8243 5.32426C19.9368 5.43679 20 5.5894 20 5.74853V21.4C20 21.7314 19.7314 22 19.4 22H4.6C4.26863 22 4 21.7314 4 21.4Z" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 10L16 10" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 18L16 18" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 14L12 14" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M16 2V5.4C16 5.73137 16.2686 6 16.6 6H20" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
|
302
|
+
</button>
|
|
241
303
|
<button id="add-arrow" class="icon-button" type="button" aria-label="Arrow tool" title="Arrow tool (A) · Select an arrow to edit endpoints · Hold Ctrl for a free endpoint" aria-pressed="false">
|
|
242
304
|
<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" color="#000000" aria-hidden="true" focusable="false"><path d="M6.00005 19L19 5.99996M19 5.99996V18.48M19 5.99996H6.52005" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
|
243
305
|
</button>
|
|
@@ -324,7 +324,8 @@ select:focus-visible {
|
|
|
324
324
|
.note-formatting,
|
|
325
325
|
.table-formatting,
|
|
326
326
|
.arrow-formatting,
|
|
327
|
-
.frame-formatting
|
|
327
|
+
.frame-formatting,
|
|
328
|
+
.code-formatting {
|
|
328
329
|
position: absolute;
|
|
329
330
|
bottom: 4rem;
|
|
330
331
|
left: 50%;
|
|
@@ -515,7 +516,9 @@ select:focus-visible {
|
|
|
515
516
|
padding: 0.2rem 0.35rem;
|
|
516
517
|
}
|
|
517
518
|
|
|
518
|
-
#arrow-stroke-width
|
|
519
|
+
#arrow-stroke-width,
|
|
520
|
+
.source-path-input,
|
|
521
|
+
.line-input {
|
|
519
522
|
width: 4rem;
|
|
520
523
|
min-height: 1.9rem;
|
|
521
524
|
border: 1px solid #cbd3df;
|
|
@@ -645,3 +648,87 @@ kbd {
|
|
|
645
648
|
border-color: #fecaca;
|
|
646
649
|
background: #fff7f7;
|
|
647
650
|
}
|
|
651
|
+
|
|
652
|
+
.code-source {
|
|
653
|
+
color: #526277;
|
|
654
|
+
padding: 0 0.35rem;
|
|
655
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
656
|
+
font-size: 0.72rem;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
.detail-toggle {
|
|
660
|
+
min-height: 1.4rem;
|
|
661
|
+
margin-left: auto;
|
|
662
|
+
border-radius: 999px;
|
|
663
|
+
color: #526277;
|
|
664
|
+
padding: 0 0.5rem;
|
|
665
|
+
font-size: 0.7rem;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.detail-toggle[aria-pressed="true"] {
|
|
669
|
+
border-color: #2563eb;
|
|
670
|
+
color: #1d4ed8;
|
|
671
|
+
background: #eff6ff;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.code-source-fields {
|
|
675
|
+
display: flex;
|
|
676
|
+
align-items: center;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
.note-format-field .source-path-input {
|
|
680
|
+
width: 18rem;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
.source-dialog {
|
|
684
|
+
width: min(32rem, calc(100% - 2rem));
|
|
685
|
+
border: 1px solid rgba(203, 213, 225, 0.9);
|
|
686
|
+
border-radius: 0.75rem;
|
|
687
|
+
color: #263447;
|
|
688
|
+
padding: 1rem;
|
|
689
|
+
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.2);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
.source-dialog::backdrop {
|
|
693
|
+
background: rgba(15, 23, 42, 0.2);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.source-dialog h2 {
|
|
697
|
+
margin: 0 0 0.8rem;
|
|
698
|
+
color: #172554;
|
|
699
|
+
font-size: 0.95rem;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
.source-field {
|
|
703
|
+
display: flex;
|
|
704
|
+
flex-direction: column;
|
|
705
|
+
gap: 0.3rem;
|
|
706
|
+
color: #526277;
|
|
707
|
+
font-size: 0.75rem;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.source-dialog .source-path-input,
|
|
711
|
+
.source-dialog .line-input {
|
|
712
|
+
width: 100%;
|
|
713
|
+
min-height: 2.25rem;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
.source-lines {
|
|
717
|
+
display: grid;
|
|
718
|
+
grid-template-columns: 1fr 1fr;
|
|
719
|
+
gap: 0.75rem;
|
|
720
|
+
margin-top: 0.75rem;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.source-error {
|
|
724
|
+
margin: 0.75rem 0 0;
|
|
725
|
+
color: #b91c1c;
|
|
726
|
+
font-size: 0.8rem;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
.source-actions {
|
|
730
|
+
display: flex;
|
|
731
|
+
justify-content: flex-end;
|
|
732
|
+
gap: 0.5rem;
|
|
733
|
+
margin-top: 1rem;
|
|
734
|
+
}
|
data/lib/canvas_erd.rb
CHANGED
|
@@ -5,6 +5,9 @@ require "canvas_erd/diagram"
|
|
|
5
5
|
require "canvas_erd/schema_provider"
|
|
6
6
|
require "canvas_erd/png_document"
|
|
7
7
|
require "canvas_erd/diagram_store"
|
|
8
|
+
require "canvas_erd/highlighter"
|
|
9
|
+
require "canvas_erd/source_files"
|
|
10
|
+
require "canvas_erd/model_details"
|
|
8
11
|
require "canvas_erd/application_loader"
|
|
9
12
|
require "canvas_erd/browser"
|
|
10
13
|
require "canvas_erd/server"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: canvas_erd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marc Heiligers
|
|
@@ -43,6 +43,26 @@ dependencies:
|
|
|
43
43
|
- - "<"
|
|
44
44
|
- !ruby/object:Gem::Version
|
|
45
45
|
version: '4'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: rouge
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '4.0'
|
|
53
|
+
- - "<"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '6'
|
|
56
|
+
type: :runtime
|
|
57
|
+
prerelease: false
|
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '4.0'
|
|
63
|
+
- - "<"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '6'
|
|
46
66
|
- !ruby/object:Gem::Dependency
|
|
47
67
|
name: minitest
|
|
48
68
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -110,9 +130,12 @@ files:
|
|
|
110
130
|
- lib/canvas_erd/cli.rb
|
|
111
131
|
- lib/canvas_erd/diagram.rb
|
|
112
132
|
- lib/canvas_erd/diagram_store.rb
|
|
133
|
+
- lib/canvas_erd/highlighter.rb
|
|
134
|
+
- lib/canvas_erd/model_details.rb
|
|
113
135
|
- lib/canvas_erd/png_document.rb
|
|
114
136
|
- lib/canvas_erd/schema_provider.rb
|
|
115
137
|
- lib/canvas_erd/server.rb
|
|
138
|
+
- lib/canvas_erd/source_files.rb
|
|
116
139
|
- lib/canvas_erd/version.rb
|
|
117
140
|
- lib/canvas_erd/web/app.js
|
|
118
141
|
- lib/canvas_erd/web/document.js
|
|
@@ -142,14 +165,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
142
165
|
requirements:
|
|
143
166
|
- - ">="
|
|
144
167
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: '3.
|
|
168
|
+
version: '3.3'
|
|
146
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
170
|
requirements:
|
|
148
171
|
- - ">="
|
|
149
172
|
- !ruby/object:Gem::Version
|
|
150
173
|
version: '0'
|
|
151
174
|
requirements: []
|
|
152
|
-
rubygems_version: 4.0.
|
|
175
|
+
rubygems_version: 4.0.20
|
|
153
176
|
specification_version: 4
|
|
154
177
|
summary: Edit Rails ERD diagrams on an interactive canvas
|
|
155
178
|
test_files: []
|