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. 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. 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 ## 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 ## Prerequisites
* [Visual Studio Code](https://code.visualstudio.com/) or [Visual Studio 2017](https://www.visualstudio.com/vs/visual-studio-2017-rc/) * [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/) * [Node.js](https://nodejs.org/en/) (development only)
* [.NET Core SDK](https://www.microsoft.com/net/download/core#/current) (Already part of Visual Studio 2017)
* [MongoDB](https://www.mongodb.com/) * [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 ## Contributors

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

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Contents.Commands;
@ -25,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Guards
ValidateData(command, e); 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."); 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 data = new NamedContentData();
var contentId = Guid.Empty; var contentId = schemaId.Id;
var content = new CreateContent { Data = data, ContentId = contentId, SchemaId = schemaId, Publish = true }; var content = new CreateContent { Data = data, ContentId = contentId, SchemaId = schemaId, Publish = true };
SimpleMapper.Map(context.Command, content); 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 { Subscription, timer } from 'rxjs';
import { onErrorResumeNext, switchMap } from 'rxjs/operators'; import { onErrorResumeNext, switchMap } from 'rxjs/operators';
import { ModalView } from '@app/shared'; import { DialogModel } from '@app/shared';
import { EventConsumerDto } from './../../services/event-consumers.service'; import { EventConsumerDto } from './../../services/event-consumers.service';
import { EventConsumersState } from './../../state/event-consumers.state'; import { EventConsumersState } from './../../state/event-consumers.state';
@ -22,7 +22,7 @@ import { EventConsumersState } from './../../state/event-consumers.state';
export class EventConsumersPageComponent implements OnDestroy, OnInit { export class EventConsumersPageComponent implements OnDestroy, OnInit {
private timerSubscription: Subscription; private timerSubscription: Subscription;
public eventConsumerErrorDialog = new ModalView(); public eventConsumerErrorDialog = new DialogModel();
public eventConsumerError = ''; public eventConsumerError = '';
constructor( constructor(

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

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

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

@ -132,8 +132,8 @@
</p> </p>
<div> <div>
<a class="btn btn-success" href="https://squidex-slack.herokuapp.com/" target="_blank"> <a class="btn btn-success" href="https://support.squidex.io" target="_blank">
Join us on Slack Join our Forum
</a> &nbsp; </a> &nbsp;
<a class="btn btn-success" href="https://github.com/squidex/squidex" target="_blank"> <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> </button>
<ng-container *ngIf="content.isPending || !schema.isSingleton"> <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"> <ng-container *ngIf="content.isPending">
<a class="dropdown-item" (click)="discardChanges()"> <a class="dropdown-item" (click)="discardChanges()">
Discard changes Discard changes

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

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

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

@ -16,7 +16,7 @@ import {
ContentsState, ContentsState,
ImmutableArray, ImmutableArray,
LanguagesState, LanguagesState,
ModalView, ModalModel,
SchemaDetailsDto, SchemaDetailsDto,
SchemasState SchemasState
} from '@app/shared'; } from '@app/shared';
@ -35,7 +35,7 @@ export class ContentsPageComponent implements OnDestroy, OnInit {
public schema: SchemaDetailsDto; public schema: SchemaDetailsDto;
public searchModal = new ModalView(); public searchModal = new ModalModel();
public selectedItems: { [id: string]: boolean; } = {}; public selectedItems: { [id: string]: boolean; } = {};
public selectionCount = 0; 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 { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { FormBuilder, FormControl } from '@angular/forms'; import { FormBuilder, FormControl } from '@angular/forms';
import { ModalView } from '@app/shared'; import { ModalModel } from '@app/shared';
@Component({ @Component({
selector: 'sqx-search-form', selector: 'sqx-search-form',
@ -40,7 +40,7 @@ export class SearchFormComponent implements OnChanges {
public contentsFilter = new FormControl(); public contentsFilter = new FormControl();
public searchModal = new ModalView(); public searchModal = new ModalModel();
public searchForm = public searchForm =
this.formBuilder.group({ this.formBuilder.group({
odataOrderBy: '', 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="assets-container" [class.disabled]="isDisabled">
<div class="row"> <div class="row">
<div class="drop-area-container"> <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. Drop files here to add them.
</div> </div>
</div> </div>
@ -16,6 +16,6 @@
</div> </div>
</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> <sqx-assets-selector (selected)="onAssetsSelected($event)"></sqx-assets-selector>
</ng-container> </ng-container>

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

@ -15,7 +15,7 @@ import {
AssetDto, AssetDto,
AssetsService, AssetsService,
ImmutableArray, ImmutableArray,
ModalView, ModalModel,
Types Types
} from '@app/shared'; } from '@app/shared';
@ -35,7 +35,7 @@ export class AssetsEditorComponent implements ControlValueAccessor {
private callChange = (v: any) => { /* NOOP */ }; private callChange = (v: any) => { /* NOOP */ };
private callTouched = () => { /* NOOP */ }; private callTouched = () => { /* NOOP */ };
public selectorModal = new ModalView(); public assetsDialog = new ModalModel();
public newAssets = ImmutableArray.empty<File>(); public newAssets = ImmutableArray.empty<File>();
public oldAssets = ImmutableArray.empty<AssetDto>(); public oldAssets = ImmutableArray.empty<AssetDto>();
@ -96,7 +96,7 @@ export class AssetsEditorComponent implements ControlValueAccessor {
this.updateValue(); this.updateValue();
} }
this.selectorModal.hide(); this.assetsDialog.hide();
} }
public onAssetRemoving(asset: AssetDto) { 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> <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> <i class="icon-dots"></i>
</button> </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'"> <a class="dropdown-item" (click)="publishing.emit(); $event.stopPropagation()" *ngIf="content.status === 'Draft'">
Publish Publish
</a> </a>

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

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

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

@ -12,7 +12,7 @@ import {
ContentDto, ContentDto,
LanguageDto, LanguageDto,
ManualContentsState, ManualContentsState,
ModalView, ModalModel,
SchemaDetailsDto SchemaDetailsDto
} from '@app/shared'; } from '@app/shared';
@ -37,7 +37,7 @@ export class ContentsSelectorComponent implements OnInit {
@Output() @Output()
public selected = new EventEmitter<ContentDto[]>(); public selected = new EventEmitter<ContentDto[]>();
public searchModal = new ModalView(); public searchModal = new ModalModel();
public selectedItems: { [id: string]: ContentDto; } = {}; public selectedItems: { [id: string]: ContentDto; } = {};
public selectionCount = 0; 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 { Component } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { fadeAnimation, ModalView } from '@app/shared'; import { DialogModel, fadeAnimation } from '@app/shared';
@Component({ @Component({
selector: 'sqx-due-time-selector', selector: 'sqx-due-time-selector',
@ -19,7 +19,7 @@ import { fadeAnimation, ModalView } from '@app/shared';
] ]
}) })
export class DueTimeSelectorComponent { export class DueTimeSelectorComponent {
public dueTimeDialog = new ModalView(); public dueTimeDialog = new DialogModel();
public dueTime: string | null = ''; public dueTime: string | null = '';
public dueTimeFunction: Subject<string | null>; public dueTimeFunction: Subject<string | null>;
public dueTimeAction: 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"> <div class="references-container" [class.disabled]="isDisabled">
<ng-container *ngIf="schema"> <ng-container *ngIf="schema">
<div class="drop-area-container"> <div class="drop-area-container">
<div class="drop-area" (click)="showModal()"> <div class="drop-area" (click)="selectorDialog.show()">
Click here to link a content. Click here to link a content.
</div> </div>
</div> </div>
@ -26,7 +26,7 @@
</div> </div>
</div> </div>
<ng-container *sqxModalView="isModalVisibible;onRoot:true;closeAuto:false"> <ng-container *sqxModalView="selectorDialog;onRoot:true;closeAuto:false">
<sqx-contents-selector <sqx-contents-selector
[language]="language" [language]="language"
[languages]="languages" [languages]="languages"

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

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

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

@ -40,13 +40,13 @@
</div> </div>
</a> </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-body">
<div class="card-image"> <div class="card-image">
<img src="/images/dashboard-feedback.png" /> <img src="/images/dashboard-feedback.png" />
</div> </div>
<h4 class="card-title">Feedback</h4> <h4 class="card-title">Feedback & Support</h4>
<div class="card-text"> <div class="card-text">
Provide feedback and request features to help us to improve Squidex. 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; color: $color-title;
font-weight: light; font-weight: light;
font-size: 1.2rem; font-size: 1.2rem;
margin-top: .4rem; margin-top: 1rem;
} }
&-href { &-href {

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

@ -20,8 +20,6 @@ import {
UsagesService UsagesService
} from '@app/shared'; } from '@app/shared';
declare var _urq: any;
@Component({ @Component({
selector: 'sqx-dashboard-page', selector: 'sqx-dashboard-page',
styleUrls: ['./dashboard-page.component.scss'], 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[] { 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 { import {
AppsState, AppsState,
ModalView, DialogModel,
ruleActions, ruleActions,
RuleDto, RuleDto,
RulesState, RulesState,
@ -27,7 +27,7 @@ export class RulesPageComponent implements OnInit {
public ruleActions = ruleActions; public ruleActions = ruleActions;
public ruleTriggers = ruleTriggers; public ruleTriggers = ruleTriggers;
public addRuleDialog = new ModalView(); public addRuleDialog = new DialogModel();
public wizardMode = 'Wizard'; public wizardMode = 'Wizard';
public wizardRule: RuleDto | null; public wizardRule: RuleDto | null;

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

@ -121,7 +121,7 @@
</button> </button>
</div> </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" <sqx-field-wizard [schema]="schema" [parent]="field"
(completed)="addFieldDialog.hide()"> (completed)="addFieldDialog.hide()">
</sqx-field-wizard> </sqx-field-wizard>

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

@ -12,10 +12,11 @@ import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AppPatternDto, AppPatternDto,
createProperties, createProperties,
DialogModel,
EditFieldForm, EditFieldForm,
fadeAnimation, fadeAnimation,
ImmutableArray, ImmutableArray,
ModalView, ModalModel,
NestedFieldDto, NestedFieldDto,
RootFieldDto, RootFieldDto,
SchemaDetailsDto, SchemaDetailsDto,
@ -44,14 +45,14 @@ export class FieldComponent implements OnInit {
@Input() @Input()
public patterns: ImmutableArray<AppPatternDto>; public patterns: ImmutableArray<AppPatternDto>;
public dropdown = new ModalView(false, true); public dropdown = new ModalModel();
public isEditing = false; public isEditing = false;
public selectedTab = 0; public selectedTab = 0;
public editForm: EditFieldForm; public editForm: EditFieldForm;
public addFieldDialog = new ModalView(); public addFieldDialog = new DialogModel();
constructor( constructor(
private readonly formBuilder: FormBuilder, 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 { import {
AppsState, AppsState,
DialogModel,
fadeAnimation, fadeAnimation,
FieldDto, FieldDto,
fieldTypes, fieldTypes,
MessageBus, MessageBus,
ModalView, ModalModel,
PatternsState, PatternsState,
SchemaDetailsDto, SchemaDetailsDto,
SchemasState, SchemasState,
@ -45,14 +46,14 @@ export class SchemaPageComponent implements OnDestroy, OnInit {
public schemaExport: any; public schemaExport: any;
public schema: SchemaDetailsDto; public schema: SchemaDetailsDto;
public exportSchemaDialog = new ModalView(); public exportSchemaDialog = new DialogModel();
public configureScriptsDialog = new ModalView(); public configureScriptsDialog = new DialogModel();
public editOptionsDropdown = new ModalView(); public editOptionsDropdown = new ModalModel();
public editSchemaDialog = new ModalView(); public editSchemaDialog = new DialogModel();
public addFieldDialog = new ModalView(); public addFieldDialog = new DialogModel();
constructor( constructor(
public readonly appsState: AppsState, public readonly appsState: AppsState,

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

@ -14,7 +14,7 @@ import {
AppPatternDto, AppPatternDto,
FieldDto, FieldDto,
ImmutableArray, ImmutableArray,
ModalView, ModalModel,
StringFieldPropertiesDto StringFieldPropertiesDto
} from '@app/shared'; } from '@app/shared';
@ -43,7 +43,7 @@ export class StringValidationComponent implements OnDestroy, OnInit {
public showPatternSuggestions: Observable<boolean>; public showPatternSuggestions: Observable<boolean>;
public patternName: string; public patternName: string;
public patternsModal = new ModalView(false, false); public patternsModal = new ModalModel();
public ngOnDestroy() { public ngOnDestroy() {
this.patternSubscription.unsubscribe(); 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 { import {
AppsState, AppsState,
CreateCategoryForm, CreateCategoryForm,
DialogModel,
MessageBus, MessageBus,
ModalView,
SchemaDto, SchemaDto,
SchemasState SchemasState
} from '@app/shared'; } from '@app/shared';
@ -30,7 +30,7 @@ import { SchemaCloning } from './../messages';
export class SchemasPageComponent implements OnDestroy, OnInit { export class SchemasPageComponent implements OnDestroy, OnInit {
private schemaCloningSubscription: Subscription; private schemaCloningSubscription: Subscription;
public addSchemaDialog = new ModalView(); public addSchemaDialog = new DialogModel();
public addCategoryForm = new CreateCategoryForm(this.formBuilder); public addCategoryForm = new CreateCategoryForm(this.formBuilder);
public schemasFilter = new FormControl(); public schemasFilter = new FormControl();

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

@ -15,8 +15,8 @@ import {
AppClientsService, AppClientsService,
AppsState, AppsState,
ClientsState, ClientsState,
DialogModel,
DialogService, DialogService,
ModalView,
RenameClientForm, RenameClientForm,
UpdateAppClientDto UpdateAppClientDto
} from '@app/shared'; } from '@app/shared';
@ -37,7 +37,7 @@ export class ClientComponent implements OnChanges {
public isRenaming = false; public isRenaming = false;
public token: AccessTokenDto; public token: AccessTokenDto;
public tokenDialog = new ModalView(); public tokenDialog = new DialogModel();
public renameForm = new RenameClientForm(this.formBuilder); 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_UP = 38;
const KEY_DOWN = 40; const KEY_DOWN = 40;
import { ModalView } from '@app/framework/internal'; import { ModalModel } from '@app/framework/internal';
export const SQX_DROPDOWN_CONTROL_VALUE_ACCESSOR: any = { export const SQX_DROPDOWN_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DropdownComponent), multi: true provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DropdownComponent), multi: true
@ -35,7 +35,7 @@ export class DropdownComponent implements AfterContentInit, ControlValueAccessor
@ContentChildren(TemplateRef) @ContentChildren(TemplateRef)
public templates: QueryList<any>; public templates: QueryList<any>;
public dropdown = new ModalView(); public dropdown = new ModalModel();
public selectedItem: any; public selectedItem: any;
public selectedIndex = -1; 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 { Subscription } from 'rxjs';
import { import {
DialogModel,
DialogRequest, DialogRequest,
DialogService, DialogService,
fadeAnimation, fadeAnimation,
ModalView,
Notification Notification
} from '@app/framework/internal'; } from '@app/framework/internal';
@ -29,7 +29,7 @@ export class DialogRendererComponent implements OnDestroy, OnInit {
private dialogsSubscription: Subscription; private dialogsSubscription: Subscription;
private notificationsSubscription: Subscription; private notificationsSubscription: Subscription;
public dialogView = new ModalView(false, true); public dialogView = new DialogModel();
public dialogRequest: DialogRequest | null = null; public dialogRequest: DialogRequest | null = null;
public notifications: Notification[] = []; 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 { Directive, EmbeddedViewRef, Input, OnChanges, OnDestroy, Renderer2, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core';
import { Subscription } from 'rxjs'; 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'; import { RootViewComponent } from './root-view.component';
@ -21,7 +25,7 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
private renderedView: EmbeddedViewRef<any> | null = null; private renderedView: EmbeddedViewRef<any> | null = null;
@Input('sqxModalView') @Input('sqxModalView')
public modalView: ModalView | any; public modalView: DialogModel | ModalModel | any;
@Input('sqxModalViewOnRoot') @Input('sqxModalViewOnRoot')
public placeOnRoot = false; public placeOnRoot = false;
@ -29,6 +33,9 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
@Input('sqxModalViewCloseAuto') @Input('sqxModalViewCloseAuto')
public closeAuto = true; public closeAuto = true;
@Input('sqxModalViewCloseAlways')
public closeAlways = false;
constructor( constructor(
private readonly templateRef: TemplateRef<any>, private readonly templateRef: TemplateRef<any>,
private readonly renderer: Renderer2, private readonly renderer: Renderer2,
@ -38,9 +45,10 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
} }
public ngOnDestroy() { 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(); this.modalView.hide();
} }
} }
@ -50,12 +58,9 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
return; return;
} }
if (this.subscription) { this.unsubscribeToModal();
this.subscription.unsubscribe();
this.subscription = null;
}
if (Types.is(this.modalView, ModalView)) { if (Types.is(this.modalView, DialogModel) || Types.is(this.modalView, ModalModel)) {
this.subscription = this.subscription =
this.modalView.isOpen.subscribe(isOpen => { this.modalView.isOpen.subscribe(isOpen => {
this.update(isOpen); this.update(isOpen);
@ -71,11 +76,9 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
} }
if (isOpen && !this.renderedView) { if (isOpen && !this.renderedView) {
if (this.placeOnRoot) { const container = this.getContainer();
this.renderedView = this.rootView.viewContainer.createEmbeddedView(this.templateRef);
} else { this.renderedView = container.createEmbeddedView(this.templateRef);
this.renderedView = this.viewContainer.createEmbeddedView(this.templateRef);
}
if (this.renderedView.rootNodes[0].style) { if (this.renderedView.rootNodes[0].style) {
this.renderer.setStyle(this.renderedView.rootNodes[0], 'display', 'block'); this.renderer.setStyle(this.renderedView.rootNodes[0], 'display', 'block');
@ -85,18 +88,21 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
this.startListening(); this.startListening();
}); });
} else if (!isOpen && this.renderedView) { } else if (!isOpen && this.renderedView) {
this.renderedView = null; const container = this.getContainer();
const containerIndex = container.indexOf(this.renderedView);
if (this.placeOnRoot) { container.remove(containerIndex);
this.rootView.viewContainer.clear();
} else {
this.viewContainer.clear();
}
this.stopListening(); this.renderedView = null;
this.unsubscribeToClick();
} }
} }
private getContainer() {
return this.placeOnRoot ? this.rootView.viewContainer : this.viewContainer;
}
private startListening() { private startListening() {
if (!this.closeAuto) { if (!this.closeAuto) {
return; return;
@ -112,7 +118,7 @@ export class ModalViewDirective implements OnChanges, OnDestroy {
return; return;
} }
if (this.modalView.closeAlways) { if (this.closeAlways) {
this.modalView.hide(); this.modalView.hide();
} else { } else {
try { 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) { if (this.documentClickListener) {
this.documentClickListener(); this.documentClickListener();
this.documentClickListener = null; 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 { import {
fadeAnimation, fadeAnimation,
ModalView, ModalModel,
OnboardingService, OnboardingService,
Types Types
} from '@app/framework/internal'; } from '@app/framework/internal';
@ -27,7 +27,7 @@ export class OnboardingTooltipComponent implements OnDestroy, OnInit {
private closeTimer: any; private closeTimer: any;
private forMouseDownListener: Function | null; private forMouseDownListener: Function | null;
public tooltipModal = new ModalView(); public tooltipModal = new ModalModel();
@Input() @Input()
public for: any; 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 { 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'; import { fadeAnimation } from './../animations';
@ -30,7 +30,7 @@ export class TooltipComponent implements OnDestroy, OnInit {
@Input() @Input()
public position = 'topLeft'; public position = 'topLeft';
public modal = new ModalView(false, false); public modal = new ModalModel();
constructor( constructor(
private readonly renderer: Renderer2 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. * 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', () => { it('should have default values', () => {
const dialog = new ModalView(); const dialog = new DialogModel();
checkValue(dialog, false); 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', () => { it('should become open after toggle', () => {
const dialog = new ModalView(true); const dialog = new DialogModel();
dialog.toggle();
checkValue(dialog, true); checkValue(dialog, true);
}); });
it('should have initial false value', () => { it('should become closed after hide', () => {
const dialog = new ModalView(false); const dialog = new DialogModel().show();
dialog.hide();
checkValue(dialog, false); checkValue(dialog, false);
}); });
it('should have close always set by constructor', () => { it('should become closed after toggle', () => {
const dialog = new ModalView(false, true); 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', () => { 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', () => { 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', () => { 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', () => { 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) { it('should hide other modal', () => {
let result: boolean; const modal1 = new ModalModel().show();
const modal2 = new ModalModel();
dialog.isOpen.subscribe(value => { modal2.toggle();
result = value;
}).unsubscribe();
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'; import { BehaviorSubject, Observable } from 'rxjs';
export class ModalView { export interface Openable {
private readonly isOpen$: BehaviorSubject<boolean>; isOpen: Observable<boolean>;
private static openView: ModalView | null = null; }
export class DialogModel implements Openable {
private readonly isOpen$ = new BehaviorSubject<boolean>(false);
public get isOpen(): Observable<boolean> { public get isOpen(): Observable<boolean> {
return this.isOpen$; return this.isOpen$;
} }
constructor(isOpen = false, public show(): DialogModel {
public readonly closeAlways: boolean = false this.isOpen$.next(true);
) {
this.isOpen$ = new BehaviorSubject(isOpen); return this;
} }
public show() { public hide(): DialogModel {
if (ModalView.openView !== this && ModalView.openView) { this.isOpen$.next(false);
ModalView.openView.hide();
}
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() { public get isOpen(): Observable<boolean> {
if (ModalView.openView === this) { return this.isOpen$;
ModalView.openView = null; }
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() { public hide(): ModalModel {
let isOpenSnapshot = false; if (this.isOpen$.value) {
if (openModal === this) {
openModal = null;
}
this.isOpen.subscribe(v => { this.isOpen$.next(false);
isOpenSnapshot = v; }
}).unsubscribe();
return this;
}
if (isOpenSnapshot) { public toggle(): ModalModel {
if (this.isOpen$.value) {
this.hide(); this.hide();
} else { } else {
this.show(); this.show();
} }
return this;
} }
} }
let openModal: ModalModel | null = null;

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

@ -14,9 +14,9 @@ import {
AssetsService, AssetsService,
AuthService, AuthService,
DateTime, DateTime,
DialogModel,
DialogService, DialogService,
fadeAnimation, fadeAnimation,
ModalView,
RenameAssetForm, RenameAssetForm,
Types, Types,
UpdateAssetDto, UpdateAssetDto,
@ -68,7 +68,7 @@ export class AssetComponent implements OnInit {
@Output() @Output()
public failed = new EventEmitter(); public failed = new EventEmitter();
public renameDialog = new ModalView(); public renameDialog = new DialogModel();
public renameForm = new RenameAssetForm(this.formBuilder); public renameForm = new RenameAssetForm(this.formBuilder);
public progress = 0; 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"> <button type="button" class="btn btn-secondary dropdown-toggle" [attr.title]="selectedLanguage.englishName" (click)="dropdown.toggle(); $event.stopPropagation()" #button tabindex="-1">
{{selectedLanguage.iso2Code}} {{selectedLanguage.iso2Code}}
</button> </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)"> <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}}) <strong class="iso-code">{{language.iso2Code}}</strong> &nbsp; &nbsp; ({{language.englishName}})
</div> </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 { 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; } 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 { export class LanguageSelectorComponent implements OnChanges, OnInit {
public dropdown = new ModalView(false, true); public dropdown = new ModalModel();
@Input() @Input()
public size: string; public size: string;

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

@ -8,6 +8,6 @@
</div> </div>
</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> <sqx-assets-selector (selected)="onAssetsSelected($event)"></sqx-assets-selector>
</ng-container> </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 { import {
AssetDto, AssetDto,
ModalView, DialogModel,
ResourceLoaderService, ResourceLoaderService,
Types Types
} from '@app/shared/internal'; } from '@app/shared/internal';
@ -34,7 +34,7 @@ export class MarkdownEditorComponent implements ControlValueAccessor, AfterViewI
private value: string; private value: string;
private isDisabled = false; private isDisabled = false;
public selectorModal = new ModalView(); public assetsDialog = new DialogModel();
@ViewChild('editor') @ViewChild('editor')
public editor: ElementRef; public editor: ElementRef;
@ -79,7 +79,7 @@ export class MarkdownEditorComponent implements ControlValueAccessor, AfterViewI
} }
private showSelector = () => { private showSelector = () => {
this.selectorModal.show(); this.assetsDialog.show();
} }
public ngAfterViewInit() { public ngAfterViewInit() {
@ -206,6 +206,6 @@ export class MarkdownEditorComponent implements ControlValueAccessor, AfterViewI
this.simplemde.codemirror.replaceSelection(content); 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>
</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> <sqx-assets-selector (selected)="onAssetsSelected($event)"></sqx-assets-selector>
</ng-container> </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 { import {
AssetDto, AssetDto,
ModalView, DialogModel,
ResourceLoaderService, ResourceLoaderService,
Types Types
} from '@app/shared/internal'; } from '@app/shared/internal';
@ -35,7 +35,7 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit,
private value: string; private value: string;
private isDisabled = false; private isDisabled = false;
public selectorModal = new ModalView(); public assetsDialog = new DialogModel();
@ViewChild('editor') @ViewChild('editor')
public editor: ElementRef; public editor: ElementRef;
@ -63,7 +63,7 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit,
} }
private showSelector = () => { private showSelector = () => {
this.selectorModal.show(); this.assetsDialog.show();
} }
private getEditorOptions() { private getEditorOptions() {
@ -147,6 +147,6 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit,
this.tinyEditor.execCommand('mceInsertContent', false, content); 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 { of } from 'rxjs';
import { IMock, Mock, Times } from 'typemoq'; import { IMock, Mock, Times } from 'typemoq';
import { MathHelper } from '@app/framework';
import { SchemaDetailsDto } from './../services/schemas.service'; import { SchemaDetailsDto } from './../services/schemas.service';
import { SchemasState } from './../state/schemas.state'; import { SchemasState } from './../state/schemas.state';
import { SchemaMustExistPublishedGuard } from './schema-must-exist-published.guard'; import { SchemaMustExistPublishedGuard } from './schema-must-exist-published.guard';
@ -50,7 +48,7 @@ describe('SchemaMustExistPublishedGuard', () => {
it('should load schema and return false when not found', () => { it('should load schema and return false when not found', () => {
schemasState.setup(x => x.select('123')) schemasState.setup(x => x.select('123'))
.returns(() => of(<SchemaDetailsDto>{ isPublished: false })); .returns(() => of(<SchemaDetailsDto>{ isPublished: false }));
let result: boolean; let result: boolean;
@ -80,7 +78,7 @@ describe('SchemaMustExistPublishedGuard', () => {
it('should redirect to content when singleton', () => { it('should redirect to content when singleton', () => {
schemasState.setup(x => x.select('123')) schemasState.setup(x => x.select('123'))
.returns(() => of(<SchemaDetailsDto>{ isSingleton: true })); .returns(() => of(<SchemaDetailsDto>{ isSingleton: true, id: 'schema-id' }));
let result: boolean; let result: boolean;
@ -90,6 +88,6 @@ describe('SchemaMustExistPublishedGuard', () => {
expect(result!).toBeFalsy(); 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 { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators'; import { map, tap } from 'rxjs/operators';
import { allParams, MathHelper } from '@app/framework'; import { allParams } from '@app/framework';
import { SchemasState } from './../state/schemas.state'; import { SchemasState } from './../state/schemas.state';
@ -32,8 +32,8 @@ export class SchemaMustExistPublishedGuard implements CanActivate {
this.router.navigate(['/404']); this.router.navigate(['/404']);
} }
if (dto && dto.isSingleton && state.url.indexOf(MathHelper.EMPTY_GUID) < 0) { if (dto && dto.isSingleton && state.url.indexOf(dto.id) < 0) {
this.router.navigate([state.url, MathHelper.EMPTY_GUID]); this.router.navigate([state.url, dto.id]);
} }
}), }),
map(s => s !== null && s.isPublished)); map(s => s !== null && s.isPublished));

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

@ -11,7 +11,7 @@
</span> </span>
<ng-container *ngIf="appsState.apps | async; let apps"> <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"> <a class="dropdown-item all-apps" routerLink="/app">
<span class="all-apps-text">All Apps</span> <span class="all-apps-text">All Apps</span>
<span class="all-apps-pill badge badge-pill badge-primary">{{apps.length}}</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 { import {
AppsState, AppsState,
DialogModel,
fadeAnimation, fadeAnimation,
ModalView ModalModel
} from '@app/shared'; } from '@app/shared';
@Component({ @Component({
@ -22,9 +23,9 @@ import {
] ]
}) })
export class AppsMenuComponent { export class AppsMenuComponent {
public addAppDialog = new ModalView(); public addAppDialog = new DialogModel();
public appsMenu = new ModalView(false, true); public appsMenu = new ModalModel();
constructor( constructor(
public readonly appsState: AppsState public readonly appsState: AppsState

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

@ -16,10 +16,12 @@
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>
<a class="github-button" href="https://github.com/Squidex/squidex/issues" target="_blank"> <a class="support-button row no-gutters" href="https://support.squidex.io" target="_blank">
<i class="icon-github github-icon"></i> <div class="col col-auto support-icon">
<i class="icon-support"></i>
<span class="github-text">Github</span> </div>
</a>
<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; float: left;
} }
.github { $support-icon-size: 50px;
$support-text-size: 200px;
.support {
&-button { &-button {
& { & {
@include fixed(50%, -103px, auto, auto); @include fixed(50%, -$support-text-size, auto, auto);
@include border-radius-left(3px);
@include transition(transform .3s ease); @include transition(transform .3s ease);
background: lighten($color-extern-github, 10%); background: $color-theme-blue;
border: 0;
cursor: pointer;
color: $color-dark-foreground;
margin-top: -60px;
padding-left: 65px;
font-size: .9rem; font-size: .9rem;
font-weight: bold; font-weight: bold;
height: 44px; height: $support-icon-size;
line-height: 40px; line-break: normal;
width: 147px; line-height: $support-icon-size - 6px;
z-index: 1000000094; z-index: 100000000;
} }
&:hover { &:hover {
& { & {
@include translate(-103px, 0); @include translate(-$support-text-size, 0);
text-decoration: none; text-decoration: none;
} }
.github-icon { .support-icon {
background: $color-extern-github; background: $color-theme-blue-dark;
} }
} }
} }
&-icon,
&-text {
cursor: pointer;
color: $color-dark-foreground;
text-align: center;
}
&-text {
width: $support-text-size;
}
&-icon { &-icon {
@include absolute(0, auto, auto, 0);
@include border-radius-left(3px);
@include transition(background-color .4s ease); @include transition(background-color .4s ease);
background: lighten($color-extern-github, 10%); background: $color-theme-blue;
display: inline-block; line-height: $support-icon-size;
line-height: 44px;
font-size: 1.5rem; font-size: 1.5rem;
font-weight: normal; font-weight: normal;
width: 44px; width: $support-icon-size;
text-align: center;
color: $color-dark-foreground;
} }
} }

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

@ -8,7 +8,7 @@
</span> </span>
</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"> <a class="dropdown-item" routerLink="/app/administration" *ngIf="isAdmin">
Administration Administration
</a> </a>

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

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

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

@ -147,19 +147,19 @@ p {
font-size: 16px; font-size: 16px;
} }
.fs1 { .fs1 {
font-size: 32px; font-size: 24px;
} }
.fs2 { .fs2 {
font-size: 28px; font-size: 32px;
} }
.fs3 { .fs3 {
font-size: 32px; font-size: 28px;
} }
.fs4 { .fs4 {
font-size: 32px; font-size: 32px;
} }
.fs5 { .fs5 {
font-size: 24px; font-size: 32px;
} }
.fs6 { .fs6 {
font-size: 20px; 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="&#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="&#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="&#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="&#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="&#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" /> <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", "IcoMoonType": "selection",
"icons": [ "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": { "icon": {
"paths": [ "paths": [
@ -26,7 +113,7 @@
"code": 59737, "code": 59737,
"name": "action-Medium" "name": "action-Medium"
}, },
"setIdx": 0, "setIdx": 1,
"setId": 2, "setId": 2,
"iconIdx": 0 "iconIdx": 0
}, },
@ -55,7 +142,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59729 "code": 59729
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 44 "iconIdx": 44
}, },
@ -85,7 +172,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59726 "code": 59726
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 45 "iconIdx": 45
}, },
@ -117,7 +204,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59727 "code": 59727
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 46 "iconIdx": 46
}, },
@ -146,7 +233,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59724 "code": 59724
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 47 "iconIdx": 47
}, },
@ -184,7 +271,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59722 "code": 59722
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 48 "iconIdx": 48
}, },
@ -213,7 +300,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59652 "code": 59652
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 49 "iconIdx": 49
}, },
@ -242,7 +329,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59653 "code": 59653
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 50 "iconIdx": 50
}, },
@ -271,7 +358,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59654 "code": 59654
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 51 "iconIdx": 51
}, },
@ -300,7 +387,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59655 "code": 59655
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 52 "iconIdx": 52
}, },
@ -329,7 +416,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59656 "code": 59656
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 53 "iconIdx": 53
}, },
@ -358,7 +445,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59657 "code": 59657
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 54 "iconIdx": 54
}, },
@ -387,7 +474,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59658 "code": 59658
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 55 "iconIdx": 55
}, },
@ -416,7 +503,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59659 "code": 59659
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 56 "iconIdx": 56
}, },
@ -445,7 +532,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59660 "code": 59660
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 57 "iconIdx": 57
}, },
@ -474,7 +561,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59661 "code": 59661
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 58 "iconIdx": 58
}, },
@ -503,7 +590,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59662 "code": 59662
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 59 "iconIdx": 59
}, },
@ -532,7 +619,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59663 "code": 59663
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 60 "iconIdx": 60
}, },
@ -561,7 +648,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59664 "code": 59664
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 61 "iconIdx": 61
}, },
@ -596,7 +683,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59665 "code": 59665
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 62 "iconIdx": 62
}, },
@ -625,7 +712,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59666 "code": 59666
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 63 "iconIdx": 63
}, },
@ -654,7 +741,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59667 "code": 59667
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 64 "iconIdx": 64
}, },
@ -683,7 +770,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59668 "code": 59668
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 65 "iconIdx": 65
}, },
@ -712,7 +799,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59669 "code": 59669
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 66 "iconIdx": 66
}, },
@ -741,7 +828,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59670 "code": 59670
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 67 "iconIdx": 67
}, },
@ -770,7 +857,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59671 "code": 59671
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 68 "iconIdx": 68
}, },
@ -799,7 +886,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59672 "code": 59672
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 69 "iconIdx": 69
}, },
@ -829,7 +916,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59713 "code": 59713
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 70 "iconIdx": 70
}, },
@ -858,7 +945,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59673 "code": 59673
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 71 "iconIdx": 71
}, },
@ -887,7 +974,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59675 "code": 59675
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 72 "iconIdx": 72
}, },
@ -916,7 +1003,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59676 "code": 59676
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 73 "iconIdx": 73
}, },
@ -945,7 +1032,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59677 "code": 59677
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 74 "iconIdx": 74
}, },
@ -974,7 +1061,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59678 "code": 59678
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 75 "iconIdx": 75
}, },
@ -1003,7 +1090,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59679 "code": 59679
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 76 "iconIdx": 76
}, },
@ -1032,7 +1119,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59680 "code": 59680
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 77 "iconIdx": 77
}, },
@ -1070,7 +1157,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59681 "code": 59681
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 78 "iconIdx": 78
}, },
@ -1099,7 +1186,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59682 "code": 59682
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 79 "iconIdx": 79
}, },
@ -1128,7 +1215,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59683 "code": 59683
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 80 "iconIdx": 80
}, },
@ -1157,7 +1244,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59684 "code": 59684
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 81 "iconIdx": 81
}, },
@ -1186,7 +1273,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59685 "code": 59685
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 82 "iconIdx": 82
}, },
@ -1215,7 +1302,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59674 "code": 59674
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 83 "iconIdx": 83
}, },
@ -1244,7 +1331,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59686 "code": 59686
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 84 "iconIdx": 84
}, },
@ -1273,7 +1360,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59687 "code": 59687
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 85 "iconIdx": 85
}, },
@ -1302,7 +1389,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59688 "code": 59688
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 86 "iconIdx": 86
}, },
@ -1341,7 +1428,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59736 "code": 59736
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 0 "iconIdx": 0
}, },
@ -1383,7 +1470,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59735 "code": 59735
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 1 "iconIdx": 1
}, },
@ -1421,7 +1508,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59734 "code": 59734
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 3 "iconIdx": 3
}, },
@ -1451,7 +1538,7 @@
"code": 59733, "code": 59733,
"name": "exclamation" "name": "exclamation"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 4 "iconIdx": 4
}, },
@ -1481,7 +1568,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59730 "code": 59730
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 5 "iconIdx": 5
}, },
@ -1511,7 +1598,7 @@
"code": 59725, "code": 59725,
"name": "action-Slack" "name": "action-Slack"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 6 "iconIdx": 6
}, },
@ -1540,7 +1627,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59723 "code": 59723
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 7 "iconIdx": 7
}, },
@ -1572,7 +1659,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59721 "code": 59721
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 8 "iconIdx": 8
}, },
@ -1604,7 +1691,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59711 "code": 59711
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 9 "iconIdx": 9
}, },
@ -1634,7 +1721,7 @@
"code": 59648, "code": 59648,
"name": "angle-down" "name": "angle-down"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 10 "iconIdx": 10
}, },
@ -1664,7 +1751,7 @@
"code": 59649, "code": 59649,
"name": "angle-left" "name": "angle-left"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 11 "iconIdx": 11
}, },
@ -1694,7 +1781,7 @@
"code": 59697, "code": 59697,
"name": "angle-right" "name": "angle-right"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 12 "iconIdx": 12
}, },
@ -1724,7 +1811,7 @@
"code": 59651, "code": 59651,
"name": "angle-up" "name": "angle-up"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 13 "iconIdx": 13
}, },
@ -1765,7 +1852,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59717 "code": 59717
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 14 "iconIdx": 14
}, },
@ -1800,7 +1887,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59720 "code": 59720
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 15 "iconIdx": 15
}, },
@ -1830,7 +1917,7 @@
"code": 59709, "code": 59709,
"name": "bug" "name": "bug"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 16 "iconIdx": 16
}, },
@ -1860,7 +1947,7 @@
"code": 59692, "code": 59692,
"name": "caret-down" "name": "caret-down"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 17 "iconIdx": 17
}, },
@ -1890,7 +1977,7 @@
"code": 59690, "code": 59690,
"name": "caret-left" "name": "caret-left"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 18 "iconIdx": 18
}, },
@ -1920,7 +2007,7 @@
"code": 59689, "code": 59689,
"name": "caret-right" "name": "caret-right"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 19 "iconIdx": 19
}, },
@ -1950,7 +2037,7 @@
"code": 59691, "code": 59691,
"name": "caret-up" "name": "caret-up"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 20 "iconIdx": 20
}, },
@ -1988,7 +2075,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59718 "code": 59718
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 21 "iconIdx": 21
}, },
@ -2017,7 +2104,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59702 "code": 59702
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 22 "iconIdx": 22
}, },
@ -2046,7 +2133,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59703 "code": 59703
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 23 "iconIdx": 23
}, },
@ -2075,7 +2162,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59704 "code": 59704
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 24 "iconIdx": 24
}, },
@ -2102,7 +2189,7 @@
"prevSize": 28, "prevSize": 28,
"code": 61450 "code": 61450
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 25 "iconIdx": 25
}, },
@ -2131,7 +2218,7 @@
"prevSize": 28, "prevSize": 28,
"code": 61641 "code": 61641
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 26 "iconIdx": 26
}, },
@ -2160,7 +2247,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59698 "code": 59698
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 27 "iconIdx": 27
}, },
@ -2210,7 +2297,7 @@
"prevSize": 28, "prevSize": 28,
"code": 59719 "code": 59719
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 28 "iconIdx": 28
}, },
@ -2242,7 +2329,7 @@
"code": 59732, "code": 59732,
"name": "hour-glass" "name": "hour-glass"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 29 "iconIdx": 29
}, },
@ -2275,7 +2362,7 @@
"code": 59731, "code": 59731,
"name": "spinner" "name": "spinner"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 30 "iconIdx": 30
}, },
@ -2306,7 +2393,7 @@
"code": 59728, "code": 59728,
"name": "clock" "name": "clock"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 31 "iconIdx": 31
}, },
@ -2343,7 +2430,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59650 "code": 59650
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 32 "iconIdx": 32
}, },
@ -2376,7 +2463,7 @@
"prevSize": 32, "prevSize": 32,
"code": 59850 "code": 59850
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 33 "iconIdx": 33
}, },
@ -2409,7 +2496,7 @@
"code": 59715, "code": 59715,
"name": "elapsed" "name": "elapsed"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 34 "iconIdx": 34
}, },
@ -2439,7 +2526,7 @@
"code": 59707, "code": 59707,
"name": "google" "name": "google"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 35 "iconIdx": 35
}, },
@ -2471,7 +2558,7 @@
"code": 59700, "code": 59700,
"name": "lock" "name": "lock"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 36 "iconIdx": 36
}, },
@ -2502,7 +2589,7 @@
"code": 59712, "code": 59712,
"name": "microsoft, action-AzureQueue" "name": "microsoft, action-AzureQueue"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 37 "iconIdx": 37
}, },
@ -2532,7 +2619,7 @@
"code": 59695, "code": 59695,
"name": "pause" "name": "pause"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 38 "iconIdx": 38
}, },
@ -2562,7 +2649,7 @@
"code": 59696, "code": 59696,
"name": "play" "name": "play"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 39 "iconIdx": 39
}, },
@ -2601,7 +2688,7 @@
"code": 59694, "code": 59694,
"name": "reset" "name": "reset"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 40 "iconIdx": 40
}, },
@ -2636,7 +2723,7 @@
"code": 59693, "code": 59693,
"name": "settings2" "name": "settings2"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 41 "iconIdx": 41
}, },
@ -2670,7 +2757,7 @@
"code": 59716, "code": 59716,
"name": "timeout" "name": "timeout"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 42 "iconIdx": 42
}, },
@ -2700,7 +2787,7 @@
"code": 59699, "code": 59699,
"name": "unlocked" "name": "unlocked"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 43 "iconIdx": 43
}, },
@ -2733,7 +2820,7 @@
"code": 59701, "code": 59701,
"name": "browser" "name": "browser"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 87 "iconIdx": 87
}, },
@ -2765,7 +2852,7 @@
"code": 59714, "code": 59714,
"name": "checkmark" "name": "checkmark"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 88 "iconIdx": 88
}, },
@ -2795,68 +2882,10 @@
"code": 59706, "code": 59706,
"name": "control-Stars" "name": "control-Stars"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 89 "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": { "icon": {
"paths": [ "paths": [
@ -2882,7 +2911,7 @@
"code": 59708, "code": 59708,
"name": "info" "name": "info"
}, },
"setIdx": 1, "setIdx": 2,
"setId": 1, "setId": 1,
"iconIdx": 92 "iconIdx": 92
} }

