@esfaenza/core 20.3.78 → 20.3.81

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.
@@ -14,7 +14,7 @@ import { PreferencesService, CacheService } from '@esfaenza/preferences';
14
14
  import * as i5 from '@esfaenza/localizations';
15
15
  import { LocalizationService } from '@esfaenza/localizations';
16
16
  import { JaceIdentity, ApplicationJob, ApplicationMenu, SearchResult, SearchResultContainer, ActiveModuleView, EntityFeedsWidgetConfiguration, Feed, CreateUpdateFeedDto, UserAccount, UpdatePasswordDto } from '@esfaenza/core/domain';
17
- import { Subscription, ReplaySubject, Subject } from 'rxjs';
17
+ import { Subscription, ReplaySubject, Subject, Observable } from 'rxjs';
18
18
  import * as i3 from '@angular/forms';
19
19
  import { NgForm, NgModel } from '@angular/forms';
20
20
  import * as i4 from '@esfaenza/core/directives';
@@ -473,9 +473,77 @@ declare class EntityFeedsWidgetComponent {
473
473
  static ɵcmp: i0.ɵɵComponentDeclaration<EntityFeedsWidgetComponent, "entity-feeds-widget", never, { "EntityType": { "alias": "EntityType"; "required": false; }; "EntityId": { "alias": "EntityId"; "required": false; }; "RefreshSubject": { "alias": "RefreshSubject"; "required": false; }; "GetFeedsAPI": { "alias": "GetFeedsAPI"; "required": false; }; "CreateFeedAPI": { "alias": "CreateFeedAPI"; "required": false; }; "UpdateFeedAPI": { "alias": "UpdateFeedAPI"; "required": false; }; "DeleteFeedAPI": { "alias": "DeleteFeedAPI"; "required": false; }; "ReactToFeedAPI": { "alias": "ReactToFeedAPI"; "required": false; }; "GetUserTagsAPI": { "alias": "GetUserTagsAPI"; "required": false; }; "GetFeedAttachmentAPI": { "alias": "GetFeedAttachmentAPI"; "required": false; }; "WidgetTitle": { "alias": "WidgetTitle"; "required": false; }; "MaxHeight": { "alias": "MaxHeight"; "required": false; }; "Readonly": { "alias": "Readonly"; "required": false; }; "AllowUserTags": { "alias": "AllowUserTags"; "required": false; }; "AllowReactions": { "alias": "AllowReactions"; "required": false; }; "AllowAttachments": { "alias": "AllowAttachments"; "required": false; }; "AllowComments": { "alias": "AllowComments"; "required": false; }; "AllowReplies": { "alias": "AllowReplies"; "required": false; }; "DebugMode": { "alias": "DebugMode"; "required": false; }; "ModuleConfig": { "alias": "ModuleConfig"; "required": false; }; }, {}, never, never, true, never>;
474
474
  }
475
475
 
