Browse Source

Editor selection

pull/1/head
Sebastian 9 years ago
parent
commit
17ea0ed04f
  1. 17
      src/Squidex.Core/Schemas/NumberFieldEditor.cs
  2. 24
      src/Squidex.Core/Schemas/NumberFieldProperties.cs
  3. 18
      src/Squidex.Core/Schemas/StringFieldEditor.cs
  4. 22
      src/Squidex.Core/Schemas/StringFieldProperties.cs
  5. 5
      src/Squidex/Controllers/Api/Schemas/Models/NumberFieldPropertiesDto.cs
  6. 5
      src/Squidex/Controllers/Api/Schemas/Models/StringFieldPropertiesDto.cs
  7. 2
      src/Squidex/app/features/schemas/declarations.ts
  8. 4
      src/Squidex/app/features/schemas/module.ts
  9. 20
      src/Squidex/app/features/schemas/pages/schema/field.component.html
  10. 8
      src/Squidex/app/features/schemas/pages/schema/field.component.scss
  11. 13
      src/Squidex/app/features/schemas/pages/schema/field.component.ts
  12. 8
      src/Squidex/app/features/schemas/pages/schema/schema-page.component.html
  13. 1
      src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts
  14. 55
      src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.html
  15. 2
      src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.scss
  16. 47
      src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.ts
  17. 30
      src/Squidex/app/features/schemas/pages/schema/types/number-validation.component.html
  18. 16
      src/Squidex/app/features/schemas/pages/schema/types/number-validation.component.scss
  19. 40
      src/Squidex/app/features/schemas/pages/schema/types/number-validation.component.ts
  20. 45
      src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.html
  21. 17
      src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.ts
  22. 2
      src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.html
  23. 5
      src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts
  24. 8
      src/Squidex/app/features/schemas/pages/schemas/schema-form.component.html
  25. 6
      src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts
  26. 4
      src/Squidex/app/features/settings/pages/clients/client.component.html
  27. 8
      src/Squidex/app/features/settings/pages/clients/clients-page.component.html
  28. 1
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts
  29. 2
      src/Squidex/app/framework/angular/autocomplete.component.html
  30. 9
      src/Squidex/app/framework/angular/autocomplete.component.ts
  31. 2
      src/Squidex/app/framework/angular/color-picker.component.html
  32. 1
      src/Squidex/app/framework/angular/color-picker.component.scss
  33. 18
      src/Squidex/app/framework/angular/color-picker.component.spec.ts
  34. 75
      src/Squidex/app/framework/angular/color-picker.component.ts
  35. 4
      src/Squidex/app/framework/angular/slider.component.html
  36. 40
      src/Squidex/app/framework/angular/slider.component.scss
  37. 123
      src/Squidex/app/framework/angular/slider.component.ts
  38. 11
      src/Squidex/app/framework/angular/tag-editor.component.html
  39. 39
      src/Squidex/app/framework/angular/tag-editor.component.scss
  40. 138
      src/Squidex/app/framework/angular/tag-editor.component.ts
  41. 1
      src/Squidex/app/framework/declarations.ts
  42. 3
      src/Squidex/app/framework/module.ts
  43. 8
      src/Squidex/app/shared/components/app-form.component.html
  44. 14
      src/Squidex/app/shared/components/history.component.ts
  45. 49
      src/Squidex/app/theme/_bootstrap.scss
  46. 1
      src/Squidex/app/theme/_vars.scss
  47. BIN
      src/Squidex/app/theme/icomoon/fonts/icomoon.eot
  48. 9
      src/Squidex/app/theme/icomoon/fonts/icomoon.svg
  49. BIN
      src/Squidex/app/theme/icomoon/fonts/icomoon.ttf
  50. BIN
      src/Squidex/app/theme/icomoon/fonts/icomoon.woff
  51. 420
      src/Squidex/app/theme/icomoon/selection.json
  52. 43
      src/Squidex/app/theme/icomoon/style.css
  53. 1
      src/Squidex/tslint.json
  54. 28
      tests/Squidex.Core.Tests/Schemas/NumberFieldPropertiesTests.cs
  55. 28
      tests/Squidex.Core.Tests/Schemas/StringFieldPropertiesTests.cs
  56. 1
      tests/Squidex.Core.Tests/project.json

17
src/Squidex.Core/Schemas/NumberFieldEditor.cs

@ -0,0 +1,17 @@
// ==========================================================================
// NumberFieldEditor.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Core.Schemas
{
public enum NumberFieldEditor
{
Input,
Radio,
Dropdown
}
}

24
src/Squidex.Core/Schemas/NumberFieldProperties.cs

