@sd-angular/core 19.0.0-beta.2 → 19.0.0-beta.4
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.
- package/components/document-builder/src/document-builder.config.d.ts +21 -0
- package/components/document-builder/src/document-builder.utils.d.ts +10 -0
- package/fesm2022/sd-angular-core-components-document-builder.mjs +426 -154
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +5 -5
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-workflow.mjs +23 -23
- package/fesm2022/sd-angular-core-components-workflow.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs +22 -2
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date.mjs +13 -3
- package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs +17 -3
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input.mjs +18 -6
- package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-radio.mjs +15 -2
- package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +13 -2
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-textarea.mjs +9 -2
- package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-auth.mjs +137 -0
- package/fesm2022/sd-angular-core-modules-auth.mjs.map +1 -0
- package/fesm2022/sd-angular-core-modules-layout.mjs +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules.mjs +1 -0
- package/fesm2022/sd-angular-core-modules.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +5 -8
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs +66 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs +12 -3
- package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
- package/forms/autocomplete/src/autocomplete.component.d.ts +5 -1
- package/forms/date/src/date.component.d.ts +4 -1
- package/forms/input/src/input.component.d.ts +6 -4
- package/forms/input-number/src/input-number.component.d.ts +4 -1
- package/forms/radio/src/radio.component.d.ts +5 -1
- package/forms/select/src/select.component.d.ts +5 -1
- package/forms/textarea/src/textarea.component.d.ts +3 -1
- package/modules/auth/configurations/auth.configuration.d.ts +19 -0
- package/modules/auth/configurations/index.d.ts +1 -0
- package/modules/auth/guards/auth.guard.d.ts +11 -0
- package/modules/auth/guards/index.d.ts +2 -0
- package/modules/auth/guards/portal.guard.d.ts +11 -0
- package/modules/auth/index.d.ts +3 -0
- package/modules/auth/services/auth.model.d.ts +8 -0
- package/modules/auth/services/auth.service.d.ts +17 -0
- package/modules/auth/services/index.d.ts +2 -0
- package/modules/index.d.ts +1 -0
- package/package.json +78 -74
- package/utilities/extensions/index.d.ts +1 -0
- package/utilities/extensions/src/color.extension.d.ts +20 -0
- package/utilities/models/src/maybe-async.model.d.ts +1 -0
- package/utilities/models/src/pattern.model.d.ts +2 -2
|
@@ -4,9 +4,8 @@ import { CommonModule } from '@angular/common';
|
|
|
4
4
|
import * as i1 from '@ckeditor/ckeditor5-angular';
|
|
5
5
|
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
|
|
6
6
|
import { Plugin, ButtonView, ClassicEditor, Essentials, Paragraph, Bold, Italic, Underline, FontSize, FontColor, FontBackgroundColor, Alignment, Widget, toWidget, GeneralHtmlSupport, FontFamily, Heading, List, Table, TableToolbar, TableProperties, TableCellProperties, TableColumnResize, PasteFromOffice, PageBreak, Undo, Subscript, Superscript, Image, ImageUpload, ImageToolbar, ImageCaption, ImageResize, ImageStyle } from 'ckeditor5';
|
|
7
|
-
import { SdResolveMaybeAsync } from '@sd-angular/core/utilities';
|
|
8
|
-
import { SdUtilities } from '@sd-angular/core/utilities/extensions';
|
|
9
7
|
import { Subscription, Subject, throttleTime } from 'rxjs';
|
|
8
|
+
import { SdResolveMaybeAsync, hslToHex, rgbToHex, SdUtilities } from '@sd-angular/core/utilities';
|
|
10
9
|
|
|
11
10
|
class PageNumberPlugin extends Plugin {
|
|
12
11
|
init() {
|
|
@@ -208,10 +207,15 @@ class CommentPlugin extends Plugin {
|
|
|
208
207
|
const editor = this.editor;
|
|
209
208
|
// --- 1. CONVERSION: MODEL MARKER -> VIEW CSS ---
|
|
210
209
|
// Biến Marker thành Highlight màu vàng
|
|
211
|
-
editor.conversion.for('
|
|
212
|
-
model: 'comment',
|
|
213
|
-
view: {
|
|
214
|
-
|
|
210
|
+
editor.conversion.for('downcast').markerToHighlight({
|
|
211
|
+
model: 'comment',
|
|
212
|
+
view: data => {
|
|
213
|
+
return {
|
|
214
|
+
classes: 'ck-comment-marker',
|
|
215
|
+
attributes: {
|
|
216
|
+
'data-comment-id': data.markerName,
|
|
217
|
+
},
|
|
218
|
+
};
|
|
215
219
|
},
|
|
216
220
|
});
|
|
217
221
|
// --- 3. ĐĂNG KÝ UI COMPONENT: 'addCommentBtn' ---
|
|
@@ -263,6 +267,29 @@ class CommentPlugin extends Plugin {
|
|
|
263
267
|
});
|
|
264
268
|
return view;
|
|
265
269
|
});
|
|
270
|
+
// 8. Xử lý sự kiện Copy (Clipboard Output)
|
|
271
|
+
this.listenTo(editor.editing.view.document, 'clipboardOutput', (evt, data) => {
|
|
272
|
+
const content = data.content;
|
|
273
|
+
editor.editing.view.change(writer => {
|
|
274
|
+
// Tạo range bao quanh toàn bộ nội dung clipboard
|
|
275
|
+
const range = writer.createRangeIn(content);
|
|
276
|
+
// Mảng chứa các item cần xử lý
|
|
277
|
+
const itemsToClean = [];
|
|
278
|
+
// 1. Duyệt qua để tìm các thẻ có class ck-comment-marker
|
|
279
|
+
for (const item of range.getItems()) {
|
|
280
|
+
if (item.is('element') && item.hasClass('ck-comment-marker')) {
|
|
281
|
+
itemsToClean.push(item);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// 2. Thực hiện xóa Class và Attribute
|
|
285
|
+
for (const item of itemsToClean) {
|
|
286
|
+
// Xóa class 'ck-comment-marker'
|
|
287
|
+
writer.removeClass('ck-comment-marker', item);
|
|
288
|
+
// Xóa thuộc tính 'data-comment-id'
|
|
289
|
+
writer.removeAttribute('data-comment-id', item);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
});
|
|
266
293
|
}
|
|
267
294
|
}
|
|
268
295
|
|
|
@@ -279,6 +306,9 @@ class VariablePlugin extends Plugin {
|
|
|
279
306
|
// 1. Định nghĩa Schema (Model)
|
|
280
307
|
schema.register('variable', {
|
|
281
308
|
inheritAllFrom: '$inlineObject',
|
|
309
|
+
allowWhere: '$text',
|
|
310
|
+
isInline: true,
|
|
311
|
+
isObject: true,
|
|
282
312
|
allowAttributes: ['id', 'value', 'display', 'data'],
|
|
283
313
|
});
|
|
284
314
|
// 2. Conversion: Model -> View (Hiển thị ra HTML)
|
|
@@ -310,12 +340,6 @@ class VariablePlugin extends Plugin {
|
|
|
310
340
|
classes: 'variable-widget',
|
|
311
341
|
},
|
|
312
342
|
model: (viewElement, { writer: modelWriter }) => {
|
|
313
|
-
// Lấy text bên trong làm label, bỏ dấu {{ }}
|
|
314
|
-
// const textNode = viewElement.getChild(0);
|
|
315
|
-
// let label = '';
|
|
316
|
-
// if (textNode && textNode.is('$text')) {
|
|
317
|
-
// label = textNode.data.replace(/{{|}}/g, '');
|
|
318
|
-
// }
|
|
319
343
|
const dataJson = viewElement.getAttribute('data-json');
|
|
320
344
|
let parsedData = null;
|
|
321
345
|
try {
|
|
@@ -399,30 +423,122 @@ class VariablePlugin extends Plugin {
|
|
|
399
423
|
});
|
|
400
424
|
}
|
|
401
425
|
});
|
|
402
|
-
//
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
//
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
+
// 5. Lắng nghe sự kiện bàn phím
|
|
427
|
+
let isNavigating = false;
|
|
428
|
+
this.editor.editing.view.document.on('keydown', (evt, data) => {
|
|
429
|
+
// Mã phím mũi tên: 37 (Left), 38 (Up), 39 (Right), 40 (Down)
|
|
430
|
+
const isArrowKey = data.keyCode >= 37 && data.keyCode <= 40;
|
|
431
|
+
if (isArrowKey) {
|
|
432
|
+
isNavigating = true;
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
isNavigating = false;
|
|
436
|
+
}
|
|
437
|
+
}, { priority: 'high' });
|
|
438
|
+
// 6. Lắng nghe sự kiện Click chuột
|
|
439
|
+
this.editor.editing.view.document.on('mousedown', () => {
|
|
440
|
+
isNavigating = true;
|
|
441
|
+
});
|
|
442
|
+
this.listenTo(editor.model.document.selection, 'change:range', () => {
|
|
443
|
+
// Nếu không phải là hành động click hoặc mũi tên thì thoát hàm.
|
|
444
|
+
if (!isNavigating) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const model = editor.model;
|
|
448
|
+
const selection = model.document.selection;
|
|
449
|
+
if (!selection.isCollapsed)
|
|
450
|
+
return;
|
|
451
|
+
const position = selection.getFirstPosition();
|
|
452
|
+
const nodeBefore = position?.nodeBefore;
|
|
453
|
+
if (!position)
|
|
454
|
+
return;
|
|
455
|
+
// Kiểm tra: Node đứng trước con trỏ là variable
|
|
456
|
+
if (nodeBefore && nodeBefore.is('element', 'variable')) {
|
|
457
|
+
// Lấy node ngay sau variable để kiểm tra
|
|
458
|
+
const nextNode = nodeBefore.nextSibling;
|
|
459
|
+
// Logic: Nếu phía sau KHÔNG CÓ GÌ hoặc KHÔNG PHẢI LÀ TEXT
|
|
460
|
+
if (!nextNode || !nextNode.is('$text')) {
|
|
461
|
+
model.change(writer => {
|
|
462
|
+
// Chèn thêm con trỏ variable
|
|
463
|
+
writer.insertText('\u00A0', nodeBefore, 'after');
|
|
464
|
+
// Lấy vị trí ngay sau variable (lúc này đang là đầu của text node mới)
|
|
465
|
+
const posAfterVariable = writer.createPositionAfter(nodeBefore);
|
|
466
|
+
// Dịch chuyển vị trí đó sang phải 1 đơn vị (bỏ qua ký tự vừa thêm)
|
|
467
|
+
const targetPos = posAfterVariable.getShiftedBy(1);
|
|
468
|
+
// 3. Đặt con trỏ vào vị trí đã tính toán
|
|
469
|
+
writer.setSelection(targetPos);
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
// 7. Handle xóa variable
|
|
475
|
+
this.editor.editing.view.document.on('keydown', (evt, data) => {
|
|
476
|
+
// Mã phím 8 là Backspace, 46 là Delete
|
|
477
|
+
const btnBackspace = data.keyCode === 8;
|
|
478
|
+
const btnDelete = data.keyCode === 46;
|
|
479
|
+
if (btnBackspace || btnDelete) {
|
|
480
|
+
const selection = editor.model.document.selection;
|
|
481
|
+
const model = editor.model;
|
|
482
|
+
// CASE 1: Nếu con trỏ đang nhấp nháy (Collapsed)
|
|
483
|
+
if (selection.isCollapsed) {
|
|
484
|
+
const position = selection.getFirstPosition();
|
|
485
|
+
// Với Backspace ta kiểm tra nodeBefore, với Delete ta kiểm tra nodeAfter
|
|
486
|
+
const targetNode = data.keyCode === 8 ? position?.nodeBefore : position?.nodeAfter;
|
|
487
|
+
if (targetNode && targetNode.is('element', 'variable')) {
|
|
488
|
+
data.preventDefault();
|
|
489
|
+
evt.stop();
|
|
490
|
+
model.change(writer => {
|
|
491
|
+
// Chọn bao quanh Variable đó
|
|
492
|
+
writer.setSelection(targetNode, 'on');
|
|
493
|
+
});
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// CASE 2: Nếu đang có một vùng chọn (đã được highlight từ lần bấm trước)
|
|
498
|
+
else {
|
|
499
|
+
const selectedElement = selection.getSelectedElement();
|
|
500
|
+
// Nếu phần tử đang được chọn chính là variable
|
|
501
|
+
if (selectedElement && selectedElement.is('element', 'variable')) {
|
|
502
|
+
// Cho phép hành động mặc định diễn ra (CKEditor sẽ tự xóa phần tử đang được chọn)
|
|
503
|
+
// Hoặc chủ động xóa để chắc chắn:
|
|
504
|
+
data.preventDefault();
|
|
505
|
+
evt.stop();
|
|
506
|
+
model.change(writer => {
|
|
507
|
+
writer.remove(selectedElement);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}, { priority: 'highest' });
|
|
513
|
+
// 8. Xử lý sự kiện Copy (Clipboard Output)
|
|
514
|
+
// Khi copy, thay thế variable bằng text
|
|
515
|
+
this.listenTo(editor.editing.view.document, 'clipboardOutput', (evt, data) => {
|
|
516
|
+
const content = data.content;
|
|
517
|
+
editor.editing.view.change(writer => {
|
|
518
|
+
// Tạo range bao quanh toàn bộ nội dung clipboard
|
|
519
|
+
const range = writer.createRangeIn(content);
|
|
520
|
+
const itemsToReplace = [];
|
|
521
|
+
// Duyệt qua tất cả các phần tử trong clipboard để tìm variable
|
|
522
|
+
for (const item of range.getItems()) {
|
|
523
|
+
// Kiểm tra đúng là thẻ span và có class variable-widget
|
|
524
|
+
if (item.is('element', 'span') && item.hasClass('variable-widget')) {
|
|
525
|
+
itemsToReplace.push(item);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
// Thay thế variable bằng text
|
|
529
|
+
for (const item of itemsToReplace) {
|
|
530
|
+
const displayText = item.getAttribute('data-display');
|
|
531
|
+
if (displayText) {
|
|
532
|
+
// Tạo một node text thuần túy
|
|
533
|
+
const textNode = writer.createText(`{{${displayText}}}`);
|
|
534
|
+
// Chèn text node vào ngay trước widget cũ
|
|
535
|
+
writer.insert(writer.createPositionBefore(item), textNode);
|
|
536
|
+
// Xóa widget cũ đi
|
|
537
|
+
writer.remove(item);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
});
|
|
426
542
|
}
|
|
427
543
|
#isSdDocumentBuilderVariableResult = (obj) => {
|
|
428
544
|
return (obj !== null &&
|
|
@@ -537,8 +653,203 @@ class Base64UploadAdapter {
|
|
|
537
653
|
}
|
|
538
654
|
}
|
|
539
655
|
|
|
656
|
+
/**
|
|
657
|
+
* Cấu hình màu cho Document Builder
|
|
658
|
+
* Bảng màu tập trung và cấu hình cho việc lựa chọn màu nhất quán
|
|
659
|
+
*/
|
|
660
|
+
/**
|
|
661
|
+
* Trả về bảng màu chung được sử dụng trong tất cả tính năng của document builder
|
|
662
|
+
* @returns Mảng các tùy chọn màu được định sẵn với giá trị hex và label
|
|
663
|
+
*/
|
|
664
|
+
function getPresetColors() {
|
|
665
|
+
return [
|
|
666
|
+
{ color: '#000000', label: 'Black' },
|
|
667
|
+
{ color: '#4D4D4D', label: 'Dim grey' },
|
|
668
|
+
{ color: '#999999', label: 'Grey' },
|
|
669
|
+
{ color: '#E6E6E6', label: 'Light grey' },
|
|
670
|
+
{ color: '#FFFFFF', label: 'White' },
|
|
671
|
+
{ color: '#E64D4D', label: 'Red' },
|
|
672
|
+
{ color: '#E6994D', label: 'Orange' },
|
|
673
|
+
{ color: '#E6E64D', label: 'Yellow' },
|
|
674
|
+
{ color: '#99E64D', label: 'Light green' },
|
|
675
|
+
{ color: '#4DE64D', label: 'Green' },
|
|
676
|
+
{ color: '#4DE699', label: 'Aquamarine' },
|
|
677
|
+
{ color: '#4DE6E6', label: 'Turquoise' },
|
|
678
|
+
{ color: '#4D99E6', label: 'Light blue' },
|
|
679
|
+
{ color: '#4D4DE6', label: 'Blue' },
|
|
680
|
+
{ color: '#994DE6', label: 'Purple' },
|
|
681
|
+
];
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Trả về cấu hình bộ chọn màu với định dạng hex
|
|
685
|
+
* @returns Đối tượng cấu hình bộ chọn màu
|
|
686
|
+
*/
|
|
687
|
+
function getColorPickerConfig() {
|
|
688
|
+
return {
|
|
689
|
+
format: 'hex',
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Trả về cấu hình kích thước font cho document builder
|
|
694
|
+
* @returns Mảng các tùy chọn kích thước font được định sẵn
|
|
695
|
+
*/
|
|
696
|
+
function getFontSizeOptions() {
|
|
697
|
+
return [
|
|
698
|
+
{
|
|
699
|
+
title: '9',
|
|
700
|
+
model: '9pt',
|
|
701
|
+
view: {
|
|
702
|
+
name: 'span',
|
|
703
|
+
styles: { 'font-size': '9pt' },
|
|
704
|
+
priority: 7,
|
|
705
|
+
},
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
title: '10',
|
|
709
|
+
model: '10pt',
|
|
710
|
+
view: {
|
|
711
|
+
name: 'span',
|
|
712
|
+
styles: { 'font-size': '10pt' },
|
|
713
|
+
priority: 7,
|
|
714
|
+
},
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
title: '11',
|
|
718
|
+
model: '11pt',
|
|
719
|
+
view: {
|
|
720
|
+
name: 'span',
|
|
721
|
+
styles: { 'font-size': '11pt' },
|
|
722
|
+
priority: 7,
|
|
723
|
+
},
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
title: '12',
|
|
727
|
+
model: '12pt',
|
|
728
|
+
view: {
|
|
729
|
+
name: 'span',
|
|
730
|
+
styles: { 'font-size': '12pt' },
|
|
731
|
+
priority: 7,
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
title: '13',
|
|
736
|
+
model: '13pt',
|
|
737
|
+
view: {
|
|
738
|
+
name: 'span',
|
|
739
|
+
styles: { 'font-size': '13pt' },
|
|
740
|
+
priority: 7,
|
|
741
|
+
},
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
title: '14',
|
|
745
|
+
model: '14pt',
|
|
746
|
+
view: {
|
|
747
|
+
name: 'span',
|
|
748
|
+
styles: { 'font-size': '14pt' },
|
|
749
|
+
priority: 7,
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
title: '16',
|
|
754
|
+
model: '16pt',
|
|
755
|
+
view: {
|
|
756
|
+
name: 'span',
|
|
757
|
+
styles: { 'font-size': '16pt' },
|
|
758
|
+
priority: 7,
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
title: '18',
|
|
763
|
+
model: '18pt',
|
|
764
|
+
view: {
|
|
765
|
+
name: 'span',
|
|
766
|
+
styles: { 'font-size': '18pt' },
|
|
767
|
+
priority: 7,
|
|
768
|
+
},
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
title: '20',
|
|
772
|
+
model: '20pt',
|
|
773
|
+
view: {
|
|
774
|
+
name: 'span',
|
|
775
|
+
styles: { 'font-size': '20pt' },
|
|
776
|
+
priority: 7,
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
title: '24',
|
|
781
|
+
model: '24pt',
|
|
782
|
+
view: {
|
|
783
|
+
name: 'span',
|
|
784
|
+
styles: { 'font-size': '24pt' },
|
|
785
|
+
priority: 7,
|
|
786
|
+
},
|
|
787
|
+
},
|
|
788
|
+
];
|
|
789
|
+
}
|
|
790
|
+
function getHeadingOptions() {
|
|
791
|
+
return [
|
|
792
|
+
{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
|
|
793
|
+
{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
|
|
794
|
+
{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
|
|
795
|
+
{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
|
|
796
|
+
];
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* Document Builder Utilities
|
|
801
|
+
* Các hàm tiện ích cho document builder
|
|
802
|
+
*/
|
|
803
|
+
/**
|
|
804
|
+
* Chuẩn hóa nội dung bằng cách chuyển đổi tất cả màu HSL và RGB sang hex
|
|
805
|
+
* @param content - Nội dung HTML cần chuẩn hóa
|
|
806
|
+
* @returns Nội dung đã được chuẩn hóa với màu hex
|
|
807
|
+
*/
|
|
808
|
+
function normalize(content) {
|
|
809
|
+
let normalized = content;
|
|
810
|
+
// Chuyển đổi HSL sang hex
|
|
811
|
+
const hslRegex = /hsl\(\s*(\d+)\s*,\s*(\d+)%?\s*,\s*(\d+)%?\s*\)/gi;
|
|
812
|
+
normalized = normalized.replace(hslRegex, (match, h, s, l) => {
|
|
813
|
+
try {
|
|
814
|
+
const hue = parseInt(h, 10);
|
|
815
|
+
const saturation = parseInt(s, 10);
|
|
816
|
+
const lightness = parseInt(l, 10);
|
|
817
|
+
// Kiểm tra giá trị hợp lệ
|
|
818
|
+
if (hue >= 0 && hue <= 360 && saturation >= 0 && saturation <= 100 && lightness >= 0 && lightness <= 100) {
|
|
819
|
+
return hslToHex(hue, saturation, lightness);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
catch (error) {
|
|
823
|
+
console.warn('Failed to convert HSL to hex:', error, match);
|
|
824
|
+
}
|
|
825
|
+
return match; // Giữ nguyên nếu không thể chuyển đổi
|
|
826
|
+
});
|
|
827
|
+
// Chuyển đổi RGB sang hex
|
|
828
|
+
const rgbRegex = /rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/gi;
|
|
829
|
+
normalized = normalized.replace(rgbRegex, (match, r, g, b) => {
|
|
830
|
+
try {
|
|
831
|
+
const red = parseInt(r, 10);
|
|
832
|
+
const green = parseInt(g, 10);
|
|
833
|
+
const blue = parseInt(b, 10);
|
|
834
|
+
if (red >= 0 && red <= 255 && green >= 0 && green <= 255 && blue >= 0 && blue <= 255) {
|
|
835
|
+
return rgbToHex(red, green, blue);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
catch (error) {
|
|
839
|
+
console.warn('Failed to convert RGB to hex:', error, match);
|
|
840
|
+
}
|
|
841
|
+
return match;
|
|
842
|
+
});
|
|
843
|
+
return normalized;
|
|
844
|
+
}
|
|
845
|
+
|
|
540
846
|
class SdDocumentBuilder {
|
|
541
847
|
#id = '1212';
|
|
848
|
+
// Shared color palette and configuration
|
|
849
|
+
#sharedColors = getPresetColors();
|
|
850
|
+
#colorPickerConfig = getColorPickerConfig();
|
|
851
|
+
#fontSizeOptions = getFontSizeOptions();
|
|
852
|
+
#headingOptions = getHeadingOptions();
|
|
542
853
|
option;
|
|
543
854
|
disabled = false;
|
|
544
855
|
set _disabled(val) {
|
|
@@ -547,6 +858,7 @@ class SdDocumentBuilder {
|
|
|
547
858
|
}
|
|
548
859
|
Editor = ClassicEditor;
|
|
549
860
|
#editor;
|
|
861
|
+
#idTimeOutScrollHeading = null;
|
|
550
862
|
// Config
|
|
551
863
|
config = {
|
|
552
864
|
getOption: () => this.option,
|
|
@@ -625,109 +937,24 @@ class SdDocumentBuilder {
|
|
|
625
937
|
toolbar: ['toggleImageCaption', '|', 'imageStyle:inline', 'imageStyle:block', 'imageStyle:side'],
|
|
626
938
|
},
|
|
627
939
|
fontSize: {
|
|
628
|
-
options:
|
|
629
|
-
// Định nghĩa từng size một cách tường minh
|
|
630
|
-
{
|
|
631
|
-
title: '9',
|
|
632
|
-
model: '9pt',
|
|
633
|
-
view: {
|
|
634
|
-
name: 'span',
|
|
635
|
-
styles: { 'font-size': '9pt' },
|
|
636
|
-
priority: 7,
|
|
637
|
-
},
|
|
638
|
-
},
|
|
639
|
-
{
|
|
640
|
-
title: '10',
|
|
641
|
-
model: '10pt',
|
|
642
|
-
view: {
|
|
643
|
-
name: 'span',
|
|
644
|
-
styles: { 'font-size': '10pt' },
|
|
645
|
-
priority: 7,
|
|
646
|
-
},
|
|
647
|
-
},
|
|
648
|
-
{
|
|
649
|
-
title: '11',
|
|
650
|
-
model: '11pt',
|
|
651
|
-
view: {
|
|
652
|
-
name: 'span',
|
|
653
|
-
styles: { 'font-size': '11pt' },
|
|
654
|
-
priority: 7,
|
|
655
|
-
},
|
|
656
|
-
},
|
|
657
|
-
{
|
|
658
|
-
title: '12',
|
|
659
|
-
model: '12pt',
|
|
660
|
-
view: {
|
|
661
|
-
name: 'span',
|
|
662
|
-
styles: { 'font-size': '12pt' },
|
|
663
|
-
priority: 7,
|
|
664
|
-
},
|
|
665
|
-
},
|
|
666
|
-
{
|
|
667
|
-
title: '13',
|
|
668
|
-
model: '13pt',
|
|
669
|
-
view: {
|
|
670
|
-
name: 'span',
|
|
671
|
-
styles: { 'font-size': '13pt' },
|
|
672
|
-
priority: 7,
|
|
673
|
-
},
|
|
674
|
-
},
|
|
675
|
-
{
|
|
676
|
-
title: '14',
|
|
677
|
-
model: '14pt',
|
|
678
|
-
view: {
|
|
679
|
-
name: 'span',
|
|
680
|
-
styles: { 'font-size': '14pt' },
|
|
681
|
-
priority: 7,
|
|
682
|
-
},
|
|
683
|
-
},
|
|
684
|
-
{
|
|
685
|
-
title: '16',
|
|
686
|
-
model: '16pt',
|
|
687
|
-
view: {
|
|
688
|
-
name: 'span',
|
|
689
|
-
styles: { 'font-size': '16pt' },
|
|
690
|
-
priority: 7,
|
|
691
|
-
},
|
|
692
|
-
},
|
|
693
|
-
{
|
|
694
|
-
title: '18',
|
|
695
|
-
model: '18pt',
|
|
696
|
-
view: {
|
|
697
|
-
name: 'span',
|
|
698
|
-
styles: { 'font-size': '18pt' },
|
|
699
|
-
priority: 7,
|
|
700
|
-
},
|
|
701
|
-
},
|
|
702
|
-
{
|
|
703
|
-
title: '20',
|
|
704
|
-
model: '20pt',
|
|
705
|
-
view: {
|
|
706
|
-
name: 'span',
|
|
707
|
-
styles: { 'font-size': '20pt' },
|
|
708
|
-
priority: 7,
|
|
709
|
-
},
|
|
710
|
-
},
|
|
711
|
-
{
|
|
712
|
-
title: '24',
|
|
713
|
-
model: '24pt',
|
|
714
|
-
view: {
|
|
715
|
-
name: 'span',
|
|
716
|
-
styles: { 'font-size': '24pt' },
|
|
717
|
-
priority: 7,
|
|
718
|
-
},
|
|
719
|
-
},
|
|
720
|
-
],
|
|
940
|
+
options: this.#fontSizeOptions,
|
|
721
941
|
supportAllValues: false, // Khuyên dùng false để ép user chọn đúng size chuẩn
|
|
722
942
|
},
|
|
943
|
+
heading: {
|
|
944
|
+
options: this.#headingOptions,
|
|
945
|
+
},
|
|
723
946
|
// 4. Cấu hình bảng màu (Tùy chọn)
|
|
724
947
|
fontColor: {
|
|
725
|
-
columns: 5,
|
|
948
|
+
// columns: 5,
|
|
726
949
|
documentColors: 10,
|
|
950
|
+
colorPicker: this.#colorPickerConfig,
|
|
951
|
+
colors: this.#sharedColors,
|
|
727
952
|
},
|
|
728
953
|
fontBackgroundColor: {
|
|
729
|
-
columns: 5,
|
|
954
|
+
// columns: 5,
|
|
730
955
|
documentColors: 10,
|
|
956
|
+
colorPicker: this.#colorPickerConfig,
|
|
957
|
+
colors: this.#sharedColors,
|
|
731
958
|
},
|
|
732
959
|
table: {
|
|
733
960
|
contentToolbar: [
|
|
@@ -738,6 +965,14 @@ class SdDocumentBuilder {
|
|
|
738
965
|
'tableProperties', // <--- Nút chỉnh thuộc tính bảng (Viền, Màu, Width)
|
|
739
966
|
'tableCellProperties',
|
|
740
967
|
],
|
|
968
|
+
tableProperties: {
|
|
969
|
+
borderColors: this.#sharedColors,
|
|
970
|
+
colorPicker: this.#colorPickerConfig,
|
|
971
|
+
},
|
|
972
|
+
tableCellProperties: {
|
|
973
|
+
borderColors: this.#sharedColors,
|
|
974
|
+
colorPicker: this.#colorPickerConfig,
|
|
975
|
+
},
|
|
741
976
|
},
|
|
742
977
|
// Quan trọng: Cho phép paste style từ Word nhưng bỏ qua margin/padding
|
|
743
978
|
htmlSupport: {
|
|
@@ -757,12 +992,11 @@ class SdDocumentBuilder {
|
|
|
757
992
|
contentChange = new EventEmitter(); // Emit HTML content
|
|
758
993
|
#subscription = new Subscription();
|
|
759
994
|
#contentChangeSubject = new Subject();
|
|
760
|
-
#editorChangeRxjs = new Subject();
|
|
761
995
|
ngOnInit() {
|
|
762
996
|
// https://onemount.atlassian.net/browse/SM-1862
|
|
763
997
|
// Debounce trong rxjs không hỗ trợ leading -->
|
|
764
998
|
this.#subscription.add(this.#contentChangeSubject.pipe(throttleTime(500, undefined, { leading: true, trailing: true })).subscribe(content => {
|
|
765
|
-
this.contentChange.emit(content);
|
|
999
|
+
this.contentChange.emit(normalize(content));
|
|
766
1000
|
}));
|
|
767
1001
|
}
|
|
768
1002
|
ngOnDestroy() {
|
|
@@ -770,6 +1004,12 @@ class SdDocumentBuilder {
|
|
|
770
1004
|
}
|
|
771
1005
|
onReady(editor) {
|
|
772
1006
|
this.#editor = editor;
|
|
1007
|
+
editor.conversion.for('editingDowncast').markerToHighlight({
|
|
1008
|
+
model: 'highlightMarker',
|
|
1009
|
+
view: {
|
|
1010
|
+
classes: 'ck-heading-highlight',
|
|
1011
|
+
},
|
|
1012
|
+
});
|
|
773
1013
|
// Setup orientation plugin callback
|
|
774
1014
|
try {
|
|
775
1015
|
const orientationPlugin = editor.plugins.get('PageOrientationPlugin');
|
|
@@ -803,10 +1043,30 @@ class SdDocumentBuilder {
|
|
|
803
1043
|
if (this.disabled) {
|
|
804
1044
|
// Bật chế độ chỉ đọc với ID khóa
|
|
805
1045
|
this.#editor.enableReadOnlyMode(this.#id);
|
|
1046
|
+
// Disable page orientation button
|
|
1047
|
+
try {
|
|
1048
|
+
const orientationPlugin = this.#editor.plugins.get('PageOrientationPlugin');
|
|
1049
|
+
if (orientationPlugin && orientationPlugin.buttonView) {
|
|
1050
|
+
orientationPlugin.buttonView.isEnabled = false;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
catch (error) {
|
|
1054
|
+
console.warn('Failed to disable orientation button:', error);
|
|
1055
|
+
}
|
|
806
1056
|
}
|
|
807
1057
|
else {
|
|
808
1058
|
// Tắt chế độ chỉ đọc với ID khóa tương ứng
|
|
809
1059
|
this.#editor.disableReadOnlyMode(this.#id);
|
|
1060
|
+
// Enable page orientation button
|
|
1061
|
+
try {
|
|
1062
|
+
const orientationPlugin = this.#editor.plugins.get('PageOrientationPlugin');
|
|
1063
|
+
if (orientationPlugin && orientationPlugin.buttonView) {
|
|
1064
|
+
orientationPlugin.buttonView.isEnabled = true;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
catch (error) {
|
|
1068
|
+
console.warn('Failed to enable orientation button:', error);
|
|
1069
|
+
}
|
|
810
1070
|
}
|
|
811
1071
|
}
|
|
812
1072
|
scrollToComment = (markerId) => {
|
|
@@ -981,31 +1241,43 @@ class SdDocumentBuilder {
|
|
|
981
1241
|
scrollToHeading: (id) => {
|
|
982
1242
|
if (!this.#editor)
|
|
983
1243
|
return;
|
|
984
|
-
// 1. Lấy Model Element từ kho lưu trữ
|
|
985
1244
|
const modelElement = this.#headingElementsMap.get(id);
|
|
986
1245
|
if (modelElement) {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1246
|
+
this.#editor.model.change(writer => {
|
|
1247
|
+
// Xóa marker cũ
|
|
1248
|
+
if (this.#idTimeOutScrollHeading) {
|
|
1249
|
+
clearTimeout(this.#idTimeOutScrollHeading);
|
|
1250
|
+
}
|
|
1251
|
+
const currentMarker = this.#editor.model.markers.get('highlightMarker');
|
|
1252
|
+
if (currentMarker) {
|
|
1253
|
+
writer.removeMarker(currentMarker);
|
|
1254
|
+
}
|
|
1255
|
+
// Tạo Range bao trùm highlight
|
|
1256
|
+
const range = writer.createRangeOn(modelElement);
|
|
1257
|
+
// Thêm Marker mới
|
|
1258
|
+
writer.addMarker('highlightMarker', {
|
|
1259
|
+
range: range,
|
|
1260
|
+
usingOperation: false,
|
|
1261
|
+
});
|
|
1262
|
+
});
|
|
1263
|
+
// Scroll tới vị trí đó
|
|
1264
|
+
const viewElement = this.#editor.editing.mapper.toViewElement(modelElement);
|
|
992
1265
|
if (viewElement) {
|
|
993
|
-
|
|
994
|
-
const domElement = view.domConverter.mapViewToDom(viewElement);
|
|
1266
|
+
const domElement = this.#editor.editing.view.domConverter.viewToDom(viewElement);
|
|
995
1267
|
if (domElement) {
|
|
996
|
-
|
|
997
|
-
domElement.scrollIntoView({
|
|
998
|
-
behavior: 'smooth',
|
|
999
|
-
block: 'start',
|
|
1000
|
-
inline: 'nearest',
|
|
1001
|
-
});
|
|
1002
|
-
// 5. (Tùy chọn) Focus và đặt con trỏ vào đó
|
|
1003
|
-
view.focus();
|
|
1004
|
-
editor.model.change(writer => {
|
|
1005
|
-
writer.setSelection(modelElement, 'on');
|
|
1006
|
-
});
|
|
1268
|
+
domElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
1007
1269
|
}
|
|
1008
1270
|
}
|
|
1271
|
+
// Tự động tắt marker sau 10 giây
|
|
1272
|
+
this.#idTimeOutScrollHeading = setTimeout(() => {
|
|
1273
|
+
if (this.#editor) {
|
|
1274
|
+
this.#editor.model.change(writer => {
|
|
1275
|
+
const marker = this.#editor.model.markers.get('highlightMarker');
|
|
1276
|
+
if (marker)
|
|
1277
|
+
writer.removeMarker(marker);
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
}, 10000);
|
|
1009
1281
|
}
|
|
1010
1282
|
else {
|
|
1011
1283
|
console.warn(`Heading with id ${id} not found.`);
|
|
@@ -1363,11 +1635,11 @@ class SdDocumentBuilder {
|
|
|
1363
1635
|
// });
|
|
1364
1636
|
}
|
|
1365
1637
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdDocumentBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1366
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdDocumentBuilder, isStandalone: true, selector: "sd-document-builder", inputs: { option: "option", _disabled: ["disabled", "_disabled"] }, outputs: { contentChange: "contentChange" }, ngImport: i0, template: "<div class=\"builder-container\">\n <ckeditor\n style=\"width: 100%\"\n [editor]=\"Editor\" \n [config]=\"config\" \n (ready)=\"onReady($event)\"\n [disabled]=\"disabled\">\n </ckeditor>\n</div>", styles: ["@charset \"UTF-8\";.builder-container{background-color:#f3f4f6;height:100%;overflow-y:auto;width:100%;display:flex;flex-direction:column;align-items:center;padding-bottom:20px}:host{display:inline-block}:host ::ng-deep .ck-editor{display:flex;flex-direction:column;align-items:center;width:100%}:host ::ng-deep .ck-editor .ck-editor__top,:host ::ng-deep .ck-editor .ck-editor__main{border:none!important;box-shadow:none!important}:host ::ng-deep .ck-content{background-color:#fff;width:210mm;min-height:1123px;padding:20mm!important;box-sizing:border-box!important;box-shadow:0 10px 15px -3px #0000001a}:host ::ng-deep .ck-content h1,:host ::ng-deep .ck-content h2,:host ::ng-deep .ck-content h3,:host ::ng-deep .ck-content h4,:host ::ng-deep .ck-content h5,:host ::ng-deep .ck-content h6{font-weight:400}:host ::ng-deep .ck-content.ck-focused{outline:none!important;border-color:#d1d5db!important}:host ::ng-deep .ck-content.landscape{width:297mm}:host ::ng-deep .ck-content>*{max-width:100%!important;box-sizing:border-box!important}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-left:0!important;margin-right:0!important;margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}\n", "@charset \"UTF-8\";:host ::ng-deep .ck-comment-marker{background-color:#ffeb3b80;border-bottom:2px solid #fbc02d;cursor:pointer;transition:background-color .2s}:host ::ng-deep .ck-comment-marker:hover{background-color:#ffeb3bcc}:host ::ng-deep .ck-comment-marker.active-highlight{background-color:#ffeb3b;outline:2px dashed #f57f17}\n", "@charset \"UTF-8\";:host ::ng-deep .variable-widget{background-color:#e3f2fd;color:#1976d2;border:1px solid #90caf9;border-radius:4px;padding:2px 6px;font-weight:600;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;font-size:10px;cursor:default;-webkit-user-select:none;user-select:none;display:inline-block;margin:0
|
|
1638
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdDocumentBuilder, isStandalone: true, selector: "sd-document-builder", inputs: { option: "option", _disabled: ["disabled", "_disabled"] }, outputs: { contentChange: "contentChange" }, ngImport: i0, template: "<div class=\"builder-container\">\n <ckeditor\n style=\"width: 100%\"\n [editor]=\"Editor\" \n [config]=\"config\" \n (ready)=\"onReady($event)\"\n [disabled]=\"disabled\">\n </ckeditor>\n</div>", styles: ["@charset \"UTF-8\";.builder-container{background-color:#f3f4f6;height:100%;overflow-y:auto;width:100%;display:flex;flex-direction:column;align-items:center;padding-bottom:20px}:host{display:inline-block}:host ::ng-deep .ck-heading-highlight{background-color:#fef08a;animation:fadeOut 2s 8s forwards}@keyframes fadeOut{0%{background-color:#fef08a}to{background-color:transparent}}:host ::ng-deep .ck-editor{display:flex;flex-direction:column;align-items:center;width:100%}:host ::ng-deep .ck-editor .ck-editor__top,:host ::ng-deep .ck-editor .ck-editor__main{border:none!important;box-shadow:none!important}:host ::ng-deep .ck-content{background-color:#fff;width:210mm;min-height:1123px;padding:20mm!important;box-sizing:border-box!important;box-shadow:0 10px 15px -3px #0000001a}:host ::ng-deep .ck-content h1,:host ::ng-deep .ck-content h2,:host ::ng-deep .ck-content h3,:host ::ng-deep .ck-content h4,:host ::ng-deep .ck-content h5,:host ::ng-deep .ck-content h6{font-weight:400}:host ::ng-deep .ck-content.ck-focused{outline:none!important;border-color:#d1d5db!important}:host ::ng-deep .ck-content.landscape{width:297mm}:host ::ng-deep .ck-content>*{max-width:100%!important;box-sizing:border-box!important}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-left:0!important;margin-right:0!important;margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}\n", "@charset \"UTF-8\";:host ::ng-deep .ck-comment-marker{background-color:#ffeb3b80;border-bottom:2px solid #fbc02d;cursor:pointer;transition:background-color .2s}:host ::ng-deep .ck-comment-marker:hover{background-color:#ffeb3bcc}:host ::ng-deep .ck-comment-marker.active-highlight{background-color:#ffeb3b;outline:2px dashed #f57f17}\n", "@charset \"UTF-8\";:host ::ng-deep .variable-widget{background-color:#e3f2fd;color:#1976d2;border:1px solid #90caf9!important;border-radius:4px;padding:2px 6px;font-weight:600;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;font-size:10px;cursor:default;-webkit-user-select:none;user-select:none;display:inline-block;margin:0 4px;vertical-align:middle;font-size:0}:host ::ng-deep .variable-widget:before{content:attr(data-display);font-size:10px}:host ::ng-deep .variable-widget:hover{background-color:#bbdefb;box-shadow:0 1px 2px #0000001a}:host ::ng-deep .variable-widget.ck-widget_selected{outline:2px solid #2196f3;background-color:#bbdefb}:host ::ng-deep .ck.ck-clipboard-drop-target-line{display:none!important}:host ::ng-deep .ck.ck-content .ck-widget,:host ::ng-deep .ck.ck-content .ck-widget:hover,:host ::ng-deep .ck.ck-content .ck-widget:focus,:host ::ng-deep .ck.ck-content .ck-widget.ck-widget_selected,:host ::ng-deep .ck.ck-content .ck-widget.ck-widget_selected:hover{outline:none!important;box-shadow:none!important}\n", "@charset \"UTF-8\";:host ::ng-deep .ck-editor__editable .ck-widget.table{float:none!important;display:block!important;max-width:100%!important;width:100%!important;margin:0!important;clear:both}:host ::ng-deep .ck-editor__editable table{table-layout:auto!important;width:100%!important;border-collapse:collapse;margin:0!important}:host ::ng-deep .ck-editor__editable table td,:host ::ng-deep .ck-editor__editable table th{word-wrap:break-word;white-space:normal!important;padding:.4em!important}:host ::ng-deep .ck-editor__editable table td img,:host ::ng-deep .ck-editor__editable table th img{max-width:100%;height:auto}\n", "@charset \"UTF-8\";::ng-deep .ck-editor{--ck-font-size-base: 11px !important;--ck-icon-size: 16px !important;--ck-content-font-family: \"Times New Roman\", serif !important;--ck-content-font-size: 13pt;--ck-content-line-height: 1.5;--ck-spacing-small: 2px !important;--ck-spacing-standard: 4px !important;--ck-spacing-large: 8px !important}::ng-deep .ck-editor .ck-editor__top{position:sticky;top:0;z-index:100;width:100%;min-width:600px;margin-bottom:10px}::ng-deep .ck-editor .ck-editor__top .ck-sticky-panel__content{border:none!important}::ng-deep .ck-editor .ck-editor__top .ck-toolbar{background:#fff!important;box-shadow:0 4px 6px -1px #0000001a!important;padding:8px!important}::ng-deep .ck-editor .ck-editor__top .ck-toolbar .ck-toolbar__items{display:flex;justify-content:center;flex-wrap:wrap;align-items:center}::ng-deep .ck-editor .ck-toolbar{min-height:32px!important;padding:2px!important}::ng-deep .ck-editor .ck-button{padding:2px 4px!important;min-height:24px!important}::ng-deep .ck-editor .ck-dropdown__button{min-height:24px!important}::ng-deep .ck.ck-toolbar{background:#f8f9fa!important;border-bottom:1px solid #e0e0e0!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CKEditorModule }, { kind: "component", type: i1.CKEditorComponent, selector: "ckeditor", inputs: ["editor", "config", "data", "tagName", "watchdog", "editorWatchdogConfig", "disableWatchdog", "disableTwoWayDataBinding", "disabled"], outputs: ["ready", "change", "blur", "focus", "error"] }] });
|
|
1367
1639
|
}
|
|
1368
1640
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdDocumentBuilder, decorators: [{
|
|
1369
1641
|
type: Component,
|
|
1370
|
-
args: [{ selector: 'sd-document-builder', standalone: true, imports: [CommonModule, CKEditorModule], template: "<div class=\"builder-container\">\n <ckeditor\n style=\"width: 100%\"\n [editor]=\"Editor\" \n [config]=\"config\" \n (ready)=\"onReady($event)\"\n [disabled]=\"disabled\">\n </ckeditor>\n</div>", styles: ["@charset \"UTF-8\";.builder-container{background-color:#f3f4f6;height:100%;overflow-y:auto;width:100%;display:flex;flex-direction:column;align-items:center;padding-bottom:20px}:host{display:inline-block}:host ::ng-deep .ck-editor{display:flex;flex-direction:column;align-items:center;width:100%}:host ::ng-deep .ck-editor .ck-editor__top,:host ::ng-deep .ck-editor .ck-editor__main{border:none!important;box-shadow:none!important}:host ::ng-deep .ck-content{background-color:#fff;width:210mm;min-height:1123px;padding:20mm!important;box-sizing:border-box!important;box-shadow:0 10px 15px -3px #0000001a}:host ::ng-deep .ck-content h1,:host ::ng-deep .ck-content h2,:host ::ng-deep .ck-content h3,:host ::ng-deep .ck-content h4,:host ::ng-deep .ck-content h5,:host ::ng-deep .ck-content h6{font-weight:400}:host ::ng-deep .ck-content.ck-focused{outline:none!important;border-color:#d1d5db!important}:host ::ng-deep .ck-content.landscape{width:297mm}:host ::ng-deep .ck-content>*{max-width:100%!important;box-sizing:border-box!important}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-left:0!important;margin-right:0!important;margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}\n", "@charset \"UTF-8\";:host ::ng-deep .ck-comment-marker{background-color:#ffeb3b80;border-bottom:2px solid #fbc02d;cursor:pointer;transition:background-color .2s}:host ::ng-deep .ck-comment-marker:hover{background-color:#ffeb3bcc}:host ::ng-deep .ck-comment-marker.active-highlight{background-color:#ffeb3b;outline:2px dashed #f57f17}\n", "@charset \"UTF-8\";:host ::ng-deep .variable-widget{background-color:#e3f2fd;color:#1976d2;border:1px solid #90caf9;border-radius:4px;padding:2px 6px;font-weight:600;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;font-size:10px;cursor:default;-webkit-user-select:none;user-select:none;display:inline-block;margin:0
|
|
1642
|
+
args: [{ selector: 'sd-document-builder', standalone: true, imports: [CommonModule, CKEditorModule], template: "<div class=\"builder-container\">\n <ckeditor\n style=\"width: 100%\"\n [editor]=\"Editor\" \n [config]=\"config\" \n (ready)=\"onReady($event)\"\n [disabled]=\"disabled\">\n </ckeditor>\n</div>", styles: ["@charset \"UTF-8\";.builder-container{background-color:#f3f4f6;height:100%;overflow-y:auto;width:100%;display:flex;flex-direction:column;align-items:center;padding-bottom:20px}:host{display:inline-block}:host ::ng-deep .ck-heading-highlight{background-color:#fef08a;animation:fadeOut 2s 8s forwards}@keyframes fadeOut{0%{background-color:#fef08a}to{background-color:transparent}}:host ::ng-deep .ck-editor{display:flex;flex-direction:column;align-items:center;width:100%}:host ::ng-deep .ck-editor .ck-editor__top,:host ::ng-deep .ck-editor .ck-editor__main{border:none!important;box-shadow:none!important}:host ::ng-deep .ck-content{background-color:#fff;width:210mm;min-height:1123px;padding:20mm!important;box-sizing:border-box!important;box-shadow:0 10px 15px -3px #0000001a}:host ::ng-deep .ck-content h1,:host ::ng-deep .ck-content h2,:host ::ng-deep .ck-content h3,:host ::ng-deep .ck-content h4,:host ::ng-deep .ck-content h5,:host ::ng-deep .ck-content h6{font-weight:400}:host ::ng-deep .ck-content.ck-focused{outline:none!important;border-color:#d1d5db!important}:host ::ng-deep .ck-content.landscape{width:297mm}:host ::ng-deep .ck-content>*{max-width:100%!important;box-sizing:border-box!important}:host ::ng-deep .ck-content img{max-width:100%!important;height:auto!important;object-fit:contain}:host ::ng-deep .ck-content p{margin-left:0!important;margin-right:0!important;margin-bottom:var(--ck-spacing-large);text-indent:0}:host ::ng-deep .ck-content ul,:host ::ng-deep .ck-content ol{padding-left:20px!important;margin-left:0!important}\n", "@charset \"UTF-8\";:host ::ng-deep .ck-comment-marker{background-color:#ffeb3b80;border-bottom:2px solid #fbc02d;cursor:pointer;transition:background-color .2s}:host ::ng-deep .ck-comment-marker:hover{background-color:#ffeb3bcc}:host ::ng-deep .ck-comment-marker.active-highlight{background-color:#ffeb3b;outline:2px dashed #f57f17}\n", "@charset \"UTF-8\";:host ::ng-deep .variable-widget{background-color:#e3f2fd;color:#1976d2;border:1px solid #90caf9!important;border-radius:4px;padding:2px 6px;font-weight:600;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;font-size:10px;cursor:default;-webkit-user-select:none;user-select:none;display:inline-block;margin:0 4px;vertical-align:middle;font-size:0}:host ::ng-deep .variable-widget:before{content:attr(data-display);font-size:10px}:host ::ng-deep .variable-widget:hover{background-color:#bbdefb;box-shadow:0 1px 2px #0000001a}:host ::ng-deep .variable-widget.ck-widget_selected{outline:2px solid #2196f3;background-color:#bbdefb}:host ::ng-deep .ck.ck-clipboard-drop-target-line{display:none!important}:host ::ng-deep .ck.ck-content .ck-widget,:host ::ng-deep .ck.ck-content .ck-widget:hover,:host ::ng-deep .ck.ck-content .ck-widget:focus,:host ::ng-deep .ck.ck-content .ck-widget.ck-widget_selected,:host ::ng-deep .ck.ck-content .ck-widget.ck-widget_selected:hover{outline:none!important;box-shadow:none!important}\n", "@charset \"UTF-8\";:host ::ng-deep .ck-editor__editable .ck-widget.table{float:none!important;display:block!important;max-width:100%!important;width:100%!important;margin:0!important;clear:both}:host ::ng-deep .ck-editor__editable table{table-layout:auto!important;width:100%!important;border-collapse:collapse;margin:0!important}:host ::ng-deep .ck-editor__editable table td,:host ::ng-deep .ck-editor__editable table th{word-wrap:break-word;white-space:normal!important;padding:.4em!important}:host ::ng-deep .ck-editor__editable table td img,:host ::ng-deep .ck-editor__editable table th img{max-width:100%;height:auto}\n", "@charset \"UTF-8\";::ng-deep .ck-editor{--ck-font-size-base: 11px !important;--ck-icon-size: 16px !important;--ck-content-font-family: \"Times New Roman\", serif !important;--ck-content-font-size: 13pt;--ck-content-line-height: 1.5;--ck-spacing-small: 2px !important;--ck-spacing-standard: 4px !important;--ck-spacing-large: 8px !important}::ng-deep .ck-editor .ck-editor__top{position:sticky;top:0;z-index:100;width:100%;min-width:600px;margin-bottom:10px}::ng-deep .ck-editor .ck-editor__top .ck-sticky-panel__content{border:none!important}::ng-deep .ck-editor .ck-editor__top .ck-toolbar{background:#fff!important;box-shadow:0 4px 6px -1px #0000001a!important;padding:8px!important}::ng-deep .ck-editor .ck-editor__top .ck-toolbar .ck-toolbar__items{display:flex;justify-content:center;flex-wrap:wrap;align-items:center}::ng-deep .ck-editor .ck-toolbar{min-height:32px!important;padding:2px!important}::ng-deep .ck-editor .ck-button{padding:2px 4px!important;min-height:24px!important}::ng-deep .ck-editor .ck-dropdown__button{min-height:24px!important}::ng-deep .ck.ck-toolbar{background:#f8f9fa!important;border-bottom:1px solid #e0e0e0!important}\n"] }]
|
|
1371
1643
|
}], propDecorators: { option: [{
|
|
1372
1644
|
type: Input,
|
|
1373
1645
|
args: [{ required: true }]
|