476
+ /** Risposta a un comando: testo prodotto, eventuale errore e il prompt da mostrare da lì in avanti */
477
+ interface EsTerminalResult {
478
+ Output?: string;
479
+ Error?: string;
480
+ Prompt?: string;
481
+ }
482
+ /** Esegue un comando: la riga digitata arriva così com'è, anche vuota (serve agli interpreti con prompt di continuazione) */
483
+ type EsTerminalExecutor = (command: string) => Observable<EsTerminalResult> | Promise<EsTerminalResult> | EsTerminalResult;
484
+ type EsTerminalLineKind = "greeting" | "command" | "output" | "error" | "info";
485
+ interface EsTerminalLine {
486
+ Kind: EsTerminalLineKind;
487
+ Text: string;
488
+ Prompt?: string;
489
+ }
490
+ /**
491
+ * Terminale testuale senza dipendenze: storico delle righe, prompt, cronologia dei comandi (frecce su/giù),
492
+ * incolla di più righe eseguite in sequenza. Ogni comando passa all'Executor; finché non risponde l'input è sospeso.
493
+ *
494
+ * Tasti: Invio esegue, ↑/↓ cronologia, Tab inserisce 4 spazi, Ctrl+C (senza testo selezionato) annulla la riga, Ctrl+L pulisce.
495
+ * Colori e font si cambiano con le variabili CSS --es-terminal-* sull'elemento.
496
+ */
497
+ declare class EsTerminalComponent {
498
+ /** Testo mostrato all'apertura */
499
+ Greetings: string;
500
+ /** Prompt iniziale; l'Executor può cambiarlo con ogni risposta */
501
+ set Prompt(value: string);
502
+ Executor: EsTerminalExecutor;
503
+ /** Chiave in localStorage per conservare la cronologia dei comandi fra una sessione e l'altra; senza chiave resta in memoria */
504
+ HistoryKey: string;
505
+ MaxHistory: number;
506
+ /** Prende il focus all'apertura */
507
+ AutoFocus: boolean;
508
+ private screen;
509
+ private input;
510
+ Lines: i0.WritableSignal<EsTerminalLine[]>;
511
+ CurrentPrompt: i0.WritableSignal<string>;
512
+ Busy: i0.WritableSignal<boolean>;
513
+ Command: string;
514
+ private history;
515
+ private historyIndex;
516
+ private draft;
517
+ private queue;
518
+ ngOnInit(): void;
519
+ ngAfterViewInit(): void;
520
+ /** Aggiunge del testo allo schermo */
521
+ echo(text: string, kind?: EsTerminalLineKind): void;
522
+ error(text: string): void;
523
+ clear(): void;
524
+ setPrompt(prompt: string): void;
525
+ focus(): void;
526
+ /** Esegue un comando come se fosse stato digitato */
527
+ exec(command: string): void;
528
+ onKeyDown(e: KeyboardEvent): void;
529
+ onPaste(e: ClipboardEvent): void;
530
+ onScreenClick(): void;
531
+ private runQueue;
532
+ private run;
533
+ private addToHistory;
534
+ private moveInHistory;
535
+ private loadHistory;
536
+ private saveHistory;
537
+ private insertAtCursor;
538
+ private hasSelection;
539
+ private scrollToBottom;
540
+ static ɵfac: i0.ɵɵFactoryDeclaration<EsTerminalComponent, never>;
541
+ static ɵcmp: i0.ɵɵComponentDeclaration<EsTerminalComponent, "es-terminal", never, { "Greetings": { "alias": "Greetings"; "required": false; }; "Prompt": { "alias": "Prompt"; "required": false; }; "Executor": { "alias": "Executor"; "required": false; }; "HistoryKey": { "alias": "HistoryKey"; "required": false; }; "MaxHistory": { "alias": "MaxHistory"; "required": false; }; "AutoFocus": { "alias": "AutoFocus"; "required": false; }; }, {}, never, never, true, never>;
542
+ }
543
+
476
544
  declare class ComponentsModule {
477
545
  static ɵfac: i0.ɵɵFactoryDeclaration<ComponentsModule, never>;
478
- static ɵmod: i0.ɵɵNgModuleDeclaration<ComponentsModule, never, [typeof i1.CommonModule, typeof i2.RouterModule, typeof i3.FormsModule, typeof i4.DirectivesModule, typeof i5.LocalizationModule, typeof i6.ProgressbarModule, typeof i7.BsDropdownModule, typeof i8.ModalModule, typeof i9.EsTableModule, typeof BackTop, typeof Breadcrumb, typeof ErrorPageComponent, typeof PagesComponent, typeof ExternalPagesComponent, typeof JaceLoginComponent, typeof Navbar, typeof RedirecterComponent, typeof Sidebar, typeof JaceResourceComponent, typeof EsModalComponent, typeof EsModalHeadComponent, typeof LabeledSpanComponent, typeof EsImageCropperComponent, typeof FormSelectorComponent, typeof FormSelectorDialogComponent, typeof EntityFeedsWidgetComponent], [typeof BackTop, typeof Breadcrumb, typeof ErrorPageComponent, typeof PagesComponent, typeof ExternalPagesComponent, typeof JaceLoginComponent, typeof Navbar, typeof RedirecterComponent, typeof Sidebar, typeof JaceResourceComponent, typeof EsModalComponent, typeof EsModalHeadComponent, typeof LabeledSpanComponent, typeof EsImageCropperComponent, typeof FormSelectorComponent, typeof FormSelectorDialogComponent, typeof EntityFeedsWidgetComponent]>;
546
+ static ɵmod: i0.ɵɵNgModuleDeclaration<ComponentsModule, never, [typeof i1.CommonModule, typeof i2.RouterModule, typeof i3.FormsModule, typeof i4.DirectivesModule, typeof i5.LocalizationModule, typeof i6.ProgressbarModule, typeof i7.BsDropdownModule, typeof i8.ModalModule, typeof i9.EsTableModule, typeof BackTop, typeof Breadcrumb, typeof ErrorPageComponent, typeof PagesComponent, typeof ExternalPagesComponent, typeof JaceLoginComponent, typeof Navbar, typeof RedirecterComponent, typeof Sidebar, typeof JaceResourceComponent, typeof EsModalComponent, typeof EsModalHeadComponent, typeof LabeledSpanComponent, typeof EsImageCropperComponent, typeof FormSelectorComponent, typeof FormSelectorDialogComponent, typeof EntityFeedsWidgetComponent, typeof EsTerminalComponent], [typeof BackTop, typeof Breadcrumb, typeof ErrorPageComponent, typeof PagesComponent, typeof ExternalPagesComponent, typeof JaceLoginComponent, typeof Navbar, typeof RedirecterComponent, typeof Sidebar, typeof JaceResourceComponent, typeof EsModalComponent, typeof EsModalHeadComponent, typeof LabeledSpanComponent, typeof EsImageCropperComponent, typeof FormSelectorComponent, typeof FormSelectorDialogComponent, typeof EntityFeedsWidgetComponent, typeof EsTerminalComponent]>;
479
547
  static ɵinj: i0.ɵɵInjectorDeclaration<ComponentsModule>;
480
548
  }