67
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?o6u2w7'); src: url('fonts/icomoon.eot?lx1t7v');
src: url('fonts/icomoon.eot?o6u2w7#iefix') format('embedded-opentype'), src: url('fonts/icomoon.eot?lx1t7v#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?o6u2w7') format('truetype'), url('fonts/icomoon.ttf?lx1t7v') format('truetype'),
url('fonts/icomoon.woff?o6u2w7') format('woff'), url('fonts/icomoon.woff?lx1t7v') format('woff'),
url('fonts/icomoon.svg?o6u2w7#icomoon') format('svg'); url('fonts/icomoon.svg?lx1t7v#icomoon') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
@ -24,6 +24,15 @@
-moz-osx-font-smoothing: grayscale; -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 { .icon-action-Medium:before {
content: "\e959"; content: "\e959";
} }
@ -324,48 +333,6 @@
.icon-unlocked:before { .icon-unlocked:before {
content: "\e933"; 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 { .icon-browser:before {
content: "\e935"; content: "\e935";
} }
@ -375,12 +342,6 @@
.icon-control-Stars:before { .icon-control-Stars:before {
content: "\e93a"; content: "\e93a";
} }
.icon-control-RichText:before {
content: "\e939";
}
.icon-download:before {
content: "\e93e";
}
.icon-info:before { .icon-info:before {
content: "\e93c"; 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] [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); 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); GuardContent.CanCreate(schema, command);
} }

Loading…
Cancel
Save