File attributes listing
This commit is contained in:
parent
7d2e9a7b7a
commit
ac8fa0ff52
@ -118,6 +118,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { ForceRedactionDialogComponent } from './dialogs/force-redaction-dialog/force-redaction-dialog.component';
|
||||
import { AuditScreenComponent } from './screens/admin/audit-screen/audit-screen.component';
|
||||
import { PaginationComponent } from './components/pagination/pagination.component';
|
||||
import { FileAttributesListingScreenComponent } from './screens/admin/file-attributes-listing-screen/file-attributes-listing-screen.component';
|
||||
import { SearchInputComponent } from './components/search-input/search-input.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
@ -237,6 +238,14 @@ const routes = [
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'file-attributes',
|
||||
component: FileAttributesListingScreenComponent,
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'watermark',
|
||||
component: WatermarkScreenComponent,
|
||||
@ -392,6 +401,7 @@ const matImports = [
|
||||
ComboSeriesVerticalComponent,
|
||||
AuditScreenComponent,
|
||||
PaginationComponent,
|
||||
FileAttributesListingScreenComponent,
|
||||
SearchInputComponent
|
||||
],
|
||||
imports: [
|
||||
|
||||
@ -7,7 +7,9 @@
|
||||
[disabled]="disabled"
|
||||
[class.small]="small"
|
||||
[class.overlay]="showDot"
|
||||
[class.dummy]="dummy"
|
||||
mat-icon-button
|
||||
[disableRipple]="dummy"
|
||||
>
|
||||
<mat-icon [svgIcon]="icon"></mat-icon>
|
||||
</button>
|
||||
|
||||
@ -36,4 +36,8 @@ button {
|
||||
background-color: $yellow-2;
|
||||
}
|
||||
}
|
||||
|
||||
&.dummy {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ export class CircleButtonComponent implements OnInit {
|
||||
@Input() disabled = false;
|
||||
@Input() small = false;
|
||||
@Input() type: 'default' | 'primary' | 'warn' | 'dark-bg' = 'default';
|
||||
@Input() dummy = false;
|
||||
@Output() action = new EventEmitter<any>();
|
||||
|
||||
constructor() {}
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
|
||||
redaction-circle-button:not(:last-child) {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
<ng-container *ngFor="let tab of tabs">
|
||||
<div
|
||||
class="red-tab"
|
||||
*ngIf="!tab.onlyDevMode || userPreferenceService.areDevFeaturesEnabled"
|
||||
*ngIf="(!tab.onlyAdmin || permissionsService.isAdmin()) && (!tab.onlyDevMode || userPreferenceService.areDevFeaturesEnabled)"
|
||||
(click)="switchView(tab.screen)"
|
||||
[class.active]="tab.screen === screen"
|
||||
>
|
||||
|
||||
@ -2,6 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AppStateService } from '../../state/app-state.service';
|
||||
import { UserPreferenceService } from '../../common/service/user-preference.service';
|
||||
import { PermissionsService } from '../../common/service/permissions.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-tabs',
|
||||
@ -9,17 +10,19 @@ import { UserPreferenceService } from '../../common/service/user-preference.serv
|
||||
styleUrls: ['./tabs.component.scss']
|
||||
})
|
||||
export class TabsComponent implements OnInit {
|
||||
@Input() public screen: 'rules' | 'dictionaries' | 'watermark' | 'default-colors';
|
||||
@Input() public screen: 'rules' | 'dictionaries' | 'watermark' | 'default-colors' | 'file-attributes';
|
||||
|
||||
public tabs: { screen: string; onlyDevMode?: boolean; label?: string }[] = [
|
||||
public tabs: { screen: string; onlyDevMode?: boolean; onlyAdmin?: boolean; label?: string }[] = [
|
||||
{ screen: 'dictionaries' },
|
||||
{ screen: 'rules', onlyDevMode: true, label: 'rule-editor' },
|
||||
{ screen: 'default-colors' },
|
||||
{ screen: 'watermark' }
|
||||
{ screen: 'watermark' },
|
||||
{ screen: 'file-attributes', onlyAdmin: true }
|
||||
];
|
||||
|
||||
constructor(
|
||||
public readonly userPreferenceService: UserPreferenceService,
|
||||
public readonly permissionsService: PermissionsService,
|
||||
private readonly _router: Router,
|
||||
private readonly _appStateService: AppStateService
|
||||
) {}
|
||||
|
||||
@ -55,6 +55,7 @@ export class IconsModule {
|
||||
'preview',
|
||||
'radio-indeterminate',
|
||||
'radio-selected',
|
||||
'read-only',
|
||||
'ready-for-approval',
|
||||
'refresh',
|
||||
'report',
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
{{ 'dictionary-listing.table-header.title' | translate: { length: displayedDictionaries.length } }}
|
||||
</span>
|
||||
|
||||
<div class="dictionary-actions-container">
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-search-input [form]="searchForm" [placeholder]="'dictionary-listing.search'"></redaction-search-input>
|
||||
<div class="actions">
|
||||
<redaction-icon-button
|
||||
@ -111,11 +111,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rank small-label">
|
||||
<div class="center small-label">
|
||||
{{ dict.rank }}
|
||||
</div>
|
||||
|
||||
<div class="analyzed">
|
||||
<div class="center">
|
||||
<redaction-annotation-icon [dictType]="dict" [type]="dict.hint ? 'circle' : 'square'"></redaction-annotation-icon>
|
||||
</div>
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
.header-item {
|
||||
padding: 0 16px 0 10px;
|
||||
|
||||
.dictionary-actions-container {
|
||||
.attributes-actions-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
@ -36,8 +36,7 @@ redaction-table-col-name::ng-deep {
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
&.analyzed,
|
||||
&.rank {
|
||||
&.center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,127 @@
|
||||
<section>
|
||||
<div class="page-header">
|
||||
<redaction-admin-breadcrumbs class="flex-1"></redaction-admin-breadcrumbs>
|
||||
|
||||
<redaction-tabs [screen]="'file-attributes'"></redaction-tabs>
|
||||
|
||||
<div class="actions flex-1">
|
||||
<redaction-circle-button [routerLink]="['../..']" tooltip="common.close" tooltipPosition="before" icon="red:close"></redaction-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="red-content-inner">
|
||||
<div class="left-container">
|
||||
<div class="header-item">
|
||||
<div class="select-all-container">
|
||||
<div
|
||||
(click)="toggleSelectAll()"
|
||||
[class.active]="areAllAttributesSelected"
|
||||
class="select-oval always-visible"
|
||||
*ngIf="!areAllAttributesSelected && !areSomeAttributesSelected"
|
||||
></div>
|
||||
<mat-icon
|
||||
*ngIf="areAllAttributesSelected"
|
||||
(click)="toggleSelectAll()"
|
||||
class="selection-icon active"
|
||||
svgIcon="red:radio-selected"
|
||||
></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="areSomeAttributesSelected && !areAllAttributesSelected"
|
||||
(click)="toggleSelectAll()"
|
||||
class="selection-icon"
|
||||
svgIcon="red:radio-indeterminate"
|
||||
></mat-icon>
|
||||
</div>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'file-attributes-listing.table-header.title' | translate: { length: displayedAttributes.length } }}
|
||||
</span>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-search-input [form]="searchForm" [placeholder]="'file-attributes-listing.search'"></redaction-search-input>
|
||||
<div class="actions">
|
||||
<redaction-icon-button
|
||||
icon="red:plus"
|
||||
(action)="openAddEditAttributeDialog($event)"
|
||||
text="file-attributes-listing.add-new"
|
||||
type="primary"
|
||||
></redaction-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<redaction-table-col-name
|
||||
label="file-attributes-listing.table-col-names.name"
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="name"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name label="file-attributes-listing.table-col-names.created-by" class="flex-center"></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name label="file-attributes-listing.table-col-names.permissions" class="flex-center"></redaction-table-col-name>
|
||||
|
||||
<div></div>
|
||||
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="noData" class="no-data heading-l" translate="file-attributes-listing.no-data"></div>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div class="table-item" *cdkVirtualFor="let attribute of displayedAttributes | sortBy: sortingOption.order:sortingOption.column">
|
||||
<div class="pr-0" (click)="toggleAttributeSelected($event, attribute)">
|
||||
<div *ngIf="!isAttributeSelected(attribute)" class="select-oval"></div>
|
||||
<mat-icon class="selection-icon active" *ngIf="isAttributeSelected(attribute)" svgIcon="red:radio-selected"></mat-icon>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ attribute.name }}
|
||||
</div>
|
||||
<div class="center">
|
||||
-
|
||||
<!-- TODO-->
|
||||
<!-- <redaction-initials-avatar [userId]="attribute.userId" [withName]="true" size="large"></redaction-initials-avatar>-->
|
||||
</div>
|
||||
<div class="center">
|
||||
<redaction-circle-button
|
||||
*ngIf="!attribute.editable"
|
||||
type="dark-bg"
|
||||
icon="red:read-only"
|
||||
tooltip="file-attributes-listing.read-only"
|
||||
[dummy]="true"
|
||||
></redaction-circle-button>
|
||||
</div>
|
||||
<div class="actions-container">
|
||||
<div class="action-buttons">
|
||||
<redaction-circle-button
|
||||
(action)="openAddEditAttributeDialog($event, attribute)"
|
||||
tooltip="file-attributes-listing.action.edit"
|
||||
tooltipPosition="before"
|
||||
type="dark-bg"
|
||||
icon="red:edit"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
(action)="openAddEditAttributeDialog($event, attribute)"
|
||||
tooltip="file-attributes-listing.action.delete"
|
||||
tooltipPosition="before"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</div>
|
||||
|
||||
<div class="right-container"></div>
|
||||
</div>
|
||||
</section>
|
||||
@ -0,0 +1,54 @@
|
||||
.page-header .actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.header-item {
|
||||
padding: 0 24px 0 10px;
|
||||
}
|
||||
|
||||
redaction-table-col-name::ng-deep {
|
||||
> div {
|
||||
padding-left: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.left-container {
|
||||
width: 100vw;
|
||||
|
||||
.header-item {
|
||||
.attributes-actions-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 1fr 1fr 1fr 1fr 11px;
|
||||
|
||||
.table-item {
|
||||
> div:not(.scrollbar-placeholder) {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
> div {
|
||||
&.center {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 1fr 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PermissionsService } from '../../../common/service/permissions.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { FileAttribute, FileAttributesControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { debounce } from '../../../utils/debounce';
|
||||
import { SortingOption, SortingService } from '../../../utils/sorting.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-attributes-listing-screen',
|
||||
templateUrl: './file-attributes-listing-screen.component.html',
|
||||
styleUrls: ['./file-attributes-listing-screen.component.scss']
|
||||
})
|
||||
export class FileAttributesListingScreenComponent implements OnInit {
|
||||
public searchForm: FormGroup;
|
||||
public attributes: FileAttribute[] = [];
|
||||
public displayedAttributes: FileAttribute[] = [];
|
||||
public selectedFileAttributeIds: string[] = [];
|
||||
|
||||
constructor(
|
||||
public readonly permissionsService: PermissionsService,
|
||||
public readonly _sortingService: SortingService,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
private readonly _fileAttributesService: FileAttributesControllerService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _activatedRoute: ActivatedRoute
|
||||
) {
|
||||
this._appStateService.activateRuleSet(_activatedRoute.snapshot.params.ruleSetId);
|
||||
|
||||
this.searchForm = this._formBuilder.group({
|
||||
query: ['']
|
||||
});
|
||||
|
||||
this.searchForm.valueChanges.subscribe((value) => this._executeSearch(value));
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
try {
|
||||
const response = await this._fileAttributesService.getFileAttributesConfiguration(this._appStateService.activeRuleSetId).toPromise();
|
||||
this.attributes = response?.fileAttributes || [];
|
||||
} catch (e) {
|
||||
// TODO: Remove
|
||||
this.attributes = [
|
||||
{
|
||||
name: 'Atribut',
|
||||
editable: true,
|
||||
id: '1',
|
||||
visible: true
|
||||
},
|
||||
{
|
||||
name: 'Alt atribut',
|
||||
editable: false,
|
||||
id: '2',
|
||||
visible: true
|
||||
}
|
||||
];
|
||||
}
|
||||
this.displayedAttributes = [...this.attributes];
|
||||
}
|
||||
|
||||
public get noData(): boolean {
|
||||
return this.displayedAttributes.length === 0;
|
||||
}
|
||||
|
||||
public get sortingOption(): SortingOption {
|
||||
return this._sortingService.getSortingOption('file-attributes-listing');
|
||||
}
|
||||
|
||||
public toggleSort($event) {
|
||||
this._sortingService.toggleSort('file-attributes-listing', $event);
|
||||
}
|
||||
|
||||
@debounce(200)
|
||||
private _executeSearch(value: { query: string }) {
|
||||
this.displayedAttributes = this.attributes.filter((attribute) => attribute.name.toLowerCase().includes(value.query.toLowerCase()));
|
||||
}
|
||||
|
||||
public openAddEditAttributeDialog($event: MouseEvent, attribute?: FileAttribute) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
|
||||
public toggleAttributeSelected($event: MouseEvent, attribute: FileAttribute) {
|
||||
$event.stopPropagation();
|
||||
const idx = this.selectedFileAttributeIds.indexOf(attribute.id);
|
||||
if (idx === -1) {
|
||||
this.selectedFileAttributeIds.push(attribute.id);
|
||||
} else {
|
||||
this.selectedFileAttributeIds.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public toggleSelectAll() {
|
||||
if (this.areSomeAttributesSelected) {
|
||||
this.selectedFileAttributeIds = [];
|
||||
} else {
|
||||
this.selectedFileAttributeIds = this.displayedAttributes.map((a) => a.id);
|
||||
}
|
||||
}
|
||||
|
||||
public get areAllAttributesSelected() {
|
||||
return this.displayedAttributes.length !== 0 && this.selectedFileAttributeIds.length === this.displayedAttributes.length;
|
||||
}
|
||||
|
||||
public get areSomeAttributesSelected() {
|
||||
return this.selectedFileAttributeIds.length > 0;
|
||||
}
|
||||
|
||||
public isAttributeSelected(attribute: FileAttribute) {
|
||||
return this.selectedFileAttributeIds.indexOf(attribute.id) !== -1;
|
||||
}
|
||||
}
|
||||
@ -5,14 +5,7 @@
|
||||
<redaction-tabs [screen]="'watermark'"></redaction-tabs>
|
||||
|
||||
<div class="actions flex-1">
|
||||
<redaction-circle-button
|
||||
class="ml-6"
|
||||
*ngIf="permissionsService.isUser()"
|
||||
[routerLink]="['/ui/projects/']"
|
||||
tooltip="common.close"
|
||||
tooltipPosition="before"
|
||||
icon="red:close"
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button [routerLink]="['../..']" tooltip="common.close" tooltipPosition="before" icon="red:close"></redaction-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -36,5 +36,5 @@
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-file-download-btn [file]="project.files" [project]="project"> </redaction-file-download-btn>
|
||||
<redaction-file-download-btn [file]="project.files" [project]="project" type="dark-bg"> </redaction-file-download-btn>
|
||||
</div>
|
||||
|
||||
@ -5,7 +5,7 @@ export class SortingOption {
|
||||
column: string;
|
||||
}
|
||||
|
||||
type Screen = 'project-listing' | 'project-overview' | 'dictionary-listing' | 'rule-sets-listing' | 'default-colors';
|
||||
type Screen = 'project-listing' | 'project-overview' | 'dictionary-listing' | 'rule-sets-listing' | 'default-colors' | 'file-attributes-listing';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -16,7 +16,8 @@ export class SortingService {
|
||||
'project-overview': { column: 'filename', order: 'asc' },
|
||||
'dictionary-listing': { column: 'label', order: 'asc' },
|
||||
'rule-sets-listing': { column: 'name', order: 'asc' },
|
||||
'default-colors': { column: 'key', order: 'asc' }
|
||||
'default-colors': { column: 'key', order: 'asc' },
|
||||
'file-attributes-listing': { column: 'name', order: 'asc' }
|
||||
};
|
||||
|
||||
constructor() {}
|
||||
|
||||
@ -694,6 +694,24 @@
|
||||
"modified-on": "Modified on"
|
||||
}
|
||||
},
|
||||
"file-attributes-listing": {
|
||||
"search": "Search by attribute name...",
|
||||
"add-new": "New Attribute",
|
||||
"table-header": {
|
||||
"title": "{{length}} file attributes"
|
||||
},
|
||||
"table-col-names": {
|
||||
"name": "Name",
|
||||
"created-by": "Created by",
|
||||
"permissions": "Permissions"
|
||||
},
|
||||
"no-data": "No file attributes.",
|
||||
"read-only": "Read-only",
|
||||
"action": {
|
||||
"edit": "Edit attribute",
|
||||
"delete": "Delete attribute"
|
||||
}
|
||||
},
|
||||
"user-listing": {
|
||||
"table-header": {
|
||||
"title": "{{length}} users"
|
||||
@ -748,6 +766,7 @@
|
||||
},
|
||||
"rule-editor": "Rule Editor",
|
||||
"watermark": "Watermark",
|
||||
"file-attributes": "File Attributes",
|
||||
"pending-changes-guard": "WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.",
|
||||
"reset-filters": "Reset Filters",
|
||||
"overwrite-files-dialog": {
|
||||
|
||||
19
apps/red-ui/src/assets/icons/general/read-only.svg
Normal file
19
apps/red-ui/src/assets/icons/general/read-only.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>9C81EE87-2992-4087-907E-26A83F796466</title>
|
||||
<g id="File-attributes" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Admin---File-attributes-list" transform="translate(-1154.000000, -212.000000)">
|
||||
<rect x="0" y="0" width="1440" height="900"></rect>
|
||||
<polygon id="Rectangle" points="0 194 1430 194 1430 244 0 244"></polygon>
|
||||
<g id="Permission" transform="translate(1124.000000, 171.000000)" fill="currentColor" fill-rule="nonzero">
|
||||
<g id="icon-read-only" transform="translate(20.000000, 31.000000)">
|
||||
<g id="read-only" transform="translate(10.000000, 10.000000)">
|
||||
<g id="noun_Lock_791668-(1)" transform="translate(1.400000, 0.000000)">
|
||||
<path d="M9.8,5.6 L9.1,5.6 L9.1,3.5 C9.1,1.54 7.56,0 5.6,0 C3.64,0 2.1,1.54 2.1,3.5 L2.1,5.6 L1.4,5.6 C0.63,5.6 0,6.23 0,7 L0,12.6 C0,13.37 0.63,14 1.4,14 L9.8,14 C10.57,14 11.2,13.37 11.2,12.6 L11.2,7 C11.2,6.23 10.57,5.6 9.8,5.6 Z M3.5,3.5 C3.5,2.31 4.41,1.4 5.6,1.4 C6.79,1.4 7.7,2.31 7.7,3.5 L7.7,5.6 L3.5,5.6 L3.5,3.5 Z M1.4,12.6 L1.4,7 L9.8,7 L9.8,12.6 L1.4,12.6 Z" id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@ -80,6 +80,10 @@ cdk-virtual-scroll-viewport {
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
redaction-circle-button:not(:last-child) {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
display: flex;
|
||||
// compensate for scroll
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user