appproject-framework 1.0.11 → 1.0.12

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,6 +14,8 @@ import { NgClass, DatePipe, DecimalPipe } from '@angular/common';
14
14
  import { ClassicEditor, AccessibilityHelp, Alignment, Autoformat, AutoImage, AutoLink, Autosave, BlockQuote, Bold, CloudServices, Code, CodeBlock, Essentials, FindAndReplace, FontBackgroundColor, FontColor, FontFamily, FontSize, GeneralHtmlSupport, Heading, Highlight, HorizontalLine, ImageBlock, ImageCaption, ImageInline, ImageInsertViaUrl, ImageResize, ImageStyle, ImageTextAlternative, ImageToolbar, ImageUpload, Indent, IndentBlock, Italic, Link, LinkImage, List, ListProperties, MediaEmbed, Paragraph, PasteFromOffice, RemoveFormat, SelectAll, SpecialCharacters, SpecialCharactersArrows, SpecialCharactersCurrency, SpecialCharactersEssentials, SpecialCharactersLatin, SpecialCharactersMathematical, SpecialCharactersText, Strikethrough, Style, Subscript, Superscript, Table, TableCaption, TableCellProperties, TableColumnResize, TableProperties, TableToolbar, TextTransformation, TodoList, Underline, Undo } from 'ckeditor5';
15
15
  import * as i1$4 from '@ckeditor/ckeditor5-angular';
16
16
  import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
17
+ import { addIcons } from 'ionicons';
18
+ import { chevronForwardOutline, chevronBackOutline } from 'ionicons/icons';
17
19
 
18
20
  class AppprojectFramework {
19
21
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AppprojectFramework, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -1351,6 +1353,26 @@ class UtilsGeralService {
1351
1353
  });
1352
1354
  //console.log('getFormValues', entity);
1353
1355
  }
1356
+ getFormValidationErrors(form, messages) {
1357
+ let result = [];
1358
+ Object.keys(form.controls).forEach(key => {
1359
+ const controlErrors = form.get(key)?.errors;
1360
+ if (controlErrors != null) {
1361
+ Object.keys(controlErrors).forEach(keyError => {
1362
+ //console.log('Key control: ' + key + ', keyError: ' + keyError + ', err value: ', controlErrors[keyError]);
1363
+ if (messages[key]) {
1364
+ messages[key].forEach((msg) => {
1365
+ if (msg['type'] == keyError) {
1366
+ console.log(msg['message']);
1367
+ result.push(msg['message']);
1368
+ }
1369
+ });
1370
+ }
1371
+ });
1372
+ }
1373
+ });
1374
+ return result;
1375
+ }
1354
1376
  //data hora
1355
1377
  converterDataFromDB(data) {
1356
1378
  if (this.isEmpty(data))
@@ -1922,6 +1944,10 @@ class BaseCadastro extends BasePage {
1922
1944
  salvando = false;
1923
1945
  cadastroServiceBase;
1924
1946
  novoAfterDelete = true;
1947
+ /**
1948
+ * Exibir alert com erros de validação
1949
+ */
1950
+ mostrarValidacao = false;
1925
1951
  //emiter para teste
1926
1952
  entidadePosted = new EventEmitter();
1927
1953
  //construtor
@@ -2028,8 +2054,20 @@ class BaseCadastro extends BasePage {
2028
2054
  }
2029
2055
  afterPesquisaEntidade() {
2030
2056
  }
2031
- validarRegistro() {
2032
- return true;
2057
+ async validarRegistro() {
2058
+ if (this.mostrarValidacao) {
2059
+ if (!this.entidadeForm.valid) {
2060
+ const mensagens = this.getFormValidationErrors(this.entidadeForm, this.validation_messages);
2061
+ const valid = await this.alertsBase.showConfirmPromise('Erro...', `Por favor, verifique o formulário.<br>${mensagens.join('<br>')}`, 'Continuar', 'Cancelar');
2062
+ return valid;
2063
+ }
2064
+ else {
2065
+ return true;
2066
+ }
2067
+ }
2068
+ else {
2069
+ return true;
2070
+ }
2033
2071
  }
2034
2072
  ngOnInit() {
2035
2073
  super.ngOnInit();
@@ -2371,6 +2409,26 @@ class BaseCadastro extends BasePage {
2371
2409
  });
2372
2410
  console.log('getFormValues', entity);
2373
2411
  }
2412
+ getFormValidationErrors(form, messages) {
2413
+ let result = [];
2414
+ Object.keys(form.controls).forEach(key => {
2415
+ const controlErrors = form.get(key)?.errors;
2416
+ if (controlErrors != null) {
2417
+ Object.keys(controlErrors).forEach(keyError => {
2418
+ //console.log('Key control: ' + key + ', keyError: ' + keyError + ', err value: ', controlErrors[keyError]);
2419
+ if (messages[key]) {
2420
+ messages[key].forEach((msg) => {
2421
+ if (msg['type'] == keyError) {
2422
+ console.log(msg['message']);
2423
+ result.push(msg['message']);
2424
+ }
2425
+ });
2426
+ }
2427
+ });
2428
+ }
2429
+ });
2430
+ return result;
2431
+ }
2374
2432
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: BaseCadastro, deps: [{ token: 'type' }, { token: i1$2.ActivatedRoute }, { token: i1$2.Router }, { token: CadastroService }], target: i0.ɵɵFactoryTarget.Component });
2375
2433
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.4", type: BaseCadastro, isStandalone: true, selector: "ng-component", inputs: { itensLista: "itensLista", masterId: "masterId" }, outputs: { entidadePosted: "entidadePosted", atualizarItensEvent: "atualizarItensEvent" }, usesInheritance: true, ngImport: i0, template: '', isInline: true });
2376
2434
  }
