Browse Source

Merge branch 'master' into medium

pull/306/head
Sebastian 8 years ago
parent
commit
118b14c1f6
  1. 13
      README.md
  2. 3
      src/Squidex.Domain.Apps.Entities/Contents/Guards/GuardContent.cs
  3. 2
      src/Squidex.Domain.Apps.Entities/Contents/SingletonCommandMiddleware.cs
  4. 4
      src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts
  5. 7
      src/Squidex/app/features/apps/pages/apps-page.component.ts
  6. 4
      src/Squidex/app/features/apps/pages/onboarding-dialog.component.html
  7. 2
      src/Squidex/app/features/content/pages/content/content-page.component.html
  8. 4
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  9. 4
      src/Squidex/app/features/content/pages/contents/contents-page.component.ts
  10. 4
      src/Squidex/app/features/content/pages/contents/search-form.component.ts
  11. 4
      src/Squidex/app/features/content/shared/assets-editor.component.html
  12. 6
      src/Squidex/app/features/content/shared/assets-editor.component.ts
  13. 2
      src/Squidex/app/features/content/shared/content-item.component.html
  14. 4
      src/Squidex/app/features/content/shared/content-item.component.ts
  15. 4
      src/Squidex/app/features/content/shared/contents-selector.component.ts
  16. 4
      src/Squidex/app/features/content/shared/due-time-selector.component.ts
  17. 4
      src/Squidex/app/features/content/shared/references-editor.component.html
  18. 13
      src/Squidex/app/features/content/shared/references-editor.component.ts
  19. 4
      src/Squidex/app/features/dashboard/pages/dashboard-page.component.html
  20. 2
      src/Squidex/app/features/dashboard/pages/dashboard-page.component.scss
  21. 6
      src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts
  22. 4
      src/Squidex/app/features/rules/pages/rules/rules-page.component.ts
  23. 2
      src/Squidex/app/features/schemas/pages/schema/field.component.html
  24. 7
      src/Squidex/app/features/schemas/pages/schema/field.component.ts
  25. 13
      src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts
  26. 4
      src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts
  27. 4
      src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts
  28. 4
      src/Squidex/app/features/settings/pages/clients/client.component.ts
  29. 4
      src/Squidex/app/framework/angular/forms/dropdown.component.ts
  30. 4
      src/Squidex/app/framework/angular/modals/dialog-renderer.component.ts
  31. 59
      src/Squidex/app/framework/angular/modals/modal-view.directive.ts
  32. 4
      src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts
  33. 4
      src/Squidex/app/framework/angular/modals/tooltip.component.ts
  34. 100
      src/Squidex/app/framework/utils/modal-view.spec.ts
  35. 77
      src/Squidex/app/framework/utils/modal-view.ts
  36. 4
      src/Squidex/app/shared/components/asset.component.ts
  37. 2
      src/Squidex/app/shared/components/language-selector.component.html
  38. 4
      src/Squidex/app/shared/components/language-selector.component.ts
  39. 2
      src/Squidex/app/shared/components/markdown-editor.component.html
  40. 8
      src/Squidex/app/shared/components/markdown-editor.component.ts
  41. 2
      src/Squidex/app/shared/components/rich-editor.component.html
  42. 8
      src/Squidex/app/shared/components/rich-editor.component.ts
  43. 8
      src/Squidex/app/shared/guards/schema-must-exist-published.guard.spec.ts
  44. 6
      src/Squidex/app/shared/guards/schema-must-exist-published.guard.ts
  45. 2
      src/Squidex/app/shell/pages/internal/apps-menu.component.html
  46. 7
      src/Squidex/app/shell/pages/internal/apps-menu.component.ts
  47. 14
      src/Squidex/app/shell/pages/internal/internal-area.component.html
  48. 51
      src/Squidex/app/shell/pages/internal/internal-area.component.scss
  49. 2
      src/Squidex/app/shell/pages/internal/profile-menu.component.html
  50. 4
      src/Squidex/app/shell/pages/internal/profile-menu.component.ts
  51. 8
      src/Squidex/app/theme/icomoon/demo-files/demo.css
  52. 518
      src/Squidex/app/theme/icomoon/demo.html
  53. BIN
      src/Squidex/app/theme/icomoon/fonts/icomoon.eot
  54. 1
      src/Squidex/app/theme/icomoon/fonts/icomoon.svg
  55. BIN
      src/Squidex/app/theme/icomoon/fonts/icomoon.ttf
  56. BIN
      src/Squidex/app/theme/icomoon/fonts/icomoon.woff
  57. 327
      src/Squidex/app/theme/icomoon/selection.json
  58. 67
      src/Squidex/app/theme/icomoon/style.css
  59. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Contents/Guard/GuardContentTests.cs

13
README.md

