diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts
index 75b049a0e..e259d489c 100644
--- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts
+++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts
@@ -23,6 +23,8 @@ import { Subscription, timer } from 'rxjs';
import { tap } from 'rxjs/operators';
import { RedactionFilterSorter } from '../../common/sorters/redaction-filter-sorter';
import { StatusSorter } from '../../common/sorters/status-sorter';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { debounce } from '../../utils/debounce';
@Component({
selector: 'redaction-project-overview-screen',
@@ -35,6 +37,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
public peopleFilters: FilterModel[];
public needsWorkFilters: FilterModel[];
public collapsedDetails = false;
+ public searchForm: FormGroup;
displayedFiles: FileStatusWrapper[] = [];
@@ -61,8 +64,15 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
private readonly _router: Router,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _translateService: TranslateService,
- private readonly _fileDropOverlayService: FileDropOverlayService
+ private readonly _fileDropOverlayService: FileDropOverlayService,
+ private readonly _formBuilder: FormBuilder
) {
+ this.searchForm = this._formBuilder.group({
+ query: ['']
+ });
+
+ this.searchForm.valueChanges.subscribe((value) => this._executeSearch(value));
+
this._activatedRoute.params.subscribe((params) => {
this.appStateService.activateProject(params.projectId);
});
@@ -89,6 +99,12 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
this.filesAutoUpdateTimer.unsubscribe();
}
+ @debounce(200)
+ private _executeSearch(value: { query: string }) {
+ this.displayedFiles = this._filteredFiles.filter((file) => file.filename.toLowerCase().includes(value.query.toLowerCase()));
+ this.selectedFileIds = this.displayedFiles.map((d) => d.fileId).filter((x) => this.selectedFileIds.includes(x));
+ }
+
get displayReanalyseBtn() {
return !!(
this.permissionsService.isManagerAndOwner() &&
@@ -263,7 +279,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
: [];
}
- private _filterFiles() {
+ private get _filteredFiles(): FileStatusWrapper[] {
const filters = [
{ values: this.statusFilters, checker: keyChecker('status') },
{ values: this.peopleFilters, checker: keyChecker('currentReviewer') },
@@ -274,7 +290,11 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
checkerArgs: this.permissionsService
}
];
- this.displayedFiles = getFilteredEntities(this.appStateService.activeProject.files, filters);
+ return getFilteredEntities(this.appStateService.activeProject.files, filters);
+ }
+
+ private _filterFiles() {
+ this.displayedFiles = this._filteredFiles.filter((file) => file.filename.toLowerCase().includes(this.searchForm.get('query').value.toLowerCase()));
this.selectedFileIds = this.displayedFiles.map((d) => d.fileId).filter((x) => this.selectedFileIds.includes(x));
this.detailsContainerFilters = {
needsWorkFilters: this.needsWorkFilters.map((f) => ({ ...f })),
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index 60cd5cfcd..6b769f02e 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -69,6 +69,7 @@
"action": "Download Redaction Report"
},
"project-listing": {
+ "search": "Project name...",
"reanalyse": {
"action": "Reanalyse entire project"
},
@@ -146,6 +147,7 @@
"collapse": "Hide Details"
},
"project-overview": {
+ "search": "Document name...",
"header-actions": {
"edit": "Edit",
"delete": "Delete",
diff --git a/apps/red-ui/src/assets/icons/general/search-viewer.svg b/apps/red-ui/src/assets/icons/general/search-viewer.svg
deleted file mode 100644
index 9fdd792d5..000000000
--- a/apps/red-ui/src/assets/icons/general/search-viewer.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
diff --git a/apps/red-ui/src/assets/icons/general/search.svg b/apps/red-ui/src/assets/icons/general/search.svg
new file mode 100644
index 000000000..f0fc5c809
--- /dev/null
+++ b/apps/red-ui/src/assets/icons/general/search.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/apps/red-ui/src/assets/styles/red-input.scss b/apps/red-ui/src/assets/styles/red-input.scss
index 5424f52e4..52a79db9d 100644
--- a/apps/red-ui/src/assets/styles/red-input.scss
+++ b/apps/red-ui/src/assets/styles/red-input.scss
@@ -5,6 +5,7 @@
display: flex;
flex-direction: column;
margin-top: 13px;
+ position: relative;
.mat-form-field-underline {
display: none;
@@ -20,6 +21,14 @@
margin-top: 0;
}
+ .icon-right {
+ width: 14px;
+ height: 14px;
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ }
+
input,
textarea,
mat-select {
@@ -36,6 +45,10 @@
margin-top: 3px;
min-height: 34px;
+ &.with-icon {
+ padding-right: 34px;
+ }
+
&:focus {
border-color: $grey-1;
}
diff --git a/apps/red-ui/src/assets/styles/red-page-layout.scss b/apps/red-ui/src/assets/styles/red-page-layout.scss
index 5adeaa5eb..de52c2284 100644
--- a/apps/red-ui/src/assets/styles/red-page-layout.scss
+++ b/apps/red-ui/src/assets/styles/red-page-layout.scss
@@ -29,9 +29,22 @@ body {
gap: 2px;
display: flex;
align-items: center;
+
> div:first-child {
margin-right: 6px;
}
+
+ form {
+ margin-left: 6px;
+
+ .red-input-group {
+ width: 250px;
+
+ input {
+ margin-top: 0;
+ }
+ }
+ }
}
.actions {