481
549
 
@@ -695,4 +763,5 @@ declare abstract class BaseSearchComponent<TSearch extends AppSearch<TItem>, TIt
695
763
  static ɵcmp: i0.ɵɵComponentDeclaration<BaseSearchComponent<any, any>, "ng-component", never, {}, {}, never, never, true, never>;
696
764
  }
697
765
 
698
- export { BackTop, BaseComponent, BaseSearchComponent, BaseSelectorComponent, BaseSelectorInitialization, Breadcrumb, BreadcrumbItem, ComponentsModule, EmbeddingComponent, EntityFeedsWidgetComponent, ErrorPageComponent, EsImageCropperComponent, EsModalComponent, EsModalHeadComponent, ExternalPagesComponent, FormSelectorComponent, FormSelectorDialogComponent, JaceLoginComponent, JaceResourceComponent, LabeledSpanComponent, Navbar, PagesComponent, ReactiveComponent, RedirecterComponent, Sidebar, UserInfosComponent };
766
+ export { BackTop, BaseComponent, BaseSearchComponent, BaseSelectorComponent, BaseSelectorInitialization, Breadcrumb, BreadcrumbItem, ComponentsModule, EmbeddingComponent, EntityFeedsWidgetComponent, ErrorPageComponent, EsImageCropperComponent, EsModalComponent, EsModalHeadComponent, EsTerminalComponent, ExternalPagesComponent, FormSelectorComponent, FormSelectorDialogComponent, JaceLoginComponent, JaceResourceComponent, LabeledSpanComponent, Navbar, PagesComponent, ReactiveComponent, RedirecterComponent, Sidebar, UserInfosComponent };
767
+ export type { EsTerminalExecutor, EsTerminalLine, EsTerminalLineKind, EsTerminalResult };
@@ -1,11 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { HostListener, ViewChild, Input, ViewEncapsulation, Component, EventEmitter, Output, Inject, Injectable, Optional, ChangeDetectionStrategy, input, model, NgModule, viewChild, contentChild } from '@angular/core';
2
+ import { HostListener, ViewChild, Input, ViewEncapsulation, Component, EventEmitter, Output, Inject, Injectable, Optional, ChangeDetectionStrategy, input, model, signal, NgModule, viewChild, contentChild } from '@angular/core';
3
3
  import * as i2 from '@angular/router';
4
4
  import { NavigationEnd, RouterLink, RouterLinkActive, RouterOutlet, ActivatedRoute, Router, RouterModule } from '@angular/router';
5
5
  import * as i4 from '@angular/common';
6
6
  import { NgIf, NgFor, NgTemplateOutlet, NgClass, CommonModule, AsyncPipe, Location } from '@angular/common';
7
7
  import { filter, map, mergeMap, takeUntil } from 'rxjs/operators';
8
- import { Subject, combineLatest, of, firstValueFrom, ReplaySubject, interval, startWith, takeUntil as takeUntil$1, takeWhile, take, map as map$1 } from 'rxjs';
8
+ import { Subject, combineLatest, of, firstValueFrom, ReplaySubject, interval, startWith, takeUntil as takeUntil$1, takeWhile, isObservable, take, map as map$1 } from 'rxjs';
9
9
  import * as i1 from '@esfaenza/core/services';
10
10
  import { AppState } from '@esfaenza/core/services';
11
11
  import * as i3 from '@angular/platform-browser';
@@ -1616,6 +1616,260 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImpo
1616
1616
  args: ["dlgFeedContent"]
1617
1617
  }] } });
1618
1618
 
