@masterkeymaterial/ui 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/README.md +9 -59
  2. package/ng-package.json +10 -0
  3. package/package.json +5 -14
  4. package/src/elements/ui-button/ui-button.css +229 -0
  5. package/src/elements/ui-button/ui-button.html +12 -0
  6. package/src/elements/ui-button/ui-button.ts +133 -0
  7. package/src/elements/ui-check-box/ui-check-box.css +66 -0
  8. package/src/elements/ui-check-box/ui-check-box.html +5 -0
  9. package/src/elements/ui-check-box/ui-check-box.ts +65 -0
  10. package/src/elements/ui-chip/ui-chip.css +24 -0
  11. package/src/elements/ui-chip/ui-chip.html +3 -0
  12. package/src/elements/ui-chip/ui-chip.ts +25 -0
  13. package/src/elements/ui-drop-zone/ui-drop-zone.css +91 -0
  14. package/src/elements/ui-drop-zone/ui-drop-zone.html +8 -0
  15. package/src/elements/ui-drop-zone/ui-drop-zone.ts +153 -0
  16. package/src/elements/ui-file-list/ui-file-list.css +43 -0
  17. package/src/elements/ui-file-list/ui-file-list.html +17 -0
  18. package/src/elements/ui-file-list/ui-file-list.ts +22 -0
  19. package/src/elements/ui-list-errors/ui-list-errors.css +30 -0
  20. package/src/elements/ui-list-errors/ui-list-errors.html +10 -0
  21. package/src/elements/ui-list-errors/ui-list-errors.ts +14 -0
  22. package/src/elements/ui-loading/ui-loading.css +13 -0
  23. package/src/elements/ui-loading/ui-loading.html +1 -0
  24. package/src/elements/ui-loading/ui-loading.ts +10 -0
  25. package/src/elements/ui-menu/ui-menu.css +69 -0
  26. package/src/elements/ui-menu/ui-menu.html +20 -0
  27. package/src/elements/ui-menu/ui-menu.ts +267 -0
  28. package/src/elements/ui-procurar/ui-procurar.css +48 -0
  29. package/src/elements/ui-procurar/ui-procurar.html +14 -0
  30. package/src/elements/ui-procurar/ui-procurar.ts +82 -0
  31. package/src/elements/ui-progress/ui-progress.css +0 -0
  32. package/src/elements/ui-progress/ui-progress.html +1 -0
  33. package/src/elements/ui-progress/ui-progress.ts +15 -0
  34. package/src/elements/ui-select/ui-select.css +211 -0
  35. package/src/elements/ui-select/ui-select.html +46 -0
  36. package/src/elements/ui-select/ui-select.ts +482 -0
  37. package/src/elements/ui-slide/ui-slide.css +75 -0
  38. package/src/elements/ui-slide/ui-slide.html +7 -0
  39. package/src/elements/ui-slide/ui-slide.ts +61 -0
  40. package/src/fields/Base/BaseFieldsForm/BaseFieldsForm.component.ts +113 -0
  41. package/src/fields/Base/BaseFieldsValues/BaseFieldsValues.ts +112 -0
  42. package/src/fields/Formulario/Formulario.ts +1056 -0
  43. package/src/fields/Formulario/form-action/form-action.css +98 -0
  44. package/src/fields/Formulario/form-action/form-action.html +75 -0
  45. package/src/fields/Formulario/form-action/form-action.ts +187 -0
  46. package/src/fields/Formulario/form-controls/form-controls.css +108 -0
  47. package/src/fields/Formulario/form-controls/form-controls.html +105 -0
  48. package/src/fields/Formulario/form-controls/form-controls.ts +122 -0
  49. package/src/fields/Formulario/form-fase/form-fase.css +84 -0
  50. package/src/fields/Formulario/form-fase/form-fase.html +24 -0
  51. package/src/fields/Formulario/form-fase/form-fase.ts +157 -0
  52. package/src/fields/Formulario/form-filter/form-filter.css +50 -0
  53. package/src/fields/Formulario/form-filter/form-filter.html +25 -0
  54. package/src/fields/Formulario/form-filter/form-filter.ts +53 -0
  55. package/src/fields/Formulario/form-no-action/form-no-action.css +32 -0
  56. package/src/fields/Formulario/form-no-action/form-no-action.html +12 -0
  57. package/src/fields/Formulario/form-no-action/form-no-action.ts +21 -0
  58. package/src/fields/Formulario/formated-values/formated-values.css +104 -0
  59. package/src/fields/Formulario/formated-values/formated-values.html +15 -0
  60. package/src/fields/Formulario/formated-values/formated-values.ts +186 -0
  61. package/src/fields/Formulario/single-values/single-values.css +88 -0
  62. package/src/fields/Formulario/single-values/single-values.html +11 -0
  63. package/src/fields/Formulario/single-values/single-values.ts +65 -0
  64. package/src/fields/autocomplete/autocomplete.css +94 -0
  65. package/src/fields/autocomplete/autocomplete.html +38 -0
  66. package/src/fields/autocomplete/autocomplete.ts +294 -0
  67. package/src/fields/button/button.css +7 -0
  68. package/src/fields/button/button.html +19 -0
  69. package/src/fields/button/button.ts +38 -0
  70. package/src/fields/checkbox/checkbox.css +27 -0
  71. package/src/fields/checkbox/checkbox.html +20 -0
  72. package/src/fields/checkbox/checkbox.ts +44 -0
  73. package/src/fields/color/CirculoColorido/circulocolorido.css +50 -0
  74. package/src/fields/color/CirculoColorido/circulocolorido.html +8 -0
  75. package/src/fields/color/CirculoColorido/circulocolorido.ts +24 -0
  76. package/src/fields/color/color.css +15 -0
  77. package/src/fields/color/color.html +24 -0
  78. package/src/fields/color/color.ts +47 -0
  79. package/src/fields/date/date.html +19 -0
  80. package/src/fields/date/date.ts +29 -0
  81. package/src/fields/datetime/datetime.html +19 -0
  82. package/src/fields/datetime/datetime.ts +29 -0
  83. package/src/fields/display/display.css +7 -0
  84. package/src/fields/display/display.html +20 -0
  85. package/src/fields/display/display.ts +43 -0
  86. package/src/fields/editor/editor.css +51 -0
  87. package/src/fields/editor/editor.html +37 -0
  88. package/src/fields/editor/editor.ts +218 -0
  89. package/src/fields/email/email.html +19 -0
  90. package/src/fields/email/email.ts +29 -0
  91. package/src/fields/fields.css +180 -0
  92. package/src/fields/generic/generic.html +3 -0
  93. package/src/fields/generic/generic.ts +91 -0
  94. package/src/fields/hidden/hidden.html +3 -0
  95. package/src/fields/hidden/hidden.ts +20 -0
  96. package/src/fields/icon/icon.css +19 -0
  97. package/src/fields/icon/icon.html +27 -0
  98. package/src/fields/icon/icon.ts +31 -0
  99. package/src/fields/multifactor/multifactor.css +21 -0
  100. package/src/fields/multifactor/multifactor.html +39 -0
  101. package/src/fields/multifactor/multifactor.ts +106 -0
  102. package/src/fields/multikv/multikv.css +43 -0
  103. package/src/fields/multikv/multikv.html +47 -0
  104. package/src/fields/multikv/multikv.ts +88 -0
  105. package/src/fields/multitext/multitext.css +36 -0
  106. package/src/fields/multitext/multitext.html +38 -0
  107. package/src/fields/multitext/multitext.ts +75 -0
  108. package/src/fields/number/number.html +20 -0
  109. package/src/fields/number/number.ts +35 -0
  110. package/src/fields/password/password.html +23 -0
  111. package/src/fields/password/password.ts +37 -0
  112. package/src/fields/search/search.css +0 -0
  113. package/src/fields/search/search.html +19 -0
  114. package/src/fields/search/search.ts +54 -0
  115. package/src/fields/select/select.css +15 -0
  116. package/src/fields/select/select.html +18 -0
  117. package/src/fields/select/select.ts +52 -0
  118. package/src/fields/slide/slide.css +27 -0
  119. package/src/fields/slide/slide.html +20 -0
  120. package/src/fields/slide/slide.ts +45 -0
  121. package/src/fields/text/text.html +19 -0
  122. package/src/fields/text/text.ts +30 -0
  123. package/src/fields/textarea/textarea.css +4 -0
  124. package/src/fields/textarea/textarea.html +20 -0
  125. package/src/fields/textarea/textarea.ts +31 -0
  126. package/src/fields/time/time.html +19 -0
  127. package/src/fields/time/time.ts +29 -0
  128. package/src/fields/upload/upload.css +24 -0
  129. package/src/fields/upload/upload.html +41 -0
  130. package/src/fields/upload/upload.ts +137 -0
  131. package/src/interfaces/interfaces.ts +61 -0
  132. package/src/public-api.ts +38 -0
  133. package/src/util/ClassOf.pipe.ts +11 -0
  134. package/src/util/JsonColorido.pipe.ts +11 -0
  135. package/src/util/util.ts +2151 -0
  136. package/tsconfig.lib.json +16 -0
  137. package/tsconfig.lib.prod.json +9 -0
  138. package/tsconfig.spec.json +13 -0
  139. package/fesm2022/masterkeymaterial-ui.mjs +0 -6457
  140. package/fesm2022/masterkeymaterial-ui.mjs.map +0 -1
  141. package/types/masterkeymaterial-ui.d.ts +0 -928