@@ -3651,7 +3709,7 @@ class InputAreaComponent extends BaseInputComponent {
3651
3709
  provide: NG_VALUE_ACCESSOR,
3652
3710
  useExisting: InputAreaComponent,
3653
3711
  multi: true
3654
- }], viewQueries: [{ propertyName: "itemArea", first: true, predicate: ["itemArea"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "<div [class]=\"{ 'input-text-padding': !classic }\">\r\n @if (classic) {\r\n <ion-item lines=\"none\" style=\"--background-focused: transparent;\" [class]=\"itemClass\" #itemArea>\r\n <ion-label position=\"{{ labelPosition }}\">{{ label }}\r\n @if (showObrigatorio) {\r\n <span \r\n class=\"label-tip-obrigatorio\">{{\r\n form?.get(formControlName)?.hasError('required') ? ' \u25CF' : ''}}\r\n </span>\r\n }\r\n </ion-label>\r\n <!-- formControlName=\"{{ formControlName }}\" -->\r\n <textarea #inputArea [placeholder]=\"placeholder\" [maxLength]=\"max\" (ionBlur)=\"onBlur()\" [value]=\"data\"\r\n [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" [disabled]=\"readonly\" (focus)=\"entered()\"></textarea>\r\n </ion-item>\r\n } @else {\r\n\r\n <ion-textarea #inputArea [label]=\"label\" [labelPlacement]=\"labelPosition\" fill=\"outline\" [maxlength]=\"max\" class=\"modern\"\r\n [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" (ionBlur)=\"onBlur()\" (ionInput)=\"onInputChange($event)\"\r\n [value]=\"data\" mode=\"md\" [counter]=\"contador\" [placeholder]=\"placeholder\">\r\n\r\n @if (icon || iconSrc) {\r\n <ion-icon slot=\"start\" [icon]=\"icon\" [src]=\"iconSrc\" aria-hidden=\"true\"></ion-icon>\r\n }\r\n @if (showSeeCopy) {\r\n\r\n <ion-button fill=\"clear\" slot=\"end\" aria-label=\"Mostrar/esconder\" class=\"btn-show-password\"\r\n (click)=\"copiarClick()\">\r\n <ion-icon slot=\"icon-only\" icon=\"copy-outline\"></ion-icon>\r\n </ion-button>\r\n\r\n }\r\n\r\n </ion-textarea>\r\n\r\n }\r\n\r\n @if (form) {\r\n <div class=\"validation-errors\">\r\n\r\n @for (validation of validation_messages; track validation.type) {\r\n <ng-container>\r\n @if (form.get(formControlName)?.hasError(validation.type) && (form.get(formControlName)?.dirty ||\r\n form.get(formControlName)?.touched)) {\r\n <div class=\"error-message\">\r\n &#8226; {{ validation.message }}\r\n </div>\r\n }\r\n </ng-container>\r\n }\r\n </div>\r\n }\r\n</div>", styles: ["@charset \"UTF-8\";ion-label{margin-bottom:4px!important}ion-textarea{padding:var(--input-padding)!important;border-radius:4px;width:100%;margin-top:2px}textarea{padding:var(--input-padding, 8px)!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;resize:none;background-color:#fff}textarea::-webkit-scrollbar{width:10px;height:10px}textarea::-webkit-scrollbar-track{background:#f1f1f1}textarea::-webkit-scrollbar-thumb{border-radius:12px;background:var(--scroll-color-thumb, #808080)}textarea::-webkit-scrollbar-thumb:hover{background:var(--scroll-color-hover, #5c5c5c)}textarea:focus{outline:none!important;border:1px solid lightblue!important}textarea:focus ion-label{color:var(--ion-color-label-focus, blue)!important}.item-has-focus ion-label{color:var(--ion-color-label-focus, blue)!important}\n", "@charset \"UTF-8\";@keyframes shake{0%{transform:translate(20px)}20%{transform:translate(-20px)}40%{transform:translate(10px)}60%{transform:translate(-10px)}80%{transform:translate(4px)}to{transform:translate(0)}}.error-input ion-label,.error-shake ion-label{color:red!important}.error-input ion-input,.error-shake ion-input{border:1px solid red!important}.error-shake ion-input{animation:shake .4s 1 linear}.error-shake-modern{--border-color: var(--input-color-error, red) !important;--color: var(--input-color-error, red) !important;--highlight-color-focused: var(--input-color-error, red) !important;animation:shake .4s 1 linear}.validation-errors{margin-top:4px}ion-label{margin-bottom:var(--label-margin-bottom, 2px)!important;color:var(--label-color, initial)!important}ion-item ion-label{overflow:initial!important}ion-input{text-align:var(--input-text-align, start)}.classic ion-input{background:var(--input-color, white);padding-left:2px!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;max-height:30px;min-height:var(--input-min-height, 30px);transition:.2s ease;color:var(--input-font-color, black)}ion-input.modern{--border-color: var(--input-border-color, darkgray);--color: var(--input-font-color, black);--highlight-color-focused: var(--input-highlight-color, #537bc7)}ion-textarea.modern{--border-color: darkgray;--border-color-focused: #00ff00;--border-color-hover: yellow;--color: var(--input-font-color, black);--highlight-color-focused: var(--input-higlight-color, #537bc7);--input-focus-border-color: transparent}.input-text-padding{padding-bottom:var(--input-text-padding-bottom, var(--input-text-default-padding, 16px));padding-left:var(--input-text-padding-left, var(--input-text-default-padding, 16px));padding-right:var(--input-text-padding-right, var(--input-text-default-padding, 16px))}.classic .has-focus{border:1px solid var(--input-focus-border-color, skyblue)!important}.item-has-focus ion-label{color:var(--label-focus-color, blue)!important}.no-padding-end{--inner-padding-end: 0}.no-padding-start{--padding-start: 0px}.item-inner{padding-right:0!important}.padding{padding:auto;padding-left:0}.no-padding{--inner-padding-end: 0px;--padding-start: 0px !important;--padding-bottom: 0px;--inner-padding-bottom: 0px;height:auto!important;--min-height: auto !important}.no-padding-no-height{--inner-padding-end: 0px;--padding-start: 0px;--padding-bottom: 0px;--inner-padding-bottom: 0px}.padding-top{--padding-top: 0px}.input-login{height:36px}.modal-editar ion-label{min-width:80px}.modal-vldt-editar{margin-left:80px}.label-right ion-label{transform-origin:right top;align-self:flex-end;margin-bottom:4%!important}.align-to-right ion-label{position:relative;left:25%;text-align:end}.error-message{font-size:small;color:var(--input-color-error, rgb(212, 79, 79));margin-left:15px}.item-interactive-disabled ion-label{opacity:var(--item-disabled-opacity, .6)}.native-input[disabled]{opacity:.6!important;background-color:transparent}.item-label-stacked{--min-height: auto}.tipObrigatorio{opacity:.4}[hidden]{display:none!important}\n"], dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"], outputs: ["ionFocus", "ionBlur"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
3712
+ }], viewQueries: [{ propertyName: "itemArea", first: true, predicate: ["itemArea"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "<div [class]=\"{ 'input-text-padding': !classic }\">\r\n @if (classic) {\r\n <ion-item lines=\"none\" style=\"--background-focused: transparent;\" [class]=\"itemClass\" #itemArea>\r\n <ion-label position=\"{{ labelPosition }}\">{{ label }}\r\n @if (showObrigatorio) {\r\n <span class=\"label-tip-obrigatorio\">{{\r\n form?.get(formControlName)?.hasError('required') ? ' \u25CF' : ''}}\r\n </span>\r\n }\r\n </ion-label>\r\n <!-- formControlName=\"{{ formControlName }}\" -->\r\n <textarea #inputArea [placeholder]=\"placeholder\" [maxLength]=\"max\" (ionBlur)=\"onBlur()\" [value]=\"data\"\r\n [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" [disabled]=\"readonly\" (focus)=\"entered()\"></textarea>\r\n </ion-item>\r\n } @else {\r\n\r\n <ion-textarea #inputArea [label]=\"label\" [labelPlacement]=\"labelPosition\" fill=\"outline\" [maxlength]=\"max\"\r\n class=\"modern\" [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" (ionBlur)=\"onBlur()\"\r\n (ionInput)=\"onInputChange($event)\" [value]=\"data\" mode=\"md\" [counter]=\"contador\" [placeholder]=\"placeholder\">\r\n\r\n @if (icon || iconSrc) {\r\n <ion-icon slot=\"start\" [icon]=\"icon\" [src]=\"iconSrc\" aria-hidden=\"true\"></ion-icon>\r\n }\r\n @if (showSeeCopy) {\r\n\r\n <ion-button fill=\"clear\" slot=\"end\" aria-label=\"Mostrar/esconder\" class=\"btn-show-password\"\r\n (click)=\"copiarClick()\">\r\n <ion-icon slot=\"icon-only\" icon=\"copy-outline\"></ion-icon>\r\n </ion-button>\r\n\r\n }\r\n\r\n </ion-textarea>\r\n\r\n }\r\n\r\n @if (form) {\r\n <div class=\"validation-errors\">\r\n\r\n @for (validation of validation_messages; track validation.type) {\r\n <ng-container>\r\n @if (form.get(formControlName)?.hasError(validation.type) && (form.get(formControlName)?.dirty ||\r\n form.get(formControlName)?.touched)) {\r\n <div class=\"error-message\">\r\n &#8226; {{ validation.message }}\r\n </div>\r\n }\r\n </ng-container>\r\n }\r\n </div>\r\n }\r\n</div>", styles: ["@charset \"UTF-8\";ion-label{margin-bottom:4px!important}ion-textarea{padding:var(--input-padding)!important;border-radius:4px;width:100%;margin-top:2px}textarea{padding:var(--input-padding, 8px)!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;resize:none;background-color:#fff}textarea::-webkit-scrollbar{width:10px;height:10px}textarea::-webkit-scrollbar-track{background:#f1f1f1}textarea::-webkit-scrollbar-thumb{border-radius:12px;background:var(--scroll-color-thumb, #808080)}textarea::-webkit-scrollbar-thumb:hover{background:var(--scroll-color-hover, #5c5c5c)}textarea:focus{outline:none!important;border:1px solid lightblue!important}textarea:focus ion-label{color:var(--ion-color-label-focus, blue)!important}.item-has-focus ion-label{color:var(--ion-color-label-focus, blue)!important}\n", "@charset \"UTF-8\";@keyframes shake{0%{transform:translate(20px)}20%{transform:translate(-20px)}40%{transform:translate(10px)}60%{transform:translate(-10px)}80%{transform:translate(4px)}to{transform:translate(0)}}.error-input ion-label,.error-shake ion-label{color:red!important}.error-input ion-input,.error-shake ion-input{border:1px solid red!important}.error-shake ion-input{animation:shake .4s 1 linear}.error-shake-modern{--border-color: var(--input-color-error, red) !important;--color: var(--input-color-error, red) !important;--highlight-color-focused: var(--input-color-error, red) !important;animation:shake .4s 1 linear}.validation-errors{margin-top:4px}ion-label{margin-bottom:var(--label-margin-bottom, 2px)!important;color:var(--label-color, initial)!important}ion-item ion-label{overflow:initial!important}ion-input{text-align:var(--input-text-align, start)}.classic ion-input{background:var(--input-color, white);padding-left:2px!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;max-height:30px;min-height:var(--input-min-height, 30px);transition:.2s ease;color:var(--input-font-color, black)}ion-input.modern{--border-color: var(--input-border-color, darkgray);--color: var(--input-font-color, black);--highlight-color-focused: var(--input-highlight-color, #537bc7)}ion-textarea.modern{--border-color: darkgray;--border-color-focused: #00ff00;--border-color-hover: yellow;--color: var(--input-font-color, black);--highlight-color-focused: var(--input-higlight-color, #537bc7);--input-focus-border-color: transparent}.input-text-padding{padding-bottom:var(--input-text-padding-bottom, var(--input-text-default-padding, 16px));padding-left:var(--input-text-padding-left, var(--input-text-default-padding, 16px));padding-right:var(--input-text-padding-right, var(--input-text-default-padding, 16px))}.classic .has-focus{border:1px solid var(--input-focus-border-color, skyblue)!important}.item-has-focus ion-label{color:var(--label-focus-color, blue)!important}.no-padding-end{--inner-padding-end: 0}.no-padding-start{--padding-start: 0px}.item-inner{padding-right:0!important}.padding{padding:auto;padding-left:0}.no-padding{--inner-padding-end: 0px;--padding-start: 0px !important;--padding-bottom: 0px;--inner-padding-bottom: 0px;height:auto!important;--min-height: auto !important}.no-padding-no-height{--inner-padding-end: 0px;--padding-start: 0px;--padding-bottom: 0px;--inner-padding-bottom: 0px}.padding-top{--padding-top: 0px}.input-login{height:36px}.modal-editar ion-label{min-width:80px}.modal-vldt-editar{margin-left:80px}.label-right ion-label{transform-origin:right top;align-self:flex-end;margin-bottom:4%!important}.align-to-right ion-label{position:relative;left:25%;text-align:end}.error-message{font-size:small;color:var(--input-color-error, rgb(212, 79, 79));margin-left:15px}.item-interactive-disabled ion-label{opacity:var(--item-disabled-opacity, .6)}.native-input[disabled]{opacity:.6!important;background-color:transparent}.item-label-stacked{--min-height: auto}.tipObrigatorio{opacity:.4}[hidden]{display:none!important}\n"], dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"], outputs: ["ionFocus", "ionBlur"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
3655
3713
  }
3656
3714
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: InputAreaComponent, decorators: [{
3657
3715
  type: Component,
@@ -3659,7 +3717,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
3659
3717
  provide: NG_VALUE_ACCESSOR,
3660
3718
  useExisting: InputAreaComponent,
3661
3719
  multi: true
3662
- }], template: "<div [class]=\"{ 'input-text-padding': !classic }\">\r\n @if (classic) {\r\n <ion-item lines=\"none\" style=\"--background-focused: transparent;\" [class]=\"itemClass\" #itemArea>\r\n <ion-label position=\"{{ labelPosition }}\">{{ label }}\r\n @if (showObrigatorio) {\r\n <span \r\n class=\"label-tip-obrigatorio\">{{\r\n form?.get(formControlName)?.hasError('required') ? ' \u25CF' : ''}}\r\n </span>\r\n }\r\n </ion-label>\r\n <!-- formControlName=\"{{ formControlName }}\" -->\r\n <textarea #inputArea [placeholder]=\"placeholder\" [maxLength]=\"max\" (ionBlur)=\"onBlur()\" [value]=\"data\"\r\n [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" [disabled]=\"readonly\" (focus)=\"entered()\"></textarea>\r\n </ion-item>\r\n } @else {\r\n\r\n <ion-textarea #inputArea [label]=\"label\" [labelPlacement]=\"labelPosition\" fill=\"outline\" [maxlength]=\"max\" class=\"modern\"\r\n [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" (ionBlur)=\"onBlur()\" (ionInput)=\"onInputChange($event)\"\r\n [value]=\"data\" mode=\"md\" [counter]=\"contador\" [placeholder]=\"placeholder\">\r\n\r\n @if (icon || iconSrc) {\r\n <ion-icon slot=\"start\" [icon]=\"icon\" [src]=\"iconSrc\" aria-hidden=\"true\"></ion-icon>\r\n }\r\n @if (showSeeCopy) {\r\n\r\n <ion-button fill=\"clear\" slot=\"end\" aria-label=\"Mostrar/esconder\" class=\"btn-show-password\"\r\n (click)=\"copiarClick()\">\r\n <ion-icon slot=\"icon-only\" icon=\"copy-outline\"></ion-icon>\r\n </ion-button>\r\n\r\n }\r\n\r\n </ion-textarea>\r\n\r\n }\r\n\r\n @if (form) {\r\n <div class=\"validation-errors\">\r\n\r\n @for (validation of validation_messages; track validation.type) {\r\n <ng-container>\r\n @if (form.get(formControlName)?.hasError(validation.type) && (form.get(formControlName)?.dirty ||\r\n form.get(formControlName)?.touched)) {\r\n <div class=\"error-message\">\r\n &#8226; {{ validation.message }}\r\n </div>\r\n }\r\n </ng-container>\r\n }\r\n </div>\r\n }\r\n</div>", styles: ["@charset \"UTF-8\";ion-label{margin-bottom:4px!important}ion-textarea{padding:var(--input-padding)!important;border-radius:4px;width:100%;margin-top:2px}textarea{padding:var(--input-padding, 8px)!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;resize:none;background-color:#fff}textarea::-webkit-scrollbar{width:10px;height:10px}textarea::-webkit-scrollbar-track{background:#f1f1f1}textarea::-webkit-scrollbar-thumb{border-radius:12px;background:var(--scroll-color-thumb, #808080)}textarea::-webkit-scrollbar-thumb:hover{background:var(--scroll-color-hover, #5c5c5c)}textarea:focus{outline:none!important;border:1px solid lightblue!important}textarea:focus ion-label{color:var(--ion-color-label-focus, blue)!important}.item-has-focus ion-label{color:var(--ion-color-label-focus, blue)!important}\n", "@charset \"UTF-8\";@keyframes shake{0%{transform:translate(20px)}20%{transform:translate(-20px)}40%{transform:translate(10px)}60%{transform:translate(-10px)}80%{transform:translate(4px)}to{transform:translate(0)}}.error-input ion-label,.error-shake ion-label{color:red!important}.error-input ion-input,.error-shake ion-input{border:1px solid red!important}.error-shake ion-input{animation:shake .4s 1 linear}.error-shake-modern{--border-color: var(--input-color-error, red) !important;--color: var(--input-color-error, red) !important;--highlight-color-focused: var(--input-color-error, red) !important;animation:shake .4s 1 linear}.validation-errors{margin-top:4px}ion-label{margin-bottom:var(--label-margin-bottom, 2px)!important;color:var(--label-color, initial)!important}ion-item ion-label{overflow:initial!important}ion-input{text-align:var(--input-text-align, start)}.classic ion-input{background:var(--input-color, white);padding-left:2px!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;max-height:30px;min-height:var(--input-min-height, 30px);transition:.2s ease;color:var(--input-font-color, black)}ion-input.modern{--border-color: var(--input-border-color, darkgray);--color: var(--input-font-color, black);--highlight-color-focused: var(--input-highlight-color, #537bc7)}ion-textarea.modern{--border-color: darkgray;--border-color-focused: #00ff00;--border-color-hover: yellow;--color: var(--input-font-color, black);--highlight-color-focused: var(--input-higlight-color, #537bc7);--input-focus-border-color: transparent}.input-text-padding{padding-bottom:var(--input-text-padding-bottom, var(--input-text-default-padding, 16px));padding-left:var(--input-text-padding-left, var(--input-text-default-padding, 16px));padding-right:var(--input-text-padding-right, var(--input-text-default-padding, 16px))}.classic .has-focus{border:1px solid var(--input-focus-border-color, skyblue)!important}.item-has-focus ion-label{color:var(--label-focus-color, blue)!important}.no-padding-end{--inner-padding-end: 0}.no-padding-start{--padding-start: 0px}.item-inner{padding-right:0!important}.padding{padding:auto;padding-left:0}.no-padding{--inner-padding-end: 0px;--padding-start: 0px !important;--padding-bottom: 0px;--inner-padding-bottom: 0px;height:auto!important;--min-height: auto !important}.no-padding-no-height{--inner-padding-end: 0px;--padding-start: 0px;--padding-bottom: 0px;--inner-padding-bottom: 0px}.padding-top{--padding-top: 0px}.input-login{height:36px}.modal-editar ion-label{min-width:80px}.modal-vldt-editar{margin-left:80px}.label-right ion-label{transform-origin:right top;align-self:flex-end;margin-bottom:4%!important}.align-to-right ion-label{position:relative;left:25%;text-align:end}.error-message{font-size:small;color:var(--input-color-error, rgb(212, 79, 79));margin-left:15px}.item-interactive-disabled ion-label{opacity:var(--item-disabled-opacity, .6)}.native-input[disabled]{opacity:.6!important;background-color:transparent}.item-label-stacked{--min-height: auto}.tipObrigatorio{opacity:.4}[hidden]{display:none!important}\n"] }]
3720
+ }], template: "<div [class]=\"{ 'input-text-padding': !classic }\">\r\n @if (classic) {\r\n <ion-item lines=\"none\" style=\"--background-focused: transparent;\" [class]=\"itemClass\" #itemArea>\r\n <ion-label position=\"{{ labelPosition }}\">{{ label }}\r\n @if (showObrigatorio) {\r\n <span class=\"label-tip-obrigatorio\">{{\r\n form?.get(formControlName)?.hasError('required') ? ' \u25CF' : ''}}\r\n </span>\r\n }\r\n </ion-label>\r\n <!-- formControlName=\"{{ formControlName }}\" -->\r\n <textarea #inputArea [placeholder]=\"placeholder\" [maxLength]=\"max\" (ionBlur)=\"onBlur()\" [value]=\"data\"\r\n [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" [disabled]=\"readonly\" (focus)=\"entered()\"></textarea>\r\n </ion-item>\r\n } @else {\r\n\r\n <ion-textarea #inputArea [label]=\"label\" [labelPlacement]=\"labelPosition\" fill=\"outline\" [maxlength]=\"max\"\r\n class=\"modern\" [rows]=\"linhas\" (input)=\"writeValue(inputArea.value)\" (ionBlur)=\"onBlur()\"\r\n (ionInput)=\"onInputChange($event)\" [value]=\"data\" mode=\"md\" [counter]=\"contador\" [placeholder]=\"placeholder\">\r\n\r\n @if (icon || iconSrc) {\r\n <ion-icon slot=\"start\" [icon]=\"icon\" [src]=\"iconSrc\" aria-hidden=\"true\"></ion-icon>\r\n }\r\n @if (showSeeCopy) {\r\n\r\n <ion-button fill=\"clear\" slot=\"end\" aria-label=\"Mostrar/esconder\" class=\"btn-show-password\"\r\n (click)=\"copiarClick()\">\r\n <ion-icon slot=\"icon-only\" icon=\"copy-outline\"></ion-icon>\r\n </ion-button>\r\n\r\n }\r\n\r\n </ion-textarea>\r\n\r\n }\r\n\r\n @if (form) {\r\n <div class=\"validation-errors\">\r\n\r\n @for (validation of validation_messages; track validation.type) {\r\n <ng-container>\r\n @if (form.get(formControlName)?.hasError(validation.type) && (form.get(formControlName)?.dirty ||\r\n form.get(formControlName)?.touched)) {\r\n <div class=\"error-message\">\r\n &#8226; {{ validation.message }}\r\n </div>\r\n }\r\n </ng-container>\r\n }\r\n </div>\r\n }\r\n</div>", styles: ["@charset \"UTF-8\";ion-label{margin-bottom:4px!important}ion-textarea{padding:var(--input-padding)!important;border-radius:4px;width:100%;margin-top:2px}textarea{padding:var(--input-padding, 8px)!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;resize:none;background-color:#fff}textarea::-webkit-scrollbar{width:10px;height:10px}textarea::-webkit-scrollbar-track{background:#f1f1f1}textarea::-webkit-scrollbar-thumb{border-radius:12px;background:var(--scroll-color-thumb, #808080)}textarea::-webkit-scrollbar-thumb:hover{background:var(--scroll-color-hover, #5c5c5c)}textarea:focus{outline:none!important;border:1px solid lightblue!important}textarea:focus ion-label{color:var(--ion-color-label-focus, blue)!important}.item-has-focus ion-label{color:var(--ion-color-label-focus, blue)!important}\n", "@charset \"UTF-8\";@keyframes shake{0%{transform:translate(20px)}20%{transform:translate(-20px)}40%{transform:translate(10px)}60%{transform:translate(-10px)}80%{transform:translate(4px)}to{transform:translate(0)}}.error-input ion-label,.error-shake ion-label{color:red!important}.error-input ion-input,.error-shake ion-input{border:1px solid red!important}.error-shake ion-input{animation:shake .4s 1 linear}.error-shake-modern{--border-color: var(--input-color-error, red) !important;--color: var(--input-color-error, red) !important;--highlight-color-focused: var(--input-color-error, red) !important;animation:shake .4s 1 linear}.validation-errors{margin-top:4px}ion-label{margin-bottom:var(--label-margin-bottom, 2px)!important;color:var(--label-color, initial)!important}ion-item ion-label{overflow:initial!important}ion-input{text-align:var(--input-text-align, start)}.classic ion-input{background:var(--input-color, white);padding-left:2px!important;border:1px solid darkgray;border-radius:4px;width:100%;margin-top:2px;max-height:30px;min-height:var(--input-min-height, 30px);transition:.2s ease;color:var(--input-font-color, black)}ion-input.modern{--border-color: var(--input-border-color, darkgray);--color: var(--input-font-color, black);--highlight-color-focused: var(--input-highlight-color, #537bc7)}ion-textarea.modern{--border-color: darkgray;--border-color-focused: #00ff00;--border-color-hover: yellow;--color: var(--input-font-color, black);--highlight-color-focused: var(--input-higlight-color, #537bc7);--input-focus-border-color: transparent}.input-text-padding{padding-bottom:var(--input-text-padding-bottom, var(--input-text-default-padding, 16px));padding-left:var(--input-text-padding-left, var(--input-text-default-padding, 16px));padding-right:var(--input-text-padding-right, var(--input-text-default-padding, 16px))}.classic .has-focus{border:1px solid var(--input-focus-border-color, skyblue)!important}.item-has-focus ion-label{color:var(--label-focus-color, blue)!important}.no-padding-end{--inner-padding-end: 0}.no-padding-start{--padding-start: 0px}.item-inner{padding-right:0!important}.padding{padding:auto;padding-left:0}.no-padding{--inner-padding-end: 0px;--padding-start: 0px !important;--padding-bottom: 0px;--inner-padding-bottom: 0px;height:auto!important;--min-height: auto !important}.no-padding-no-height{--inner-padding-end: 0px;--padding-start: 0px;--padding-bottom: 0px;--inner-padding-bottom: 0px}.padding-top{--padding-top: 0px}.input-login{height:36px}.modal-editar ion-label{min-width:80px}.modal-vldt-editar{margin-left:80px}.label-right ion-label{transform-origin:right top;align-self:flex-end;margin-bottom:4%!important}.align-to-right ion-label{position:relative;left:25%;text-align:end}.error-message{font-size:small;color:var(--input-color-error, rgb(212, 79, 79));margin-left:15px}.item-interactive-disabled ion-label{opacity:var(--item-disabled-opacity, .6)}.native-input[disabled]{opacity:.6!important;background-color:transparent}.item-label-stacked{--min-height: auto}.tipObrigatorio{opacity:.4}[hidden]{display:none!important}\n"] }]
3663
3721
  }], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { linhas: [{
3664
3722
  type: Input
3665
3723
  }], contador: [{
@@ -5380,6 +5438,237 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
5380
5438
  args: ['inputNome', { read: ElementRef, static: true }]
5381
5439
  }] } });
