TSK-289 Create select types component and refactor when it is used.

This commit is contained in:
Martin Rojas Miguel Angel 2018-02-21 12:01:31 +01:00 committed by Holger Hagen
parent da53c87a68
commit cdb9f0b44e
19 changed files with 148 additions and 48 deletions

View File

@ -27,6 +27,7 @@ import { WorkbasketInformationComponent } from './workbasket/details/information
import { NoAccessComponent } from './workbasket/noAccess/no-access.component'; import { NoAccessComponent } from './workbasket/noAccess/no-access.component';
import { SpinnerComponent } from './shared/spinner/spinner.component'; import { SpinnerComponent } from './shared/spinner/spinner.component';
import { FilterComponent } from './shared/filter/filter.component'; import { FilterComponent } from './shared/filter/filter.component';
import { IconTypeComponent } from './shared/type-icon/icon-type.component';
//Shared //Shared
import { MasterAndDetailComponent} from './shared/masterAndDetail/master-and-detail.component'; import { MasterAndDetailComponent} from './shared/masterAndDetail/master-and-detail.component';
@ -44,7 +45,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
* Pipes * Pipes
*/ */
import { MapValuesPipe } from './pipes/map-values.pipe'; import { MapValuesPipe } from './pipes/map-values.pipe';
import { RemoveNoneTypePipe } from './pipes/remove-none-type';
const MODULES = [ const MODULES = [
BrowserModule, BrowserModule,
@ -72,7 +73,9 @@ const DECLARATIONS = [
NoAccessComponent, NoAccessComponent,
SpinnerComponent, SpinnerComponent,
FilterComponent, FilterComponent,
MapValuesPipe IconTypeComponent,
MapValuesPipe,
RemoveNoneTypePipe
]; ];
@NgModule({ @NgModule({

View File

@ -0,0 +1,16 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({name: 'removeNoneType'})
export class RemoveNoneTypePipe implements PipeTransform {
transform(value: any): Object[] {
let returnArray = [];
value.forEach((entry) => {
if(entry.key !== 'NONE')
returnArray.push({
key: entry.key,
value: entry.value
});
});
return returnArray;
}
}

View File

@ -1,22 +1,14 @@
<div type="text" id="{{target}}" class="list-group-seach collapse"> <div type="text" id="{{target}}" class="list-group-seach collapse">
<div class="row"> <div class="row">
<div class="dropdown col-xs-2"> <div class="dropdown col-xs-2">
<button class="btn btn-default {{!filter.type? 'glyphicon glyphicon-asterisk blue' : '' }}" type="button" id="dropdownMenufilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <button class="btn btn-default" type="button" id="dropdownMenufilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<svg-icon *ngIf="filter.type" class="small blue" src="./assets/icons/{{(filter.type === 'PERSONAL')? 'user.svg': (filter.type === 'GROUP')? 'users.svg' :''}}"></svg-icon> <taskana-icon-type [type] ="filter.type" class="vertical-align"></taskana-icon-type>
</button> </button>
<ul class="dropdown-menu dropdown-menu-users" role="menu"> <ul class="dropdown-menu dropdown-menu-users" role="menu">
<li> <li *ngFor ="let type of allTypes | mapValues">
<button type="button" (click)="selectType(-1)" placeholder="individual" class="btn btn-default glyphicon glyphicon-asterisk btn-users-list blue" data-toggle="tooltip" title="all"> <button type="button" (click)="selectType(type.key)" class="btn btn-default btn-users-list" data-toggle="tooltip" [title]="type.value">
</button> <taskana-icon-type class="vertical-align" [type] ='type.key'></taskana-icon-type>
</li>
<li>
<button type="button" (click)="selectType(0)" placeholder="individual" class="btn btn-default btn-users-list" data-toggle="tooltip" title="individual">
<svg-icon class="small blue" src="./assets/icons/user.svg"></svg-icon>
</button>
</li>
<li>
<button type="button" (click)="selectType(1)" placeholder="group" data-toggle="tooltip" title="group" class="btn btn-default btn-users-list">
<svg-icon class="small blue" src="./assets/icons/users.svg"></svg-icon>
</button> </button>
</li> </li>
</ul> </ul>
@ -28,7 +20,7 @@
<input type="text" [(ngModel)]= "filter.key" (keyup.enter)="search()" class="form-control" id="wb-display-key-filter" placeholder="Filter key"> <input type="text" [(ngModel)]= "filter.key" (keyup.enter)="search()" class="form-control" id="wb-display-key-filter" placeholder="Filter key">
</div> </div>
<button (click)="clear()" type="button" <button (click)="clear()" type="button"
class="btn btn-default glyphicon glyphicon-remove-circle blue pull-right margin-right" data-toggle="tooltip" title="Clear"> class="btn btn-default glyphicon glyphicon-ban-circle blue pull-right margin-right" data-toggle="tooltip" title="Clear">
</button> </button>
</div> </div>
<div class="row"> <div class="row">
@ -47,5 +39,5 @@
<button (click)="search()" type="button" <button (click)="search()" type="button"
class="btn btn-default glyphicon glyphicon-search blue pull-right margin-right" data-toggle="tooltip" title="Search"> class="btn btn-default glyphicon glyphicon-search blue pull-right margin-right" data-toggle="tooltip" title="Search">
</button> </button>
</div> </div>
</div> </div>

View File

@ -1,4 +1,3 @@
.dropdown-menu-users { .dropdown-menu-users {
&>li{ &>li{
margin-bottom: 5px; margin-bottom: 5px;

View File

@ -3,8 +3,9 @@ import { FormsModule } from '@angular/forms';
import { AngularSvgIconModule } from 'angular-svg-icon'; import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http'; import { HttpModule } from '@angular/http';
import { IconTypeComponent } from '../type-icon/icon-type.component';
import { FilterComponent, FilterModel } from './filter.component'; import { FilterComponent, FilterModel } from './filter.component';
import { MapValuesPipe } from '../../pipes/map-values.pipe';
describe('FilterComponent', () => { describe('FilterComponent', () => {
let component: FilterComponent, let component: FilterComponent,
@ -14,7 +15,7 @@ describe('FilterComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ FilterComponent ], declarations: [ FilterComponent, IconTypeComponent, MapValuesPipe ],
imports: [AngularSvgIconModule, FormsModule, HttpClientModule, HttpModule ] imports: [AngularSvgIconModule, FormsModule, HttpClientModule, HttpModule ]
}) })
.compileComponents(); .compileComponents();

View File

@ -1,4 +1,5 @@
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core'; import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { IconTypeComponent, ICONTYPES } from '../type-icon/icon-type.component'
export class FilterModel { export class FilterModel {
type:string; type:string;
@ -22,8 +23,10 @@ export class FilterModel {
}) })
export class FilterComponent{ export class FilterComponent{
constructor() { } constructor() {
this.allTypes = IconTypeComponent.allTypes;
}
allTypes: Map<string, string>;
filter: FilterModel = new FilterModel(); filter: FilterModel = new FilterModel();
@Input() @Input()
@ -32,8 +35,8 @@ export class FilterComponent{
@Output() @Output()
performFilter = new EventEmitter<FilterModel>(); performFilter = new EventEmitter<FilterModel>();
selectType(type: number){ selectType(type: ICONTYPES){
this.filter.type = type === 0 ? 'PERSONAL': type === 1? 'GROUP': ''; this.filter.type = type;
} }
clear(){ clear(){

View File

@ -0,0 +1,2 @@
<svg-icon *ngIf="type !== 'NONE'" class="{{selected? 'white': 'blue' }} small" src="./assets/icons/{{type === 'PERSONAL'? 'user.svg': type === 'GROUP'? 'users.svg' : type === 'TOPIC'? 'topic.svg' : 'clearance.svg'}}"></svg-icon>
<div *ngIf="type === 'NONE'" class = "glyphicon glyphicon-asterisk blue"></div>

After

Width:  |  Height:  |  Size: 310 B

View File

@ -0,0 +1,28 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { IconTypeComponent } from './icon-type.component';
describe('IconTypeComponent', () => {
let component: IconTypeComponent;
let fixture: ComponentFixture<IconTypeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports:[AngularSvgIconModule,HttpClientModule, HttpModule],
declarations: [ IconTypeComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(IconTypeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,36 @@
import { Component, OnInit, Input } from '@angular/core';
export enum ICONTYPES {
NONE = 'NONE',
PERSONAL = 'PERSONAL',
GROUP = 'GROUP',
CLEARANCE = 'CLEARANCE',
TOPIC = 'TOPIC'
}
@Component({
selector: 'taskana-icon-type',
templateUrl: './icon-type.component.html',
styleUrls: ['./icon-type.component.scss']
})
export class IconTypeComponent implements OnInit {
public static get allTypes(): Map<string, string> { return new Map([['NONE', 'None'], ['PERSONAL', 'Personal'], ['GROUP', 'Group'], ['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']])};
constructor() { }
@Input()
type: ICONTYPES = ICONTYPES.PERSONAL;
@Input()
selected: boolean = false;
@Input()
tooltip: boolean = false;
ngOnInit() {
}
}

View File

@ -20,14 +20,16 @@
<label for="wb-type" class="control-label">Type</label> <label for="wb-type" class="control-label">Type</label>
<div class="dropdown clearfix btn-group"> <div class="dropdown clearfix btn-group">
<button class="btn btn-default" type="button" id="dropdownMenu24" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <button class="btn btn-default" type="button" id="dropdownMenu24" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<svg-icon class="small blue" src="./assets/icons/{{workbasket.type === 'PERSONAL'? 'user.svg': 'users.svg'}}"></svg-icon> <taskana-icon-type class="vertical-align" [type] ='workbasket.type'></taskana-icon-type>
{{workbasket.type === 'PERSONAL'? 'Individual': 'Multiple'}} {{allTypes.get(workbasket.type)}}
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu dropdown-menu" aria-labelledby="dropdownMenu1"> <ul class="dropdown-menu dropdown-menu" aria-labelledby="dropdownMenu1">
<li> <li>
<a (click)="selectType(0)"> <svg-icon class="small blue" src="./assets/icons/user.svg"></svg-icon> Individual </a> <a *ngFor="let type of allTypes | mapValues | removeNoneType" (click)="selectType(type.key)">
<a (click)="selectType(1)"> <svg-icon class="small blue" src="./assets/icons/users.svg"></svg-icon> Multiple </a> <taskana-icon-type class="vertical-align" [type] ='type.key'></taskana-icon-type>
{{type.value}}
</a>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -6,6 +6,10 @@ import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { HttpModule, JsonpModule } from '@angular/http'; import { HttpModule, JsonpModule } from '@angular/http';
import { Workbasket } from 'app/model/workbasket'; import { Workbasket } from 'app/model/workbasket';
import { ICONTYPES, IconTypeComponent } from '../../../shared/type-icon/icon-type.component';
import { MapValuesPipe } from '../../../pipes/map-values.pipe';
import { RemoveNoneTypePipe } from '../../../pipes/remove-none-type';
describe('InformationComponent', () => { describe('InformationComponent', () => {
@ -15,19 +19,16 @@ describe('InformationComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ WorkbasketInformationComponent ], declarations: [ WorkbasketInformationComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe],
imports:[FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule], imports:[FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
providers:[WorkbasketService] providers:[WorkbasketService]
}) })
.compileComponents(); .compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WorkbasketInformationComponent); fixture = TestBed.createComponent(WorkbasketInformationComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement; debugElement = fixture.debugElement.nativeElement;
}); }));
afterEach(() =>{ afterEach(() =>{
document.body.removeChild(debugElement); document.body.removeChild(debugElement);
@ -49,13 +50,13 @@ describe('InformationComponent', () => {
})); }));
it('selectType should set workbasket.type to personal with 0 and multiple in other case', () => { it('selectType should set workbasket.type to personal with 0 and group in other case', () => {
component.workbasket = new Workbasket(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); component.workbasket = new Workbasket(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
expect(component.workbasket.type).toEqual(null); expect(component.workbasket.type).toEqual(null);
component.selectType(0); component.selectType(ICONTYPES.PERSONAL);
expect(component.workbasket.type).toEqual('PERSONAL'); expect(component.workbasket.type).toEqual('PERSONAL');
component.selectType(1); component.selectType(ICONTYPES.GROUP);
expect(component.workbasket.type).toEqual('MULTIPLE'); expect(component.workbasket.type).toEqual('GROUP');
}); });
}); });

View File

@ -1,6 +1,7 @@
import { Component, OnInit, Input, Output } from '@angular/core'; import { Component, OnInit, Input, Output } from '@angular/core';
import { Workbasket } from '../../../model/workbasket'; import { Workbasket } from '../../../model/workbasket';
import { WorkbasketService } from '../../../services/workbasketservice.service'; import { WorkbasketService } from '../../../services/workbasketservice.service';
import { IconTypeComponent, ICONTYPES } from '../../../shared/type-icon/icon-type.component';
@Component({ @Component({
selector: 'workbasket-information', selector: 'workbasket-information',
@ -11,13 +12,15 @@ export class WorkbasketInformationComponent implements OnInit {
@Input() @Input()
workbasket: Workbasket; workbasket: Workbasket;
allTypes: Map<string, string>;
constructor(private service: WorkbasketService) { } constructor(private service: WorkbasketService) {
this.allTypes = IconTypeComponent.allTypes;
}
ngOnInit() { ngOnInit() {
} }
selectType(type: number){ selectType(type: ICONTYPES){
this.workbasket.type = type === 0 ? 'PERSONAL': 'MULTIPLE'; this.workbasket.type = type;
} }
} }

View File

@ -5,6 +5,9 @@ import { WorkbasketInformationComponent } from './information/workbasket-informa
import { Workbasket } from 'app/model/workbasket'; import { Workbasket } from 'app/model/workbasket';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { SpinnerComponent } from '../../shared/spinner/spinner.component'; import { SpinnerComponent } from '../../shared/spinner/spinner.component';
import { ICONTYPES, IconTypeComponent } from '../../shared/type-icon/icon-type.component';
import { MapValuesPipe } from '../../pipes/map-values.pipe';
import { RemoveNoneTypePipe } from '../../pipes/remove-none-type';
import { WorkbasketService } from '../../services/workbasketservice.service'; import { WorkbasketService } from '../../services/workbasketservice.service';
import { MasterAndDetailService } from '../../services/master-and-detail.service'; import { MasterAndDetailService } from '../../services/master-and-detail.service';
@ -26,7 +29,7 @@ describe('WorkbasketDetailsComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports:[RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule], imports:[RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [ WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent ], declarations: [ WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe ],
providers:[WorkbasketService, MasterAndDetailService, PermissionService] providers:[WorkbasketService, MasterAndDetailService, PermissionService]
}) })
.compileComponents(); .compileComponents();

View File

@ -63,7 +63,9 @@
<li class="list-group-item" *ngFor= "let workbasket of workbaskets" [class.active]="workbasket.workbasketId == selectedId" type="text" (click) ="selectWorkbasket(workbasket.workbasketId)" [routerLink]="[ {outlets: { detail: [workbasket.workbasketId] } }]"> <li class="list-group-item" *ngFor= "let workbasket of workbaskets" [class.active]="workbasket.workbasketId == selectedId" type="text" (click) ="selectWorkbasket(workbasket.workbasketId)" [routerLink]="[ {outlets: { detail: [workbasket.workbasketId] } }]">
<div class="row"> <div class="row">
<dl class="col-xs-1"> <dl class="col-xs-1">
<dt><svg-icon class="{{workbasket.workbasketId === selectedId? 'white': 'blue' }} small" src="./assets/icons/{{workbasket.type === 'PERSONAL'? 'user.svg': 'users.svg'}}"></svg-icon></dt> <dt>
<taskana-icon-type class="vertical-align" [type] ="workbasket.type" [selected] = "workbasket.workbasketId === selectedId" ></taskana-icon-type>
</dt>
</dl> </dl>
<dl class="col-xs-10"> <dl class="col-xs-10">
<dt>{{workbasket.name}} ({{workbasket.key}}) </dt> <dt>{{workbasket.name}} ({{workbasket.key}}) </dt>

View File

@ -10,8 +10,11 @@ import { Router, Routes } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { SpinnerComponent } from '../../shared/spinner/spinner.component'; import { SpinnerComponent } from '../../shared/spinner/spinner.component';
import { MapValuesPipe } from '../../pipes/map-values.pipe';
import { FilterModel } from '../../shared/filter/filter.component'; import { FilterModel } from '../../shared/filter/filter.component';
import { IconTypeComponent } from '../../shared/type-icon/icon-type.component';
import { RemoveNoneTypePipe } from '../../pipes/remove-none-type';
import { MapValuesPipe } from '../../pipes/map-values.pipe';
@Component({ @Component({
selector: 'dummy-detail', selector: 'dummy-detail',
@ -30,7 +33,7 @@ export class FilterComponent {
} }
const workbasketSummary: WorkbasketSummary[] = [ new WorkbasketSummary("1", "key1", "NAME1", "description 1", "owner 1", "", "", "PERSONAL", "", "", "", ""), const workbasketSummary: WorkbasketSummary[] = [ new WorkbasketSummary("1", "key1", "NAME1", "description 1", "owner 1", "", "", "PERSONAL", "", "", "", ""),
new WorkbasketSummary("2", "key2", "NAME2", "description 2", "owner 2", "", "", "MULTIPLE", "", "", "", "") new WorkbasketSummary("2", "key2", "NAME2", "description 2", "owner 2", "", "", "GROUP", "", "", "", "")
]; ];
@ -47,7 +50,7 @@ describe('WorkbasketListComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ WorkbasketListComponent, DummyDetailComponent, MapValuesPipe, SpinnerComponent, FilterComponent], declarations: [ WorkbasketListComponent, DummyDetailComponent, MapValuesPipe, SpinnerComponent, FilterComponent, RemoveNoneTypePipe, IconTypeComponent],
imports:[ imports:[
AngularSvgIconModule, AngularSvgIconModule,
HttpModule, HttpModule,

View File

@ -247,3 +247,7 @@ li > div.row > dl {
taskana-spinner.centered-horizontally > div { taskana-spinner.centered-horizontally > div {
margin-top: calc(50vh - 250px); margin-top: calc(50vh - 250px);
} }
.vertical-align{
vertical-align: middle;
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M6.873 15.967a8.737 8.737 0 0 1-3.447-1.37c-.655-.445-1.546-1.336-1.99-1.992C.93 11.86.416 10.723.213 9.901c-.238-.966-.257-2.67-.04-3.609A8.135 8.135 0 0 1 6.286.178C7.23-.039 8.933-.02 9.894.217a8.404 8.404 0 0 1 3.781 2.137 8.418 8.418 0 0 1 2.137 3.782c.254 1.022.254 2.743 0 3.765a8.418 8.418 0 0 1-2.137 3.782c-.996.997-2.41 1.8-3.74 2.124-.776.19-2.358.272-3.062.16zm2.86-1.158c2.766-.762 4.74-2.932 5.187-5.702.12-.743.06-2.141-.122-2.81-.746-2.754-2.93-4.742-5.698-5.188-.743-.12-2.14-.06-2.809.122-2.753.746-4.74 2.93-5.187 5.7-.12.742-.06 2.14.122 2.809.72 2.656 2.736 4.57 5.421 5.147.682.147 2.43.102 3.086-.078zm-2.444-2.856v-.883h1.686v1.766H7.29zm.014-2.432c.045-1.035.244-1.373 1.428-2.426.497-.441.957-.908 1.024-1.036.195-.375.104-1.038-.184-1.342-.31-.326-.568-.453-1.054-.517-.88-.117-1.774.419-2.03 1.216-.055.173-.123.34-.15.37-.028.031-.421.016-.874-.033l-.823-.09V5.44c0-.767.824-1.88 1.714-2.318.68-.334 1.61-.465 2.443-.344.938.137 1.476.37 2.024.878.636.589.906 1.14.91 1.859.005.942-.334 1.484-1.643 2.627-.437.38-.851.804-.922.94-.07.137-.147.46-.17.717l-.043.469H7.27z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M13.327.011H2.68A2.666 2.666 0 0 0 .017 2.674v7.989a2.665 2.665 0 0 0 2.662 2.662h2.386l2.467 2.469a.662.662 0 0 0 .942 0l2.467-2.469h2.386a2.665 2.665 0 0 0 2.662-2.662v-7.99A2.666 2.666 0 0 0 13.327.012zm1.33 10.652c0 .733-.596 1.332-1.331 1.332h-2.66l-.034.001h-.01l-.023.002-.016.002-.016.001-.02.004-.013.001-.02.005c-.003.002-.008.002-.011.003l-.02.005c-.003.002-.008.002-.01.004-.007.001-.014.003-.019.006l-.013.005-.016.006-.015.005-.015.007-.014.006-.013.007-.017.008-.013.007a.143.143 0 0 1-.016.01l-.013.008-.015.01-.013.01-.013.009a.114.114 0 0 0-.016.013l-.01.008-.023.02-.001.001c-.01.008-.018.017-.026.025l-2.189 2.188-2.19-2.19-.026-.024-.002-.002-.023-.02-.01-.006c-.004-.005-.011-.008-.016-.013l-.013-.01-.013-.01-.015-.01-.013-.008a.051.051 0 0 0-.016-.008c-.005-.001-.008-.005-.013-.006-.005-.004-.01-.005-.016-.008l-.013-.007-.015-.006-.015-.007-.013-.005-.016-.006-.013-.005-.018-.007c-.003-.001-.008-.001-.011-.003l-.02-.005c-.003-.002-.008-.002-.011-.003l-.02-.005c-.005-.002-.008-.002-.013-.002l-.02-.003-.016-.002L5.407 12l-.023-.002h-.01l-.034-.002H2.68a1.333 1.333 0 0 1-1.332-1.332V2.675c0-.733.597-1.332 1.332-1.332h10.647c.733 0 1.331.597 1.331 1.332z"/><path d="M11.996 3.34H4.01a.665.665 0 1 0 0 1.331h7.986a.666.666 0 0 0 0-1.33zM4.01 7.335h4.658a.666.666 0 0 0 0-1.33H4.01a.665.665 0 1 0 0 1.33zM10.664 8.666H4.01a.665.665 0 1 0 0 1.33h6.654a.666.666 0 0 0 0-1.33z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB