diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index de0e1cb63..a924ae422 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -23,7 +23,7 @@ import { AddEditProjectDialogComponent } from './dialogs/add-edit-project-dialog import { MatDialogModule } from '@angular/material/dialog'; import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatTooltipModule } from '@angular/material/tooltip'; -import { ConfirmationDialogComponent } from './common/confirmation-dialog/confirmation-dialog.component'; +import { ConfirmationDialogComponent } from './dialogs/confirmation-dialog/confirmation-dialog.component'; import { FilePreviewScreenComponent } from './screens/file/file-preview-screen/file-preview-screen.component'; import { PdfViewerComponent } from './screens/file/pdf-viewer/pdf-viewer.component'; import { MatTabsModule } from '@angular/material/tabs'; diff --git a/apps/red-ui/src/app/components/team-members/team-members.component.html b/apps/red-ui/src/app/components/team-members/team-members.component.html index b7b2ec4db..817338b65 100644 --- a/apps/red-ui/src/app/components/team-members/team-members.component.html +++ b/apps/red-ui/src/app/components/team-members/team-members.component.html @@ -1,15 +1,25 @@ -
-
+
+
+
+ +
-
+
+{{ overflowCount }}
(); + + @ViewChild('container', { static: true }) container: ElementRef; public expandedTeam = false; @@ -16,8 +22,15 @@ export class TeamMembersComponent implements OnInit { ngOnInit(): void {} + public get maxTeamMembersBeforeExpand(): number { + const width = this.container.nativeElement.offsetWidth; + // 32px element width + margin right (2px or 12px) + const elementWidth = this.largeSpacing ? 46 : 34; + return Math.floor(width / elementWidth) - (this.canAdd ? 1 : 0); + } + public get displayedMembers(): string[] { - return this.expandedTeam || !this.overflowCount ? this.memberIds : this.memberIds.slice(0, 7); + return this.expandedTeam || !this.overflowCount ? this.memberIds : this.memberIds.slice(0, this.maxTeamMembersBeforeExpand - 1); } public toggleExpandedTeam() { @@ -25,6 +38,6 @@ export class TeamMembersComponent implements OnInit { } public get overflowCount() { - return this.memberIds.length > 8 ? this.memberIds.length - 7 : 0; + return this.memberIds.length > this.maxTeamMembersBeforeExpand ? this.memberIds.length - (this.maxTeamMembersBeforeExpand - 1) : 0; } } diff --git a/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.html b/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.html index 1ed555c90..c964cc9b6 100644 --- a/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.html +++ b/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.html @@ -44,7 +44,5 @@
- + diff --git a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.html b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.html index 83c55d073..c787272c3 100644 --- a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.html +++ b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.html @@ -1,48 +1,57 @@
-
+
- {{ - 'assign-' + data.type + '-owner.dialog.single-user' | translate - }} + {{ 'assign-' + data.type + '-owner.dialog.single-user' | translate }} - - {{ userService.getNameForId(userId) }} - - - -
-
- - {{ - 'assign-' + data.type + '-owner.dialog.multi-user' | translate - }} - - + {{ userService.getNameForId(userId) }}
+ +
+ + +
+ + +
+ +
+
+ + + +
+
+
- + +
- +
diff --git a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.scss b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.scss index f11829a84..27860197e 100644 --- a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.scss +++ b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.scss @@ -1,3 +1,67 @@ -.red-input-group { - max-width: 200px; +@import '../../../assets/styles/red-mixins'; + +.search-container { + width: 560px; + margin-top: 16px; +} + +.members-list { + max-height: 220px; + height: 220px; + margin-top: 16px; + overflow-y: hidden; + width: 587px; + + &:hover { + overflow-y: auto; + @include scroll-bar; + } + + > div { + margin-bottom: 2px; + padding: 3px 5px; + border-radius: 4px; + cursor: pointer; + position: relative; + transition: background-color ease-in-out 0.1s; + width: 560px; + box-sizing: border-box; + + mat-icon { + display: none; + position: absolute; + right: 13px; + top: 12px; + width: 14px; + height: 14px; + } + + &.selected { + background-color: $green-2; + + mat-icon.add { + display: initial; + } + } + + &:hover { + background-color: $grey-2; + + &.selected { + mat-icon.remove { + display: initial; + } + + mat-icon.add { + display: none; + } + } + + &:not(.selected) { + mat-icon.add { + display: initial; + } + } + } + } } diff --git a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts index 9b6a0e4da..f486f9186 100644 --- a/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts +++ b/apps/red-ui/src/app/dialogs/assign-owner-dialog/assign-owner-dialog.component.ts @@ -1,15 +1,16 @@ import { Component, Inject } from '@angular/core'; -import { Project, ProjectControllerService, StatusControllerService } from '@redaction/red-ui-http'; +import { ProjectControllerService, StatusControllerService } from '@redaction/red-ui-http'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { AppStateService } from '../../state/app-state.service'; import { UserService } from '../../user/user.service'; import { NotificationService, NotificationType } from '../../notification/notification.service'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FileStatusWrapper } from '../../screens/file/model/file-status.wrapper'; +import { ProjectWrapper } from '../../state/model/project.wrapper'; class DialogData { type: 'file' | 'project'; - project?: Project; + project?: ProjectWrapper; files?: FileStatusWrapper[]; } @@ -19,7 +20,8 @@ class DialogData { styleUrls: ['./assign-owner-dialog.component.scss'] }) export class AssignOwnerDialogComponent { - usersForm: FormGroup; + public usersForm: FormGroup; + public searchForm: FormGroup; constructor( public readonly userService: UserService, @@ -39,7 +41,10 @@ export class AssignOwnerDialogComponent { const project = this.data.project; this.usersForm = this._formBuilder.group({ singleUser: [project?.ownerId, Validators.required], - userList: [project?.memberIds] + userList: [[...project?.memberIds]] + }); + this.searchForm = this._formBuilder.group({ + query: [''] }); } @@ -57,22 +62,30 @@ export class AssignOwnerDialogComponent { } } + public get selectedSingleUser(): string { + return this.usersForm.get('singleUser').value; + } + + public get selectedUserList(): string[] { + return this.usersForm.get('userList').value; + } + async saveUsers() { try { if (this.data.type === 'project') { - const ownerId = this.usersForm.get('singleUser').value; - const memberIds = this.usersForm.get('userList').value; - const project = Object.assign({}, this.data.project); - project.memberIds = memberIds; - project.ownerId = ownerId; - await this._appStateService.addOrUpdateProject(project); + const ownerId = this.selectedSingleUser; + const memberIds = this.selectedUserList; + const pw = Object.assign({}, this.data.project); + pw.project.memberIds = memberIds; + pw.project.ownerId = ownerId; + await this._appStateService.addOrUpdateProject(pw.project); this._notificationService.showToastNotification( - 'Successfully assigned ' + this.userService.getNameForId(ownerId) + ' to project: ' + project.projectName + 'Successfully assigned ' + this.userService.getNameForId(ownerId) + ' to project: ' + pw.project.projectName ); } if (this.data.type === 'file') { - const reviewerId = this.usersForm.get('singleUser').value; + const reviewerId = this.selectedSingleUser; const promises = this.data.files.map((file) => this._statusControllerService.assignProjectOwner(this._appStateService.activeProjectId, file.fileId, reviewerId).toPromise() @@ -95,10 +108,57 @@ export class AssignOwnerDialogComponent { } get singleUsersSelectOptions() { - return this.data.type === 'file' ? this._appStateService.activeProject.project.memberIds : this.userService.managerUsers.map((m) => m.userId); + return this.data.type === 'file' ? this._appStateService.activeProject.memberIds : this.userService.managerUsers.map((m) => m.userId); } get multiUsersSelectOptions() { - return this.userService.eligibleUsers.map((m) => m.userId); + const searchQuery = this.searchForm.get('query').value; + return this.userService.eligibleUsers + .filter((user) => this.userService.getNameForId(user.userId).toLowerCase().includes(searchQuery.toLowerCase())) + .map((user) => user.userId); + } + + public isMemberSelected(userId: string): boolean { + return this.selectedUserList.indexOf(userId) !== -1; + } + + public toggleSelected(userId: string) { + if (this.isMemberSelected(userId)) { + const idx = this.selectedUserList.indexOf(userId); + this.selectedUserList.splice(idx, 1); + } else { + this.selectedUserList.push(userId); + } + } + + public get changed(): boolean { + if (this.data.type === 'project') { + if (this.data.project.ownerId !== this.selectedSingleUser) { + return true; + } + + const initial = this.data.project.memberIds.sort(); + const current = this.selectedUserList.sort(); + + if (initial.length !== current.length) { + return true; + } + + for (let idx = 0; idx < initial.length; ++idx) { + if (initial[idx] !== current[idx]) { + return true; + } + } + } else if (this.data.type === 'file') { + const reviewerId = this.selectedSingleUser; + + for (const file of this.data.files) { + if (file.currentReviewer !== reviewerId) { + return true; + } + } + } + + return false; } } diff --git a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.html b/apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.html similarity index 78% rename from apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.html rename to apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.html index a2c0d6dd9..8e8451696 100644 --- a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.html +++ b/apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.html @@ -6,15 +6,13 @@
- -
- + diff --git a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.scss b/apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.scss similarity index 100% rename from apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.scss rename to apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.scss diff --git a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.ts b/apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.ts similarity index 93% rename from apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.ts rename to apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.ts index bd3896fee..c5761b8f7 100644 --- a/apps/red-ui/src/app/common/confirmation-dialog/confirmation-dialog.component.ts +++ b/apps/red-ui/src/app/dialogs/confirmation-dialog/confirmation-dialog.component.ts @@ -11,8 +11,7 @@ export class ConfirmationDialogInput { constructor(options: ConfirmationDialogInput) { this.title = options.title || ConfirmationDialogInput.default().title; this.question = options.question || ConfirmationDialogInput.default().question; - this.confirmationText = - options.confirmationText || ConfirmationDialogInput.default().confirmationText; + this.confirmationText = options.confirmationText || ConfirmationDialogInput.default().confirmationText; this.denyText = options.denyText || ConfirmationDialogInput.default().denyText; } diff --git a/apps/red-ui/src/app/dialogs/dialog.service.ts b/apps/red-ui/src/app/dialogs/dialog.service.ts index 5d3b05588..5fc08a369 100644 --- a/apps/red-ui/src/app/dialogs/dialog.service.ts +++ b/apps/red-ui/src/app/dialogs/dialog.service.ts @@ -9,7 +9,7 @@ import { TypeValue, DictionaryControllerService } from '@redaction/red-ui-http'; -import { ConfirmationDialogComponent, ConfirmationDialogInput } from '../common/confirmation-dialog/confirmation-dialog.component'; +import { ConfirmationDialogComponent, ConfirmationDialogInput } from './confirmation-dialog/confirmation-dialog.component'; import { NotificationService, NotificationType } from '../notification/notification.service'; import { TranslateService } from '@ngx-translate/core'; import { AppStateService } from '../state/app-state.service'; @@ -23,7 +23,7 @@ import { ProjectWrapper } from '../state/model/project.wrapper'; import { AddEditDictionaryDialogComponent } from '../screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component'; const dialogConfig = { - width: '600px', + width: '662px', maxWidth: '90vw', autoFocus: false }; diff --git a/apps/red-ui/src/app/dialogs/file-details-dialog/file-details-dialog.component.html b/apps/red-ui/src/app/dialogs/file-details-dialog/file-details-dialog.component.html index 276771ef2..28ca2dd54 100644 --- a/apps/red-ui/src/app/dialogs/file-details-dialog/file-details-dialog.component.html +++ b/apps/red-ui/src/app/dialogs/file-details-dialog/file-details-dialog.component.html @@ -10,42 +10,23 @@ {{ 'project-overview.file-listing.file-entry.status' | translate: fileStatus }}
- {{ - 'project-overview.file-listing.file-entry.number-of-pages' - | translate: fileStatus - }} + {{ 'project-overview.file-listing.file-entry.number-of-pages' | translate: fileStatus }}
- {{ - 'project-overview.file-listing.file-entry.number-of-analyses' - | translate: fileStatus - }} + {{ 'project-overview.file-listing.file-entry.number-of-analyses' | translate: fileStatus }}
- {{ - 'project-overview.file-listing.file-entry.added' - | translate: { added: fileStatus.added | date: 'short' } - }} + {{ 'project-overview.file-listing.file-entry.added' | translate: { added: fileStatus.added | date: 'short' } }}
- {{ - 'project-overview.file-listing.file-entry.last-updated' - | translate: { lastUpdated: fileStatus.lastUpdated | date: 'short' } - }} + {{ 'project-overview.file-listing.file-entry.last-updated' | translate: { lastUpdated: fileStatus.lastUpdated | date: 'short' } }}
- +
- + diff --git a/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html b/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html index c92cd7956..f59de3b1d 100644 --- a/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html +++ b/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html @@ -50,7 +50,6 @@ - + + diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html index a592b970a..4a3c4cbea 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html @@ -23,7 +23,7 @@ >
- +
diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss b/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss index d375a2b0b..888100604 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss @@ -3,6 +3,13 @@ .header-wrapper { display: flex; flex-direction: row; + position: relative; + + redaction-circle-button { + position: absolute; + top: -5px; + left: 277px; + } } .legend { diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html index 04a9c8f86..cd6766055 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.html @@ -24,7 +24,7 @@ >
- +
diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss index e7517fdb7..ece80b89c 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.scss @@ -68,14 +68,18 @@ redaction-table-col-name::ng-deep { } .left-container { - width: calc(100vw - 350px); + width: calc(100vw - 358px); } .right-container { display: flex; - width: 350px; - min-width: 350px; + width: 358px; + min-width: 358px; padding: 16px 16px 16px 24px; + + redaction-project-details { + width: 100%; + } } .reanalyse-link { diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index dde800d5f..aef28b041 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -344,15 +344,19 @@ "dialog": { "single-user": "Reviewer", "title": "Manage File Reviewer", - "save": "Save" + "save": "Save", + "cancel": "Cancel" } }, "assign-project-owner": { "dialog": { "single-user": "Owner", "multi-user": "Review Team", - "title": "Manage Project Owner and Review Team", - "save": "Save" + "title": "Manage Project Team", + "members": "Members", + "save": "Save Changes", + "cancel": "Cancel", + "search": "Search..." } }, "project-member-guard": { diff --git a/apps/red-ui/src/assets/styles/red-button.scss b/apps/red-ui/src/assets/styles/red-button.scss index 9aa2bc910..80b746231 100644 --- a/apps/red-ui/src/assets/styles/red-button.scss +++ b/apps/red-ui/src/assets/styles/red-button.scss @@ -12,10 +12,24 @@ .mat-button-wrapper { display: flex; align-items: center; + line-height: 34px; gap: 6px; } } +.cdk-program-focused .mat-button-focus-overlay { + opacity: 0 !important; +} + +.mat-flat-button.mat-primary.red-button { + padding: 0 14px; + transition: background-color 0.2s; + + &:not(.mat-button-disabled):hover { + background-color: $red-2; + } +} + redaction-icon-button, redaction-chevron-button, redaction-circle-button { diff --git a/apps/red-ui/src/assets/styles/red-dialog.scss b/apps/red-ui/src/assets/styles/red-dialog.scss index c91678a7a..cddf6e42d 100644 --- a/apps/red-ui/src/assets/styles/red-dialog.scss +++ b/apps/red-ui/src/assets/styles/red-dialog.scss @@ -1,5 +1,9 @@ +@import './red-variables'; + .mat-dialog-container { - border-radius: 8px; + color: $grey-1; + padding: 0 !important; + border-radius: 8px !important; } .dialog { @@ -8,31 +12,28 @@ .dialog-close { position: absolute; - top: 0; - right: -10px; - - mat-icon { - width: 14px; - height: 14px; - } + top: 16px; + right: 16px; } .dialog-header { - padding-top: 12px; - padding-bottom: 12px; + padding: 32px 32px 16px 32px; } .dialog-content { - padding-top: 12px; - padding-bottom: 12px; + padding: 0 32px; } .dialog-actions { - padding-top: 12px; + height: 81px; + box-sizing: border-box; + border-top: 1px solid $separator; + padding: 0 32px; + align-items: center; + display: flex; > * { margin-right: 16px; } - padding-bottom: 40px; } } 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 37104d388..88a71654a 100644 --- a/apps/red-ui/src/assets/styles/red-page-layout.scss +++ b/apps/red-ui/src/assets/styles/red-page-layout.scss @@ -36,10 +36,6 @@ body { .red-input-group { width: 250px; - - input { - margin-top: 0; - } } } } @@ -145,6 +141,10 @@ body { flex: 2; } +.mt-0 { + margin-top: 0 !important; +} + .mt-5 { margin-top: 5px; } diff --git a/apps/red-ui/src/assets/styles/red-text-styles.scss b/apps/red-ui/src/assets/styles/red-text-styles.scss index d9f318bec..61963927a 100644 --- a/apps/red-ui/src/assets/styles/red-text-styles.scss +++ b/apps/red-ui/src/assets/styles/red-text-styles.scss @@ -18,9 +18,9 @@ a { } .heading-l { - font-size: 18px; + font-size: 20px; font-weight: 600; - line-height: 22px; + line-height: 24px; } .heading {