@@ -0,0 +1,98 @@
1
+ :host {
2
+ display: block;
3
+ width: 100%;
4
+ }
5
+
6
+ .buttonsGap {
7
+ display: flex;
8
+ flex-direction: var(--ui-form-flex-direction, column);
9
+ gap: var(--MasterGap);
10
+ margin-top: var(--MasterGap);
11
+ z-index: 9;
12
+ }
13
+
14
+ .fieldHidden {
15
+ display: none;
16
+ }
17
+
18
+
19
+ .showOutlineFields fields-g {
20
+ outline: 1px dashed #555;
21
+ z-index: 2;
22
+ }
23
+
24
+ .icons {
25
+ display: flex;
26
+ flex-direction: row;
27
+ gap: 5px;
28
+ justify-content: center;
29
+ align-items: center;
30
+ }
31
+
32
+ .icons .done {
33
+ color: var(--sys-warning);
34
+ }
35
+
36
+ .icons .done.success {
37
+ color: var(--sys-success);
38
+ }
39
+
40
+ .icons .done.fail {
41
+ color: var(--sys-error);
42
+ }
43
+
44
+ .containerFases {
45
+ display: flex;
46
+ flex-direction: row;
47
+ width: 100%;
48
+ gap: calc(var(--MasterGap) * 2);
49
+ margin-top: var(--MasterGap);
50
+ margin-bottom: var(--MasterGap);
51
+ overflow: hidden;
52
+ /* overflow-x: hidden;
53
+ overflow-y: auto;
54
+ O OverflowX é necessário, o Y não. E o Y está gerando problemas. Ao definir o X, o Y resolve ser obrigatório.
55
+ Problemas quando overflow-y é auto:
56
+ - A largura da barra causa um erro no calculo do translateX, fazendo um pequeno espaço sumir no início.
57
+ */
58
+ position: relative;
59
+ padding: 2px;
60
+ z-index: 10;
61
+ }
62
+
63
+ .containerFases.showOutlineFields {
64
+ outline: 1px solid var(--sys-outline);
65
+ }
66
+
67
+ .areaFase {
68
+ transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;
69
+ width: 100%;
70
+ min-width: 100%;
71
+ flex-shrink: 0;
72
+ height: fit-content;
73
+ transform: translateX(calc(var(--fase, 0) * (100% + (var(--MasterGap) * 2)) * -1));
74
+ /* margin-left: var(--MasterGap); */
75
+ }
76
+
77
+ .areaFase.ativo {
78
+ opacity: 1;
79
+ }
80
+
81
+ .areaFase:not(.ativo) {
82
+ opacity: 0;
83
+ height: 1px;
84
+ }
85
+
86
+ .botaoAcaoSave {
87
+ position: relative;
88
+ }
89
+
90
+ .loadingSubmit {
91
+ position: absolute;
92
+ right: 5px;
93
+ font-size: 32px;
94
+ /* transform: translate(10px); */
95
+ display: flex;
96
+ justify-content: center;
97
+ align-items: center;
98
+ }
@@ -0,0 +1,75 @@
1
+ <ui-form-fase [fases]="fases()" [campos]="form.listaCampos()" [(faseIndex)]="faseIndex"></ui-form-fase>
2
+ @if(isFaseado()){
3
+ <div class="containerFases" [class.showOutlineFields]="hasOutline()">
4
+ @for (fase of listaFase(); track $index;let fIndex = $index) {
5
+ <div class="areaFase g-fields" [style.--fase]="faseIndex()" [class.ativo]="faseIndex() == fIndex"
6
+ [style.--g-fields-min]="fase.gridMin" [style.--g-fields-max]="fase.gridMax"
7
+ [class.showOutlineFields]="hasOutline()">
8
+ @for (faseGrupo of faseGrupo(); track $index) {
9
+ @if(faseGrupo.faseIndex == fIndex){
10
+
11
+ @if(faseGrupo.tipo == 'campo' && faseGrupo.campo){
12
+
13
+ <fields-g [form]="form" [name]="faseGrupo.campo.prop"
14
+ [class]="faseGrupo.campo.tipo == 'hidden' ? 'fieldHidden' : ''"></fields-g>
15
+
16
+ } @else if (faseGrupo.tipo == 'grupo' && faseGrupo.grupo) {
17
+
18
+ <div class="field-group" [style.grid-area]="faseGrupo.grupo.area ?? 'auto / auto / auto / span 2'">
19
+ @if(faseGrupo.grupo.titulo){ <div class="group-title"
20
+ [style.grid-area]="faseGrupo.grupo.tituloArea ?? 'auto / auto / auto / span 2'">{{
21
+ faseGrupo.grupo!.titulo }}</div> }
22
+ @for(campo of faseGrupo.grupo!.campos; track $index){
23
+ <fields-g [form]="form" [name]="campo"
24
+ [class]="form.campos()[campo]?.tipo == 'hidden' ? 'fieldHidden' : ''"></fields-g>
25
+ }
26
+ </div>
27
+
28
+ }@else{
29
+
30
+ <div class="card bg-danger"> ❌ Falha tipo {{ faseGrupo.tipo }}.<br> Campo {{ faseGrupo.nome }} não encontrado!</div>
31
+ }
32
+
33
+ }
34
+ }
35
+ </div>
36
+ }
37
+ </div>
38
+
39
+ }@else {
40
+ <div class="g-fields" [style.--g-fields-min]="gmin()" [style.--g-fields-max]="gmax()"
41
+ [class.showOutlineFields]="hasOutline()">
42
+
43
+ @for (campo of form.listaCampos(); track $index) {
44
+ <fields-g [form]="form" [name]="campo.prop" [class]="campo.tipo == 'hidden' ? 'fieldHidden' : ''"></fields-g>
45
+ }
46
+
47
+ </div>
48
+ }
49
+
50
+ <div class="buttonsGap">
51
+ <ui-button tipo="fill" tema="primary" (clicked)="onSave()" [disabled]="isDisabledAction()" class="botaoAcaoSave">
52
+ @if(showFormControls()){
53
+ <div class="icons">
54
+ @for (task of tasksToSave(); track $index) {
55
+ <i [class]="task.icone" [class.done]="task.done" [class.success]="task.success == true"
56
+ [class.fail]="task.success == false"></i>
57
+ }
58
+ </div>
59
+ }
60
+ <div class="f-1">
61
+ {{ actionTitle() ?? 'Salvar' }}
62
+ </div>
63
+ @if(isLoadingActive()){
64
+ <div class="loadingSubmit">
65
+ <ui-loading></ui-loading>
66
+ </div>
67
+ }
68
+ </ui-button>
69
+ <ng-content></ng-content>
70
+ </div>
71
+
72
+ @if(showFormControls()){
73
+ <ui-form-controls [form]="form" [recebido]="this.values()" [(hasOutline)]="hasOutline" [faseIndex]="faseIndex()"
74
+ [totalFases]="listaFase().length"></ui-form-controls>
75
+ }
@@ -0,0 +1,187 @@
1
+ import { Component, input, model, OnInit, output, signal } from '@angular/core';
2
+ import { UiButton } from "../../../elements/ui-button/ui-button";
3
+ import { LibUtil, LOG } from '../../../util/util';
4
+ import { BaseFieldsValues } from '../../Base/BaseFieldsValues/BaseFieldsValues';
5
+ import { FieldsGeneric } from '../../generic/generic';
6
+ import { FormControls } from "../form-controls/form-controls";
7
+ import { FormFase } from "../form-fase/form-fase";
8
+ import { UiLoading } from "../../../elements/ui-loading/ui-loading";
9
+
10
+ export interface ISaveTasks {
11
+ title: string;
12
+ icone: string;
13
+ task: () => Promise<boolean>;
14
+ done?: boolean;
15
+ success?: boolean;
16
+ }
17
+
18
+ export interface IActionsDone {
19
+ values: any;
20
+ result: any;
21
+ tasks: ISaveTasks[];
22
+ ok: boolean; // Booleano que indica se todas tarefas inseridas foram concluídas com sucesso.
23
+ }
24
+
25
+ @Component({
26
+ selector: 'fields-form-action',
27
+ templateUrl: './form-action.html',
28
+ styleUrls: ['./form-action.css'],
29
+ imports: [UiButton, FieldsGeneric, FormControls, FormFase, UiLoading],
30
+ })
31
+ export class FormAction<T> extends BaseFieldsValues<T> implements OnInit {
32
+
33
+ hasOutline = model<boolean>(false);
34
+
35
+ actionTitle = input<string | undefined>();
36
+ sendValues = input<((values: any) => Promise<any>) | undefined>();
37
+ sending = output<boolean>();
38
+ done = output<IActionsDone>();
39
+
40
+ // Permite customizar tarefas.
41
+ taskTocar = input<boolean>(true);
42
+ taskSanitizar = input<boolean>(true);
43
+ taskDisponiveis = input<boolean>(true);
44
+ taskValidar = input<boolean>(true);
45
+ taskEnviar = input<boolean>(true);
46
+ tasksToSave = signal<ISaveTasks[]>([]);
47
+
48
+ result: any = null;
49
+
50
+ override ngOnInit(): void {
51
+ super.ngOnInit();
52
+ this.updateDisabledAction();
53
+
54
+ // Incrementa tarefa TOCAR
55
+ if (this.taskTocar()) {
56
+ this.tasksToSave.update(tasks => [...tasks, {
57
+ title: 'Tocando campos',
58
+ icone: 'fa fa-handshake',
59
+ task: async () => {
60
+ this.form.setTouchedAll(true);
61
+ return true;
62
+ }
63
+ }]);
64
+ }
65
+
66
+ // Incrementa tarefa Sanitizando
67
+ if (this.taskSanitizar()) {
68
+ this.tasksToSave.update(tasks => [...tasks, {
69
+ title: 'Sanitizando',
70
+ icone: 'fa fa-quidditch-broom-ball',
71
+ task: async () => {
72
+ this.form.sanitizar();
73
+ return true;
74
+ }
75
+ }]);
76
+ }
77
+
78
+ // Tarefa para filtrar apenas os campos disponíveis para envio (ex: campos desabilitados, etc).
79
+ if (this.taskDisponiveis()) {
80
+ this.tasksToSave.update(tasks => [...tasks, {
81
+ title: 'Disponíveis para envio',
82
+ icone: 'fa fa-power-off',
83
+ task: async () => {
84
+ this.form.onlyAvailable();
85
+ return true;
86
+ }
87
+ }]);
88
+ }
89
+
90
+ // Incrementa tarefa VALIDAR
91
+ if (this.taskValidar()) {
92
+ this.tasksToSave.update(tasks => [...tasks, {
93
+ title: 'Validando',
94
+ icone: 'bi bi-ui-checks',
95
+ task: async () => {
96
+ try {
97
+ await this.form.validar();
98
+ return true;
99
+ } catch (e) {
100
+ return false;
101
+ }
102
+ }
103
+ }]);
104
+ }
105
+
106
+ // Incrementa tarefa SENDVALUES
107
+ if (this.taskEnviar() && this.sendValues()) {
108
+ this.tasksToSave.update(tasks => [...tasks, {
109
+ title: 'Ação de enviar',
110
+ icone: 'fa fa-paper-plane',
111
+ task: async () => {
112
+ // Para enviar, o form deve estar válido.
113
+ if (!this.form.valido()) return false;
114
+
115
+ // Para enviar, deve existir a função de envio.
116
+ let fnEnviar = this.sendValues();
117
+ if (!fnEnviar) return false;
118
+
119
+ // Reinicia o resultado anterior, se houver.
120
+ this.result = null;
121
+
122
+ // Obtem os valores do formulário.
123
+ let valores = LibUtil.clonar(this.form.values());
124
+
125
+ // Inicia o envio.
126
+ try {
127
+ this.form.isEnviando = true;
128
+ this.sending.emit(true);
129
+ this.result = await fnEnviar(valores);
130
+ this.form.isEnviando = false;
131
+ this.sending.emit(false);
132
+ if (this.result != null) {
133
+ // Indica que a tarefa de envio foi concluída com sucesso.
134
+ return true;
135
+ }
136
+ } catch (e) {
137
+ LOG(1, "❌ ERRO ao Enviar Valores. ", e);
138
+ }
139
+
140
+ // Qualquer outro caso, indica falha.
141
+ return false;
142
+ }
143
+ }]);
144
+ }
145
+
146
+ // Neste componente, há sempre uma ação e sempre emite tasksDone.
147
+ this.tasksToSave.update(tasks => [
148
+ ...tasks,
149
+ {
150
+ title: 'Ações concluídas',
151
+ icone: 'fa fa-flag-checkered',
152
+ task: async () => {
153
+ let ok = this.tasksToSave().filter(task => task.title !== 'Ações concluídas').every(task => task.success);
154
+ let values = LibUtil.clonar(this.form.values());
155
+ let actionsDone: IActionsDone = {
156
+ values,
157
+ result: this.result,
158
+ tasks: this.tasksToSave(),
159
+ ok
160
+ }
161
+ this.done.emit(actionsDone);
162
+ if (ok) this.form.isEnviado = true;
163
+ return ok;
164
+ }
165
+ }
166
+ ]);
167
+
168
+ }
169
+
170
+ async onSave() {
171
+ this.tasksToSave.update(tasks => tasks.map(t => ({ ...t, done: false })));
172
+ this.updateDisabledAction(true);
173
+ this.isLoadingActive.set(true);
174
+
175
+ for await (const task of this.tasksToSave()) {
176
+ // await LibUtil.wait(1000);
177
+ let r = task.task();
178
+ r.then(s => task.success = s).catch(f => task.success = false);
179
+ await r;
180
+ task.done = true;
181
+ }
182
+
183
+ this.isLoadingActive.set(false);
184
+ this.updateDisabledAction();
185
+ }
186
+
187
+ }
@@ -0,0 +1,108 @@
1
+ .areaFormControl {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--MasterGap);
5
+ margin-top: var(--MasterGap);
6
+ }
7
+
8
+ .barStatus {
9
+ display: flex;
10
+ flex-direction: row;
11
+ gap: var(--MasterGap);
12
+ align-items: center;
13
+ }
14
+
15
+ .formColtrols {
16
+ display: flex;
17
+ flex-direction: row;
18
+ gap: var(--MasterGap);
19
+ }
20
+
21
+ .collapsed .formColtrols {
22
+ display: none;
23
+ }
24
+
25
+ .areaValues {
26
+ outline: 1px solid color-mix(in srgb, var(--sys-outline) 50%, transparent 50%);
27
+ background-color: color-mix(in srgb, var(--sys-card) 80%, var(--sys-background) 20%);
28
+ border-radius: var(--MasterRadius);
29
+ padding: 0.5rem;
30
+ }
31
+
32
+ .areaValues.jsonArea {
33
+ flex: 1;
34
+ overflow: auto;
35
+ }
36
+
37
+ .divider {
38
+ flex: 1;
39
+ height: 30px;
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ cursor: pointer;
44
+ }
45
+
46
+ .controls {
47
+ display: flex;
48
+ flex-direction: column;
49
+ gap: 10px;
50
+ --ui-justify-content: left;
51
+ }
52
+
53
+ .controls .dados {
54
+ --ui-font-size: 20px;
55
+ }
56
+
57
+ .controls .estado {
58
+ --ui-font-size: 20px;
59
+ }
60
+
61
+ ui-button.estado.ativo {
62
+ outline: 1px outset var(--sys-high);
63
+ box-shadow:
64
+ 0 0 1px var(--sys-high),
65
+ inset 0 0 5px var(--sys-high);
66
+ border-radius: var(--MasterRadius);
67
+ }
68
+
69
+ pre {
70
+ font-size: 16px;
71
+ padding: 1rem;
72
+ }
73
+
74
+ .status {
75
+ gap: 5px;
76
+ }
77
+
78
+ .statusItem {
79
+ width: 30px;
80
+ height: 30px;
81
+ border: 1px solid var(--sys-outline);
82
+ display: flex;
83
+ justify-content: center;
84
+ align-items: center;
85
+ text-align: center;
86
+ border-radius: 4px;
87
+ line-height: 13px;
88
+ background-color: var(--sys-background);
89
+ }
90
+
91
+ .statusItem.ativo {
92
+ background-color: var(--sys-success-15);
93
+ border-color: var(--sys-success);
94
+ }
95
+
96
+ .statusItem.inativo {
97
+ background-color: var(--sys-error-15);
98
+ border-color: var(--sys-error);
99
+ }
100
+
101
+ .barIcoCollapse i {
102
+ transition: 300ms;
103
+ }
104
+
105
+ .collapsed .barIcoCollapse i {
106
+ transition: 300ms;
107
+ transform: rotate(180deg);
108
+ }
@@ -0,0 +1,105 @@
1
+ <div class="areaFormControl" [class.collapsed]="colapsed()">
2
+ <div class="areaValues barStatus">
3
+ <div class="f-s-e status">
4
+ <div class="statusItem f-s-12 f-t-b" [title]="'Fases. Atual: ' + faseIndex() + '. Total: ' + totalFases()"
5
+ [class.ativo]="totalFases() > 1" [class.inativo]="faseIndex() < 0 || faseIndex() > totalFases()">
6
+ @if(totalFases() > 1){
7
+ <div class="f-s-e">
8
+ <div>A</div>
9
+ <div>{{ faseIndex() }}</div>
10
+ </div>
11
+ <div class="f-s-e">
12
+ <div>U</div>
13
+ <div>{{ totalFases() - 1 }}</div>
14
+ </div>
15
+ } @else {
16
+ <i class="fa fa-list-check f-s-18"></i>
17
+ }
18
+ </div>
19
+ <div class="statusItem" [class.ativo]="form().algumTocado()" [class.inativo]="!form().algumTocado()"
20
+ title="Algum campo tocado">
21
+ <i class="fa fa-handshake f-s-20"></i>
22
+ </div>
23
+ <div class="statusItem" [class.ativo]="form().valido()" [class.inativo]="!form().valido()"
24
+ title="Todos campos Válidos">
25
+ <i class="bi bi-check2-all f-s-20"></i>
26
+ </div>
27
+ <div class="statusItem" [class.ativo]="form().isEnviado" [class.inativo]="!form().isEnviado"
28
+ title="Estado de Enviado">
29
+ <i class="bi bi-send-check f-s-18"></i>
30
+ </div>
31
+ </div>
32
+ <div class="divider barIcoCollapse" (click)="colapsed.set(!colapsed())">
33
+ <i class="bi bi-caret-down"></i>
34
+ </div>
35
+ <div class="f-s-e status">
36
+ <ui-button tipo="icon" tema="success" class="dados" (click)="copiar()" icone="bi bi-copy"
37
+ title="Copiar o JSON de valores"></ui-button>
38
+ <ui-button tipo="icon" tema="success" class="estado" (click)="setOutline()" [class.ativo]="hasOutline()"
39
+ icone="fa fa-border-top-left" [title]="(hasOutline() ? 'Com' : 'Sem') +' Outline'"></ui-button>
40
+ <ui-button tipo="icon" tema="info" class="estado" (click)="changePreview()" [class.ativo]="showingErrors()"
41
+ icone="bi bi-exclamation-triangle" [title]="showingErrors() ? 'Errors' : 'Values'"></ui-button>
42
+ <ui-button tipo="icon" tema="info" class="estado" (click)="obrigatorio()" [class.ativo]="fullRequired()"
43
+ icone="fa fa-file-circle-exclamation" [title]="fullRequired() ? 'Obrigatório' : 'Liberado'"></ui-button>
44
+
45
+ <ui-button tipo="icon" tema="info" class="estado" (click)="desativados()" [class.ativo]="fullDisabled()"
46
+ icone="bi bi-person-fill-lock" [title]="fullDisabled() ? 'Desativado' : 'Ativo'"></ui-button>
47
+ <ui-button tipo="icon" tema="info" class="estado" (click)="pendentes()" [class.ativo]="fullPending()"
48
+ icone="fa fa-clock-four" [title]="fullPending() ? 'Pendente' : 'Sincronizado'"></ui-button>
49
+
50
+ </div>
51
+ </div>
52
+ @if(!colapsed()){
53
+ <div class="formColtrols">
54
+ <div class="areaValues jsonArea">
55
+ @if(showingErrors()){
56
+ <div>Erros do Formulário (Tipo: {{ form().listaErrors() | classOf }})</div>
57
+ <pre class="p-2" [innerHTML]="form().listaErrors() | jsonColorido"></pre>
58
+ } @else {
59
+ <div>Valor do Formulário (Tipo: {{ form().values() | classOf }})</div>
60
+ <pre class="p-2" [innerHTML]="valoresOrdenados() | jsonColorido"></pre>
61
+ }
62
+ </div>
63
+ <div class="areaValues controls">
64
+
65
+ <ui-button tipo="outlined" tema="success" class="dados" (click)="sanitizar()" icone="fa fa-quidditch-broom-ball"
66
+ title="Filtra e mantém apenas os valores dos campos que estão definidos para este formulário.">
67
+ Sanitizar
68
+ </ui-button>
69
+ <ui-button tipo="outlined" tema="success" class="dados" (click)="onlyAvailable()" icone="fa fa-power-off"
70
+ title="Filtra e mantém apenas os valores dos campos que estão disponíveis para este formulário.">
71
+ Disponíveis
72
+ </ui-button>
73
+ <ui-button tipo="outlined" tema="success" class="dados" (click)="validar()" icone="bi bi-ui-checks"
74
+ title="Valida o formulário e seus campos.">
75
+ Validar
76
+ </ui-button>
77
+ <ui-button tipo="outlined" tema="warning" class="dados" (click)="setarValRecebido()"
78
+ icone="fa fa-clock-rotate-left" title="Seta os valores que foram recebidos no formulário.">
79
+ Recebido
80
+ </ui-button>
81
+ <ui-button tipo="outlined" tema="error" class="dados" (click)="forcarVazio()" icone="bi bi-eraser-fill"
82
+ title="Limpa todos os valores do formulário.">
83
+ Limpar
84
+ </ui-button>
85
+ <ui-button tipo="outlined" tema="error" class="dados" (click)="setarValInicio()" icone="bi bi-skip-backward"
86
+ title="Reseta os valores do formulário para os valores iniciais.">
87
+ Reset
88
+ </ui-button>
89
+ <ui-button tipo="outlined" tema="info" class="dados" (click)="tocados()"
90
+ [icone]="fullTouched() ? 'fa fa-handshake' : 'fa fa-handshake-slash'"
91
+ title="Marca todos os campos como tocados ou não tocados.">
92
+ {{ fullTouched() ? 'Tocados' : 'Tocar Todos' }}
93
+ </ui-button>
94
+
95
+ <ui-button tipo="outlined" tema="error" class="estado" (click)="setErrorAll()"
96
+ [class.ativo]="form().listaErrors().length > 0"
97
+ [icone]="form().listaErrors().length > 0 ? 'bi bi-exclamation-triangle' : 'bi bi-circle'"
98
+ [title]="form().listaErrors().length > 0 ? 'Erros adicionados' : 'Erros removidos'">
99
+ {{ form().listaErrors().length > 0 ? 'Erros Forçados' : 'Erros removidos' }}
100
+ </ui-button>
101
+
102
+ </div>
103
+ </div>
104
+ }
105
+ </div>
@@ -0,0 +1,122 @@
1
+ import { Component, computed, input, model, signal } from '@angular/core';
2
+ import { UiButton } from "../../../elements/ui-button/ui-button";
3
+ import { Formulario } from '../Formulario';
4
+ import { JsonColoridoPipe } from '../../../util/JsonColorido.pipe';
5
+ import { ClassOfPipe } from '../../../util/ClassOf.pipe';
6
+ import { LibUtil } from '../../../util/util';
7
+
8
+ @Component({
9
+ selector: 'ui-form-controls',
10
+ templateUrl: './form-controls.html',
11
+ styleUrls: ['./form-controls.css'],
12
+ imports: [UiButton, JsonColoridoPipe, ClassOfPipe],
13
+ })
14
+ export class FormControls {
15
+
16
+ form = input.required<Formulario>();
17
+ recebido = input<any>({});
18
+ hasOutline = model<boolean>(false);
19
+ faseIndex = input<number>(0);
20
+ totalFases = input<number>(0);
21
+
22
+ colapsed = signal(true);
23
+
24
+ valoresOrdenados = computed(() => {
25
+ let jsonValues: any = {};
26
+ let formValues = this.form().values();
27
+ if (LibUtil.classof(formValues) !== 'object') {
28
+ return formValues;
29
+ }
30
+ let keys = Object.keys(formValues);
31
+ keys.sort();
32
+ for (let key of keys) {
33
+ jsonValues[key] = formValues[key];
34
+ }
35
+ return jsonValues;
36
+ });
37
+
38
+ // CONTROLES
39
+ copiar() {
40
+ let values = LibUtil.formatJson(this.valoresOrdenados(), true)
41
+ LibUtil.copy(values);
42
+ }
43
+
44
+
45
+ fullDisabled = signal(false);
46
+ desativados() {
47
+ this.fullDisabled.set(!this.fullDisabled());
48
+ this.form().setDisabledAll(this.fullDisabled());
49
+ }
50
+
51
+ fullRequired = signal(false);
52
+ obrigatorio() {
53
+ this.fullRequired.set(!this.fullRequired());
54
+ this.form().campos.update(c => {
55
+ for (const key of Object.keys(c)) {
56
+ c[key].need = this.fullRequired();
57
+ }
58
+ return c;
59
+ });
60
+ }
61
+
62
+ fullPending = signal(false);
63
+ pendentes() {
64
+ this.fullPending.set(!this.fullPending());
65
+ this.form().campos.update(c => {
66
+ for (const key of Object.keys(c)) {
67
+ c[key].pending = this.fullPending();
68
+ }
69
+ return c;
70
+ });
71
+ }
72
+
73
+ fullTouched = signal(false);
74
+ tocados() {
75
+ this.fullTouched.set(!this.fullTouched());
76
+ this.form().setTouchedAll(this.fullTouched());
77
+ }
78
+
79
+ forcarVazio() {
80
+ this.form().setAllValuesTo('');
81
+ }
82
+
83
+ setarValInicio() {
84
+ this.form().resetToStartValues();
85
+ }
86
+
87
+ setarValRecebido() {
88
+ this.form().updateValues(this.recebido());
89
+ }
90
+
91
+ setOutline() {
92
+ this.hasOutline.set(!this.hasOutline());
93
+ this.form().showTouched.update(v => !v);
94
+ }
95
+
96
+ sanitizar() {
97
+ this.form().sanitizar();
98
+ }
99
+
100
+ onlyAvailable() {
101
+ this.form().onlyAvailable();
102
+ }
103
+
104
+ async validar() {
105
+ await this.form().validar();
106
+ }
107
+
108
+ showingErrors = signal(false);
109
+ changePreview() {
110
+ this.showingErrors.set(!this.showingErrors());
111
+ }
112
+
113
+ errorsSetted = signal(false);
114
+ setErrorAll() {
115
+ this.errorsSetted.set(!this.errorsSetted());
116
+ if (this.errorsSetted()) {
117
+ this.form().setAllCamposPartial({ errors: ['Erro exemplo'] });
118
+ } else {
119
+ this.form().setAllCamposPartial({ errors: [] });
120
+ }
121
+ }
122
+ }