@bnsights/bbsf-controls 1.2.24 → 1.2.25

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Optional, Injectable, EventEmitter, Output, Input, Component, SkipSelf, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, NgModule, Pipe, ViewChild, HostListener, Directive, Self, Inject, ViewEncapsulation, forwardRef, ViewContainerRef, ViewChildren } from '@angular/core';
2
+ import { Optional, Injectable, EventEmitter, Output, Input, Component, SkipSelf, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, NgModule, Pipe, ViewChild, HostListener, Directive, Self, Inject, ViewEncapsulation, signal, computed, forwardRef, ViewContainerRef, ViewChildren } from '@angular/core';
3
3
  import * as i5 from '@angular/common';
4
4
  import { CommonModule, DatePipe, KeyValuePipe } from '@angular/common';
5
5
  import * as i2 from '@angular/forms';
@@ -20,7 +20,7 @@ import * as i3 from '@bnsights/bbsf-utilities/ui';
20
20
  import { UtilityService } from '@bnsights/bbsf-utilities/ui';
21
21
  import * as i3$1 from '@bnsights/bbsf-utilities/http';
22
22
  import { RequestOptionsModel } from '@bnsights/bbsf-utilities/http';
23
- import { Subject, Subscription, switchMap, Observable, noop as noop$1, of, EMPTY } from 'rxjs';
23
+ import { Subject, Subscription, Observable, noop as noop$1, of, EMPTY } from 'rxjs';
24
24
  import * as i4 from '@bnsights/bbsf-utilities/translate';
25
25
  import * as i6 from '@angular/material/slide-toggle';
26
26
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@@ -37,23 +37,30 @@ import Swal from 'sweetalert2/dist/sweetalert2.js';
37
37
  import { plainToClass } from 'class-transformer';
38
38
  import * as i1 from '@angular/common/http';
39
39
  import { HttpEventType, HttpHeaders, HttpParams } from '@angular/common/http';
40
- import * as i7$3 from 'ngx-markdown-editor';
41
- import { LMarkdownEditorModule } from 'ngx-markdown-editor';
42
40
  import * as i6$2 from '@kolkov/angular-editor';
43
41
  import { AngularEditorModule } from '@kolkov/angular-editor';
44
- import * as i5$2 from 'ngx-script-loader';
45
- import { ScriptLoaderModule } from 'ngx-script-loader';
46
- import * as i7$4 from 'ngx-dropzone';
42
+ import { Editor } from '@tiptap/core';
43
+ import { Markdown } from '@tiptap/markdown';
44
+ import { CharacterCount } from '@tiptap/extension-character-count';
45
+ import { Table, TableRow, TableHeader, TableCell } from '@tiptap/extension-table';
46
+ import TaskItem from '@tiptap/extension-task-item';
47
+ import TaskList from '@tiptap/extension-task-list';
48
+ import { Typography } from '@tiptap/extension-typography';
49
+ import Underline from '@tiptap/extension-underline';
50
+ import StarterKit from '@tiptap/starter-kit';
51
+ import * as i7$3 from 'ngx-dropzone';
47
52
  import { NgxDropzoneModule } from 'ngx-dropzone';
48
53
  import * as i8 from 'angular-cropperjs';
49
54
  import { AngularCropperjsModule } from 'angular-cropperjs';
50
- import * as i5$3 from 'ng2-file-upload';
55
+ import * as i5$2 from 'ng2-file-upload';
51
56
  import { FileUploader, FileUploadModule } from 'ng2-file-upload';
52
- import { takeUntil, switchMap as switchMap$1, map, tap } from 'rxjs/operators';
53
- import * as i7$5 from '@fullcalendar/angular';
57
+ import { takeUntil, switchMap, map, tap } from 'rxjs/operators';
58
+ import * as i7$4 from '@fullcalendar/angular';
54
59
  import { FullCalendarModule } from '@fullcalendar/angular';
55
60
  import * as i8$1 from '@angular/google-maps';
56
61
  import { GoogleMapsModule } from '@angular/google-maps';
62
+ import * as i6$3 from 'ngx-script-loader';
63
+ import { ScriptLoaderModule } from 'ngx-script-loader';
57
64
  import * as i9 from 'angular-ng-autocomplete';
58
65
  import { AutocompleteLibModule } from 'angular-ng-autocomplete';
59
66
  import { InfiniteScrollModule } from 'ngx-infinite-scroll';
@@ -6385,137 +6392,273 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImpo
6385
6392
  type: Output
6386
6393
  }] } });
6387
6394
 
