Fix: deselect and trigger refresh for deleted documents from bulk operations with "delete originals" (#8996)

This commit is contained in:
shamoon
2025-02-06 16:47:50 -08:00
committed by GitHub
parent 046d8456e2
commit 52ab07c673
24 changed files with 897 additions and 664 deletions

View File

@@ -33,14 +33,14 @@ import { PermissionsGuard } from 'src/app/guards/permissions.guard'
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
import { SafeUrlPipe } from 'src/app/pipes/safeurl.pipe'
import {
ConsumerStatusService,
FileStatus,
} from 'src/app/services/consumer-status.service'
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
import { PermissionsService } from 'src/app/services/permissions.service'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { DocumentService } from 'src/app/services/rest/document.service'
import {
FileStatus,
WebsocketStatusService,
} from 'src/app/services/websocket-status.service'
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
import { SavedViewWidgetComponent } from './saved-view-widget.component'
@@ -112,7 +112,7 @@ describe('SavedViewWidgetComponent', () => {
let component: SavedViewWidgetComponent
let fixture: ComponentFixture<SavedViewWidgetComponent>
let documentService: DocumentService
let consumerStatusService: ConsumerStatusService
let websocketStatusService: WebsocketStatusService
let documentListViewService: DocumentListViewService
let router: Router
@@ -176,7 +176,7 @@ describe('SavedViewWidgetComponent', () => {
}).compileComponents()
documentService = TestBed.inject(DocumentService)
consumerStatusService = TestBed.inject(ConsumerStatusService)
websocketStatusService = TestBed.inject(WebsocketStatusService)
documentListViewService = TestBed.inject(DocumentListViewService)
router = TestBed.inject(Router)
fixture = TestBed.createComponent(SavedViewWidgetComponent)
@@ -235,7 +235,7 @@ describe('SavedViewWidgetComponent', () => {
it('should reload on document consumption finished', () => {
const fileStatusSubject = new Subject<FileStatus>()
jest
.spyOn(consumerStatusService, 'onDocumentConsumptionFinished')
.spyOn(websocketStatusService, 'onDocumentConsumptionFinished')
.mockReturnValue(fileStatusSubject)
const reloadSpy = jest.spyOn(component, 'reload')
component.ngOnInit()

View File

@@ -42,7 +42,6 @@ import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
import { DocumentTypeNamePipe } from 'src/app/pipes/document-type-name.pipe'
import { StoragePathNamePipe } from 'src/app/pipes/storage-path-name.pipe'
import { UsernamePipe } from 'src/app/pipes/username.pipe'
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
import {
@@ -53,6 +52,7 @@ import {
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { DocumentService } from 'src/app/services/rest/document.service'
import { SettingsService } from 'src/app/services/settings.service'
import { WebsocketStatusService } from 'src/app/services/websocket-status.service'
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
@Component({
@@ -94,7 +94,7 @@ export class SavedViewWidgetComponent
private documentService: DocumentService,
private router: Router,
private list: DocumentListViewService,
private consumerStatusService: ConsumerStatusService,
private websocketStatusService: WebsocketStatusService,
public openDocumentsService: OpenDocumentsService,
public documentListViewService: DocumentListViewService,
public permissionsService: PermissionsService,
@@ -124,7 +124,7 @@ export class SavedViewWidgetComponent
ngOnInit(): void {
this.reload()
this.displayMode = this.savedView.display_mode ?? DisplayMode.TABLE
this.consumerStatusService
this.websocketStatusService
.onDocumentConsumptionFinished()
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(() => {

View File

@@ -12,9 +12,9 @@ import { routes } from 'src/app/app-routing.module'
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
import {
ConsumerStatusService,
FileStatus,
} from 'src/app/services/consumer-status.service'
WebsocketStatusService,
} from 'src/app/services/websocket-status.service'
import { environment } from 'src/environments/environment'
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
import { StatisticsWidgetComponent } from './statistics-widget.component'
@@ -23,7 +23,7 @@ describe('StatisticsWidgetComponent', () => {
let component: StatisticsWidgetComponent
let fixture: ComponentFixture<StatisticsWidgetComponent>
let httpTestingController: HttpTestingController
let consumerStatusService: ConsumerStatusService
let websocketStatusService: WebsocketStatusService
const fileStatusSubject = new Subject<FileStatus>()
beforeEach(async () => {
@@ -44,9 +44,9 @@ describe('StatisticsWidgetComponent', () => {
}).compileComponents()
fixture = TestBed.createComponent(StatisticsWidgetComponent)
consumerStatusService = TestBed.inject(ConsumerStatusService)
websocketStatusService = TestBed.inject(WebsocketStatusService)
jest
.spyOn(consumerStatusService, 'onDocumentConsumptionFinished')
.spyOn(websocketStatusService, 'onDocumentConsumptionFinished')
.mockReturnValue(fileStatusSubject)
component = fixture.componentInstance

View File

@@ -8,8 +8,8 @@ import { first, Subject, Subscription, takeUntil } from 'rxjs'
import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
import { FILTER_HAS_TAGS_ANY } from 'src/app/data/filter-rule-type'
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
import { WebsocketStatusService } from 'src/app/services/websocket-status.service'
import { environment } from 'src/environments/environment'
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
@@ -51,7 +51,7 @@ export class StatisticsWidgetComponent
constructor(
private http: HttpClient,
private consumerStatusService: ConsumerStatusService,
private websocketConnectionService: WebsocketStatusService,
private documentListViewService: DocumentListViewService
) {
super()
@@ -109,7 +109,7 @@ export class StatisticsWidgetComponent
ngOnInit(): void {
this.reload()
this.subscription = this.consumerStatusService
this.subscription = this.websocketConnectionService
.onDocumentConsumptionFinished()
.subscribe(() => {
this.reload()

View File

@@ -12,13 +12,13 @@ import { NgbAlert, NgbCollapse } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { routes } from 'src/app/app-routing.module'
import { PermissionsGuard } from 'src/app/guards/permissions.guard'
import {
ConsumerStatusService,
FileStatus,
FileStatusPhase,
} from 'src/app/services/consumer-status.service'
import { PermissionsService } from 'src/app/services/permissions.service'
import { UploadDocumentsService } from 'src/app/services/upload-documents.service'
import {
FileStatus,
FileStatusPhase,
WebsocketStatusService,
} from 'src/app/services/websocket-status.service'
import { UploadFileWidgetComponent } from './upload-file-widget.component'
const FAILED_STATUSES = [new FileStatus()]
@@ -42,7 +42,7 @@ const DEFAULT_STATUSES = [
describe('UploadFileWidgetComponent', () => {
let component: UploadFileWidgetComponent
let fixture: ComponentFixture<UploadFileWidgetComponent>
let consumerStatusService: ConsumerStatusService
let websocketStatusService: WebsocketStatusService
let uploadDocumentsService: UploadDocumentsService
beforeEach(async () => {
@@ -65,7 +65,7 @@ describe('UploadFileWidgetComponent', () => {
],
}).compileComponents()
consumerStatusService = TestBed.inject(ConsumerStatusService)
websocketStatusService = TestBed.inject(WebsocketStatusService)
uploadDocumentsService = TestBed.inject(UploadDocumentsService)
fixture = TestBed.createComponent(UploadFileWidgetComponent)
component = fixture.componentInstance
@@ -91,14 +91,14 @@ describe('UploadFileWidgetComponent', () => {
})
it('should generate stats summary', () => {
mockConsumerStatuses(consumerStatusService)
mockConsumerStatuses(websocketStatusService)
expect(component.getStatusSummary()).toEqual(
'Processing: 6, Failed: 1, Added: 4'
)
})
it('should report an upload progress summary', () => {
mockConsumerStatuses(consumerStatusService)
mockConsumerStatuses(websocketStatusService)
expect(component.getTotalUploadProgress()).toEqual(0.75)
})
@@ -117,7 +117,7 @@ describe('UploadFileWidgetComponent', () => {
})
it('should enforce a maximum number of alerts', () => {
mockConsumerStatuses(consumerStatusService)
mockConsumerStatuses(websocketStatusService)
fixture.detectChanges()
// 5 total, 1 hidden
expect(fixture.debugElement.queryAll(By.directive(NgbAlert))).toHaveLength(
@@ -131,19 +131,19 @@ describe('UploadFileWidgetComponent', () => {
})
it('should allow dismissing an alert', () => {
const dismissSpy = jest.spyOn(consumerStatusService, 'dismiss')
const dismissSpy = jest.spyOn(websocketStatusService, 'dismiss')
component.dismiss(new FileStatus())
expect(dismissSpy).toHaveBeenCalled()
})
it('should allow dismissing completed alerts', fakeAsync(() => {
mockConsumerStatuses(consumerStatusService)
mockConsumerStatuses(websocketStatusService)
component.alertsExpanded = true
fixture.detectChanges()
jest
.spyOn(component, 'getStatusCompleted')
.mockImplementation(() => SUCCESS_STATUSES)
const dismissSpy = jest.spyOn(consumerStatusService, 'dismiss')
const dismissSpy = jest.spyOn(websocketStatusService, 'dismiss')
component.dismissCompleted()
tick(1000)
fixture.detectChanges()

View File

@@ -12,13 +12,13 @@ import { TourNgBootstrapModule } from 'ngx-ui-tour-ng-bootstrap'
import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
import {
ConsumerStatusService,
FileStatus,
FileStatusPhase,
} from 'src/app/services/consumer-status.service'
import { SettingsService } from 'src/app/services/settings.service'
import { UploadDocumentsService } from 'src/app/services/upload-documents.service'
import {
FileStatus,
FileStatusPhase,
WebsocketStatusService,
} from 'src/app/services/websocket-status.service'
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
const MAX_ALERTS = 5
@@ -46,7 +46,7 @@ export class UploadFileWidgetComponent extends ComponentWithPermissions {
@ViewChildren(NgbAlert) alerts: QueryList<NgbAlert>
constructor(
private consumerStatusService: ConsumerStatusService,
private websocketStatusService: WebsocketStatusService,
private uploadDocumentsService: UploadDocumentsService,
public settingsService: SettingsService
) {
@@ -54,13 +54,13 @@ export class UploadFileWidgetComponent extends ComponentWithPermissions {
}
getStatus() {
return this.consumerStatusService.getConsumerStatus().slice(0, MAX_ALERTS)
return this.websocketStatusService.getConsumerStatus().slice(0, MAX_ALERTS)
}
getStatusSummary() {
let strings = []
let countUploadingAndProcessing =
this.consumerStatusService.getConsumerStatusNotCompleted().length
this.websocketStatusService.getConsumerStatusNotCompleted().length
let countFailed = this.getStatusFailed().length
let countSuccess = this.getStatusSuccess().length
if (countUploadingAndProcessing > 0) {
@@ -78,27 +78,30 @@ export class UploadFileWidgetComponent extends ComponentWithPermissions {
}
getStatusHidden() {
if (this.consumerStatusService.getConsumerStatus().length < MAX_ALERTS)
if (this.websocketStatusService.getConsumerStatus().length < MAX_ALERTS)
return []
else return this.consumerStatusService.getConsumerStatus().slice(MAX_ALERTS)
else
return this.websocketStatusService.getConsumerStatus().slice(MAX_ALERTS)
}
getStatusUploading() {
return this.consumerStatusService.getConsumerStatus(
return this.websocketStatusService.getConsumerStatus(
FileStatusPhase.UPLOADING
)
}
getStatusFailed() {
return this.consumerStatusService.getConsumerStatus(FileStatusPhase.FAILED)
return this.websocketStatusService.getConsumerStatus(FileStatusPhase.FAILED)
}
getStatusSuccess() {
return this.consumerStatusService.getConsumerStatus(FileStatusPhase.SUCCESS)
return this.websocketStatusService.getConsumerStatus(
FileStatusPhase.SUCCESS
)
}
getStatusCompleted() {
return this.consumerStatusService.getConsumerStatusCompleted()
return this.websocketStatusService.getConsumerStatusCompleted()
}
getTotalUploadProgress() {
@@ -134,12 +137,12 @@ export class UploadFileWidgetComponent extends ComponentWithPermissions {
}
dismiss(status: FileStatus) {
this.consumerStatusService.dismiss(status)
this.websocketStatusService.dismiss(status)
}
dismissCompleted() {
this.getStatusCompleted().forEach((status) =>
this.consumerStatusService.dismiss(status)
this.websocketStatusService.dismiss(status)
)
}