@ -19,6 +19,7 @@ namespace Squidex.Core.Schemas
private double? minValue; private double? minValue;
private double? defaultValue; private double? defaultValue;
private ImmutableList<double> allowedValues; private ImmutableList<double> allowedValues;
private NumberFieldEditor editor;
public double? MaxValue public double? MaxValue
{ {
@ -64,14 +65,35 @@ namespace Squidex.Core.Schemas
} }
} }
public NumberFieldEditor Editor
{
get { return editor; }
set
{
ThrowIfFrozen();
editor = value;
}
}
protected override IEnumerable<ValidationError> ValidateCore() protected override IEnumerable<ValidationError> ValidateCore()
{ {
if (!Editor.IsEnumValue())
{
yield return new ValidationError("Editor ist not a valid value", nameof(Editor));
}
if ((Editor == NumberFieldEditor.Radio || Editor == NumberFieldEditor.Dropdown) && (AllowedValues == null || AllowedValues.Count == 0))
{
yield return new ValidationError("Radio buttons or dropdown list need allowed values", nameof(AllowedValues));
}
if (MaxValue.HasValue && MinValue.HasValue && MinValue.Value >= MaxValue.Value) if (MaxValue.HasValue && MinValue.HasValue && MinValue.Value >= MaxValue.Value)
{ {
yield return new ValidationError("Max value must be greater than min value", nameof(MinValue), nameof(MaxValue)); yield return new ValidationError("Max value must be greater than min value", nameof(MinValue), nameof(MaxValue));
} }
if (AllowedValues != null && (MinValue.HasValue || MaxValue.HasValue)) if (AllowedValues != null && AllowedValues.Count > 0 && (MinValue.HasValue || MaxValue.HasValue))
{ {
yield return new ValidationError("Either or allowed values or range can be defined", yield return new ValidationError("Either or allowed values or range can be defined",
nameof(AllowedValues), nameof(AllowedValues),

18
src/Squidex.Core/Schemas/StringFieldEditor.cs

@ -0,0 +1,18 @@
// ==========================================================================
// StringFieldEditor.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Core.Schemas
{
public enum StringFieldEditor
{
Input,
TextArea,
Radio,
Dropdown
}
}

22
src/Squidex.Core/Schemas/StringFieldProperties.cs

@ -23,6 +23,7 @@ namespace Squidex.Core.Schemas
private string pattern; private string pattern;
private string patternMessage; private string patternMessage;
private ImmutableList<string> allowedValues; private ImmutableList<string> allowedValues;
private StringFieldEditor editor;
public int? MinLength public int? MinLength
{ {
@ -79,8 +80,29 @@ namespace Squidex.Core.Schemas
} }
} }
public StringFieldEditor Editor
{
get { return editor; }
set
{
ThrowIfFrozen();
editor = value;
}
}
protected override IEnumerable<ValidationError> ValidateCore() protected override IEnumerable<ValidationError> ValidateCore()
{ {
if (!Editor.IsEnumValue())
{
yield return new ValidationError("Editor ist not a valid value", nameof(Editor));
}
if ((Editor == StringFieldEditor.Radio || Editor == StringFieldEditor.Dropdown) && (AllowedValues == null || AllowedValues.Count == 0))
{
yield return new ValidationError("Radio buttons or dropdown list need allowed values", nameof(AllowedValues));
}
if (MaxLength.HasValue && MinLength.HasValue && MinLength.Value >= MaxLength.Value) if (MaxLength.HasValue && MinLength.HasValue && MinLength.Value >= MaxLength.Value)
{ {
yield return new ValidationError("Max length must be greater than min length", nameof(MinLength), nameof(MaxLength)); yield return new ValidationError("Max length must be greater than min length", nameof(MinLength), nameof(MaxLength));

5
src/Squidex/Controllers/Api/Schemas/Models/NumberFieldPropertiesDto.cs

@ -35,6 +35,11 @@ namespace Squidex.Controllers.Api.Schemas.Models
/// </summary> /// </summary>
public double[] AllowedValues { get; set; } public double[] AllowedValues { get; set; }
/// <summary>
/// The editor that is used to manage this field.
/// </summary>
public NumberFieldEditor Editor { get; set; }
public override FieldProperties ToProperties() public override FieldProperties ToProperties()
{ {
return SimpleMapper.Map(this, new NumberFieldProperties()); return SimpleMapper.Map(this, new NumberFieldProperties());

5
src/Squidex/Controllers/Api/Schemas/Models/StringFieldPropertiesDto.cs

@ -45,6 +45,11 @@ namespace Squidex.Controllers.Api.Schemas.Models
/// </summary> /// </summary>
public string[] AllowedValues { get; set; } public string[] AllowedValues { get; set; }
/// <summary>
/// The editor that is used to manage this field.
/// </summary>
public StringFieldEditor Editor { get; set; }
public override FieldProperties ToProperties() public override FieldProperties ToProperties()
{ {
return SimpleMapper.Map(this, new StringFieldProperties()); return SimpleMapper.Map(this, new StringFieldProperties());

2
src/Squidex/app/features/schemas/declarations.ts

@ -5,6 +5,8 @@
* Copyright (c) Sebastian Stehle. All rights reserved * Copyright (c) Sebastian Stehle. All rights reserved
*/ */
export * from './pages/schema/types/number-ui.component';
export * from './pages/schema/types/number-validation.component';
export * from './pages/schema/types/string-ui.component'; export * from './pages/schema/types/string-ui.component';
export * from './pages/schema/types/string-validation.component'; export * from './pages/schema/types/string-validation.component';
export * from './pages/schema/field.component'; export * from './pages/schema/field.component';

4
src/Squidex/app/features/schemas/module.ts

@ -12,6 +12,8 @@ import { SqxFrameworkModule, SqxSharedModule } from 'shared';
import { import {
FieldComponent, FieldComponent,
NumberUIComponent,
NumberValidationComponent,
SchemaFormComponent, SchemaFormComponent,
SchemaPageComponent, SchemaPageComponent,
SchemasPageComponent, SchemasPageComponent,
@ -42,6 +44,8 @@ const routes: Routes = [
], ],
declarations: [ declarations: [
FieldComponent, FieldComponent,
NumberUIComponent,
NumberValidationComponent,
SchemaFormComponent, SchemaFormComponent,
SchemaPageComponent, SchemaPageComponent,
SchemasPageComponent, SchemasPageComponent,

20
src/Squidex/app/features/schemas/pages/schema/field.component.html

@ -2,7 +2,7 @@
<div class="field-summary"> <div class="field-summary">
<div class="row"> <div class="row">
<div class="col-xs-8"> <div class="col-xs-8">
{{field.name}} <i class="field-icon icon-type-{{field.properties.fieldType}}"></i> {{field.name}}
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<div class="float-xs-right"> <div class="float-xs-right">
@ -28,7 +28,7 @@
<a class="nav-link" (click)="selectTab(1)" [class.active]="selectedTab === 1">Validation</a> <a class="nav-link" (click)="selectTab(1)" [class.active]="selectedTab === 1">Validation</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" (click)="selectTab(2)" [class.active]="selectedTab === 2">User Interface</a> <a class="nav-link" (click)="selectTab(2)" [class.active]="selectedTab === 2">Editing</a>
</li> </li>
</ul> </ul>
@ -43,9 +43,9 @@
<label for="field-label" class="col-xs-3 col-form-label">Label</label> <label for="field-label" class="col-xs-3 col-form-label">Label</label>
<div class="col-xs-6"> <div class="col-xs-6">
<div class="errors-box" *ngIf="editForm.get('label').invalid && editForm.get('label').touched" [@fade]> <div class="errors-box" *ngIf="editForm.controls.label.invalid && editForm.controls.label.touched" [@fade]>
<div class="errors"> <div class="errors">
<span *ngIf="editForm.get('label').hasError('maxlength')"> <span *ngIf="editForm.controls.label.hasError('maxlength')">
Label can not have more than 100 characters. Label can not have more than 100 characters.
</span> </span>
</div> </div>
@ -63,9 +63,9 @@
<label for="field-hints" class="col-xs-3 col-form-label">Hints</label> <label for="field-hints" class="col-xs-3 col-form-label">Hints</label>
<div class="col-xs-6"> <div class="col-xs-6">
<div class="errors-box" *ngIf="editForm.get('hints').invalid && editForm.get('hints').touched" [@fade]> <div class="errors-box" *ngIf="editForm.controls.hints.invalid && editForm.controls.hints.touched" [@fade]>
<div class="errors"> <div class="errors">
<span *ngIf="editForm.get('hints').hasError('maxlength')"> <span *ngIf="editForm.controls.hints.hasError('maxlength')">
Hints can not have more than 100 characters. Hints can not have more than 100 characters.
</span> </span>
</div> </div>
@ -83,10 +83,10 @@
<div class="field-details-tab" *ngIf="selectedTab == 1"> <div class="field-details-tab" *ngIf="selectedTab == 1">
<div [ngSwitch]="field.properties.fieldType"> <div [ngSwitch]="field.properties.fieldType">
<div *ngSwitchCase="'number'"> <div *ngSwitchCase="'number'">
asdsad <sqx-number-validation [editForm]="editForm"></sqx-number-validation>
</div> </div>
<div *ngSwitchCase="'string'"> <div *ngSwitchCase="'string'">
<sqx-string-validation [editForm]="editForm" [properties]="field.properties"></sqx-string-validation> <sqx-string-validation [editForm]="editForm"></sqx-string-validation>
</div> </div>
</div> </div>
</div> </div>
@ -94,10 +94,10 @@
<div class="field-details-tab" *ngIf="selectedTab == 2"> <div class="field-details-tab" *ngIf="selectedTab == 2">
<div [ngSwitch]="field.properties.fieldType"> <div [ngSwitch]="field.properties.fieldType">
<div *ngSwitchCase="'number'"> <div *ngSwitchCase="'number'">
asdsad <sqx-number-ui [editForm]="editForm"></sqx-number-ui>
</div> </div>
<div *ngSwitchCase="'string'"> <div *ngSwitchCase="'string'">
<sqx-string-ui [editForm]="editForm" [properties]="field.properties"></sqx-string-ui> <sqx-string-ui [editForm]="editForm"></sqx-string-ui>
</div> </div>
</div> </div>
</div> </div>

8
src/Squidex/app/features/schemas/pages/schema/field.component.scss

@ -13,6 +13,14 @@ $field-header: #e7ebef;
line-height: 40px; line-height: 40px;
} }
&-icon {
color: darken($color-border, 15%);
font-size: 1.2rem;
font-weight: normal;
vertical-align: middle;
margin-right: 1rem;
}
&-edit-button { &-edit-button {
& { & {
color: $color-theme-blue; color: $color-theme-blue;

13
src/Squidex/app/features/schemas/pages/schema/field.component.ts

@ -7,16 +7,13 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable} from 'rxjs';
import { import {
createProperties, createProperties,
fadeAnimation, fadeAnimation,
FieldDto, FieldDto
FieldPropertiesDto
} from 'shared'; } from 'shared';
const ESCAPE_KEY = 27;
@Component({ @Component({
selector: 'sqx-field', selector: 'sqx-field',
styleUrls: ['./field.component.scss'], styleUrls: ['./field.component.scss'],
@ -34,8 +31,8 @@ export class FieldComponent implements OnInit {
@Output() @Output()
public saved = new EventEmitter<FieldDto>(); public saved = new EventEmitter<FieldDto>();
public isEditing: boolean = false; public isEditing: boolean = true;
public selectedTab = 0; public selectedTab = 2;
public editForm: FormGroup = public editForm: FormGroup =
this.formBuilder.group({ this.formBuilder.group({
@ -102,8 +99,6 @@ export class FieldComponent implements OnInit {
} }
this.oldValue = Object.assign({}, this.editForm.value); this.oldValue = Object.assign({}, this.editForm.value);
this.isEditing = false;
} }
} }

8
src/Squidex/app/features/schemas/pages/schema/schema-page.component.html

@ -24,15 +24,15 @@
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="errors-box" *ngIf="addFieldForm.get('name').invalid && addFieldForm.get('name').dirty"> <div class="errors-box" *ngIf="addFieldForm.controls.name.invalid && addFieldForm.controls.name.dirty">
<div class="errors"> <div class="errors">
<span *ngIf="addFieldForm.get('name').hasError('required')"> <span *ngIf="addFieldForm.controls.name.hasError('required')">
Name is required. Name is required.
</span> </span>
<span *ngIf="addFieldForm.get('name').hasError('maxlength')"> <span *ngIf="addFieldForm.controls.name.hasError('maxlength')">
Name can not have more than 40 characters. Name can not have more than 40 characters.
</span> </span>
<span *ngIf="addFieldForm.get('name').hasError('pattern')"> <span *ngIf="addFieldForm.controls.name.hasError('pattern')">
Name can contain lower case letters (a-z), numbers and dashes (not at the end). Name can contain lower case letters (a-z), numbers and dashes (not at the end).
</span> </span>
</div> </div>

1
src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts

@ -21,7 +21,6 @@ import {
MessageBus, MessageBus,
NotificationService, NotificationService,
NumberFieldPropertiesDto, NumberFieldPropertiesDto,
SchemaDetailsDto,
SchemasService, SchemasService,
StringFieldPropertiesDto, StringFieldPropertiesDto,
UsersProviderService UsersProviderService

55
src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.html

@ -0,0 +1,55 @@
<div [formGroup]="editForm">
<div class="form-group row">
<label for="field-placeholder" class="col-xs-3 col-form-label">Placeholder</label>
<div class="col-xs-6">
<div class="errors-box" *ngIf="editForm.controls.placeholder.invalid && editForm.controls.placeholder.touched" [@fade]>
<div class="errors">
<span *ngIf="editForm.controls.placeholder.hasError('maxlength')">
Placeholder can not have more than 100 characters.
</span>
</div>
</div>
<input type="text" class="form-control" id="field-placeholder" maxlength="100" formControlName="placeholder" />
<span class="form-hint">
Define the placeholder for the input control.
</span>
</div>
</div>
<div class="form-group row">
<label for="field-editor" class="col-xs-3 col-form-label">Editor</label>
<div class="col-xs-9">
<label class="btn btn-radio" [class.active]="editForm.controls.editor.value === 'Input'">
<input type="radio" class="radio-input" formControlName="editor" value="Input" />
<i class="icon-control-input"></i>
<span class="radio-label">Input</span>
</label>
<label class="btn btn-radio" [class.active]="editForm.controls.editor.value === 'Dropdown'">
<input type="radio" class="radio-input" formControlName="editor" value="Dropdown" />
<i class="icon-control-dropdown"></i>
<span class="radio-label" clas>Dropdown</span>
</label>
<label class="btn btn-radio" [class.active]="editForm.controls.editor.value === 'Radio'">
<input type="radio" class="radio-input" formControlName="editor" value="Radio" />
<i class="icon-control-radio"></i>
<span class="radio-label">Radio</span>
</label>
</div>
</div>
<div class="form-group row">
<label for="field-allowed-values" class="col-xs-3 col-form-label">Allowed Values</label>
<div class="col-xs-6">
<sqx-tag-editor formControlName="allowedValues" [converter]="converter"></sqx-tag-editor>
</div>
</div>
</div>

2
src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.scss

@ -0,0 +1,2 @@
@import '_vars';
@import '_mixins';

47
src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.ts

@ -0,0 +1,47 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { fadeAnimation, FloatConverter } from 'shared';
@Component({
selector: 'sqx-number-ui',
styleUrls: ['number-ui.component.scss'],
templateUrl: 'number-ui.component.html',
animations: [
fadeAnimation
]
})
export class NumberUIComponent implements OnInit {
@Input()
public editForm: FormGroup;
public converter = new FloatConverter();
public hideAllowedValues: Observable<boolean>;
public ngOnInit() {
this.editForm.addControl('editor',
new FormControl('Input', [
Validators.required
]));
this.editForm.addControl('placeholder',
new FormControl('', [
Validators.maxLength(100)
]));
this.editForm.addControl('allowedValues',
new FormControl(undefined, []));
this.hideAllowedValues =
Observable.of(false)
.merge(this.editForm.get('editor').valueChanges)
.map(x => !x || x === 'Input' || x === 'Textarea');
}
}

30
src/Squidex/app/features/schemas/pages/schema/types/number-validation.component.html

@ -0,0 +1,30 @@
<div [formGroup]="editForm">
<div class="form-group row">
<label class="col-xs-3 col-form-checkbox-label" for="field-required">Required</label>
<div class="col-xs-6">
<input type="checkbox" class="form-check-input" id="field-required" formControlName="isRequired" />
</div>
</div>
<div class="form-group row">
<label class="col-xs-3 col-form-label">Range</label>
<div class="col-xs-3 minlength-col">
<input type="number" class="form-control" id="field-min-value" formControlName="minValue" placeholder="Min Value" />
<label class="col-form-label minlength-label">-</label>
</div>
<div class="col-xs-3">
<input type="number" class="form-control" id="field-max-value" formControlName="maxValue" placeholder="Max Value" />
</div>
</div>
<div class="form-group row" [class.hide]="(hideDefaultValue | async)">
<label class="col-xs-3 col-form-label" for="field-default-value">Default Value</label>
<div class="col-xs-6">
<input type="number" class="form-control" id="field-default-value" formControlName="defaultValue" />
</div>
</div>
</div>

16
src/Squidex/app/features/schemas/pages/schema/types/number-validation.component.scss

@ -0,0 +1,16 @@
@import '_vars';
@import '_mixins';
.minlength {
&-col {
position: relative;
}
&-label {
@include absolute(0, -4px, auto, auto);
}
}
.form-check-input {
margin: 0;
}

40
src/Squidex/app/features/schemas/pages/schema/types/number-validation.component.ts

@ -0,0 +1,40 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';
@Component({
selector: 'sqx-number-validation',
styleUrls: ['number-validation.component.scss'],
templateUrl: 'number-validation.component.html'
})
export class NumberValidationComponent implements OnInit {
@Input()
public editForm: FormGroup;
public hideDefaultValue: Observable<boolean>;
public ngOnInit() {
this.editForm.addControl('maxValue',
new FormControl());
this.editForm.addControl('minValue',
new FormControl());
this.editForm.addControl('pattern',
new FormControl());
this.editForm.addControl('patternMessage',
new FormControl());
this.editForm.addControl('defaultValue',
new FormControl());
this.hideDefaultValue =
Observable.of(false)
.merge(this.editForm.get('isRequired').valueChanges)
.map(x => !!x);
}
}

45
src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.html

@ -3,9 +3,9 @@
<label for="field-input-placeholder" class="col-xs-3 col-form-label">Placeholder</label> <label for="field-input-placeholder" class="col-xs-3 col-form-label">Placeholder</label>
<div class="col-xs-6"> <div class="col-xs-6">
<div class="errors-box" *ngIf="editForm.get('placeholder').invalid && editForm.get('placeholder').touched" [@fade]> <div class="errors-box" *ngIf="editForm.controls.placeholder.invalid && editForm.controls.placeholder.touched" [@fade]>
<div class="errors"> <div class="errors">
<span *ngIf="editForm.get('placeholder').hasError('maxlength')"> <span *ngIf="editForm.controls.placeholder.hasError('maxlength')">
Placeholder can not have more than 100 characters. Placeholder can not have more than 100 characters.
</span> </span>
</div> </div>
@ -18,4 +18,45 @@
</span> </span>
</div> </div>
</div> </div>
<div class="form-group row">
<label for="field-input-editor" class="col-xs-3 col-form-label">Editor</label>
<div class="col-xs-9">
<label class="btn btn-radio" [class.active]="editForm.controls.editor.value === 'Input'">
<input type="radio" class="radio-input" formControlName="editor" value="Input" />
<i class="icon-control-input"></i>
<span class="radio-label">Input</span>
</label>
<label class="btn btn-radio" [class.active]="editForm.controls.editor.value === 'Textarea'">
<input type="radio" class="radio-input" formControlName="editor" value="Textarea" />
<i class="icon-control-textarea"></i>
<span class="radio-label">Textarea</span>
</label>
<label class="btn btn-radio" [class.active]="editForm.controls.editor.value === 'Dropdown'">
<input type="radio" class="radio-input" formControlName="editor" value="Dropdown" />
<i class="icon-control-dropdown"></i>
<span class="radio-label" clas>Dropdown</span>
</label>
<label class="btn btn-radio" [class.active]="editForm.controls.editor.value === 'Radio'">
<input type="radio" class="radio-input" formControlName="editor" value="Radio" />
<i class="icon-control-radio"></i>
<span class="radio-label">Radio</span>
</label>
</div>
</div>
<div class="form-group row" [class.hide]="hideAllowedValues | async">
<label for="field-allowed-values" class="col-xs-3 col-form-label">Allowed Values</label>
<div class="col-xs-6">
<sqx-tag-editor formControlName="allowedValues"></sqx-tag-editor>
</div>
</div>
</div> </div>

17
src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.ts

@ -7,8 +7,9 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { fadeAnimation, StringFieldPropertiesDto } from 'shared'; import { fadeAnimation } from 'shared';
@Component({ @Component({
selector: 'sqx-string-ui', selector: 'sqx-string-ui',
@ -22,13 +23,23 @@ export class StringUIComponent implements OnInit {
@Input() @Input()
public editForm: FormGroup; public editForm: FormGroup;
@Input() public hideAllowedValues: Observable<boolean>;
public properties: StringFieldPropertiesDto;
public ngOnInit() { public ngOnInit() {
this.editForm.addControl('editor',
new FormControl('Input', [
Validators.required
]));
this.editForm.addControl('placeholder', this.editForm.addControl('placeholder',
new FormControl('', [ new FormControl('', [
Validators.maxLength(100) Validators.maxLength(100)
])); ]));
this.editForm.addControl('allowedValues',
new FormControl(10, []));
this.hideAllowedValues =
Observable.of(false)
.merge(this.editForm.get('editor').valueChanges)
.map(x => !x || x === 'Input' || x === 'Textarea');
} }
} }

2
src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.html

@ -1,6 +1,6 @@
<div [formGroup]="editForm"> <div [formGroup]="editForm">
<div class="form-group row"> <div class="form-group row">
<label for="field-required" class="col-xs-3">Required</label> <label class="col-xs-3 col-form-checkbox-label" for="field-required">Required</label>
<div class="col-xs-6"> <div class="col-xs-6">
<input type="checkbox" class="form-check-input" id="field-required" formControlName="isRequired" /> <input type="checkbox" class="form-check-input" id="field-required" formControlName="isRequired" />

5
src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts

@ -9,8 +9,6 @@ import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'; import { FormControl, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { StringFieldPropertiesDto } from 'shared';
@Component({ @Component({
selector: 'sqx-string-validation', selector: 'sqx-string-validation',
styleUrls: ['string-validation.component.scss'], styleUrls: ['string-validation.component.scss'],
@ -20,9 +18,6 @@ export class StringValidationComponent implements OnInit {
@Input() @Input()
public editForm: FormGroup; public editForm: FormGroup;
@Input()
public properties: StringFieldPropertiesDto;
public hidePatternMessage: Observable<boolean>; public hidePatternMessage: Observable<boolean>;
public hideDefaultValue: Observable<boolean>; public hideDefaultValue: Observable<boolean>;

8
src/Squidex/app/features/schemas/pages/schemas/schema-form.component.html

@ -8,15 +8,15 @@
<div class="form-group"> <div class="form-group">
<label for="schema-name">Name</label> <label for="schema-name">Name</label>
<div class="errors-box" *ngIf="createForm.get('name').invalid && createForm.get('name').touched" [@fade]> <div class="errors-box" *ngIf="createForm.controls.name.invalid && createForm.controls.name.touched" [@fade]>
<div class="errors"> <div class="errors">
<span *ngIf="createForm.get('name').hasError('required')"> <span *ngIf="createForm.controls.name.hasError('required')">
Name is required. Name is required.
</span> </span>
<span *ngIf="createForm.get('name').hasError('maxlength')"> <span *ngIf="createForm.controls.name.hasError('maxlength')">
Name can not have more than 40 characters. Name can not have more than 40 characters.
</span> </span>
<span *ngIf="createForm.get('name').hasError('pattern')"> <span *ngIf="createForm.controls.name.hasError('pattern')">
Name can contain lower case letters (a-z), numbers and dashes only (not at the end). Name can contain lower case letters (a-z), numbers and dashes only (not at the end).
</span> </span>
</div> </div>

6
src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts

@ -5,8 +5,8 @@
* Copyright (c) Sebastian Stehle. All rights reserved * Copyright (c) Sebastian Stehle. All rights reserved
*/ */
import { Component, OnInit } from '@angular/core'; import { Component } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormControl } from '@angular/forms';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { import {
@ -21,8 +21,6 @@ import {
UsersProviderService UsersProviderService
} from 'shared'; } from 'shared';
const FALLBACK_NAME = 'my-schema';
@Component({ @Component({
selector: 'sqx-schemas-page', selector: 'sqx-schemas-page',
styleUrls: ['./schemas-page.component.scss'], styleUrls: ['./schemas-page.component.scss'],

4
src/Squidex/app/features/settings/pages/clients/client.component.html

@ -15,9 +15,9 @@
<div class="client-name"> <div class="client-name">
<form *ngIf="isRenaming" class="form-inline" [formGroup]="renameForm" (ngSubmit)="rename()"> <form *ngIf="isRenaming" class="form-inline" [formGroup]="renameForm" (ngSubmit)="rename()">
<div class="form-group"> <div class="form-group">
<div class="errors-box" *ngIf="renameForm.get('name').invalid" [@fade]> <div class="errors-box" *ngIf="renameForm.controls.name.invalid" [@fade]>
<div class="errors"> <div class="errors">
<span *ngIf="renameForm.get('name').hasError('required')"> <span *ngIf="renameForm.controls.name.hasError('required')">
Name is required. Name is required.
</span> </span>
</div> </div>

8
src/Squidex/app/features/settings/pages/clients/clients-page.component.html

@ -22,15 +22,15 @@
<div class="table-items-footer"> <div class="table-items-footer">
<form class="form-inline" [formGroup]="addClientForm" (ngSubmit)="attachClient()"> <form class="form-inline" [formGroup]="addClientForm" (ngSubmit)="attachClient()">
<div class="form-group"> <div class="form-group">
<div class="errors-box" *ngIf="addClientForm.get('name').invalid && addClientForm.get('name').dirty"> <div class="errors-box" *ngIf="addClientForm.controls.name.invalid && addClientForm.controls.name.dirty">
<div class="errors"> <div class="errors">
<span *ngIf="addClientForm.get('name').hasError('required')"> <span *ngIf="addClientForm.controls.name.hasError('required')">
Name is required. Name is required.
</span> </span>
<span *ngIf="addClientForm.get('name').hasError('maxlength')"> <span *ngIf="addClientForm.controls.name.hasError('maxlength')">
Name can not have more than 40 characters. Name can not have more than 40 characters.
</span> </span>
<span *ngIf="addClientForm.get('name').hasError('pattern')"> <span *ngIf="addClientForm.controls.name.hasError('pattern')">
Name can contain lower case letters (a-z), numbers and dashes (not at the end). Name can contain lower case letters (a-z), numbers and dashes (not at the end).
</span> </span>
</div> </div>

1
src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts

@ -21,7 +21,6 @@ import {
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
NotificationService, NotificationService,
UserDto,
UsersProviderService, UsersProviderService,
UsersService UsersService
} from 'shared'; } from 'shared';

2
src/Squidex/app/framework/angular/autocomplete.component.html

@ -1,5 +1,5 @@
<span> <span>
<input type="text" class="form-control" (blur)="blur()" [attr.name]="inputName" (keydown)="keyDown($event)" <input type="text" class="form-control" (blur)="blur()" [attr.name]="inputName" (keydown)="onKeyDown($event)" (blur)="onBlur()"
[formControl]="queryInput" [formControl]="queryInput"
autocomplete="off" autocomplete="off"
autocorrect="off" autocorrect="off"

9
src/Squidex/app/framework/angular/autocomplete.component.ts

@ -45,7 +45,6 @@ export const SQX_AUTOCOMPLETE_CONTROL_VALUE_ACCESSOR: any = {
}) })
export class AutocompleteComponent implements ControlValueAccessor, OnDestroy, OnInit { export class AutocompleteComponent implements ControlValueAccessor, OnDestroy, OnInit {
private subscription: Subscription | null = null; private subscription: Subscription | null = null;
private lastQuery: string | null;
private changeCallback: (value: any) => void = NOOP; private changeCallback: (value: any) => void = NOOP;
private touchedCallback: () => void = NOOP; private touchedCallback: () => void = NOOP;
@ -53,7 +52,7 @@ export class AutocompleteComponent implements ControlValueAccessor, OnDestroy, O
public source: AutocompleteSource; public source: AutocompleteSource;
@Input() @Input()
public inputName: string; public inputName: string = 'autocompletion';
public items: AutocompleteItem[] = []; public items: AutocompleteItem[] = [];
public itemSelection = -1; public itemSelection = -1;
@ -121,7 +120,11 @@ export class AutocompleteComponent implements ControlValueAccessor, OnDestroy, O
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
public keyDown(event: KeyboardEvent) { public onBlur() {
this.touchedCallback();
}
public onKeyDown(event: KeyboardEvent) {
switch (event.keyCode) { switch (event.keyCode) {
case KEY_UP: case KEY_UP:
this.up(); this.up();

2
src/Squidex/app/framework/angular/color-picker.component.html

@ -1,7 +1,7 @@
<div class="btn-group" [class.open]="isOpen"> <div class="btn-group" [class.open]="isOpen">
<button type="button" class="btn btn-secondary btn-sm" (click)="toggleOpen()" [style.background]="selectedColor.toString()"></button> <button type="button" class="btn btn-secondary btn-sm" (click)="toggleOpen()" [style.background]="selectedColor.toString()"></button>
<div class="dropdown-menu dropdown-menu-right"> <div class="dropdown-menu dropdown-menu-{{dropdownSide}}">
<div class="color-palette"> <div class="color-palette">
<span *ngFor="let color of palette.colors" class="color-palette-box" (click)="selectColor(color)" [class.selected]="selectedColor && color.eq(selectedColor)"> <span *ngFor="let color of palette.colors" class="color-palette-box" (click)="selectColor(color)" [class.selected]="selectedColor && color.eq(selectedColor)">
<span class="color-palette-color" [style.background]="color.toString()"></span> <span class="color-palette-color" [style.background]="color.toString()"></span>

1
src/Squidex/app/framework/angular/color-picker.component.scss

@ -1,4 +1,5 @@
@import '_mixins'; @import '_mixins';
@import '_vars';
$color-size: 24px; $color-size: 24px;
$color-button: #1875cc; $color-button: #1875cc;

18
src/Squidex/app/framework/angular/color-picker.component.spec.ts

@ -53,7 +53,7 @@ describe('ColorPickerComponent', () => {
let lastColor: Color | null = null; let lastColor: Color | null = null;
colorPicker.colorChange.subscribe((c: Color) => { colorPicker.registerOnChange((c: Color) => {
lastColor = c; lastColor = c;
}); });
@ -72,7 +72,7 @@ describe('ColorPickerComponent', () => {
let lastColor: Color | null = null; let lastColor: Color | null = null;
colorPicker.colorChange.subscribe((c: Color) => { colorPicker.registerOnChange((c: Color) => {
lastColor = c; lastColor = c;
}); });
@ -81,13 +81,11 @@ describe('ColorPickerComponent', () => {
expect(lastColor).toBeNull(); expect(lastColor).toBeNull();
}); });
it('should update selected color when component changes', () => { it('should update selected color when writing value', () => {
const colorPicker = new ColorPickerComponent({ nativeElement: {} }); const colorPicker = new ColorPickerComponent({ nativeElement: {} });
const selectedColor = Color.RED; const selectedColor = Color.RED;
colorPicker.color = selectedColor; colorPicker.writeValue(selectedColor);
colorPicker.ngOnChanges();
expect(colorPicker.selectedColor).toBe(selectedColor); expect(colorPicker.selectedColor).toBe(selectedColor);
}); });
@ -95,9 +93,7 @@ describe('ColorPickerComponent', () => {
it('should update selected color with palette default if setting invalid color', () => { it('should update selected color with palette default if setting invalid color', () => {
const colorPicker = new ColorPickerComponent({ nativeElement: {} }); const colorPicker = new ColorPickerComponent({ nativeElement: {} });
colorPicker.color = 'invalid'; colorPicker.writeValue('invalid');
colorPicker.ngOnChanges();
expect(colorPicker.selectedColor).toBe(colorPicker.palette.defaultColor); expect(colorPicker.selectedColor).toBe(colorPicker.palette.defaultColor);
}); });
@ -106,9 +102,7 @@ describe('ColorPickerComponent', () => {
const colorPicker = new ColorPickerComponent({ nativeElement: {} }); const colorPicker = new ColorPickerComponent({ nativeElement: {} });
colorPicker.palette = undefined!; colorPicker.palette = undefined!;
colorPicker.color = 'invalid'; colorPicker.writeValue('invalid');
colorPicker.ngOnChanges();
expect(colorPicker.selectedColor).toBe(Color.BLACK); expect(colorPicker.selectedColor).toBe(Color.BLACK);
}); });

75
src/Squidex/app/framework/angular/color-picker.component.ts

@ -5,39 +5,62 @@
* Copyright (c) Sebastian Stehle. All rights reserved * Copyright (c) Sebastian Stehle. All rights reserved
*/ */
import { Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, Output } from '@angular/core'; import { Component, ElementRef, forwardRef, HostListener, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Color } from './../utils/color'; import { Color } from './../utils/color';
import { ColorPalette } from './../utils/color-palette'; import { ColorPalette } from './../utils/color-palette';
/* tslint:disable:no-empty */
const NOOP = () => { };
export const SQX_COLOR_PICKER_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ColorPickerComponent),
multi: true
};
@Component({ @Component({
selector: 'sqx-color-picker', selector: 'sqx-color-picker',
styleUrls: ['./color-picker.component.scss'], styleUrls: ['./color-picker.component.scss'],
templateUrl: './color-picker.component.html' templateUrl: './color-picker.component.html',
providers: [SQX_COLOR_PICKER_CONTROL_VALUE_ACCESSOR]
}) })
export class ColorPickerComponent implements OnChanges { export class ColorPickerComponent implements ControlValueAccessor {
private selectedColorValue = new Color(0, 0, 0); private changeCallback: (value: any) => void = NOOP;
private touchedCallback: () => void = NOOP;
@Output() public selectedColor: Color = Color.BLACK;
public colorChange = new EventEmitter();
@Input() @Input()
public color: string | number | Color; public palette = ColorPalette.colors();
@Input() @Input()
public palette = ColorPalette.colors(); public dropdownSide: 'left';
@Input() @Input()
public isOpen = false; public isOpen = false;
public get selectedColor(): Color {
return this.selectedColorValue;
}
constructor(private readonly element: ElementRef) { constructor(private readonly element: ElementRef) {
this.updateColor(); this.updateColor();
} }
public writeValue(value: any) {
this.updateColor(value);
}
public setDisabledState(isDisabled: boolean): void {
}
public registerOnChange(fn: any) {
this.changeCallback = fn;
}
public registerOnTouched(fn: any) {
this.touchedCallback = fn;
}
@HostListener('document:click', ['$event.target']) @HostListener('document:click', ['$event.target'])
public onClick(targetElement: any) { public onClick(targetElement: any) {
const clickedInside = this.element.nativeElement.contains(targetElement); const clickedInside = this.element.nativeElement.contains(targetElement);
@ -47,20 +70,22 @@ export class ColorPickerComponent implements OnChanges {
} }
} }
public ngOnChanges() { public toggleOpen() {
this.updateColor(); if (this.isOpen) {
this.close();
} else {
this.open();
}
} }
public toggleOpen() { public open() {
this.isOpen = !this.isOpen; this.isOpen = true;
} }
public close() { public close() {
this.isOpen = false; this.isOpen = false;
}
public open() { this.touchedCallback();
this.isOpen = true;
} }
public selectColor(color: Color) { public selectColor(color: Color) {
@ -70,26 +95,26 @@ export class ColorPickerComponent implements OnChanges {
} }
private updateParent(color: Color) { private updateParent(color: Color) {
if (this.selectedColorValue.ne(color)) { if (this.selectedColor.ne(color)) {
this.colorChange.emit(color); this.changeCallback(color);
} }
} }
private updateColor(color?: Color) { private updateColor(color?: Color) {
let hasColor = false; let hasColor = false;
try { try {
this.selectedColorValue = Color.fromValue(color || this.color); this.selectedColor = Color.fromValue(color);
hasColor = true; hasColor = true;
} catch (e) { } catch (e) {
hasColor = false; hasColor = false;
} }
if (!hasColor || !this.selectedColorValue) { if (!hasColor || !this.selectedColor) {
if (this.palette) { if (this.palette) {
this.selectedColorValue = this.palette.defaultColor; this.selectedColor = this.palette.defaultColor;
} else { } else {
this.selectedColorValue = Color.BLACK; this.selectedColor = Color.BLACK;
} }
} }
} }

4
src/Squidex/app/framework/angular/slider.component.html

@ -1,3 +1,3 @@
<div class="slider-bar" #bar (click)="onBarMouseClick($event)"> <div class="slider-bar" #bar (click)="onBarMouseClick($event)" [class.disabled]="isDisabled">
<div class="slider-thumb" #thumb (mousedown)="onThumbMouseDown($event)"></div> <div class="slider-thumb" #thumb (mousedown)="onThumbMouseDown($event)" [class.disabled]="isDisabled"></div>
</div> </div>

40
src/Squidex/app/framework/angular/slider.component.scss

@ -1,23 +1,27 @@
@import '_mixins'; @import '_mixins';
@import '_vars';
$bar-height: 12px; $bar-height: 12px;
$thumb-size: 20px; $thumb-size: 20px;
$thumb-margin: ($thumb-size - $bar-height) * .5; $thumb-margin: ($thumb-size - $bar-height) * .5;
$color-border: #ccc;
$color-focus: #66afe9;
.slider { .slider {
&-bar { &-bar {
@include border-radius($bar-height * .5); & {
position: relative; @include border-radius($bar-height * .5);
border: 1px solid $color-border; position: relative;
margin-bottom: 20px; border: 1px solid $color-control;
margin-top: 5px; margin-bottom: 20px;
margin-right: $thumb-size * .5; margin-top: 5px;
background: $color-border; margin-right: $thumb-size * .5;
height: $bar-height; background: $color-accent-dark;
height: $bar-height;
}
&.disabled {
background: lighten($color-border, 5%);
}
} }
&-thumb { &-thumb {
@ -26,14 +30,22 @@ $color-focus: #66afe9;
position: absolute; position: absolute;
width: $thumb-size; width: $thumb-size;
height: $thumb-size; height: $thumb-size;
border: 1px solid $color-border; border: 1px solid $color-control;
background: $color-border; background: $color-accent-dark;
margin-top: -$thumb-margin; margin-top: -$thumb-margin;
margin-left: -$thumb-size * .5; margin-left: -$thumb-size * .5;
} }
&.disabled {
background: lighten($color-border, 5%);
}
&.focused { &.focused {
border-color: $color-focus; border-color: $color-theme-blue;
} }
} }
}
.disabled {
pointer-events: none;
} }

123
src/Squidex/app/framework/angular/slider.component.ts

@ -5,18 +5,37 @@
* Copyright (c) Sebastian Stehle. All rights reserved * Copyright (c) Sebastian Stehle. All rights reserved
*/ */
import { Component, ElementRef, EventEmitter, Input, OnChanges, Output, Renderer, ViewChild } from '@angular/core'; import { Component, ElementRef, forwardRef, Input, Renderer, ViewChild } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
/* tslint:disable:no-empty */
const NOOP = () => { };
export const SQX_SLIDER_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SliderComponent),
multi: true
};
@Component({ @Component({
selector: 'sqx-slider', selector: 'sqx-slider',
styleUrls: ['./slider.component.scss'], styleUrls: ['./slider.component.scss'],
templateUrl: './slider.component.html' templateUrl: './slider.component.html',
providers: [SQX_SLIDER_CONTROL_VALUE_ACCESSOR]
}) })
export class SliderComponent implements OnChanges { export class SliderComponent implements ControlValueAccessor {
private changeCallback: (value: any) => void = NOOP;
private touchedCallback: () => void = NOOP;
private mouseMoveSubscription: Function | null; private mouseMoveSubscription: Function | null;
private mouseUpSubscription: Function | null; private mouseUpSubscription: Function | null;
private centerStartOffset = 0; private centerStartOffset = 0;
private startValue: number; private startValue: number;
private lastValue: number;
private value: number;
private isDragging = false;
public isDisabled: boolean = false;
@ViewChild('bar') @ViewChild('bar')
public bar: ElementRef; public bar: ElementRef;
@ -31,31 +50,42 @@ export class SliderComponent implements OnChanges {
public max = 100; public max = 100;
@Input() @Input()
public value: number; public step = 1;
@Output()
public valueChange = new EventEmitter();
constructor(private readonly renderer: Renderer) { } constructor(private readonly renderer: Renderer) { }
public ngOnChanges() { public writeValue(value: any) {
const relativeValue = (this.value - this.min) / (this.max - this.min); this.lastValue = this.value = value;
this.setThumbPosition(relativeValue); this.updateThumbPosition();
} }
public onBarMouseClick(event: MouseEvent) { public setDisabledState(isDisabled: boolean): void {
const relativeValue = this.getRelativeX(event); this.isDisabled = isDisabled;
}
this.setThumbPosition(relativeValue); public registerOnChange(fn: any) {
this.changeCallback = fn;
}
const newValue = Math.round(relativeValue * (this.max - this.min) + this.min); public registerOnTouched(fn: any) {
this.touchedCallback = fn;
}
if (newValue !== this.value) { public onBarMouseClick(event: MouseEvent) {
this.valueChange.emit(newValue); if (this.mouseMoveSubscription) {
return;
} }
this.stopEvent(event); const relativeValue = this.getRelativeX(event);
this.value = Math.round((relativeValue * (this.max - this.min) + this.min) / this.step) * this.step;
this.updateThumbPosition();
this.updateTouched();
this.updateValue();
return false;
} }
public onThumbMouseDown(event: MouseEvent) { public onThumbMouseDown(event: MouseEvent) {
@ -75,32 +105,39 @@ export class SliderComponent implements OnChanges {
this.renderer.setElementClass(this.thumb.nativeElement, 'focused', true); this.renderer.setElementClass(this.thumb.nativeElement, 'focused', true);
this.stopEvent(event); this.isDragging = true;
return false;
} }
private onMouseMove(event: MouseEvent) { private onMouseMove(event: MouseEvent) {
if (!this.isDragging) {
return;
}
const relativeValue = this.getRelativeX(event); const relativeValue = this.getRelativeX(event);
this.setThumbPosition(relativeValue); this.value = Math.round((relativeValue * (this.max - this.min) + this.min) / this.step) * this.step;
this.updateThumbPosition();
this.updateTouched();
this.stopEvent(event); return false;
} }
private onMouseUp(event: MouseEvent) { private onMouseUp(event: MouseEvent) {
const relativeValue = this.getRelativeX(event); this.updateValue();
const newValue = Math.round(relativeValue * (this.max - this.min) + this.min);
if (newValue !== this.startValue) {
this.valueChange.emit(newValue);
}
this.releaseMouseHandlers(); setTimeout(() => {
this.renderer.setElementClass(this.thumb.nativeElement, 'focused', false); this.releaseMouseHandlers();
this.renderer.setElementClass(this.thumb.nativeElement, 'focused', false);
}, 10);
this.centerStartOffset = 0; this.centerStartOffset = 0;
this.stopEvent(event); this.isDragging = false;
return false;
} }
private getRelativeX(event: MouseEvent): number { private getRelativeX(event: MouseEvent): number {
@ -115,20 +152,30 @@ export class SliderComponent implements OnChanges {
private getParentX(e: any, container: any): number { private getParentX(e: any, container: any): number {
const rect = container.getBoundingClientRect(); const rect = container.getBoundingClientRect();
const x = !!e.touches ? e.touches[0].pageX : e.pageX; const x =
!!e.touches ?
e.touches[0].pageX :
e.pageX;
return x - rect.left; return x - rect.left;
} }
private setThumbPosition(relativeValue: number) { private updateTouched() {
relativeValue = Math.min(1, Math.max(0, relativeValue)); this.touchedCallback();
}
private updateValue() {
if (this.lastValue !== this.value) {
this.lastValue = this.value;
this.renderer.setElementStyle(this.thumb.nativeElement, 'left', relativeValue * 100 + '%'); this.changeCallback(this.value);
}
} }
private stopEvent(event: Event) { private updateThumbPosition() {
event.preventDefault(); const relativeValue = Math.min(1, Math.max(0, (this.value - this.min) / (this.max - this.min)));
event.stopPropagation();
this.renderer.setElementStyle(this.thumb.nativeElement, 'left', relativeValue * 100 + '%');
} }
private releaseMouseHandlers() { private releaseMouseHandlers() {
@ -141,5 +188,7 @@ export class SliderComponent implements OnChanges {
this.mouseUpSubscription(); this.mouseUpSubscription();
this.mouseUpSubscription = null; this.mouseUpSubscription = null;
} }
this.isDragging = false;
} }
} }

11
src/Squidex/app/framework/angular/tag-editor.component.html

@ -0,0 +1,11 @@
<input type="text" class="form-control" [attr.name]="inputName" (keydown)="onKeyDown($event)" (blur)="onBlur()"
[formControl]="addInput"
autocomplete="off"
autocorrect="off"
autocapitalize="off">
<div class="items">
<span class="item" *ngFor="let item of items; let i = index" [class.disabled]="addInput.disabled">
{{item}} <i class="icon-close" (click)="remove(i)"></i>
</span>
</div>

39
src/Squidex/app/framework/angular/tag-editor.component.scss

@ -0,0 +1,39 @@
@import '_mixins';
@import '_vars';
.items {
margin-top: .4rem;
min-height: 1.6rem;
}
.item {
& {
@include border-radius(.8rem);
display: inline-block;
color: $color-accent-dark;
margin-right: .4rem;
margin-bottom: .3rem;
min-height: 1.6rem;
padding: 0 .6rem;
background: $color-theme-blue;
border: 0;
font-size: .8rem;
font-weight: normal;
line-height: 1.6rem;
}
&.disabled {
& {
pointer-events: none;
}
&,
&:hover {
background: $color-theme-blue-light;
}
}
&:hover {
background: $color-theme-blue-dark;
}
}

138
src/Squidex/app/framework/angular/tag-editor.component.ts

@ -0,0 +1,138 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import { Component, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
/* tslint:disable:no-empty */
const KEY_ENTER = 13;
const NOOP = () => { };
export interface Converter {
convert(input: string): any;
isValid(input: string): boolean;
}
export class IntConverter implements Converter {
public isValid(input: string): boolean {
return !!parseInt(input, 10) || input === '0';
}
public convert(input: string): any {
return parseInt(input, 10) || 0;
}
}
export class FloatConverter implements Converter {
public isValid(input: string): boolean {
return !!parseFloat(input) || input === '0';
}
public convert(input: string): any {
return parseFloat(input) || 0;
}
}
export class NoopConverter implements Converter {
public isValid(input: string): boolean {
return input.trim().length > 0;
}
public convert(input: string): any {
return input.trim();
}
}
export const SQX_TAG_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TagEditorComponent),
multi: true
};
@Component({
selector: 'sqx-tag-editor',
styleUrls: ['./tag-editor.component.scss'],
templateUrl: './tag-editor.component.html',
providers: [SQX_TAG_EDITOR_CONTROL_VALUE_ACCESSOR]
})
export class TagEditorComponent implements ControlValueAccessor {
private changeCallback: (value: any) => void = NOOP;
private touchedCallback: () => void = NOOP;
public addInput = new FormControl();
@Input()
public converter: Converter = new NoopConverter();
@Input()
public useDefaultValue: boolean = true;
@Input()
public inputName: string = 'tag-editor';
public items: any[] = [];
public writeValue(value: any) {
this.addInput.setValue('');
if (Array.isArray(value)) {
this.items = value;
} else {
this.items = [];
}
}
public setDisabledState(isDisabled: boolean): void {
if (isDisabled) {
this.addInput.disable();
} else {
this.addInput.enable();
}
}
public registerOnChange(fn: any) {
this.changeCallback = fn;
}
public registerOnTouched(fn: any) {
this.touchedCallback = fn;
}
public remove(index: number) {
this.updateItems([...this.items.slice(0, index), ...this.items.splice(index + 1)]);
}
public onBlur() {
this.touchedCallback();
}
public onKeyDown(event: KeyboardEvent) {
if (event.keyCode === KEY_ENTER) {
const value = <string>this.addInput.value;
if (this.converter.isValid(value)) {
const converted = this.converter.convert(value);
this.updateItems([...this.items, converted]);
this.addInput.reset();
return false;
}
}
}
private updateItems(items: string[]) {
this.items = items;
if (items.length === 0 && this.useDefaultValue) {
this.changeCallback(undefined);
} else {
this.changeCallback(this.items);
}
}
}

1
src/Squidex/app/framework/declarations.ts

@ -26,6 +26,7 @@ export * from './angular/scroll-active.directive';
export * from './angular/shortcut.component'; export * from './angular/shortcut.component';
export * from './angular/slider.component'; export * from './angular/slider.component';
export * from './angular/spinner.component'; export * from './angular/spinner.component';
export * from './angular/tag-editor.component';
export * from './angular/title.component'; export * from './angular/title.component';
export * from './angular/user-report.component'; export * from './angular/user-report.component';
export * from './configurations'; export * from './configurations';

3
src/Squidex/app/framework/module.ts

@ -35,6 +35,7 @@ import {
ShortTimePipe, ShortTimePipe,
SliderComponent, SliderComponent,
SpinnerComponent, SpinnerComponent,
TagEditorComponent,
TitleComponent, TitleComponent,
UserReportComponent UserReportComponent
} from './declarations'; } from './declarations';
@ -71,6 +72,7 @@ import {
ShortTimePipe, ShortTimePipe,
SliderComponent, SliderComponent,
SpinnerComponent, SpinnerComponent,
TagEditorComponent,
TitleComponent, TitleComponent,
UserReportComponent UserReportComponent
], ],
@ -98,6 +100,7 @@ import {
ShortTimePipe, ShortTimePipe,
SliderComponent, SliderComponent,
SpinnerComponent, SpinnerComponent,
TagEditorComponent,
TitleComponent, TitleComponent,
UserReportComponent, UserReportComponent,
HttpModule, HttpModule,

8
src/Squidex/app/shared/components/app-form.component.html

@ -8,15 +8,15 @@
<div class="form-group"> <div class="form-group">
<label for="app-name">Name</label> <label for="app-name">Name</label>
<div class="errors-box" *ngIf="createForm.get('name').invalid && createForm.get('name').touched" [@fade]> <div class="errors-box" *ngIf="createForm.controls.name.invalid && createForm.controls.name.touched" [@fade]>
<div class="errors"> <div class="errors">
<span *ngIf="createForm.get('name').hasError('required')"> <span *ngIf="createForm.controls.name.hasError('required')">
Name is required. Name is required.
</span> </span>
<span *ngIf="createForm.get('name').hasError('maxlength')"> <span *ngIf="createForm.controls.name.hasError('maxlength')">
Name can not have more than 40 characters. Name can not have more than 40 characters.
</span> </span>
<span *ngIf="createForm.get('name').hasError('pattern')"> <span *ngIf="createForm.controls.name.hasError('pattern')">
Name can contain lower case letters (a-z), numbers and dashes only (not at the end). Name can contain lower case letters (a-z), numbers and dashes only (not at the end).
</span> </span>
</div> </div>

14
src/Squidex/app/shared/components/history.component.ts

@ -5,24 +5,18 @@
* Copyright (c) Sebastian Stehle. All rights reserved * Copyright (c) Sebastian Stehle. All rights reserved
*/ */
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Observable, Subscription } from 'rxjs'; import { Observable } from 'rxjs';
import { import { MessageBus, NotificationService } from 'framework';
ImmutableArray,
MessageBus,
NotificationService
} from 'framework';
import { AppComponentBase } from './../app-component-base'; import { AppComponentBase } from './../app-component-base';
import { AppsStoreService } from './../services/apps-store.service'; import { AppsStoreService } from './../services/apps-store.service';
import { HistoryChannelUpdated } from './../utils/messages'; import { HistoryChannelUpdated } from './../utils/messages';
import { HistoryEventDto, HistoryService } from './../services/history.service'; import { HistoryService } from './../services/history.service';
import { UsersProviderService } from './../services/users-provider.service'; import { UsersProviderService } from './../services/users-provider.service';
const FALLBACK_NAME = 'my-app';
const REPLACEMENT_REGEXP = new RegExp('{([^\s:]*):([^}]*)}');
const REPLACEMENT_TEMP = '$TEMP$'; const REPLACEMENT_TEMP = '$TEMP$';
@Component({ @Component({

49
src/Squidex/app/theme/_bootstrap.scss

@ -144,6 +144,11 @@
} }
} }
.col-form-label,
.col-form-checkbox-label {
text-align: right;
}
.form-hint { .form-hint {
& { & {
font-size: .8rem; font-size: .8rem;
@ -239,6 +244,50 @@
font-weight: normal; font-weight: normal;
} }
&-radio {
& {
color: darken($color-border, 20%);
cursor: pointer;
border: 1px solid $color-border;
background: transparent;
margin-right: .5rem;
font-size: 1.5rem;
font-weight: normal;
text-align: center;
width: 4.5rem;
}
.radio-label {
display: block;
font-size: .7rem;
font-weight: bold;
margin-left: -.5rem;
margin-right: -.5rem;
line-height: 1.5rem;
}
&.active {
& {
@include box-shadow(0, 0, 10px, .5);
background: $color-theme-blue;
border: 0;
color: $color-accent-dark;
}
&:hover {
color: $color-accent-dark;
}
}
&:hover {
color: $color-theme-blue;
}
.radio-input {
display: none;
}
}
&-link { &-link {
&.btn-danger { &.btn-danger {
@include link-button($color-theme-error); @include link-button($color-theme-error);

1
src/Squidex/app/theme/_vars.scss

@ -3,6 +3,7 @@ $color-border: #dbe4eb;
$color-text: #373a3c; $color-text: #373a3c;
$color-empty: #777; $color-empty: #777;
$color-control: rgba(0, 0, 0, 0.15);
$color-theme-blue: #438cef; $color-theme-blue: #438cef;
$color-theme-blue-dark: #3f83df; $color-theme-blue-dark: #3f83df;

BIN
src/Squidex/app/theme/icomoon/fonts/icomoon.eot

Binary file not shown.

9
src/Squidex/app/theme/icomoon/fonts/icomoon.svg

@ -15,7 +15,16 @@
<glyph unicode="&#xe901;" glyph-name="plus" d="M810 384.667h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" /> <glyph unicode="&#xe901;" glyph-name="plus" d="M810 384.667h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
<glyph unicode="&#xe902;" glyph-name="settings2" d="M972.512 554.24l-98.048 19.648c-4.928 14.176-10.752 27.936-17.184 41.248l55.552 83.328c16.928 25.376 13.568 59.2-8 80.736l-61.568 61.568c-12.384 12.384-28.736 18.752-45.312 18.752-12.256 0-24.64-3.52-35.424-10.752l-83.328-55.52c-13.376 6.464-27.136 12.224-41.312 17.152l-19.648 98.080c-5.952 29.952-32.256 51.456-62.752 51.456h-87.040c-30.496 0-56.768-21.536-62.752-51.456l-19.648-98.080c-14.176-4.928-27.936-10.72-41.248-17.152l-83.296 55.52c-10.848 7.232-23.2 10.752-35.488 10.752-16.544 0-32.896-6.368-45.28-18.752l-61.536-61.568c-21.568-21.568-24.928-55.36-8-80.736l55.52-83.328c-6.464-13.344-12.224-27.104-17.152-41.28l-98.112-19.616c-29.92-5.984-51.456-32.256-51.456-62.752v-87.040c0-30.496 21.536-56.8 51.456-62.752l98.080-19.68c4.928-14.176 10.72-27.936 17.152-41.248l-55.488-83.328c-16.928-25.376-13.568-59.2 8-80.736l61.568-61.568c12.384-12.384 28.736-18.752 45.28-18.752 12.288 0 24.672 3.552 35.456 10.752l83.328 55.552c13.344-6.496 27.104-12.256 41.28-17.184l19.616-98.048c5.984-29.952 32.256-51.488 62.752-51.488h87.040c30.496 0 56.8 21.568 62.752 51.488l19.68 98.048c14.176 4.928 27.936 10.752 41.248 17.184l83.328-55.552c10.816-7.2 23.2-10.752 35.424-10.752 16.576 0 32.928 6.368 45.312 18.752l61.568 61.568c21.568 21.568 24.928 55.36 8 80.736l-55.552 83.328c6.496 13.376 12.256 27.136 17.184 41.312l98.048 19.616c29.92 5.92 51.488 32.256 51.488 62.752v87.040c0 30.496-21.568 56.768-51.488 62.752zM861.888 384.8c-22.24-4.448-40.448-20.32-47.872-41.76-4.128-11.808-8.928-23.264-14.304-34.368-9.952-20.448-8.256-44.576 4.32-63.424l55.552-83.328-61.568-61.568-83.328 55.552c-10.688 7.136-23.072 10.752-35.488 10.752-9.504 0-19.072-2.112-27.872-6.368-11.136-5.376-22.56-10.24-34.432-14.368-21.376-7.424-37.248-25.632-41.696-47.872l-19.68-98.112h-87.040l-19.616 98.112c-4.448 22.24-20.32 40.448-41.728 47.872-11.808 4.128-23.296 8.928-34.4 14.304-8.832 4.32-18.368 6.432-27.904 6.432-12.448 0-24.8-3.616-35.488-10.752l-83.328-55.552-61.568 61.568 55.52 83.328c12.576 18.88 14.208 43.008 4.384 63.36-5.376 11.136-10.208 22.56-14.336 34.432-7.424 21.376-25.664 37.248-47.872 41.696l-98.080 19.68-0.064 87.072 98.112 19.616c22.208 4.448 40.448 20.32 47.872 41.728 4.128 11.808 8.896 23.296 14.304 34.4 9.92 20.416 8.256 44.544-4.352 63.392l-55.488 83.328 61.536 61.568 83.328-55.52c10.688-7.136 23.072-10.752 35.488-10.752 9.504 0 19.040 2.112 27.872 6.368 11.104 5.376 22.56 10.208 34.4 14.336 21.408 7.424 37.28 25.664 41.728 47.872l19.648 98.080 87.040 0.032 19.616-98.112c4.448-22.208 20.32-40.448 41.76-47.872 11.808-4.128 23.264-8.896 34.368-14.304 8.864-4.288 18.368-6.4 27.936-6.4 12.448 0 24.8 3.616 35.488 10.752l83.328 55.52 61.568-61.568-55.552-83.328c-12.576-18.88-14.176-42.976-4.384-63.36 5.376-11.104 10.24-22.56 14.368-34.4 7.424-21.408 25.632-37.28 47.872-41.728l98.048-19.648 0.096-87.040-98.112-19.648zM512 671.968c-123.68 0-224-100.32-224-224 0-123.712 100.32-224 224-224s224 100.32 224 224c0 123.68-100.32 224-224 224zM512 251.936c-108.224 0-196 87.808-196 196 0 108.224 87.776 196 196 196 108.192 0 196-87.776 196-196 0-108.192-87.808-196-196-196zM512 575.968c-70.72 0-128-57.28-128-128 0-70.688 57.28-128 128-128 70.688 0 128 57.312 128 128s-57.312 128-128 128zM512 351.936c-52.992 0-96 43.008-96 96s43.008 96 96 96 96-43.008 96-96c0-52.992-43.008-96-96-96z" /> <glyph unicode="&#xe902;" glyph-name="settings2" d="M972.512 554.24l-98.048 19.648c-4.928 14.176-10.752 27.936-17.184 41.248l55.552 83.328c16.928 25.376 13.568 59.2-8 80.736l-61.568 61.568c-12.384 12.384-28.736 18.752-45.312 18.752-12.256 0-24.64-3.52-35.424-10.752l-83.328-55.52c-13.376 6.464-27.136 12.224-41.312 17.152l-19.648 98.080c-5.952 29.952-32.256 51.456-62.752 51.456h-87.040c-30.496 0-56.768-21.536-62.752-51.456l-19.648-98.080c-14.176-4.928-27.936-10.72-41.248-17.152l-83.296 55.52c-10.848 7.232-23.2 10.752-35.488 10.752-16.544 0-32.896-6.368-45.28-18.752l-61.536-61.568c-21.568-21.568-24.928-55.36-8-80.736l55.52-83.328c-6.464-13.344-12.224-27.104-17.152-41.28l-98.112-19.616c-29.92-5.984-51.456-32.256-51.456-62.752v-87.040c0-30.496 21.536-56.8 51.456-62.752l98.080-19.68c4.928-14.176 10.72-27.936 17.152-41.248l-55.488-83.328c-16.928-25.376-13.568-59.2 8-80.736l61.568-61.568c12.384-12.384 28.736-18.752 45.28-18.752 12.288 0 24.672 3.552 35.456 10.752l83.328 55.552c13.344-6.496 27.104-12.256 41.28-17.184l19.616-98.048c5.984-29.952 32.256-51.488 62.752-51.488h87.040c30.496 0 56.8 21.568 62.752 51.488l19.68 98.048c14.176 4.928 27.936 10.752 41.248 17.184l83.328-55.552c10.816-7.2 23.2-10.752 35.424-10.752 16.576 0 32.928 6.368 45.312 18.752l61.568 61.568c21.568 21.568 24.928 55.36 8 80.736l-55.552 83.328c6.496 13.376 12.256 27.136 17.184 41.312l98.048 19.616c29.92 5.92 51.488 32.256 51.488 62.752v87.040c0 30.496-21.568 56.768-51.488 62.752zM861.888 384.8c-22.24-4.448-40.448-20.32-47.872-41.76-4.128-11.808-8.928-23.264-14.304-34.368-9.952-20.448-8.256-44.576 4.32-63.424l55.552-83.328-61.568-61.568-83.328 55.552c-10.688 7.136-23.072 10.752-35.488 10.752-9.504 0-19.072-2.112-27.872-6.368-11.136-5.376-22.56-10.24-34.432-14.368-21.376-7.424-37.248-25.632-41.696-47.872l-19.68-98.112h-87.040l-19.616 98.112c-4.448 22.24-20.32 40.448-41.728 47.872-11.808 4.128-23.296 8.928-34.4 14.304-8.832 4.32-18.368 6.432-27.904 6.432-12.448 0-24.8-3.616-35.488-10.752l-83.328-55.552-61.568 61.568 55.52 83.328c12.576 18.88 14.208 43.008 4.384 63.36-5.376 11.136-10.208 22.56-14.336 34.432-7.424 21.376-25.664 37.248-47.872 41.696l-98.080 19.68-0.064 87.072 98.112 19.616c22.208 4.448 40.448 20.32 47.872 41.728 4.128 11.808 8.896 23.296 14.304 34.4 9.92 20.416 8.256 44.544-4.352 63.392l-55.488 83.328 61.536 61.568 83.328-55.52c10.688-7.136 23.072-10.752 35.488-10.752 9.504 0 19.040 2.112 27.872 6.368 11.104 5.376 22.56 10.208 34.4 14.336 21.408 7.424 37.28 25.664 41.728 47.872l19.648 98.080 87.040 0.032 19.616-98.112c4.448-22.208 20.32-40.448 41.76-47.872 11.808-4.128 23.264-8.896 34.368-14.304 8.864-4.288 18.368-6.4 27.936-6.4 12.448 0 24.8 3.616 35.488 10.752l83.328 55.52 61.568-61.568-55.552-83.328c-12.576-18.88-14.176-42.976-4.384-63.36 5.376-11.104 10.24-22.56 14.368-34.4 7.424-21.408 25.632-37.28 47.872-41.728l98.048-19.648 0.096-87.040-98.112-19.648zM512 671.968c-123.68 0-224-100.32-224-224 0-123.712 100.32-224 224-224s224 100.32 224 224c0 123.68-100.32 224-224 224zM512 251.936c-108.224 0-196 87.808-196 196 0 108.224 87.776 196 196 196 108.192 0 196-87.776 196-196 0-108.192-87.808-196-196-196zM512 575.968c-70.72 0-128-57.28-128-128 0-70.688 57.28-128 128-128 70.688 0 128 57.312 128 128s-57.312 128-128 128zM512 351.936c-52.992 0-96 43.008-96 96s43.008 96 96 96 96-43.008 96-96c0-52.992-43.008-96-96-96z" />
<glyph unicode="&#xe903;" glyph-name="dots" d="M512.051 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64zM153.651 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.483 112.589 112.64s-50.381 112.64-112.589 112.64zM870.451 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64z" /> <glyph unicode="&#xe903;" glyph-name="dots" d="M512.051 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64zM153.651 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.483 112.589 112.64s-50.381 112.64-112.589 112.64zM870.451 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64z" />
<glyph unicode="&#xe904;" glyph-name="type-boolean" d="M97.897 837.749c-13.477 0-24.37 10.943-24.37 24.371 0 13.477 10.894 24.371 24.37 24.371h292.443c13.452 0 24.37-10.894 24.37-24.371 0-13.453-10.918-24.371-24.37-24.371h-121.851v-316.829c0-13.453-10.918-24.371-24.37-24.371-13.477 0-24.37 10.918-24.37 24.371v316.829h-121.851zM926.487 252.858c13.452 0 24.37-10.894 24.37-24.371s-10.894-24.371-24.37-24.371h-170.592v-170.6c0-13.477-10.894-24.371-24.37-24.371s-24.37 10.894-24.37 24.371v341.201c0 13.477 10.894 24.371 24.37 24.371h194.962c13.477 0 24.37-10.894 24.37-24.371s-10.894-24.371-24.37-24.371h-170.592v-97.486h170.592zM943.351 879.765c9.456-9.481 9.456-24.859 0-34.315l-828.785-828.801c-9.456-9.481-24.809-9.481-34.313 0-9.48 9.481-9.48 24.835 0 34.315l828.785 828.801c9.456 9.456 24.833 9.456 34.313 0z" />
<glyph unicode="&#xe905;" glyph-name="pencil" d="M864 960c88.364 0 160-71.634 160-160 0-36.020-11.91-69.258-32-96l-64-64-224 224 64 64c26.742 20.090 59.978 32 96 32zM64 224l-64-288 288 64 592 592-224 224-592-592zM715.578 596.422l-448-448-55.156 55.156 448 448 55.156-55.156z" /> <glyph unicode="&#xe905;" glyph-name="pencil" d="M864 960c88.364 0 160-71.634 160-160 0-36.020-11.91-69.258-32-96l-64-64-224 224 64 64c26.742 20.090 59.978 32 96 32zM64 224l-64-288 288 64 592 592-224 224-592-592zM715.578 596.422l-448-448-55.156 55.156 448 448 55.156-55.156z" />
<glyph unicode="&#xe906;" glyph-name="control-checkbox" d="M768 115.2v256h51.2v-281.6c0-28.262-22.938-51.2-51.2-51.2h-716.8c-28.262 0-51.2 22.938-51.2 51.2v716.8c0 28.262 22.938 51.2 51.2 51.2h716.8c28.262 0 51.2-22.938 51.2-51.2v-128h-51.2v102.4c0 14.157-11.443 25.6-25.6 25.6h-665.6c-14.131 0-25.6-11.443-25.6-25.6v-665.6c0-14.157 11.469-25.6 25.6-25.6h665.6c14.157 0 25.6 11.443 25.6 25.6zM1016.678 747.853c9.933-9.907 9.933-26.010 0-35.942l-408.448-408.474c-0.461-0.512-0.614-1.178-1.126-1.69-5.043-5.018-11.674-7.475-18.278-7.373-6.605-0.102-13.235 2.355-18.278 7.373-0.512 0.486-0.666 1.152-1.126 1.69l-254.874 254.874c-9.933 9.933-9.933 26.035 0 35.942 9.907 9.958 26.010 9.958 35.942 0l238.31-238.285 391.91 391.885c9.933 9.958 26.010 9.958 35.968 0z" />
<glyph unicode="&#xe907;" glyph-name="control-dropdown" d="M146.286 326.095c-40.375 0-73.143-32.744-73.143-73.143s32.768-73.143 73.143-73.143c40.375 0 73.143 32.744 73.143 73.143s-32.768 73.143-73.143 73.143zM146.286 228.571c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381zM146.286 131.048c-40.375 0-73.143-32.744-73.143-73.143s32.768-73.143 73.143-73.143c40.375 0 73.143 32.744 73.143 73.143s-32.768 73.143-73.143 73.143zM146.286 33.524c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381zM950.857 935.619h-877.714c-26.917 0-48.762-21.845-48.762-48.762v-268.19c0-26.917 21.845-48.762 48.762-48.762h877.714c26.917 0 48.762 21.845 48.762 48.762v268.19c0 26.917-21.845 48.762-48.762 48.762zM585.143 618.667h-487.619c-13.483 0-24.381 10.898-24.381 24.381v219.429c0 13.483 10.898 24.381 24.381 24.381h487.619v-268.19zM950.857 643.048c0-13.483-10.898-24.381-24.381-24.381h-292.571v268.19h292.571c13.483 0 24.381-10.898 24.381-24.381v-219.429zM926.476 472.381c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-609.524c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381h609.524zM926.476 277.333c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-609.524c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381h609.524zM926.476 82.286c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-609.524c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381h609.524zM146.286 521.143c-40.375 0-73.143-32.768-73.143-73.143s32.768-73.143 73.143-73.143c40.375 0 73.143 32.768 73.143 73.143s-32.768 73.143-73.143 73.143zM146.286 423.619c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381zM707.048 789.333c6.729 0 170.667-0.366 170.667 0 0-6.705-84.846-97.524-85.333-97.524-0.414-0.512-85.699 97.182-85.333 97.524z" />
<glyph unicode="&#xe908;" glyph-name="control-input" d="M298.374 618.715c-0.585 0.098-1.122 0.098-1.707 0.146-0.561-0.049-1.097-0.049-1.682-0.146-7.851-0.049-15.579-4.267-19.846-12.434l-126.22-291.669c-6.363-12.142-2.755-27.575 8.070-34.45s24.747-2.609 31.086 9.533l26.307 60.806c0.049 0 0.073-0.024 0.098-0.024h162.28c0.488 0 0.853 0.219 1.317 0.244l26.161-61.026c6.315-12.142 20.139-16.408 30.866-9.533s14.287 22.309 7.997 34.45l-125.050 291.669c-4.242 8.168-11.874 12.361-19.675 12.434zM235.496 399.238l61.172 141.385 60.611-141.385zM950.857 716.19c26.917 0 48.762-21.845 48.762-48.762v-438.857c0-26.917-21.845-48.762-48.762-48.762h-219.429v48.762h195.048c13.483 0 24.381 10.898 24.381 24.381v390.095c0 13.483-10.898 24.381-24.381 24.381h-195.048v48.762h219.429zM585.143 179.81h-512c-26.917 0-48.762 21.845-48.762 48.762v438.857c0 26.917 21.845 48.762 48.762 48.762h512v-48.762h-487.619c-13.458 0-24.381-10.898-24.381-24.381v-390.095c0-13.483 10.923-24.381 24.381-24.381h487.619zM804.571 33.524c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-292.571c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381h121.905v828.952h-121.905c-13.483 0-24.381 10.898-24.381 24.381s10.898 24.381 24.381 24.381h292.571c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-121.905v-828.952h121.905z" />
<glyph unicode="&#xe909;" glyph-name="type-number" d="M268.19 301.714c13.458 0 24.381-10.923 24.381-24.381s-10.923-24.381-24.381-24.381h-195.048c-13.458 0-24.381 10.923-24.381 24.381s10.923 24.381 24.381 24.381h73.143v292.571h-48.762c-13.458 0-24.381 10.923-24.381 24.381s10.923 24.381 24.381 24.381h73.143c13.458 0 24.381-10.923 24.381-24.381v-316.952h73.143zM609.524 643.048c13.458 0 24.381-10.923 24.381-24.381v-170.667c0-13.458-10.923-24.381-24.381-24.381h-170.667v-121.905h170.667c13.458 0 24.381-10.923 24.381-24.381s-10.923-24.381-24.381-24.381h-195.048c-13.458 0-24.381 10.923-24.381 24.381v170.667c0 13.458 10.923 24.381 24.381 24.381h170.667v121.905h-170.667c-13.458 0-24.381 10.923-24.381 24.381s10.923 24.381 24.381 24.381h195.048zM950.857 643.048c13.458 0 24.381-10.923 24.381-24.381v-341.333c0-13.458-10.923-24.381-24.381-24.381h-195.048c-13.458 0-24.381 10.923-24.381 24.381s10.923 24.381 24.381 24.381h170.667v121.905h-170.667c-13.458 0-24.381 10.923-24.381 24.381s10.923 24.381 24.381 24.381h170.667v121.905h-170.667c-13.458 0-24.381 10.923-24.381 24.381s10.923 24.381 24.381 24.381h195.048z" />
<glyph unicode="&#xe90a;" glyph-name="control-textarea" d="M97.524 374.857h48.762v-97.524h-48.762zM97.524 667.429h48.762v73.143h73.143v195.048h-195.048v-195.048h73.143zM73.143 789.333v97.524h97.524v-97.524zM146.286 472.381h-48.762v97.524h48.762zM804.571 935.619v-195.048h195.048v195.048zM950.857 789.333h-97.524v97.524h97.524zM780.19 813.714h-97.524v48.762h97.524zM585.143 813.714h-97.524v48.762h97.524zM390.095 813.714h-97.524v48.762h97.524zM390.095 82.286h97.524v-48.762h-97.524zM585.143 82.286h97.524v-48.762h-97.524zM772.974 661.723c9.874-9.923 9.874-25.966 0-35.84-9.923-9.874-25.941-9.874-35.84 0l-65.926 65.926h-134.827v-463.238h48.494c6.827 0.293 13.726-1.999 18.944-7.217l22.869-22.869c9.874-9.923 9.874-25.941 0-35.84-9.899-9.874-25.941-9.874-35.84 0l-17.164 17.164h-123.611l-16.433-16.457c-9.801-9.826-25.771-9.826-35.596 0s-9.826 25.771 0 35.596l22.455 22.455c5.169 5.193 12.044 7.461 18.846 7.168h48.274v463.238h-135.095l-65.195-65.219c-9.801-9.826-25.771-9.826-35.596 0s-9.826 25.795 0 35.596l71.217 71.192c5.169 5.193 12.044 7.485 18.822 7.192h340.626c6.827 0.293 13.726-1.999 18.944-7.217l71.631-71.631zM877.714 277.333h48.762v-97.524h-48.762zM219.429 155.429h-73.143v24.381h-48.762v-24.381h-73.143v-195.048h195.048v73.143h73.143v48.762h-73.143zM170.667 9.143h-97.524v97.524h97.524zM926.476 569.905h-48.762v97.524h48.762zM877.714 472.381h48.762v-97.524h-48.762zM804.571 82.286h-24.381v-48.762h24.381v-73.143h195.048v195.048h-195.048zM853.333 106.667h97.524v-97.524h-97.524z" />
<glyph unicode="&#xe90b;" glyph-name="type-string" d="M853.333 57.905h-682.667c-13.458 0-24.381-10.898-24.381-24.381s10.923-24.381 24.381-24.381h682.667c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381zM209.822 157.379c12.386-5.291 26.722 0.439 32.012 12.8l119.052 277.821h302.226l119.052-277.821c3.974-9.216 12.922-14.75 22.406-14.75 3.243 0 6.485 0.61 9.63 1.95 12.386 5.339 18.091 19.675 12.8 32.037l-125.342 292.352c-0.049 0.049-0.049 0.146-0.098 0.195l-167.131 390.095c-3.852 8.997-12.678 14.799-22.43 14.799s-18.578-5.803-22.43-14.775l-167.156-390.095c-0.049-0.049-0.049-0.146-0.098-0.195l-125.318-292.352c-5.266-12.386 0.439-26.722 12.824-32.061zM512 800.597l130.194-303.835h-260.389l130.194 303.835z" />
<glyph unicode="&#xe90c;" glyph-name="control-toggle" d="M682.667 911.238h-341.333c-121.198 0-219.429-98.231-219.429-219.429s98.231-219.429 219.429-219.429h341.333c121.198 0 219.429 98.231 219.429 219.429s-98.231 219.429-219.429 219.429zM682.667 521.143h-341.333c-94.257 0-170.667 76.41-170.667 170.667s76.41 170.667 170.667 170.667h341.333c94.257 0 170.667-76.41 170.667-170.667s-76.41-170.667-170.667-170.667zM341.333 813.714c-67.34 0-121.905-54.565-121.905-121.905s54.565-121.905 121.905-121.905c67.34 0 121.905 54.565 121.905 121.905s-54.565 121.905-121.905 121.905zM341.333 618.667c-40.399 0-73.143 32.744-73.143 73.143s32.744 73.143 73.143 73.143c40.399 0 73.143-32.744 73.143-73.143s-32.744-73.143-73.143-73.143zM121.905 204.19c0-121.198 98.231-219.429 219.429-219.429h341.333c121.198 0 219.429 98.231 219.429 219.429s-98.231 219.429-219.429 219.429h-341.333c-121.198 0-219.429-98.231-219.429-219.429zM170.667 204.19c0 94.257 76.41 170.667 170.667 170.667h341.333c94.257 0 170.667-76.41 170.667-170.667s-76.41-170.667-170.667-170.667h-341.333c-94.257 0-170.667 76.41-170.667 170.667zM560.762 204.19c0-67.34 54.565-121.905 121.905-121.905s121.905 54.565 121.905 121.905c0 67.34-54.565 121.905-121.905 121.905s-121.905-54.565-121.905-121.905zM609.524 204.19c0 40.399 32.744 73.143 73.143 73.143s73.143-32.744 73.143-73.143c0-40.399-32.744-73.143-73.143-73.143s-73.143 32.744-73.143 73.143z" />
<glyph unicode="&#xe90d;" glyph-name="control-radio" d="M170.667 252.952c-80.774 0-146.286-65.512-146.286-146.286s65.512-146.286 146.286-146.286c80.774 0 146.286 65.512 146.286 146.286s-65.512 146.286-146.286 146.286zM170.667 9.143c-53.858 0-97.524 43.666-97.524 97.524s43.666 97.524 97.524 97.524c53.858 0 97.524-43.666 97.524-97.524s-43.666-97.524-97.524-97.524zM390.095 764.952c-13.458 0-24.381 10.898-24.381 24.381s10.923 24.381 24.381 24.381h585.143c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-585.143zM975.238 472.381c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-585.143c-13.458 0-24.381 10.898-24.381 24.381s10.923 24.381 24.381 24.381h585.143zM170.667 935.619c-80.774 0-146.286-65.512-146.286-146.286s65.512-146.286 146.286-146.286c80.774 0 146.286 65.512 146.286 146.286s-65.512 146.286-146.286 146.286zM170.667 691.81c-53.858 0-97.524 43.666-97.524 97.524s43.666 97.524 97.524 97.524c53.858 0 97.524-43.666 97.524-97.524s-43.666-97.524-97.524-97.524zM170.667 594.286c-80.774 0-146.286-65.512-146.286-146.286s65.512-146.286 146.286-146.286c80.774 0 146.286 65.512 146.286 146.286s-65.512 146.286-146.286 146.286zM170.667 350.476c-53.858 0-97.524 43.666-97.524 97.524s43.666 97.524 97.524 97.524c53.858 0 97.524-43.666 97.524-97.524s-43.666-97.524-97.524-97.524zM170.667 838.095c26.917 0 48.762-21.845 48.762-48.762s-21.845-48.762-48.762-48.762c-26.917 0-48.762 21.845-48.762 48.762s21.845 48.762 48.762 48.762zM975.238 131.048c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381h-585.143c-13.458 0-24.381 10.898-24.381 24.381s10.923 24.381 24.381 24.381h585.143z" />
<glyph unicode="&#xe90e;" glyph-name="media" horiz-adv-x="1152" d="M1088 832h-64v64c0 35.2-28.8 64-64 64h-896c-35.2 0-64-28.8-64-64v-768c0-35.2 28.8-64 64-64h64v-64c0-35.2 28.8-64 64-64h896c35.2 0 64 28.8 64 64v768c0 35.2-28.8 64-64 64zM128 768v-640h-63.886c-0.040 0.034-0.082 0.076-0.114 0.116v767.77c0.034 0.040 0.076 0.082 0.114 0.114h895.77c0.040-0.034 0.082-0.076 0.116-0.116v-63.884h-768c-35.2 0-64-28.8-64-64v0zM1088 0.116c-0.034-0.040-0.076-0.082-0.116-0.116h-895.77c-0.040 0.034-0.082 0.076-0.114 0.116v767.77c0.034 0.040 0.076 0.082 0.114 0.114h895.77c0.040-0.034 0.082-0.076 0.116-0.116v-767.768zM960 608c0-53.020-42.98-96-96-96s-96 42.98-96 96 42.98 96 96 96 96-42.98 96-96zM1024 64h-768v128l224 384 256-320h64l224 192z" /> <glyph unicode="&#xe90e;" glyph-name="media" horiz-adv-x="1152" d="M1088 832h-64v64c0 35.2-28.8 64-64 64h-896c-35.2 0-64-28.8-64-64v-768c0-35.2 28.8-64 64-64h64v-64c0-35.2 28.8-64 64-64h896c35.2 0 64 28.8 64 64v768c0 35.2-28.8 64-64 64zM128 768v-640h-63.886c-0.040 0.034-0.082 0.076-0.114 0.116v767.77c0.034 0.040 0.076 0.082 0.114 0.114h895.77c0.040-0.034 0.082-0.076 0.116-0.116v-63.884h-768c-35.2 0-64-28.8-64-64v0zM1088 0.116c-0.034-0.040-0.076-0.082-0.116-0.116h-895.77c-0.040 0.034-0.082 0.076-0.114 0.116v767.77c0.034 0.040 0.076 0.082 0.114 0.114h895.77c0.040-0.034 0.082-0.076 0.116-0.116v-767.768zM960 608c0-53.020-42.98-96-96-96s-96 42.98-96 96 42.98 96 96 96 96-42.98 96-96zM1024 64h-768v128l224 384 256-320h64l224 192z" />
<glyph unicode="&#xe925;" glyph-name="content" d="M917.806 602.924c-22.21 30.292-53.174 65.7-87.178 99.704s-69.412 64.964-99.704 87.178c-51.574 37.82-76.592 42.194-90.924 42.194h-368c-44.114 0-80-35.888-80-80v-736c0-44.112 35.886-80 80-80h608c44.112 0 80 35.888 80 80v496c0 14.332-4.372 39.35-42.194 90.924zM785.374 657.374c30.7-30.7 54.8-58.398 72.58-81.374h-153.954v153.946c22.982-17.78 50.678-41.878 81.374-72.572v0zM896 16c0-8.672-7.328-16-16-16h-608c-8.672 0-16 7.328-16 16v736c0 8.672 7.328 16 16 16 0 0 367.956 0.002 368 0v-224c0-17.672 14.324-32 32-32h224v-496zM602.924 917.804c-51.574 37.822-76.592 42.196-90.924 42.196h-368c-44.112 0-80-35.888-80-80v-736c0-38.632 27.528-70.958 64-78.39v814.39c0 8.672 7.328 16 16 16h486.876c-9.646 7.92-19.028 15.26-27.952 21.804z" /> <glyph unicode="&#xe925;" glyph-name="content" d="M917.806 602.924c-22.21 30.292-53.174 65.7-87.178 99.704s-69.412 64.964-99.704 87.178c-51.574 37.82-76.592 42.194-90.924 42.194h-368c-44.114 0-80-35.888-80-80v-736c0-44.112 35.886-80 80-80h608c44.112 0 80 35.888 80 80v496c0 14.332-4.372 39.35-42.194 90.924zM785.374 657.374c30.7-30.7 54.8-58.398 72.58-81.374h-153.954v153.946c22.982-17.78 50.678-41.878 81.374-72.572v0zM896 16c0-8.672-7.328-16-16-16h-608c-8.672 0-16 7.328-16 16v736c0 8.672 7.328 16 16 16 0 0 367.956 0.002 368 0v-224c0-17.672 14.324-32 32-32h224v-496zM602.924 917.804c-51.574 37.822-76.592 42.196-90.924 42.196h-368c-44.112 0-80-35.888-80-80v-736c0-38.632 27.528-70.958 64-78.39v814.39c0 8.672 7.328 16 16 16h486.876c-9.646 7.92-19.028 15.26-27.952 21.804z" />
<glyph unicode="&#xe92c;" glyph-name="copy" d="M640 704v256h-448l-192-192v-576h384v-256h640v768h-384zM192 869.49v-101.49h-101.49l101.49 101.49zM64 256v448h192v192h320v-192l-192-192v-256h-320zM576 613.49v-101.49h-101.49l101.49 101.49zM960 0h-512v448h192v192h320v-640z" /> <glyph unicode="&#xe92c;" glyph-name="copy" d="M640 704v256h-448l-192-192v-576h384v-256h640v768h-384zM192 869.49v-101.49h-101.49l101.49 101.49zM64 256v448h192v192h320v-192l-192-192v-256h-320zM576 613.49v-101.49h-101.49l101.49 101.49zM960 0h-512v448h192v192h320v-640z" />

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
src/Squidex/app/theme/icomoon/fonts/icomoon.ttf

Binary file not shown.

BIN
src/Squidex/app/theme/icomoon/fonts/icomoon.woff

Binary file not shown.

420
src/Squidex/app/theme/icomoon/selection.json

@ -1,6 +1,357 @@
{ {
"IcoMoonType": "selection", "IcoMoonType": "selection",
"icons": [ "icons": [
{
"icon": {
"paths": [
"M170.667 707.048c-80.774 0-146.286 65.512-146.286 146.286s65.512 146.286 146.286 146.286c80.774 0 146.286-65.512 146.286-146.286s-65.512-146.286-146.286-146.286zM170.667 950.857c-53.858 0-97.524-43.666-97.524-97.524s43.666-97.524 97.524-97.524c53.858 0 97.524 43.666 97.524 97.524s-43.666 97.524-97.524 97.524zM390.095 195.048c-13.458 0-24.381-10.898-24.381-24.381s10.923-24.381 24.381-24.381h585.143c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-585.143zM975.238 487.619c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-585.143c-13.458 0-24.381-10.898-24.381-24.381s10.923-24.381 24.381-24.381h585.143zM170.667 24.381c-80.774 0-146.286 65.512-146.286 146.286s65.512 146.286 146.286 146.286c80.774 0 146.286-65.512 146.286-146.286s-65.512-146.286-146.286-146.286zM170.667 268.19c-53.858 0-97.524-43.666-97.524-97.524s43.666-97.524 97.524-97.524c53.858 0 97.524 43.666 97.524 97.524s-43.666 97.524-97.524 97.524zM170.667 365.714c-80.774 0-146.286 65.512-146.286 146.286s65.512 146.286 146.286 146.286c80.774 0 146.286-65.512 146.286-146.286s-65.512-146.286-146.286-146.286zM170.667 609.524c-53.858 0-97.524-43.666-97.524-97.524s43.666-97.524 97.524-97.524c53.858 0 97.524 43.666 97.524 97.524s-43.666 97.524-97.524 97.524zM170.667 121.905c26.917 0 48.762 21.845 48.762 48.762s-21.845 48.762-48.762 48.762c-26.917 0-48.762-21.845-48.762-48.762s21.845-48.762 48.762-48.762zM975.238 828.952c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-585.143c-13.458 0-24.381-10.898-24.381-24.381s10.923-24.381 24.381-24.381h585.143z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Radio"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 41,
"id": 10,
"name": "control-radio",
"prevSize": 32,
"code": 59661
},
"setIdx": 0,
"setId": 6,
"iconIdx": 0
},
{
"icon": {
"paths": [
"M97.897 122.251c-13.477 0-24.37-10.943-24.37-24.371 0-13.477 10.894-24.371 24.37-24.371h292.443c13.452 0 24.37 10.894 24.37 24.371 0 13.453-10.918 24.371-24.37 24.371h-121.851v316.829c0 13.453-10.918 24.371-24.37 24.371-13.477 0-24.37-10.918-24.37-24.371v-316.829h-121.851zM926.487 707.142c13.452 0 24.37 10.894 24.37 24.371s-10.894 24.371-24.37 24.371h-170.592v170.6c0 13.477-10.894 24.371-24.37 24.371s-24.37-10.894-24.37-24.371v-341.201c0-13.477 10.894-24.371 24.37-24.371h194.962c13.477 0 24.37 10.894 24.37 24.371s-10.894 24.371-24.37 24.371h-170.592v97.486h170.592zM943.351 80.235c9.456 9.481 9.456 24.859 0 34.315l-828.785 828.801c-9.456 9.481-24.809 9.481-34.313 0-9.48-9.481-9.48-24.835 0-34.315l828.785-828.801c9.456-9.456 24.833-9.456 34.313 0z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Bolean"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 30,
"id": 8,
"name": "type-boolean",
"prevSize": 32,
"code": 59652
},
"setIdx": 0,
"setId": 6,
"iconIdx": 2
},
{
"icon": {
"paths": [
"M768 844.8v-256h51.2v281.6c0 28.262-22.938 51.2-51.2 51.2h-716.8c-28.262 0-51.2-22.938-51.2-51.2v-716.8c0-28.262 22.938-51.2 51.2-51.2h716.8c28.262 0 51.2 22.938 51.2 51.2v128h-51.2v-102.4c0-14.157-11.443-25.6-25.6-25.6h-665.6c-14.131 0-25.6 11.443-25.6 25.6v665.6c0 14.157 11.469 25.6 25.6 25.6h665.6c14.157 0 25.6-11.443 25.6-25.6zM1016.678 212.147c9.933 9.907 9.933 26.010 0 35.942l-408.448 408.474c-0.461 0.512-0.614 1.178-1.126 1.69-5.043 5.018-11.674 7.475-18.278 7.373-6.605 0.102-13.235-2.355-18.278-7.373-0.512-0.486-0.666-1.152-1.126-1.69l-254.874-254.874c-9.933-9.933-9.933-26.035 0-35.942 9.907-9.958 26.010-9.958 35.942 0l238.31 238.285 391.91-391.885c9.933-9.958 26.010-9.958 35.968 0z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_CheckBox"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 31,
"id": 7,
"name": "control-checkbox",
"prevSize": 32,
"code": 59654
},
"setIdx": 0,
"setId": 6,
"iconIdx": 3
},
{
"icon": {
"paths": [
"M146.286 633.905c-40.375 0-73.143 32.744-73.143 73.143s32.768 73.143 73.143 73.143c40.375 0 73.143-32.744 73.143-73.143s-32.768-73.143-73.143-73.143zM146.286 731.429c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381zM146.286 828.952c-40.375 0-73.143 32.744-73.143 73.143s32.768 73.143 73.143 73.143c40.375 0 73.143-32.744 73.143-73.143s-32.768-73.143-73.143-73.143zM146.286 926.476c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381zM950.857 24.381h-877.714c-26.917 0-48.762 21.845-48.762 48.762v268.19c0 26.917 21.845 48.762 48.762 48.762h877.714c26.917 0 48.762-21.845 48.762-48.762v-268.19c0-26.917-21.845-48.762-48.762-48.762zM585.143 341.333h-487.619c-13.483 0-24.381-10.898-24.381-24.381v-219.429c0-13.483 10.898-24.381 24.381-24.381h487.619v268.19zM950.857 316.952c0 13.483-10.898 24.381-24.381 24.381h-292.571v-268.19h292.571c13.483 0 24.381 10.898 24.381 24.381v219.429zM926.476 487.619c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-609.524c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381h609.524zM926.476 682.667c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-609.524c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381h609.524zM926.476 877.714c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-609.524c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381h609.524zM146.286 438.857c-40.375 0-73.143 32.768-73.143 73.143s32.768 73.143 73.143 73.143c40.375 0 73.143-32.768 73.143-73.143s-32.768-73.143-73.143-73.143zM146.286 536.381c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381zM707.048 170.667c6.729 0 170.667 0.366 170.667 0 0 6.705-84.846 97.524-85.333 97.524-0.414 0.512-85.699-97.182-85.333-97.524z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Dropdown"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 32,
"id": 6,
"name": "control-dropdown",
"prevSize": 32,
"code": 59655
},
"setIdx": 0,
"setId": 6,
"iconIdx": 4
},
{
"icon": {
"paths": [
"M298.374 341.285c-0.585-0.098-1.122-0.098-1.707-0.146-0.561 0.049-1.097 0.049-1.682 0.146-7.851 0.049-15.579 4.267-19.846 12.434l-126.22 291.669c-6.363 12.142-2.755 27.575 8.070 34.45s24.747 2.609 31.086-9.533l26.307-60.806c0.049 0 0.073 0.024 0.098 0.024h162.28c0.488 0 0.853-0.219 1.317-0.244l26.161 61.026c6.315 12.142 20.139 16.408 30.866 9.533s14.287-22.309 7.997-34.45l-125.050-291.669c-4.242-8.168-11.874-12.361-19.675-12.434zM235.496 560.762l61.172-141.385 60.611 141.385zM950.857 243.81c26.917 0 48.762 21.845 48.762 48.762v438.857c0 26.917-21.845 48.762-48.762 48.762h-219.429v-48.762h195.048c13.483 0 24.381-10.898 24.381-24.381v-390.095c0-13.483-10.898-24.381-24.381-24.381h-195.048v-48.762h219.429zM585.143 780.19h-512c-26.917 0-48.762-21.845-48.762-48.762v-438.857c0-26.917 21.845-48.762 48.762-48.762h512v48.762h-487.619c-13.458 0-24.381 10.898-24.381 24.381v390.095c0 13.483 10.923 24.381 24.381 24.381h487.619zM804.571 926.476c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-292.571c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381h121.905v-828.952h-121.905c-13.483 0-24.381-10.898-24.381-24.381s10.898-24.381 24.381-24.381h292.571c13.483 0 24.381 10.898 24.381 24.381s-10.898 24.381-24.381 24.381h-121.905v828.952h121.905z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Input"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 33,
"id": 5,
"name": "control-input",
"prevSize": 32,
"code": 59656
},
"setIdx": 0,
"setId": 6,
"iconIdx": 5
},
{
"icon": {
"paths": [
"M268.19 658.286c13.458 0 24.381 10.923 24.381 24.381s-10.923 24.381-24.381 24.381h-195.048c-13.458 0-24.381-10.923-24.381-24.381s10.923-24.381 24.381-24.381h73.143v-292.571h-48.762c-13.458 0-24.381-10.923-24.381-24.381s10.923-24.381 24.381-24.381h73.143c13.458 0 24.381 10.923 24.381 24.381v316.952h73.143zM609.524 316.952c13.458 0 24.381 10.923 24.381 24.381v170.667c0 13.458-10.923 24.381-24.381 24.381h-170.667v121.905h170.667c13.458 0 24.381 10.923 24.381 24.381s-10.923 24.381-24.381 24.381h-195.048c-13.458 0-24.381-10.923-24.381-24.381v-170.667c0-13.458 10.923-24.381 24.381-24.381h170.667v-121.905h-170.667c-13.458 0-24.381-10.923-24.381-24.381s10.923-24.381 24.381-24.381h195.048zM950.857 316.952c13.458 0 24.381 10.923 24.381 24.381v341.333c0 13.458-10.923 24.381-24.381 24.381h-195.048c-13.458 0-24.381-10.923-24.381-24.381s10.923-24.381 24.381-24.381h170.667v-121.905h-170.667c-13.458 0-24.381-10.923-24.381-24.381s10.923-24.381 24.381-24.381h170.667v-121.905h-170.667c-13.458 0-24.381-10.923-24.381-24.381s10.923-24.381 24.381-24.381h195.048z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Number"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 34,
"id": 4,
"name": "type-number",
"prevSize": 32,
"code": 59657
},
"setIdx": 0,
"setId": 6,
"iconIdx": 6
},
{
"icon": {
"paths": [
"M97.524 585.143h48.762v97.524h-48.762zM97.524 292.571h48.762v-73.143h73.143v-195.048h-195.048v195.048h73.143zM73.143 170.667v-97.524h97.524v97.524zM146.286 487.619h-48.762v-97.524h48.762zM804.571 24.381v195.048h195.048v-195.048zM950.857 170.667h-97.524v-97.524h97.524zM780.19 146.286h-97.524v-48.762h97.524zM585.143 146.286h-97.524v-48.762h97.524zM390.095 146.286h-97.524v-48.762h97.524zM390.095 877.714h97.524v48.762h-97.524zM585.143 877.714h97.524v48.762h-97.524zM772.974 298.277c9.874 9.923 9.874 25.966 0 35.84-9.923 9.874-25.941 9.874-35.84 0l-65.926-65.926h-134.827v463.238h48.494c6.827-0.293 13.726 1.999 18.944 7.217l22.869 22.869c9.874 9.923 9.874 25.941 0 35.84-9.899 9.874-25.941 9.874-35.84 0l-17.164-17.164h-123.611l-16.433 16.457c-9.801 9.826-25.771 9.826-35.596 0s-9.826-25.771 0-35.596l22.455-22.455c5.169-5.193 12.044-7.461 18.846-7.168h48.274v-463.238h-135.095l-65.195 65.219c-9.801 9.826-25.771 9.826-35.596 0s-9.826-25.795 0-35.596l71.217-71.192c5.169-5.193 12.044-7.485 18.822-7.192h340.626c6.827-0.293 13.726 1.999 18.944 7.217l71.631 71.631zM877.714 682.667h48.762v97.524h-48.762zM219.429 804.571h-73.143v-24.381h-48.762v24.381h-73.143v195.048h195.048v-73.143h73.143v-48.762h-73.143zM170.667 950.857h-97.524v-97.524h97.524zM926.476 390.095h-48.762v-97.524h48.762zM877.714 487.619h48.762v97.524h-48.762zM804.571 877.714h-24.381v48.762h24.381v73.143h195.048v-195.048h-195.048zM853.333 853.333h97.524v97.524h-97.524z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Text Area"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 39,
"id": 2,
"name": "control-textarea",
"prevSize": 32,
"code": 59658
},
"setIdx": 0,
"setId": 6,
"iconIdx": 8
},
{
"icon": {
"paths": [
"M853.333 902.095h-682.667c-13.458 0-24.381 10.898-24.381 24.381s10.923 24.381 24.381 24.381h682.667c13.483 0 24.381-10.898 24.381-24.381s-10.898-24.381-24.381-24.381zM209.822 802.621c12.386 5.291 26.722-0.439 32.012-12.8l119.052-277.821h302.226l119.052 277.821c3.974 9.216 12.922 14.75 22.406 14.75 3.243 0 6.485-0.61 9.63-1.95 12.386-5.339 18.091-19.675 12.8-32.037l-125.342-292.352c-0.049-0.049-0.049-0.146-0.098-0.195l-167.131-390.095c-3.852-8.997-12.678-14.799-22.43-14.799s-18.578 5.803-22.43 14.775l-167.156 390.095c-0.049 0.049-0.049 0.146-0.098 0.195l-125.318 292.352c-5.266 12.386 0.439 26.722 12.824 32.061zM512 159.403l130.194 303.835h-260.389l130.194-303.835z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Text Icon"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 37,
"id": 1,
"name": "type-string",
"prevSize": 32,
"code": 59659
},
"setIdx": 0,
"setId": 6,
"iconIdx": 9
},
{
"icon": {
"paths": [
"M682.667 48.762h-341.333c-121.198 0-219.429 98.231-219.429 219.429s98.231 219.429 219.429 219.429h341.333c121.198 0 219.429-98.231 219.429-219.429s-98.231-219.429-219.429-219.429zM682.667 438.857h-341.333c-94.257 0-170.667-76.41-170.667-170.667s76.41-170.667 170.667-170.667h341.333c94.257 0 170.667 76.41 170.667 170.667s-76.41 170.667-170.667 170.667z",
"M341.333 146.286c-67.34 0-121.905 54.565-121.905 121.905s54.565 121.905 121.905 121.905c67.34 0 121.905-54.565 121.905-121.905s-54.565-121.905-121.905-121.905zM341.333 341.333c-40.399 0-73.143-32.744-73.143-73.143s32.744-73.143 73.143-73.143c40.399 0 73.143 32.744 73.143 73.143s-32.744 73.143-73.143 73.143z",
"M121.905 755.81c0 121.198 98.231 219.429 219.429 219.429h341.333c121.198 0 219.429-98.231 219.429-219.429s-98.231-219.429-219.429-219.429h-341.333c-121.198 0-219.429 98.231-219.429 219.429zM170.667 755.81c0-94.257 76.41-170.667 170.667-170.667h341.333c94.257 0 170.667 76.41 170.667 170.667s-76.41 170.667-170.667 170.667h-341.333c-94.257 0-170.667-76.41-170.667-170.667z",
"M560.762 755.81c0 67.34 54.565 121.905 121.905 121.905s121.905-54.565 121.905-121.905c0-67.34-54.565-121.905-121.905-121.905s-121.905 54.565-121.905 121.905zM609.524 755.81c0-40.399 32.744-73.143 73.143-73.143s73.143 32.744 73.143 73.143c0 40.399-32.744 73.143-73.143 73.143s-73.143-32.744-73.143-73.143z"
],
"attrs": [
{
"fill": "rgb(67, 140, 239)"
},
{
"fill": "rgb(67, 140, 239)"
},
{
"fill": "rgb(67, 140, 239)"
},
{
"fill": "rgb(67, 140, 239)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Icon_Toggle"
]
},
"attrs": [
{
"fill": "rgb(67, 140, 239)"
},
{
"fill": "rgb(67, 140, 239)"
},
{
"fill": "rgb(67, 140, 239)"
},
{
"fill": "rgb(67, 140, 239)"
}
],
"properties": {
"order": 38,
"id": 0,
"name": "control-toggle",
"prevSize": 32,
"code": 59660
},
"setIdx": 0,
"setId": 6,
"iconIdx": 10
},
{
"icon": {
"paths": [
"M512.34 20.48c-0.174 0.065-226.41 96.5-283.902 294.74-5.545 19.035 40.453 10.673 38.399 31.6-2.517 25.409-55.264 35.821-48.385 108.78 7.001 74.289 74.617 149.342 84.791 194.72v31.78c-0.615 9.802-5.639 36.405-22.285 49.4-9.13 7.105-21.442 9.661-37.671 7.78-22.528-2.612-31.493-16.604-35.078-27.9-5.881-18.616-0.409-40.331 12.793-50.52 13.271-10.243 15.084-28.513 4.029-40.82-11.055-12.296-30.785-13.965-44.056-3.7-32.168 24.839-45.65 70.615-32.785 111.34 12.146 38.328 44.789 64.147 87.363 69.080 6.067 0.699 11.848 1.040 17.335 1.040 32.945 0 55.27-11.669 68.785-22.32 40.671-32.105 43.867-85.623 44.099-91.62 0.011-0.355 0.022-0.705 0.022-1.060v-24.36h0.129v-1.64c0-14.177 12.394-25.66 27.707-25.66 14.869 0 26.889 10.843 27.578 24.46v232.2c-0.255 3.343-3.155 34.297-22.157 49.28-9.118 7.201-21.512 9.802-37.799 7.9-22.54-2.612-31.526-16.605-35.099-27.88-5.893-18.627-0.387-40.341 12.814-50.52 13.271-10.254 15.062-28.523 4.007-40.84-11.044-12.274-30.764-13.945-44.035-3.68-32.191 24.828-45.65 70.615-32.785 111.34 12.122 38.328 44.789 64.136 87.363 69.080 6.067 0.699 11.848 1.040 17.335 1.040 32.945 0 55.262-11.669 68.742-22.32 40.683-32.105 43.879-85.623 44.099-91.62 0.024-0.376 0.042-0.696 0.042-1.040v-259l0.129-0.060v-1.14c0-14.456 12.65-26.18 28.264-26.18 15.288 0 27.657 11.292 28.135 25.36v261.020c0 0.355-0.002 0.675 0.022 1.040 0.232 5.987 3.438 59.515 44.121 91.62 13.504 10.652 35.819 22.32 68.764 22.32 5.499 0 11.258-0.341 17.314-1.040 42.562-4.944 75.24-30.763 87.363-69.080 12.876-40.725-0.584-86.501-32.764-111.34-13.294-10.265-33.013-8.584-44.056 3.68-11.055 12.328-9.264 30.586 4.007 40.84 13.201 10.179 18.697 31.893 12.793 50.52-3.561 11.275-12.55 25.268-35.078 27.88-16.217 1.892-28.531-0.675-37.649-7.78-16.716-13.038-21.715-39.783-22.307-49.36v-231.8c0.445-13.816 12.612-24.9 27.642-24.9 15.313 0 27.707 11.472 27.707 25.66v1.64h0.085v24.36c0 0.365-0.002 0.716 0.022 1.060 0.22 5.987 3.438 59.515 44.121 91.62 13.503 10.651 35.818 22.32 68.763 22.32 5.487 0 11.259-0.332 17.314-1.020 42.562-4.933 75.24-30.783 87.363-69.1 12.876-40.725-0.606-86.49-32.785-111.34-13.294-10.254-33.003-8.576-44.035 3.72-11.067 12.307-9.285 30.557 3.986 40.8 13.201 10.189 18.719 31.904 12.814 50.52-3.561 11.296-12.571 25.299-35.099 27.9-16.194 1.892-28.51-0.686-37.628-7.78-16.716-13.048-21.727-39.785-22.307-49.34v-24.24c6.634-62.066 78.084-123.637 85.499-202.32 6.844-72.959-45.943-83.371-48.449-108.78-2.065-20.927 43.943-12.565 38.421-31.6-57.503-198.24-283.718-294.675-283.88-294.74z"
],
"attrs": [
{
"fill": "rgb(0, 0, 0)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"logo"
]
},
"attrs": [
{
"fill": "rgb(0, 0, 0)"
}
],
"properties": {
"order": 3,
"id": 0,
"name": "logo",
"prevSize": 32,
"code": 59648
},
"setIdx": 5,
"setId": 1,
"iconIdx": 12
},
{ {
"icon": { "icon": {
"paths": [ "paths": [
@ -26,7 +377,7 @@
"code": 59651, "code": 59651,
"name": "dots" "name": "dots"
}, },
"setIdx": 0, "setIdx": 2,
"setId": 4, "setId": 4,
"iconIdx": 0 "iconIdx": 0
}, },
@ -57,7 +408,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59650 "code": 59650
}, },
"setIdx": 1, "setIdx": 3,
"setId": 3, "setId": 3,
"iconIdx": 0 "iconIdx": 0
}, },
@ -84,7 +435,7 @@
"code": 59573, "code": 59573,
"name": "time" "name": "time"
}, },
"setIdx": 2, "setIdx": 4,
"setId": 2, "setId": 2,
"iconIdx": 4 "iconIdx": 4
}, },
@ -111,7 +462,7 @@
"code": 58829, "code": 58829,
"name": "close" "name": "close"
}, },
"setIdx": 2, "setIdx": 4,
"setId": 2, "setId": 2,
"iconIdx": 157 "iconIdx": 157
}, },
@ -138,7 +489,7 @@
"code": 59389, "code": 59389,
"name": "person" "name": "person"
}, },
"setIdx": 2, "setIdx": 4,
"setId": 2, "setId": 2,
"iconIdx": 557 "iconIdx": 557
}, },
@ -165,7 +516,7 @@
"code": 59574, "code": 59574,
"name": "search" "name": "search"
}, },
"setIdx": 2, "setIdx": 4,
"setId": 2, "setId": 2,
"iconIdx": 655 "iconIdx": 655
}, },
@ -194,7 +545,7 @@
"code": 59649, "code": 59649,
"name": "plus" "name": "plus"
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 11 "iconIdx": 11
}, },
@ -223,7 +574,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59653 "code": 59653
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 0 "iconIdx": 0
}, },
@ -256,7 +607,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59662 "code": 59662
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 1 "iconIdx": 1
}, },
@ -288,7 +639,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59685 "code": 59685
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 2 "iconIdx": 2
}, },
@ -320,7 +671,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59692 "code": 59692
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 3 "iconIdx": 3
}, },
@ -348,7 +699,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59694 "code": 59694
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 4 "iconIdx": 4
}, },
@ -377,7 +728,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59713 "code": 59713
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 5 "iconIdx": 5
}, },
@ -408,7 +759,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59725 "code": 59725
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 6 "iconIdx": 6
}, },
@ -441,7 +792,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59796 "code": 59796
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 7 "iconIdx": 7
}, },
@ -472,7 +823,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59814 "code": 59814
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 8 "iconIdx": 8
}, },
@ -505,7 +856,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59820 "code": 59820
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 9 "iconIdx": 9
}, },
@ -533,42 +884,9 @@
"prevSize": 32, "prevSize": 32,
"code": 59995 "code": 59995
}, },
"setIdx": 3, "setIdx": 5,
"setId": 1, "setId": 1,
"iconIdx": 10 "iconIdx": 10
},
{
"icon": {
"paths": [
"M512.34 20.48c-0.174 0.065-226.41 96.5-283.902 294.74-5.545 19.035 40.453 10.673 38.399 31.6-2.517 25.409-55.264 35.821-48.385 108.78 7.001 74.289 74.617 149.342 84.791 194.72v31.78c-0.615 9.802-5.639 36.405-22.285 49.4-9.13 7.105-21.442 9.661-37.671 7.78-22.528-2.612-31.493-16.604-35.078-27.9-5.881-18.616-0.409-40.331 12.793-50.52 13.271-10.243 15.084-28.513 4.029-40.82-11.055-12.296-30.785-13.965-44.056-3.7-32.168 24.839-45.65 70.615-32.785 111.34 12.146 38.328 44.789 64.147 87.363 69.080 6.067 0.699 11.848 1.040 17.335 1.040 32.945 0 55.27-11.669 68.785-22.32 40.671-32.105 43.867-85.623 44.099-91.62 0.011-0.355 0.022-0.705 0.022-1.060v-24.36h0.129v-1.64c0-14.177 12.394-25.66 27.707-25.66 14.869 0 26.889 10.843 27.578 24.46v232.2c-0.255 3.343-3.155 34.297-22.157 49.28-9.118 7.201-21.512 9.802-37.799 7.9-22.54-2.612-31.526-16.605-35.099-27.88-5.893-18.627-0.387-40.341 12.814-50.52 13.271-10.254 15.062-28.523 4.007-40.84-11.044-12.274-30.764-13.945-44.035-3.68-32.191 24.828-45.65 70.615-32.785 111.34 12.122 38.328 44.789 64.136 87.363 69.080 6.067 0.699 11.848 1.040 17.335 1.040 32.945 0 55.262-11.669 68.742-22.32 40.683-32.105 43.879-85.623 44.099-91.62 0.024-0.376 0.042-0.696 0.042-1.040v-259l0.129-0.060v-1.14c0-14.456 12.65-26.18 28.264-26.18 15.288 0 27.657 11.292 28.135 25.36v261.020c0 0.355-0.002 0.675 0.022 1.040 0.232 5.987 3.438 59.515 44.121 91.62 13.504 10.652 35.819 22.32 68.764 22.32 5.499 0 11.258-0.341 17.314-1.040 42.562-4.944 75.24-30.763 87.363-69.080 12.876-40.725-0.584-86.501-32.764-111.34-13.294-10.265-33.013-8.584-44.056 3.68-11.055 12.328-9.264 30.586 4.007 40.84 13.201 10.179 18.697 31.893 12.793 50.52-3.561 11.275-12.55 25.268-35.078 27.88-16.217 1.892-28.531-0.675-37.649-7.78-16.716-13.038-21.715-39.783-22.307-49.36v-231.8c0.445-13.816 12.612-24.9 27.642-24.9 15.313 0 27.707 11.472 27.707 25.66v1.64h0.085v24.36c0 0.365-0.002 0.716 0.022 1.060 0.22 5.987 3.438 59.515 44.121 91.62 13.503 10.651 35.818 22.32 68.763 22.32 5.487 0 11.259-0.332 17.314-1.020 42.562-4.933 75.24-30.783 87.363-69.1 12.876-40.725-0.606-86.49-32.785-111.34-13.294-10.254-33.003-8.576-44.035 3.72-11.067 12.307-9.285 30.557 3.986 40.8 13.201 10.189 18.719 31.904 12.814 50.52-3.561 11.296-12.571 25.299-35.099 27.9-16.194 1.892-28.51-0.686-37.628-7.78-16.716-13.048-21.727-39.785-22.307-49.34v-24.24c6.634-62.066 78.084-123.637 85.499-202.32 6.844-72.959-45.943-83.371-48.449-108.78-2.065-20.927 43.943-12.565 38.421-31.6-57.503-198.24-283.718-294.675-283.88-294.74z"
],
"attrs": [
{
"fill": "rgb(0, 0, 0)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"logo"
]
},
"attrs": [
{
"fill": "rgb(0, 0, 0)"
}
],
"properties": {
"order": 3,
"id": 0,
"name": "logo",
"prevSize": 32,
"code": 59648
},
"setIdx": 3,
"setId": 1,
"iconIdx": 12
} }
], ],
"height": 1024, "height": 1024,

43
src/Squidex/app/theme/icomoon/style.css

@ -1,10 +1,10 @@
@font-face { @font-face {
font-family: 'icomoon'; font-family: 'icomoon';
src: url('fonts/icomoon.eot?sp5644'); src: url('fonts/icomoon.eot?pmbjza');
src: url('fonts/icomoon.eot?sp5644#iefix') format('embedded-opentype'), src: url('fonts/icomoon.eot?pmbjza#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?sp5644') format('truetype'), url('fonts/icomoon.ttf?pmbjza') format('truetype'),
url('fonts/icomoon.woff?sp5644') format('woff'), url('fonts/icomoon.woff?pmbjza') format('woff'),
url('fonts/icomoon.svg?sp5644#icomoon') format('svg'); url('fonts/icomoon.svg?pmbjza#icomoon') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
@ -24,6 +24,36 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-control-radio:before {
content: "\e90d";
}
.icon-type-boolean:before {
content: "\e904";
}
.icon-control-checkbox:before {
content: "\e906";
}
.icon-control-dropdown:before {
content: "\e907";
}
.icon-control-input:before {
content: "\e908";
}
.icon-type-number:before {
content: "\e909";
}
.icon-control-textarea:before {
content: "\e90a";
}
.icon-type-string:before {
content: "\e90b";
}
.icon-control-toggle:before {
content: "\e90c";
}
.icon-logo:before {
content: "\e900";
}
.icon-dots:before { .icon-dots:before {
content: "\e903"; content: "\e903";
} }
@ -78,7 +108,4 @@
.icon-filter:before { .icon-filter:before {
content: "\ea5b"; content: "\ea5b";
} }
.icon-logo:before {
content: "\e900";
}

1
src/Squidex/tslint.json

@ -50,6 +50,7 @@
"no-trailing-whitespace": true, "no-trailing-whitespace": true,
"no-unused-expression": true, "no-unused-expression": true,
"no-unused-variable": true,
"no-use-before-declare": true, "no-use-before-declare": true,
"no-var-keyword": true, "no-var-keyword": true,
"object-literal-sort-keys": false, "object-literal-sort-keys": false,

28
tests/Squidex.Core.Tests/Schemas/NumberFieldPropertiesTests.cs

@ -106,6 +106,34 @@ namespace Squidex.Core.Schemas
}); });
} }
[Fact]
public void Should_add_error_if_radio_button_has_no_allowed_values()
{
var sut = new NumberFieldProperties { Editor = NumberFieldEditor.Radio };
sut.Validate(errors);
errors.ShouldBeEquivalentTo(
new List<ValidationError>
{
new ValidationError("Radio buttons or dropdown list need allowed values", "AllowedValues")
});
}
[Fact]
public void Should_add_error_if_editor_is_not_valid()
{
var sut = new NumberFieldProperties { Editor = (NumberFieldEditor)123 };
sut.Validate(errors);
errors.ShouldBeEquivalentTo(
new List<ValidationError>
{
new ValidationError("Editor ist not a valid value", "Editor")
});
}
[Fact] [Fact]
public void Should_set_or_freeze_sut() public void Should_set_or_freeze_sut()
{ {

28
tests/Squidex.Core.Tests/Schemas/StringFieldPropertiesTests.cs

@ -34,6 +34,34 @@ namespace Squidex.Core.Schemas
}); });
} }
[Fact]
public void Should_add_error_if_radio_button_has_no_allowed_values()
{
var sut = new StringFieldProperties { Editor = StringFieldEditor.Radio };
sut.Validate(errors);
errors.ShouldBeEquivalentTo(
new List<ValidationError>
{
new ValidationError("Radio buttons or dropdown list need allowed values", "AllowedValues")
});
}
[Fact]
public void Should_add_error_if_editor_is_not_valid()
{
var sut = new StringFieldProperties { Editor = (StringFieldEditor)123 };
sut.Validate(errors);
errors.ShouldBeEquivalentTo(
new List<ValidationError>
{
new ValidationError("Editor ist not a valid value", "Editor")
});
}
[Fact] [Fact]
public void Should_add_error_if_pattern_is_not_valid_regex() public void Should_add_error_if_pattern_is_not_valid_regex()
{ {

1
tests/Squidex.Core.Tests/project.json

@ -28,6 +28,7 @@
"defaultNamespace": "Squidex.Core" "defaultNamespace": "Squidex.Core"
}, },
"tools": { "tools": {
"Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final"
}, },
"version": "1.0.0-*" "version": "1.0.0-*"
} }
Loading…
Cancel
Save