@ -4,21 +4,24 @@
Squidex is an open source headless CMS and content management hub. In contrast to a traditional CMS Squidex provides a rich API with OData filter and Swagger definitions. It is up to you to build your UI on top of it. It can be website, a native app or just another server. We build it with ASP.NET Core and CQRS and is tested for Windows and Linux on modern browsers.
[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=square)](https://gitter.im/squidex-cms/Lobby) [![Slack](https://img.shields.io/badge/chat-on_slack-E01765.svg?style=square)](https://squidex-slack.herokuapp.com/) [![Build Status](http://build.squidex.io/api/badges/Squidex/squidex/status.svg)](http://build.squidex.io/Squidex/squidex) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FSquidex%2Fsquidex.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FSquidex%2Fsquidex?ref=badge_shield)
[![Discourse topics](https://img.shields.io/discourse/https/support.squidex.io/topics.svg)](https://support.squidex.io) [![Build Status](http://build.squidex.io/api/badges/Squidex/squidex/status.svg)](http://build.squidex.io/Squidex/squidex) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FSquidex%2Fsquidex.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FSquidex%2Fsquidex?ref=badge_shield)
Read the docs at [https://docs.squidex.io/](https://docs.squidex.io/) (work in progress) or just check out the code and play around.
## How to make feature requests or report bugs?
Please join our community forum: https://support.squidex.io
## Status
Current Version 1.6. Roadmap: https://trello.com/b/KakM4F3S/squidex-roadmap
Current Version 1.8.0. Roadmap: https://trello.com/b/KakM4F3S/squidex-roadmap
## Prerequisites
* [Visual Studio Code](https://code.visualstudio.com/) or [Visual Studio 2017](https://www.visualstudio.com/vs/visual-studio-2017-rc/)
* [Node.js](https://nodejs.org/en/)
* [.NET Core SDK](https://www.microsoft.com/net/download/core#/current) (Already part of Visual Studio 2017)
* [Node.js](https://nodejs.org/en/) (development only)
* [MongoDB](https://www.mongodb.com/)
* [Redis](https://redis.io/download) (If you want to run Squidex on multiple hosts)
* [.NET Core SDK](https://www.microsoft.com/net/download/core#/current) (Already part of Visual Studio 2017)
## Contributors

3
src/Squidex.Domain.Apps.Entities/Contents/Guards/GuardContent.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands;
@ -25,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Guards
ValidateData(command, e);
});
if (schema.IsSingleton && command.ContentId != Guid.Empty)
if (schema.IsSingleton && command.ContentId != schema.Id)
{
throw new DomainException("Singleton content cannot be created.");
}

2
src/Squidex.Domain.Apps.Entities/Contents/SingletonCommandMiddleware.cs

@ -30,7 +30,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
var data = new NamedContentData();
var contentId = Guid.Empty;
var contentId = schemaId.Id;
var content = new CreateContent { Data = data, ContentId = contentId, SchemaId = schemaId, Publish = true };
SimpleMapper.Map(context.Command, content);

4
src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts

@ -9,7 +9,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription, timer } from 'rxjs';
import { onErrorResumeNext, switchMap } from 'rxjs/operators';
import { ModalView } from '@app/shared';
import { DialogModel } from '@app/shared';
import { EventConsumerDto } from './../../services/event-consumers.service';
import { EventConsumersState } from './../../state/event-consumers.state';
@ -22,7 +22,7 @@ import { EventConsumersState } from './../../state/event-consumers.state';
export class EventConsumersPageComponent implements OnDestroy, OnInit {
private timerSubscription: Subscription;
public eventConsumerErrorDialog = new ModalView();
public eventConsumerErrorDialog = new DialogModel();
public eventConsumerError = '';
constructor(

7
src/Squidex/app/features/apps/pages/apps-page.component.ts

@ -11,7 +11,8 @@ import { take } from 'rxjs/operators';
import {
AppsState,
AuthService,
ModalView,
DialogModel,
ModalModel,
OnboardingService
} from '@app/shared';
@ -21,10 +22,10 @@ import {
templateUrl: './apps-page.component.html'
})
export class AppsPageComponent implements OnInit {
public addAppDialog = new ModalView();
public addAppDialog = new DialogModel();
public addAppTemplate = '';
public onboardingModal = new ModalView();
public onboardingModal = new ModalModel();
constructor(
public readonly appsState: AppsState,

4
src/Squidex/app/features/apps/pages/onboarding-dialog.component.html

@ -132,8 +132,8 @@
</p>
<div>
<a class="btn btn-success" href="https://squidex-slack.herokuapp.com/" target="_blank">
Join us on Slack
<a class="btn btn-success" href="https://support.squidex.io" target="_blank">
Join our Forum
</a> &nbsp;
<a class="btn btn-success" href="https://github.com/squidex/squidex" target="_blank">

2
src/Squidex/app/features/content/pages/content/content-page.component.html

@ -44,7 +44,7 @@
</button>
<ng-container *ngIf="content.isPending || !schema.isSingleton">
<div class="dropdown-menu" *sqxModalView="dropdown" [sqxModalTarget]="optionsButton" @fade>
<div class="dropdown-menu" *sqxModalView="dropdown;closeAlways:true" [sqxModalTarget]="optionsButton" @fade>
<ng-container *ngIf="content.isPending">
<a class="dropdown-item" (click)="discardChanges()">
Discard changes

4
src/Squidex/app/features/content/pages/content/content-page.component.ts

@ -24,7 +24,7 @@ import {
ImmutableArray,
LanguagesState,
MessageBus,
ModalView,
ModalModel,
SchemaDetailsDto,
SchemasState,
Version
@ -52,7 +52,7 @@ export class ContentPageComponent implements CanComponentDeactivate, OnDestroy,
public contentVersion: Version | null;
public contentForm: EditContentForm;
public dropdown = new ModalView(false, true);
public dropdown = new ModalModel();
public language: AppLanguageDto;
public languages: ImmutableArray<AppLanguageDto>;

4
src/Squidex/app/features/content/pages/contents/contents-page.component.ts

@ -16,7 +16,7 @@ import {
ContentsState,
ImmutableArray,
LanguagesState,
ModalView,
ModalModel,
SchemaDetailsDto,
SchemasState
} from '@app/shared';
@ -35,7 +35,7 @@ export class ContentsPageComponent implements OnDestroy, OnInit {
public schema: SchemaDetailsDto;
public searchModal = new ModalView();
public searchModal = new ModalModel();
public selectedItems: { [id: string]: boolean; } = {};
public selectionCount = 0;

4
src/Squidex/app/features/content/pages/contents/search-form.component.ts

@ -8,7 +8,7 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { FormBuilder, FormControl } from '@angular/forms';
import { ModalView } from '@app/shared';
import { ModalModel } from '@app/shared';
@Component({
selector: 'sqx-search-form',
@ -40,7 +40,7 @@ export class SearchFormComponent implements OnChanges {
public contentsFilter = new FormControl();
public searchModal = new ModalView();
public searchModal = new ModalModel();
public searchForm =
this.formBuilder.group({
odataOrderBy: '',

4
src/Squidex/app/features/content/shared/assets-editor.component.html

@ -1,7 +1,7 @@
<div class="assets-container" [class.disabled]="isDisabled">
<div class="row">
<div class="drop-area-container">
<div class="drop-area" (sqxFileDrop)="addFiles($event)" (click)="selectorModal.show()">
<div class="drop-area" (sqxFileDrop)="addFiles($event)" (click)="assetsDialog.show()">
Drop files here to add them.
</div>
</div>
@ -16,6 +16,6 @@
</div>
</div>
<ng-container *sqxModalView="selectorModal;onRoot:true;closeAuto:false">
<ng-container *sqxModalView="assetsDialog;onRoot:true;closeAuto:false">
<sqx-assets-selector (selected)="onAssetsSelected($event)"></sqx-assets-selector>
</ng-container>

6
src/Squidex/app/features/content/shared/assets-editor.component.ts

@ -15,7 +15,7 @@ import {
AssetDto,
AssetsService,
ImmutableArray,
ModalView,
ModalModel,
Types
} from '@app/shared';
@ -35,7 +35,7 @@ export class AssetsEditorComponent implements ControlValueAccessor {
private callChange = (v: any) => { /* NOOP */ };
private callTouched = () => { /* NOOP */ };
public selectorModal = new ModalView();
public assetsDialog = new ModalModel();
public newAssets = ImmutableArray.empty<File>();
public oldAssets = ImmutableArray.empty<AssetDto>();
@ -96,7 +96,7 @@ export class AssetsEditorComponent implements ControlValueAccessor {
this.updateValue();
}
this.selectorModal.hide();
this.assetsDialog.hide();
}
public onAssetRemoving(asset: AssetDto) {

2
src/Squidex/app/features/content/shared/content-item.component.html

@ -86,7 +86,7 @@
<button type="button" class="btn btn-link btn-secondary" (click)="dropdown.toggle(); $event.stopPropagation()" [class.active]="dropdown.isOpen | async" #optionsButton>
<i class="icon-dots"></i>
</button>
<div class="dropdown-menu" *sqxModalView="dropdown" [sqxModalTarget]="optionsButton" @fade>
<div class="dropdown-menu" *sqxModalView="dropdown;closeAlways:true" [sqxModalTarget]="optionsButton" @fade>
<a class="dropdown-item" (click)="publishing.emit(); $event.stopPropagation()" *ngIf="content.status === 'Draft'">
Publish
</a>

4
src/Squidex/app/features/content/shared/content-item.component.ts

@ -14,7 +14,7 @@ import {
fadeAnimation,
FieldFormatter,
fieldInvariant,
ModalView,
ModalModel,
PatchContentForm,
RootFieldDto,
SchemaDetailsDto,
@ -70,7 +70,7 @@ export class ContentItemComponent implements OnChanges {
public patchForm: PatchContentForm;
public dropdown = new ModalView(false, true);
public dropdown = new ModalModel();
public values: any[] = [];

4
src/Squidex/app/features/content/shared/contents-selector.component.ts

@ -12,7 +12,7 @@ import {
ContentDto,
LanguageDto,
ManualContentsState,
ModalView,
ModalModel,
SchemaDetailsDto
} from '@app/shared';
@ -37,7 +37,7 @@ export class ContentsSelectorComponent implements OnInit {
@Output()
public selected = new EventEmitter<ContentDto[]>();
public searchModal = new ModalView();
public searchModal = new ModalModel();
public selectedItems: { [id: string]: ContentDto; } = {};
public selectionCount = 0;

4
src/Squidex/app/features/content/shared/due-time-selector.component.ts

@ -8,7 +8,7 @@
import { Component } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { fadeAnimation, ModalView } from '@app/shared';
import { DialogModel, fadeAnimation } from '@app/shared';
@Component({
selector: 'sqx-due-time-selector',
@ -19,7 +19,7 @@ import { fadeAnimation, ModalView } from '@app/shared';
]
})
export class DueTimeSelectorComponent {
public dueTimeDialog = new ModalView();
public dueTimeDialog = new DialogModel();
public dueTime: string | null = '';
public dueTimeFunction: Subject<string | null>;
public dueTimeAction: string | null = '';

4
src/Squidex/app/features/content/shared/references-editor.component.html

@ -1,7 +1,7 @@
<div class="references-container" [class.disabled]="isDisabled">
<ng-container *ngIf="schema">
<div class="drop-area-container">
<div class="drop-area" (click)="showModal()">
<div class="drop-area" (click)="selectorDialog.show()">
Click here to link a content.
</div>
</div>
@ -26,7 +26,7 @@
</div>
</div>
<ng-container *sqxModalView="isModalVisibible;onRoot:true;closeAuto:false">
<ng-container *sqxModalView="selectorDialog;onRoot:true;closeAuto:false">
<sqx-contents-selector
[language]="language"
[languages]="languages"

13
src/Squidex/app/features/content/shared/references-editor.component.ts

@ -15,6 +15,7 @@ import {
AppsState,
ContentDto,
ContentsService,
DialogModel,
ImmutableArray,
MathHelper,
SchemaDetailsDto,
@ -47,7 +48,7 @@ export class ReferencesEditorComponent implements ControlValueAccessor, OnInit {
@Input()
public languages: ImmutableArray<AppLanguageDto>;
public isModalVisibible = false;
public selectorDialog = new DialogModel();
public schema: SchemaDetailsDto;
@ -110,14 +111,6 @@ export class ReferencesEditorComponent implements ControlValueAccessor, OnInit {
this.callTouched = fn;
}
public showModal() {
this.isModalVisibible = true;
}
public hideModal() {
this.isModalVisibible = false;
}
public select(contents: ContentDto[]) {
for (let content of contents) {
this.contentItems = this.contentItems.push(content);
@ -127,7 +120,7 @@ export class ReferencesEditorComponent implements ControlValueAccessor, OnInit {
this.updateValue();
}
this.hideModal();
this.selectorDialog.hide();
}
public remove(content: ContentDto) {

4
src/Squidex/app/features/dashboard/pages/dashboard-page.component.html

@ -40,13 +40,13 @@
</div>
</a>
<a class="card card-href" (click)="showForum()">
<a class="card card-href" href="https://support.squidex.io" target="_blank">
<div class="card-body">
<div class="card-image">
<img src="/images/dashboard-feedback.png" />
</div>
<h4 class="card-title">Feedback</h4>
<h4 class="card-title">Feedback & Support</h4>
<div class="card-text">
Provide feedback and request features to help us to improve Squidex.

2
src/Squidex/app/features/dashboard/pages/dashboard-page.component.scss

@ -65,7 +65,7 @@
color: $color-title;
font-weight: light;
font-size: 1.2rem;
margin-top: .4rem;
margin-top: 1rem;
}
&-href {

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

@ -20,8 +20,6 @@ import {
UsagesService
} from '@app/shared';
declare var _urq: any;
@Component({
selector: 'sqx-dashboard-page',
styleUrls: ['./dashboard-page.component.scss'],
@ -175,10 +173,6 @@ export class DashboardPageComponent implements OnDestroy, OnInit {
};
}));
}
public showForum() {
_urq.push(['Feedback_Open']);
}
}
function createLabels(dtos: { date: DateTime }[]): string[] {

4
src/Squidex/app/features/rules/pages/rules/rules-page.component.ts

@ -10,7 +10,7 @@ import { onErrorResumeNext } from 'rxjs/operators';
import {
AppsState,
ModalView,
DialogModel,
ruleActions,
RuleDto,
RulesState,
@ -27,7 +27,7 @@ export class RulesPageComponent implements OnInit {
public ruleActions = ruleActions;
public ruleTriggers = ruleTriggers;
public addRuleDialog = new ModalView();
public addRuleDialog = new DialogModel();
public wizardMode = 'Wizard';
public wizardRule: RuleDto | null;

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

@ -121,7 +121,7 @@
</button>
</div>
<ng-container *sqxModalView="addFieldDialog;onRoot:true;closeAuto:false">
<ng-container *sqxModalView="addFieldDialog;onRoot:true;closeAuto:false;closeAlways:true">
<sqx-field-wizard [schema]="schema" [parent]="field"
(completed)="addFieldDialog.hide()">
</sqx-field-wizard>

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

@ -12,10 +12,11 @@ import { onErrorResumeNext } from 'rxjs/operators';
import {
AppPatternDto,
createProperties,
DialogModel,
EditFieldForm,
fadeAnimation,
ImmutableArray,
ModalView,
ModalModel,
NestedFieldDto,
RootFieldDto,
SchemaDetailsDto,
@ -44,14 +45,14 @@ export class FieldComponent implements OnInit {
@Input()
public patterns: ImmutableArray<AppPatternDto>;
public dropdown = new ModalView(false, true);
public dropdown = new ModalModel();
public isEditing = false;
public selectedTab = 0;
public editForm: EditFieldForm;
public addFieldDialog = new ModalView();
public addFieldDialog = new DialogModel();
constructor(
private readonly formBuilder: FormBuilder,

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

@ -14,11 +14,12 @@ import { filter, map, onErrorResumeNext } from 'rxjs/operators';
import {
AppsState,
DialogModel,
fadeAnimation,
FieldDto,
fieldTypes,
MessageBus,
ModalView,
ModalModel,
PatternsState,
SchemaDetailsDto,
SchemasState,
@ -45,14 +46,14 @@ export class SchemaPageComponent implements OnDestroy, OnInit {
public schemaExport: any;
public schema: SchemaDetailsDto;
public exportSchemaDialog = new ModalView();
public exportSchemaDialog = new DialogModel();
public configureScriptsDialog = new ModalView();
public configureScriptsDialog = new DialogModel();
public editOptionsDropdown = new ModalView();
public editSchemaDialog = new ModalView();
public editOptionsDropdown = new ModalModel();
public editSchemaDialog = new DialogModel();
public addFieldDialog = new ModalView();
public addFieldDialog = new DialogModel();
constructor(
public readonly appsState: AppsState,

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

@ -14,7 +14,7 @@ import {
AppPatternDto,
FieldDto,
ImmutableArray,
ModalView,
ModalModel,
StringFieldPropertiesDto
} from '@app/shared';
@ -43,7 +43,7 @@ export class StringValidationComponent implements OnDestroy, OnInit {
public showPatternSuggestions: Observable<boolean>;
public patternName: string;
public patternsModal = new ModalView(false, false);
public patternsModal = new ModalModel();
public ngOnDestroy() {
this.patternSubscription.unsubscribe();

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

@ -14,8 +14,8 @@ import { map, onErrorResumeNext } from 'rxjs/operators';
import {
AppsState,
CreateCategoryForm,
DialogModel,
MessageBus,
ModalView,
SchemaDto,
SchemasState
} from '@app/shared';
@ -30,7 +30,7 @@ import { SchemaCloning } from './../messages';
export class SchemasPageComponent implements OnDestroy, OnInit {
private schemaCloningSubscription: Subscription;
public addSchemaDialog = new ModalView();
public addSchemaDialog = new DialogModel();
public addCategoryForm = new CreateCategoryForm(this.formBuilder);
public schemasFilter = new FormControl();

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

@ -15,8 +15,8 @@ import {
AppClientsService,
AppsState,
ClientsState,
DialogModel,
DialogService,
ModalView,
RenameClientForm,
UpdateAppClientDto
} from '@app/shared';
@ -37,7 +37,7 @@ export class ClientComponent implements OnChanges {
public isRenaming = false;
public token: AccessTokenDto;
public tokenDialog = new ModalView();
public tokenDialog = new DialogModel();
public renameForm = new RenameClientForm(this.formBuilder);

4
src/Squidex/app/framework/angular/forms/dropdown.component.ts

@ -13,7 +13,7 @@ const KEY_ESCAPE = 27;
const KEY_UP = 38;
const KEY_DOWN = 40;
import { ModalView } from '@app/framework/internal';
import { ModalModel } from '@app/framework/internal';
export const SQX_DROPDOWN_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DropdownComponent), multi: true
@ -35,7 +35,7 @@ export class DropdownComponent implements AfterContentInit, ControlValueAccessor
@ContentChildren(TemplateRef)
public templates: QueryList<any>;
public dropdown = new ModalView();
public dropdown = new ModalModel();
public selectedItem: any;
public selectedIndex = -1;

4
src/Squidex/app/framework/angular/modals/dialog-renderer.component.ts

@ -9,10 +9,10 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import {
DialogModel,
DialogRequest,
DialogService,
fadeAnimation,
ModalView,
Notification
} from '@app/framework/internal';
@ -29,7 +29,7 @@ export class DialogRendererComponent implements OnDestroy, OnInit {
private dialogsSubscription: Subscription;
private notificationsSubscription: Subscription;
public dialogView = new ModalView(false, true);
public dialogView = new DialogModel();
public dialogRequest: DialogRequest | null = null;
public notifications: Notification[] = [];

59
src/Squidex/app/framework/angular/modals/modal-view.directive.ts

@ -8,7 +8,11 @@
import { Directive, EmbeddedViewRef, Input, OnChanges, OnDestroy, Renderer2, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core';
import { Subscription } from 'rxjs';
import { ModalView, Types } from '@app/framework/internal';
import {
DialogModel,
ModalModel,
Types
} from '@app/framework/internal';
import { RootViewComponent } from './root-view.component';
@ -21,7 +25,7 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
private renderedView: EmbeddedViewRef<any> | null = null;
@Input('sqxModalView')
public modalView: ModalView | any;
public modalView: DialogModel | ModalModel | any;
@Input('sqxModalViewOnRoot')
public placeOnRoot = false;
@ -29,6 +33,9 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
@Input('sqxModalViewCloseAuto')
public closeAuto = true;
@Input('sqxModalViewCloseAlways')
public closeAlways = false;
constructor(
private readonly templateRef: TemplateRef<any>,
private readonly renderer: Renderer2,
@ -38,9 +45,10 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
}
public ngOnDestroy() {
this.stopListening();
this.unsubscribeToModal();
this.unsubscribeToClick();
if (Types.is(this.modalView, ModalView)) {
if (Types.is(this.modalView, DialogModel) || Types.is(this.modalView, ModalModel)) {
this.modalView.hide();
}
}
@ -50,12 +58,9 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
return;
}
if (this.subscription) {
this.subscription.unsubscribe();
this.subscription = null;
}
this.unsubscribeToModal();
if (Types.is(this.modalView, ModalView)) {
if (Types.is(this.modalView, DialogModel) || Types.is(this.modalView, ModalModel)) {
this.subscription =
this.modalView.isOpen.subscribe(isOpen => {
this.update(isOpen);
@ -71,11 +76,9 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
}
if (isOpen && !this.renderedView) {
if (this.placeOnRoot) {
this.renderedView = this.rootView.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.renderedView = this.viewContainer.createEmbeddedView(this.templateRef);
}
const container = this.getContainer();
this.renderedView = container.createEmbeddedView(this.templateRef);
if (this.renderedView.rootNodes[0].style) {
this.renderer.setStyle(this.renderedView.rootNodes[0], 'display', 'block');
@ -85,18 +88,21 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
this.startListening();
});
} else if (!isOpen && this.renderedView) {
this.renderedView = null;
const container = this.getContainer();
const containerIndex = container.indexOf(this.renderedView);
if (this.placeOnRoot) {
this.rootView.viewContainer.clear();
} else {
this.viewContainer.clear();
}
container.remove(containerIndex);
this.stopListening();
this.renderedView = null;
this.unsubscribeToClick();
}
}
private getContainer() {
return this.placeOnRoot ? this.rootView.viewContainer : this.viewContainer;
}
private startListening() {
if (!this.closeAuto) {
return;
@ -112,7 +118,7 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
return;
}
if (this.modalView.closeAlways) {
if (this.closeAlways) {
this.modalView.hide();
} else {
try {
@ -133,7 +139,14 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
});
}
private stopListening() {
private unsubscribeToModal() {
if (this.subscription) {
this.subscription.unsubscribe();
this.subscription = null;
}
}
private unsubscribeToClick() {
if (this.documentClickListener) {
this.documentClickListener();
this.documentClickListener = null;

4
src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts

@ -9,7 +9,7 @@ import { Component, Input, OnDestroy, OnInit, Renderer2 } from '@angular/core';
import {
fadeAnimation,
ModalView,
ModalModel,
OnboardingService,
Types
} from '@app/framework/internal';
@ -27,7 +27,7 @@ export class OnboardingTooltipComponent implements OnDestroy, OnInit {
private closeTimer: any;
private forMouseDownListener: Function | null;
public tooltipModal = new ModalView();
public tooltipModal = new ModalModel();
@Input()
public for: any;

4
src/Squidex/app/framework/angular/modals/tooltip.component.ts

@ -7,7 +7,7 @@
import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit, Renderer2 } from '@angular/core';
import { ModalView } from './../../utils/modal-view';
import { ModalModel } from './../../utils/modal-view';
import { fadeAnimation } from './../animations';
@ -30,7 +30,7 @@ export class TooltipComponent implements OnDestroy, OnInit {
@Input()
public position = 'topLeft';
public modal = new ModalView(false, false);
public modal = new ModalModel();
constructor(
private readonly renderer: Renderer2

100
src/Squidex/app/framework/utils/modal-view.spec.ts

@ -5,75 +5,115 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { ModalView } from './modal-view';
import { DialogModel, ModalModel, Openable } from './modal-view';
describe('ModalView', () => {
describe('DialogModel', () => {
it('should have default values', () => {
const dialog = new ModalView();
const dialog = new DialogModel();
checkValue(dialog, false);
});
it('should become open after show', () => {
const dialog = new DialogModel();
dialog.show();
expect(dialog.closeAlways).toBeFalsy();
checkValue(dialog, true);
});
it('should have initial true value', () => {
const dialog = new ModalView(true);
it('should become open after toggle', () => {
const dialog = new DialogModel();
dialog.toggle();
checkValue(dialog, true);
});
it('should have initial false value', () => {
const dialog = new ModalView(false);
it('should become closed after hide', () => {
const dialog = new DialogModel().show();
dialog.hide();
checkValue(dialog, false);
});
it('should have close always set by constructor', () => {
const dialog = new ModalView(false, true);
it('should become closed after toggle', () => {
const dialog = new DialogModel().show();
dialog.toggle();
expect(dialog.closeAlways).toBeTruthy();
checkValue(dialog, false);
});
it('should not hide other dialog', () => {
const dialog1 = new DialogModel().show();
const dialog2 = new DialogModel();
dialog2.toggle();
checkValue(dialog1, true);
checkValue(dialog2, true);
});
});
describe('ModalModel', () => {
it('should have default values', () => {
const modal = new ModalModel();
checkValue(modal, false);
});
it('should become open after show', () => {
const dialog = new ModalView(false);
const modal = new ModalModel();
dialog.show();
modal.show();
checkValue(dialog, true);
checkValue(modal, true);
});
it('should become open after toggle', () => {
const dialog = new ModalView(false);
const modal = new ModalModel();
dialog.toggle();
modal.toggle();
checkValue(dialog, true);
checkValue(modal, true);
});
it('should become closed after hide', () => {
const dialog = new ModalView(true);
const modal = new ModalModel().show();
dialog.hide();
modal.hide();
checkValue(dialog, false);
checkValue(modal, false);
});
it('should become closed after toggle', () => {
const dialog = new ModalView(true);
const modal = new ModalModel().show();
dialog.toggle();
modal.toggle();
checkValue(dialog, false);
checkValue(modal, false);
});
function checkValue(dialog: ModalView, expected: boolean) {
let result: boolean;
it('should hide other modal', () => {
const modal1 = new ModalModel().show();
const modal2 = new ModalModel();
dialog.isOpen.subscribe(value => {
result = value;
}).unsubscribe();
modal2.toggle();
expect(result!).toBe(expected);
}
checkValue(modal1, false);
checkValue(modal2, true);
});
});
function checkValue(modal: Openable, expected: boolean) {
let result: boolean;
modal.isOpen.subscribe(value => {
result = value;
}).unsubscribe();
expect(result!).toBe(expected);
}

77
src/Squidex/app/framework/utils/modal-view.ts

@ -7,49 +7,78 @@
import { BehaviorSubject, Observable } from 'rxjs';
export class ModalView {
private readonly isOpen$: BehaviorSubject<boolean>;
private static openView: ModalView | null = null;
export interface Openable {
isOpen: Observable<boolean>;
}
export class DialogModel implements Openable {
private readonly isOpen$ = new BehaviorSubject<boolean>(false);
public get isOpen(): Observable<boolean> {
return this.isOpen$;
}
constructor(isOpen = false,
public readonly closeAlways: boolean = false
) {
this.isOpen$ = new BehaviorSubject(isOpen);
public show(): DialogModel {
this.isOpen$.next(true);
return this;
}
public show() {
if (ModalView.openView !== this && ModalView.openView) {
ModalView.openView.hide();
}
public hide(): DialogModel {
this.isOpen$.next(false);
ModalView.openView = this;
return this;
}
this.isOpen$.next(true);
public toggle(): DialogModel {
this.isOpen$.next(!this.isOpen$.value);
return this;
}
}
export class ModalModel implements Openable {
private readonly isOpen$ = new BehaviorSubject<boolean>(false);
public hide() {
if (ModalView.openView === this) {
ModalView.openView = null;
public get isOpen(): Observable<boolean> {
return this.isOpen$;
}
public show(): ModalModel {
if (!this.isOpen$.value) {
if (openModal && openModal !== this) {
openModal.hide();
}
openModal = this;
this.isOpen$.next(true);
}
this.isOpen$.next(false);
return this;
}
public toggle() {
let isOpenSnapshot = false;
public hide(): ModalModel {
if (this.isOpen$.value) {
if (openModal === this) {
openModal = null;
}
this.isOpen.subscribe(v => {
isOpenSnapshot = v;
}).unsubscribe();
this.isOpen$.next(false);
}
return this;
}
if (isOpenSnapshot) {
public toggle(): ModalModel {
if (this.isOpen$.value) {
this.hide();
} else {
this.show();
}
return this;
}
}
}
let openModal: ModalModel | null = null;

4
src/Squidex/app/shared/components/asset.component.ts

@ -14,9 +14,9 @@ import {
AssetsService,
AuthService,
DateTime,
DialogModel,
DialogService,
fadeAnimation,
ModalView,
RenameAssetForm,
Types,
UpdateAssetDto,
@ -68,7 +68,7 @@ export class AssetComponent implements OnInit {
@Output()
public failed = new EventEmitter();
public renameDialog = new ModalView();
public renameDialog = new DialogModel();
public renameForm = new RenameAssetForm(this.formBuilder);
public progress = 0;

2
src/Squidex/app/shared/components/language-selector.component.html

@ -8,7 +8,7 @@
<button type="button" class="btn btn-secondary dropdown-toggle" [attr.title]="selectedLanguage.englishName" (click)="dropdown.toggle(); $event.stopPropagation()" #button tabindex="-1">
{{selectedLanguage.iso2Code}}
</button>
<div class="dropdown-menu" *sqxModalView="dropdown" [sqxModalTarget]="button" @fade>
<div class="dropdown-menu" *sqxModalView="dropdown;closeAlways:true" [sqxModalTarget]="button" @fade>
<div class="dropdown-item" *ngFor="let language of languages" [class.active]="language == selectedLanguage" (click)="selectLanguage(language)">
<strong class="iso-code">{{language.iso2Code}}</strong> &nbsp; &nbsp; ({{language.englishName}})
</div>

4
src/Squidex/app/shared/components/language-selector.component.ts

@ -7,7 +7,7 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import { fadeAnimation, ModalView } from '@app/shared/internal';
import { fadeAnimation, ModalModel } from '@app/shared/internal';
export interface Language { iso2Code: string; englishName: string; isMasterLanguage: true; }
@ -20,7 +20,7 @@ export interface Language { iso2Code: string; englishName: string; isMasterLangu
]
})
export class LanguageSelectorComponent implements OnChanges, OnInit {
public dropdown = new ModalView(false, true);
public dropdown = new ModalModel();
@Input()
public size: string;

2
src/Squidex/app/shared/components/markdown-editor.component.html

@ -8,6 +8,6 @@
</div>
</div>
<ng-container *sqxModalView="selectorModal;onRoot:true;closeAuto:false">
<ng-container *sqxModalView="assetsDialog;onRoot:true;closeAuto:false">
<sqx-assets-selector (selected)="onAssetsSelected($event)"></sqx-assets-selector>
</ng-container>

8
src/Squidex/app/shared/components/markdown-editor.component.ts

@ -10,7 +10,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import {
AssetDto,
ModalView,
DialogModel,
ResourceLoaderService,
Types
} from '@app/shared/internal';
@ -34,7 +34,7 @@ export class MarkdownEditorComponent implements ControlValueAccessor, AfterViewI
private value: string;
private isDisabled = false;
public selectorModal = new ModalView();
public assetsDialog = new DialogModel();
@ViewChild('editor')
public editor: ElementRef;
@ -79,7 +79,7 @@ export class MarkdownEditorComponent implements ControlValueAccessor, AfterViewI
}
private showSelector = () => {
this.selectorModal.show();
this.assetsDialog.show();
}
public ngAfterViewInit() {
@ -206,6 +206,6 @@ export class MarkdownEditorComponent implements ControlValueAccessor, AfterViewI
this.simplemde.codemirror.replaceSelection(content);
}
this.selectorModal.hide();
this.assetsDialog.hide();
}
}

2
src/Squidex/app/shared/components/rich-editor.component.html

@ -6,6 +6,6 @@
</div>
</div>
<ng-container *sqxModalView="selectorModal;onRoot:true;closeAuto:false">
<ng-container *sqxModalView="assetsDialog;onRoot:true;closeAuto:false">
<sqx-assets-selector (selected)="onAssetsSelected($event)"></sqx-assets-selector>
</ng-container>

8
src/Squidex/app/shared/components/rich-editor.component.ts

@ -10,7 +10,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import {
AssetDto,
ModalView,
DialogModel,
ResourceLoaderService,
Types
} from '@app/shared/internal';
@ -35,7 +35,7 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit,
private value: string;
private isDisabled = false;
public selectorModal = new ModalView();
public assetsDialog = new DialogModel();
@ViewChild('editor')
public editor: ElementRef;
@ -63,7 +63,7 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit,
}
private showSelector = () => {
this.selectorModal.show();
this.assetsDialog.show();
}
private getEditorOptions() {
@ -147,6 +147,6 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit,
this.tinyEditor.execCommand('mceInsertContent', false, content);
}
this.selectorModal.hide();
this.assetsDialog.hide();
}
}

8
src/Squidex/app/shared/guards/schema-must-exist-published.guard.spec.ts

@ -9,8 +9,6 @@ import { Router, RouterStateSnapshot } from '@angular/router';
import { of } from 'rxjs';
import { IMock, Mock, Times } from 'typemoq';
import { MathHelper } from '@app/framework';
import { SchemaDetailsDto } from './../services/schemas.service';
import { SchemasState } from './../state/schemas.state';
import { SchemaMustExistPublishedGuard } from './schema-must-exist-published.guard';
@ -50,7 +48,7 @@ describe('SchemaMustExistPublishedGuard', () => {
it('should load schema and return false when not found', () => {
schemasState.setup(x => x.select('123'))
.returns(() => of(<SchemaDetailsDto>{ isPublished: false }));
.returns(() => of(<SchemaDetailsDto>{ isPublished: false }));
let result: boolean;
@ -80,7 +78,7 @@ describe('SchemaMustExistPublishedGuard', () => {
it('should redirect to content when singleton', () => {
schemasState.setup(x => x.select('123'))
.returns(() => of(<SchemaDetailsDto>{ isSingleton: true }));
.returns(() => of(<SchemaDetailsDto>{ isSingleton: true, id: 'schema-id' }));
let result: boolean;
@ -90,6 +88,6 @@ describe('SchemaMustExistPublishedGuard', () => {
expect(result!).toBeFalsy();
router.verify(x => x.navigate([state.url, MathHelper.EMPTY_GUID]), Times.once());
router.verify(x => x.navigate([state.url, 'schema-id']), Times.once());
});
});

6
src/Squidex/app/shared/guards/schema-must-exist-published.guard.ts

@ -10,7 +10,7 @@ import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { allParams, MathHelper } from '@app/framework';
import { allParams } from '@app/framework';
import { SchemasState } from './../state/schemas.state';
@ -32,8 +32,8 @@ export class SchemaMustExistPublishedGuard implements CanActivate {
this.router.navigate(['/404']);
}
if (dto && dto.isSingleton && state.url.indexOf(MathHelper.EMPTY_GUID) < 0) {
this.router.navigate([state.url, MathHelper.EMPTY_GUID]);
if (dto && dto.isSingleton && state.url.indexOf(dto.id) < 0) {
this.router.navigate([state.url, dto.id]);
}
}),
map(s => s !== null && s.isPublished));

2
src/Squidex/app/shell/pages/internal/apps-menu.component.html

@ -11,7 +11,7 @@
</span>
<ng-container *ngIf="appsState.apps | async; let apps">
<div class="dropdown-menu" *sqxModalView="appsMenu" @fade>
<div class="dropdown-menu" *sqxModalView="appsMenu;closeAlways:true" @fade>
<a class="dropdown-item all-apps" routerLink="/app">
<span class="all-apps-text">All Apps</span>
<span class="all-apps-pill badge badge-pill badge-primary">{{apps.length}}</span>

7
src/Squidex/app/shell/pages/internal/apps-menu.component.ts

@ -9,8 +9,9 @@ import { Component } from '@angular/core';
import {
AppsState,
DialogModel,
fadeAnimation,
ModalView
ModalModel
} from '@app/shared';
@Component({
@ -22,9 +23,9 @@ import {
]
})
export class AppsMenuComponent {
public addAppDialog = new ModalView();
public addAppDialog = new DialogModel();
public appsMenu = new ModalView(false, true);
public appsMenu = new ModalModel();
constructor(
public readonly appsState: AppsState

14
src/Squidex/app/shell/pages/internal/internal-area.component.html

@ -16,10 +16,12 @@
<router-outlet></router-outlet>
</div>
<a class="github-button" href="https://github.com/Squidex/squidex/issues" target="_blank">
<i class="icon-github github-icon"></i>
<span class="github-text">Github</span>
</a>
<a class="support-button row no-gutters" href="https://support.squidex.io" target="_blank">
<div class="col col-auto support-icon">
<i class="icon-support"></i>
</div>
<sqx-user-report></sqx-user-report>
<div class="col support-text">
Get help and support
</div>
</a>

51
src/Squidex/app/shell/pages/internal/internal-area.component.scss

@ -23,49 +23,52 @@
float: left;
}
.github {
$support-icon-size: 50px;
$support-text-size: 200px;
.support {
&-button {
& {
@include fixed(50%, -103px, auto, auto);
@include border-radius-left(3px);
@include fixed(50%, -$support-text-size, auto, auto);
@include transition(transform .3s ease);
background: lighten($color-extern-github, 10%);
border: 0;
cursor: pointer;
color: $color-dark-foreground;
margin-top: -60px;
padding-left: 65px;
background: $color-theme-blue;
font-size: .9rem;
font-weight: bold;
height: 44px;
line-height: 40px;
width: 147px;
z-index: 1000000094;
height: $support-icon-size;
line-break: normal;
line-height: $support-icon-size - 6px;
z-index: 100000000;
}
&:hover {
& {
@include translate(-103px, 0);
@include translate(-$support-text-size, 0);
text-decoration: none;
}
.github-icon {
background: $color-extern-github;
.support-icon {
background: $color-theme-blue-dark;
}
}
}
&-icon,
&-text {
cursor: pointer;
color: $color-dark-foreground;
text-align: center;
}
&-text {
width: $support-text-size;
}
&-icon {
@include absolute(0, auto, auto, 0);
@include border-radius-left(3px);
@include transition(background-color .4s ease);
background: lighten($color-extern-github, 10%);
display: inline-block;
line-height: 44px;
background: $color-theme-blue;
line-height: $support-icon-size;
font-size: 1.5rem;
font-weight: normal;
width: 44px;
text-align: center;
color: $color-dark-foreground;
width: $support-icon-size;
}
}

2
src/Squidex/app/shell/pages/internal/profile-menu.component.html

@ -8,7 +8,7 @@
</span>
</span>
<div class="dropdown-menu" *sqxModalView="modalMenu" @fade>
<div class="dropdown-menu" *sqxModalView="modalMenu;closeAlways:true" @fade>
<a class="dropdown-item" routerLink="/app/administration" *ngIf="isAdmin">
Administration
</a>

4
src/Squidex/app/shell/pages/internal/profile-menu.component.ts

@ -13,7 +13,7 @@ import {
ApiUrlConfig,
AuthService,
fadeAnimation,
ModalView
ModalModel
} from '@app/shared';
@Component({
@ -27,7 +27,7 @@ import {
export class ProfileMenuComponent implements OnDestroy, OnInit {
private authenticationSubscription: Subscription;
public modalMenu = new ModalView(false, true);
public modalMenu = new ModalModel();
public profileDisplayName = '';
public profileId = '';

8
src/Squidex/app/theme/icomoon/demo-files/demo.css

@ -147,19 +147,19 @@ p {
font-size: 16px;
}
.fs1 {
font-size: 32px;
font-size: 24px;
}
.fs2 {
font-size: 28px;
font-size: 32px;
}
.fs3 {
font-size: 32px;
font-size: 28px;
}
.fs4 {
font-size: 32px;
}
.fs5 {
font-size: 24px;
font-size: 32px;
}
.fs6 {
font-size: 20px;

518
src/Squidex/app/theme/icomoon/demo.html

File diff suppressed because it is too large

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

Binary file not shown.

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

@ -97,6 +97,7 @@
<glyph unicode="&#xe957;" glyph-name="multiple-content" horiz-adv-x="1029" d="M777.143 4.571h-525.714c-89.143 0-160 70.857-160 160v297.143c0 89.143 70.857 160 160 160h525.714c89.143 0 160-70.857 160-160v-297.143c0-89.143-70.857-160-160-160zM251.429 576c-64 0-114.286-50.286-114.286-114.286v-297.143c0-64 50.286-114.286 114.286-114.286h525.714c64 0 114.286 50.286 114.286 114.286v297.143c0 64-50.286 114.286-114.286 114.286h-525.714zM731.429 370.286h-457.143c-13.714 0-22.857 9.143-22.857 22.857s9.143 22.857 22.857 22.857h457.143c13.714 0 22.857-9.143 22.857-22.857s-9.143-22.857-22.857-22.857zM502.857 210.286h-228.571c-13.714 0-22.857 9.143-22.857 22.857s9.143 22.857 22.857 22.857h228.571c13.714 0 22.857-9.143 22.857-22.857s-9.143-22.857-22.857-22.857zM777.143 690.286h-525.714c-13.714 0-22.857 9.143-22.857 22.857s9.143 22.857 22.857 22.857h525.714c13.714 0 22.857-9.143 22.857-22.857s-9.143-22.857-22.857-22.857zM685.714 804.571h-342.857c-13.714 0-22.857 9.143-22.857 22.857s9.143 22.857 22.857 22.857h342.857c13.714 0 22.857-9.143 22.857-22.857s-9.143-22.857-22.857-22.857z" />
<glyph unicode="&#xe958;" glyph-name="single-content" horiz-adv-x="1029" d="M251.429 850.277c-87.896 0-160-72.104-160-160v-525.714c0-87.896 72.104-160 160-160h525.714c87.896 0 160 72.104 160 160v525.714c0 87.896-72.104 160-160 160zM251.429 804.562h525.714c62.961 0 114.286-51.325 114.286-114.286v-525.714c0-62.961-51.325-114.286-114.286-114.286h-525.714c-62.961 0-114.286 51.325-114.286 114.286v525.714c0 62.961 51.325 114.286 114.286 114.286zM251.429 644.562c-0.096 0.001-0.21 0.002-0.323 0.002-12.625 0-22.859-10.235-22.859-22.859s10.235-22.859 22.859-22.859c0.114 0 0.227 0.001 0.34 0.002h525.697c0.096-0.001 0.21-0.002 0.323-0.002 12.625 0 22.859 10.235 22.859 22.859s-10.235 22.859-22.859 22.859c-0.114 0-0.227-0.001-0.34-0.002h0.017zM251.429 507.419c-0.096 0.001-0.21 0.002-0.323 0.002-12.625 0-22.859-10.235-22.859-22.859s10.235-22.859 22.859-22.859c0.114 0 0.227 0.001 0.34 0.002h297.126c0.096-0.001 0.21-0.002 0.323-0.002 12.625 0 22.859 10.235 22.859 22.859s-10.235 22.859-22.859 22.859c-0.114 0-0.227-0.001-0.34-0.002h0.017zM251.429 370.277c-0.096 0.001-0.21 0.002-0.323 0.002-12.625 0-22.859-10.235-22.859-22.859s10.235-22.859 22.859-22.859c0.114 0 0.227 0.001 0.34 0.002h297.126c0.096-0.001 0.21-0.002 0.323-0.002 12.625 0 22.859 10.235 22.859 22.859s-10.235 22.859-22.859 22.859c-0.114 0-0.227-0.001-0.34-0.002h0.017z" />
<glyph unicode="&#xe959;" glyph-name="action-Medium" d="M121.429 688.64c1.28 12.587-3.541 25.003-12.928 33.451l-95.573 115.2v17.195h296.832l229.461-503.253 201.728 503.253h283.051v-17.195l-81.792-78.379c-7.040-5.376-10.539-14.208-9.088-22.955v-576c-1.451-8.704 2.048-17.493 9.088-22.912l79.787-78.379v-17.195h-401.493v17.195l82.645 80.299c8.107 8.107 8.107 10.496 8.107 22.955v465.536l-229.973-584.021h-31.019l-267.733 584.021v-391.424c-2.219-16.469 3.243-33.024 14.805-44.928l107.52-130.56v-17.152h-304.853v17.195l107.52 130.56c11.52 11.861 16.64 28.587 13.909 44.885v452.608z" />
<glyph unicode="&#xe95a;" glyph-name="support" d="M726 426.667c0-24-20-42-44-42h-426l-170-172v598c0 24 18 42 42 42h554c24 0 44-18 44-42v-384zM896 682.667c24 0 42-18 42-42v-640l-170 170h-470c-24 0-42 18-42 42v86h554v384h86z" />
<glyph unicode="&#xe9ca;" glyph-name="earth" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512-0.002c-62.958 0-122.872 13.012-177.23 36.452l233.148 262.29c5.206 5.858 8.082 13.422 8.082 21.26v96c0 17.674-14.326 32-32 32-112.99 0-232.204 117.462-233.374 118.626-6 6.002-14.14 9.374-22.626 9.374h-128c-17.672 0-32-14.328-32-32v-192c0-12.122 6.848-23.202 17.69-28.622l110.31-55.156v-187.886c-116.052 80.956-192 215.432-192 367.664 0 68.714 15.49 133.806 43.138 192h116.862c8.488 0 16.626 3.372 22.628 9.372l128 128c6 6.002 9.372 14.14 9.372 22.628v77.412c40.562 12.074 83.518 18.588 128 18.588 70.406 0 137.004-16.26 196.282-45.2-4.144-3.502-8.176-7.164-12.046-11.036-36.266-36.264-56.236-84.478-56.236-135.764s19.97-99.5 56.236-135.764c36.434-36.432 85.218-56.264 135.634-56.26 3.166 0 6.342 0.080 9.518 0.236 13.814-51.802 38.752-186.656-8.404-372.334-0.444-1.744-0.696-3.488-0.842-5.224-81.324-83.080-194.7-134.656-320.142-134.656z" />
<glyph unicode="&#xf00a;" glyph-name="grid" d="M292.571 237.714v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM292.571 530.286v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM658.286 237.714v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM292.571 822.857v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM658.286 530.286v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM1024 237.714v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM658.286 822.857v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM1024 530.286v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857zM1024 822.857v-109.714c0-30.286-24.571-54.857-54.857-54.857h-182.857c-30.286 0-54.857 24.571-54.857 54.857v109.714c0 30.286 24.571 54.857 54.857 54.857h182.857c30.286 0 54.857-24.571 54.857-54.857z" />
<glyph unicode="&#xf0c9;" glyph-name="list" horiz-adv-x="878" d="M877.714 182.857v-73.143c0-20-16.571-36.571-36.571-36.571h-804.571c-20 0-36.571 16.571-36.571 36.571v73.143c0 20 16.571 36.571 36.571 36.571h804.571c20 0 36.571-16.571 36.571-36.571zM877.714 475.428v-73.143c0-20-16.571-36.571-36.571-36.571h-804.571c-20 0-36.571 16.571-36.571 36.571v73.143c0 20 16.571 36.571 36.571 36.571h804.571c20 0 36.571-16.571 36.571-36.571zM877.714 768v-73.143c0-20-16.571-36.571-36.571-36.571h-804.571c-20 0-36.571 16.571-36.571 36.571v73.143c0 20 16.571 36.571 36.571 36.571h804.571c20 0 36.571-16.571 36.571-36.571z" />

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 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.

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

@ -1,6 +1,93 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M726 512c0 24-20 42-44 42h-426l-170 172v-598c0-24 18-42 42-42h554c24 0 44 18 44 42v384zM896 256c24 0 42 18 42 42v640l-170-170h-470c-24 0-42-18-42-42v-86h554v-384h86z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"question_answer"
],
"grid": 24
},
"attrs": [
{}
],
"properties": {
"order": 1,
"id": 0,
"prevSize": 24,
"code": 59738,
"name": "support"
},
"setIdx": 0,
"setId": 3,
"iconIdx": 0
},
{
"icon": {
"paths": [
"M918 384v128h-128v298h-128v-298h-128v-128h384zM106 170h556v128h-214v512h-128v-512h-214v-128z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"text_fields"
],
"grid": 24
},
"attrs": [
{}
],
"properties": {
"order": 75,
"id": 0,
"prevSize": 24,
"code": 59705,
"name": "control-RichText"
},
"setIdx": 2,
"setId": 1,
"iconIdx": 90
},
{
"icon": {
"paths": [
"M640 85.333q78 0 149.167 30.5t122.5 81.833 81.833 122.5 30.5 149.167q0 85-35 160.667t-96.667 129.167-140 77.5l21-20.667q18-18.333 28-42.667 9.333-22.667 9.333-49.333 0-6.667-0.333-9.333 59.333-41.333 93.833-105.833t34.5-139.5q0-60.667-23.667-116t-63.667-95.333-95.333-63.667-116-23.667q-55.333 0-106.5 19.833t-90 53.833-65 81.333-33.833 101h-88.667q-70.667 0-120.667 50t-50 120.667q0 38.667 15.167 71.667t39.833 54.167 54.833 33 60.833 11.833h50q11.667 29.333 30 48l37.667 37.333h-117.667q-69.667 0-128.5-34.333t-93.167-93.167-34.333-128.5 34.333-128.5 93.167-93.167 128.5-34.333h22q26.333-74.333 79.333-132.167t126.833-90.833 155.833-33zM554.667 426.667q17.667 0 30.167 12.5t12.5 30.167v281l55-55.333q12.333-12.333 30.333-12.333 18.333 0 30.5 12.167t12.167 30.5q0 18-12.333 30.333l-128 128q-12.333 12.333-30.333 12.333t-30.333-12.333l-128-128q-12.333-13-12.333-30.333 0-17.667 12.5-30.167t30.167-12.5q18 0 30.333 12.333l55 55.333v-281q0-17.667 12.5-30.167t30.167-12.5z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"cloud-download"
],
"grid": 24
},
"attrs": [
{}
],
"properties": {
"order": 1,
"id": 0,
"prevSize": 24,
"code": 59710,
"name": "download"
},
"setIdx": 2,
"setId": 1,
"iconIdx": 91
},
{
"icon": {
"paths": [
@ -26,7 +113,7 @@
"code": 59737,
"name": "action-Medium"
},
"setIdx": 0,
"setIdx": 1,
"setId": 2,
"iconIdx": 0
},
@ -55,7 +142,7 @@
"prevSize": 32,
"code": 59729
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 44
},
@ -85,7 +172,7 @@
"prevSize": 32,
"code": 59726
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 45
},
@ -117,7 +204,7 @@
"prevSize": 32,
"code": 59727
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 46
},
@ -146,7 +233,7 @@
"prevSize": 32,
"code": 59724
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 47
},
@ -184,7 +271,7 @@
"prevSize": 32,
"code": 59722
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 48
},
@ -213,7 +300,7 @@
"prevSize": 32,
"code": 59652
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 49
},
@ -242,7 +329,7 @@
"prevSize": 32,
"code": 59653
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 50
},
@ -271,7 +358,7 @@
"prevSize": 32,
"code": 59654
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 51
},
@ -300,7 +387,7 @@
"prevSize": 32,
"code": 59655
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 52
},
@ -329,7 +416,7 @@
"prevSize": 32,
"code": 59656
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 53
},
@ -358,7 +445,7 @@
"prevSize": 32,
"code": 59657
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 54
},
@ -387,7 +474,7 @@
"prevSize": 32,
"code": 59658
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 55
},
@ -416,7 +503,7 @@
"prevSize": 32,
"code": 59659
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 56
},
@ -445,7 +532,7 @@
"prevSize": 32,
"code": 59660
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 57
},
@ -474,7 +561,7 @@
"prevSize": 32,
"code": 59661
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 58
},
@ -503,7 +590,7 @@
"prevSize": 32,
"code": 59662
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 59
},
@ -532,7 +619,7 @@
"prevSize": 32,
"code": 59663
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 60
},
@ -561,7 +648,7 @@
"prevSize": 32,
"code": 59664
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 61
},
@ -596,7 +683,7 @@
"prevSize": 32,
"code": 59665
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 62
},
@ -625,7 +712,7 @@
"prevSize": 32,
"code": 59666
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 63
},
@ -654,7 +741,7 @@
"prevSize": 32,
"code": 59667
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 64
},
@ -683,7 +770,7 @@
"prevSize": 32,
"code": 59668
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 65
},
@ -712,7 +799,7 @@
"prevSize": 32,
"code": 59669
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 66
},
@ -741,7 +828,7 @@
"prevSize": 32,
"code": 59670
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 67
},
@ -770,7 +857,7 @@
"prevSize": 32,
"code": 59671
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 68
},
@ -799,7 +886,7 @@
"prevSize": 32,
"code": 59672
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 69
},
@ -829,7 +916,7 @@
"prevSize": 32,
"code": 59713
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 70
},
@ -858,7 +945,7 @@
"prevSize": 32,
"code": 59673
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 71
},
@ -887,7 +974,7 @@
"prevSize": 32,
"code": 59675
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 72
},
@ -916,7 +1003,7 @@
"prevSize": 32,
"code": 59676
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 73
},
@ -945,7 +1032,7 @@
"prevSize": 32,
"code": 59677
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 74
},
@ -974,7 +1061,7 @@
"prevSize": 32,
"code": 59678
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 75
},
@ -1003,7 +1090,7 @@
"prevSize": 32,
"code": 59679
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 76
},
@ -1032,7 +1119,7 @@
"prevSize": 32,
"code": 59680
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 77
},
@ -1070,7 +1157,7 @@
"prevSize": 32,
"code": 59681
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 78
},
@ -1099,7 +1186,7 @@
"prevSize": 32,
"code": 59682
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 79
},
@ -1128,7 +1215,7 @@
"prevSize": 32,
"code": 59683
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 80
},
@ -1157,7 +1244,7 @@
"prevSize": 32,
"code": 59684
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 81
},
@ -1186,7 +1273,7 @@
"prevSize": 32,
"code": 59685
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 82
},
@ -1215,7 +1302,7 @@
"prevSize": 32,
"code": 59674
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 83
},
@ -1244,7 +1331,7 @@
"prevSize": 32,
"code": 59686
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 84
},
@ -1273,7 +1360,7 @@
"prevSize": 32,
"code": 59687
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 85
},
@ -1302,7 +1389,7 @@
"prevSize": 32,
"code": 59688
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 86
},
@ -1341,7 +1428,7 @@
"prevSize": 28,
"code": 59736
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 0
},
@ -1383,7 +1470,7 @@
"prevSize": 28,
"code": 59735
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 1
},
@ -1421,7 +1508,7 @@
"prevSize": 28,
"code": 59734
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 3
},
@ -1451,7 +1538,7 @@
"code": 59733,
"name": "exclamation"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 4
},
@ -1481,7 +1568,7 @@
"prevSize": 28,
"code": 59730
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 5
},
@ -1511,7 +1598,7 @@
"code": 59725,
"name": "action-Slack"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 6
},
@ -1540,7 +1627,7 @@
"prevSize": 28,
"code": 59723
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 7
},
@ -1572,7 +1659,7 @@
"prevSize": 28,
"code": 59721
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 8
},
@ -1604,7 +1691,7 @@
"prevSize": 28,
"code": 59711
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 9
},
@ -1634,7 +1721,7 @@
"code": 59648,
"name": "angle-down"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 10
},
@ -1664,7 +1751,7 @@
"code": 59649,
"name": "angle-left"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 11
},
@ -1694,7 +1781,7 @@
"code": 59697,
"name": "angle-right"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 12
},
@ -1724,7 +1811,7 @@
"code": 59651,
"name": "angle-up"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 13
},
@ -1765,7 +1852,7 @@
"prevSize": 28,
"code": 59717
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 14
},
@ -1800,7 +1887,7 @@
"prevSize": 28,
"code": 59720
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 15
},
@ -1830,7 +1917,7 @@
"code": 59709,
"name": "bug"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 16
},
@ -1860,7 +1947,7 @@
"code": 59692,
"name": "caret-down"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 17
},
@ -1890,7 +1977,7 @@
"code": 59690,
"name": "caret-left"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 18
},
@ -1920,7 +2007,7 @@
"code": 59689,
"name": "caret-right"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 19
},
@ -1950,7 +2037,7 @@
"code": 59691,
"name": "caret-up"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 20
},
@ -1988,7 +2075,7 @@
"prevSize": 28,
"code": 59718
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 21
},
@ -2017,7 +2104,7 @@
"prevSize": 28,
"code": 59702
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 22
},
@ -2046,7 +2133,7 @@
"prevSize": 28,
"code": 59703
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 23
},
@ -2075,7 +2162,7 @@
"prevSize": 28,
"code": 59704
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 24
},
@ -2102,7 +2189,7 @@
"prevSize": 28,
"code": 61450
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 25
},
@ -2131,7 +2218,7 @@
"prevSize": 28,
"code": 61641
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 26
},
@ -2160,7 +2247,7 @@
"prevSize": 28,
"code": 59698
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 27
},
@ -2210,7 +2297,7 @@
"prevSize": 28,
"code": 59719
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 28
},
@ -2242,7 +2329,7 @@
"code": 59732,
"name": "hour-glass"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 29
},
@ -2275,7 +2362,7 @@
"code": 59731,
"name": "spinner"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 30
},
@ -2306,7 +2393,7 @@
"code": 59728,
"name": "clock"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 31
},
@ -2343,7 +2430,7 @@
"prevSize": 32,
"code": 59650
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 32
},
@ -2376,7 +2463,7 @@
"prevSize": 32,
"code": 59850
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 33
},
@ -2409,7 +2496,7 @@
"code": 59715,
"name": "elapsed"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 34
},
@ -2439,7 +2526,7 @@
"code": 59707,
"name": "google"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 35
},
@ -2471,7 +2558,7 @@
"code": 59700,
"name": "lock"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 36
},
@ -2502,7 +2589,7 @@
"code": 59712,
"name": "microsoft, action-AzureQueue"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 37
},
@ -2532,7 +2619,7 @@
"code": 59695,
"name": "pause"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 38
},
@ -2562,7 +2649,7 @@
"code": 59696,
"name": "play"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 39
},
@ -2601,7 +2688,7 @@
"code": 59694,
"name": "reset"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 40
},
@ -2636,7 +2723,7 @@
"code": 59693,
"name": "settings2"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 41
},
@ -2670,7 +2757,7 @@
"code": 59716,
"name": "timeout"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 42
},
@ -2700,7 +2787,7 @@
"code": 59699,
"name": "unlocked"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 43
},
@ -2733,7 +2820,7 @@
"code": 59701,
"name": "browser"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 87
},
@ -2765,7 +2852,7 @@
"code": 59714,
"name": "checkmark"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 88
},
@ -2795,68 +2882,10 @@
"code": 59706,
"name": "control-Stars"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 89
},
{
"icon": {
"paths": [
"M918 384v128h-128v298h-128v-298h-128v-128h384zM106 170h556v128h-214v512h-128v-512h-214v-128z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"text_fields"
],
"grid": 24
},
"attrs": [
{}
],
"properties": {
"order": 75,
"id": 0,
"prevSize": 24,
"code": 59705,
"name": "control-RichText"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 90
},
{
"icon": {
"paths": [
"M640 85.333q78 0 149.167 30.5t122.5 81.833 81.833 122.5 30.5 149.167q0 85-35 160.667t-96.667 129.167-140 77.5l21-20.667q18-18.333 28-42.667 9.333-22.667 9.333-49.333 0-6.667-0.333-9.333 59.333-41.333 93.833-105.833t34.5-139.5q0-60.667-23.667-116t-63.667-95.333-95.333-63.667-116-23.667q-55.333 0-106.5 19.833t-90 53.833-65 81.333-33.833 101h-88.667q-70.667 0-120.667 50t-50 120.667q0 38.667 15.167 71.667t39.833 54.167 54.833 33 60.833 11.833h50q11.667 29.333 30 48l37.667 37.333h-117.667q-69.667 0-128.5-34.333t-93.167-93.167-34.333-128.5 34.333-128.5 93.167-93.167 128.5-34.333h22q26.333-74.333 79.333-132.167t126.833-90.833 155.833-33zM554.667 426.667q17.667 0 30.167 12.5t12.5 30.167v281l55-55.333q12.333-12.333 30.333-12.333 18.333 0 30.5 12.167t12.167 30.5q0 18-12.333 30.333l-128 128q-12.333 12.333-30.333 12.333t-30.333-12.333l-128-128q-12.333-13-12.333-30.333 0-17.667 12.5-30.167t30.167-12.5q18 0 30.333 12.333l55 55.333v-281q0-17.667 12.5-30.167t30.167-12.5z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"cloud-download"
],
"grid": 24
},
"attrs": [
{}
],
"properties": {
"order": 1,
"id": 0,
"prevSize": 24,
"code": 59710,
"name": "download"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 91
},
{
"icon": {
"paths": [
@ -2882,7 +2911,7 @@
"code": 59708,
"name": "info"
},
"setIdx": 1,
"setIdx": 2,
"setId": 1,
"iconIdx": 92
}

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

@ -1,10 +1,10 @@
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?o6u2w7');
src: url('fonts/icomoon.eot?o6u2w7#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?o6u2w7') format('truetype'),
url('fonts/icomoon.woff?o6u2w7') format('woff'),
url('fonts/icomoon.svg?o6u2w7#icomoon') format('svg');
src: url('fonts/icomoon.eot?lx1t7v');
src: url('fonts/icomoon.eot?lx1t7v#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?lx1t7v') format('truetype'),
url('fonts/icomoon.woff?lx1t7v') format('woff'),
url('fonts/icomoon.svg?lx1t7v#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
@ -24,6 +24,15 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-support:before {
content: "\e95a";
}
.icon-control-RichText:before {
content: "\e939";
}
.icon-download:before {
content: "\e93e";
}
.icon-action-Medium:before {
content: "\e959";
}
@ -324,48 +333,6 @@
.icon-unlocked:before {
content: "\e933";
}
.icon-control-TextArea:before {
content: "\e90e";
}
.icon-control-Toggle:before {
content: "\e90f";
}
.icon-copy:before {
content: "\e910";
}
.icon-dashboard:before {
content: "\e911";
}
.icon-delete:before {
content: "\e912";
}
.icon-bin:before {
content: "\e912";
}
.icon-delete-filled:before {
content: "\e913";
}
.icon-document-delete:before {
content: "\e914";
}
.icon-document-disable:before {
content: "\e915";
}
.icon-document-publish:before {
content: "\e916";
}
.icon-drag:before {
content: "\e917";
}
.icon-filter:before {
content: "\e918";
}
.icon-github:before {
content: "\e941";
}
.icon-help:before {
content: "\e919";
}
.icon-browser:before {
content: "\e935";
}
@ -375,12 +342,6 @@
.icon-control-Stars:before {
content: "\e93a";
}
.icon-control-RichText:before {
content: "\e939";
}
.icon-download:before {
content: "\e93e";
}
.icon-info:before {
content: "\e93c";
}

4
tests/Squidex.Domain.Apps.Entities.Tests/Contents/Guard/GuardContentTests.cs

@ -43,11 +43,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.Guard
}
[Fact]
public void CanCreate_should_not_throw_exception_if_singleton_and_id_empty()
public void CanCreate_should_not_throw_exception_if_singleton_and_id_is_schema_id()
{
A.CallTo(() => schema.IsSingleton).Returns(true);
var command = new CreateContent { Data = new NamedContentData(), ContentId = Guid.Empty };
var command = new CreateContent { Data = new NamedContentData(), ContentId = schema.Id };
GuardContent.CanCreate(schema, command);
}

Loading…
Cancel
Save