6388
- var MarkdownMode;
6389
- (function (MarkdownMode) {
6390
- MarkdownMode["editor"] = "editor";
6391
- MarkdownMode["preview"] = "preview";
6392
- })(MarkdownMode || (MarkdownMode = {}));
6393
- var MarkDownIcons;
6394
- (function (MarkDownIcons) {
6395
- MarkDownIcons["Bold"] = "Bold";
6396
- MarkDownIcons["Italic"] = "Italic";
6397
- MarkDownIcons["Heading"] = "Heading";
6398
- MarkDownIcons["Reference"] = "Reference";
6399
- MarkDownIcons["Link"] = "Link";
6400
- MarkDownIcons["Image"] = "Image";
6401
- MarkDownIcons["Ul"] = "Ul";
6402
- MarkDownIcons["Ol"] = "Ol";
6403
- MarkDownIcons["Code"] = "Code";
6404
- MarkDownIcons["TogglePreview"] = "TogglePreview";
6405
- MarkDownIcons["FullScreen"] = "FullScreen";
6406
- })(MarkDownIcons || (MarkDownIcons = {}));
6407
-
6395
+ const MARKDOWN_TOOLBAR_ITEMS = [
6396
+ 'undo', 'redo', '|',
6397
+ 'h1', 'h2', 'h3', '|',
6398
+ 'bold', 'italic', 'underline', 'strike', 'code', '|',
6399
+ 'bulletList', 'orderedList', 'taskList', '|',
6400
+ 'blockquote', 'codeBlock', 'horizontalRule', 'table', '|',
6401
+ 'link',
6402
+ ];
6403
+ const TOOLBAR_BUTTONS = {
6404
+ undo: { icon: 'pi-undo', label: 'Undo', cmd: (editor) => editor.commands.undo() },
6405
+ redo: { icon: 'pi-refresh', label: 'Redo', cmd: (editor) => editor.commands.redo() },
6406
+ bold: { icon: '', label: 'Bold', cmd: (editor) => editor.chain().focus().toggleBold().run(), active: { name: 'bold' } },
6407
+ italic: { icon: '', label: 'Italic', cmd: (editor) => editor.chain().focus().toggleItalic().run(), active: { name: 'italic' } },
6408
+ underline: { icon: '', label: 'Underline', cmd: (editor) => editor.chain().focus().toggleUnderline().run(), active: { name: 'underline' } },
6409
+ strike: { icon: '', label: 'Strikethrough', cmd: (editor) => editor.chain().focus().toggleStrike().run(), active: { name: 'strike' } },
6410
+ code: { icon: 'pi-code', label: 'Inline code', cmd: (editor) => editor.chain().focus().toggleCode().run(), active: { name: 'code' } },
6411
+ codeBlock: { icon: 'pi-file-edit', label: 'Code block', cmd: (editor) => editor.chain().focus().toggleCodeBlock().run(), active: { name: 'codeBlock' } },
6412
+ blockquote: { icon: 'pi-comment', label: 'Quote', cmd: (editor) => editor.chain().focus().toggleBlockquote().run(), active: { name: 'blockquote' } },
6413
+ bulletList: { icon: 'pi-list', label: 'Bulleted list', cmd: (editor) => editor.chain().focus().toggleBulletList().run(), active: { name: 'bulletList' } },
6414
+ orderedList: { icon: 'pi-sort-numeric-down', label: 'Numbered list', cmd: (editor) => editor.chain().focus().toggleOrderedList().run(), active: { name: 'orderedList' } },
6415
+ taskList: { icon: 'pi-check-square', label: 'Task list', cmd: (editor) => editor.chain().focus().toggleTaskList().run(), active: { name: 'taskList' } },
6416
+ horizontalRule: { icon: 'pi-minus', label: 'Divider', cmd: (editor) => editor.chain().focus().setHorizontalRule().run() },
6417
+ h1: { icon: '', label: 'Heading 1', cmd: (editor) => editor.chain().focus().toggleHeading({ level: 1 }).run(), active: { name: 'heading', attrs: { level: 1 } } },
6418
+ h2: { icon: '', label: 'Heading 2', cmd: (editor) => editor.chain().focus().toggleHeading({ level: 2 }).run(), active: { name: 'heading', attrs: { level: 2 } } },
6419
+ h3: { icon: '', label: 'Heading 3', cmd: (editor) => editor.chain().focus().toggleHeading({ level: 3 }).run(), active: { name: 'heading', attrs: { level: 3 } } },
6420
+ };
6421
+ const TABLE_OPS = {
6422
+ addRowAbove: { icon: 'pi-arrow-up', label: 'Add row above', cmd: (editor) => editor.chain().focus().addRowBefore().run() },
6423
+ addRowBelow: { icon: 'pi-arrow-down', label: 'Add row below', cmd: (editor) => editor.chain().focus().addRowAfter().run() },
6424
+ addColBefore: { icon: 'pi-chevron-left', label: 'Add column before', cmd: (editor) => editor.chain().focus().addColumnBefore().run() },
6425
+ addColAfter: { icon: 'pi-chevron-right', label: 'Add column after', cmd: (editor) => editor.chain().focus().addColumnAfter().run() },
6426
+ deleteRow: { icon: 'pi-minus', label: 'Delete row', cmd: (editor) => editor.chain().focus().deleteRow().run() },
6427
+ deleteCol: { icon: 'pi-minus-circle', label: 'Delete column', cmd: (editor) => editor.chain().focus().deleteColumn().run() },
6428
+ toggleHeader: { icon: 'pi-table', label: 'Toggle header row', cmd: (editor) => editor.chain().focus().toggleHeaderRow().run() },
6429
+ mergeSplit: { icon: 'pi-clone', label: 'Merge / split cells', cmd: (editor) => editor.chain().focus().mergeOrSplit().run() },
6430
+ alignLeft: { icon: 'pi-align-left', label: 'Align left', cmd: (editor) => editor.chain().focus().setCellAttribute('align', 'left').run() },
6431
+ alignCenter: { icon: 'pi-align-center', label: 'Align center', cmd: (editor) => editor.chain().focus().setCellAttribute('align', 'center').run() },
6432
+ alignRight: { icon: 'pi-align-right', label: 'Align right', cmd: (editor) => editor.chain().focus().setCellAttribute('align', 'right').run() },
6433
+ deleteTable: { icon: 'pi-trash', label: 'Delete table', cmd: (editor) => editor.chain().focus().deleteTable().run() },
6434
+ };
6435
+ const HIDDEN_ICON_MAP = {
6436
+ Bold: ['bold'],
6437
+ Italic: ['italic'],
6438
+ Heading: ['h1', 'h2', 'h3'],
6439
+ Reference: ['blockquote'],
6440
+ Link: ['link'],
6441
+ Image: [],
6442
+ UnorderedList: ['bulletList', 'taskList'],
6443
+ OrderedList: ['orderedList'],
6444
+ CodeBlock: ['codeBlock', 'code'],
6445
+ ShowPreview: [],
6446
+ HidePreview: [],
6447
+ Fullscreen: [],
6448
+ Ul: ['bulletList', 'taskList'],
6449
+ Ol: ['orderedList'],
6450
+ Code: ['codeBlock', 'code'],
6451
+ TogglePreview: [],
6452
+ FullScreen: [],
6453
+ };
6408
6454
  class MarkdownEditorComponent {
6409
6455
  static { this.controlContainerstatic = null; }
6410
- constructor(utilityService, globalSettings, controlValidationService, controlUtility, markdownEditorControlHost, scriptService, controlContainer) {
6456
+ constructor(utilityService, globalSettings, controlValidationService, controlUtility, markdownEditorControlHost, cdr, controlContainer) {
6411
6457
  this.utilityService = utilityService;
6412
6458
  this.globalSettings = globalSettings;
6413
6459
  this.controlValidationService = controlValidationService;
6414
6460
  this.controlUtility = controlUtility;
6415
6461
  this.markdownEditorControlHost = markdownEditorControlHost;
6416
- this.scriptService = scriptService;
6462
+ this.cdr = cdr;
6417
6463
  this.controlContainer = controlContainer;
6418
6464
  this.OnChange = new EventEmitter();
6419
- this.hideToolbar = false;
6420
6465
  this.validationRules = [];
6421
6466
  this.validationRulesasync = [];
6422
6467
  this.markAllAsTouched = false;
6423
- this.showMarkdown = false;
6424
- this.btnsText = {
6425
- Buttons: {
6426
- Bold: { title: this.utilityService.getResourceValue('Bold') },
6427
- Italic: { title: this.utilityService.getResourceValue('Italic') },
6428
- Heading: { title: this.utilityService.getResourceValue('Heading') },
6429
- Reference: { title: this.utilityService.getResourceValue('Reference') },
6430
- Link: { title: this.utilityService.getResourceValue('Link') },
6431
- Image: { title: this.utilityService.getResourceValue('Image') },
6432
- UnorderedList: { title: this.utilityService.getResourceValue('UnorderedList') },
6433
- OrderedList: { title: this.utilityService.getResourceValue('OrderedList') },
6434
- CodeBlock: { title: this.utilityService.getResourceValue('CodeBlock') },
6435
- ShowPreview: { title: this.utilityService.getResourceValue('ShowPreview') },
6436
- HidePreview: { title: this.utilityService.getResourceValue('HidePreview') },
6437
- Fullscreen: { title: this.utilityService.getResourceValue('Fullscreen') }
6438
- },
6439
- Upload: {
6440
- Drag: this.utilityService.getResourceValue('DragHere'),
6441
- Uploading: this.utilityService.getResourceValue('Uploading')
6442
- }
6443
- };
6444
- this.locales = {
6445
- en: this.btnsText,
6446
- ar: this.btnsText
6447
- };
6468
+ this.activeStates = signal({});
6469
+ this.canUndo = signal(false);
6470
+ this.canRedo = signal(false);
6471
+ this.showLinkPopover = signal(false);
6472
+ this.linkInputValue = signal('');
6473
+ this.showTablePopover = signal(false);
6474
+ this.characters = signal(0);
6475
+ this.words = signal(0);
6476
+ this.isOverLimit = computed(() => {
6477
+ const max = this.options?.maxLength;
6478
+ return max != null && max > 0 && this.characters() > max;
6479
+ });
6480
+ this.toolbarItems = [...MARKDOWN_TOOLBAR_ITEMS];
6481
+ this.tableMenuGroups = [
6482
+ ['addRowAbove', 'addRowBelow', 'addColBefore', 'addColAfter'],
6483
+ ['deleteRow', 'deleteCol', 'toggleHeader', 'mergeSplit'],
6484
+ ['alignLeft', 'alignCenter', 'alignRight'],
6485
+ ['deleteTable'],
6486
+ ];
6448
6487
  this.resetError = () => {
6449
6488
  this.controlValidationService.removeGlobalError();
6450
6489
  };
6451
- //External Method
6452
6490
  this.removeRequiredValidation = () => {
6453
6491
  this.controlUtility.removeRequiredValidation(this.markdownEditorFormControl, this.validationRules, this.options);
6454
6492
  };
6455
- //External Method
6456
6493
  this.addRequiredValidation = () => {
6457
6494
  this.controlUtility.addRequiredValidation(this.markdownEditorFormControl, this.validationRules, this.options);
6458
6495
  };
6459
- //External Method
6460
6496
  this.removeCustomValidation = (customValidation) => {
6461
6497
  this.controlUtility.removeCustomValidation(this.markdownEditorFormControl, this.validationRules, customValidation);
6462
6498
  };
6463
- //External Method
6464
6499
  this.addCustomValidation = (customValidation) => {
6465
6500
  this.controlUtility.addCustomValidation(this.markdownEditorFormControl, this.validationRules, customValidation);
6466
6501
  };
6467
- //External Method
6468
6502
  this.isValid = () => {
6469
6503
  this.controlUtility.isValid(this.markdownEditorFormControl);
6470
6504
  };
6471
6505
  MarkdownEditorComponent.controlContainerstatic = this.controlContainer;
6472
- this.currentLocale = this.utilityService.getCurrentLanguage();
6473
- }
6474
- loadAllScripts() {
6475
- return this.scriptService.loadScript('assets/ace-builds/ace.js').pipe(switchMap(() => this.scriptService.loadScript('assets/ace-builds/mode-markdown.js')), switchMap(() => this.scriptService.loadScript('assets/ngx-markdown-editor/marked.min.js')), switchMap(() => this.scriptService.loadScript('assets/ngx-markdown-editor/highlight.js/highlight.min.js')));
6476
6506
  }
6477
6507
  ngOnInit() {
6478
- this.loadAllScripts()
6479
- .subscribe({
6480
- next: () => this.showMarkdown = true,
6481
- error: (err) => console.error('Error loading scripts', err)
6482
- });
6483
- this.mode = this.options.isReadonly ? MarkdownMode.preview : MarkdownMode.editor;
6484
- this.editorOptions = {
6485
- hideIcons: this.options.hideIcons,
6486
- showPreviewPanel: this.options.showPreviewPanelOnLoad,
6487
- resizable: false,
6488
- enablePreviewContentClick: this.options.isReadonly, // Allow user fire the click event on the preview panel, like href etc.
6489
- markedjsOpt: {
6490
- breaks: true,
6491
- sanitize: true,
6492
- smartypants: true,
6493
- xhtml: true,
6494
- },
6495
- customRender: this.options.customRender,
6496
- placeholder: this.options.placeholder,
6497
- locales: this.locales,
6498
- customIcons: {
6499
- CodeBlock: {
6500
- fontClass: 'fa fa-file-code'
6501
- }
6502
- }
6503
- };
6504
6508
  this.controlValidationService.isCreatedBefor = false;
6505
- this.group.addControl(this.options.name, new FormControl(''));
6506
- this.markdownEditorFormControl = this.group.controls[this.options.name]; // new FormControl('',validationRules);
6507
- this.markdownEditorFormControl.setValue(this.options.value);
6508
- if (!this.options.viewType)
6509
+ this.initializeOptions();
6510
+ this.initializeControl();
6511
+ this.subscribeToControlChanges();
6512
+ this.subscribeToSubmit();
6513
+ }
6514
+ ngAfterViewInit() {
6515
+ this.initializeEditor();
6516
+ }
6517
+ ngOnDestroy() {
6518
+ this.valueChangesSubscription?.unsubscribe();
6519
+ this.submitSubscription?.unsubscribe();
6520
+ this.editor?.destroy();
6521
+ }
6522
+ button(id) {
6523
+ const button = TOOLBAR_BUTTONS[id];
6524
+ return button ? { icon: button.icon, label: button.label } : null;
6525
+ }
6526
+ textLabel(id) {
6527
+ switch (id) {
6528
+ case 'bold': return 'B';
6529
+ case 'italic': return 'I';
6530
+ case 'underline': return 'U';
6531
+ case 'strike': return 'S';
6532
+ case 'h1': return 'H1';
6533
+ case 'h2': return 'H2';
6534
+ case 'h3': return 'H3';
6535
+ default: return null;
6536
+ }
6537
+ }
6538
+ run(id) {
6539
+ const button = TOOLBAR_BUTTONS[id];
6540
+ if (!this.editor || !button || this.isReadonly())
6541
+ return;
6542
+ button.cmd(this.editor);
6543
+ this.refreshState();
6544
+ this.cdr.markForCheck();
6545
+ }
6546
+ isActive(id) {
6547
+ return this.activeStates()[id] ?? false;
6548
+ }
6549
+ disabled(id) {
6550
+ if (this.isReadonly())
6551
+ return true;
6552
+ if (id === 'undo')
6553
+ return !this.canUndo();
6554
+ if (id === 'redo')
6555
+ return !this.canRedo();
6556
+ return false;
6557
+ }
6558
+ openLinkPopover() {
6559
+ if (!this.editor || this.isReadonly())
6560
+ return;
6561
+ this.showTablePopover.set(false);
6562
+ this.linkInputValue.set(this.editor.getAttributes('link')['href'] ?? '');
6563
+ this.showLinkPopover.set(true);
6564
+ }
6565
+ onLinkInput(value) {
6566
+ this.linkInputValue.set(value);
6567
+ }
6568
+ commitLink() {
6569
+ if (!this.editor)
6570
+ return;
6571
+ const url = this.linkInputValue().trim();
6572
+ const chain = this.editor.chain().focus().extendMarkRange('link');
6573
+ if (url === '')
6574
+ chain.unsetLink().run();
6575
+ else
6576
+ chain.setLink({ href: url }).run();
6577
+ this.showLinkPopover.set(false);
6578
+ this.refreshState();
6579
+ this.cdr.markForCheck();
6580
+ }
6581
+ cancelLink() {
6582
+ this.showLinkPopover.set(false);
6583
+ }
6584
+ onLinkKeydown(event) {
6585
+ if (event.key === 'Enter') {
6586
+ event.preventDefault();
6587
+ this.commitLink();
6588
+ }
6589
+ if (event.key === 'Escape') {
6590
+ this.cancelLink();
6591
+ }
6592
+ }
6593
+ inTable() {
6594
+ return this.isActive('table');
6595
+ }
6596
+ toggleTablePopover() {
6597
+ if (!this.editor || this.isReadonly())
6598
+ return;
6599
+ this.showLinkPopover.set(false);
6600
+ this.showTablePopover.update((open) => !open);
6601
+ }
6602
+ insertTable() {
6603
+ if (!this.editor)
6604
+ return;
6605
+ this.editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
6606
+ this.showTablePopover.set(false);
6607
+ this.refreshState();
6608
+ this.cdr.markForCheck();
6609
+ }
6610
+ tableOpMeta(id) {
6611
+ const op = TABLE_OPS[id];
6612
+ return op ? { icon: op.icon, label: op.label } : { icon: '', label: '' };
6613
+ }
6614
+ tableOp(id) {
6615
+ if (!this.editor)
6616
+ return;
6617
+ const op = TABLE_OPS[id];
6618
+ if (!op)
6619
+ return;
6620
+ op.cmd(this.editor);
6621
+ if (id === 'deleteTable')
6622
+ this.showTablePopover.set(false);
6623
+ this.refreshState();
6624
+ this.cdr.markForCheck();
6625
+ }
6626
+ showGlobalError() {
6627
+ this.controlUtility.showGlobalError();
6628
+ }
6629
+ getErrorValidation(ErrorList) {
6630
+ if (this.markAllAsTouched && this.group.invalid) {
6631
+ this.showGlobalError();
6632
+ this.markAllAsTouched = false;
6633
+ }
6634
+ return this.controlUtility.getErrorValidationMassage(ErrorList, this.group, this.options);
6635
+ }
6636
+ get editorHeight() {
6637
+ return this.options?.height || '400px';
6638
+ }
6639
+ get maxLength() {
6640
+ return this.options?.maxLength && this.options.maxLength > 0 ? this.options.maxLength : null;
6641
+ }
6642
+ initializeOptions() {
6643
+ if (!this.options.viewType) {
6509
6644
  this.options.viewType = this.globalSettings.viewType;
6510
- if (this.options.customValidation.length > 0) {
6511
- let validations = this.options.customValidation;
6512
- for (let index = 0; index < validations.length; index++) {
6513
- const Validation = validations[index];
6514
- this.validationRules.push(Validation.functionBody);
6515
- }
6516
6645
  }
6517
- if (this.options.labelKey != null && this.options.labelKey != "")
6646
+ if (this.options.labelKey != null && this.options.labelKey !== '') {
6518
6647
  this.options.labelValue = this.utilityService.getResourceValue(this.options.labelKey);
6648
+ }
6649
+ this.toolbarItems = this.buildToolbarItems(this.options.hideIcons ?? []);
6650
+ }
6651
+ initializeControl() {
6652
+ if (!this.group.controls[this.options.name]) {
6653
+ this.group.addControl(this.options.name, new FormControl(''));
6654
+ }
6655
+ this.markdownEditorFormControl = this.group.controls[this.options.name];
6656
+ this.markdownEditorFormControl.setValue(this.options.value ?? '', { emitEvent: false });
6657
+ if (this.options.customValidation?.length > 0) {
6658
+ for (const validation of this.options.customValidation) {
6659
+ this.validationRules.push(validation.functionBody);
6660
+ }
6661
+ }
6519
6662
  if (this.options.minLength > 0) {
6520
6663
  this.validationRules.push(Validators.minLength(this.options.minLength));
6521
6664
  }
@@ -6528,102 +6671,122 @@ class MarkdownEditorComponent {
6528
6671
  this.markdownEditorFormControl.setValidators(this.validationRules);
6529
6672
  this.markdownEditorFormControl.setAsyncValidators(this.validationRulesasync);
6530
6673
  if (this.options.isDisabled) {
6531
- this.markdownEditorFormControl.disable();
6532
- }
6533
- this.markdownEditorControlHost.ngSubmit.subscribe((value) => {
6674
+ this.markdownEditorFormControl.disable({ emitEvent: false });
6675
+ }
6676
+ }
6677
+ initializeEditor() {
6678
+ this.editor = new Editor({
6679
+ extensions: [
6680
+ StarterKit.configure({ link: { openOnClick: false } }),
6681
+ Underline,
6682
+ Markdown,
6683
+ TaskList,
6684
+ TaskItem.configure({ nested: true }),
6685
+ Table.configure({ resizable: true }),
6686
+ TableRow,
6687
+ TableHeader,
6688
+ TableCell,
6689
+ Typography,
6690
+ CharacterCount,
6691
+ ],
6692
+ element: this.editorBody.nativeElement,
6693
+ content: this.markdownEditorFormControl.value ?? '',
6694
+ editorProps: {
6695
+ attributes: {
6696
+ class: 'md-editor__prosemirror',
6697
+ spellcheck: 'true',
6698
+ 'data-placeholder': this.options.placeholder ?? '',
6699
+ 'aria-label': this.options.labelValue ?? this.options.name
6700
+ },
6701
+ },
6702
+ onCreate: ({ editor }) => {
6703
+ editor.commands.setContent(this.markdownEditorFormControl.value ?? '', { emitUpdate: false, contentType: 'markdown' });
6704
+ editor.setEditable(!this.isReadonly());
6705
+ this.refreshState();
6706
+ },
6707
+ onUpdate: () => {
6708
+ const value = this.editor.getMarkdown();
6709
+ this.options.value = value;
6710
+ this.markdownEditorFormControl.setValue(value, { emitEvent: false });
6711
+ this.markdownEditorFormControl.markAsDirty();
6712
+ this.OnChange.emit(value);
6713
+ this.refreshState();
6714
+ this.cdr.markForCheck();
6715
+ },
6716
+ onSelectionUpdate: () => {
6717
+ this.refreshState();
6718
+ this.cdr.markForCheck();
6719
+ },
6720
+ onBlur: () => {
6721
+ this.markdownEditorFormControl.markAsTouched();
6722
+ },
6723
+ });
6724
+ }
6725
+ subscribeToControlChanges() {
6726
+ this.valueChangesSubscription = this.markdownEditorFormControl.valueChanges.subscribe((value) => {
6727
+ const nextValue = value ?? '';
6728
+ if (nextValue !== this.options.value) {
6729
+ this.options.value = nextValue;
6730
+ }
6731
+ if (this.editor && this.editor.getMarkdown() !== nextValue) {
6732
+ this.editor.commands.setContent(nextValue, { emitUpdate: false, contentType: 'markdown' });
6733
+ this.refreshState();
6734
+ }
6735
+ this.editor?.setEditable(!this.isReadonly());
6736
+ });
6737
+ }
6738
+ subscribeToSubmit() {
6739
+ this.submitSubscription = this.markdownEditorControlHost.ngSubmit.subscribe(() => {
6534
6740
  this.group.markAllAsTouched();
6535
6741
  this.markAllAsTouched = true;
6536
6742
  });
6537
6743
  }
6538
- uploadImg(evt) {
6539
- if (!evt)
6744
+ refreshState() {
6745
+ if (!this.editor)
6540
6746
  return;
6541
- const file = evt.target.files[0];
6542
- const reader = new FileReader();
6543
- reader.addEventListener('load', () => {
6544
- this.options.value += `![](${reader.result})`;
6545
- }, false);
6546
- if (file)
6547
- reader.readAsDataURL(file);
6548
- }
6549
- onPreviewDomChanged(dom) {
6550
- this.OnChange.emit(dom);
6551
- }
6552
- showGlobalError() {
6553
- this.controlUtility.showGlobalError();
6554
- }
6555
- getErrorValidation(ErrorList) {
6556
- if (this.markAllAsTouched && this.group.invalid) {
6557
- this.showGlobalError();
6558
- this.markAllAsTouched = false;
6559
- }
6560
- return this.controlUtility.getErrorValidationMassage(ErrorList, this.group, this.options);
6561
- }
6562
- //Fires on markdown editor has been loaded
6563
- onEditorLoaded(editor) {
6564
- if (this.options.isDisabled) {
6565
- const textarea = editor.renderer.textarea;
6566
- if (textarea && this.options.isDisabled) {
6567
- textarea.setAttribute('disabled', 'true');
6568
- }
6569
- this.hideToolbar = true;
6570
- }
6571
- }
6572
- //The doUpload method handles file uploads when users add images or other files to the editor.
6573
- //This method should be implemented to manage file uploads to a server or cloud storage and return the result to the editor.
6574
- //fires on drag and drop or copy paste
6575
- //if not set will can't add files or images using this way
6576
- onDragFile(files) {
6577
- const results = [];
6578
- // Function to handle a single file
6579
- const processFile = (file) => {
6580
- return new Promise((resolve, reject) => {
6581
- const reader = new FileReader();
6582
- reader.onload = () => {
6583
- const fileUrl = reader.result;
6584
- const result = {
6585
- name: file.name,
6586
- url: fileUrl,
6587
- isImg: file.type.startsWith('image/')
6588
- };
6589
- resolve(result);
6590
- };
6591
- reader.onerror = (error) => {
6592
- reject(error);
6593
- };
6594
- // Read the file as a data URL
6595
- reader.readAsDataURL(file);
6596
- });
6597
- };
6598
- // // Iterate over files and process each one
6599
- const processAllFiles = async () => {
6600
- for (const file of files) {
6601
- try {
6602
- const result = await processFile(file);
6603
- results.push(result);
6604
- }
6605
- catch (error) {
6606
- console.error('Error processing file:', error);
6607
- }
6608
- }
6609
- return results;
6610
- };
6611
- //Return the promise that resolves when all files are processed
6612
- return processAllFiles();
6613
- }
6614
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MarkdownEditorComponent, deps: [{ token: i3.UtilityService }, { token: GlobalSettings }, { token: i3.ControlValidationService }, { token: ControlUtility }, { token: i2.FormGroupDirective }, { token: i5$2.ScriptService }, { token: i2.ControlContainer, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
6615
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: MarkdownEditorComponent, isStandalone: true, selector: "BBSF-MarkdownEditor", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange" }, ngImport: i0, template: "<ng-container *ngIf=\"showMarkdown\">\r\n <div class=\"form-group bbsf-control bbsf-htmleditor\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"bbsf-input-container {{options.extraClasses}}\">\r\n <md-editor id=\"{{options.name}}\" formControlName=\"{{options.name}}\"\r\n (onPreviewDomChanged)=\"onPreviewDomChanged($event)\"\r\n [(ngModel)]=\"options.value\" [mode]=\"mode\" [options]=\"editorOptions\" [attr.required]=\"options.isRequired ? true : null\" [upload]=\"onDragFile\" \r\n [maxlength]=\"options.maxLength\" [height]=\"options.height\" [locale]=\"currentLocale\" (onEditorLoaded)=\"onEditorLoaded($event)\" [hideToolbar]=\"hideToolbar\">\r\n <!-- [ngStyle]=\"{ 'direction': textDirection, 'text-align': textDirection === 'rtl' ? 'right' : 'left' }\" -->\r\n <div custom-btns>\r\n <input #imgInput type=\"file\" style=\"display: none\" (change)=\"uploadImg($event)\" />\r\n <button type=\"button\" class=\"btn btn-sm btn-default\" (click)=\"imgInput.click()\">\r\n {{utilityService.getResourceValue(\"UploadImg\")}}\r\n </button>\r\n </div>\r\n </md-editor>\r\n </div>\r\n\r\n <div class=\"subtext-container\">\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div class=\"bbsf-validation\" *ngIf=\"(markdownEditorFormControl.invalid && markdownEditorFormControl.touched)\">\r\n {{getErrorValidation(markdownEditorFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: LMarkdownEditorModule }, { kind: "component", type: i7$3.MarkdownEditorComponent, selector: "md-editor", inputs: ["hideToolbar", "height", "preRender", "postRender", "upload", "locale", "maxlength", "mode", "options"], outputs: ["onEditorLoaded", "onPreviewDomChanged"] }, { kind: "ngmodule", type: ScriptLoaderModule }] }); }
6747
+ this.canUndo.set(this.editor.can().undo());
6748
+ this.canRedo.set(this.editor.can().redo());
6749
+ const states = {};
6750
+ for (const [id, button] of Object.entries(TOOLBAR_BUTTONS)) {
6751
+ if (button.active)
6752
+ states[id] = this.editor.isActive(button.active.name, button.active.attrs ?? {});
6753
+ }
6754
+ states['link'] = this.editor.isActive('link');
6755
+ states['table'] = this.editor.isActive('table');
6756
+ this.activeStates.set(states);
6757
+ const characterCount = this.editor.storage['characterCount'];
6758
+ this.characters.set(characterCount?.characters?.() ?? 0);
6759
+ this.words.set(characterCount?.words?.() ?? 0);
6760
+ }
6761
+ buildToolbarItems(hiddenIcons) {
6762
+ const hidden = new Set();
6763
+ for (const icon of hiddenIcons) {
6764
+ for (const item of HIDDEN_ICON_MAP[icon] ?? []) {
6765
+ hidden.add(item);
6766
+ }
6767
+ }
6768
+ return MARKDOWN_TOOLBAR_ITEMS.filter((item, index, items) => {
6769
+ if (item !== '|')
6770
+ return !hidden.has(item);
6771
+ const previousVisible = items.slice(0, index).some((candidate) => candidate !== '|' && !hidden.has(candidate));
6772
+ const nextVisible = items.slice(index + 1).some((candidate) => candidate !== '|' && !hidden.has(candidate));
6773
+ return previousVisible && nextVisible;
6774
+ }).filter((item, index, items) => item !== '|' || items[index - 1] !== '|');
6775
+ }
6776
+ isReadonly() {
6777
+ return !!(this.options?.isReadonly || this.options?.isDisabled || this.markdownEditorFormControl?.disabled);
6778
+ }
6779
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MarkdownEditorComponent, deps: [{ token: i3.UtilityService }, { token: GlobalSettings }, { token: i3.ControlValidationService }, { token: ControlUtility }, { token: i2.FormGroupDirective }, { token: i0.ChangeDetectorRef }, { token: i2.ControlContainer, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
6780
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.16", type: MarkdownEditorComponent, isStandalone: true, selector: "BBSF-MarkdownEditor", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange" }, viewQueries: [{ propertyName: "editorBody", first: true, predicate: ["editorBody"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-htmleditor bbsf-markdowneditor\" [formGroup]=\"group\">\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\n {{options.labelValue}}\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\n class=\"text-danger\">*</span>\n </label>\n\n <div class=\"bbsf-input-container {{options.extraClasses}}\">\n <div class=\"md-editor\" [style.height]=\"editorHeight\">\n <div class=\"md-editor__toolbar\" role=\"toolbar\" [attr.aria-label]=\"utilityService.getResourceValue('FormattingToolbar') || 'Formatting toolbar'\">\n @for (item of toolbarItems; track $index) {\n @switch (item) {\n @case ('|') {\n <span class=\"md-editor__divider\" aria-hidden=\"true\"></span>\n }\n @case ('link') {\n <div class=\"md-editor__link-wrap\">\n <button type=\"button\" class=\"md-editor__btn\" [class.is-active]=\"isActive('link')\"\n [disabled]=\"disabled('link')\" (click)=\"openLinkPopover()\" title=\"Link\" aria-label=\"Link\">\n <i class=\"pi pi-link\" aria-hidden=\"true\"></i>\n </button>\n @if (showLinkPopover()) {\n <div class=\"md-editor__link-popover\" role=\"dialog\" aria-label=\"Link\">\n <input class=\"md-editor__link-input\" type=\"url\"\n [value]=\"linkInputValue()\" (input)=\"onLinkInput($any($event.target).value)\"\n (keydown)=\"onLinkKeydown($event)\"\n placeholder=\"https://...\" aria-label=\"Link URL\" />\n <button type=\"button\" class=\"md-editor__link-ok\" (click)=\"commitLink()\" title=\"Apply\">\n <i class=\"pi pi-check\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"md-editor__link-cancel\" (click)=\"cancelLink()\" title=\"Cancel\">\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n }\n @case ('table') {\n <div class=\"md-editor__table-wrap\">\n <button type=\"button\" class=\"md-editor__btn\" [class.is-active]=\"isActive('table') || showTablePopover()\"\n [disabled]=\"disabled('table')\" (click)=\"toggleTablePopover()\" [attr.aria-expanded]=\"showTablePopover()\"\n aria-haspopup=\"menu\" title=\"Table\" aria-label=\"Table\">\n <i class=\"pi pi-table\" aria-hidden=\"true\"></i>\n </button>\n @if (showTablePopover()) {\n <div class=\"md-editor__table-popover\" role=\"menu\" aria-label=\"Table\">\n @if (inTable()) {\n @for (group of tableMenuGroups; track $index) {\n <div class=\"md-editor__table-group\" role=\"group\">\n @for (id of group; track id) {\n <button type=\"button\" class=\"md-editor__btn\" role=\"menuitem\"\n [class.md-editor__btn--danger]=\"id === 'deleteTable'\"\n (click)=\"tableOp(id)\"\n [title]=\"tableOpMeta(id).label\" [attr.aria-label]=\"tableOpMeta(id).label\">\n <i class=\"pi {{ tableOpMeta(id).icon }}\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n } @else {\n <button type=\"button\" class=\"md-editor__table-insert\" role=\"menuitem\" (click)=\"insertTable()\">\n <i class=\"pi pi-table\" aria-hidden=\"true\"></i>\n <span>Insert table</span>\n </button>\n }\n </div>\n }\n </div>\n }\n @default {\n <button type=\"button\" class=\"md-editor__btn\"\n [class.is-active]=\"isActive(item)\" [disabled]=\"disabled(item)\"\n (click)=\"run(item)\"\n [title]=\"button(item)?.label ?? ''\" [attr.aria-label]=\"button(item)?.label ?? ''\">\n @if (textLabel(item); as txt) {\n <span class=\"md-editor__btn-text\">{{ txt }}</span>\n } @else {\n <i class=\"pi {{ button(item)?.icon }}\" aria-hidden=\"true\"></i>\n }\n </button>\n }\n }\n }\n @if (maxLength !== null) {\n <span class=\"md-editor__count\" [class.md-editor__count--over]=\"isOverLimit()\"\n aria-live=\"polite\">{{ characters() }} / {{ maxLength }}</span>\n }\n </div>\n\n <div #editorBody class=\"md-editor__body\"\n [attr.aria-label]=\"options.labelValue || options.name\"\n [attr.data-placeholder]=\"options.placeholder || ''\"></div>\n </div>\n </div>\n\n <div class=\"subtext-container\">\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\n <div class=\"bbsf-validation\" *ngIf=\"(markdownEditorFormControl.invalid && markdownEditorFormControl.touched)\">\n {{getErrorValidation(markdownEditorFormControl.errors|keyvalue)}}\n </div>\n </div>\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\n {{resetError()}}</div>\n </div>\n</div>\n", styles: [":host{display:block;--mde-text: #1d1d1f;--mde-text-secondary: #6e6e73;--mde-border: rgba(0, 0, 0, .14);--mde-hover: rgba(0, 0, 0, .05);--mde-primary: #1b84ff;--mde-primary-subtle: rgba(27, 132, 255, .12);--mde-popover-bg: #ffffff;--mde-popover-border: rgba(0, 0, 0, .12);--mde-danger: #d70015;--mde-danger-subtle: rgba(215, 0, 21, .1);--mde-cell-selected: rgba(27, 132, 255, .15);--mde-th-bg: rgba(0, 0, 0, .04);--mde-code-bg: rgba(0, 0, 0, .06)}.bbsf-markdowneditor .md-editor{display:flex;flex-direction:column;min-height:180px;position:relative;color:var(--mde-text);border:1px solid var(--mde-border);border-radius:.475rem;background:#fff;overflow:visible}.bbsf-markdowneditor .md-editor__toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:4px 6px;border-bottom:1px solid var(--mde-border)}.bbsf-markdowneditor .md-editor__divider{width:1px;height:18px;margin-inline:4px;background:var(--mde-border)}.bbsf-markdowneditor .md-editor__btn{min-width:28px;height:28px;padding-inline:7px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--mde-text-secondary);font-size:12px;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.bbsf-markdowneditor .md-editor__btn:hover:not(:disabled){background:var(--mde-hover)}.bbsf-markdowneditor .md-editor__btn.is-active{background:var(--mde-primary-subtle);color:var(--mde-primary);border-color:var(--mde-primary-subtle)}.bbsf-markdowneditor .md-editor__btn:disabled{opacity:.4;cursor:default}.bbsf-markdowneditor .md-editor__btn i.pi{font-size:13px}.bbsf-markdowneditor .md-editor__btn-text{font-weight:600;font-style:normal}.bbsf-markdowneditor .md-editor__link-wrap,.bbsf-markdowneditor .md-editor__table-wrap{position:relative;display:inline-flex}.bbsf-markdowneditor .md-editor__link-popover,.bbsf-markdowneditor .md-editor__table-popover{position:absolute;top:calc(100% + 4px);inset-inline-start:0;z-index:1000;color:var(--mde-text);background:var(--mde-popover-bg);border:1px solid var(--mde-popover-border);box-shadow:0 8px 24px #0000002e}.bbsf-markdowneditor .md-editor__link-popover{display:flex;gap:4px;padding:4px;border-radius:6px}.bbsf-markdowneditor .md-editor__link-input{width:200px;padding:4px 6px;font-size:12px;border:1px solid var(--mde-border);border-radius:4px;outline:none;background:transparent;color:inherit}.bbsf-markdowneditor .md-editor__link-input:focus{border-color:var(--mde-primary)}.bbsf-markdowneditor .md-editor__link-ok,.bbsf-markdowneditor .md-editor__link-cancel{width:24px;height:24px;border-radius:4px;border:none;background:transparent;cursor:pointer;color:var(--mde-text-secondary)}.bbsf-markdowneditor .md-editor__link-ok:hover,.bbsf-markdowneditor .md-editor__link-cancel:hover{background:var(--mde-hover)}.bbsf-markdowneditor .md-editor__table-popover{display:flex;flex-direction:column;gap:4px;padding:6px;border-radius:8px}.bbsf-markdowneditor .md-editor__table-group{display:flex;gap:2px}.bbsf-markdowneditor .md-editor__table-group:not(:last-child){padding-bottom:4px;border-bottom:1px solid var(--mde-border)}.bbsf-markdowneditor .md-editor__table-insert{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:6px;border:1px solid transparent;background:transparent;color:inherit;font-size:12px;white-space:nowrap;cursor:pointer}.bbsf-markdowneditor .md-editor__table-insert:hover{background:var(--mde-hover)}.bbsf-markdowneditor .md-editor__btn--danger{color:var(--mde-danger)}.bbsf-markdowneditor .md-editor__btn--danger:hover:not(:disabled){background:var(--mde-danger-subtle)}.bbsf-markdowneditor .md-editor__count{margin-inline-start:auto;padding-inline:6px;font-size:11px;font-variant-numeric:tabular-nums;color:var(--mde-text-secondary)}.bbsf-markdowneditor .md-editor__count--over{color:var(--mde-danger);font-weight:600}.bbsf-markdowneditor .md-editor__body{flex:1;min-height:56px;overflow-y:auto;padding:8px 10px;font-size:13px;line-height:1.55;color:var(--mde-text);cursor:text}.bbsf-markdowneditor .md-editor__body:focus-within{outline:none}:host ::ng-deep .md-editor__prosemirror{outline:none}:host ::ng-deep .md-editor__prosemirror>*{margin-block:0 .5em}:host ::ng-deep .md-editor__prosemirror>:last-child{margin-block-end:0}:host ::ng-deep .md-editor__prosemirror h1{font-size:1.4em;font-weight:700}:host ::ng-deep .md-editor__prosemirror h2{font-size:1.2em;font-weight:700}:host ::ng-deep .md-editor__prosemirror h3{font-size:1.05em;font-weight:700}:host ::ng-deep .md-editor__prosemirror ul,:host ::ng-deep .md-editor__prosemirror ol{padding-inline-start:1.4em}:host ::ng-deep .md-editor__prosemirror a{color:var(--mde-primary);text-decoration:underline;cursor:pointer}:host ::ng-deep .md-editor__prosemirror code{background:var(--mde-code-bg);padding:1px 4px;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.95em}:host ::ng-deep .md-editor__prosemirror pre{background:var(--mde-code-bg);border-radius:6px;padding:8px 10px;overflow-x:auto}:host ::ng-deep .md-editor__prosemirror pre code{background:transparent;padding:0}:host ::ng-deep .md-editor__prosemirror blockquote{margin-inline:0;padding-inline-start:10px;border-inline-start:3px solid var(--mde-border);color:var(--mde-text-secondary)}:host ::ng-deep .md-editor__prosemirror ul[data-type=taskList]{list-style:none;padding-inline-start:.2em}:host ::ng-deep .md-editor__prosemirror ul[data-type=taskList] li{display:flex;align-items:flex-start;gap:6px}:host ::ng-deep .md-editor__prosemirror ul[data-type=taskList] li>label{margin-block-start:.15em}:host ::ng-deep .md-editor__prosemirror .tableWrapper{overflow-x:auto}:host ::ng-deep .md-editor__prosemirror table{border-collapse:collapse;table-layout:fixed;width:100%;margin:0;overflow:hidden}:host ::ng-deep .md-editor__prosemirror table td,:host ::ng-deep .md-editor__prosemirror table th{position:relative;box-sizing:border-box;min-width:3em;padding:4px 8px;border:1px solid var(--mde-border);vertical-align:top;text-align:start}:host ::ng-deep .md-editor__prosemirror table td>*,:host ::ng-deep .md-editor__prosemirror table th>*{margin-block:0}:host ::ng-deep .md-editor__prosemirror table th{font-weight:600;background:var(--mde-th-bg)}:host ::ng-deep .md-editor__prosemirror table .selectedCell:after{content:\"\";position:absolute;inset:0;background:var(--mde-cell-selected);pointer-events:none;z-index:2}:host ::ng-deep .md-editor__prosemirror table .column-resize-handle{position:absolute;inset-inline-end:-2px;inset-block:0;width:4px;background:var(--mde-primary);cursor:col-resize}:host ::ng-deep .md-editor__prosemirror.resize-cursor{cursor:col-resize}:host ::ng-deep .md-editor__prosemirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--mde-text-secondary);float:inline-start;pointer-events:none;height:0}:host ::ng-deep .ProseMirror-gapcursor{display:none;pointer-events:none;position:absolute}:host ::ng-deep .ProseMirror-gapcursor:after{content:\"\";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid var(--mde-text, currentColor);animation:md-editor-gapcursor-blink 1.1s steps(2,start) infinite}:host ::ng-deep .ProseMirror-focused .ProseMirror-gapcursor{display:block}@keyframes md-editor-gapcursor-blink{to{visibility:hidden}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
6616
6781
  }
6617
6782
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MarkdownEditorComponent, decorators: [{
6618
6783
  type: Component,
6619
6784
  args: [{ selector: 'BBSF-MarkdownEditor', standalone: true, imports: [
6620
6785
  CommonModule,
6621
6786
  FormsModule,
6622
- ReactiveFormsModule,
6623
- LMarkdownEditorModule,
6624
- ScriptLoaderModule
6625
- ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], template: "<ng-container *ngIf=\"showMarkdown\">\r\n <div class=\"form-group bbsf-control bbsf-htmleditor\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"bbsf-input-container {{options.extraClasses}}\">\r\n <md-editor id=\"{{options.name}}\" formControlName=\"{{options.name}}\"\r\n (onPreviewDomChanged)=\"onPreviewDomChanged($event)\"\r\n [(ngModel)]=\"options.value\" [mode]=\"mode\" [options]=\"editorOptions\" [attr.required]=\"options.isRequired ? true : null\" [upload]=\"onDragFile\" \r\n [maxlength]=\"options.maxLength\" [height]=\"options.height\" [locale]=\"currentLocale\" (onEditorLoaded)=\"onEditorLoaded($event)\" [hideToolbar]=\"hideToolbar\">\r\n <!-- [ngStyle]=\"{ 'direction': textDirection, 'text-align': textDirection === 'rtl' ? 'right' : 'left' }\" -->\r\n <div custom-btns>\r\n <input #imgInput type=\"file\" style=\"display: none\" (change)=\"uploadImg($event)\" />\r\n <button type=\"button\" class=\"btn btn-sm btn-default\" (click)=\"imgInput.click()\">\r\n {{utilityService.getResourceValue(\"UploadImg\")}}\r\n </button>\r\n </div>\r\n </md-editor>\r\n </div>\r\n\r\n <div class=\"subtext-container\">\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div class=\"bbsf-validation\" *ngIf=\"(markdownEditorFormControl.invalid && markdownEditorFormControl.touched)\">\r\n {{getErrorValidation(markdownEditorFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n </div>\r\n</ng-container>\r\n" }]
6626
- }], ctorParameters: () => [{ type: i3.UtilityService }, { type: GlobalSettings }, { type: i3.ControlValidationService }, { type: ControlUtility }, { type: i2.FormGroupDirective }, { type: i5$2.ScriptService }, { type: i2.ControlContainer, decorators: [{
6787
+ ReactiveFormsModule
6788
+ ], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"form-group bbsf-control bbsf-htmleditor bbsf-markdowneditor\" [formGroup]=\"group\">\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\n {{options.labelValue}}\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\n class=\"text-danger\">*</span>\n </label>\n\n <div class=\"bbsf-input-container {{options.extraClasses}}\">\n <div class=\"md-editor\" [style.height]=\"editorHeight\">\n <div class=\"md-editor__toolbar\" role=\"toolbar\" [attr.aria-label]=\"utilityService.getResourceValue('FormattingToolbar') || 'Formatting toolbar'\">\n @for (item of toolbarItems; track $index) {\n @switch (item) {\n @case ('|') {\n <span class=\"md-editor__divider\" aria-hidden=\"true\"></span>\n }\n @case ('link') {\n <div class=\"md-editor__link-wrap\">\n <button type=\"button\" class=\"md-editor__btn\" [class.is-active]=\"isActive('link')\"\n [disabled]=\"disabled('link')\" (click)=\"openLinkPopover()\" title=\"Link\" aria-label=\"Link\">\n <i class=\"pi pi-link\" aria-hidden=\"true\"></i>\n </button>\n @if (showLinkPopover()) {\n <div class=\"md-editor__link-popover\" role=\"dialog\" aria-label=\"Link\">\n <input class=\"md-editor__link-input\" type=\"url\"\n [value]=\"linkInputValue()\" (input)=\"onLinkInput($any($event.target).value)\"\n (keydown)=\"onLinkKeydown($event)\"\n placeholder=\"https://...\" aria-label=\"Link URL\" />\n <button type=\"button\" class=\"md-editor__link-ok\" (click)=\"commitLink()\" title=\"Apply\">\n <i class=\"pi pi-check\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"md-editor__link-cancel\" (click)=\"cancelLink()\" title=\"Cancel\">\n <i class=\"pi pi-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n }\n @case ('table') {\n <div class=\"md-editor__table-wrap\">\n <button type=\"button\" class=\"md-editor__btn\" [class.is-active]=\"isActive('table') || showTablePopover()\"\n [disabled]=\"disabled('table')\" (click)=\"toggleTablePopover()\" [attr.aria-expanded]=\"showTablePopover()\"\n aria-haspopup=\"menu\" title=\"Table\" aria-label=\"Table\">\n <i class=\"pi pi-table\" aria-hidden=\"true\"></i>\n </button>\n @if (showTablePopover()) {\n <div class=\"md-editor__table-popover\" role=\"menu\" aria-label=\"Table\">\n @if (inTable()) {\n @for (group of tableMenuGroups; track $index) {\n <div class=\"md-editor__table-group\" role=\"group\">\n @for (id of group; track id) {\n <button type=\"button\" class=\"md-editor__btn\" role=\"menuitem\"\n [class.md-editor__btn--danger]=\"id === 'deleteTable'\"\n (click)=\"tableOp(id)\"\n [title]=\"tableOpMeta(id).label\" [attr.aria-label]=\"tableOpMeta(id).label\">\n <i class=\"pi {{ tableOpMeta(id).icon }}\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n } @else {\n <button type=\"button\" class=\"md-editor__table-insert\" role=\"menuitem\" (click)=\"insertTable()\">\n <i class=\"pi pi-table\" aria-hidden=\"true\"></i>\n <span>Insert table</span>\n </button>\n }\n </div>\n }\n </div>\n }\n @default {\n <button type=\"button\" class=\"md-editor__btn\"\n [class.is-active]=\"isActive(item)\" [disabled]=\"disabled(item)\"\n (click)=\"run(item)\"\n [title]=\"button(item)?.label ?? ''\" [attr.aria-label]=\"button(item)?.label ?? ''\">\n @if (textLabel(item); as txt) {\n <span class=\"md-editor__btn-text\">{{ txt }}</span>\n } @else {\n <i class=\"pi {{ button(item)?.icon }}\" aria-hidden=\"true\"></i>\n }\n </button>\n }\n }\n }\n @if (maxLength !== null) {\n <span class=\"md-editor__count\" [class.md-editor__count--over]=\"isOverLimit()\"\n aria-live=\"polite\">{{ characters() }} / {{ maxLength }}</span>\n }\n </div>\n\n <div #editorBody class=\"md-editor__body\"\n [attr.aria-label]=\"options.labelValue || options.name\"\n [attr.data-placeholder]=\"options.placeholder || ''\"></div>\n </div>\n </div>\n\n <div class=\"subtext-container\">\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\n <div class=\"bbsf-validation\" *ngIf=\"(markdownEditorFormControl.invalid && markdownEditorFormControl.touched)\">\n {{getErrorValidation(markdownEditorFormControl.errors|keyvalue)}}\n </div>\n </div>\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\n {{resetError()}}</div>\n </div>\n</div>\n", styles: [":host{display:block;--mde-text: #1d1d1f;--mde-text-secondary: #6e6e73;--mde-border: rgba(0, 0, 0, .14);--mde-hover: rgba(0, 0, 0, .05);--mde-primary: #1b84ff;--mde-primary-subtle: rgba(27, 132, 255, .12);--mde-popover-bg: #ffffff;--mde-popover-border: rgba(0, 0, 0, .12);--mde-danger: #d70015;--mde-danger-subtle: rgba(215, 0, 21, .1);--mde-cell-selected: rgba(27, 132, 255, .15);--mde-th-bg: rgba(0, 0, 0, .04);--mde-code-bg: rgba(0, 0, 0, .06)}.bbsf-markdowneditor .md-editor{display:flex;flex-direction:column;min-height:180px;position:relative;color:var(--mde-text);border:1px solid var(--mde-border);border-radius:.475rem;background:#fff;overflow:visible}.bbsf-markdowneditor .md-editor__toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:4px 6px;border-bottom:1px solid var(--mde-border)}.bbsf-markdowneditor .md-editor__divider{width:1px;height:18px;margin-inline:4px;background:var(--mde-border)}.bbsf-markdowneditor .md-editor__btn{min-width:28px;height:28px;padding-inline:7px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--mde-text-secondary);font-size:12px;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.bbsf-markdowneditor .md-editor__btn:hover:not(:disabled){background:var(--mde-hover)}.bbsf-markdowneditor .md-editor__btn.is-active{background:var(--mde-primary-subtle);color:var(--mde-primary);border-color:var(--mde-primary-subtle)}.bbsf-markdowneditor .md-editor__btn:disabled{opacity:.4;cursor:default}.bbsf-markdowneditor .md-editor__btn i.pi{font-size:13px}.bbsf-markdowneditor .md-editor__btn-text{font-weight:600;font-style:normal}.bbsf-markdowneditor .md-editor__link-wrap,.bbsf-markdowneditor .md-editor__table-wrap{position:relative;display:inline-flex}.bbsf-markdowneditor .md-editor__link-popover,.bbsf-markdowneditor .md-editor__table-popover{position:absolute;top:calc(100% + 4px);inset-inline-start:0;z-index:1000;color:var(--mde-text);background:var(--mde-popover-bg);border:1px solid var(--mde-popover-border);box-shadow:0 8px 24px #0000002e}.bbsf-markdowneditor .md-editor__link-popover{display:flex;gap:4px;padding:4px;border-radius:6px}.bbsf-markdowneditor .md-editor__link-input{width:200px;padding:4px 6px;font-size:12px;border:1px solid var(--mde-border);border-radius:4px;outline:none;background:transparent;color:inherit}.bbsf-markdowneditor .md-editor__link-input:focus{border-color:var(--mde-primary)}.bbsf-markdowneditor .md-editor__link-ok,.bbsf-markdowneditor .md-editor__link-cancel{width:24px;height:24px;border-radius:4px;border:none;background:transparent;cursor:pointer;color:var(--mde-text-secondary)}.bbsf-markdowneditor .md-editor__link-ok:hover,.bbsf-markdowneditor .md-editor__link-cancel:hover{background:var(--mde-hover)}.bbsf-markdowneditor .md-editor__table-popover{display:flex;flex-direction:column;gap:4px;padding:6px;border-radius:8px}.bbsf-markdowneditor .md-editor__table-group{display:flex;gap:2px}.bbsf-markdowneditor .md-editor__table-group:not(:last-child){padding-bottom:4px;border-bottom:1px solid var(--mde-border)}.bbsf-markdowneditor .md-editor__table-insert{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:6px;border:1px solid transparent;background:transparent;color:inherit;font-size:12px;white-space:nowrap;cursor:pointer}.bbsf-markdowneditor .md-editor__table-insert:hover{background:var(--mde-hover)}.bbsf-markdowneditor .md-editor__btn--danger{color:var(--mde-danger)}.bbsf-markdowneditor .md-editor__btn--danger:hover:not(:disabled){background:var(--mde-danger-subtle)}.bbsf-markdowneditor .md-editor__count{margin-inline-start:auto;padding-inline:6px;font-size:11px;font-variant-numeric:tabular-nums;color:var(--mde-text-secondary)}.bbsf-markdowneditor .md-editor__count--over{color:var(--mde-danger);font-weight:600}.bbsf-markdowneditor .md-editor__body{flex:1;min-height:56px;overflow-y:auto;padding:8px 10px;font-size:13px;line-height:1.55;color:var(--mde-text);cursor:text}.bbsf-markdowneditor .md-editor__body:focus-within{outline:none}:host ::ng-deep .md-editor__prosemirror{outline:none}:host ::ng-deep .md-editor__prosemirror>*{margin-block:0 .5em}:host ::ng-deep .md-editor__prosemirror>:last-child{margin-block-end:0}:host ::ng-deep .md-editor__prosemirror h1{font-size:1.4em;font-weight:700}:host ::ng-deep .md-editor__prosemirror h2{font-size:1.2em;font-weight:700}:host ::ng-deep .md-editor__prosemirror h3{font-size:1.05em;font-weight:700}:host ::ng-deep .md-editor__prosemirror ul,:host ::ng-deep .md-editor__prosemirror ol{padding-inline-start:1.4em}:host ::ng-deep .md-editor__prosemirror a{color:var(--mde-primary);text-decoration:underline;cursor:pointer}:host ::ng-deep .md-editor__prosemirror code{background:var(--mde-code-bg);padding:1px 4px;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.95em}:host ::ng-deep .md-editor__prosemirror pre{background:var(--mde-code-bg);border-radius:6px;padding:8px 10px;overflow-x:auto}:host ::ng-deep .md-editor__prosemirror pre code{background:transparent;padding:0}:host ::ng-deep .md-editor__prosemirror blockquote{margin-inline:0;padding-inline-start:10px;border-inline-start:3px solid var(--mde-border);color:var(--mde-text-secondary)}:host ::ng-deep .md-editor__prosemirror ul[data-type=taskList]{list-style:none;padding-inline-start:.2em}:host ::ng-deep .md-editor__prosemirror ul[data-type=taskList] li{display:flex;align-items:flex-start;gap:6px}:host ::ng-deep .md-editor__prosemirror ul[data-type=taskList] li>label{margin-block-start:.15em}:host ::ng-deep .md-editor__prosemirror .tableWrapper{overflow-x:auto}:host ::ng-deep .md-editor__prosemirror table{border-collapse:collapse;table-layout:fixed;width:100%;margin:0;overflow:hidden}:host ::ng-deep .md-editor__prosemirror table td,:host ::ng-deep .md-editor__prosemirror table th{position:relative;box-sizing:border-box;min-width:3em;padding:4px 8px;border:1px solid var(--mde-border);vertical-align:top;text-align:start}:host ::ng-deep .md-editor__prosemirror table td>*,:host ::ng-deep .md-editor__prosemirror table th>*{margin-block:0}:host ::ng-deep .md-editor__prosemirror table th{font-weight:600;background:var(--mde-th-bg)}:host ::ng-deep .md-editor__prosemirror table .selectedCell:after{content:\"\";position:absolute;inset:0;background:var(--mde-cell-selected);pointer-events:none;z-index:2}:host ::ng-deep .md-editor__prosemirror table .column-resize-handle{position:absolute;inset-inline-end:-2px;inset-block:0;width:4px;background:var(--mde-primary);cursor:col-resize}:host ::ng-deep .md-editor__prosemirror.resize-cursor{cursor:col-resize}:host ::ng-deep .md-editor__prosemirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--mde-text-secondary);float:inline-start;pointer-events:none;height:0}:host ::ng-deep .ProseMirror-gapcursor{display:none;pointer-events:none;position:absolute}:host ::ng-deep .ProseMirror-gapcursor:after{content:\"\";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid var(--mde-text, currentColor);animation:md-editor-gapcursor-blink 1.1s steps(2,start) infinite}:host ::ng-deep .ProseMirror-focused .ProseMirror-gapcursor{display:block}@keyframes md-editor-gapcursor-blink{to{visibility:hidden}}\n"] }]
6789
+ }], ctorParameters: () => [{ type: i3.UtilityService }, { type: GlobalSettings }, { type: i3.ControlValidationService }, { type: ControlUtility }, { type: i2.FormGroupDirective }, { type: i0.ChangeDetectorRef }, { type: i2.ControlContainer, decorators: [{
6627
6790
  type: Optional
6628
6791
  }] }], propDecorators: { group: [{
6629
6792
  type: Input
@@ -6631,6 +6794,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImpo
6631
6794
  type: Input
6632
6795
  }], OnChange: [{
6633
6796
  type: Output
6797
+ }], editorBody: [{
6798
+ type: ViewChild,
6799
+ args: ['editorBody', { static: true }]
6634
6800
  }] } });
6635
6801
 
6636
6802
  class MultiLingualHtmlEditorComponent {
@@ -7080,13 +7246,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImpo
7080
7246
  *
7081
7247
  * Contains rich text editor controls (~800 KB gzipped):
7082
7248
  * - HtmlEditorComponent: WYSIWYG HTML editor
7083
- * - MarkdownEditorComponent: Markdown editor with preview
7249
+ * - MarkdownEditorComponent: Tiptap-powered markdown editor
7084
7250
  * - MultiLingualHtmlEditorComponent: HTML editor with multilingual support
7085
7251
  *
7086
7252
  * Dependencies:
7087
7253
  * - @kolkov/angular-editor (~300 KB)
7088
- * - ngx-markdown-editor (~400 KB)
7089
- * - ngx-script-loader
7254
+ * - Tiptap
7090
7255
  *
7091
7256
  * @example New way (Recommended):
7092
7257
  * ```typescript
@@ -7113,7 +7278,6 @@ class BBSFEditorsModule {
7113
7278
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: BBSFEditorsModule, imports: [CommonModule,
7114
7279
  FormsModule,
7115
7280
  ReactiveFormsModule,
7116
- LMarkdownEditorModule,
7117
7281
  BBSFUtilitiesModule,
7118
7282
  // Import standalone components
7119
7283
  HtmlEditorComponent,
@@ -7126,7 +7290,6 @@ class BBSFEditorsModule {
7126
7290
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: BBSFEditorsModule, imports: [CommonModule,
7127
7291
  FormsModule,
7128
7292
  ReactiveFormsModule,
7129
- LMarkdownEditorModule,
7130
7293
  BBSFUtilitiesModule,
7131
7294
  // Import standalone components
7132
7295
  HtmlEditorComponent,
@@ -7141,7 +7304,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImpo
7141
7304
  CommonModule,
7142
7305
  FormsModule,
7143
7306
  ReactiveFormsModule,
7144
- LMarkdownEditorModule,
7145
7307
  BBSFUtilitiesModule,
7146
7308
  // Import standalone components
7147
7309
  HtmlEditorComponent,
@@ -7917,7 +8079,7 @@ class FileUploadComponent {
7917
8079
  this.OnChange.emit(value);
7918
8080
  }
7919
8081
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: FileUploadComponent, deps: [{ token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: ControlUtility }, { token: i3.UtilityService }, { token: i3.ControlValidationService }, { token: GlobalSettings }, { token: FileUploadService }], target: i0.ɵɵFactoryTarget.Component }); }
7920
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: FileUploadComponent, isStandalone: true, selector: "BBSF-FileUpload", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange", isUploadComplete: "isUploadComplete" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType == 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk && options.isRequired) || options.isRequired) && !options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !(options.isMultipleFile == false && uploader.queue.length > 0) && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" id=\"{{ options.name }}\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" aria-invalid=\"true\" type=\"file\"\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputDropZone.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ dropHeaderLabel }}\r\n </div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInputDropZone\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg text-center\">{{ headerLabel }}</div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly && !options.value\">\r\n <span class=\"readonly-view\">{{ UtilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!--items uploaded-->\r\n <div class=\"uploaded-items\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue\">\r\n <ng-container *ngIf=\"item?.progress == 100 && options.isUploadFileAsync\">\r\n <a *ngIf=\"item?.file?.rawFile['url']\" href=\"{{ item?.file?.rawFile['url'] }}\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" download>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <a href=\"{{ item?.file?.rawFile['url'] }}\" *ngIf=\"item?.file?.rawFile['url']\" class=\"btn btn-download-file btn-sm\" download>\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm btn-danger\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <i class=\"fa fa-times px-0\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!--progress bar file upload-->\r\n <div *ngFor=\"let item of uploader.queue\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile == true }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync\">\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ item?.file?.name }}</h4>\r\n <span (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"70\" aria-valuemin=\"0\" aria-valuemax=\"100\"\r\n [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\" *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"maxFilesReached\">\r\n {{maxFilesValidationMsg}}\r\n </div>\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n {{ getErrorValidation(fileUploadFormControl.errors | keyvalue) }}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription != null\">{{ options.labelDescription }}</div>\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "directive", type: i5$3.FileDropDirective, selector: "[ng2FileDrop]", inputs: ["uploader"], outputs: ["fileOver", "onFileDrop"] }, { kind: "directive", type: i5$3.FileSelectDirective, selector: "[ng2FileSelect]", inputs: ["uploader"], outputs: ["onFileSelected"] }, { kind: "ngmodule", type: NgxDropzoneModule }] }); }
8082
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: FileUploadComponent, isStandalone: true, selector: "BBSF-FileUpload", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange", isUploadComplete: "isUploadComplete" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType == 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk && options.isRequired) || options.isRequired) && !options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !(options.isMultipleFile == false && uploader.queue.length > 0) && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" id=\"{{ options.name }}\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" aria-invalid=\"true\" type=\"file\"\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputDropZone.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ dropHeaderLabel }}\r\n </div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInputDropZone\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg text-center\">{{ headerLabel }}</div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-invalid=\"true\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly && !options.value\">\r\n <span class=\"readonly-view\">{{ UtilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!--items uploaded-->\r\n <div class=\"uploaded-items\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue\">\r\n <ng-container *ngIf=\"item?.progress == 100 && options.isUploadFileAsync\">\r\n <a *ngIf=\"item?.file?.rawFile['url']\" href=\"{{ item?.file?.rawFile['url'] }}\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" download>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <a href=\"{{ item?.file?.rawFile['url'] }}\" *ngIf=\"item?.file?.rawFile['url']\" class=\"btn btn-download-file btn-sm\" download>\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ sanitizeFileName(item?.file?.name || '') }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm btn-danger\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <i class=\"fa fa-times px-0\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!--progress bar file upload-->\r\n <div *ngFor=\"let item of uploader.queue\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile == true }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync\">\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ item?.file?.name }}</h4>\r\n <span (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"70\" aria-valuemin=\"0\" aria-valuemax=\"100\"\r\n [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\" *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"maxFilesReached\">\r\n {{maxFilesValidationMsg}}\r\n </div>\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n {{ getErrorValidation(fileUploadFormControl.errors | keyvalue) }}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription != null\">{{ options.labelDescription }}</div>\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "directive", type: i5$2.FileDropDirective, selector: "[ng2FileDrop]", inputs: ["uploader"], outputs: ["fileOver", "onFileDrop"] }, { kind: "directive", type: i5$2.FileSelectDirective, selector: "[ng2FileSelect]", inputs: ["uploader"], outputs: ["onFileSelected"] }, { kind: "ngmodule", type: NgxDropzoneModule }] }); }
7921
8083
  }
7922
8084
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: FileUploadComponent, decorators: [{
7923
8085
  type: Component,
@@ -8261,7 +8423,7 @@ class ImageUploaderComponent {
8261
8423
  this.mdlSampleIsOpen = open;
8262
8424
  }
8263
8425
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ImageUploaderComponent, deps: [{ token: i0.NgZone }, { token: ControlUtility }, { token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: i3.UtilityService }, { token: i3.ControlValidationService }, { token: GlobalSettings }, { token: i3$2.NgbModal }], target: i0.ɵɵFactoryTarget.Component }); }
8264
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: ImageUploaderComponent, isStandalone: true, selector: "BBSF-ImageUpload", inputs: { group: "group", options: "options" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "angularCropper", first: true, predicate: ["angularCropper"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-image-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div *ngIf=\"options.allowDropZone&&!options.isReadonly\" class=\"bbsf-input-container {{options.extraClasses}}\"\r\n ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\" [multiple]=\"options.isMultiple\"\r\n (change)=\"onFileChange($event)\" ngDefaultControl formControlName=\"{{options.name}}\" [maxFileSize]=\"maxFileSize\"\r\n id=\"{{options.name}}\" [class.is-invalid]=\"imageUploadFormControl.invalid && imageUploadFormControl.touched\">\r\n <ngx-dropzone-label class=\"dropzone-label\">\r\n <img *ngIf=\"imageSource\" [src]=\"imageSource\"\r\n style=\"align-items: center;border-radius: 5px;display: flex;height: 100px;justify-content: center;margin: 10px;max-width: 180px;min-height: 100px;min-width: 180px;padding: 0px 20px;position: relative;\" />\r\n <div class=\"svg-and-validation\" *ngIf=\"!imageSource\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"\r\n style=\"width: 50px; height: 50px;\">\r\n <path opacity=\"0.3\"\r\n d=\"M5 16C3.3 16 2 14.7 2 13C2 11.3 3.3 10 5 10H5.1C5 9.7 5 9.3 5 9C5 6.2 7.2 4 10 4C11.9 4 13.5 5 14.3 6.5C14.8 6.2 15.4 6 16 6C17.7 6 19 7.3 19 9C19 9.4 18.9 9.7 18.8 10C18.9 10 18.9 10 19 10C20.7 10 22 11.3 22 13C22 14.7 20.7 16 19 16H5ZM8 13.6H16L12.7 10.3C12.3 9.89999 11.7 9.89999 11.3 10.3L8 13.6Z\"\r\n fill=\"currentColor\" style=\"fill: #a1a1a1;\"></path>\r\n <path d=\"M11 13.6V19C11 19.6 11.4 20 12 20C12.6 20 13 19.6 13 19V13.6H11Z\" fill=\"currentColor\"\r\n style=\"fill: #989898;\"></path>\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </ngx-dropzone-label>\r\n <ngx-dropzone-image-preview class=\"dropzone-preview\" *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div *ngIf=\"!options.allowDropZone&&!options.isReadonly\">\r\n <ngx-dropzone-label *ngIf=\"files.length==0\">\r\n <div #element (click)=\"showImageUploader(element)\">\r\n <img [src]=\"imageSource\" />\r\n </div>\r\n </ngx-dropzone-label>\r\n <div class=\"d-none {{options.extraClasses}}\" ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\"\r\n [multiple]=\"options.isMultiple\" (change)=\"onFileChange($event)\" ngDefaultControl\r\n formControlName=\"{{options.name}}\" [maxFileSize]=\"maxFileSize\" id=\"{{options.name}}\"\r\n [class.is-invalid]=\"imageUploadFormControl.invalid && imageUploadFormControl.touched\">\r\n </div>\r\n <ngx-dropzone-image-preview *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n\r\n <ngx-dropzone-label *ngIf=\"files.length==0&&options.isReadonly\">\r\n <div *ngIf=\"imageSource\" #element>\r\n <img [src]=\"imageSource\" />\r\n </div>\r\n <div *ngIf=\"!imageSource\">\r\n <span class=\"readonly-view\">{{utilityService.getResourceValue('NA')}}</span>\r\n </div>\r\n </ngx-dropzone-label>\r\n </div>\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"(imageUploadFormControl.invalid && imageUploadFormControl.touched)\">\r\n {{getErrorValidation(imageUploadFormControl.errors|keyvalue)}}\r\n </div>\r\n\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n <!-- image cropper modal-->\r\n <div id=\"mdlSample\" class=\"modal bbsf-cropper-modal\" role=\"dialog\"\r\n [ngStyle]=\"{'display': mdlSampleIsOpen ? 'block' : 'none', 'opacity': 1}\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">\r\n {{utilityService.getResourceValue(\"CropImage\")}}\r\n </h4>\r\n <button type=\"button\" class=\"btn-close\" data-dismiss=\"modal\" (click)=\"openModal(false)\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"imageUrl\">\r\n <angular-cropper #angularCropper [cropperOptions]=\"config\" [imageUrl]=\"imageUrl\">\r\n </angular-cropper>\r\n <img [src]=\"imgwUrl\" />\r\n </div>\r\n <div class=\"cropper-btns\">\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"zoomImage(0.1)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"ZoomIn\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-plus\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"zoomImage(-0.1)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"ZoomOut\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-minus\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"moveImage(-10,0)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveLeft\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-left\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(10,0)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveRight\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-right\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,-10)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveUp\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-up\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,10)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveDown\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-down\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"rotateImage(-45)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"RotateLeft\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-undo-alt\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"rotateImage(45)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"RotateRight\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-redo-alt\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\" align=\"right\">\r\n <button type=\"button\" id=\"btnClose\" class=\"btn btn-sm btn-light\" (click)=\"openModal(false)\">\r\n {{utilityService.getResourceValue(\"CancelLabel\")}}\r\n </button>\r\n <button type=\"button\" (click)=\"cropImage()\" id=\"btnOK\" class=\"btn btn-sm btn-brand\">\r\n {{utilityService.getResourceValue(\"Crop\")}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- readonly -->\r\n\r\n\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: NgxDropzoneModule }, { kind: "component", type: i7$4.NgxDropzoneComponent, selector: "ngx-dropzone, [ngx-dropzone]", inputs: ["accept", "disabled", "multiple", "maxFileSize", "expandable", "disableClick", "processDirectoryDrop", "id", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["change"] }, { kind: "directive", type: i7$4.NgxDropzoneLabelDirective, selector: "ngx-dropzone-label" }, { kind: "component", type: i7$4.NgxDropzoneImagePreviewComponent, selector: "ngx-dropzone-image-preview", inputs: ["file"] }, { kind: "ngmodule", type: AngularCropperjsModule }, { kind: "component", type: i8.CropperComponent, selector: "angular-cropper", inputs: ["imageUrl", "settings", "cropbox", "loadImageErrorText", "cropperOptions"], outputs: ["export", "ready"] }, { kind: "ngmodule", type: NgbModule }, { kind: "directive", type: i3$2.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }] }); }
8426
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: ImageUploaderComponent, isStandalone: true, selector: "BBSF-ImageUpload", inputs: { group: "group", options: "options" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "angularCropper", first: true, predicate: ["angularCropper"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-image-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div *ngIf=\"options.allowDropZone&&!options.isReadonly\" class=\"bbsf-input-container {{options.extraClasses}}\"\r\n ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\" [multiple]=\"options.isMultiple\"\r\n (change)=\"onFileChange($event)\" ngDefaultControl formControlName=\"{{options.name}}\" [maxFileSize]=\"maxFileSize\"\r\n id=\"{{options.name}}\" [class.is-invalid]=\"imageUploadFormControl.invalid && imageUploadFormControl.touched\">\r\n <ngx-dropzone-label class=\"dropzone-label\">\r\n <img *ngIf=\"imageSource\" [src]=\"imageSource\"\r\n style=\"align-items: center;border-radius: 5px;display: flex;height: 100px;justify-content: center;margin: 10px;max-width: 180px;min-height: 100px;min-width: 180px;padding: 0px 20px;position: relative;\" />\r\n <div class=\"svg-and-validation\" *ngIf=\"!imageSource\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"\r\n style=\"width: 50px; height: 50px;\">\r\n <path opacity=\"0.3\"\r\n d=\"M5 16C3.3 16 2 14.7 2 13C2 11.3 3.3 10 5 10H5.1C5 9.7 5 9.3 5 9C5 6.2 7.2 4 10 4C11.9 4 13.5 5 14.3 6.5C14.8 6.2 15.4 6 16 6C17.7 6 19 7.3 19 9C19 9.4 18.9 9.7 18.8 10C18.9 10 18.9 10 19 10C20.7 10 22 11.3 22 13C22 14.7 20.7 16 19 16H5ZM8 13.6H16L12.7 10.3C12.3 9.89999 11.7 9.89999 11.3 10.3L8 13.6Z\"\r\n fill=\"currentColor\" style=\"fill: #a1a1a1;\"></path>\r\n <path d=\"M11 13.6V19C11 19.6 11.4 20 12 20C12.6 20 13 19.6 13 19V13.6H11Z\" fill=\"currentColor\"\r\n style=\"fill: #989898;\"></path>\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </ngx-dropzone-label>\r\n <ngx-dropzone-image-preview class=\"dropzone-preview\" *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div *ngIf=\"!options.allowDropZone&&!options.isReadonly\">\r\n <ngx-dropzone-label *ngIf=\"files.length==0\">\r\n <div #element (click)=\"showImageUploader(element)\">\r\n <img [src]=\"imageSource\" />\r\n </div>\r\n </ngx-dropzone-label>\r\n <div class=\"d-none {{options.extraClasses}}\" ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\"\r\n [multiple]=\"options.isMultiple\" (change)=\"onFileChange($event)\" ngDefaultControl\r\n formControlName=\"{{options.name}}\" [maxFileSize]=\"maxFileSize\" id=\"{{options.name}}\"\r\n [class.is-invalid]=\"imageUploadFormControl.invalid && imageUploadFormControl.touched\">\r\n </div>\r\n <ngx-dropzone-image-preview *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n\r\n <ngx-dropzone-label *ngIf=\"files.length==0&&options.isReadonly\">\r\n <div *ngIf=\"imageSource\" #element>\r\n <img [src]=\"imageSource\" />\r\n </div>\r\n <div *ngIf=\"!imageSource\">\r\n <span class=\"readonly-view\">{{utilityService.getResourceValue('NA')}}</span>\r\n </div>\r\n </ngx-dropzone-label>\r\n </div>\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"(imageUploadFormControl.invalid && imageUploadFormControl.touched)\">\r\n {{getErrorValidation(imageUploadFormControl.errors|keyvalue)}}\r\n </div>\r\n\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n <!-- image cropper modal-->\r\n <div id=\"mdlSample\" class=\"modal bbsf-cropper-modal\" role=\"dialog\"\r\n [ngStyle]=\"{'display': mdlSampleIsOpen ? 'block' : 'none', 'opacity': 1}\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">\r\n {{utilityService.getResourceValue(\"CropImage\")}}\r\n </h4>\r\n <button type=\"button\" class=\"btn-close\" data-dismiss=\"modal\" (click)=\"openModal(false)\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"imageUrl\">\r\n <angular-cropper #angularCropper [cropperOptions]=\"config\" [imageUrl]=\"imageUrl\">\r\n </angular-cropper>\r\n <img [src]=\"imgwUrl\" />\r\n </div>\r\n <div class=\"cropper-btns\">\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"zoomImage(0.1)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"ZoomIn\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-plus\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"zoomImage(-0.1)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"ZoomOut\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-minus\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"moveImage(-10,0)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveLeft\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-left\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(10,0)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveRight\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-right\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,-10)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveUp\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-up\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,10)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"MoveDown\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-down\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"rotateImage(-45)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"RotateLeft\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-undo-alt\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"rotateImage(45)\" class=\"btn btn-default\"\r\n ngbTooltip='{{utilityService.getResourceValue(\"RotateRight\")}}'>\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-redo-alt\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\" align=\"right\">\r\n <button type=\"button\" id=\"btnClose\" class=\"btn btn-sm btn-light\" (click)=\"openModal(false)\">\r\n {{utilityService.getResourceValue(\"CancelLabel\")}}\r\n </button>\r\n <button type=\"button\" (click)=\"cropImage()\" id=\"btnOK\" class=\"btn btn-sm btn-brand\">\r\n {{utilityService.getResourceValue(\"Crop\")}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- readonly -->\r\n\r\n\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: NgxDropzoneModule }, { kind: "component", type: i7$3.NgxDropzoneComponent, selector: "ngx-dropzone, [ngx-dropzone]", inputs: ["accept", "disabled", "multiple", "maxFileSize", "expandable", "disableClick", "processDirectoryDrop", "id", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["change"] }, { kind: "directive", type: i7$3.NgxDropzoneLabelDirective, selector: "ngx-dropzone-label" }, { kind: "component", type: i7$3.NgxDropzoneImagePreviewComponent, selector: "ngx-dropzone-image-preview", inputs: ["file"] }, { kind: "ngmodule", type: AngularCropperjsModule }, { kind: "component", type: i8.CropperComponent, selector: "angular-cropper", inputs: ["imageUrl", "settings", "cropbox", "loadImageErrorText", "cropperOptions"], outputs: ["export", "ready"] }, { kind: "ngmodule", type: NgbModule }, { kind: "directive", type: i3$2.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }] }); }
8265
8427
  }
8266
8428
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ImageUploaderComponent, decorators: [{
8267
8429
  type: Component,
@@ -8637,7 +8799,7 @@ class ProfileImageUploaderComponent {
8637
8799
  this.mdlSampleIsOpen = open;
8638
8800
  }
8639
8801
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ProfileImageUploaderComponent, deps: [{ token: i0.NgZone }, { token: ControlUtility }, { token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: i3.UtilityService }, { token: i3.ControlValidationService }, { token: GlobalSettings }], target: i0.ɵɵFactoryTarget.Component }); }
8640
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: ProfileImageUploaderComponent, isStandalone: true, selector: "BBSF-ProfileImageUploader", inputs: { group: "group", options: "options" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "angularCropper", first: true, predicate: ["angularCropper"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-profile-image-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div *ngIf=\"options.allowDropZone&&!options.isReadonly\" class=\"bbsf-input-container {{options.extraClasses}}\"\r\n ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\" (change)=\"onFileChange($event)\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\" ngDefaultControl formControlName=\"{{options.name}}\"\r\n id=\"{{options.name}}\"\r\n [class.is-invalid]=\"profileImageUploadFormControl.invalid && profileImageUploadFormControl.touched\">\r\n <ngx-dropzone-label class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"\r\n style=\"width: 50px; height: 50px;\">\r\n <path opacity=\"0.3\"\r\n d=\"M5 16C3.3 16 2 14.7 2 13C2 11.3 3.3 10 5 10H5.1C5 9.7 5 9.3 5 9C5 6.2 7.2 4 10 4C11.9 4 13.5 5 14.3 6.5C14.8 6.2 15.4 6 16 6C17.7 6 19 7.3 19 9C19 9.4 18.9 9.7 18.8 10C18.9 10 18.9 10 19 10C20.7 10 22 11.3 22 13C22 14.7 20.7 16 19 16H5ZM8 13.6H16L12.7 10.3C12.3 9.89999 11.7 9.89999 11.3 10.3L8 13.6Z\"\r\n fill=\"currentColor\" style=\"fill: #a1a1a1;\"></path>\r\n <path d=\"M11 13.6V19C11 19.6 11.4 20 12 20C12.6 20 13 19.6 13 19V13.6H11Z\" fill=\"currentColor\"\r\n style=\"fill: #989898;\"></path>\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </ngx-dropzone-label>\r\n <ngx-dropzone-image-preview class=\"dropzone-preview\" *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div *ngIf=\"!options.allowDropZone&&!options.isReadonly\" style=\"width:fit-content\">\r\n <ngx-dropzone-label *ngIf=\"files.length==0\">\r\n <div #element (click)=\"showImageUploader(element)\">\r\n <img [src]=\"imageSource\" class=\"profile-upload-img\" />\r\n </div>\r\n </ngx-dropzone-label>\r\n <div class=\"d-none {{options.extraClasses}}\" ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\"\r\n (change)=\"onFileChange($event)\" aria-describedby=\"email-error\" aria-invalid=\"true\" ngDefaultControl\r\n formControlName=\"{{options.name}}\" id=\"{{options.name}}\"\r\n [class.is-invalid]=\"profileImageUploadFormControl.invalid && profileImageUploadFormControl.touched\">\r\n </div>\r\n <ngx-dropzone-image-preview *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n\r\n <ngx-dropzone-label *ngIf=\"files.length==0&&options.isReadonly\">\r\n <div #element>\r\n <img [src]=\"imageSource\" />\r\n </div>\r\n </ngx-dropzone-label>\r\n </div>\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\"\r\n *ngIf=\"(profileImageUploadFormControl.invalid && profileImageUploadFormControl.touched)\">\r\n {{getErrorValidation(profileImageUploadFormControl.errors|keyvalue)}}\r\n </div>\r\n\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n <!-- image cropper modal-->\r\n <div id=\"mdlSample\" class=\"modal bbsf-cropper-modal\" role=\"dialog\"\r\n [ngStyle]=\"{'display': mdlSampleIsOpen ? 'block' : 'none', 'opacity': 1}\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">\r\n {{utilityService.getResourceValue(\"CropImage\")}}\r\n </h4>\r\n <button type=\"button\" class=\"btn-close\" data-dismiss=\"modal\" (click)=\"openModal(false)\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"imageUrl\">\r\n <angular-cropper #angularCropper [cropperOptions]=\"config\" [imageUrl]=\"imageUrl\">\r\n </angular-cropper>\r\n <img [src]=\"imgwUrl\" />\r\n </div>\r\n <div class=\"cropper-btns\">\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"zoomImage(0.1)\" class=\"btn btn-default\" ngbTooltip=\"Zoom in\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-plus\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"zoomImage(-0.1)\" class=\"btn btn-default\" ngbTooltip=\"Zoom out\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-minus\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"moveImage(-10,0)\" class=\"btn btn-default\" ngbTooltip=\"Move left\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-left\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(10,0)\" class=\"btn btn-default\" ngbTooltip=\"Move right\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-right\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,-10)\" class=\"btn btn-default\" ngbTooltip=\"Move up\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-up\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,10)\" class=\"btn btn-default\" ngbTooltip=\"Move down\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-down\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"rotateImage(-45)\" class=\"btn btn-default\" ngbTooltip=\"Rotate left\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-undo-alt\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"rotateImage(45)\" class=\"btn btn-default\" ngbTooltip=\"Rotate right\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-redo-alt\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\" align=\"right\">\r\n <button type=\"button\" id=\"btnClose\" class=\"btn btn-sm btn-light\" (click)=\"openModal(false)\">\r\n {{utilityService.getResourceValue(\"CancelLabel\")}}\r\n </button>\r\n <button type=\"button\" (click)=\"cropImage()\" id=\"btnOK\" class=\"btn btn-sm btn-brand\">\r\n {{utilityService.getResourceValue(\"Crop\")}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: NgxDropzoneModule }, { kind: "component", type: i7$4.NgxDropzoneComponent, selector: "ngx-dropzone, [ngx-dropzone]", inputs: ["accept", "disabled", "multiple", "maxFileSize", "expandable", "disableClick", "processDirectoryDrop", "id", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["change"] }, { kind: "directive", type: i7$4.NgxDropzoneLabelDirective, selector: "ngx-dropzone-label" }, { kind: "component", type: i7$4.NgxDropzoneImagePreviewComponent, selector: "ngx-dropzone-image-preview", inputs: ["file"] }, { kind: "ngmodule", type: AngularCropperjsModule }, { kind: "component", type: i8.CropperComponent, selector: "angular-cropper", inputs: ["imageUrl", "settings", "cropbox", "loadImageErrorText", "cropperOptions"], outputs: ["export", "ready"] }, { kind: "ngmodule", type: NgbModule }, { kind: "directive", type: i3$2.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }] }); }
8802
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: ProfileImageUploaderComponent, isStandalone: true, selector: "BBSF-ProfileImageUploader", inputs: { group: "group", options: "options" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "angularCropper", first: true, predicate: ["angularCropper"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-profile-image-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div *ngIf=\"options.allowDropZone&&!options.isReadonly\" class=\"bbsf-input-container {{options.extraClasses}}\"\r\n ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\" (change)=\"onFileChange($event)\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\" ngDefaultControl formControlName=\"{{options.name}}\"\r\n id=\"{{options.name}}\"\r\n [class.is-invalid]=\"profileImageUploadFormControl.invalid && profileImageUploadFormControl.touched\">\r\n <ngx-dropzone-label class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"\r\n style=\"width: 50px; height: 50px;\">\r\n <path opacity=\"0.3\"\r\n d=\"M5 16C3.3 16 2 14.7 2 13C2 11.3 3.3 10 5 10H5.1C5 9.7 5 9.3 5 9C5 6.2 7.2 4 10 4C11.9 4 13.5 5 14.3 6.5C14.8 6.2 15.4 6 16 6C17.7 6 19 7.3 19 9C19 9.4 18.9 9.7 18.8 10C18.9 10 18.9 10 19 10C20.7 10 22 11.3 22 13C22 14.7 20.7 16 19 16H5ZM8 13.6H16L12.7 10.3C12.3 9.89999 11.7 9.89999 11.3 10.3L8 13.6Z\"\r\n fill=\"currentColor\" style=\"fill: #a1a1a1;\"></path>\r\n <path d=\"M11 13.6V19C11 19.6 11.4 20 12 20C12.6 20 13 19.6 13 19V13.6H11Z\" fill=\"currentColor\"\r\n style=\"fill: #989898;\"></path>\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n </ngx-dropzone-label>\r\n <ngx-dropzone-image-preview class=\"dropzone-preview\" *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div *ngIf=\"!options.allowDropZone&&!options.isReadonly\" style=\"width:fit-content\">\r\n <ngx-dropzone-label *ngIf=\"files.length==0\">\r\n <div #element (click)=\"showImageUploader(element)\">\r\n <img [src]=\"imageSource\" class=\"profile-upload-img\" />\r\n </div>\r\n </ngx-dropzone-label>\r\n <div class=\"d-none {{options.extraClasses}}\" ngx-dropzone [disabled]=\"options.isDisabled\" [accept]=\"acceptedType\"\r\n (change)=\"onFileChange($event)\" aria-describedby=\"email-error\" aria-invalid=\"true\" ngDefaultControl\r\n formControlName=\"{{options.name}}\" id=\"{{options.name}}\"\r\n [class.is-invalid]=\"profileImageUploadFormControl.invalid && profileImageUploadFormControl.touched\">\r\n </div>\r\n <ngx-dropzone-image-preview *ngFor=\"let f of files\" [file]=\"f\" [removable]=\"true\"\r\n (removed)=\"removeFromControlValue(f)\" ngProjectAs=\"ngx-dropzone-preview\">\r\n </ngx-dropzone-image-preview>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n </div>\r\n\r\n <ngx-dropzone-label *ngIf=\"files.length==0&&options.isReadonly\">\r\n <div #element>\r\n <img [src]=\"imageSource\" />\r\n </div>\r\n </ngx-dropzone-label>\r\n </div>\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\"\r\n *ngIf=\"(profileImageUploadFormControl.invalid && profileImageUploadFormControl.touched)\">\r\n {{getErrorValidation(profileImageUploadFormControl.errors|keyvalue)}}\r\n </div>\r\n\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n <!-- image cropper modal-->\r\n <div id=\"mdlSample\" class=\"modal bbsf-cropper-modal\" role=\"dialog\"\r\n [ngStyle]=\"{'display': mdlSampleIsOpen ? 'block' : 'none', 'opacity': 1}\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">\r\n {{utilityService.getResourceValue(\"CropImage\")}}\r\n </h4>\r\n <button type=\"button\" class=\"btn-close\" data-dismiss=\"modal\" (click)=\"openModal(false)\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"imageUrl\">\r\n <angular-cropper #angularCropper [cropperOptions]=\"config\" [imageUrl]=\"imageUrl\">\r\n </angular-cropper>\r\n <img [src]=\"imgwUrl\" />\r\n </div>\r\n <div class=\"cropper-btns\">\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"zoomImage(0.1)\" class=\"btn btn-default\" ngbTooltip=\"Zoom in\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-plus\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"zoomImage(-0.1)\" class=\"btn btn-default\" ngbTooltip=\"Zoom out\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-search-minus\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"moveImage(-10,0)\" class=\"btn btn-default\" ngbTooltip=\"Move left\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-left\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(10,0)\" class=\"btn btn-default\" ngbTooltip=\"Move right\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-right\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,-10)\" class=\"btn btn-default\" ngbTooltip=\"Move up\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-up\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"moveImage(0,10)\" class=\"btn btn-default\" ngbTooltip=\"Move down\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-arrow-down\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"btn-group\">\r\n <button type=\"button\" (click)=\"rotateImage(-45)\" class=\"btn btn-default\" ngbTooltip=\"Rotate left\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-undo-alt\"></span>\r\n </span>\r\n </button>\r\n <button type=\"button\" (click)=\"rotateImage(45)\" class=\"btn btn-default\" ngbTooltip=\"Rotate right\">\r\n <span class=\"docs-tooltip\">\r\n <span class=\"fa fa-redo-alt\"></span>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\" align=\"right\">\r\n <button type=\"button\" id=\"btnClose\" class=\"btn btn-sm btn-light\" (click)=\"openModal(false)\">\r\n {{utilityService.getResourceValue(\"CancelLabel\")}}\r\n </button>\r\n <button type=\"button\" (click)=\"cropImage()\" id=\"btnOK\" class=\"btn btn-sm btn-brand\">\r\n {{utilityService.getResourceValue(\"Crop\")}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: NgxDropzoneModule }, { kind: "component", type: i7$3.NgxDropzoneComponent, selector: "ngx-dropzone, [ngx-dropzone]", inputs: ["accept", "disabled", "multiple", "maxFileSize", "expandable", "disableClick", "processDirectoryDrop", "id", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["change"] }, { kind: "directive", type: i7$3.NgxDropzoneLabelDirective, selector: "ngx-dropzone-label" }, { kind: "component", type: i7$3.NgxDropzoneImagePreviewComponent, selector: "ngx-dropzone-image-preview", inputs: ["file"] }, { kind: "ngmodule", type: AngularCropperjsModule }, { kind: "component", type: i8.CropperComponent, selector: "angular-cropper", inputs: ["imageUrl", "settings", "cropbox", "loadImageErrorText", "cropperOptions"], outputs: ["export", "ready"] }, { kind: "ngmodule", type: NgbModule }, { kind: "directive", type: i3$2.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }] }); }
8641
8803
  }
8642
8804
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ProfileImageUploaderComponent, decorators: [{
8643
8805
  type: Component,
@@ -8897,7 +9059,7 @@ class CalendarComponent {
8897
9059
  }
8898
9060
  }
8899
9061
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: CalendarComponent, deps: [{ token: ErrorMassageValidation }, { token: ControlUtility }, { token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: i3.UtilityService }, { token: i4.BBSFTranslateService }, { token: i3.ControlValidationService }], target: i0.ɵɵFactoryTarget.Component }); }
8900
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: CalendarComponent, isStandalone: true, selector: "BBSF-Calendar", inputs: { group: "group", options: "options" }, viewQueries: [{ propertyName: "calendarComponent", first: true, predicate: ["calendar"], descendants: true }], ngImport: i0, template: "<div class=\"b-control b-calendar\">\r\n <div class=\"form-group validate is-invalid\" [formGroup]=\"group\">\r\n <!-- <full-calendar #calendar\r\n [defaultDate]=\"options.DefaultDate\"\r\n [defaultView]=\"DefaultView\"\r\n [header]=\"{\r\n left: 'prev,next today',\r\n center: 'title',\r\n right: CalendarViews\r\n }\"\r\n ngDefaultControl\r\n formControlName=\"{{options.Name}}\"\r\n [locales]=\"locales\"\r\n [plugins]=\"calendarPlugins\"\r\n [weekends]=\"calendarWeekends\"\r\n [events]=\"calendarEvents\"\r\n (dateClick)=\"OnDayClickFunction($event)\"\r\n (eventClick)=\"OnEventClickFunction($event)\"\r\n id=\"{{options.Name}}\"></full-calendar> -->\r\n\r\n\r\n <full-calendar *ngIf=\"options.calendarVisible\" [options]='calendarOptions' id=\"{{options.name}}\" ngDefaultControl\r\n formControlName=\"{{options.name}}\"></full-calendar>\r\n\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FullCalendarModule }, { kind: "component", type: i7$5.FullCalendarComponent, selector: "full-calendar", inputs: ["options", "deepChangeDetection", "events", "eventSources", "resources"] }] }); }
9062
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: CalendarComponent, isStandalone: true, selector: "BBSF-Calendar", inputs: { group: "group", options: "options" }, viewQueries: [{ propertyName: "calendarComponent", first: true, predicate: ["calendar"], descendants: true }], ngImport: i0, template: "<div class=\"b-control b-calendar\">\r\n <div class=\"form-group validate is-invalid\" [formGroup]=\"group\">\r\n <!-- <full-calendar #calendar\r\n [defaultDate]=\"options.DefaultDate\"\r\n [defaultView]=\"DefaultView\"\r\n [header]=\"{\r\n left: 'prev,next today',\r\n center: 'title',\r\n right: CalendarViews\r\n }\"\r\n ngDefaultControl\r\n formControlName=\"{{options.Name}}\"\r\n [locales]=\"locales\"\r\n [plugins]=\"calendarPlugins\"\r\n [weekends]=\"calendarWeekends\"\r\n [events]=\"calendarEvents\"\r\n (dateClick)=\"OnDayClickFunction($event)\"\r\n (eventClick)=\"OnEventClickFunction($event)\"\r\n id=\"{{options.Name}}\"></full-calendar> -->\r\n\r\n\r\n <full-calendar *ngIf=\"options.calendarVisible\" [options]='calendarOptions' id=\"{{options.name}}\" ngDefaultControl\r\n formControlName=\"{{options.name}}\"></full-calendar>\r\n\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FullCalendarModule }, { kind: "component", type: i7$4.FullCalendarComponent, selector: "full-calendar", inputs: ["options", "deepChangeDetection", "events", "eventSources", "resources"] }] }); }
8901
9063
  }
8902
9064
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: CalendarComponent, decorators: [{
8903
9065
  type: Component,
@@ -9387,7 +9549,7 @@ class MapAutoCompleteComponent {
9387
9549
  this.GermanAddressMapped(this.selectedPin);
9388
9550
  this.closeMapModal();
9389
9551
  }
9390
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MapAutoCompleteComponent, deps: [{ token: i0.NgZone }, { token: ControlUtility }, { token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: i3.UtilityService }, { token: i4.BBSFTranslateService }, { token: i3.ControlValidationService }, { token: GlobalSettings }, { token: i5$2.ScriptService }], target: i0.ɵɵFactoryTarget.Component }); }
9552
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MapAutoCompleteComponent, deps: [{ token: i0.NgZone }, { token: ControlUtility }, { token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: i3.UtilityService }, { token: i4.BBSFTranslateService }, { token: i3.ControlValidationService }, { token: GlobalSettings }, { token: i6$3.ScriptService }], target: i0.ɵɵFactoryTarget.Component }); }
9391
9553
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: MapAutoCompleteComponent, isStandalone: true, selector: "BBSF-MapAutoComplete", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange" }, viewQueries: [{ propertyName: "searchElementRef", first: true, predicate: ["mapSearch"], descendants: true }, { propertyName: "advancedMapModal", first: true, predicate: ["advancedMapModal"], descendants: true }, { propertyName: "setLocationSearch", first: true, predicate: ["setLocationSearch"], descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"showMap\">\r\n <div class=\"form-group bbsf-control bbsf-maps\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n\r\n <!--#region input-->\r\n <div class=\"input-group bbsf-input-container\" *ngIf=\"!options.isReadonly\">\r\n <input class=\"form-control input-icon-o {{options.extraClasses}}\" [value]=\"mapAutoCompleteModel.text\"\r\n [address]=\"mapAutoCompleteModel.text\" value=\"{{mapAutoCompleteModel.text}}\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\"\r\n [class.is-invalid]=\"mapAutoCompleteFormControl.invalid && mapAutoCompleteFormControl.touched\"\r\n [placeholder]=\"options.placeholder\" [id]=\"options.name\" (keyup)=\"GermanAddressMapped($event)\" #mapSearch />\r\n <button *ngIf=\"options.showAdvancedMap\" class=\"border-0 btn-secondary btn-icon-o\"\r\n ngbTooltip=\"{{translateValue('SetLocation')}}\" type=\"button\" (click)=\"openMapModal()\">\r\n\r\n <span class=\"svg-icon svg-icon-1\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M12 13C13.6569 13 15 11.6569 15 10C15 8.34315 13.6569 7 12 7C10.3431 7 9 8.34315 9 10C9 11.6569 10.3431 13 12 13Z\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M12 22C16 18 20 14.4183 20 10C20 5.58172 16.4183 2 12 2C7.58172 2 4 5.58172 4 10C4 14.4183 8 18 12 22Z\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n\r\n </button>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region readonly -->\r\n <div *ngIf=\"options.isReadonly\">\r\n <a href=\"{{mapAutoCompleteModel.googleMapsURL}}\" target=\"_blank\">{{mapAutoCompleteModel.text}}</a>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <!-- requiredText-->\r\n <div class=\"bbsf-validation\" *ngIf=\"(mapAutoCompleteFormControl.invalid && mapAutoCompleteFormControl.touched)\">\r\n {{getErrorValidation(mapAutoCompleteFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty)\">\r\n {{resetError()}} </div>\r\n\r\n </div>\r\n\r\n <div id=\"mdlSample\" class=\"modal bbsf-cropper-modal\" role=\"dialog\" [ngClass]=\"{'bbsf-blur': modalIsOpen}\"\r\n [ngStyle]=\"{'display': modalIsOpen ? 'block' : 'none', 'opacity': 1}\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">\r\n {{translateValue('SetLocationOnMap')}}\r\n </h4>\r\n <button type=\"button\" class=\"btn-close\" data-dismiss=\"modal\" (click)=\"closeMapModal()\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <input class=\"form-control mt-3 mb-3\" id=\"setLocationSearch\" #setLocationSearch type=\"text\"\r\n placeholder=\"{{translateValue('SetLocation')}}\">\r\n <div class=\"google-map-container\">\r\n <google-map [zoom]=\"zoomLevel\" [center]=\"mapCenter\" [width]=\"null\" [height]=\"null\" #googleMap (mapClick)=\"onMapClick($event)\">\r\n <map-marker [position]=\"markerPosition\" [options]=\"markerOptions\"></map-marker>\r\n </google-map>\r\n </div>\r\n <div class=\"text-danger\" *ngIf=\"(options.validateLocationWithinCity && options.city && invalidLocationWithinCity)\">\r\n {{translateValue('InvalidLocationWithinCity').replace('{0}', options.city)}}\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-sm btn-light\" (click)=\"closeMapModal()\">\r\n {{translateValue(\"Cancel\")}}\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-brand\" (click)=\"submitSetLocation()\">\r\n {{translateValue('Confirm')}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-container>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ScriptLoaderModule }, { kind: "ngmodule", type: GoogleMapsModule }, { kind: "component", type: i8$1.GoogleMap, selector: "google-map", inputs: ["height", "width", "mapId", "mapTypeId", "center", "zoom", "options"], outputs: ["mapInitialized", "authFailure", "boundsChanged", "centerChanged", "mapClick", "mapDblclick", "mapDrag", "mapDragend", "mapDragstart", "headingChanged", "idle", "maptypeidChanged", "mapMousemove", "mapMouseout", "mapMouseover", "projectionChanged", "mapRightclick", "tilesloaded", "tiltChanged", "zoomChanged"], exportAs: ["googleMap"] }, { kind: "directive", type: i8$1.MapMarker, selector: "map-marker", inputs: ["title", "position", "label", "clickable", "options", "icon", "visible"], outputs: ["animationChanged", "mapClick", "clickableChanged", "cursorChanged", "mapDblclick", "mapDrag", "mapDragend", "draggableChanged", "mapDragstart", "flatChanged", "iconChanged", "mapMousedown", "mapMouseout", "mapMouseover", "mapMouseup", "positionChanged", "mapRightclick", "shapeChanged", "titleChanged", "visibleChanged", "zindexChanged", "markerInitialized"], exportAs: ["mapMarker"] }], encapsulation: i0.ViewEncapsulation.None }); }
9392
9554
  }
9393
9555
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MapAutoCompleteComponent, decorators: [{
@@ -9401,7 +9563,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImpo
9401
9563
  ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], template: "<ng-container *ngIf=\"showMap\">\r\n <div class=\"form-group bbsf-control bbsf-maps\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n\r\n <!--#region input-->\r\n <div class=\"input-group bbsf-input-container\" *ngIf=\"!options.isReadonly\">\r\n <input class=\"form-control input-icon-o {{options.extraClasses}}\" [value]=\"mapAutoCompleteModel.text\"\r\n [address]=\"mapAutoCompleteModel.text\" value=\"{{mapAutoCompleteModel.text}}\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\"\r\n [class.is-invalid]=\"mapAutoCompleteFormControl.invalid && mapAutoCompleteFormControl.touched\"\r\n [placeholder]=\"options.placeholder\" [id]=\"options.name\" (keyup)=\"GermanAddressMapped($event)\" #mapSearch />\r\n <button *ngIf=\"options.showAdvancedMap\" class=\"border-0 btn-secondary btn-icon-o\"\r\n ngbTooltip=\"{{translateValue('SetLocation')}}\" type=\"button\" (click)=\"openMapModal()\">\r\n\r\n <span class=\"svg-icon svg-icon-1\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M12 13C13.6569 13 15 11.6569 15 10C15 8.34315 13.6569 7 12 7C10.3431 7 9 8.34315 9 10C9 11.6569 10.3431 13 12 13Z\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M12 22C16 18 20 14.4183 20 10C20 5.58172 16.4183 2 12 2C7.58172 2 4 5.58172 4 10C4 14.4183 8 18 12 22Z\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n\r\n </button>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n <!-- #region readonly -->\r\n <div *ngIf=\"options.isReadonly\">\r\n <a href=\"{{mapAutoCompleteModel.googleMapsURL}}\" target=\"_blank\">{{mapAutoCompleteModel.text}}</a>\r\n </div>\r\n <!-- #endregion -->\r\n\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <!-- requiredText-->\r\n <div class=\"bbsf-validation\" *ngIf=\"(mapAutoCompleteFormControl.invalid && mapAutoCompleteFormControl.touched)\">\r\n {{getErrorValidation(mapAutoCompleteFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty)\">\r\n {{resetError()}} </div>\r\n\r\n </div>\r\n\r\n <div id=\"mdlSample\" class=\"modal bbsf-cropper-modal\" role=\"dialog\" [ngClass]=\"{'bbsf-blur': modalIsOpen}\"\r\n [ngStyle]=\"{'display': modalIsOpen ? 'block' : 'none', 'opacity': 1}\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">\r\n {{translateValue('SetLocationOnMap')}}\r\n </h4>\r\n <button type=\"button\" class=\"btn-close\" data-dismiss=\"modal\" (click)=\"closeMapModal()\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <input class=\"form-control mt-3 mb-3\" id=\"setLocationSearch\" #setLocationSearch type=\"text\"\r\n placeholder=\"{{translateValue('SetLocation')}}\">\r\n <div class=\"google-map-container\">\r\n <google-map [zoom]=\"zoomLevel\" [center]=\"mapCenter\" [width]=\"null\" [height]=\"null\" #googleMap (mapClick)=\"onMapClick($event)\">\r\n <map-marker [position]=\"markerPosition\" [options]=\"markerOptions\"></map-marker>\r\n </google-map>\r\n </div>\r\n <div class=\"text-danger\" *ngIf=\"(options.validateLocationWithinCity && options.city && invalidLocationWithinCity)\">\r\n {{translateValue('InvalidLocationWithinCity').replace('{0}', options.city)}}\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-sm btn-light\" (click)=\"closeMapModal()\">\r\n {{translateValue(\"Cancel\")}}\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-brand\" (click)=\"submitSetLocation()\">\r\n {{translateValue('Confirm')}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-container>" }]
9402
9564
  }], ctorParameters: () => [{ type: i0.NgZone }, { type: ControlUtility }, { type: i2.ControlContainer, decorators: [{
9403
9565
  type: Optional
9404
- }] }, { type: i2.FormGroupDirective }, { type: i3.UtilityService }, { type: i4.BBSFTranslateService }, { type: i3.ControlValidationService }, { type: GlobalSettings }, { type: i5$2.ScriptService }], propDecorators: { group: [{
9566
+ }] }, { type: i2.FormGroupDirective }, { type: i3.UtilityService }, { type: i4.BBSFTranslateService }, { type: i3.ControlValidationService }, { type: GlobalSettings }, { type: i6$3.ScriptService }], propDecorators: { group: [{
9405
9567
  type: Input
9406
9568
  }], options: [{
9407
9569
  type: Input
@@ -9570,7 +9732,7 @@ class AutocompleteTextBoxComponent {
9570
9732
  };
9571
9733
  this.suggestions$ = new Observable((observer) => {
9572
9734
  observer.next(this.Search);
9573
- }).pipe(switchMap$1((query) => {
9735
+ }).pipe(switchMap((query) => {
9574
9736
  if (query) {
9575
9737
  let params = new HttpParams();
9576
9738
  params = params.append(this.options.queryParam, query);
@@ -11838,6 +12000,26 @@ var FileType;
11838
12000
  FileType["None"] = "";
11839
12001
  })(FileType || (FileType = {}));
11840
12002
 
12003
+ var MarkdownMode;
12004
+ (function (MarkdownMode) {
12005
+ MarkdownMode["editor"] = "editor";
12006
+ MarkdownMode["preview"] = "preview";
12007
+ })(MarkdownMode || (MarkdownMode = {}));
12008
+ var MarkDownIcons;
12009
+ (function (MarkDownIcons) {
12010
+ MarkDownIcons["Bold"] = "Bold";
12011
+ MarkDownIcons["Italic"] = "Italic";
12012
+ MarkDownIcons["Heading"] = "Heading";
12013
+ MarkDownIcons["Reference"] = "Reference";
12014
+ MarkDownIcons["Link"] = "Link";
12015
+ MarkDownIcons["Image"] = "Image";
12016
+ MarkDownIcons["Ul"] = "Ul";
12017
+ MarkDownIcons["Ol"] = "Ol";
12018
+ MarkDownIcons["Code"] = "Code";
12019
+ MarkDownIcons["TogglePreview"] = "TogglePreview";
12020
+ MarkDownIcons["FullScreen"] = "FullScreen";
12021
+ })(MarkDownIcons || (MarkDownIcons = {}));
12022
+
11841
12023
  var ToolbarButtons;
11842
12024
  (function (ToolbarButtons) {
11843
12025
  ToolbarButtons["undo"] = "undo";