This repository has been archived by the owner on Feb 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 353
Feature: merge tool UI #789
Merged
jonaswinkler
merged 63 commits into
jonaswinkler:feature-merge-tool
from
shamoon:feature/merge-tool-ui
Apr 3, 2021
Merged
Changes from 53 commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
eb7b767
Basic button for initiating split/merge from bulk editor
shamoon 321fad0
Basic drag-n-drop
shamoon 9e6cb1b
Basic layout elements, loading spinner
shamoon 6a3ad77
Skeleton UI for buttons
shamoon 8e330fc
Basic live preview
shamoon 58cb42b
Typescript
shamoon 7746ab4
Basic document chooser
shamoon 87d969f
Basic action buttons
shamoon 4a61608
Naming
shamoon 274df28
Spacer styling
shamoon 7cbb505
Basic duplicate & delete
shamoon 8d0ac69
Basic page chooser component
shamoon ea34283
Basic mode toggling
shamoon bb872ab
Tooltip, random styling stuff
shamoon ce19525
Change icons
shamoon 86ca379
Basic page support
shamoon 37c0fa4
Merge branch 'feature-merge-tool' into feature/merge-tool-ui
shamoon b8fabb6
InputDebounce component for page fields
shamoon 33ddd03
Allow additional classes for input-debounce & fix field display
shamoon 35f9989
Allow input-debounce input
shamoon 73c80c3
Page field formatting
shamoon d88cd05
Allow empty pages field
shamoon baae3c2
Allow removing last document
shamoon 746c03c
Remove 'mode' concept, basic split UI, many visual changes
shamoon cfc0925
Split support including tabbed previews
shamoon af1034f
Visual reorganization
shamoon 3c25595
Separator styling
shamoon 20b95fb
Disable page chooser button if no page chosen
shamoon 14116c8
Hide preview after all documents removed
shamoon 24d07fc
Missing handle
shamoon 38d8b34
Clear pages button
shamoon 7df9e1f
Translation stuff
shamoon cf5747f
Toggle for source document handling
shamoon aaa913f
Options popover
shamoon e0a1ba5
Typescript fixes
shamoon 63b4c33
Metadata options & source options merged into options popover panel
shamoon a5de83f
Better clear button
shamoon 88bf679
Unified button toolbar
shamoon 142c2ac
Sanitize pages input
shamoon c07bbcb
No return type on setter
shamoon c18180f
Remove debug stuff
shamoon 4ddd031
Slightly increasing button spacing on cards
shamoon c5ae337
Basic error handling
shamoon 9713923
Dont allow separator at the end of document parts list
shamoon 66aee14
Light mode fixes, styling tweaks
shamoon 484edce
Split button should respect pre-selected pages
shamoon cc3c7ad
Apply danger on delete toggle to entire label
shamoon ae60fc8
Fix popover shadow
shamoon 7203182
Preview page numbers
shamoon e957d9a
Changes missed from last commit, enables page numbers in previews
shamoon b4db388
Dont initialize page number until page is rendered
shamoon e0231a4
Dont allow separator at start of document
shamoon 846a997
Better button responsive layout
shamoon b07537a
Merge branch 'feature-merge-tool' into feature/merge-tool-ui
shamoon caa9a34
Increase height of dropzone
shamoon e328c43
Change to 5/7 column width layout
shamoon f07fb6e
Fix tabs in light mode
shamoon 3915149
Remove separators from first / last position when dragged
shamoon 6f3c72e
Fix options text color not visible in light mode
shamoon 9502917
Fix overhang of separator background
shamoon 2b4a0ef
Move add to split merge directly into bulk editor
shamoon cc5b7eb
Center preview title when empty
shamoon 99bde7b
Dont import entire dark mode theme just for 1 color
shamoon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
src-ui/src/app/components/common/document-chooser/document-chooser.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<div class="modal-header"> | ||
<h4 class="modal-title" id="modal-basic-title" i18n>Choose Documents</h4> | ||
<button type="button" class="close" aria-label="Close" (click)="cancelClicked()"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
<div class="modal-body"> | ||
<div class="m-n2 row row-cols-paperless-cards"> | ||
<app-document-card-small [simpleCard]="true" [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" [document]="d" *ngFor="let d of list.documents"></app-document-card-small> | ||
</div> | ||
</div> | ||
<div class="modal-footer"> | ||
<button type="button" class="btn btn-outline-danger" (click)="cancelClicked()" i18n>Cancel</button> | ||
<button type="button" class="btn btn-outline-primary" [disabled]="list.selected.size == 0" (click)="confirmClicked.emit()" i18n>Add Selected</button> | ||
</div> |
28 changes: 28 additions & 0 deletions
28
src-ui/src/app/components/common/document-chooser/document-chooser.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
@import "/src/theme"; | ||
|
||
.modal-body { | ||
max-height: 70vh; | ||
overflow-y: scroll; | ||
} | ||
|
||
$paperless-card-breakpoints: ( | ||
0: 2, // xs | ||
768px: 3, //md | ||
992px: 4, //lg | ||
1200px: 5, //xl | ||
1400px: 6, // xxl | ||
1600px: 7, | ||
1800px: 8, | ||
2000px: 9 | ||
); | ||
|
||
.row-cols-paperless-cards { | ||
@each $width, $n_cols in $paperless-card-breakpoints { | ||
@media(min-width: $width) { | ||
> * { | ||
flex: 0 0 auto; | ||
width: 100% / $n_cols; | ||
} | ||
} | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src-ui/src/app/components/common/document-chooser/document-chooser.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { DocumentChooserComponent } from './document-chooser.component'; | ||
|
||
describe('DocumentChooserComponent', () => { | ||
let component: DocumentChooserComponent; | ||
let fixture: ComponentFixture<DocumentChooserComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
declarations: [ DocumentChooserComponent ] | ||
}) | ||
.compileComponents(); | ||
}); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(DocumentChooserComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
36 changes: 36 additions & 0 deletions
36
src-ui/src/app/components/common/document-chooser/document-chooser.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core'; | ||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; | ||
import { PaperlessDocument } from 'src/app/data/paperless-document'; | ||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'; | ||
|
||
@Component({ | ||
selector: 'app-document-chooser', | ||
templateUrl: './document-chooser.component.html', | ||
styleUrls: ['./document-chooser.component.scss'] | ||
}) | ||
export class DocumentChooserComponent implements OnInit { | ||
|
||
constructor( | ||
public activeModal: NgbActiveModal, | ||
public list: DocumentListViewService | ||
) { } | ||
|
||
@Output() | ||
public confirmClicked = new EventEmitter() | ||
|
||
ngOnInit(): void { | ||
this.list.selectNone() | ||
this.list.activateSavedView(null) | ||
this.list.reload() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need to do all this here? I've removed the init entirely and it feels quite natural. |
||
} | ||
|
||
cancelClicked() { | ||
this.list.selectNone() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just as with the above, I'd not rely on the document list for selection state. |
||
this.activeModal.close() | ||
} | ||
|
||
toggleSelected(d: PaperlessDocument, event: MouseEvent): void { | ||
if (!event.shiftKey) this.list.toggleSelected(d) | ||
else this.list.selectRangeTo(d) | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
src-ui/src/app/components/common/input/debounce/input-debounce.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<input type="text" [class]="cssClasses" [placeholder]="placeholder" [(ngModel)]="inputValue" (keyup)="keyUp($event)" /> | ||
<span *ngIf="allowClear && inputValue?.length > 0" class="clear-wrapper" title="Clear all" (click)="clear()"><span aria-hidden="true" class="clear">×</span></span> |
23 changes: 23 additions & 0 deletions
23
src-ui/src/app/components/common/input/debounce/input-debounce.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
.clear-wrapper { | ||
-moz-user-select: none; | ||
-ms-user-select: none; | ||
-webkit-user-select: none; | ||
cursor: pointer; | ||
position: absolute; | ||
top: 5px; | ||
right: 5px; | ||
user-select: none; | ||
width: 17px; | ||
color: #999; | ||
|
||
.clear { | ||
display: inline-block; | ||
font-size: 18px; | ||
line-height: 1; | ||
pointer-events: none; | ||
} | ||
|
||
&:hover .clear { | ||
color: #D0021B; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src-ui/src/app/components/common/input/debounce/input-debounce.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { InputDebounceComponent } from './text.component'; | ||
|
||
describe('InputDebounceComponent', () => { | ||
let component: InputDebounceComponent; | ||
let fixture: ComponentFixture<InputDebounceComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
declarations: [ InputDebounceComponent ] | ||
}) | ||
.compileComponents(); | ||
}); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(InputDebounceComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
66 changes: 66 additions & 0 deletions
66
src-ui/src/app/components/common/input/debounce/input-debounce.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { Component, Input, Output, ElementRef, EventEmitter } from '@angular/core'; | ||
import { fromEvent } from 'rxjs'; | ||
import { map, debounceTime, distinctUntilChanged } from 'rxjs/operators'; | ||
|
||
@Component({ | ||
selector: 'app-input-debounce', | ||
templateUrl: './input-debounce.component.html', | ||
styleUrls: ['./input-debounce.component.scss'] | ||
}) | ||
export class InputDebounceComponent { | ||
|
||
@Input() | ||
placeholder: string | ||
|
||
@Input() | ||
delay: number = 500 | ||
|
||
@Input() | ||
classes: string | ||
|
||
@Input() | ||
allowClear: boolean = true | ||
|
||
@Input() | ||
set pattern(regexStr: string) { | ||
this._pattern = new RegExp(regexStr) | ||
} | ||
|
||
_pattern: RegExp | ||
|
||
@Output() | ||
value: EventEmitter<string> = new EventEmitter<string>() | ||
|
||
@Input() | ||
inputValue: string; | ||
|
||
constructor(private elementRef: ElementRef) { | ||
fromEvent(elementRef.nativeElement, 'keyup').pipe( | ||
map(() => this.inputValue), | ||
debounceTime(this.delay), | ||
distinctUntilChanged() | ||
).subscribe(input => | ||
this.value.emit(input) | ||
); | ||
} | ||
|
||
keyUp(event: any) { | ||
if (!this._pattern) return | ||
if (event.key.length == 1 && !this._pattern.test(event.key)) { // e.g. dont do for backspace | ||
// invalid character, prevent input | ||
event.preventDefault() | ||
event.stopImmediatePropagation() | ||
this.inputValue = this.inputValue.slice(this.inputValue.length, 1) | ||
} | ||
} | ||
|
||
get cssClasses(): string { | ||
return 'form-control ' + this.classes | ||
} | ||
|
||
clear() { | ||
this.inputValue = '' | ||
this.value.emit(this.inputValue) | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src-ui/src/app/components/common/page-chooser/page-chooser.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<div class="modal-header"> | ||
<h4 class="modal-title" id="modal-basic-title">{{title}}: {{document.title}}</h4> | ||
<button type="button" class="close" aria-label="Close" (click)="cancelClicked()"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
<div class="modal-body"> | ||
<pdf-viewer class="page-chooser-viewer" [class.splitting]="splitting" [src]="previewUrl" [original-size]="false" [zoom]=".25" [autoresize]="true" [show-borders]="true" [show-all]="true" [render-text-mode]="2" (page-rendered)="afterPageRendered($event)" (after-load-complete)="pdfLoaded($event)"></pdf-viewer> | ||
</div> | ||
<div class="modal-footer"> | ||
<button type="button" class="btn btn-outline-danger" (click)="cancelClicked()" i18n>Cancel</button> | ||
<button type="button" class="btn btn-outline-primary" (click)="confirmClicked()" [disabled]="pages.length == 0">{{title}}</button> | ||
</div> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably do a separate selection model for the document chooser and not interfere with the list view at all.
This is also not very difficult, since there's no pagination / hidden items / filtering happenind in the chooser popup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, so to accomplish this would you basically copy the logic from the list view service e.g.
toggleSelected
,selectRangeTo
and others directly into the chooser component? Just want to make sure I understand. That would mean the code essentially duplicated in two places but yes, would no longer mess with the main list.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or another service?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right, range selection.
I'll take care of that.