Compare commits

..

1 Commits

Author SHA1 Message Date
shamoon
13338088cb Performance: add index to paperlesstask task_id 2025-06-19 02:33:58 -07:00
5 changed files with 128 additions and 119 deletions

View File

@@ -158,13 +158,10 @@
</div> </div>
<div class="nav-group mt-3 mb-1"> <div class="nav-group mt-3 mb-1">
<h6 class="sidebar-heading px-3 text-muted d-flex align-items-center"> <h6 class="sidebar-heading px-3 text-muted">
<span i18n>Manage</span> <span i18n>Manage</span>
<button class="btn btn-link p-2 py-0" (click)="manageCollapse.toggle()">
<i-bs width="0.9em" height="0.9em" [name]="isManageMenuCollapsed ? 'chevron-down' : 'chevron-up'"></i-bs>
</button>
</h6> </h6>
<ul class="nav flex-column mb-2" #manageCollapse="ngbCollapse" [(ngbCollapse)]="isManageMenuCollapsed"> <ul class="nav flex-column mb-2">
<li class="nav-item app-link" <li class="nav-item app-link"
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Correspondent }"> *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Correspondent }">
<a class="nav-link" routerLink="correspondents" routerLinkActive="active" (click)="closeMenu()" <a class="nav-link" routerLink="correspondents" routerLinkActive="active" (click)="closeMenu()"
@@ -238,124 +235,117 @@
</div> </div>
<div class="nav-group mt-auto mb-1"> <div class="nav-group mt-auto mb-1">
<h6 class="sidebar-heading px-3 pt-4 text-muted d-flex align-items-center"> <h6 class="sidebar-heading px-3 pt-4 text-muted">
<span i18n>Administration</span> <span i18n>Administration</span>
<button class="btn btn-link p-2 py-0" (click)="adminCollapse.toggle()">
<i-bs width="0.9em" height="0.9em" [name]="isAdminMenuCollapsed ? 'chevron-down' : 'chevron-up'"></i-bs>
</button>
</h6> </h6>
<div class="mb-2"> <ul class="nav flex-column mb-2">
<ul class="nav flex-column" #adminCollapse="ngbCollapse" [(ngbCollapse)]="isAdminMenuCollapsed"> <li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.UISettings }"
<li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.UISettings }" tourAnchor="tour.settings">
tourAnchor="tour.settings"> <a class="nav-link" routerLink="settings" routerLinkActive="active" (click)="closeMenu()"
<a class="nav-link" routerLink="settings" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Settings" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end"
ngbPopover="Settings" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim"> <i-bs class="me-1" name="gear"></i-bs><span>&nbsp;<ng-container i18n>Settings</ng-container></span>
<i-bs class="me-1" name="gear"></i-bs><span>&nbsp;<ng-container i18n>Settings</ng-container></span> </a>
</a> </li>
</li> <li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.AppConfig }">
<li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.AppConfig }"> <a class="nav-link" routerLink="config" routerLinkActive="active" (click)="closeMenu()"
<a class="nav-link" routerLink="config" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Configuration" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end"
ngbPopover="Configuration" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim"> <i-bs class="me-1" name="sliders2-vertical"></i-bs><span>&nbsp;<ng-container i18n>Configuration</ng-container></span>
<i-bs class="me-1" name="sliders2-vertical"></i-bs><span>&nbsp;<ng-container i18n>Configuration</ng-container></span> </a>
</a> </li>
</li> <li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.User }">
<li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.User }"> <a class="nav-link" routerLink="usersgroups" routerLinkActive="active" (click)="closeMenu()"
<a class="nav-link" routerLink="usersgroups" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Users & Groups" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end"
ngbPopover="Users & Groups" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim"> <i-bs class="me-1" name="people"></i-bs><span>&nbsp;<ng-container i18n>Users & Groups</ng-container></span>
<i-bs class="me-1" name="people"></i-bs><span>&nbsp;<ng-container i18n>Users & Groups</ng-container></span> </a>
</a> </li>
</li> <li class="nav-item app-link"
<li class="nav-item app-link" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.PaperlessTask }"
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.PaperlessTask }" tourAnchor="tour.file-tasks">
tourAnchor="tour.file-tasks"> <a class="nav-link" routerLink="tasks" routerLinkActive="active" (click)="closeMenu()"
<a class="nav-link" routerLink="tasks" routerLinkActive="active" (click)="closeMenu()" ngbPopover="File Tasks" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end"
ngbPopover="File Tasks" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim"> <i-bs class="me-1" name="list-task"></i-bs><span>&nbsp;<ng-container i18n>File Tasks</ng-container>@if (tasksService.failedFileTasks.length > 0) {
<i-bs class="me-1" name="list-task"></i-bs><span>&nbsp;<ng-container i18n>File Tasks</ng-container>@if (tasksService.failedFileTasks.length > 0) { <span><span class="badge bg-danger ms-2 d-inline">{{tasksService.failedFileTasks.length}}</span></span>
<span><span class="badge bg-danger ms-2 d-inline">{{tasksService.failedFileTasks.length}}</span></span> }</span>
}</span> @if (tasksService.failedFileTasks.length > 0 && slimSidebarEnabled) {
@if (tasksService.failedFileTasks.length > 0 && slimSidebarEnabled) { <span class="badge bg-danger position-absolute top-0 end-0 d-none d-md-block">{{tasksService.failedFileTasks.length}}</span>
<span class="badge bg-danger position-absolute top-0 end-0 d-none d-md-block">{{tasksService.failedFileTasks.length}}</span> }
} </a>
</a> </li>
</li> @if (permissionsService.isAdmin()) {
@if (permissionsService.isAdmin()) { <li class="nav-item app-link">
<li class="nav-item app-link"> <a class="nav-link" routerLink="logs" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Logs"
<a class="nav-link" routerLink="logs" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Logs"
i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body"
triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<i-bs class="me-1" name="text-left"></i-bs><span>&nbsp;<ng-container i18n>Logs</ng-container></span>
</a>
</li>
}
</ul>
<ul class="nav flex-column">
<li class="nav-item mt-2" tourAnchor="tour.outro">
<a class="px-3 py-2 text-muted small d-flex align-items-center flex-wrap text-decoration-none"
target="_blank" rel="noopener noreferrer" href="https://docs.paperless-ngx.com" ngbPopover="Documentation"
i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body"
triggers="mouseenter:mouseleave" popoverClass="popover-slim"> triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<i-bs class="d-flex" name="question-circle"></i-bs><span class="ms-1">&nbsp;<ng-container i18n>Documentation</ng-container></span> <i-bs class="me-1" name="text-left"></i-bs><span>&nbsp;<ng-container i18n>Logs</ng-container></span>
</a> </a>
</li> </li>
<li class="nav-item" [class.visually-hidden]="slimSidebarEnabled"> }
<div class="px-3 py-0 text-muted small d-flex align-items-center flex-wrap"> <li class="nav-item mt-2" tourAnchor="tour.outro">
<div class="me-3"> <a class="px-3 py-2 text-muted small d-flex align-items-center flex-wrap text-decoration-none"
<a class="text-muted text-decoration-none" target="_blank" rel="noopener noreferrer" target="_blank" rel="noopener noreferrer" href="https://docs.paperless-ngx.com" ngbPopover="Documentation"
href="https://github.com/paperless-ngx/paperless-ngx" ngbPopover="GitHub" i18n-ngbPopover i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body"
[disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
triggers="mouseenter:mouseleave" popoverClass="popover-slim"> <i-bs class="d-flex" name="question-circle"></i-bs><span class="ms-1">&nbsp;<ng-container i18n>Documentation</ng-container></span>
{{ versionString }} </a>
</a> </li>
</div> <li class="nav-item" [class.visually-hidden]="slimSidebarEnabled">
@if (!settingsService.updateCheckingIsSet || appRemoteVersion) { <div class="px-3 py-0 text-muted small d-flex align-items-center flex-wrap">
<div class="version-check"> <div class="me-3">
<ng-template #updateAvailablePopContent> <a class="text-muted text-decoration-none" target="_blank" rel="noopener noreferrer"
<span class="small">Paperless-ngx {{ appRemoteVersion.version }} <ng-container i18n>is href="https://github.com/paperless-ngx/paperless-ngx" ngbPopover="GitHub" i18n-ngbPopover
available.</ng-container><br /><ng-container i18n>Click to view.</ng-container></span> [disablePopover]="!slimSidebarEnabled" placement="end" container="body"
</ng-template> triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<ng-template #updateCheckingNotEnabledPopContent> {{ versionString }}
<p class="small mb-2"> </a>
<ng-container i18n>Paperless-ngx can automatically check for updates</ng-container> </div>
</p> @if (!settingsService.updateCheckingIsSet || appRemoteVersion) {
<div class="btn-group btn-group-xs flex-fill w-100"> <div class="version-check">
<button class="btn btn-outline-primary" (click)="setUpdateChecking(true)">Enable</button> <ng-template #updateAvailablePopContent>
<button class="btn btn-outline-secondary" (click)="setUpdateChecking(false)">Disable</button> <span class="small">Paperless-ngx {{ appRemoteVersion.version }} <ng-container i18n>is
</div> available.</ng-container><br /><ng-container i18n>Click to view.</ng-container></span>
<p class="small mb-0 mt-2"> </ng-template>
<a class="small text-decoration-none fst-italic" routerLink="/settings" fragment="update-checking" i18n> <ng-template #updateCheckingNotEnabledPopContent>
How does this work? <p class="small mb-2">
</a> <ng-container i18n>Paperless-ngx can automatically check for updates</ng-container>
</p> </p>
</ng-template> <div class="btn-group btn-group-xs flex-fill w-100">
@if (settingsService.updateCheckingIsSet) { <button class="btn btn-outline-primary" (click)="setUpdateChecking(true)">Enable</button>
@if (appRemoteVersion.update_available) { <button class="btn btn-outline-secondary" (click)="setUpdateChecking(false)">Disable</button>
<a class="small text-decoration-none" target="_blank" rel="noopener noreferrer" </div>
href="https://github.com/paperless-ngx/paperless-ngx/releases" <p class="small mb-0 mt-2">
[ngbPopover]="updateAvailablePopContent" popoverClass="shadow" triggers="mouseenter:mouseleave" <a class="small text-decoration-none fst-italic" routerLink="/settings" fragment="update-checking" i18n>
container="body"> How does this work?
<i-bs width="1.2em" height="1.2em" name="info-circle"></i-bs> </a>
@if (appRemoteVersion?.update_available) { </p>
&nbsp;<ng-container i18n>Update available</ng-container> </ng-template>
} @if (settingsService.updateCheckingIsSet) {
</a> @if (appRemoteVersion.update_available) {
} <a class="small text-decoration-none" target="_blank" rel="noopener noreferrer"
} @else { href="https://github.com/paperless-ngx/paperless-ngx/releases"
<a *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.UISettings }" class="small text-decoration-none" routerLink="/settings" fragment="update-checking" [ngbPopover]="updateAvailablePopContent" popoverClass="shadow" triggers="mouseenter:mouseleave"
[ngbPopover]="updateCheckingNotEnabledPopContent" popoverClass="shadow" triggers="mouseenter"
container="body"> container="body">
<i-bs width="1.2em" height="1.2em" name="info-circle"></i-bs> <i-bs width="1.2em" height="1.2em" name="info-circle"></i-bs>
@if (appRemoteVersion?.update_available) {
&nbsp;<ng-container i18n>Update available</ng-container>
}
</a> </a>
} }
</div> } @else {
} <a *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.UISettings }" class="small text-decoration-none" routerLink="/settings" fragment="update-checking"
</div> [ngbPopover]="updateCheckingNotEnabledPopContent" popoverClass="shadow" triggers="mouseenter"
</li> container="body">
</ul> <i-bs width="1.2em" height="1.2em" name="info-circle"></i-bs>
</div> </a>
}
</div>
}
</div>
</li>
</ul>
</div> </div>
</div> </div>
</nav> </nav>

