Redo comments layout
This commit is contained in:
parent
d744eab962
commit
b2f5e02673
@ -24,6 +24,7 @@ export class AnnotationWrapper {
|
||||
comments: Comment[] = [];
|
||||
firstTopLeftPoint: Point;
|
||||
annotationId: string;
|
||||
shortContent: string;
|
||||
content: string;
|
||||
value: string;
|
||||
userId: string;
|
||||
@ -361,6 +362,7 @@ export class AnnotationWrapper {
|
||||
if (entry.section) {
|
||||
content += 'In section: "' + entry.section + '"';
|
||||
}
|
||||
annotationWrapper.shortContent = entry.reason || content;
|
||||
annotationWrapper.content = content;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<redaction-side-nav title="type">
|
||||
<redaction-side-nav [title]="type">
|
||||
<ng-container *ngFor="let item of items[type]">
|
||||
<div
|
||||
*ngIf="
|
||||
|
||||
@ -107,11 +107,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="isSearchOpen" class="search-input-container">
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
placeholder="file-attributes-csv-import.search.placeholder"
|
||||
type="search"
|
||||
width="full"
|
||||
></redaction-search-input>
|
||||
></redaction-input-with-action>
|
||||
</div>
|
||||
<div [class.search-open]="isSearchOpen" class="csv-header-pill-content">
|
||||
<div
|
||||
|
||||
@ -37,10 +37,11 @@
|
||||
</span>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'dictionary-listing.search'"
|
||||
></redaction-search-input>
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
<div class="actions">
|
||||
<redaction-icon-button
|
||||
(action)="openAddEditDictionaryDialog()"
|
||||
|
||||
@ -35,10 +35,11 @@
|
||||
</span>
|
||||
|
||||
<div class="actions flex-1">
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'dossier-templates-listing.search'"
|
||||
></redaction-search-input>
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
|
||||
<redaction-icon-button
|
||||
(action)="openAddDossierTemplateDialog()"
|
||||
|
||||
@ -46,10 +46,11 @@
|
||||
<mat-spinner *ngIf="loading" diameter="15"></mat-spinner>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'file-attributes-listing.search'"
|
||||
></redaction-search-input>
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
<input
|
||||
#fileInput
|
||||
(change)="importCSV($event.target['files'])"
|
||||
|
||||
@ -8,10 +8,11 @@
|
||||
<div class="breadcrumb" translate="user-management"></div>
|
||||
|
||||
<div class="actions">
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'user-listing.search'"
|
||||
></redaction-search-input>
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
<redaction-icon-button
|
||||
(action)="openAddEditUserDialog($event)"
|
||||
*ngIf="permissionsService.isUserAdmin()"
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
.page-header .actions {
|
||||
justify-content: flex-end;
|
||||
|
||||
redaction-search-input:not(:last-child) {
|
||||
redaction-input-with-action:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
|
||||
@ -1,21 +1,7 @@
|
||||
@import '../../../../../assets/styles/red-variables';
|
||||
|
||||
:host {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.annotation-actions {
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
top: -8px;
|
||||
height: calc(100% + 8px);
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-start;
|
||||
width: 80px;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, #f9fafb, #f9fafb);
|
||||
|
||||
redaction-circle-button {
|
||||
display: block;
|
||||
@ -28,6 +14,10 @@
|
||||
&.visible {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.false-positive-icon {
|
||||
|
||||
@ -1,79 +1,34 @@
|
||||
<div class="wrapper">
|
||||
<ng-container *ngIf="expanded">
|
||||
<div *ngFor="let comment of annotation.comments; let idx = index" class="comment">
|
||||
<div
|
||||
[class.comment-owner]="isCommentOwner(comment)"
|
||||
[class.red]="isCommentOwner(comment)"
|
||||
class="comment-icon"
|
||||
>
|
||||
<mat-icon
|
||||
[svgIcon]="isCommentOwner(comment) ? 'red:comment-fill' : 'red:comment'"
|
||||
></mat-icon>
|
||||
</div>
|
||||
<div
|
||||
(click)="deleteComment(comment)"
|
||||
[class.comment-owner]="isCommentOwner(comment)"
|
||||
class="trash-icon red"
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="owner">{{ getOwnerName(comment) }}</div>
|
||||
<div>{{ comment.text }}</div>
|
||||
</div>
|
||||
<div *ngFor="let comment of annotation.comments" class="comment">
|
||||
<div class="comment-details-wrapper">
|
||||
<div class="comment-details">
|
||||
<div>{{ getOwnerName(comment) }}</div>
|
||||
<div>{{ comment.date | date: 'd MMM. yyyy, hh:mm a' }}</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div class="actions-container all-caps-label">
|
||||
<div (click)="toggleExpandComments($event)" *ngIf="annotation.comments.length">
|
||||
{{
|
||||
expanded
|
||||
? translateService.instant('comments.hide-comments')
|
||||
: translateService.instant(
|
||||
annotation.comments.length === 1
|
||||
? 'comments.comment'
|
||||
: 'comments.comments',
|
||||
{
|
||||
count: annotation.comments.length
|
||||
}
|
||||
)
|
||||
}}
|
||||
<div class="comment-actions">
|
||||
<redaction-circle-button
|
||||
(action)="deleteComment(comment)"
|
||||
*ngIf="isCommentOwner(comment)"
|
||||
[iconSize]="10"
|
||||
[size]="20"
|
||||
class="pointer"
|
||||
icon="red:trash"
|
||||
></redaction-circle-button>
|
||||
</div>
|
||||
<div
|
||||
(click)="toggleAddingComment($event)"
|
||||
*ngIf="!addingComment && canAddComment && permissionsService.canAddComment()"
|
||||
translate="comments.add-comment"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<form
|
||||
(submit)="addComment()"
|
||||
*ngIf="addingComment && permissionsService.canAddComment()"
|
||||
[formGroup]="commentForm"
|
||||
>
|
||||
<div class="red-input-group">
|
||||
<input
|
||||
[placeholder]="translateService.instant('comments.add-comment')"
|
||||
class="w-full"
|
||||
formControlName="comment"
|
||||
name="comment"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div *ngIf="addingComment" class="comment-actions-container">
|
||||
<redaction-circle-button
|
||||
(action)="addComment()"
|
||||
[disabled]="!commentForm.value.comment"
|
||||
icon="red:check"
|
||||
type="primary"
|
||||
></redaction-circle-button>
|
||||
<div
|
||||
(click)="toggleAddingComment($event)"
|
||||
class="all-caps-label cancel"
|
||||
translate="comments.cancel"
|
||||
></div>
|
||||
</div>
|
||||
<div>{{ comment.text }}</div>
|
||||
</div>
|
||||
|
||||
<redaction-input-with-action
|
||||
(action)="addComment()"
|
||||
*ngIf="permissionsService.canAddComment()"
|
||||
[form]="commentForm"
|
||||
[placeholder]="translateService.instant('comments.add-comment')"
|
||||
type="submit"
|
||||
width="full"
|
||||
></redaction-input-with-action>
|
||||
|
||||
<div
|
||||
(click)="toggleExpandComments($event)"
|
||||
class="all-caps-label pointer hide-comments"
|
||||
translate="comments.hide-comments"
|
||||
></div>
|
||||
|
||||
@ -1,74 +1,53 @@
|
||||
@import '../../../../../assets/styles/red-variables';
|
||||
|
||||
.wrapper {
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 10px;
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
padding: 8px 0 8px 16px;
|
||||
|
||||
.comment {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-right: 12px;
|
||||
.comment-details-wrapper {
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
|
||||
.comment-details {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.comment-actions {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -4px;
|
||||
|
||||
mat-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.owner {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
width: 14px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.comment-icon {
|
||||
color: $grey-5;
|
||||
&:hover .comment-details-wrapper .comment-actions {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.trash-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.comment-icon.comment-owner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.trash-icon.comment-owner {
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comment-actions-container,
|
||||
.actions-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-right: 15px;
|
||||
}
|
||||
redaction-input-with-action {
|
||||
margin: 5px 0 10px 0;
|
||||
}
|
||||
|
||||
.actions-container {
|
||||
margin-left: 26px;
|
||||
.hide-comments {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
> div:not(:last-child):after {
|
||||
content: '•';
|
||||
margin-left: 5px;
|
||||
}
|
||||
.comment,
|
||||
.hide-comments {
|
||||
padding-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectorRef, Component, Input } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, HostBinding, Input } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Comment } from '@redaction/red-ui-http';
|
||||
import { ManualAnnotationService } from '../../services/manual-annotation.service';
|
||||
@ -15,9 +15,8 @@ import { PermissionsService } from '@services/permissions.service';
|
||||
})
|
||||
export class CommentsComponent {
|
||||
@Input() annotation: AnnotationWrapper;
|
||||
expanded = false;
|
||||
commentForm: FormGroup;
|
||||
addingComment = false;
|
||||
@HostBinding('class.hidden') private _hidden = true;
|
||||
|
||||
constructor(
|
||||
readonly translateService: TranslateService,
|
||||
@ -29,34 +28,12 @@ export class CommentsComponent {
|
||||
private readonly _manualAnnotationService: ManualAnnotationService
|
||||
) {
|
||||
this.commentForm = this._formBuilder.group({
|
||||
comment: ['', Validators.required]
|
||||
value: ['', Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
get canAddComment() {
|
||||
return !this.annotation.isChangeLogRemoved;
|
||||
}
|
||||
|
||||
toggleExpandComments($event: MouseEvent): void {
|
||||
$event.stopPropagation();
|
||||
if (!this.annotation.comments.length) {
|
||||
return;
|
||||
}
|
||||
this.expanded = !this.expanded;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
toggleAddingComment($event?: MouseEvent): void {
|
||||
$event?.stopPropagation();
|
||||
this.addingComment = !this.addingComment;
|
||||
if (this.addingComment) {
|
||||
this.expanded = true;
|
||||
}
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
addComment(): void {
|
||||
const value = this.commentForm.value.comment;
|
||||
const value = this.commentForm.value.value;
|
||||
if (value) {
|
||||
this._manualAnnotationService
|
||||
.addComment(value, this.annotation.id)
|
||||
@ -68,17 +45,21 @@ export class CommentsComponent {
|
||||
});
|
||||
});
|
||||
this.commentForm.reset();
|
||||
this.toggleAddingComment();
|
||||
}
|
||||
}
|
||||
|
||||
toggleExpandComments($event?: MouseEvent) {
|
||||
$event?.stopPropagation();
|
||||
this._hidden = !this._hidden;
|
||||
}
|
||||
|
||||
deleteComment(comment: Comment): void {
|
||||
this._manualAnnotationService
|
||||
.deleteComment(comment.id, this.annotation.id)
|
||||
.subscribe(() => {
|
||||
this.annotation.comments.splice(this.annotation.comments.indexOf(comment), 1);
|
||||
if (!this.annotation.comments.length) {
|
||||
this.expanded = false;
|
||||
this._hidden = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -155,7 +155,11 @@
|
||||
(action)="logAnnotation(annotation)"
|
||||
[requiredClicks]="2"
|
||||
>
|
||||
<div class="details">
|
||||
<div
|
||||
[matTooltip]="annotation.content"
|
||||
class="details"
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<redaction-type-annotation-icon
|
||||
[annotation]="annotation"
|
||||
></redaction-type-annotation-icon>
|
||||
@ -174,17 +178,12 @@
|
||||
>: </strong
|
||||
>{{ annotation.dictionary | humanize: false }}
|
||||
</div>
|
||||
<div *ngIf="annotation.content && !annotation.isHint">
|
||||
<div *ngIf="annotation.shortContent && !annotation.isHint">
|
||||
<strong><span translate="content"></span>: </strong
|
||||
>{{ annotation.content }}
|
||||
>{{ annotation.shortContent }}
|
||||
</div>
|
||||
</div>
|
||||
<ng-container
|
||||
*ngIf="!multiSelectActive"
|
||||
[ngTemplateOutletContext]="{ annotation: annotation }"
|
||||
[ngTemplateOutlet]="annotationActionsTemplate"
|
||||
>
|
||||
</ng-container>
|
||||
|
||||
<div class="active-icon-marker-container">
|
||||
<redaction-round-checkbox
|
||||
*ngIf="
|
||||
@ -194,8 +193,37 @@
|
||||
></redaction-round-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions-wrapper">
|
||||
<div
|
||||
(click)="toggleExpandComments(annotation, $event)"
|
||||
[matTooltip]="
|
||||
(annotation.comments.length === 1
|
||||
? 'comments.comment'
|
||||
: 'comments.comments'
|
||||
)
|
||||
| translate
|
||||
: {
|
||||
count: annotation.comments.length
|
||||
}
|
||||
"
|
||||
class="comments-counter"
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon svgIcon="red:comment"></mat-icon>
|
||||
{{ annotation.comments.length }}
|
||||
</div>
|
||||
<div class="actions">
|
||||
<ng-container
|
||||
*ngIf="!multiSelectActive"
|
||||
[ngTemplateOutletContext]="{ annotation: annotation }"
|
||||
[ngTemplateOutlet]="annotationActionsTemplate"
|
||||
>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<redaction-comments [annotation]="annotation"></redaction-comments>
|
||||
</redaction-hidden-action>
|
||||
<redaction-comments [annotation]="annotation"></redaction-comments>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -146,7 +146,7 @@
|
||||
}
|
||||
|
||||
.annotation {
|
||||
padding: 10px 21px 10px 6px;
|
||||
padding: 10px 16px 8px 10px;
|
||||
font-size: 11px;
|
||||
line-height: 14px;
|
||||
cursor: pointer;
|
||||
@ -164,6 +164,36 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.actions-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 8px;
|
||||
min-height: 34px;
|
||||
padding-left: 18px;
|
||||
|
||||
.comments-counter {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
transition: background-color 0.2s;
|
||||
line-height: 13px;
|
||||
height: 24px;
|
||||
border-radius: 12px;
|
||||
|
||||
mat-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $grey-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
redaction-type-annotation-icon {
|
||||
margin-top: 6px;
|
||||
margin-right: 10px;
|
||||
@ -184,10 +214,8 @@
|
||||
@include scroll-bar;
|
||||
}
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
.annotation {
|
||||
padding-right: 10px;
|
||||
}
|
||||
&.has-scrollbar:hover .annotation-wrapper .annotation {
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,8 +6,10 @@ import {
|
||||
HostListener,
|
||||
Input,
|
||||
Output,
|
||||
QueryList,
|
||||
TemplateRef,
|
||||
ViewChild
|
||||
ViewChild,
|
||||
ViewChildren
|
||||
} from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||
@ -16,6 +18,7 @@ import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import { debounce } from '@utils/debounce';
|
||||
import { FileDataModel } from '@models/file/file-data.model';
|
||||
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
||||
import { CommentsComponent } from '../comments/comments.component';
|
||||
|
||||
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
||||
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||
@ -46,6 +49,7 @@ export class FileWorkloadComponent {
|
||||
@Output() annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
||||
displayedPages: number[] = [];
|
||||
pagesPanelActive = true;
|
||||
@ViewChildren(CommentsComponent) annotationCommentsComponents: QueryList<CommentsComponent>;
|
||||
@ViewChild('annotationsElement') private _annotationsElement: ElementRef;
|
||||
@ViewChild('quickNavigation') private _quickNavigationElement: ElementRef;
|
||||
|
||||
@ -99,6 +103,13 @@ export class FileWorkloadComponent {
|
||||
return this.selectedAnnotations?.find(a => a?.id === annotation.id);
|
||||
}
|
||||
|
||||
toggleExpandComments(annotation: AnnotationWrapper, $event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.annotationCommentsComponents
|
||||
.find(c => c.annotation === annotation)
|
||||
.toggleExpandComments();
|
||||
}
|
||||
|
||||
logAnnotation(annotation: AnnotationWrapper) {
|
||||
console.log(annotation);
|
||||
}
|
||||
|
||||
@ -43,12 +43,13 @@
|
||||
class="info"
|
||||
></pre>
|
||||
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'assign-dossier-owner.dialog.search' | translate"
|
||||
[width]="560"
|
||||
class="search-container"
|
||||
></redaction-search-input>
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
|
||||
<div class="members-list">
|
||||
<div
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
(action)="openAssignDossierMembersDialog.emit()"
|
||||
*ngIf="permissionsService.isManager() && canAdd"
|
||||
[class.large-spacing]="largeSpacing"
|
||||
[small]="true"
|
||||
[size]="32"
|
||||
class="member"
|
||||
icon="red:plus"
|
||||
tooltip="dossier-details.assign-members"
|
||||
|
||||
@ -109,7 +109,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
dossierTemplateId: this.dossierForm.get('dossierTemplateId').value
|
||||
};
|
||||
const updatedDossier = await this._appStateService.addOrUpdateDossier(dossier);
|
||||
this.updateDossier.emit(updatedDossier);
|
||||
if (updatedDossier) this.updateDossier.emit(updatedDossier);
|
||||
}
|
||||
|
||||
openDeleteDossierDialog($event: MouseEvent) {
|
||||
|
||||
@ -32,10 +32,11 @@
|
||||
[icon]="'red:template'"
|
||||
[primaryFilters]="dossierTemplateFilters"
|
||||
></redaction-popup-filter>
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'dossier-listing.search'"
|
||||
></redaction-search-input>
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
<div
|
||||
(click)="resetFilters()"
|
||||
*ngIf="hasActiveFilters"
|
||||
|
||||
@ -25,10 +25,11 @@
|
||||
[primaryFilters]="needsWorkFilters"
|
||||
></redaction-popup-filter>
|
||||
|
||||
<redaction-search-input
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'dossier-overview.search'"
|
||||
></redaction-search-input>
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
|
||||
<div
|
||||
(click)="resetFilters()"
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
[class.dark-bg]="type === 'dark-bg'"
|
||||
[class.overlay]="showDot"
|
||||
[class.primary]="type === 'primary'"
|
||||
[class.small]="small"
|
||||
[class.warn]="type === 'warn'"
|
||||
[disabled]="disabled"
|
||||
mat-icon-button
|
||||
type="submit"
|
||||
>
|
||||
<mat-icon [svgIcon]="icon"></mat-icon>
|
||||
</button>
|
||||
|
||||
@ -1,40 +1,41 @@
|
||||
@import '../../../../../../assets/styles/red-variables';
|
||||
|
||||
:host {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
height: var(--size);
|
||||
width: var(--size);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
line-height: 33px;
|
||||
button {
|
||||
height: var(--size);
|
||||
width: var(--size);
|
||||
line-height: var(--size);
|
||||
|
||||
&.small {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
mat-icon {
|
||||
width: var(--iconSize);
|
||||
height: var(--iconSize);
|
||||
line-height: var(--iconSize);
|
||||
margin: 0;
|
||||
|
||||
mat-icon {
|
||||
width: 14px;
|
||||
height: 34px;
|
||||
margin: 0;
|
||||
}
|
||||
svg {
|
||||
line-height: var(--iconSize);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary {
|
||||
&.mat-button-disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.primary.mat-button-disabled {
|
||||
background-color: $grey-6;
|
||||
color: $white !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.warn:not([disabled]) {
|
||||
background-color: $yellow-2;
|
||||
|
||||
&:hover {
|
||||
&.warn:not([disabled]) {
|
||||
background-color: $yellow-2;
|
||||
|
||||
&:hover {
|
||||
background-color: $yellow-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
@ -21,13 +22,21 @@ export class CircleButtonComponent {
|
||||
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
|
||||
@Input() tooltipClass: string;
|
||||
@Input() disabled = false;
|
||||
@Input() small = false;
|
||||
@Input() type: 'default' | 'primary' | 'warn' | 'dark-bg' = 'default';
|
||||
@Input() removeTooltip = false;
|
||||
@Output() action = new EventEmitter<any>();
|
||||
@Input() size = 34;
|
||||
@Input() iconSize = 14;
|
||||
|
||||
@ViewChild(MatTooltip) matTooltip: MatTooltip;
|
||||
|
||||
constructor(private _elRef: ElementRef) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._elRef.nativeElement.style.setProperty('--size', this.size + 'px');
|
||||
this._elRef.nativeElement.style.setProperty('--iconSize', this.iconSize + 'px');
|
||||
}
|
||||
|
||||
performAction($event: any) {
|
||||
if (!this.disabled) {
|
||||
if (this.removeTooltip) {
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
<form (submit)="type === 'submit' && submit()" [formGroup]="form">
|
||||
<div [style.max-width]="computedWidth" [style.width]="computedWidth" class="red-input-group">
|
||||
<input
|
||||
[formControlName]="formControlName"
|
||||
[name]="formControlName"
|
||||
[placeholder]="placeholder | translate"
|
||||
class="with-icon mt-0"
|
||||
type="text"
|
||||
/>
|
||||
|
||||
<!-- Search-->
|
||||
<mat-icon
|
||||
*ngIf="type === 'search' && !hasContent"
|
||||
class="icon-right"
|
||||
svgIcon="red:search"
|
||||
></mat-icon>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="clearContent()"
|
||||
*ngIf="type === 'search' && hasContent"
|
||||
[disabled]="form.invalid"
|
||||
[size]="25"
|
||||
icon="red:close"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<!-- Submit-->
|
||||
<redaction-circle-button
|
||||
(action)="submit($event)"
|
||||
*ngIf="type === 'submit'"
|
||||
[disabled]="form.invalid"
|
||||
[size]="25"
|
||||
icon="red:collapse"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,14 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
mat-icon.disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
redaction-circle-button {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
right: 5px;
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-input-with-action',
|
||||
templateUrl: './input-with-action.component.html',
|
||||
styleUrls: ['./input-with-action.component.scss']
|
||||
})
|
||||
export class InputWithActionComponent {
|
||||
@Input() form: FormGroup;
|
||||
@Input() placeholder: string;
|
||||
@Input() width: number | 'full' = 250;
|
||||
@Input() type: 'search' | 'submit';
|
||||
@Output() action = new EventEmitter<any>();
|
||||
|
||||
get formControlName(): 'query' | 'value' {
|
||||
return this.type === 'search' ? 'query' : 'value';
|
||||
}
|
||||
|
||||
get hasContent() {
|
||||
return !!this.form.get(this.formControlName).value.length;
|
||||
}
|
||||
|
||||
get computedWidth() {
|
||||
return this.width === 'full' ? '100%' : `${this.width}px`;
|
||||
}
|
||||
|
||||
clearContent() {
|
||||
this.form.patchValue({ query: '' });
|
||||
}
|
||||
|
||||
submit($event?: MouseEvent) {
|
||||
$event?.stopPropagation();
|
||||
if (this.hasContent) {
|
||||
this.action.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
<form [formGroup]="form">
|
||||
<div [style.max-width]="computedWidth" [style.width]="computedWidth" class="red-input-group">
|
||||
<input
|
||||
[placeholder]="placeholder | translate"
|
||||
class="with-icon mt-0"
|
||||
formControlName="query"
|
||||
name="query"
|
||||
type="text"
|
||||
/>
|
||||
<mat-icon *ngIf="!hasContent" class="icon-right" svgIcon="red:search"></mat-icon>
|
||||
<mat-icon
|
||||
(click)="clearContent()"
|
||||
*ngIf="hasContent"
|
||||
class="icon-right pointer"
|
||||
svgIcon="red:close"
|
||||
></mat-icon>
|
||||
</div>
|
||||
</form>
|
||||
@ -1,3 +0,0 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-search-input',
|
||||
templateUrl: './search-input.component.html',
|
||||
styleUrls: ['./search-input.component.scss']
|
||||
})
|
||||
export class SearchInputComponent {
|
||||
@Input() form: FormGroup;
|
||||
@Input() placeholder: string;
|
||||
@Input() width: number | 'full' = 250;
|
||||
|
||||
get hasContent() {
|
||||
return !!this.form.get('query').value.length;
|
||||
}
|
||||
|
||||
get computedWidth() {
|
||||
return this.width === 'full' ? '100%' : `${this.width}px`;
|
||||
}
|
||||
|
||||
clearContent() {
|
||||
this.form.patchValue({ query: '' });
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,6 @@ import { FileDownloadBtnComponent } from './components/buttons/file-download-btn
|
||||
import { IconButtonComponent } from './components/buttons/icon-button/icon-button.component';
|
||||
import { UserButtonComponent } from './components/buttons/user-button/user-button.component';
|
||||
import { MatConfigModule } from '../mat-config/mat-config.module';
|
||||
import { SearchInputComponent } from './components/search-input/search-input.component';
|
||||
import { IconsModule } from '../icons/icons.module';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { AnnotationIconComponent } from './components/annotation-icon/annotation-icon.component';
|
||||
@ -37,6 +36,7 @@ import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
|
||||
import { QuickFiltersComponent } from './components/filters/quick-filters/quick-filters.component';
|
||||
import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component';
|
||||
import { AssignUserDropdownComponent } from './components/assign-user-dropdown/assign-user-dropdown.component';
|
||||
import { InputWithActionComponent } from '@shared/components/input-with-action/input-with-action.component';
|
||||
|
||||
const buttons = [
|
||||
ChevronButtonComponent,
|
||||
@ -51,7 +51,7 @@ const components = [
|
||||
InitialsAvatarComponent,
|
||||
TableColNameComponent,
|
||||
PaginationComponent,
|
||||
SearchInputComponent,
|
||||
InputWithActionComponent,
|
||||
AnnotationIconComponent,
|
||||
SimpleDoughnutChartComponent,
|
||||
StatusBarComponent,
|
||||
|
||||
@ -18,6 +18,14 @@ export class PermissionsService {
|
||||
return this._userService.user;
|
||||
}
|
||||
|
||||
private get _activeFile(): FileStatusWrapper | undefined {
|
||||
return this._appStateService.activeFile;
|
||||
}
|
||||
|
||||
private get _activeDossier(): DossierWrapper | undefined {
|
||||
return this._appStateService.activeDossier;
|
||||
}
|
||||
|
||||
isManager(user?: User) {
|
||||
return this._userService.isManager(user);
|
||||
}
|
||||
@ -93,7 +101,6 @@ export class PermissionsService {
|
||||
|
||||
canAssignUser(fileStatus = this._activeFile): boolean {
|
||||
const precondition =
|
||||
this.isDossierMember() &&
|
||||
!fileStatus.isProcessing &&
|
||||
!fileStatus.isError &&
|
||||
!fileStatus.isApproved &&
|
||||
@ -209,12 +216,4 @@ export class PermissionsService {
|
||||
canAddComment(fileStatus = this._activeFile): boolean {
|
||||
return this.isFileReviewer(fileStatus) || this.isApprover();
|
||||
}
|
||||
|
||||
private get _activeFile(): FileStatusWrapper | undefined {
|
||||
return this._appStateService.activeFile;
|
||||
}
|
||||
|
||||
private get _activeDossier(): DossierWrapper | undefined {
|
||||
return this._appStateService.activeDossier;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"OAUTH_URL": "https://dev-08.iqser.cloud/auth/realms/redaction",
|
||||
"API_URL": "https://dev-08.iqser.cloud/redaction-gateway-v1",
|
||||
"OAUTH_URL": "https://dev-06.iqser.cloud/auth/realms/redaction",
|
||||
"API_URL": "https://dev-06.iqser.cloud/redaction-gateway-v1",
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"BACKEND_APP_VERSION": "4.4.40",
|
||||
"FRONTEND_APP_VERSION": "1.1",
|
||||
|
||||
@ -162,7 +162,7 @@
|
||||
},
|
||||
"errors": {
|
||||
"dossier-already-exists": "Dossier with this name already exists!",
|
||||
"generic": "Failed to save dossier"
|
||||
"generic": "Failed to save dossier."
|
||||
},
|
||||
"actions": {
|
||||
"save": "Save",
|
||||
@ -520,8 +520,8 @@
|
||||
"comments": {
|
||||
"comment": "{{count}} comment",
|
||||
"comments": "{{count}} comments",
|
||||
"add-comment": "Add a comment",
|
||||
"hide-comments": "Hide",
|
||||
"add-comment": "Enter comment",
|
||||
"hide-comments": "Hide comments",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
"UNPROCESSED": "Unprocessed",
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
}
|
||||
|
||||
.mat-checkbox-layout {
|
||||
align-items: center !important;
|
||||
|
||||
.mat-checkbox-inner-container {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user