some work on annotation flows
This commit is contained in:
parent
b6e11fcddb
commit
d1d3e2b5bb
@ -47,6 +47,10 @@
|
||||
background-color: $grey-1;
|
||||
}
|
||||
|
||||
.request{
|
||||
background-color: $blue-1;
|
||||
}
|
||||
|
||||
.ignore {
|
||||
background-color: $grey-5;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { Component, Input, OnInit } from '@angular/core';
|
||||
styleUrls: ['./annotation-icon.component.scss']
|
||||
})
|
||||
export class AnnotationIconComponent implements OnInit {
|
||||
@Input() public type: 'hint' | 'redaction' | 'suggestion' | 'ignore' | 'comment';
|
||||
@Input() public type: 'hint' | 'redaction' | 'suggestion' | 'ignore' | 'comment' | 'request';
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatIconModule, MatIconRegistry } from '@angular/material/icon';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {MatIconModule, MatIconRegistry} from '@angular/material/icon';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, MatIconModule],
|
||||
@ -18,7 +18,7 @@ export class IconsModule {
|
||||
'close', 'document', 'double-chevron-right', 'download',
|
||||
'edit', 'error', 'folder', 'info', 'lightning', 'logout', 'menu', 'pages',
|
||||
'plus', 'preview', 'refresh', 'report', 'secret', 'sort-asc', 'sort-desc',
|
||||
'status', 'trash', 'user'
|
||||
'status', 'trash', 'user', 'check-alt'
|
||||
];
|
||||
|
||||
for (const icon of icons) {
|
||||
|
||||
@ -128,7 +128,10 @@
|
||||
{{annotation.getPageNumber()}}
|
||||
</div>
|
||||
|
||||
<div class="annotation-actions">
|
||||
<div class="annotation-actions" *ngIf="isManuallyAddedAnnotation(annotation)">
|
||||
<button mat-icon-button (click)="acceptSuggestionAnnotation($event, annotation)" class="confirm">
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="suggestRemoveAnnotation($event, annotation)">
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
|
||||
@ -101,7 +101,16 @@ redaction-pdf-viewer {
|
||||
background-color: #F9FAFB;
|
||||
|
||||
.annotation-actions {
|
||||
background: linear-gradient(to right, transparent 0%, #F9FAFB, #F9FAFB, #F9FAFB);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 120px;
|
||||
padding-right: 16px;
|
||||
|
||||
.confirm{
|
||||
color: $green-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import {ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {
|
||||
AddRedactionRequest,
|
||||
FileUploadControllerService,
|
||||
@ -8,25 +8,25 @@ import {
|
||||
ProjectControllerService,
|
||||
StatusControllerService
|
||||
} from '@redaction/red-ui-http';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { NotificationService, NotificationType } from '../../../notification/notification.service';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { FileDetailsDialogComponent } from './file-details-dialog/file-details-dialog.component';
|
||||
import { ViewerSyncService } from '../service/viewer-sync.service';
|
||||
import { Annotations } from '@pdftron/webviewer';
|
||||
import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component';
|
||||
import { AnnotationUtils } from '../../../utils/annotation-utils';
|
||||
import { ManualRedactionDialogComponent } from '../manual-redaction-dialog/manual-redaction-dialog.component';
|
||||
import { UserService } from '../../../user/user.service';
|
||||
import { debounce } from '../../../utils/debounce';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {NotificationService, NotificationType} from '../../../notification/notification.service';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {AppStateService} from '../../../state/app-state.service';
|
||||
import {FileDetailsDialogComponent} from './file-details-dialog/file-details-dialog.component';
|
||||
import {ViewerSyncService} from '../service/viewer-sync.service';
|
||||
import {Annotations} from '@pdftron/webviewer';
|
||||
import {PdfViewerComponent} from '../pdf-viewer/pdf-viewer.component';
|
||||
import {AnnotationUtils} from '../../../utils/annotation-utils';
|
||||
import {ManualRedactionDialogComponent} from '../manual-redaction-dialog/manual-redaction-dialog.component';
|
||||
import {UserService} from '../../../user/user.service';
|
||||
import {debounce} from '../../../utils/debounce';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import { AnnotationFilters } from '../../../utils/types';
|
||||
import { FiltersService } from '../service/filters.service';
|
||||
import { FileDownloadService } from '../service/file-download.service';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { FileType } from '../model/file-type';
|
||||
import { ConfirmationDialogComponent } from '../../../common/confirmation-dialog/confirmation-dialog.component';
|
||||
import {AnnotationFilters} from '../../../utils/types';
|
||||
import {FiltersService} from '../service/filters.service';
|
||||
import {FileDownloadService} from '../service/file-download.service';
|
||||
import {saveAs} from 'file-saver';
|
||||
import {FileType} from '../model/file-type';
|
||||
import {ConfirmationDialogComponent} from '../../../common/confirmation-dialog/confirmation-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-preview-screen',
|
||||
@ -48,7 +48,7 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
public displayedAnnotations: { [key: number]: { annotations: Annotations.Annotation[] } } = {};
|
||||
public selectedAnnotation: Annotations.Annotation;
|
||||
public filters: AnnotationFilters;
|
||||
public expandedFilters: AnnotationFilters = { hint: false };
|
||||
public expandedFilters: AnnotationFilters = {hint: false};
|
||||
public activeViewerPage: number;
|
||||
|
||||
constructor(
|
||||
@ -228,26 +228,26 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
return AnnotationUtils.getDictionary(annotation);
|
||||
}
|
||||
|
||||
// async getText(pageNumber: number, rect) {
|
||||
// const viewerObject = this._viewerSyncService.activeViewerObject;
|
||||
//
|
||||
// const { PDFNet } = viewerObject;
|
||||
// await PDFNet.initialize();
|
||||
// const pdfDoc = await viewerObject.docViewer.getDocument().getPDFDoc();
|
||||
// const txt = await PDFNet.TextExtractor.create();
|
||||
// await txt.begin(await pdfDoc.getPage(pageNumber), rect);
|
||||
//
|
||||
// // Extract words one by one.
|
||||
// let text = '';
|
||||
// let line = await txt.getFirstLine();
|
||||
// for (; (await line.isValid()); line = (await line.getNextLine())) {
|
||||
// for (let word = await line.getFirstWord(); (await word.isValid()); word = (await word.getNextWord())) {
|
||||
// await word.getString();
|
||||
// text += word;
|
||||
// }
|
||||
// }
|
||||
// console.log(text);
|
||||
// }
|
||||
acceptSuggestionAnnotation($event: MouseEvent, annotation: Annotations.Annotation) {
|
||||
$event.stopPropagation();
|
||||
const dialogRef = this._dialog.open(ConfirmationDialogComponent, {
|
||||
width: '400px',
|
||||
maxWidth: '90vw'
|
||||
});
|
||||
|
||||
const parts = annotation.Id.split(':');
|
||||
const annotationId = parts[parts.length - 1];
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
this._manualRedactionControllerService.approveRequest(this.appStateService.activeProjectId, this.appStateService.activeFile.fileId, annotationId).subscribe(ok => {
|
||||
this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.confirm-annotation.success.label'), null, NotificationType.SUCCESS);
|
||||
}, (err) => {
|
||||
this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.confirm-annotation.failed.label', err), null, NotificationType.ERROR);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
suggestRemoveAnnotation($event: MouseEvent, annotation: Annotations.Annotation) {
|
||||
$event.stopPropagation();
|
||||
@ -256,10 +256,8 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
maxWidth: '90vw'
|
||||
});
|
||||
|
||||
console.log(annotation);
|
||||
|
||||
const parts = annotation.Id.split(':');
|
||||
const annotationId = parts[parts.length-1];
|
||||
const annotationId = parts[parts.length - 1];
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
@ -315,4 +313,9 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
$event.stopPropagation();
|
||||
this.expandedFilters[key] = value;
|
||||
}
|
||||
|
||||
isManuallyAddedAnnotation(annotation: Annotations.Annotation) {
|
||||
return annotation.Id.indexOf('request:') >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<section class="dialog">
|
||||
<form (submit)="saveManualRedaction()" [formGroup]="redactionForm">
|
||||
<form (submit)="handleAddRedaction()" [formGroup]="redactionForm">
|
||||
<div
|
||||
class="dialog-header heading-l" translate="manual-redaction.dialog.header.label">
|
||||
|
||||
@ -15,13 +15,15 @@
|
||||
|
||||
<div class="red-input-group">
|
||||
<label translate="manual-redaction.dialog.content.reason.label"></label>
|
||||
<textarea formControlName="reason" name="reason" type="text" rows="3"></textarea>
|
||||
<textarea formControlName="reason" name="reason" type="text" rows="2"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="red-input-group">
|
||||
<mat-checkbox
|
||||
formControlName="addToDictionary">{{'manual-redaction.dialog.content.dictionary.add.label' | translate}}</mat-checkbox>
|
||||
<label translate="manual-redaction.dialog.content.comment.label"></label>
|
||||
<textarea formControlName="comment" name="comment" type="text" rows="2"></textarea>
|
||||
</div>
|
||||
<mat-form-field [class.hidden]="showDictionary">
|
||||
|
||||
<mat-form-field >
|
||||
<mat-label>{{'manual-redaction.dialog.content.dictionary.label' | translate}}</mat-label>
|
||||
<mat-select formControlName="dictionary">
|
||||
<mat-option *ngFor="let dictionary of dictionaries | async" [value]="dictionary.type">
|
||||
@ -30,6 +32,12 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="red-input-group">
|
||||
<mat-checkbox
|
||||
formControlName="addToDictionary">{{'manual-redaction.dialog.content.dictionary.add.label' | translate}}</mat-checkbox>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
|
||||
@ -6,13 +6,13 @@ import {
|
||||
AddRedactionRequest,
|
||||
DictionaryControllerService,
|
||||
ManualRedactionControllerService,
|
||||
ManualRedactionEntry,
|
||||
TypeValue
|
||||
} from "@redaction/red-ui-http";
|
||||
import {NotificationService, NotificationType} from "../../../notification/notification.service";
|
||||
import {TranslateService} from "@ngx-translate/core";
|
||||
import {map} from "rxjs/operators";
|
||||
import {Observable} from "rxjs";
|
||||
import {UserService} from "../../../user/user.service";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -24,9 +24,11 @@ export class ManualRedactionDialogComponent implements OnInit {
|
||||
|
||||
redactionForm: FormGroup;
|
||||
dictionaries: Observable<Array<TypeValue>>;
|
||||
isDocumentAdmin: boolean;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
private readonly _notificationService: NotificationService,
|
||||
private readonly _translateService: TranslateService,
|
||||
@ -37,38 +39,56 @@ export class ManualRedactionDialogComponent implements OnInit {
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.isDocumentAdmin = (this._appStateService.isActiveProjectOwner || this._appStateService.isActiveFileDocumentReviewer) && this._userService.user.isManager;
|
||||
const commentField = this.isDocumentAdmin ? [null] : [null, Validators.required];
|
||||
this.redactionForm = this._formBuilder.group({
|
||||
addToDictionary: [false],
|
||||
reason: [null, Validators.required],
|
||||
dictionary: null,
|
||||
dictionary: [null, Validators.required],
|
||||
comment: commentField,
|
||||
});
|
||||
this.dictionaries = this._dictionaryControllerService.getAllTypes().pipe(map(r => r.types));
|
||||
}
|
||||
|
||||
|
||||
saveManualRedaction() {
|
||||
handleAddRedaction() {
|
||||
if (this.isDocumentAdmin) {
|
||||
this.addManualRedaction();
|
||||
} else {
|
||||
this.suggestManualRedaction()
|
||||
}
|
||||
}
|
||||
|
||||
suggestManualRedaction() {
|
||||
const mre = Object.assign({}, this.addRedactionRequest);
|
||||
this._enhanceManualRedaction(mre);
|
||||
mre.comment = {
|
||||
text: 'Lorem ipsum'
|
||||
};
|
||||
this._manualRedactionControllerService.requestAddRedaction(mre, this._appStateService.activeProject.project.projectId, this._appStateService.activeFile.fileId).subscribe(ok => {
|
||||
this._appStateService.reanalyseActiveFile();
|
||||
this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.dialog.add-redaction.success.label'), null, NotificationType.SUCCESS);
|
||||
this.dialogRef.close();
|
||||
}, (err) => {
|
||||
this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.dialog.add-redaction.failed.label', err), null, NotificationType.ERROR);
|
||||
});
|
||||
}
|
||||
|
||||
addManualRedaction() {
|
||||
const mre = Object.assign({}, this.addRedactionRequest);
|
||||
this._enhanceManualRedaction(mre);
|
||||
this._manualRedactionControllerService.addRedaction(mre, this._appStateService.activeProject.project.projectId, this._appStateService.activeFile.fileId).subscribe(ok => {
|
||||
this._appStateService.reanalyseActiveFile();
|
||||
this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.dialog.add-redaction.success.label'), null, NotificationType.SUCCESS);
|
||||
this.dialogRef.close();
|
||||
}, (err) => {
|
||||
this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.dialog.add-redaction.failed.label', err), null, NotificationType.ERROR);
|
||||
});
|
||||
}
|
||||
|
||||
private _enhanceManualRedaction(addRedactionRequest: AddRedactionRequest) {
|
||||
addRedactionRequest.type = this.redactionForm.get('dictionary').value;
|
||||
addRedactionRequest.addToDictionary = this.redactionForm.get('addToDictionary').value;
|
||||
addRedactionRequest.reason = this.redactionForm.get('reason').value;
|
||||
}
|
||||
|
||||
get showDictionary() {
|
||||
return !this.redactionForm.get('addToDictionary').value
|
||||
const commentValue = this.redactionForm.get('comment').value;
|
||||
addRedactionRequest.comment = commentValue ? {text: commentValue} : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import {ViewerSyncService} from '../service/viewer-sync.service';
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {FileDownloadService} from "../service/file-download.service";
|
||||
import {FileType} from "../model/file-type";
|
||||
import {AppStateService} from "../../../state/app-state.service";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -41,6 +42,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
_fileData: Blob;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _viewerSyncService: ViewerSyncService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _fileDownloadService: FileDownloadService,
|
||||
@ -65,7 +67,6 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private _loadViewer(pdfBlob: any) {
|
||||
const license = this._appConfigService.getConfig(AppConfigKey.PDFTRON_LICENSE);
|
||||
WebViewer({
|
||||
@ -97,7 +98,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
});
|
||||
|
||||
instance.docViewer.on('documentLoaded', this.wvDocumentLoadedHandler);
|
||||
instance.loadDocument(pdfBlob, {filename: this.fileStatus ? this.fileStatus.filename : 'file.pdf'});
|
||||
instance.loadDocument(pdfBlob, {filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'});
|
||||
});
|
||||
}
|
||||
|
||||
@ -122,7 +123,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
private _configureTextPopup() {
|
||||
this.wvInstance.textPopup.add(<any>{
|
||||
type: 'actionButton',
|
||||
img: '/assets/icons/general/add.svg',
|
||||
img: '/assets/icons/general/add-redaction.svg',
|
||||
title: this._translateService.instant('pdf-viewer.text-popup.actions.suggestion-redaction.label'),
|
||||
onClick: () => {
|
||||
const selectedQuads = this.wvInstance.docViewer.getSelectedTextQuads();
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {FileStatus, Project, ProjectControllerService, StatusControllerService} from "@redaction/red-ui-http";
|
||||
import {
|
||||
FileStatus,
|
||||
Project,
|
||||
ProjectControllerService,
|
||||
ReanalysisControllerService,
|
||||
StatusControllerService
|
||||
} from "@redaction/red-ui-http";
|
||||
import {NotificationService, NotificationType} from "../notification/notification.service";
|
||||
import {TranslateService} from "@ngx-translate/core";
|
||||
import {Router} from "@angular/router";
|
||||
import {UserService} from "../user/user.service";
|
||||
|
||||
|
||||
export interface AppState {
|
||||
@ -35,8 +42,10 @@ export class AppStateService {
|
||||
|
||||
constructor(
|
||||
private readonly _router: Router,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _projectControllerService: ProjectControllerService,
|
||||
private readonly _notificationService: NotificationService,
|
||||
private readonly _reanalysisControllerService: ReanalysisControllerService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _statusControllerService: StatusControllerService) {
|
||||
this._appState = {
|
||||
@ -46,6 +55,20 @@ export class AppStateService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get isActiveProjectOwner() {
|
||||
return this._appState.activeProject.project.ownerId == this._userService.userId
|
||||
}
|
||||
|
||||
get isActiveProjectMember() {
|
||||
return this._appState.activeProject.project.memberIds.indexOf(this._userService.userId) >= 0;
|
||||
}
|
||||
|
||||
get isActiveFileDocumentReviewer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
get aggregatedFiles(): FileStatus[] {
|
||||
const result: FileStatus[] = [];
|
||||
this._appState.projects.forEach(p => {
|
||||
@ -187,4 +210,9 @@ export class AppStateService {
|
||||
await this.loadAllProjects();
|
||||
}
|
||||
}
|
||||
|
||||
async reanalyseActiveFile() {
|
||||
await this._reanalysisControllerService.reanalyzeFile(this._appState.activeProject.project.projectId, this._appState.activeFile.fileId).toPromise();
|
||||
await this.reloadActiveProjectFiles();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { KeycloakProfile } from 'keycloak-js';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {KeycloakService} from 'keycloak-angular';
|
||||
import {KeycloakProfile} from 'keycloak-js';
|
||||
import jwt_decode from 'jwt-decode';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import {User, UserControllerService} from '@redaction/red-ui-http';
|
||||
|
||||
export class UserWrapper {
|
||||
|
||||
@ -48,6 +48,9 @@ export class UserService {
|
||||
this._keycloakService.logout(window.location.origin);
|
||||
}
|
||||
|
||||
get userId() {
|
||||
return this._currentUser.id;
|
||||
}
|
||||
|
||||
get allUsers() {
|
||||
return this._allUsers;
|
||||
|
||||
@ -17,6 +17,14 @@
|
||||
}
|
||||
},
|
||||
"manual-redaction": {
|
||||
"confirm-annotation": {
|
||||
"success": {
|
||||
"label": "Annotation Confirmed!"
|
||||
},
|
||||
"failed": {
|
||||
"label": "Error confirming Annotation removal!"
|
||||
}
|
||||
},
|
||||
"remove-annotation": {
|
||||
"success": {
|
||||
"label": "Annotation Suggested for removal!"
|
||||
@ -50,10 +58,13 @@
|
||||
"add": {
|
||||
"label": "Add to dictionary"
|
||||
},
|
||||
"label": "Dictionary"
|
||||
"label": "Type"
|
||||
},
|
||||
"reason": {
|
||||
"label": "Reason"
|
||||
},
|
||||
"comment": {
|
||||
"label": "Comment"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
apps/red-ui/src/assets/icons/general/add-redaction.svg
Normal file
13
apps/red-ui/src/assets/icons/general/add-redaction.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg id="Capa_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="rgb(136,142,149)">
|
||||
<path d="m0 0h406.333v90.667h-406.333z"/>
|
||||
<path d="m406.333 240.666v-44.999h-406.333v120.667h284.679c22.182-44.793 68.376-75.668 121.654-75.668z"/>
|
||||
<path d="m278.347 421.333h-278.347v90.667h406.333c-59.039 0-109.382-37.912-127.986-90.667z"/>
|
||||
<path d="m60 113.167c-16.569 0-30 13.431-30 30s13.431 30 30 30h286.333c16.569 0 30-13.431 30-30s-13.431-30-30-30z"/>
|
||||
<path
|
||||
d="m275.941 338.833h-215.941c-16.569 0-30 13.431-30 30s13.431 30 30 30h212.542c-1.227-7.321-1.876-14.836-1.876-22.5 0-13.004 1.843-25.585 5.275-37.5z"/>
|
||||
<path
|
||||
d="m406.333 270.666c-58.265 0-105.667 47.402-105.667 105.667s47.402 105.667 105.667 105.667 105.667-47.402 105.667-105.667-47.402-105.667-105.667-105.667zm60.334 120.667h-45.167v45.333h-30v-45.333h-45.167v-30h45.167v-45h30v45h45.167z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 982 B |
@ -1 +0,0 @@
|
||||
<svg id="Capa_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m0 0h406.333v90.667h-406.333z"/><path d="m406.333 240.666v-44.999h-406.333v120.667h284.679c22.182-44.793 68.376-75.668 121.654-75.668z"/><path d="m278.347 421.333h-278.347v90.667h406.333c-59.039 0-109.382-37.912-127.986-90.667z"/><path d="m60 113.167c-16.569 0-30 13.431-30 30s13.431 30 30 30h286.333c16.569 0 30-13.431 30-30s-13.431-30-30-30z"/><path d="m275.941 338.833h-215.941c-16.569 0-30 13.431-30 30s13.431 30 30 30h212.542c-1.227-7.321-1.876-14.836-1.876-22.5 0-13.004 1.843-25.585 5.275-37.5z"/><path d="m406.333 270.666c-58.265 0-105.667 47.402-105.667 105.667s47.402 105.667 105.667 105.667 105.667-47.402 105.667-105.667-47.402-105.667-105.667-105.667zm60.334 120.667h-45.167v45.333h-30v-45.333h-45.167v-30h45.167v-45h30v45h45.167z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 903 B |
10
apps/red-ui/src/assets/icons/general/check-alt.svg
Normal file
10
apps/red-ui/src/assets/icons/general/check-alt.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
viewBox="0 0 426.667 426.667" style="enable-background:new 0 0 426.667 426.667;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M421.876,56.307c-6.548-6.78-17.352-6.968-24.132-0.42c-0.142,0.137-0.282,0.277-0.42,0.42L119.257,334.375
|
||||
l-90.334-90.334c-6.78-6.548-17.584-6.36-24.132,0.42c-6.388,6.614-6.388,17.099,0,23.713l102.4,102.4
|
||||
c6.665,6.663,17.468,6.663,24.132,0L421.456,80.44C428.236,73.891,428.424,63.087,421.876,56.307z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 535 B |
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>document</title>
|
||||
<g id="document" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M90,0 L90,100 L10,100 L10,0 L90,0 Z M80,10 L20,10 L20,90 L80,90 L80,10 Z M50,60 L50,70 L30,70 L30,60 L50,60 Z M70,40 L70,50 L30,50 L30,40 L70,40 Z M70,20 L70,30 L30,30 L30,20 L70,20 Z" id="Combined-Shape" fill="#283241" fill-rule="nonzero"></path>
|
||||
<g id="document" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd">
|
||||
<path d="M90,0 L90,100 L10,100 L10,0 L90,0 Z M80,10 L20,10 L20,90 L80,90 L80,10 Z M50,60 L50,70 L30,70 L30,60 L50,60 Z M70,40 L70,50 L30,50 L30,40 L70,40 Z M70,20 L70,30 L30,30 L30,20 L70,20 Z" id="Combined-Shape" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 581 B After Width: | Height: | Size: 576 B |
Loading…
x
Reference in New Issue
Block a user