1619
+ // Angular
1620
+ /**
1621
+ * Terminale testuale senza dipendenze: storico delle righe, prompt, cronologia dei comandi (frecce su/giù),
1622
+ * incolla di più righe eseguite in sequenza. Ogni comando passa all'Executor; finché non risponde l'input è sospeso.
1623
+ *
1624
+ * Tasti: Invio esegue, ↑/↓ cronologia, Tab inserisce 4 spazi, Ctrl+C (senza testo selezionato) annulla la riga, Ctrl+L pulisce.
1625
+ * Colori e font si cambiano con le variabili CSS --es-terminal-* sull'elemento.
1626
+ */
1627
+ class EsTerminalComponent {
1628
+ constructor() {
1629
+ /** Testo mostrato all'apertura */
1630
+ this.Greetings = "";
1631
+ this.MaxHistory = 200;
1632
+ /** Prende il focus all'apertura */
1633
+ this.AutoFocus = true;
1634
+ this.Lines = signal([], ...(ngDevMode ? [{ debugName: "Lines" }] : []));
1635
+ this.CurrentPrompt = signal(">", ...(ngDevMode ? [{ debugName: "CurrentPrompt" }] : []));
1636
+ this.Busy = signal(false, ...(ngDevMode ? [{ debugName: "Busy" }] : []));
1637
+ this.Command = "";
1638
+ this.history = [];
1639
+ //Posizione nella cronologia mentre si scorre con le frecce: history.length vuol dire "riga nuova", con la bozza salvata a parte
1640
+ this.historyIndex = 0;
1641
+ this.draft = "";
1642
+ //Righe incollate in attesa di essere eseguite, una alla volta
1643
+ this.queue = [];
1644
+ }
1645
+ /** Prompt iniziale; l'Executor può cambiarlo con ogni risposta */
1646
+ set Prompt(value) { this.CurrentPrompt.set(value ?? ""); }
1647
+ ngOnInit() {
1648
+ this.history = this.loadHistory();
1649
+ this.historyIndex = this.history.length;
1650
+ if (this.Greetings)
1651
+ this.Lines.set([{ Kind: "greeting", Text: this.Greetings }]);
1652
+ }
1653
+ ngAfterViewInit() {
1654
+ if (this.AutoFocus)
1655
+ setTimeout(() => this.focus());
1656
+ }
1657
+ //******************************************************************* API pubblica
1658
+ /** Aggiunge del testo allo schermo */
1659
+ echo(text, kind = "output") {
1660
+ if (text === null || text === undefined)
1661
+ return;
1662
+ this.Lines.update(l => [...l, { Kind: kind, Text: text }]);
1663
+ this.scrollToBottom();
1664
+ }
1665
+ error(text) {
1666
+ this.echo(text, "error");
1667
+ }
1668
+ clear() {
1669
+ this.Lines.set([]);
1670
+ }
1671
+ setPrompt(prompt) {
1672
+ this.CurrentPrompt.set(prompt ?? "");
1673
+ }
1674
+ focus() {
1675
+ this.input?.nativeElement.focus({ preventScroll: true });
1676
+ }
1677
+ /** Esegue un comando come se fosse stato digitato */
1678
+ exec(command) {
1679
+ this.queue.push(command);
1680
+ if (!this.Busy())
1681
+ this.runQueue();
1682
+ }
1683
+ //******************************************************************* Input
1684
+ onKeyDown(e) {
1685
+ if (this.Busy())
1686
+ return;
1687
+ switch (e.key) {
1688
+ case "Enter":
1689
+ e.preventDefault();
1690
+ let command = this.Command;
1691
+ this.Command = "";
1692
+ this.exec(command);
1693
+ return;
1694
+ case "ArrowUp":
1695
+ e.preventDefault();
1696
+ this.moveInHistory(-1);
1697
+ return;
1698
+ case "ArrowDown":
1699
+ e.preventDefault();
1700
+ this.moveInHistory(1);
1701
+ return;
1702
+ case "Tab":
1703
+ e.preventDefault();
1704
+ this.insertAtCursor(" ");
1705
+ return;
1706
+ }
1707
+ if (e.ctrlKey && !e.altKey && !e.metaKey) {
1708
+ let key = e.key.toLowerCase();
1709
+ //Ctrl+C copia se c'è testo selezionato, altrimenti annulla la riga come in una shell
1710
+ if (key == "c" && !this.hasSelection()) {
1711
+ e.preventDefault();
1712
+ this.Lines.update(l => [...l, { Kind: "command", Prompt: this.CurrentPrompt(), Text: this.Command + "^C" }]);
1713
+ this.Command = "";
1714
+ this.historyIndex = this.history.length;
1715
+ this.scrollToBottom();
1716
+ }
1717
+ else if (key == "l") {
1718
+ e.preventDefault();
1719
+ this.clear();
1720
+ }
1721
+ }
1722
+ }
1723
+ onPaste(e) {
1724
+ let text = e.clipboardData?.getData("text") ?? "";
1725
+ if (!/[\r\n]/.test(text))
1726
+ return;
1727
+ //Più righe: la prima completa quella in corso, le altre vengono eseguite in fila; l'ultima, se non chiusa da un a capo, resta da completare
1728
+ e.preventDefault();
1729
+ let lines = text.replace(/\r\n?/g, "\n").split("\n");
1730
+ let last = lines.pop();
1731
+ lines[0] = this.Command + lines[0];
1732
+ this.Command = last;
1733
+ lines.forEach(l => this.queue.push(l));
1734
+ if (!this.Busy())
1735
+ this.runQueue();
1736
+ }
1737
+ //Un clic sullo schermo porta il focus sull'input, a meno che non si stia selezionando del testo da copiare
1738
+ onScreenClick() {
1739
+ if (!this.hasSelection())
1740
+ this.focus();
1741
+ }
1742
+ //******************************************************************* Esecuzione
1743
+ async runQueue() {
1744
+ while (this.queue.length > 0) {
1745
+ let command = this.queue.shift();
1746
+ await this.run(command);
1747
+ }
1748
+ setTimeout(() => this.focus());
1749
+ }
1750
+ async run(command) {
1751
+ this.Lines.update(l => [...l, { Kind: "command", Prompt: this.CurrentPrompt(), Text: command }]);
1752
+ this.addToHistory(command);
1753
+ this.scrollToBottom();
1754
+ if (!this.Executor)
1755
+ return;
1756
+ this.Busy.set(true);
1757
+ try {
1758
+ let ret = this.Executor(command);
1759
+ let res = isObservable(ret) ? await firstValueFrom(ret, { defaultValue: null }) : await ret;
1760
+ if (res?.Output)
1761
+ this.echo(res.Output, "output");
1762
+ if (res?.Error)
1763
+ this.echo(res.Error, "error");
1764
+ if (res?.Prompt !== undefined && res?.Prompt !== null)
1765
+ this.CurrentPrompt.set(res.Prompt);
1766
+ }
1767
+ catch (ex) {
1768
+ //Un errore della chiamata non deve bloccare il terminale: lo mostro e si continua
1769
+ this.echo(ex?.message ?? ex?.toString() ?? "Errore", "error");
1770
+ }
1771
+ finally {
1772
+ this.Busy.set(false);
1773
+ this.scrollToBottom();
1774
+ }
1775
+ }
1776
+ //******************************************************************* Cronologia
1777
+ addToHistory(command) {
1778
+ if (command.trim() && this.history[this.history.length - 1] !== command) {
1779
+ this.history.push(command);
1780
+ if (this.history.length > this.MaxHistory)
1781
+ this.history.splice(0, this.history.length - this.MaxHistory);
1782
+ this.saveHistory();
1783
+ }
1784
+ this.historyIndex = this.history.length;
1785
+ this.draft = "";
1786
+ }
1787
+ moveInHistory(step) {
1788
+ let next = this.historyIndex + step;
1789
+ if (next < 0 || next > this.history.length)
1790
+ return;
1791
+ //Uscendo dalla riga nuova ne tengo la bozza, per ritrovarla scendendo
1792
+ if (this.historyIndex == this.history.length)
1793
+ this.draft = this.Command;
1794
+ this.historyIndex = next;
1795
+ this.Command = next == this.history.length ? this.draft : this.history[next];
1796
+ //Cursore in fondo, come nelle shell
1797
+ setTimeout(() => {
1798
+ let el = this.input?.nativeElement;
1799
+ if (el)
1800
+ el.setSelectionRange(el.value.length, el.value.length);
1801
+ });
1802
+ }
1803
+ loadHistory() {
1804
+ if (!this.HistoryKey)
1805
+ return [];
1806
+ try {
1807
+ let saved = JSON.parse(localStorage.getItem(this.HistoryKey) ?? "[]");
1808
+ return Array.isArray(saved) ? saved.filter(t => typeof t === "string") : [];
1809
+ }
1810
+ catch {
1811
+ return [];
1812
+ }
1813
+ }
1814
+ saveHistory() {
1815
+ if (!this.HistoryKey)
1816
+ return;
1817
+ try {
1818
+ localStorage.setItem(this.HistoryKey, JSON.stringify(this.history));
1819
+ }
1820
+ catch { }
1821
+ }
1822
+ //******************************************************************* Utilità
1823
+ insertAtCursor(text) {
1824
+ let el = this.input?.nativeElement;
1825
+ if (!el)
1826
+ return;
1827
+ let start = el.selectionStart ?? this.Command.length;
1828
+ let end = el.selectionEnd ?? start;
1829
+ this.Command = this.Command.substring(0, start) + text + this.Command.substring(end);
1830
+ setTimeout(() => el.setSelectionRange(start + text.length, start + text.length));
1831
+ }
1832
+ //Testo selezionato sullo schermo o dentro l'input (la selezione di un input non compare in window.getSelection)
1833
+ hasSelection() {
1834
+ let el = this.input?.nativeElement;
1835
+ if (el && document.activeElement === el && el.selectionStart !== el.selectionEnd)
1836
+ return true;
1837
+ let sel = window.getSelection();
1838
+ return !!sel && !sel.isCollapsed && sel.toString().length > 0;
1839
+ }
1840
+ scrollToBottom() {
1841
+ setTimeout(() => {
1842
+ let el = this.screen?.nativeElement;
1843
+ if (el)
1844
+ el.scrollTop = el.scrollHeight;
1845
+ });
1846
+ }
1847
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: EsTerminalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1848
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.34", type: EsTerminalComponent, isStandalone: true, selector: "es-terminal", inputs: { Greetings: "Greetings", Prompt: "Prompt", Executor: "Executor", HistoryKey: "HistoryKey", MaxHistory: "MaxHistory", AutoFocus: "AutoFocus" }, viewQueries: [{ propertyName: "screen", first: true, predicate: ["screen"], descendants: true, static: true }, { propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"es-terminal\" #screen (click)=\"onScreenClick()\">\n @for (line of Lines(); track $index) {\n @if (line.Kind == 'command') {\n <div class=\"es-terminal-line es-terminal-command\"><span class=\"es-terminal-prompt\">{{line.Prompt}}</span>{{line.Text}}</div>\n } @else {\n <div class=\"es-terminal-line\" [class]=\"'es-terminal-' + line.Kind\">{{line.Text}}</div>\n }\n }\n\n <div class=\"es-terminal-line es-terminal-input-line\" [class.es-terminal-busy]=\"Busy()\">\n @if (Busy()) {\n <span class=\"es-terminal-spinner\"></span>\n } @else {\n <span class=\"es-terminal-prompt\">{{CurrentPrompt()}}</span>\n }\n <input #input class=\"es-terminal-input\" type=\"text\" autocomplete=\"off\" autocapitalize=\"off\" spellcheck=\"false\"\n aria-label=\"Comando\" [readonly]=\"Busy()\" [(ngModel)]=\"Command\" (keydown)=\"onKeyDown($event)\" (paste)=\"onPaste($event)\" />\n </div>\n</div>\n", styles: ["es-terminal{--es-terminal-background: #1e1e1e;--es-terminal-color: #d4d4d4;--es-terminal-command-color: #ffffff;--es-terminal-prompt-color: #4ec9b0;--es-terminal-greeting-color: #569cd6;--es-terminal-info-color: #9a9a9a;--es-terminal-error-color: #f48771;--es-terminal-selection: rgba(255, 255, 255, .25);--es-terminal-font: Consolas, \"Cascadia Mono\", \"DejaVu Sans Mono\", \"Courier New\", monospace;--es-terminal-font-size: 13px;--es-terminal-line-height: 1.45;display:block;height:100%;min-height:0}.es-terminal{height:100%;overflow-y:auto;overflow-x:hidden;padding:10px 12px;box-sizing:border-box;background:var(--es-terminal-background);color:var(--es-terminal-color);font-family:var(--es-terminal-font);font-size:var(--es-terminal-font-size);line-height:var(--es-terminal-line-height);cursor:text}.es-terminal ::selection{background:var(--es-terminal-selection)}.es-terminal-line{white-space:pre-wrap;overflow-wrap:anywhere;min-height:calc(var(--es-terminal-font-size) * var(--es-terminal-line-height))}.es-terminal-command{color:var(--es-terminal-command-color)}.es-terminal-greeting{color:var(--es-terminal-greeting-color);margin-bottom:4px}.es-terminal-info{color:var(--es-terminal-info-color)}.es-terminal-error{color:var(--es-terminal-error-color)}.es-terminal-prompt{color:var(--es-terminal-prompt-color);white-space:pre;margin-right:.5ch;-webkit-user-select:none;user-select:none}.es-terminal-input-line{display:flex;align-items:baseline}.es-terminal-input{flex:1 1 auto;min-width:0;padding:0;margin:0;border:none;outline:none;background:transparent;color:var(--es-terminal-command-color);caret-color:var(--es-terminal-command-color);font:inherit;line-height:inherit}.es-terminal-busy .es-terminal-input{color:transparent;caret-color:transparent}.es-terminal-spinner{display:inline-block;width:1ch;margin-right:.5ch;color:var(--es-terminal-prompt-color)}.es-terminal-spinner:after{content:\"|\";animation:es-terminal-spin .6s steps(4) infinite}@keyframes es-terminal-spin{0%{content:\"|\"}25%{content:\"/\"}50%{content:\"-\"}75%{content:\"\\\\\"}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], encapsulation: i0.ViewEncapsulation.None }); }
1849
+ }
1850
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: EsTerminalComponent, decorators: [{
1851
+ type: Component,
1852
+ args: [{ selector: "es-terminal", encapsulation: ViewEncapsulation.None, imports: [FormsModule], template: "<div class=\"es-terminal\" #screen (click)=\"onScreenClick()\">\n @for (line of Lines(); track $index) {\n @if (line.Kind == 'command') {\n <div class=\"es-terminal-line es-terminal-command\"><span class=\"es-terminal-prompt\">{{line.Prompt}}</span>{{line.Text}}</div>\n } @else {\n <div class=\"es-terminal-line\" [class]=\"'es-terminal-' + line.Kind\">{{line.Text}}</div>\n }\n }\n\n <div class=\"es-terminal-line es-terminal-input-line\" [class.es-terminal-busy]=\"Busy()\">\n @if (Busy()) {\n <span class=\"es-terminal-spinner\"></span>\n } @else {\n <span class=\"es-terminal-prompt\">{{CurrentPrompt()}}</span>\n }\n <input #input class=\"es-terminal-input\" type=\"text\" autocomplete=\"off\" autocapitalize=\"off\" spellcheck=\"false\"\n aria-label=\"Comando\" [readonly]=\"Busy()\" [(ngModel)]=\"Command\" (keydown)=\"onKeyDown($event)\" (paste)=\"onPaste($event)\" />\n </div>\n</div>\n", styles: ["es-terminal{--es-terminal-background: #1e1e1e;--es-terminal-color: #d4d4d4;--es-terminal-command-color: #ffffff;--es-terminal-prompt-color: #4ec9b0;--es-terminal-greeting-color: #569cd6;--es-terminal-info-color: #9a9a9a;--es-terminal-error-color: #f48771;--es-terminal-selection: rgba(255, 255, 255, .25);--es-terminal-font: Consolas, \"Cascadia Mono\", \"DejaVu Sans Mono\", \"Courier New\", monospace;--es-terminal-font-size: 13px;--es-terminal-line-height: 1.45;display:block;height:100%;min-height:0}.es-terminal{height:100%;overflow-y:auto;overflow-x:hidden;padding:10px 12px;box-sizing:border-box;background:var(--es-terminal-background);color:var(--es-terminal-color);font-family:var(--es-terminal-font);font-size:var(--es-terminal-font-size);line-height:var(--es-terminal-line-height);cursor:text}.es-terminal ::selection{background:var(--es-terminal-selection)}.es-terminal-line{white-space:pre-wrap;overflow-wrap:anywhere;min-height:calc(var(--es-terminal-font-size) * var(--es-terminal-line-height))}.es-terminal-command{color:var(--es-terminal-command-color)}.es-terminal-greeting{color:var(--es-terminal-greeting-color);margin-bottom:4px}.es-terminal-info{color:var(--es-terminal-info-color)}.es-terminal-error{color:var(--es-terminal-error-color)}.es-terminal-prompt{color:var(--es-terminal-prompt-color);white-space:pre;margin-right:.5ch;-webkit-user-select:none;user-select:none}.es-terminal-input-line{display:flex;align-items:baseline}.es-terminal-input{flex:1 1 auto;min-width:0;padding:0;margin:0;border:none;outline:none;background:transparent;color:var(--es-terminal-command-color);caret-color:var(--es-terminal-command-color);font:inherit;line-height:inherit}.es-terminal-busy .es-terminal-input{color:transparent;caret-color:transparent}.es-terminal-spinner{display:inline-block;width:1ch;margin-right:.5ch;color:var(--es-terminal-prompt-color)}.es-terminal-spinner:after{content:\"|\";animation:es-terminal-spin .6s steps(4) infinite}@keyframes es-terminal-spin{0%{content:\"|\"}25%{content:\"/\"}50%{content:\"-\"}75%{content:\"\\\\\"}}\n"] }]
1853
+ }], propDecorators: { Greetings: [{
1854
+ type: Input
1855
+ }], Prompt: [{
1856
+ type: Input
1857
+ }], Executor: [{
1858
+ type: Input
1859
+ }], HistoryKey: [{
1860
+ type: Input
1861
+ }], MaxHistory: [{
1862
+ type: Input
1863
+ }], AutoFocus: [{
1864
+ type: Input
1865
+ }], screen: [{
1866
+ type: ViewChild,
1867
+ args: ["screen", { static: true }]
1868
+ }], input: [{
1869
+ type: ViewChild,
1870
+ args: ["input", { static: false }]
1871
+ }] } });
1872
+
1619
1873
  // Angular