5382
5440
 
5441
+ class AgendaSemanalComponent {
5442
+ alertController;
5443
+ itens = [];
5444
+ legendas = [];
5445
+ textoAjuda = '';
5446
+ horaInicio = 6;
5447
+ horaFim = 23;
5448
+ intervaloMinutos = 30;
5449
+ horariosPadrao = [];
5450
+ horarioSelecionado = new EventEmitter();
5451
+ itemSelecionado = new EventEmitter();
5452
+ nomesMeses = [
5453
+ 'Janeiro',
5454
+ 'Fevereiro',
5455
+ 'Março',
5456
+ 'Abril',
5457
+ 'Maio',
5458
+ 'Junho',
5459
+ 'Julho',
5460
+ 'Agosto',
5461
+ 'Setembro',
5462
+ 'Outubro',
5463
+ 'Novembro',
5464
+ 'Dezembro'
5465
+ ];
5466
+ nomesDias = [
5467
+ 'Dom',
5468
+ 'Seg',
5469
+ 'Ter',
5470
+ 'Qua',
5471
+ 'Qui',
5472
+ 'Sex',
5473
+ 'Sáb'
5474
+ ];
5475
+ mesSelecionado = 0;
5476
+ anoSelecionado = 0;
5477
+ dataReferenciaSemana = new Date();
5478
+ diasSemana = [];
5479
+ horarios = [];
5480
+ constructor(alertController) {
5481
+ this.alertController = alertController;
5482
+ addIcons({
5483
+ chevronBackOutline,
5484
+ chevronForwardOutline
5485
+ });
5486
+ }
5487
+ ngOnInit() {
5488
+ const hoje = new Date();
5489
+ hoje.setHours(0, 0, 0, 0);
5490
+ this.dataReferenciaSemana = this.obterSegundaFeira(hoje);
5491
+ this.atualizarMesAno(this.dataReferenciaSemana);
5492
+ this.gerarHorarios();
5493
+ this.gerarSemana(this.dataReferenciaSemana);
5494
+ }
5495
+ get nomeMes() {
5496
+ return this.nomesMeses[this.mesSelecionado];
5497
+ }
5498
+ get numeroMes() {
5499
+ return (this.mesSelecionado + 1).toString().padStart(2, '0');
5500
+ }
5501
+ mesAnterior() {
5502
+ const novaData = new Date(this.dataReferenciaSemana);
5503
+ novaData.setDate(novaData.getDate() - 30);
5504
+ this.gerarSemana(novaData);
5505
+ this.atualizarMesAno(this.dataReferenciaSemana);
5506
+ }
5507
+ proximoMes() {
5508
+ const novaData = new Date(this.dataReferenciaSemana);
5509
+ novaData.setDate(novaData.getDate() + 30);
5510
+ this.gerarSemana(novaData);
5511
+ this.atualizarMesAno(this.dataReferenciaSemana);
5512
+ }
5513
+ semanaAnterior() {
5514
+ const novaData = new Date(this.dataReferenciaSemana);
5515
+ novaData.setDate(novaData.getDate() - 7);
5516
+ this.gerarSemana(novaData);
5517
+ this.atualizarMesAno(this.dataReferenciaSemana);
5518
+ }
5519
+ proximaSemana() {
5520
+ const novaData = new Date(this.dataReferenciaSemana);
5521
+ novaData.setDate(novaData.getDate() + 7);
5522
+ this.gerarSemana(novaData);
5523
+ this.atualizarMesAno(this.dataReferenciaSemana);
5524
+ }
5525
+ obterSegundaFeira(data) {
5526
+ const resultado = new Date(data);
5527
+ resultado.setHours(0, 0, 0, 0);
5528
+ const diaSemana = resultado.getDay();
5529
+ const diasVoltar = diaSemana === 0 ? 6 : diaSemana - 1;
5530
+ resultado.setDate(resultado.getDate() - diasVoltar);
5531
+ return resultado;
5532
+ }
5533
+ atualizarMesAno(data) {
5534
+ this.mesSelecionado = data.getMonth();
5535
+ this.anoSelecionado = data.getFullYear();
5536
+ }
5537
+ gerarSemana(dataReferencia) {
5538
+ const segunda = this.obterSegundaFeira(dataReferencia);
5539
+ this.dataReferenciaSemana = new Date(segunda);
5540
+ const domingo = new Date(segunda);
5541
+ domingo.setDate(domingo.getDate() - 1);
5542
+ this.diasSemana = [];
5543
+ for (let i = 0; i < 7; i++) {
5544
+ const data = new Date(domingo);
5545
+ data.setDate(domingo.getDate() + i);
5546
+ this.diasSemana.push({
5547
+ data,
5548
+ numero: data.getDate(),
5549
+ nome: this.nomesDias[data.getDay()],
5550
+ hoje: this.ehHoje(data)
5551
+ });
5552
+ }
5553
+ }
5554
+ gerarHorarios() {
5555
+ this.horarios = [];
5556
+ const minutoInicio = this.horaInicio * 60;
5557
+ const minutoFim = (this.horaFim * 60) + 30;
5558
+ for (let minutoAtual = minutoInicio; minutoAtual <= minutoFim; minutoAtual += this.intervaloMinutos) {
5559
+ const hora = Math.floor(minutoAtual / 60);
5560
+ const minuto = minutoAtual % 60;
5561
+ this.horarios.push(`${hora.toString().padStart(2, '0')}:${minuto.toString().padStart(2, '0')}`);
5562
+ }
5563
+ }
5564
+ ehHoje(data) {
5565
+ const hoje = new Date();
5566
+ return (data.getDate() === hoje.getDate() && data.getMonth() === hoje.getMonth() && data.getFullYear() === hoje.getFullYear());
5567
+ }
5568
+ getItem(dia, horario) {
5569
+ return this.itens.find(item => {
5570
+ if (!item.DataHora) {
5571
+ return false;
5572
+ }
5573
+ const dataHora = new Date(item.DataHora);
5574
+ return (this.mesmaData(dataHora, dia) && this.formatarHorario(dataHora) === horario);
5575
+ });
5576
+ }
5577
+ async aplicarHorariosPadrao(data) {
5578
+ if (!this.horariosPadrao.length) {
5579
+ const alert = await this.alertController.create({
5580
+ header: 'Horários Padrões',
5581
+ message: 'Nenhum horário padrão foi configurado.',
5582
+ buttons: ['OK']
5583
+ });
5584
+ await alert.present();
5585
+ return;
5586
+ }
5587
+ const dataFormatada = new Date(data).toLocaleDateString('pt-BR');
5588
+ const alert = await this.alertController.create({
5589
+ header: 'Horários Padrões',
5590
+ message: `Deseja adicionar os horários padrões no dia ${dataFormatada}?`,
5591
+ buttons: [{ text: 'Cancelar', role: 'cancel' }, { text: 'Adicionar', handler: () => { this.confirmarAplicacaoHorariosPadrao(data); } }]
5592
+ });
5593
+ await alert.present();
5594
+ }
5595
+ confirmarAplicacaoHorariosPadrao(data) {
5596
+ if (!this.horariosPadrao.length) {
5597
+ return;
5598
+ }
5599
+ const horariosExistentes = new Set();
5600
+ this.itens.forEach(item => {
5601
+ if (!item.DataHora) {
5602
+ return;
5603
+ }
5604
+ const dataHora = new Date(item.DataHora);
5605
+ if (!this.mesmaData(dataHora, data)) {
5606
+ return;
5607
+ }
5608
+ horariosExistentes.add(this.formatarHorario(dataHora));
5609
+ });
5610
+ this.horariosPadrao.forEach(horario => {
5611
+ if (!this.horarios.includes(horario)) {
5612
+ return;
5613
+ }
5614
+ if (horariosExistentes.has(horario)) {
5615
+ return;
5616
+ }
5617
+ const dataHora = this.criarDataHora(data, horario);
5618
+ this.horarioSelecionado.emit({ DataHora: dataHora });
5619
+ horariosExistentes.add(horario);
5620
+ });
5621
+ }
5622
+ duploCliqueHorario(dia, horario) {
5623
+ const item = this.getItem(dia, horario);
5624
+ if (item) {
5625
+ this.itemSelecionado.emit({
5626
+ ...item
5627
+ });
5628
+ return;
5629
+ }
5630
+ this.horarioSelecionado.emit({ DataHora: this.criarDataHora(dia, horario) });
5631
+ }
5632
+ criarDataHora(dia, horario) {
5633
+ const data = new Date(dia);
5634
+ const [hora, minuto] = horario.split(':');
5635
+ data.setHours(Number(hora), Number(minuto), 0, 0);
5636
+ return data;
5637
+ }
5638
+ mesmaData(data1, data2) {
5639
+ return (data1.getDate() === data2.getDate() && data1.getMonth() === data2.getMonth() && data1.getFullYear() === data2.getFullYear());
5640
+ }
5641
+ formatarHorario(data) {
5642
+ const hora = data.getHours().toString().padStart(2, '0');
5643
+ const minuto = data.getMinutes().toString().padStart(2, '0');
5644
+ return `${hora}:${minuto}`;
5645
+ }
5646
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AgendaSemanalComponent, deps: [{ token: i2.AlertController }], target: i0.ɵɵFactoryTarget.Component });
5647
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: AgendaSemanalComponent, isStandalone: true, selector: "kb-agenda-semanal", inputs: { itens: "itens", legendas: "legendas", textoAjuda: "textoAjuda", horaInicio: "horaInicio", horaFim: "horaFim", intervaloMinutos: "intervaloMinutos", horariosPadrao: "horariosPadrao" }, outputs: { horarioSelecionado: "horarioSelecionado", itemSelecionado: "itemSelecionado" }, ngImport: i0, template: "<div style=\"width:100%;box-sizing:border-box;\">\n <!-- LEGENDAS -->\n @if (legendas.length > 0 || textoAjuda) {\n <ion-row\n style=\"align-items:center;margin-bottom:8px;padding:6px 4px;min-height:70px;border-bottom:1px solid #cbd5e1;\">\n @for (legenda of legendas; track legenda.Texto) {\n <ion-col size=\"auto\">\n <div style=\"display:flex;align-items:center;gap:5px;\">\n <span [ngClass]=\"legenda.ClasseCss\"\n style=\"display:inline-block;width:18px;height:18px;border:1px solid #64748b;\">\n </span>\n <span style=\"font-size:18px;color:#475569;\">\n {{ legenda.Texto }}\n </span>\n </div>\n </ion-col>\n }\n\n @if (textoAjuda) {\n <ion-col style=\"display:flex;height:100%;justify-content:end;align-self:end;\">\n <div style=\"font-size:14px;color:#475569;\">\n {{ textoAjuda }}\n </div>\n </ion-col>\n }\n </ion-row>\n }\n\n <!-- GRADE -->\n <div style=\"width:100%;max-height:610px;overflow:auto;border:1px solid #475569;background:#ffffff;\">\n <table style=\"width:100%;min-width:900px;border-collapse:collapse;table-layout:fixed;font-size:12px;\">\n <!-- CABE\u00C7ALHO -->\n <thead style=\"position:sticky;top:0;z-index:10;background:#ffffff;\">\n <tr>\n <!-- M\u00CAS / ANO -->\n <th\n style=\"width:90px;height:64px;padding:2px;border-right:1px solid #475569;border-bottom:1px solid #475569;background:#ffffff;\">\n <div style=\"font-size:10px;font-weight:400;color:#475569;\">\n {{ anoSelecionado }}\n </div>\n\n <div style=\"display:flex;align-items:center;justify-content:space-between;padding:0 2px;\">\n <button type=\"button\" (click)=\"mesAnterior()\"\n style=\"border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-back-outline\" style=\"font-size:16px;color:#334155;\">\n </ion-icon>\n </button>\n\n <span style=\"font-size:25px;line-height:1;font-weight:700;color:#84cc16;\">\n {{ numeroMes }}\n </span>\n\n <button type=\"button\" (click)=\"proximoMes()\"\n style=\"border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-forward-outline\" style=\"font-size:16px;color:#334155;\">\n </ion-icon>\n </button>\n </div>\n\n <div style=\"font-size:9px;color:#475569;margin-top:2px;\">\n {{ nomeMes }}\n </div>\n </th>\n\n <!-- DIAS -->\n @for (dia of diasSemana; track dia.data.getTime(); let primeiro = $first; let ultimo = $last) {\n <th [style.background]=\"dia.hoje ? '#fff7ed' : '#ffffff'\"\n style=\"height:64px;padding:3px;border-right:1px solid #475569;border-bottom:1px solid #475569;text-align:center;position:relative;\">\n\n @if (primeiro) {\n <button type=\"button\" (click)=\"semanaAnterior()\"\n style=\"position:absolute;left:3px;top:22px;border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-back-outline\" style=\"font-size:15px;color:#334155;\">\n </ion-icon>\n </button>\n }\n\n <div (dblclick)=\"aplicarHorariosPadrao(dia.data)\"\n [style.color]=\"dia.hoje ? '#fb923c' : '#134e4a'\"\n title=\"Duplo clique para aplicar os hor\u00E1rios padr\u00F5es\"\n style=\"font-size:24px;font-weight:700;line-height:1.1;cursor:pointer;user-select:none;\">\n {{ dia.numero }}\n </div>\n\n <div [style.color]=\"dia.hoje ? '#fb923c' : '#111827'\"\n style=\"font-size:11px;font-weight:700;margin-top:3px;\">\n {{ dia.nome }}\n </div>\n\n @if (ultimo) {\n <button type=\"button\" (click)=\"proximaSemana()\"\n style=\"position:absolute;right:3px;top:22px;border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-forward-outline\" style=\"font-size:15px;color:#334155;\">\n </ion-icon>\n </button>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- CORPO -->\n <tbody>\n @for (horario of horarios; track horario) {\n <tr>\n <!-- HOR\u00C1RIO -->\n <td\n style=\"width:90px;height:29px;padding:1px 4px;text-align:center;font-size:13px;color:#1e293b;background:#ffffff;border-right:1px solid #475569;border-bottom:1px solid #94a3b8;\">\n {{ horario }}\n </td>\n\n <!-- DIAS -->\n @for (dia of diasSemana; track dia.data.getTime()) {\n @let item = getItem(dia.data, horario);\n\n <td (dblclick)=\"duploCliqueHorario(dia.data, horario)\" [ngClass]=\"item?.ClasseCss || ''\"\n style=\"height:29px;padding:0;text-align:center;vertical-align:middle;cursor:pointer;border-right:1px solid #475569;border-bottom:1px solid #94a3b8;user-select:none;overflow:hidden;\">\n\n @if (item?.Texto) {\n <div\n style=\"width:100%;height:100%;min-height:27px;display:flex;align-items:center;justify-content:center;padding:1px 3px;box-sizing:border-box;overflow:hidden;\">\n <span\n style=\"font-size:9px;font-weight:600;line-height:1.05;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;\">\n {{ item?.Texto }}\n </span>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>", styles: [".status-disponivel{background:#8cc63f!important;color:#fff}.status-agendada{background:#f29a52!important;color:#fff}.status-nao-realizada{background:#aeb4b7!important;color:#fff}.status-nao-compareceu{background:#5f91c9!important;color:#fff}.status-sem-prontuario{background:#d00000!important;color:#fff}td:not([class*=status-]):hover{background:#f8fafc}.status-live-agendada,.status-agendada{background:#f29a52!important;color:#fff}.status-realizada{background:#07594f!important;color:#fff}.status-live-nao-realizada{background:#d00000!important;color:#fff}.status-live-realizada{background:#07594f!important;color:#fff}\n"], dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: IonRow, selector: "ion-row" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
5648
+ }
5649
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: AgendaSemanalComponent, decorators: [{
5650
+ type: Component,
5651
+ args: [{ imports: [IonIcon, IonCol, IonRow, NgClass], selector: 'kb-agenda-semanal', template: "<div style=\"width:100%;box-sizing:border-box;\">\n <!-- LEGENDAS -->\n @if (legendas.length > 0 || textoAjuda) {\n <ion-row\n style=\"align-items:center;margin-bottom:8px;padding:6px 4px;min-height:70px;border-bottom:1px solid #cbd5e1;\">\n @for (legenda of legendas; track legenda.Texto) {\n <ion-col size=\"auto\">\n <div style=\"display:flex;align-items:center;gap:5px;\">\n <span [ngClass]=\"legenda.ClasseCss\"\n style=\"display:inline-block;width:18px;height:18px;border:1px solid #64748b;\">\n </span>\n <span style=\"font-size:18px;color:#475569;\">\n {{ legenda.Texto }}\n </span>\n </div>\n </ion-col>\n }\n\n @if (textoAjuda) {\n <ion-col style=\"display:flex;height:100%;justify-content:end;align-self:end;\">\n <div style=\"font-size:14px;color:#475569;\">\n {{ textoAjuda }}\n </div>\n </ion-col>\n }\n </ion-row>\n }\n\n <!-- GRADE -->\n <div style=\"width:100%;max-height:610px;overflow:auto;border:1px solid #475569;background:#ffffff;\">\n <table style=\"width:100%;min-width:900px;border-collapse:collapse;table-layout:fixed;font-size:12px;\">\n <!-- CABE\u00C7ALHO -->\n <thead style=\"position:sticky;top:0;z-index:10;background:#ffffff;\">\n <tr>\n <!-- M\u00CAS / ANO -->\n <th\n style=\"width:90px;height:64px;padding:2px;border-right:1px solid #475569;border-bottom:1px solid #475569;background:#ffffff;\">\n <div style=\"font-size:10px;font-weight:400;color:#475569;\">\n {{ anoSelecionado }}\n </div>\n\n <div style=\"display:flex;align-items:center;justify-content:space-between;padding:0 2px;\">\n <button type=\"button\" (click)=\"mesAnterior()\"\n style=\"border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-back-outline\" style=\"font-size:16px;color:#334155;\">\n </ion-icon>\n </button>\n\n <span style=\"font-size:25px;line-height:1;font-weight:700;color:#84cc16;\">\n {{ numeroMes }}\n </span>\n\n <button type=\"button\" (click)=\"proximoMes()\"\n style=\"border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-forward-outline\" style=\"font-size:16px;color:#334155;\">\n </ion-icon>\n </button>\n </div>\n\n <div style=\"font-size:9px;color:#475569;margin-top:2px;\">\n {{ nomeMes }}\n </div>\n </th>\n\n <!-- DIAS -->\n @for (dia of diasSemana; track dia.data.getTime(); let primeiro = $first; let ultimo = $last) {\n <th [style.background]=\"dia.hoje ? '#fff7ed' : '#ffffff'\"\n style=\"height:64px;padding:3px;border-right:1px solid #475569;border-bottom:1px solid #475569;text-align:center;position:relative;\">\n\n @if (primeiro) {\n <button type=\"button\" (click)=\"semanaAnterior()\"\n style=\"position:absolute;left:3px;top:22px;border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-back-outline\" style=\"font-size:15px;color:#334155;\">\n </ion-icon>\n </button>\n }\n\n <div (dblclick)=\"aplicarHorariosPadrao(dia.data)\"\n [style.color]=\"dia.hoje ? '#fb923c' : '#134e4a'\"\n title=\"Duplo clique para aplicar os hor\u00E1rios padr\u00F5es\"\n style=\"font-size:24px;font-weight:700;line-height:1.1;cursor:pointer;user-select:none;\">\n {{ dia.numero }}\n </div>\n\n <div [style.color]=\"dia.hoje ? '#fb923c' : '#111827'\"\n style=\"font-size:11px;font-weight:700;margin-top:3px;\">\n {{ dia.nome }}\n </div>\n\n @if (ultimo) {\n <button type=\"button\" (click)=\"proximaSemana()\"\n style=\"position:absolute;right:3px;top:22px;border:0;background:transparent;padding:0;cursor:pointer;\">\n <ion-icon name=\"chevron-forward-outline\" style=\"font-size:15px;color:#334155;\">\n </ion-icon>\n </button>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- CORPO -->\n <tbody>\n @for (horario of horarios; track horario) {\n <tr>\n <!-- HOR\u00C1RIO -->\n <td\n style=\"width:90px;height:29px;padding:1px 4px;text-align:center;font-size:13px;color:#1e293b;background:#ffffff;border-right:1px solid #475569;border-bottom:1px solid #94a3b8;\">\n {{ horario }}\n </td>\n\n <!-- DIAS -->\n @for (dia of diasSemana; track dia.data.getTime()) {\n @let item = getItem(dia.data, horario);\n\n <td (dblclick)=\"duploCliqueHorario(dia.data, horario)\" [ngClass]=\"item?.ClasseCss || ''\"\n style=\"height:29px;padding:0;text-align:center;vertical-align:middle;cursor:pointer;border-right:1px solid #475569;border-bottom:1px solid #94a3b8;user-select:none;overflow:hidden;\">\n\n @if (item?.Texto) {\n <div\n style=\"width:100%;height:100%;min-height:27px;display:flex;align-items:center;justify-content:center;padding:1px 3px;box-sizing:border-box;overflow:hidden;\">\n <span\n style=\"font-size:9px;font-weight:600;line-height:1.05;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;\">\n {{ item?.Texto }}\n </span>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>", styles: [".status-disponivel{background:#8cc63f!important;color:#fff}.status-agendada{background:#f29a52!important;color:#fff}.status-nao-realizada{background:#aeb4b7!important;color:#fff}.status-nao-compareceu{background:#5f91c9!important;color:#fff}.status-sem-prontuario{background:#d00000!important;color:#fff}td:not([class*=status-]):hover{background:#f8fafc}.status-live-agendada,.status-agendada{background:#f29a52!important;color:#fff}.status-realizada{background:#07594f!important;color:#fff}.status-live-nao-realizada{background:#d00000!important;color:#fff}.status-live-realizada{background:#07594f!important;color:#fff}\n"] }]
5652
+ }], ctorParameters: () => [{ type: i2.AlertController }], propDecorators: { itens: [{
5653
+ type: Input
5654
+ }], legendas: [{
5655
+ type: Input
5656
+ }], textoAjuda: [{
5657
+ type: Input
5658
+ }], horaInicio: [{
5659
+ type: Input
5660
+ }], horaFim: [{
5661
+ type: Input
5662
+ }], intervaloMinutos: [{
5663
+ type: Input
5664
+ }], horariosPadrao: [{
5665
+ type: Input
5666
+ }], horarioSelecionado: [{
5667
+ type: Output
5668
+ }], itemSelecionado: [{
5669
+ type: Output
5670
+ }] } });
5671
+
5383
5672
  class BaseBtnComponent {
5384
5673
  disabled = false;
5385
5674
  type = 'submit';
@@ -5643,5 +5932,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
5643
5932
  * Generated bundle index. Do not edit.
5644
5933
  */
5645
5934
 
5646
- export { AppprojectFramework, BaseCadastro, BaseInputComponent, BaseModel, BasePage, BtnActionComponent, BtnCancelarComponent, BtnExcluirComponent, BtnNovoComponent, BtnRoundedComponent, BtnSalvarComponent, CadastroService, DataService, Dominio, EntityEditComponent, EventoCadastro, EventoFoco, GridColuna, GridFiltroValor, GridTabela, GridViewComponent, HtmlCampo, HtmlRow, InputAreaComponent, InputArquivoComponent, InputCepComponent, InputCheckboxComponent, InputFormatComponent, InputHtmlComponent, InputPesquisaComponent, InputRadioComponent, InputSelectComponent, InputTextComponent, InputValorComponent, Intervalo, LibConfigService, LibService, NomePipe, PageResult, PeriodoIntervaloComponent, PesquisaCampo, SafeHtmlPipe, TituloComponent, Tree, UtilsGeralService, UtilsService, ValorFormatPipe, email, formatted, getEmail, getFormatted, getIgnore, getLabel, getMax, getMaxLength, getMin, getMinLength, getPattern, getPlaceholder, getPosicao, getReadOnly, getRequired, getTipo, ignore, label, max, maxLength, min, minLength, pattern, placeholder, posicao, readOnly, required, tipo };
5935
+ export { AgendaSemanalComponent, AppprojectFramework, BaseCadastro, BaseInputComponent, BaseModel, BasePage, BtnActionComponent, BtnCancelarComponent, BtnExcluirComponent, BtnNovoComponent, BtnRoundedComponent, BtnSalvarComponent, CadastroService, DataService, Dominio, EntityEditComponent, EventoCadastro, EventoFoco, GridColuna, GridFiltroValor, GridTabela, GridViewComponent, HtmlCampo, HtmlRow, InputAreaComponent, InputArquivoComponent, InputCepComponent, InputCheckboxComponent, InputFormatComponent, InputHtmlComponent, InputPesquisaComponent, InputRadioComponent, InputSelectComponent, InputTextComponent, InputValorComponent, Intervalo, LibConfigService, LibService, NomePipe, PageResult, PeriodoIntervaloComponent, PesquisaCampo, SafeHtmlPipe, TituloComponent, Tree, UtilsGeralService, UtilsService, ValorFormatPipe, email, formatted, getEmail, getFormatted, getIgnore, getLabel, getMax, getMaxLength, getMin, getMinLength, getPattern, getPlaceholder, getPosicao, getReadOnly, getRequired, getTipo, ignore, label, max, maxLength, min, minLength, pattern, placeholder, posicao, readOnly, required, tipo };
5647
5936
  //# sourceMappingURL=appproject-framework.mjs.map