@dev-tcloud/tcloud-ui 7.0.2 → 7.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/tcloud-ui-upload-area.md +2 -2
- package/fesm2022/dev-tcloud-tcloud-ui.mjs +22 -12
- package/fesm2022/dev-tcloud-tcloud-ui.mjs.map +1 -1
- package/js/tcloud-ui-app.js +3 -3
- package/package.json +1 -1
- package/scss/tcloud-revitalizacao/components/_tc-rev-button.scss +2 -2
- package/types/dev-tcloud-tcloud-ui.d.ts +2 -0
|
@@ -18,7 +18,7 @@ Componente de área de upload com suporte a drag-and-drop, pré-visualização d
|
|
|
18
18
|
|------|------|---------|-----------|
|
|
19
19
|
| `maxFiles` | `number \| undefined` | `undefined` | Número máximo de arquivos permitidos. Se `undefined`, não há limite. |
|
|
20
20
|
| `acceptedFileTypes` | `AcceptedFileType[] \| undefined` | `undefined` | Lista de tipos MIME aceitos. Se `undefined`, todos os tipos são aceitos. Utiliza o enum `AcceptedFileType`. |
|
|
21
|
-
| `acceptedExtensions` | `string[] \| undefined` | `undefined` | Lista de extensões de arquivo aceitas, ex: `['.doc', '.pdf']`. O ponto inicial é opcional. Validado com lógica **OU** em relação a `acceptedFileTypes`. |
|
|
21
|
+
| `acceptedExtensions` | `string[] \| undefined` | `undefined` | Lista de extensões de arquivo aceitas, ex: `['.doc', '.pdf', '.tar.gz']`. O ponto inicial é opcional. Suporta extensões compostas (ex.: `.tar.gz`, `.tar.bz2`), validadas por sufixo do nome do arquivo. Validado com lógica **OU** em relação a `acceptedFileTypes`. |
|
|
22
22
|
| `imageDimensions` | `ImageDimensions \| undefined` | `undefined` | Dimensões permitidas para imagens (largura x altura em pixels). Se `strict: true`, valida exatamente; caso contrário, aceita até as dimensões informadas. |
|
|
23
23
|
| `showProgress` | `boolean` | `false` | Exibe barra de progresso animada durante o carregamento dos arquivos. |
|
|
24
24
|
| `preloadedImages` | `PreloadedImage[] \| string[]` | — | Imagens pré-carregadas para modo de edição. Aceita array de URLs (strings) ou objetos `PreloadedImage` com `url`, `key` e `order`. As imagens são baixadas e convertidas em `File`. |
|
|
@@ -180,7 +180,7 @@ existingImages: PreloadedImage[] = [
|
|
|
180
180
|
- **Pré-visualização**: Exibe thumbnails das imagens selecionadas.
|
|
181
181
|
- **Reordenação**: Arraste e solte as imagens para alterar a ordem.
|
|
182
182
|
- **Remoção**: Botão "×" para remover imagens individualmente.
|
|
183
|
-
- **Validação de tipos**: Filtra arquivos por tipo MIME usando o enum `AcceptedFileType`.
|
|
183
|
+
- **Validação de tipos**: Filtra arquivos por tipo MIME usando o enum `AcceptedFileType` ou por extensão (`acceptedExtensions`), incluindo extensões compostas como `.tar.gz` (validação por sufixo, aceita qualquer extensão composta configurada). A renomeação interna (`new_name`) e a exibição da extensão reconhecem nativamente `.tar.gz`, `.tar.bz2`, `.tar.xz`, `.tar.zst`, `.tar.lz` e `.tar.lzma`; outras extensões compostas fora dessa lista são validadas normalmente, mas exibidas/renomeadas usando apenas o último segmento.
|
|
184
184
|
- **Validação de dimensões**: Valida largura e altura das imagens (exata ou máxima).
|
|
185
185
|
- **Limite de arquivos**: Controla o número máximo de arquivos.
|
|
186
186
|
- **Barra de progresso**: Exibe progresso animado durante o carregamento com efeito shimmer.
|
|
@@ -3773,7 +3773,7 @@ class TCloudUiModalComponent {
|
|
|
3773
3773
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TCloudUiModalComponent, isStandalone: true, selector: "tcloud-ui-modal", inputs: { confirm: "confirm", confirmText: "confirmText", confirmInput: "confirmInput", autoClose: "autoClose", title: "title", maxWidth: "maxWidth", position: "position", sticky: "sticky", window: "window", open: "open", loading: "loading" }, outputs: { openChange: "openChange", toConfirm: "toConfirm", toCancel: "toCancel", toAction: "toAction" }, providers: [
|
|
3774
3774
|
TcloudModalService,
|
|
3775
3775
|
TCloudUiLayoutService
|
|
3776
|
-
], ngImport: i0, template: "@if (control_open) {\n <div class=\"tc-background-modal\" >{{ checkIsOpen() }}</div>\n}\n\n@if (open) {\n <div class=\"tcloud-ui-modal base-modal tcloud-ui-modal-layout-{{ layout }} tcloud-ui-modal-postition-{{ position }}\" [attr.data-layout]=\"layout\">\n <div class=\"sub-modal\" [ngClass]=\"['position-' + position, sticky ? 'is-sticky' : '']\" [@fade]=\"animationParams\">\n <div class=\"tc-modal tc-modal-shadow\" [style.max-width.px]=\"maxWidth\" [class.tcloud-ui-modal-sticky]=\"sticky\">\n <div class=\"area-top-actions tc-ui-modal-{{mode}}\">\n @if( layout === 'classic'){\n <button type=\"button\" class=\"tc-btn-action-close-ui-modal\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }@else{\n <button type=\"button\" class=\"tc-rev-btn-square tc-btn-x\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }\n </div>\n @if (title) {\n <h4 [innerHTML]=\"title\"></h4>\n }\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n\n<!-- Ex: Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open\">\n\n <tcloud-ui-modal-header title=\"T\u00EDtulo do Modal\" ></tcloud-ui-modal-header>\n\n <tcloud-ui-modal-body>\n Conte\u00FAdo do modal aqui\n </tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open = !open\">open modal {{ open }}</button>\n-->\n\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n\n<!-- Ex: Confirm Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open_confirm\" [title]=\"'Aten\u00E7\u00E3o'\" [confirmText]=\"'Aceito'\" [confirm]=\"true\" (toAction)=\"$event\" >\n\n <tcloud-ui-modal-body>Deseja realmente executar esta a\u00E7\u00E3o?</tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open_confirm = !open_confirm\">open_confirm modal {{ open_confirm }}</button>\n-->", styles: [".tc-background-modal{border:1px solid var(--c-neutral-300);position:fixed;width:100%;left:0;top:0;background-color:#000;z-index:4005;height:100%;opacity:.3}.base-modal{height:100%;overflow:scroll;position:fixed;width:100%;z-index:4005;left:0;top:0;text-align:left!important}.sub-modal{padding:30px;position:absolute;width:100%;display:flex;justify-content:center;align-items:flex-start}.sub-modal.position-left{justify-content:flex-start}.sub-modal.position-right{justify-content:flex-end}.sub-modal.position-bottom{align-items:flex-end}.tc-modal{position:relative;background-color:var(--c-neutral-50);border:1px solid var(--c-neutral-200);padding:12px;border-radius:8px;margin:auto;width:100%;transition:max-width .3s ease-out}@media(prefers-reduced-motion:reduce){.tc-modal{transition:none}}.sub-modal.is-sticky{padding:0}.sub-modal.is-sticky
|
|
3776
|
+
], ngImport: i0, template: "@if (control_open) {\n <div class=\"tc-background-modal\" >{{ checkIsOpen() }}</div>\n}\n\n@if (open) {\n <div class=\"tcloud-ui-modal base-modal tcloud-ui-modal-layout-{{ layout }} tcloud-ui-modal-postition-{{ position }}\" [attr.data-layout]=\"layout\">\n <div class=\"sub-modal\" [ngClass]=\"['position-' + position, sticky ? 'is-sticky' : '']\" [@fade]=\"animationParams\">\n <div class=\"tc-modal tc-modal-shadow\" [style.max-width.px]=\"maxWidth\" [class.tcloud-ui-modal-sticky]=\"sticky\">\n <div class=\"area-top-actions tc-ui-modal-{{mode}}\">\n @if( layout === 'classic'){\n <button type=\"button\" class=\"tc-btn-action-close-ui-modal\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }@else{\n <button type=\"button\" class=\"tc-rev-btn-square tc-btn-x\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }\n </div>\n @if (title) {\n <h4 [innerHTML]=\"title\"></h4>\n }\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n\n<!-- Ex: Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open\">\n\n <tcloud-ui-modal-header title=\"T\u00EDtulo do Modal\" ></tcloud-ui-modal-header>\n\n <tcloud-ui-modal-body>\n Conte\u00FAdo do modal aqui\n </tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open = !open\">open modal {{ open }}</button>\n-->\n\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n\n<!-- Ex: Confirm Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open_confirm\" [title]=\"'Aten\u00E7\u00E3o'\" [confirmText]=\"'Aceito'\" [confirm]=\"true\" (toAction)=\"$event\" >\n\n <tcloud-ui-modal-body>Deseja realmente executar esta a\u00E7\u00E3o?</tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open_confirm = !open_confirm\">open_confirm modal {{ open_confirm }}</button>\n-->", styles: [".tc-background-modal{border:1px solid var(--c-neutral-300);position:fixed;width:100%;left:0;top:0;background-color:#000;z-index:4005;height:100%;opacity:.3}.base-modal{height:100%;overflow:scroll;position:fixed;width:100%;z-index:4005;left:0;top:0;text-align:left!important}.sub-modal{padding:30px;position:absolute;width:100%;display:flex;justify-content:center;align-items:flex-start}.sub-modal.position-left{justify-content:flex-start}.sub-modal.position-right{justify-content:flex-end}.sub-modal.position-bottom{align-items:flex-end}.tc-modal{position:relative;background-color:var(--c-neutral-50);border:1px solid var(--c-neutral-200);padding:12px;border-radius:8px;margin:auto;width:100%;transition:max-width .3s ease-out}@media(prefers-reduced-motion:reduce){.tc-modal{transition:none}}.sub-modal.is-sticky{padding:0}.sub-modal.is-sticky>.tc-modal{border-radius:0}.sub-modal.is-sticky.position-left>.tc-modal{margin:0 auto 0 0}.sub-modal.is-sticky.position-right>.tc-modal{margin:0 0 0 auto}.sub-modal.is-sticky.position-bottom>.tc-modal{margin:auto 0 0}.sub-modal.is-sticky.position-center>.tc-modal,.sub-modal.is-sticky.position-bottom>.tc-modal{max-width:100%!important;width:100%!important}.tc-modal-shadow{-webkit-box-shadow:2px 2px 10px 0px rgba(0,0,0,.368627451);box-shadow:2px 2px 10px #0000005e}.tc-btn-x{min-height:25px!important;min-width:25px!important;height:25px;width:25px;margin-top:8px}.area-top-actions{position:absolute;top:2px;right:5px;z-index:1}.area-top-actions.tc-ui-modal-colorless button.tc-btn-action-close-ui-modal i{color:var(--c-neutral-600)!important}.area-top-actions button.tc-btn-action-close-ui-modal{cursor:pointer;background-color:transparent;border:none;font-size:15px;padding:5px 7px}.area-top-actions button.tc-btn-action-close-ui-modal i{font-size:17px;color:#fff;transition:all .25s;opacity:.7}.area-top-actions button.tc-btn-action-close-ui-modal i:hover{opacity:1!important}h4{font-size:16px;margin:5px 30px 10px 0;font-weight:700}.no-use-header i{color:var(--c-neutral-500)!important}.tcloud-ui-modal-sticky{height:100vh;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], animations: [
|
|
3777
3777
|
trigger('fade', [
|
|
3778
3778
|
transition('void => *', [
|
|
3779
3779
|
style({ opacity: 0, transform: '{{enterTransform}}' }),
|
|
@@ -3800,7 +3800,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
3800
3800
|
animate('0.3s ease-out', style({ opacity: 0, transform: '{{leaveTransform}}' }))
|
|
3801
3801
|
], { params: { leaveTransform: 'translateY(-38%)' } })
|
|
3802
3802
|
])
|
|
3803
|
-
], standalone: true, imports: [CommonModule], template: "@if (control_open) {\n <div class=\"tc-background-modal\" >{{ checkIsOpen() }}</div>\n}\n\n@if (open) {\n <div class=\"tcloud-ui-modal base-modal tcloud-ui-modal-layout-{{ layout }} tcloud-ui-modal-postition-{{ position }}\" [attr.data-layout]=\"layout\">\n <div class=\"sub-modal\" [ngClass]=\"['position-' + position, sticky ? 'is-sticky' : '']\" [@fade]=\"animationParams\">\n <div class=\"tc-modal tc-modal-shadow\" [style.max-width.px]=\"maxWidth\" [class.tcloud-ui-modal-sticky]=\"sticky\">\n <div class=\"area-top-actions tc-ui-modal-{{mode}}\">\n @if( layout === 'classic'){\n <button type=\"button\" class=\"tc-btn-action-close-ui-modal\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }@else{\n <button type=\"button\" class=\"tc-rev-btn-square tc-btn-x\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }\n </div>\n @if (title) {\n <h4 [innerHTML]=\"title\"></h4>\n }\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n\n<!-- Ex: Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open\">\n\n <tcloud-ui-modal-header title=\"T\u00EDtulo do Modal\" ></tcloud-ui-modal-header>\n\n <tcloud-ui-modal-body>\n Conte\u00FAdo do modal aqui\n </tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open = !open\">open modal {{ open }}</button>\n-->\n\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n\n<!-- Ex: Confirm Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open_confirm\" [title]=\"'Aten\u00E7\u00E3o'\" [confirmText]=\"'Aceito'\" [confirm]=\"true\" (toAction)=\"$event\" >\n\n <tcloud-ui-modal-body>Deseja realmente executar esta a\u00E7\u00E3o?</tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open_confirm = !open_confirm\">open_confirm modal {{ open_confirm }}</button>\n-->", styles: [".tc-background-modal{border:1px solid var(--c-neutral-300);position:fixed;width:100%;left:0;top:0;background-color:#000;z-index:4005;height:100%;opacity:.3}.base-modal{height:100%;overflow:scroll;position:fixed;width:100%;z-index:4005;left:0;top:0;text-align:left!important}.sub-modal{padding:30px;position:absolute;width:100%;display:flex;justify-content:center;align-items:flex-start}.sub-modal.position-left{justify-content:flex-start}.sub-modal.position-right{justify-content:flex-end}.sub-modal.position-bottom{align-items:flex-end}.tc-modal{position:relative;background-color:var(--c-neutral-50);border:1px solid var(--c-neutral-200);padding:12px;border-radius:8px;margin:auto;width:100%;transition:max-width .3s ease-out}@media(prefers-reduced-motion:reduce){.tc-modal{transition:none}}.sub-modal.is-sticky{padding:0}.sub-modal.is-sticky
|
|
3803
|
+
], standalone: true, imports: [CommonModule], template: "@if (control_open) {\n <div class=\"tc-background-modal\" >{{ checkIsOpen() }}</div>\n}\n\n@if (open) {\n <div class=\"tcloud-ui-modal base-modal tcloud-ui-modal-layout-{{ layout }} tcloud-ui-modal-postition-{{ position }}\" [attr.data-layout]=\"layout\">\n <div class=\"sub-modal\" [ngClass]=\"['position-' + position, sticky ? 'is-sticky' : '']\" [@fade]=\"animationParams\">\n <div class=\"tc-modal tc-modal-shadow\" [style.max-width.px]=\"maxWidth\" [class.tcloud-ui-modal-sticky]=\"sticky\">\n <div class=\"area-top-actions tc-ui-modal-{{mode}}\">\n @if( layout === 'classic'){\n <button type=\"button\" class=\"tc-btn-action-close-ui-modal\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }@else{\n <button type=\"button\" class=\"tc-rev-btn-square tc-btn-x\" [class.no-use-header]=\"title\" (click)=\"toClose()\" [disabled]=\"loading\">\n @if (!loading) {\n <i class=\"fas fa-times\"></i>\n }\n @if (loading) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n </button>\n }\n </div>\n @if (title) {\n <h4 [innerHTML]=\"title\"></h4>\n }\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n\n<!-- Ex: Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open\">\n\n <tcloud-ui-modal-header title=\"T\u00EDtulo do Modal\" ></tcloud-ui-modal-header>\n\n <tcloud-ui-modal-body>\n Conte\u00FAdo do modal aqui\n </tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open = !open\">open modal {{ open }}</button>\n-->\n\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n<!-- ****** -->\n\n<!-- Ex: Confirm Modal -->\n<!--\n<tcloud-ui-modal [(open)]=\"open_confirm\" [title]=\"'Aten\u00E7\u00E3o'\" [confirmText]=\"'Aceito'\" [confirm]=\"true\" (toAction)=\"$event\" >\n\n <tcloud-ui-modal-body>Deseja realmente executar esta a\u00E7\u00E3o?</tcloud-ui-modal-body>\n\n <tcloud-ui-modal-footer></tcloud-ui-modal-footer>\n\n</tcloud-ui-modal>\n\n<button type=\"button\" (click)=\"open_confirm = !open_confirm\">open_confirm modal {{ open_confirm }}</button>\n-->", styles: [".tc-background-modal{border:1px solid var(--c-neutral-300);position:fixed;width:100%;left:0;top:0;background-color:#000;z-index:4005;height:100%;opacity:.3}.base-modal{height:100%;overflow:scroll;position:fixed;width:100%;z-index:4005;left:0;top:0;text-align:left!important}.sub-modal{padding:30px;position:absolute;width:100%;display:flex;justify-content:center;align-items:flex-start}.sub-modal.position-left{justify-content:flex-start}.sub-modal.position-right{justify-content:flex-end}.sub-modal.position-bottom{align-items:flex-end}.tc-modal{position:relative;background-color:var(--c-neutral-50);border:1px solid var(--c-neutral-200);padding:12px;border-radius:8px;margin:auto;width:100%;transition:max-width .3s ease-out}@media(prefers-reduced-motion:reduce){.tc-modal{transition:none}}.sub-modal.is-sticky{padding:0}.sub-modal.is-sticky>.tc-modal{border-radius:0}.sub-modal.is-sticky.position-left>.tc-modal{margin:0 auto 0 0}.sub-modal.is-sticky.position-right>.tc-modal{margin:0 0 0 auto}.sub-modal.is-sticky.position-bottom>.tc-modal{margin:auto 0 0}.sub-modal.is-sticky.position-center>.tc-modal,.sub-modal.is-sticky.position-bottom>.tc-modal{max-width:100%!important;width:100%!important}.tc-modal-shadow{-webkit-box-shadow:2px 2px 10px 0px rgba(0,0,0,.368627451);box-shadow:2px 2px 10px #0000005e}.tc-btn-x{min-height:25px!important;min-width:25px!important;height:25px;width:25px;margin-top:8px}.area-top-actions{position:absolute;top:2px;right:5px;z-index:1}.area-top-actions.tc-ui-modal-colorless button.tc-btn-action-close-ui-modal i{color:var(--c-neutral-600)!important}.area-top-actions button.tc-btn-action-close-ui-modal{cursor:pointer;background-color:transparent;border:none;font-size:15px;padding:5px 7px}.area-top-actions button.tc-btn-action-close-ui-modal i{font-size:17px;color:#fff;transition:all .25s;opacity:.7}.area-top-actions button.tc-btn-action-close-ui-modal i:hover{opacity:1!important}h4{font-size:16px;margin:5px 30px 10px 0;font-weight:700}.no-use-header i{color:var(--c-neutral-500)!important}.tcloud-ui-modal-sticky{height:100vh;overflow:hidden}\n"] }]
|
|
3804
3804
|
}], ctorParameters: () => [{ type: TCloudUiLayoutService }, { type: TcloudModalService }], propDecorators: { confirm: [{
|
|
3805
3805
|
type: Input
|
|
3806
3806
|
}], confirmText: [{
|
|
@@ -6301,15 +6301,26 @@ class TCloudUiUploadAreaComponent {
|
|
|
6301
6301
|
this.onImagesSelected(files);
|
|
6302
6302
|
}
|
|
6303
6303
|
generateNameFile(fileName) {
|
|
6304
|
-
|
|
6305
|
-
const lastDotIndex = fileName.lastIndexOf('.');
|
|
6306
|
-
const extension = lastDotIndex !== -1 ? fileName.substring(lastDotIndex) : '';
|
|
6304
|
+
const extension = this.getFullExtension(fileName);
|
|
6307
6305
|
// Gera um nome aleatório (16 caracteres)
|
|
6308
6306
|
const randomName = Math.random().toString(36).substring(2, 15) +
|
|
6309
6307
|
Math.random().toString(36).substring(2, 15);
|
|
6310
6308
|
// Retorna o nome aleatório + extensão, tudo em minúsculo
|
|
6311
6309
|
return (randomName + extension).toLowerCase();
|
|
6312
6310
|
}
|
|
6311
|
+
// Extensões compostas conhecidas (ex.: pacotes Linux) que não podem ser cortadas pelo último ponto
|
|
6312
|
+
static { this.COMPOUND_EXTENSIONS = [
|
|
6313
|
+
'.tar.gz', '.tar.bz2', '.tar.xz', '.tar.zst', '.tar.lz', '.tar.lzma'
|
|
6314
|
+
]; }
|
|
6315
|
+
// Extrai a extensão do arquivo, reconhecendo extensões compostas (.tar.gz, etc.)
|
|
6316
|
+
getFullExtension(fileName) {
|
|
6317
|
+
const lower = fileName.toLowerCase();
|
|
6318
|
+
const compound = TCloudUiUploadAreaComponent.COMPOUND_EXTENSIONS.find(ext => lower.endsWith(ext));
|
|
6319
|
+
if (compound)
|
|
6320
|
+
return compound;
|
|
6321
|
+
const lastDot = fileName.lastIndexOf('.');
|
|
6322
|
+
return lastDot !== -1 ? fileName.substring(lastDot).toLowerCase() : '';
|
|
6323
|
+
}
|
|
6313
6324
|
onImagesSelected(files) {
|
|
6314
6325
|
// Não limpa o array, apenas adiciona novas imagens ao final
|
|
6315
6326
|
// Verifica se há limite máximo e quantos arquivos ainda podem ser adicionados
|
|
@@ -6474,13 +6485,12 @@ class TCloudUiUploadAreaComponent {
|
|
|
6474
6485
|
const matchesMime = hasTypesFilter
|
|
6475
6486
|
? this.acceptedFileTypes.includes(file.type)
|
|
6476
6487
|
: false;
|
|
6477
|
-
// Verifica por extensão (case-insensitive,
|
|
6488
|
+
// Verifica por extensão (case-insensitive, por sufixo para suportar extensões compostas como .tar.gz)
|
|
6478
6489
|
let matchesExt = false;
|
|
6479
6490
|
if (hasExtFilter) {
|
|
6480
|
-
const
|
|
6481
|
-
const fileExt = lastDot !== -1 ? file.name.substring(lastDot).toLowerCase() : '';
|
|
6491
|
+
const fileName = file.name.toLowerCase();
|
|
6482
6492
|
const normalizedExts = this.acceptedExtensions.map(e => (e.startsWith('.') ? e : `.${e}`).toLowerCase());
|
|
6483
|
-
matchesExt = normalizedExts.
|
|
6493
|
+
matchesExt = normalizedExts.some(ext => fileName.endsWith(ext));
|
|
6484
6494
|
}
|
|
6485
6495
|
return matchesMime || matchesExt;
|
|
6486
6496
|
}
|
|
@@ -6558,11 +6568,11 @@ class TCloudUiUploadAreaComponent {
|
|
|
6558
6568
|
isImageFile(index) {
|
|
6559
6569
|
return this.images[index]?.file?.type?.startsWith('image/') ?? false;
|
|
6560
6570
|
}
|
|
6561
|
-
// Retorna a extensão do arquivo em maiúsculo (sem ponto), ex: 'PDF', '
|
|
6571
|
+
// Retorna a extensão do arquivo em maiúsculo (sem ponto), ex: 'PDF', 'TAR.GZ'
|
|
6562
6572
|
getFileExtension(index) {
|
|
6563
6573
|
const name = this.images[index]?.name ?? '';
|
|
6564
|
-
const
|
|
6565
|
-
return
|
|
6574
|
+
const extension = this.getFullExtension(name);
|
|
6575
|
+
return extension ? extension.substring(1).toUpperCase() : 'FILE';
|
|
6566
6576
|
}
|
|
6567
6577
|
// Valida dimensões da imagem
|
|
6568
6578
|
validateImageDimensions(imageSrc, fileName) {
|