1620
1874
  const COMPONENTS = [
1621
1875
  BackTop,
@@ -1634,7 +1888,8 @@ const COMPONENTS = [
1634
1888
  EsImageCropperComponent,
1635
1889
  FormSelectorComponent,
1636
1890
  FormSelectorDialogComponent,
1637
- EntityFeedsWidgetComponent
1891
+ EntityFeedsWidgetComponent,
1892
+ EsTerminalComponent
1638
1893
  ];
1639
1894
  class ComponentsModule {
1640
1895
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: ComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -1654,7 +1909,8 @@ class ComponentsModule {
1654
1909
  EsImageCropperComponent,
1655
1910
  FormSelectorComponent,
1656
1911
  FormSelectorDialogComponent,
1657
- EntityFeedsWidgetComponent], exports: [BackTop,
1912
+ EntityFeedsWidgetComponent,
1913
+ EsTerminalComponent], exports: [BackTop,
1658
1914
  Breadcrumb,
1659
1915
  ErrorPageComponent,
1660
1916
  PagesComponent,
@@ -1670,7 +1926,8 @@ class ComponentsModule {
1670
1926
  EsImageCropperComponent,
1671
1927
  FormSelectorComponent,
1672
1928
  FormSelectorDialogComponent,
1673
- EntityFeedsWidgetComponent] }); }
1929
+ EntityFeedsWidgetComponent,
1930
+ EsTerminalComponent] }); }
1674
1931
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: ComponentsModule, imports: [CommonModule, RouterModule, FormsModule, DirectivesModule, LocalizationModule, ProgressbarModule, BsDropdownModule, ModalModule, EsTableModule, ErrorPageComponent,
1675
1932
  PagesComponent,
1676
1933
  Navbar,
@@ -1678,7 +1935,8 @@ class ComponentsModule {
1678
1935
  EsImageCropperComponent,
1679
1936
  FormSelectorComponent,
1680
1937
  FormSelectorDialogComponent,
1681
- EntityFeedsWidgetComponent] }); }
1938
+ EntityFeedsWidgetComponent,
1939
+ EsTerminalComponent] }); }
1682
1940
  }