View File

@@ -78,8 +78,6 @@ export class AppFrameComponent
appRemoteVersion: AppRemoteVersion appRemoteVersion: AppRemoteVersion
isMenuCollapsed: boolean = true isMenuCollapsed: boolean = true
isManageMenuCollapsed: boolean = false
isAdminMenuCollapsed: boolean = false
slimSidebarAnimating: boolean = false slimSidebarAnimating: boolean = false

View File

@@ -55,8 +55,6 @@ import {
checkLg, checkLg,
chevronDoubleLeft, chevronDoubleLeft,
chevronDoubleRight, chevronDoubleRight,
chevronDown,
chevronUp,
clipboard, clipboard,
clipboardCheck, clipboardCheck,
clipboardCheckFill, clipboardCheckFill,
@@ -262,8 +260,6 @@ const icons = {
checkAll, checkAll,
checkCircleFill, checkCircleFill,
checkLg, checkLg,
chevronDown,
chevronUp,
chevronDoubleLeft, chevronDoubleLeft,
chevronDoubleRight, chevronDoubleRight,
clipboard, clipboard,

View File

@@ -0,0 +1,24 @@
# Generated by Django 5.1.8 on 2025-06-19 09:33
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1068_alter_document_created"),
]
operations = [
migrations.AlterField(
model_name="paperlesstask",
name="task_id",
field=models.CharField(
db_index=True,
help_text="Celery ID for the Task that was run",
max_length=255,
unique=True,
verbose_name="Task ID",
),
),
]

View File

@@ -545,6 +545,7 @@ class PaperlessTask(ModelWithOwner):
INDEX_OPTIMIZE = ("index_optimize", _("Index Optimize")) INDEX_OPTIMIZE = ("index_optimize", _("Index Optimize"))
task_id = models.CharField( task_id = models.CharField(
db_index=True,
max_length=255, max_length=255,
unique=True, unique=True,
verbose_name=_("Task ID"), verbose_name=_("Task ID"),