mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Enhancement: relocate and smaller upload widget, dont limit upload list (#9244)
This commit is contained in:
parent
0eb765c3e8
commit
865e9fe233
@ -272,7 +272,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
||||||
<context context-type="linenumber">73</context>
|
<context context-type="linenumber">58</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8582620835547864448" datatype="html">
|
<trans-unit id="8582620835547864448" datatype="html">
|
||||||
@ -735,7 +735,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html</context>
|
||||||
<context context-type="linenumber">14</context>
|
<context context-type="linenumber">15</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
|
||||||
@ -6172,10 +6172,6 @@
|
|||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
|
||||||
<context context-type="linenumber">9</context>
|
<context context-type="linenumber">9</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
|
||||||
<context context-type="linenumber">39</context>
|
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8076495233090006322" datatype="html">
|
<trans-unit id="8076495233090006322" datatype="html">
|
||||||
<source>Filter by correspondent</source>
|
<source>Filter by correspondent</source>
|
||||||
@ -6314,69 +6310,54 @@
|
|||||||
<context context-type="linenumber">83</context>
|
<context context-type="linenumber">83</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8187573012244728580" datatype="html">
|
<trans-unit id="3402055842664792382" datatype="html">
|
||||||
<source>Upload new documents</source>
|
<source>Upload documents</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
||||||
<context context-type="linenumber">1</context>
|
<context context-type="linenumber">6</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8161815301131859114" datatype="html">
|
<trans-unit id="6388681050646106203" datatype="html">
|
||||||
<source>Drop documents anywhere or</source>
|
<source>or drop files anywhere</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
||||||
<context context-type="linenumber">4</context>
|
<context context-type="linenumber">7</context>
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="8133800334834354642" datatype="html">
|
|
||||||
<source>Browse files</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
|
||||||
<context context-type="linenumber">5</context>
|
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1749180330008942007" datatype="html">
|
<trans-unit id="1749180330008942007" datatype="html">
|
||||||
<source>Dismiss completed</source>
|
<source>Dismiss completed</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
||||||
<context context-type="linenumber">20</context>
|
<context context-type="linenumber">23</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<note priority="1" from="description">This button dismisses all status messages about processed documents on the dashboard (failed and successful)</note>
|
<note priority="1" from="description">This button dismisses all status messages about processed documents on the dashboard (failed and successful)</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2330646618997399019" datatype="html">
|
|
||||||
<source>{VAR_PLURAL, plural, =1 {One more document} other {<x id="INTERPOLATION"/> more documents}}</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
|
|
||||||
<context context-type="linenumber">37</context>
|
|
||||||
</context-group>
|
|
||||||
<note priority="1" from="description">This is shown as a summary line when there are more than 5 document in the processing pipeline.</note>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="6443586946875325554" datatype="html">
|
<trans-unit id="6443586946875325554" datatype="html">
|
||||||
<source>Processing: <x id="PH" equiv-text="countUploadingAndProcessing"/></source>
|
<source>Processing: <x id="PH" equiv-text="countUploadingAndProcessing"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
||||||
<context context-type="linenumber">67</context>
|
<context context-type="linenumber">61</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="9182918211699394982" datatype="html">
|
<trans-unit id="9182918211699394982" datatype="html">
|
||||||
<source>Failed: <x id="PH" equiv-text="countFailed"/></source>
|
<source>Failed: <x id="PH" equiv-text="countFailed"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
||||||
<context context-type="linenumber">70</context>
|
<context context-type="linenumber">64</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="534116346205124059" datatype="html">
|
<trans-unit id="534116346205124059" datatype="html">
|
||||||
<source>Added: <x id="PH" equiv-text="countSuccess"/></source>
|
<source>Added: <x id="PH" equiv-text="countSuccess"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
||||||
<context context-type="linenumber">73</context>
|
<context context-type="linenumber">67</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="760986369763309193" datatype="html">
|
<trans-unit id="760986369763309193" datatype="html">
|
||||||
<source>, </source>
|
<source>, </source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts</context>
|
||||||
<context context-type="linenumber">76</context>
|
<context context-type="linenumber">70</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||||
|
@ -49,12 +49,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-lg-4 col-xl-3 col-sidebar">
|
<div class="col-12 col-lg-4 col-xl-3 col-sidebar">
|
||||||
<div class="row row-cols-1 g-4 mb-4 sticky-lg-top z-0">
|
<div class="row row-cols-1 g-4 mb-4 sticky-lg-top z-0">
|
||||||
<div class="col">
|
<pngx-upload-file-widget></pngx-upload-file-widget>
|
||||||
<pngx-statistics-widget *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.UISettings }"></pngx-statistics-widget>
|
<pngx-statistics-widget *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.UISettings }"></pngx-statistics-widget>
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<pngx-upload-file-widget></pngx-upload-file-widget>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
<pngx-widget-frame title="Upload new documents" i18n-title *pngxIfPermissions="{ action: PermissionAction.Add, type: PermissionType.Document }">
|
<pngx-widget-frame *pngxIfPermissions="{ action: PermissionAction.Add, type: PermissionType.Document }" [cardless]="true">
|
||||||
<div content tourAnchor="tour.upload-widget">
|
<div content tourAnchor="tour.upload-widget">
|
||||||
<form class="justify-content-center d-flex flex-column align-items-center py-3 px-2">
|
<form class="justify-content-center d-flex flex-column align-items-center">
|
||||||
<span class="text-muted" i18n>Drop documents anywhere or</span>
|
<button type="button" class="btn btn-outline-dark bg-light shadow-sm w-100 h-100 pt-3 pb-2" (click)="fileUpload.click()">
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary mt-3" (click)="fileUpload.click()" i18n>Browse files</button>
|
<i-bs class="text-primary" name="plus-circle"></i-bs>
|
||||||
|
<span class="text-primary" i18n>Upload documents</span>
|
||||||
|
<div class="text-muted smaller fst-italic" i18n>or drop files anywhere</div>
|
||||||
|
</button>
|
||||||
<input type="file" class="visually-hidden" (change)="onFileSelected($event)" multiple #fileUpload>
|
<input type="file" class="visually-hidden" (change)="onFileSelected($event)" multiple #fileUpload>
|
||||||
</form>
|
</form>
|
||||||
@if (getStatus().length > 0) {
|
@if (getStatus().length > 0) {
|
||||||
<div class="fixed-bottom p-2 p-md-4 d-flex justify-content-end pe-none max-vh100-40" [ngClass]="slimSidebarEnabled ? 'col-slim' : 'offset-md-3 offset-lg-2'">
|
<div class="fixed-bottom p-2 p-md-4 d-flex justify-content-end pe-none consumer-status-list" [ngClass]="slimSidebarEnabled ? 'col-slim' : 'offset-md-3 offset-lg-2'">
|
||||||
<div class="col col-lg-4 col-xl-3 ps-0 pe-0 ps-lg-3 pe-lg-0 pe-auto overflow-y-scroll">
|
<div class="col col-lg-4 col-xl-3 ps-0 pe-0 ps-lg-3 pe-lg-0 pe-auto overflow-y-scroll">
|
||||||
<div class="card shadow-sm consumer-status-card">
|
<div class="card shadow-sm consumer-status-card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -30,24 +33,6 @@
|
|||||||
<ng-container [ngTemplateOutlet]="consumerAlert" [ngTemplateOutletContext]="{ $implicit: status }"></ng-container>
|
<ng-container [ngTemplateOutlet]="consumerAlert" [ngTemplateOutletContext]="{ $implicit: status }"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (getStatusHidden().length) {
|
|
||||||
<div class="alerts-hidden">
|
|
||||||
@if (!alertsExpanded) {
|
|
||||||
<p class="mt-3 mb-0 text-center">
|
|
||||||
<span i18n="This is shown as a summary line when there are more than 5 document in the processing pipeline.">{getStatusHidden().length, plural, =1 {One more document} other {{{getStatusHidden().length}} more documents}}</span>
|
|
||||||
•
|
|
||||||
<a [routerLink]="[]" (click)="alertsExpanded = !alertsExpanded" aria-controls="hiddenAlerts" [attr.aria-expanded]="alertsExpanded" i18n>Show all</a>
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
<div #hiddenAlerts="ngbCollapse" [ngbCollapse]="!alertsExpanded" (ngbCollapseChange)="alertsExpanded = $event">
|
|
||||||
@for (status of getStatusHidden(); track status) {
|
|
||||||
<div>
|
|
||||||
<ng-container [ngTemplateOutlet]="consumerAlert" [ngTemplateOutletContext]="{ $implicit: status }"></ng-container>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
form {
|
:host ::ng-deep i-bs svg {
|
||||||
position: relative;
|
margin-top: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-dark {
|
||||||
|
--bs-btn-border-color: var(--bs-border-color-translucent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.smaller {
|
||||||
|
font-size: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-heading {
|
.alert-heading {
|
||||||
@ -40,6 +48,10 @@ form {
|
|||||||
background-color: rgba(var(--bs-body-bg-rgb), .95) !important;
|
background-color: rgba(var(--bs-body-bg-rgb), .95) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.max-vh100-40 {
|
.consumer-status-list {
|
||||||
max-height: calc(100vh - 40px);
|
max-height: calc(100vh - 315px); // e.g. below the upload button, mobile
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
max-height: calc(100vh - 200px); // e.g. below the upload button
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
} from '@angular/core/testing'
|
} from '@angular/core/testing'
|
||||||
import { By } from '@angular/platform-browser'
|
import { By } from '@angular/platform-browser'
|
||||||
import { RouterTestingModule } from '@angular/router/testing'
|
import { RouterTestingModule } from '@angular/router/testing'
|
||||||
import { NgbAlert, NgbCollapse } from '@ng-bootstrap/ng-bootstrap'
|
|
||||||
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||||
import { routes } from 'src/app/app-routing.module'
|
import { routes } from 'src/app/app-routing.module'
|
||||||
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
|
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
|
||||||
@ -116,20 +115,6 @@ describe('UploadFileWidgetComponent', () => {
|
|||||||
expect(component.getStatusColor(successStatus)).toEqual('success')
|
expect(component.getStatusColor(successStatus)).toEqual('success')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should enforce a maximum number of alerts', () => {
|
|
||||||
mockConsumerStatuses(websocketStatusService)
|
|
||||||
fixture.detectChanges()
|
|
||||||
// 5 total, 1 hidden
|
|
||||||
expect(fixture.debugElement.queryAll(By.directive(NgbAlert))).toHaveLength(
|
|
||||||
6
|
|
||||||
)
|
|
||||||
expect(
|
|
||||||
fixture.debugElement
|
|
||||||
.query(By.directive(NgbCollapse))
|
|
||||||
.queryAll(By.directive(NgbAlert))
|
|
||||||
).toHaveLength(1)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should allow dismissing an alert', () => {
|
it('should allow dismissing an alert', () => {
|
||||||
const dismissSpy = jest.spyOn(websocketStatusService, 'dismiss')
|
const dismissSpy = jest.spyOn(websocketStatusService, 'dismiss')
|
||||||
component.dismiss(new FileStatus())
|
component.dismiss(new FileStatus())
|
||||||
@ -138,7 +123,6 @@ describe('UploadFileWidgetComponent', () => {
|
|||||||
|
|
||||||
it('should allow dismissing completed alerts', fakeAsync(() => {
|
it('should allow dismissing completed alerts', fakeAsync(() => {
|
||||||
mockConsumerStatuses(websocketStatusService)
|
mockConsumerStatuses(websocketStatusService)
|
||||||
component.alertsExpanded = true
|
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
jest
|
jest
|
||||||
.spyOn(component, 'getStatusCompleted')
|
.spyOn(component, 'getStatusCompleted')
|
||||||
|
@ -4,7 +4,6 @@ import { RouterModule } from '@angular/router'
|
|||||||
import {
|
import {
|
||||||
NgbAlert,
|
NgbAlert,
|
||||||
NgbAlertModule,
|
NgbAlertModule,
|
||||||
NgbCollapseModule,
|
|
||||||
NgbProgressbarModule,
|
NgbProgressbarModule,
|
||||||
} from '@ng-bootstrap/ng-bootstrap'
|
} from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
@ -21,8 +20,6 @@ import {
|
|||||||
} from 'src/app/services/websocket-status.service'
|
} from 'src/app/services/websocket-status.service'
|
||||||
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
|
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
|
||||||
|
|
||||||
const MAX_ALERTS = 5
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pngx-upload-file-widget',
|
selector: 'pngx-upload-file-widget',
|
||||||
templateUrl: './upload-file-widget.component.html',
|
templateUrl: './upload-file-widget.component.html',
|
||||||
@ -34,15 +31,12 @@ const MAX_ALERTS = 5
|
|||||||
NgTemplateOutlet,
|
NgTemplateOutlet,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
NgbAlertModule,
|
NgbAlertModule,
|
||||||
NgbCollapseModule,
|
|
||||||
NgbProgressbarModule,
|
NgbProgressbarModule,
|
||||||
NgxBootstrapIconsModule,
|
NgxBootstrapIconsModule,
|
||||||
TourNgBootstrapModule,
|
TourNgBootstrapModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class UploadFileWidgetComponent extends ComponentWithPermissions {
|
export class UploadFileWidgetComponent extends ComponentWithPermissions {
|
||||||
alertsExpanded = false
|
|
||||||
|
|
||||||
@ViewChildren(NgbAlert) alerts: QueryList<NgbAlert>
|
@ViewChildren(NgbAlert) alerts: QueryList<NgbAlert>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -54,7 +48,7 @@ export class UploadFileWidgetComponent extends ComponentWithPermissions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getStatus() {
|
getStatus() {
|
||||||
return this.websocketStatusService.getConsumerStatus().slice(0, MAX_ALERTS)
|
return this.websocketStatusService.getConsumerStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatusSummary() {
|
getStatusSummary() {
|
||||||
@ -77,13 +71,6 @@ export class UploadFileWidgetComponent extends ComponentWithPermissions {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatusHidden() {
|
|
||||||
if (this.websocketStatusService.getConsumerStatus().length < MAX_ALERTS)
|
|
||||||
return []
|
|
||||||
else
|
|
||||||
return this.websocketStatusService.getConsumerStatus().slice(MAX_ALERTS)
|
|
||||||
}
|
|
||||||
|
|
||||||
getStatusUploading() {
|
getStatusUploading() {
|
||||||
return this.websocketStatusService.getConsumerStatus(
|
return this.websocketStatusService.getConsumerStatus(
|
||||||
FileStatusPhase.UPLOADING
|
FileStatusPhase.UPLOADING
|
||||||
|
@ -1,23 +1,32 @@
|
|||||||
<div class="card shadow-sm bg-light fade" [class.show]="show" cdkDrag [cdkDragDisabled]="!draggable" cdkDragPreviewContainer="parent">
|
@if (!cardless) {
|
||||||
<div class="card-header">
|
<div class="card shadow-sm bg-light fade" [class.show]="show" cdkDrag [cdkDragDisabled]="!draggable" cdkDragPreviewContainer="parent">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="card-header">
|
||||||
<div class="d-flex">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
@if (draggable) {
|
<div class="d-flex">
|
||||||
<div class="ms-n2 me-1" cdkDragHandle>
|
@if (draggable) {
|
||||||
<i-bs name="grip-vertical"></i-bs>
|
<div class="ms-n2 me-1" cdkDragHandle>
|
||||||
</div>
|
<i-bs name="grip-vertical"></i-bs>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<h6 class="card-title mb-0">{{title}}</h6>
|
||||||
|
</div>
|
||||||
|
@if (loading) {
|
||||||
|
<div class="spinner-border spinner-border-sm fw-normal ms-2 me-auto" role="status"></div>
|
||||||
|
<div class="visually-hidden" i18n>Loading...</div>
|
||||||
}
|
}
|
||||||
<h6 class="card-title mb-0">{{title}}</h6>
|
<ng-content select="[header-buttons]"></ng-content>
|
||||||
</div>
|
</div>
|
||||||
@if (loading) {
|
|
||||||
<div class="spinner-border spinner-border-sm fw-normal ms-2 me-auto" role="status"></div>
|
|
||||||
<div class="visually-hidden" i18n>Loading...</div>
|
|
||||||
}
|
|
||||||
<ng-content select="[header-buttons]"></ng-content>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-body text-dark">
|
||||||
|
<ng-container [ngTemplateOutlet]="content"></ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<div class="fade" [class.show]="show">
|
||||||
|
<ng-container [ngTemplateOutlet]="content"></ng-container>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
</div>
|
<ng-template #content>
|
||||||
<div class="card-body text-dark">
|
<ng-content select="[content]"></ng-content>
|
||||||
<ng-content select="[content]"></ng-content>
|
</ng-template>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { DragDropModule } from '@angular/cdk/drag-drop'
|
import { DragDropModule } from '@angular/cdk/drag-drop'
|
||||||
|
import { NgTemplateOutlet } from '@angular/common'
|
||||||
import { AfterViewInit, Component, Input } from '@angular/core'
|
import { AfterViewInit, Component, Input } from '@angular/core'
|
||||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||||
import { LoadingComponentWithPermissions } from 'src/app/components/loading-component/loading.component'
|
import { LoadingComponentWithPermissions } from 'src/app/components/loading-component/loading.component'
|
||||||
@ -7,7 +8,7 @@ import { LoadingComponentWithPermissions } from 'src/app/components/loading-comp
|
|||||||
selector: 'pngx-widget-frame',
|
selector: 'pngx-widget-frame',
|
||||||
templateUrl: './widget-frame.component.html',
|
templateUrl: './widget-frame.component.html',
|
||||||
styleUrls: ['./widget-frame.component.scss'],
|
styleUrls: ['./widget-frame.component.scss'],
|
||||||
imports: [DragDropModule, NgxBootstrapIconsModule],
|
imports: [DragDropModule, NgxBootstrapIconsModule, NgTemplateOutlet],
|
||||||
})
|
})
|
||||||
export class WidgetFrameComponent
|
export class WidgetFrameComponent
|
||||||
extends LoadingComponentWithPermissions
|
extends LoadingComponentWithPermissions
|
||||||
@ -26,6 +27,9 @@ export class WidgetFrameComponent
|
|||||||
@Input()
|
@Input()
|
||||||
draggable: any
|
draggable: any
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
cardless: boolean = false
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.show = true
|
this.show = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user