1683
1941
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: ComponentsModule, decorators: [{
1684
1942
  type: NgModule,
@@ -2460,5 +2718,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImpo
2460
2718
  * Generated bundle index. Do not edit.
2461
2719
  */
2462
2720
 
2463
- export { BackTop, BaseComponent, BaseSearchComponent, BaseSelectorComponent, BaseSelectorInitialization, Breadcrumb, BreadcrumbItem, ComponentsModule, EmbeddingComponent, EntityFeedsWidgetComponent, ErrorPageComponent, EsImageCropperComponent, EsModalComponent, EsModalHeadComponent, ExternalPagesComponent, FormSelectorComponent, FormSelectorDialogComponent, JaceLoginComponent, JaceResourceComponent, LabeledSpanComponent, Navbar, PagesComponent, ReactiveComponent, RedirecterComponent, Sidebar, UserInfosComponent };
2721
+ export { BackTop, BaseComponent, BaseSearchComponent, BaseSelectorComponent, BaseSelectorInitialization, Breadcrumb, BreadcrumbItem, ComponentsModule, EmbeddingComponent, EntityFeedsWidgetComponent, ErrorPageComponent, EsImageCropperComponent, EsModalComponent, EsModalHeadComponent, EsTerminalComponent, ExternalPagesComponent, FormSelectorComponent, FormSelectorDialogComponent, JaceLoginComponent, JaceResourceComponent, LabeledSpanComponent, Navbar, PagesComponent, ReactiveComponent, RedirecterComponent, Sidebar, UserInfosComponent };
2464
2722
  //# sourceMappingURL=esfaenza-core-components.mjs.map