();
+
+ @Input()
+ public query: Query;
+
+ @Input()
+ public language: LanguageDto;
+
+ public get metaFields() {
+ return MetaFields;
+ }
+
+ public get isSortable() {
+ return Types.is(this.field, RootFieldDto) ? this.field.properties.isSortable : false;
+ }
+
+ public get fieldName() {
+ return Types.is(this.field, RootFieldDto) ? this.field.name : this.field;
+ }
+
+ public get fieldDisplayName() {
+ return Types.is(this.field, RootFieldDto) ? this.field.displayName : '';
+ }
+
+ public get fieldPath() {
+ if (Types.isString(this.field)) {
+ return this.field;
+ } else if (this.field.isLocalizable && this.language) {
+ return `data.${this.field.name}.${this.language.iso2Code}`;
+ } else {
+ return `data.${this.field.name}.iv`;
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend/app/features/content/shared/list/content-value-editor.component.html b/frontend/app/features/content/shared/list/content-value-editor.component.html
new file mode 100644
index 000000000..b94b4ff30
--- /dev/null
+++ b/frontend/app/features/content/shared/list/content-value-editor.component.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{value}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{value}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/features/content/shared/list/content-value-editor.component.scss b/frontend/app/features/content/shared/list/content-value-editor.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/features/content/shared/list/content-value-editor.component.ts b/frontend/app/features/content/shared/list/content-value-editor.component.ts
new file mode 100644
index 000000000..233a58994
--- /dev/null
+++ b/frontend/app/features/content/shared/list/content-value-editor.component.ts
@@ -0,0 +1,25 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+
+import { FieldDto } from '@app/shared';
+
+@Component({
+ selector: 'sqx-content-value-editor',
+ styleUrls: ['./content-value-editor.component.scss'],
+ templateUrl: './content-value-editor.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class ContentValueEditorComponent {
+ @Input()
+ public field: FieldDto;
+
+ @Input()
+ public form: FormGroup;
+}
\ No newline at end of file
diff --git a/frontend/app/features/content/shared/list/content-value.component.html b/frontend/app/features/content/shared/list/content-value.component.html
new file mode 100644
index 000000000..7545608ed
--- /dev/null
+++ b/frontend/app/features/content/shared/list/content-value.component.html
@@ -0,0 +1,6 @@
+
+ {{value}}
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/features/content/shared/list/content-value.component.scss b/frontend/app/features/content/shared/list/content-value.component.scss
new file mode 100644
index 000000000..39752b104
--- /dev/null
+++ b/frontend/app/features/content/shared/list/content-value.component.scss
@@ -0,0 +1,14 @@
+:ng-deep {
+ .html-value {
+ img {
+ margin-top: -25px;
+ max-height: 50px;
+ min-height: 50px;
+ position: absolute;
+ }
+ }
+}
+
+.html-value {
+ position: relative;
+}
\ No newline at end of file
diff --git a/frontend/app/features/content/shared/list/content-value.component.ts b/frontend/app/features/content/shared/list/content-value.component.ts
new file mode 100644
index 000000000..51d5b18bb
--- /dev/null
+++ b/frontend/app/features/content/shared/list/content-value.component.ts
@@ -0,0 +1,25 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+
+import { HtmlValue, Types } from '@app/shared';
+
+@Component({
+ selector: 'sqx-content-value',
+ styleUrls: ['./content-value.component.scss'],
+ templateUrl: './content-value.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class ContentValueComponent {
+ @Input()
+ public value: any;
+
+ public get isPlain() {
+ return !Types.is(this.value, HtmlValue);
+ }
+}
\ No newline at end of file
diff --git a/frontend/app/features/content/shared/content.component.html b/frontend/app/features/content/shared/list/content.component.html
similarity index 88%
rename from frontend/app/features/content/shared/content.component.html
rename to frontend/app/features/content/shared/list/content.component.html
index a60669440..cc3604ca9 100644
--- a/frontend/app/features/content/shared/content.component.html
+++ b/frontend/app/features/content/shared/list/content.component.html
@@ -2,7 +2,7 @@
+ (ngModelChange)="selectedChange.emit($event)" />
@@ -28,4 +28,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/frontend/app/framework/angular/modals/modal-dialog.component.scss b/frontend/app/framework/angular/modals/modal-dialog.component.scss
index b0c4a1e0f..fd6e87b78 100644
--- a/frontend/app/framework/angular/modals/modal-dialog.component.scss
+++ b/frontend/app/framework/angular/modals/modal-dialog.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
.modal {
display: block;
}
diff --git a/frontend/app/framework/angular/modals/modal-dialog.component.ts b/frontend/app/framework/angular/modals/modal-dialog.component.ts
index eaa3411fb..8877839ec 100644
--- a/frontend/app/framework/angular/modals/modal-dialog.component.ts
+++ b/frontend/app/framework/angular/modals/modal-dialog.component.ts
@@ -78,8 +78,4 @@ export class ModalDialogComponent implements AfterViewInit {
}
}
}
-
- public emitClose() {
- this.close.emit();
- }
}
\ No newline at end of file
diff --git a/frontend/app/framework/angular/modals/onboarding-tooltip.component.scss b/frontend/app/framework/angular/modals/onboarding-tooltip.component.scss
index f29416548..13f9381e0 100644
--- a/frontend/app/framework/angular/modals/onboarding-tooltip.component.scss
+++ b/frontend/app/framework/angular/modals/onboarding-tooltip.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
$hide-shadow: rgba(0, 0, 0, .5);
.onboarding {
diff --git a/frontend/app/framework/angular/modals/root-view.component.html b/frontend/app/framework/angular/modals/root-view.component.html
new file mode 100644
index 000000000..56146ad9f
--- /dev/null
+++ b/frontend/app/framework/angular/modals/root-view.component.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/frontend/app/framework/angular/modals/root-view.component.scss b/frontend/app/framework/angular/modals/root-view.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/framework/angular/modals/root-view.component.ts b/frontend/app/framework/angular/modals/root-view.component.ts
index 6f306d703..5a53a9d79 100644
--- a/frontend/app/framework/angular/modals/root-view.component.ts
+++ b/frontend/app/framework/angular/modals/root-view.component.ts
@@ -9,11 +9,8 @@ import { ChangeDetectionStrategy, Component, ViewChild, ViewContainerRef } from
@Component({
selector: 'sqx-root-view',
- template: `
-
-
-
- `,
+ styleUrls: ['./root-view.component.scss'],
+ templateUrl: './root-view.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RootViewComponent {
diff --git a/frontend/app/framework/angular/pager.component.scss b/frontend/app/framework/angular/pager.component.scss
index e891b9183..af496b3dc 100644
--- a/frontend/app/framework/angular/pager.component.scss
+++ b/frontend/app/framework/angular/pager.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
.form-control {
display: inline-block;
margin-right: 2rem;
diff --git a/frontend/app/framework/angular/panel.component.html b/frontend/app/framework/angular/panel.component.html
index 7e5eebb42..74df578eb 100644
--- a/frontend/app/framework/angular/panel.component.html
+++ b/frontend/app/framework/angular/panel.component.html
@@ -18,7 +18,7 @@
-
+
diff --git a/frontend/app/framework/angular/panel.component.scss b/frontend/app/framework/angular/panel.component.scss
index 83949a038..acc0e5f5f 100644
--- a/frontend/app/framework/angular/panel.component.scss
+++ b/frontend/app/framework/angular/panel.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
.no-padding {
padding: 0;
}
\ No newline at end of file
diff --git a/frontend/app/framework/angular/panel.component.ts b/frontend/app/framework/angular/panel.component.ts
index ed62f38dc..94a9b3e32 100644
--- a/frontend/app/framework/angular/panel.component.ts
+++ b/frontend/app/framework/angular/panel.component.ts
@@ -143,8 +143,4 @@ export class PanelComponent implements AfterViewInit, OnChanges, OnDestroy, OnIn
}
}
}
-
- public emitClose() {
- this.close.emit();
- }
}
\ No newline at end of file
diff --git a/frontend/app/framework/angular/status-icon.component.scss b/frontend/app/framework/angular/status-icon.component.scss
index 25c837688..5aa11ffc4 100644
--- a/frontend/app/framework/angular/status-icon.component.scss
+++ b/frontend/app/framework/angular/status-icon.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
$circle-size-sm: 1.6rem;
$circle-size-lg: 2.8rem;
diff --git a/frontend/app/framework/declarations.ts b/frontend/app/framework/declarations.ts
index a9518ced4..f53416572 100644
--- a/frontend/app/framework/declarations.ts
+++ b/frontend/app/framework/declarations.ts
@@ -5,29 +5,30 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
-export * from './angular/forms/autocomplete.component';
-export * from './angular/forms/checkbox-group.component';
-export * from './angular/forms/code-editor.component';
-export * from './angular/forms/color-picker.component';
+export * from './angular/forms/editable-title.component';
+export * from './angular/forms/editors/autocomplete.component';
+export * from './angular/forms/editors/checkbox-group.component';
+export * from './angular/forms/editors/code-editor.component';
+export * from './angular/forms/editors/color-picker.component';
+export * from './angular/forms/editors/date-time-editor.component';
+export * from './angular/forms/editors/dropdown.component';
+export * from './angular/forms/editors/iframe-editor.component';
+export * from './angular/forms/editors/json-editor.component';
+export * from './angular/forms/editors/stars.component';
+export * from './angular/forms/editors/tag-editor.component';
+export * from './angular/forms/editors/toggle.component';
+
export * from './angular/forms/confirm-click.directive';
export * from './angular/forms/control-errors.component';
export * from './angular/forms/copy.directive';
-export * from './angular/forms/date-time-editor.component';
-export * from './angular/forms/dropdown.component';
-export * from './angular/forms/editable-title.component';
export * from './angular/forms/file-drop.directive';
export * from './angular/forms/focus-on-init.directive';
export * from './angular/forms/form-alert.component';
export * from './angular/forms/form-error.component';
export * from './angular/forms/form-hint.component';
export * from './angular/forms/forms-helper';
-export * from './angular/forms/iframe-editor.component';
export * from './angular/forms/indeterminate-value.directive';
-export * from './angular/forms/json-editor.component';
export * from './angular/forms/progress-bar.component';
-export * from './angular/forms/stars.component';
-export * from './angular/forms/tag-editor.component';
-export * from './angular/forms/toggle.component';
export * from './angular/forms/transform-input.directive';
export * from './angular/forms/validators';
diff --git a/frontend/app/framework/services/analytics.service.ts b/frontend/app/framework/services/analytics.service.ts
index 9bf3183c1..227898c06 100644
--- a/frontend/app/framework/services/analytics.service.ts
+++ b/frontend/app/framework/services/analytics.service.ts
@@ -5,6 +5,8 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
+// tslint:disable:only-arrow-functions
+
import { Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs/operators';
@@ -13,8 +15,6 @@ import { AnalyticsIdConfig } from './../configurations';
import { Types } from './../utils/types';
import { ResourceLoaderService } from './resource-loader.service';
-// tslint:disable:only-arrow-functions
-
export const AnalyticsServiceFactory = (analyticsId: AnalyticsIdConfig, router: Router, resourceLoader: ResourceLoaderService) => {
return new AnalyticsService(analyticsId, router, resourceLoader);
};
diff --git a/frontend/app/framework/utils/array-extensions.ts b/frontend/app/framework/utils/array-extensions.ts
index 7033e1d83..91d81aa70 100644
--- a/frontend/app/framework/utils/array-extensions.ts
+++ b/frontend/app/framework/utils/array-extensions.ts
@@ -1,4 +1,3 @@
-
/*
* Squidex Headless CMS
*
diff --git a/frontend/app/framework/utils/hateos.ts b/frontend/app/framework/utils/hateos.ts
index 9bc67ac10..09578404f 100644
--- a/frontend/app/framework/utils/hateos.ts
+++ b/frontend/app/framework/utils/hateos.ts
@@ -1,4 +1,3 @@
-
/*
* Squidex Headless CMS
*
diff --git a/frontend/app/framework/utils/picasso.ts b/frontend/app/framework/utils/picasso.ts
index 3bf9ecb7d..d3e444995 100644
--- a/frontend/app/framework/utils/picasso.ts
+++ b/frontend/app/framework/utils/picasso.ts
@@ -1,4 +1,11 @@
-import MersenneTwister from 'mersenne-twister';
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+ import MersenneTwister from 'mersenne-twister';
const ALL_COLORS: ReadonlyArray = [
'rgb(226,27,12)',
diff --git a/frontend/app/framework/utils/types.spec.ts b/frontend/app/framework/utils/types.spec.ts
index eeeef1153..fdd2edf34 100644
--- a/frontend/app/framework/utils/types.spec.ts
+++ b/frontend/app/framework/utils/types.spec.ts
@@ -5,16 +5,9 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
-import { mergeInto, Types } from './types';
+import { Types } from './types';
describe('Types', () => {
- it('should calculate hash string', () => {
- expect(Types.hash(null)).toBe('null');
- expect(Types.hash(undefined)).toBeUndefined();
-
- expect(Types.hash(new RegExp('.*'))).toEqual('{}');
- });
-
it('should make string check', () => {
expect(Types.isString('')).toBeTruthy();
expect(Types.isString('string')).toBeTruthy();
@@ -103,12 +96,6 @@ describe('Types', () => {
expect(Types.is(1, MyClass)).toBeFalsy();
});
- it('should make json equals check', () => {
- expect(Types.jsJsonEquals({ a: 1, b: 2 }, { a: 1, b: 2 })).toBeTruthy();
-
- expect(Types.jsJsonEquals({ a: 1, b: 2 }, { b: 2, a: 1 })).toBeFalsy();
- });
-
it('should not treat zero as empty', () => {
expect(Types.isEmpty(0)).toBeFalsy();
});
@@ -153,10 +140,83 @@ describe('Types', () => {
expect(Types.isEmpty({ a: null, b: null })).toBeTruthy();
});
+ it('should compare undefined', () => {
+ expect(Types.equals(undefined, undefined)).toBeTruthy();
+ });
+
+ it('should compare null', () => {
+ expect(Types.equals(null, null)).toBeTruthy();
+ });
+
+ it('should compare invalid', () => {
+ expect(Types.equals(null, undefined)).toBeFalsy();
+ });
+
+ it('should compare scalars', () => {
+ expect(Types.equals(1, false)).toBeFalsy();
+ expect(Types.equals(1, 2)).toBeFalsy();
+ expect(Types.equals(2, 2)).toBeTruthy();
+ });
+
+ it('should compare arrays', () => {
+ expect(Types.equals([1, 2], [2, 3])).toBeFalsy();
+ expect(Types.equals([1, 2], [1, 2])).toBeTruthy();
+ });
+
+ it('should compare objects', () => {
+ expect(Types.equals({ a: 1, b: 2 }, { a: 2, b: 3 })).toBeFalsy();
+ expect(Types.equals({ a: 1, b: 2 }, { a: 1, b: 2 })).toBeTruthy();
+ });
+
+ it('should compare nested objects', () => {
+ expect(Types.equals({ a: [1, 2] }, { a: [2, 3] })).toBeFalsy();
+ expect(Types.equals({ a: [1, 2] }, { a: [1, 2] })).toBeTruthy();
+ });
+
+ it('should clone array', () => {
+ const source = [1, 2, 3];
+ const result = Types.clone(source);
+
+ expect(result).toEqual(source);
+ expect(result).not.toBe(source);
+ });
+
+ it('should compare arrays', () => {
+ const source = 13;
+ const result = Types.clone(source);
+
+ expect(result).toEqual(source);
+ });
+
+ it('should clone value', () => {
+ const source = 13;
+ const result = Types.clone(source);
+
+ expect(result).toEqual(source);
+ });
+
+ it('should clone object', () => {
+ const source = { a: 1, b: 2 };
+ const result = Types.clone(source);
+
+ expect(result).toEqual(source);
+ expect(result).not.toBe(source);
+ });
+
+ it('should clone object of array', () => {
+ const source = { a: [1, 2], b: [3, 4] };
+ const result = Types.clone(source);
+
+ expect(result).toEqual(source);
+ expect(result).not.toBe(source);
+ expect(result.a).not.toBe(source.a);
+ expect(result.b).not.toBe(source.b);
+ });
+
it('should merge deeply', () => {
const source = {};
- mergeInto(source, {
+ Types.mergeInto(source, {
rootShared: 1,
rootA: 2,
nested: {
@@ -165,7 +225,7 @@ describe('Types', () => {
array: [4]
});
- mergeInto(source, {
+ Types.mergeInto(source, {
rootShared: 5,
rootB: 6,
nested: {
diff --git a/frontend/app/framework/utils/types.ts b/frontend/app/framework/utils/types.ts
index 090514083..5c40b4e35 100644
--- a/frontend/app/framework/utils/types.ts
+++ b/frontend/app/framework/utils/types.ts
@@ -8,14 +8,6 @@
// tslint:disable: readonly-array
export module Types {
- export function hash(value: any): string {
- try {
- return JSON.stringify(value);
- } catch (e) {
- return '';
- }
- }
-
export function isString(value: any): value is string {
return typeof value === 'string' || value instanceof String;
}
@@ -82,28 +74,6 @@ export module Types {
return true;
}
- export function jsJsonEquals(lhs: T, rhs: T) {
- return hash(lhs) === hash(rhs);
- }
-
- export function isEquals(lhs: ReadonlyArray, rhs: ReadonlyArray) {
- if (!lhs && !rhs) {
- return true;
- }
-
- if (lhs.length !== rhs.length) {
- return false;
- }
-
- for (let i = 0; i < lhs.length; i++) {
- if (rhs[i] !== lhs[i]) {
- return false;
- }
- }
-
- return true;
- }
-
export function isEmpty(value: any): boolean {
if (Types.isArray(value)) {
for (const v of value) {
@@ -129,25 +99,91 @@ export module Types {
return Types.isUndefined(value) === true || Types.isNull(value) === true;
}
-}
-export function mergeInto(target: object, source: object) {
- if (!Types.isObject(target) || !Types.isObject(source)) {
- return source;
+ export function clone(lhs: T): T {
+ const any: any = lhs;
+
+ if (Types.isArray(lhs)) {
+ const result = [];
+
+ for (let i = 0; i < lhs.length; i++) {
+ result[i] = clone(lhs[i]);
+ }
+
+ return result as any;
+ } else if (Types.isObject(lhs)) {
+ const result = {};
+
+ for (let key in any) {
+ if (any.hasOwnProperty(key)) {
+ result[key] = clone(lhs[key]);
+ }
+ }
+
+ return result as any;
+ }
+
+ return lhs;
}
- Object.keys(source).forEach(key => {
- const targetValue = target[key];
- const sourceValue = source[key];
+ export function equals(lhs: any, rhs: any) {
+ if (lhs === rhs || (lhs !== lhs && rhs !== rhs)) {
+ return true;
+ }
+
+ if (!lhs || !rhs) {
+ return false;
+ }
+
+ if (Types.isArray(lhs) && Types.isArray(rhs)) {
+ if (lhs.length !== rhs.length) {
+ return false;
+ }
+
+ for (let i = 0; i < lhs.length; i++) {
+ if (!equals(lhs[i], rhs[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ } else if (Types.isObject(lhs) && Types.isObject(rhs)) {
+ if (Object.keys(lhs).length !== Object.keys(rhs).length) {
+ return false;
+ }
- if (Types.isArray(targetValue) && Types.isArray(sourceValue)) {
- target[key] = targetValue.concat(sourceValue);
- } else if (Types.isObject(targetValue) && Types.isObject(sourceValue)) {
- target[key] = mergeInto({ ...targetValue }, sourceValue);
- } else {
- target[key] = sourceValue;
+ for (let key in lhs) {
+ if (lhs.hasOwnProperty(key)) {
+ if (!equals(lhs[key], rhs[key])) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ export function mergeInto(target: object, source: object) {
+ if (!Types.isObject(target) || !Types.isObject(source)) {
+ return source;
}
- });
- return target;
+ Object.keys(source).forEach(key => {
+ const targetValue = target[key];
+ const sourceValue = source[key];
+
+ if (Types.isArray(targetValue) && Types.isArray(sourceValue)) {
+ target[key] = targetValue.concat(sourceValue);
+ } else if (Types.isObject(targetValue) && Types.isObject(sourceValue)) {
+ target[key] = mergeInto({ ...targetValue }, sourceValue);
+ } else {
+ target[key] = sourceValue;
+ }
+ });
+
+ return target;
+ }
}
\ No newline at end of file
diff --git a/frontend/app/shared/components/app-form.component.scss b/frontend/app/shared/components/app-form.component.scss
index fbb752506..e69de29bb 100644
--- a/frontend/app/shared/components/app-form.component.scss
+++ b/frontend/app/shared/components/app-form.component.scss
@@ -1,2 +0,0 @@
-@import '_vars';
-@import '_mixins';
\ No newline at end of file
diff --git a/frontend/app/shared/components/asset-folder-form.component.scss b/frontend/app/shared/components/asset-folder-form.component.scss
deleted file mode 100644
index fbb752506..000000000
--- a/frontend/app/shared/components/asset-folder-form.component.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import '_vars';
-@import '_mixins';
\ No newline at end of file
diff --git a/frontend/app/shared/components/asset-path.component.ts b/frontend/app/shared/components/asset-path.component.ts
deleted file mode 100644
index 280b07889..000000000
--- a/frontend/app/shared/components/asset-path.component.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Squidex Headless CMS
- *
- * @license
- * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
- */
-
-import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
-
-import { AssetPathItem } from '@app/shared/internal';
-
-@Component({
- selector: 'sqx-asset-path',
- template: `
-
- Search Results
-
-
-
- 0">
-
-
- {{item.folderName}}
-
-
-
- `,
- styles: [`
- i {
- vertical-align: middle;
- }`
- ],
- changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class AssetPathComponent {
- @Output()
- public navigate = new EventEmitter();
-
- @Input()
- public path: ReadonlyArray;
-
- public emitNavigate(item: AssetPathItem) {
- this.navigate.emit(item);
- }
-}
\ No newline at end of file
diff --git a/frontend/app/shared/components/asset-dialog.component.html b/frontend/app/shared/components/assets/asset-dialog.component.html
similarity index 100%
rename from frontend/app/shared/components/asset-dialog.component.html
rename to frontend/app/shared/components/assets/asset-dialog.component.html
diff --git a/frontend/app/shared/components/asset-dialog.component.scss b/frontend/app/shared/components/assets/asset-dialog.component.scss
similarity index 84%
rename from frontend/app/shared/components/asset-dialog.component.scss
rename to frontend/app/shared/components/assets/asset-dialog.component.scss
index 845a0b88f..598de5f21 100644
--- a/frontend/app/shared/components/asset-dialog.component.scss
+++ b/frontend/app/shared/components/assets/asset-dialog.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.form-group {
position: relative;
}
diff --git a/frontend/app/shared/components/asset-dialog.component.ts b/frontend/app/shared/components/assets/asset-dialog.component.ts
similarity index 100%
rename from frontend/app/shared/components/asset-dialog.component.ts
rename to frontend/app/shared/components/assets/asset-dialog.component.ts
diff --git a/frontend/app/shared/components/asset-folder-form.component.html b/frontend/app/shared/components/assets/asset-folder-form.component.html
similarity index 100%
rename from frontend/app/shared/components/asset-folder-form.component.html
rename to frontend/app/shared/components/assets/asset-folder-form.component.html
diff --git a/frontend/app/shared/components/assets/asset-folder-form.component.scss b/frontend/app/shared/components/assets/asset-folder-form.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/asset-folder-form.component.ts b/frontend/app/shared/components/assets/asset-folder-form.component.ts
similarity index 100%
rename from frontend/app/shared/components/asset-folder-form.component.ts
rename to frontend/app/shared/components/assets/asset-folder-form.component.ts
diff --git a/frontend/app/shared/components/asset-folder.component.html b/frontend/app/shared/components/assets/asset-folder.component.html
similarity index 96%
rename from frontend/app/shared/components/asset-folder.component.html
rename to frontend/app/shared/components/assets/asset-folder.component.html
index b57b65cdc..d83490fc5 100644
--- a/frontend/app/shared/components/asset-folder.component.html
+++ b/frontend/app/shared/components/assets/asset-folder.component.html
@@ -25,7 +25,7 @@
Delete
diff --git a/frontend/app/shared/components/asset-folder.component.scss b/frontend/app/shared/components/assets/asset-folder.component.scss
similarity index 93%
rename from frontend/app/shared/components/asset-folder.component.scss
rename to frontend/app/shared/components/assets/asset-folder.component.scss
index 3de377410..dfff89a63 100644
--- a/frontend/app/shared/components/asset-folder.component.scss
+++ b/frontend/app/shared/components/assets/asset-folder.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
:host /deep/ {
.cdk-drag-placeholder {
display: none;
diff --git a/frontend/app/shared/components/asset-folder.component.ts b/frontend/app/shared/components/assets/asset-folder.component.ts
similarity index 94%
rename from frontend/app/shared/components/asset-folder.component.ts
rename to frontend/app/shared/components/assets/asset-folder.component.ts
index 240dcd4aa..f6c53afeb 100644
--- a/frontend/app/shared/components/asset-folder.component.ts
+++ b/frontend/app/shared/components/assets/asset-folder.component.ts
@@ -56,8 +56,4 @@ export class AssetFolderComponent {
public emitNavigate() {
this.navigate.emit(this.assetFolder);
}
-
- public emitDelete() {
- this.delete.emit(this.assetFolder);
- }
}
\ No newline at end of file
diff --git a/frontend/app/shared/components/assets/asset-path.component.html b/frontend/app/shared/components/assets/asset-path.component.html
new file mode 100644
index 000000000..864331291
--- /dev/null
+++ b/frontend/app/shared/components/assets/asset-path.component.html
@@ -0,0 +1,12 @@
+
+ Search Results
+
+
+
+ 0">
+
+
+ {{item.folderName}}
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/assets/asset-path.component.scss b/frontend/app/shared/components/assets/asset-path.component.scss
new file mode 100644
index 000000000..2ef6a98f9
--- /dev/null
+++ b/frontend/app/shared/components/assets/asset-path.component.scss
@@ -0,0 +1,3 @@
+i {
+ vertical-align: middle;
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/assets/asset-path.component.ts b/frontend/app/shared/components/assets/asset-path.component.ts
new file mode 100644
index 000000000..fbba57145
--- /dev/null
+++ b/frontend/app/shared/components/assets/asset-path.component.ts
@@ -0,0 +1,24 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { AssetPathItem } from '@app/shared/internal';
+
+@Component({
+ selector: 'sqx-asset-path',
+ styleUrls: ['./asset-path.component.scss'],
+ templateUrl: './asset-path.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class AssetPathComponent {
+ @Output()
+ public navigate = new EventEmitter();
+
+ @Input()
+ public path: ReadonlyArray;
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/asset-uploader.component.html b/frontend/app/shared/components/assets/asset-uploader.component.html
similarity index 100%
rename from frontend/app/shared/components/asset-uploader.component.html
rename to frontend/app/shared/components/assets/asset-uploader.component.html
diff --git a/frontend/app/shared/components/asset-uploader.component.scss b/frontend/app/shared/components/assets/asset-uploader.component.scss
similarity index 97%
rename from frontend/app/shared/components/asset-uploader.component.scss
rename to frontend/app/shared/components/assets/asset-uploader.component.scss
index 5dea7b1e5..f25e8d02d 100644
--- a/frontend/app/shared/components/asset-uploader.component.scss
+++ b/frontend/app/shared/components/assets/asset-uploader.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.icon-upload-3 {
font-size: 1.4rem;
font-weight: lighter;
diff --git a/frontend/app/shared/components/asset-uploader.component.ts b/frontend/app/shared/components/assets/asset-uploader.component.ts
similarity index 95%
rename from frontend/app/shared/components/asset-uploader.component.ts
rename to frontend/app/shared/components/assets/asset-uploader.component.ts
index 4bd64fe44..a391f59ec 100644
--- a/frontend/app/shared/components/asset-uploader.component.ts
+++ b/frontend/app/shared/components/assets/asset-uploader.component.ts
@@ -15,7 +15,7 @@ import {
Upload
} from '@app/shared/internal';
-import { AppsState } from './../state/apps.state';
+import { AppsState } from '@app/shared/internal';
@Component({
selector: 'sqx-asset-uploader',
diff --git a/frontend/app/shared/components/asset.component.html b/frontend/app/shared/components/assets/asset.component.html
similarity index 94%
rename from frontend/app/shared/components/asset.component.html
rename to frontend/app/shared/components/assets/asset.component.html
index 13188bff4..bcdd6cf2f 100644
--- a/frontend/app/shared/components/asset.component.html
+++ b/frontend/app/shared/components/assets/asset.component.html
@@ -1,5 +1,5 @@
-
@@ -84,7 +84,7 @@
-
@@ -126,12 +126,12 @@
-
+
diff --git a/frontend/app/shared/components/asset.component.scss b/frontend/app/shared/components/assets/asset.component.scss
similarity index 99%
rename from frontend/app/shared/components/asset.component.scss
rename to frontend/app/shared/components/assets/asset.component.scss
index 3c8972d14..d6f664f43 100644
--- a/frontend/app/shared/components/asset.component.scss
+++ b/frontend/app/shared/components/assets/asset.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
// sass-lint:disable single-line-per-selector
$list-height: 2.25rem;
diff --git a/frontend/app/shared/components/asset.component.ts b/frontend/app/shared/components/assets/asset.component.ts
similarity index 94%
rename from frontend/app/shared/components/asset.component.ts
rename to frontend/app/shared/components/assets/asset.component.ts
index c2fc2cdf1..6e17c0f9a 100644
--- a/frontend/app/shared/components/asset.component.ts
+++ b/frontend/app/shared/components/assets/asset.component.ts
@@ -134,14 +134,6 @@ export class AssetComponent implements OnInit {
}
}
- public emitSelect() {
- this.select.emit(this.asset);
- }
-
- public emitDelete() {
- this.delete.emit(this.asset);
- }
-
public emitLoad(asset: AssetDto) {
this.load.emit(asset);
}
@@ -150,10 +142,6 @@ export class AssetComponent implements OnInit {
this.loadError.emit(error);
}
- public emitRemove() {
- this.remove.emit();
- }
-
private setProgress(progress: number) {
this.progress = progress;
diff --git a/frontend/app/shared/components/assets-list.component.html b/frontend/app/shared/components/assets/assets-list.component.html
similarity index 98%
rename from frontend/app/shared/components/assets-list.component.html
rename to frontend/app/shared/components/assets/assets-list.component.html
index f4576152b..bfbc16352 100644
--- a/frontend/app/shared/components/assets-list.component.html
+++ b/frontend/app/shared/components/assets/assets-list.component.html
@@ -80,7 +80,7 @@
[isSelectable]="!!selectedIds"
[isSelected]="isSelected(asset)"
[allTags]="tags"
- (select)="emitSelect(asset)"
+ (select)="select.emit(asset)"
(delete)="deleteAsset(asset)">
diff --git a/frontend/app/shared/components/assets-list.component.scss b/frontend/app/shared/components/assets/assets-list.component.scss
similarity index 97%
rename from frontend/app/shared/components/assets-list.component.scss
rename to frontend/app/shared/components/assets/assets-list.component.scss
index 90ab88f68..19e12c089 100644
--- a/frontend/app/shared/components/assets-list.component.scss
+++ b/frontend/app/shared/components/assets/assets-list.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.unrow {
display: block;
}
diff --git a/frontend/app/shared/components/assets-list.component.ts b/frontend/app/shared/components/assets/assets-list.component.ts
similarity index 97%
rename from frontend/app/shared/components/assets-list.component.ts
rename to frontend/app/shared/components/assets/assets-list.component.ts
index ec4d3bff0..ff6432500 100644
--- a/frontend/app/shared/components/assets-list.component.ts
+++ b/frontend/app/shared/components/assets/assets-list.component.ts
@@ -85,10 +85,6 @@ export class AssetsListComponent {
this.state.deleteAssetFolder(assetFolder);
}
- public emitSelect(asset: AssetDto) {
- this.select.emit(asset);
- }
-
public isSelected(asset: AssetDto) {
return this.selectedIds && this.selectedIds[asset.id];
}
diff --git a/frontend/app/shared/components/assets-selector.component.html b/frontend/app/shared/components/assets/assets-selector.component.html
similarity index 100%
rename from frontend/app/shared/components/assets-selector.component.html
rename to frontend/app/shared/components/assets/assets-selector.component.html
diff --git a/frontend/app/shared/components/assets-selector.component.scss b/frontend/app/shared/components/assets/assets-selector.component.scss
similarity index 92%
rename from frontend/app/shared/components/assets-selector.component.scss
rename to frontend/app/shared/components/assets/assets-selector.component.scss
index 1a6127d3a..e13db9d58 100644
--- a/frontend/app/shared/components/assets-selector.component.scss
+++ b/frontend/app/shared/components/assets/assets-selector.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
:host ::ng-deep {
.search {
.form-control {
diff --git a/frontend/app/shared/components/assets-selector.component.ts b/frontend/app/shared/components/assets/assets-selector.component.ts
similarity index 100%
rename from frontend/app/shared/components/assets-selector.component.ts
rename to frontend/app/shared/components/assets/assets-selector.component.ts
diff --git a/frontend/app/shared/components/assets/pipes.ts b/frontend/app/shared/components/assets/pipes.ts
new file mode 100644
index 000000000..154046a96
--- /dev/null
+++ b/frontend/app/shared/components/assets/pipes.ts
@@ -0,0 +1,75 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { Pipe, PipeTransform } from '@angular/core';
+
+import {
+ ApiUrlConfig,
+ AssetDto,
+ MathHelper
+} from '@app/shared/internal';
+
+@Pipe({
+ name: 'sqxAssetUrl',
+ pure: true
+})
+export class AssetUrlPipe implements PipeTransform {
+ constructor(
+ private readonly apiUrl: ApiUrlConfig
+ ) {
+ }
+
+ public transform(asset: AssetDto): string {
+ return `${asset.fullUrl(this.apiUrl)}&sq=${MathHelper.guid()}`;
+ }
+}
+
+@Pipe({
+ name: 'sqxAssetPreviewUrl',
+ pure: true
+})
+export class AssetPreviewUrlPipe implements PipeTransform {
+ constructor(
+ private readonly apiUrl: ApiUrlConfig
+ ) {
+ }
+
+ public transform(asset: AssetDto): string {
+ return asset.fullUrl(this.apiUrl);
+ }
+}
+
+@Pipe({
+ name: 'sqxFileIcon',
+ pure: true
+})
+export class FileIconPipe implements PipeTransform {
+ public transform(asset: { mimeType: string, fileType: string }): string {
+ const knownTypes = [
+ 'doc',
+ 'docx',
+ 'pdf',
+ 'ppt',
+ 'pptx',
+ 'video',
+ 'xls',
+ 'xlsx'
+ ];
+
+ let mimeIcon: string;
+
+ const mimeParts = asset.mimeType.split('/');
+
+ if (mimeParts.length === 2 && mimeParts[0].toLowerCase() === 'video') {
+ mimeIcon = 'video';
+ } else {
+ mimeIcon = knownTypes.indexOf(asset.fileType) >= 0 ? asset.fileType : 'generic';
+ }
+
+ return `./images/asset_${mimeIcon}.svg`;
+ }
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/comment.component.html b/frontend/app/shared/components/comments/comment.component.html
similarity index 95%
rename from frontend/app/shared/components/comment.component.html
rename to frontend/app/shared/components/comments/comment.component.html
index 09abf1940..15415a663 100644
--- a/frontend/app/shared/components/comment.component.html
+++ b/frontend/app/shared/components/comments/comment.component.html
@@ -21,7 +21,7 @@
diff --git a/frontend/app/shared/components/comment.component.scss b/frontend/app/shared/components/comments/comment.component.scss
similarity index 95%
rename from frontend/app/shared/components/comment.component.scss
rename to frontend/app/shared/components/comments/comment.component.scss
index 558871db7..39a0c7449 100644
--- a/frontend/app/shared/components/comment.component.scss
+++ b/frontend/app/shared/components/comments/comment.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.item-remove {
@include absolute(-5px, -15px, auto, auto);
display: none;
diff --git a/frontend/app/shared/components/comment.component.ts b/frontend/app/shared/components/comments/comment.component.ts
similarity index 92%
rename from frontend/app/shared/components/comment.component.ts
rename to frontend/app/shared/components/comments/comment.component.ts
index 4e3971005..4be80932f 100644
--- a/frontend/app/shared/components/comment.component.ts
+++ b/frontend/app/shared/components/comments/comment.component.ts
@@ -33,8 +33,4 @@ export class CommentComponent {
@Input()
public userToken: string;
-
- public emitDelete() {
- this.delete.emit();
- }
}
\ No newline at end of file
diff --git a/frontend/app/shared/components/comments.component.html b/frontend/app/shared/components/comments/comments.component.html
similarity index 100%
rename from frontend/app/shared/components/comments.component.html
rename to frontend/app/shared/components/comments/comments.component.html
diff --git a/frontend/app/shared/components/comments.component.scss b/frontend/app/shared/components/comments/comments.component.scss
similarity index 93%
rename from frontend/app/shared/components/comments.component.scss
rename to frontend/app/shared/components/comments/comments.component.scss
index 86700a24a..3e92a30a4 100644
--- a/frontend/app/shared/components/comments.component.scss
+++ b/frontend/app/shared/components/comments/comments.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
:host ::ng-deep {
.mention-menu {
border-color: $color-border !important;
diff --git a/frontend/app/shared/components/comments.component.ts b/frontend/app/shared/components/comments/comments.component.ts
similarity index 100%
rename from frontend/app/shared/components/comments.component.ts
rename to frontend/app/shared/components/comments/comments.component.ts
diff --git a/frontend/app/shared/components/geolocation-editor.component.html b/frontend/app/shared/components/forms/geolocation-editor.component.html
similarity index 100%
rename from frontend/app/shared/components/geolocation-editor.component.html
rename to frontend/app/shared/components/forms/geolocation-editor.component.html
diff --git a/frontend/app/shared/components/geolocation-editor.component.scss b/frontend/app/shared/components/forms/geolocation-editor.component.scss
similarity index 88%
rename from frontend/app/shared/components/geolocation-editor.component.scss
rename to frontend/app/shared/components/forms/geolocation-editor.component.scss
index 1e55176c4..54f3bfbd1 100644
--- a/frontend/app/shared/components/geolocation-editor.component.scss
+++ b/frontend/app/shared/components/forms/geolocation-editor.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
.editor {
height: 30rem;
}
diff --git a/frontend/app/shared/components/geolocation-editor.component.ts b/frontend/app/shared/components/forms/geolocation-editor.component.ts
similarity index 99%
rename from frontend/app/shared/components/geolocation-editor.component.ts
rename to frontend/app/shared/components/forms/geolocation-editor.component.ts
index 3763f4391..bf054568b 100644
--- a/frontend/app/shared/components/geolocation-editor.component.ts
+++ b/frontend/app/shared/components/forms/geolocation-editor.component.ts
@@ -39,7 +39,9 @@ type UpdateOptions = { reset?: boolean; pan?: true; fire?: boolean };
selector: 'sqx-geolocation-editor',
styleUrls: ['./geolocation-editor.component.scss'],
templateUrl: './geolocation-editor.component.html',
- providers: [SQX_GEOLOCATION_EDITOR_CONTROL_VALUE_ACCESSOR],
+ providers: [
+ SQX_GEOLOCATION_EDITOR_CONTROL_VALUE_ACCESSOR
+ ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GeolocationEditorComponent extends StatefulControlComponent implements AfterViewInit {
diff --git a/frontend/app/shared/components/language-selector.component.html b/frontend/app/shared/components/forms/language-selector.component.html
similarity index 100%
rename from frontend/app/shared/components/language-selector.component.html
rename to frontend/app/shared/components/forms/language-selector.component.html
diff --git a/frontend/app/shared/components/language-selector.component.scss b/frontend/app/shared/components/forms/language-selector.component.scss
similarity index 82%
rename from frontend/app/shared/components/language-selector.component.scss
rename to frontend/app/shared/components/forms/language-selector.component.scss
index 2281e1a3e..11a2b2fe5 100644
--- a/frontend/app/shared/components/language-selector.component.scss
+++ b/frontend/app/shared/components/forms/language-selector.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.dropdown-item {
cursor: pointer;
}
diff --git a/frontend/app/shared/components/language-selector.component.ts b/frontend/app/shared/components/forms/language-selector.component.ts
similarity index 93%
rename from frontend/app/shared/components/language-selector.component.ts
rename to frontend/app/shared/components/forms/language-selector.component.ts
index 651fb34b1..c649ef4fd 100644
--- a/frontend/app/shared/components/language-selector.component.ts
+++ b/frontend/app/shared/components/forms/language-selector.component.ts
@@ -7,8 +7,11 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
-import { fadeAnimation, ModalModel } from '@app/shared/internal';
-import { LanguageDto } from '../services/languages.service';
+import {
+ fadeAnimation,
+ LanguageDto,
+ ModalModel
+} from '@app/shared/internal';
export interface Language { iso2Code: string; englishName: string; isMasterLanguage: true; }
diff --git a/frontend/app/shared/components/markdown-editor.component.html b/frontend/app/shared/components/forms/markdown-editor.component.html
similarity index 100%
rename from frontend/app/shared/components/markdown-editor.component.html
rename to frontend/app/shared/components/forms/markdown-editor.component.html
diff --git a/frontend/app/shared/components/markdown-editor.component.scss b/frontend/app/shared/components/forms/markdown-editor.component.scss
similarity index 83%
rename from frontend/app/shared/components/markdown-editor.component.scss
rename to frontend/app/shared/components/forms/markdown-editor.component.scss
index 0f012abd6..685346310 100644
--- a/frontend/app/shared/components/markdown-editor.component.scss
+++ b/frontend/app/shared/components/forms/markdown-editor.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
$background: #fff;
:host ::ng-deep {
diff --git a/frontend/app/shared/components/markdown-editor.component.ts b/frontend/app/shared/components/forms/markdown-editor.component.ts
similarity index 99%
rename from frontend/app/shared/components/markdown-editor.component.ts
rename to frontend/app/shared/components/forms/markdown-editor.component.ts
index 2ce0e7b8b..c3fa7fb70 100644
--- a/frontend/app/shared/components/markdown-editor.component.ts
+++ b/frontend/app/shared/components/forms/markdown-editor.component.ts
@@ -34,7 +34,9 @@ interface State {
selector: 'sqx-markdown-editor',
styleUrls: ['./markdown-editor.component.scss'],
templateUrl: './markdown-editor.component.html',
- providers: [SQX_MARKDOWN_EDITOR_CONTROL_VALUE_ACCESSOR],
+ providers: [
+ SQX_MARKDOWN_EDITOR_CONTROL_VALUE_ACCESSOR
+ ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MarkdownEditorComponent extends StatefulControlComponent implements AfterViewInit {
diff --git a/frontend/app/shared/components/forms/references-dropdown.component.html b/frontend/app/shared/components/forms/references-dropdown.component.html
new file mode 100644
index 000000000..0d42c4076
--- /dev/null
+++ b/frontend/app/shared/components/forms/references-dropdown.component.html
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/forms/references-dropdown.component.scss b/frontend/app/shared/components/forms/references-dropdown.component.scss
new file mode 100644
index 000000000..103b9730a
--- /dev/null
+++ b/frontend/app/shared/components/forms/references-dropdown.component.scss
@@ -0,0 +1,3 @@
+.truncate {
+ min-height: 1.5rem;
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/references-dropdown.component.ts b/frontend/app/shared/components/forms/references-dropdown.component.ts
similarity index 91%
rename from frontend/app/shared/components/references-dropdown.component.ts
rename to frontend/app/shared/components/forms/references-dropdown.component.ts
index 72b801699..9c652714e 100644
--- a/frontend/app/shared/components/references-dropdown.component.ts
+++ b/frontend/app/shared/components/forms/references-dropdown.component.ts
@@ -36,19 +36,11 @@ const NO_EMIT = { emitEvent: false };
@Component({
selector: 'sqx-references-dropdown',
- template: `
-
-
-
-
-
- `,
- styles: [`
- .truncate {
- min-height: 1.5rem;
- }`
+ styleUrls: ['./references-dropdown.component.scss'],
+ templateUrl: './references-dropdown.component.html',
+ providers: [
+ SQX_REFERENCES_DROPDOWN_CONTROL_VALUE_ACCESSOR
],
- providers: [SQX_REFERENCES_DROPDOWN_CONTROL_VALUE_ACCESSOR],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ReferencesDropdownComponent extends StatefulControlComponent | string> implements OnChanges {
diff --git a/frontend/app/shared/components/forms/references-tags.component.html b/frontend/app/shared/components/forms/references-tags.component.html
new file mode 100644
index 000000000..d501ef9a4
--- /dev/null
+++ b/frontend/app/shared/components/forms/references-tags.component.html
@@ -0,0 +1,3 @@
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/forms/references-tags.component.scss b/frontend/app/shared/components/forms/references-tags.component.scss
new file mode 100644
index 000000000..103b9730a
--- /dev/null
+++ b/frontend/app/shared/components/forms/references-tags.component.scss
@@ -0,0 +1,3 @@
+.truncate {
+ min-height: 1.5rem;
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/references-tags.component.ts b/frontend/app/shared/components/forms/references-tags.component.ts
similarity index 92%
rename from frontend/app/shared/components/references-tags.component.ts
rename to frontend/app/shared/components/forms/references-tags.component.ts
index cb67ed841..0f4280f2f 100644
--- a/frontend/app/shared/components/references-tags.component.ts
+++ b/frontend/app/shared/components/forms/references-tags.component.ts
@@ -71,17 +71,11 @@ interface State {
@Component({
selector: 'sqx-references-tags',
- template: `
-
-
- `,
- styles: [`
- .truncate {
- min-height: 1.5rem;
- }`
+ styleUrls: ['./references-tags.component.scss'],
+ templateUrl: './references-tags.component.html',
+ providers: [
+ SQX_REFERENCES_TAGS_CONTROL_VALUE_ACCESSOR
],
- providers: [SQX_REFERENCES_TAGS_CONTROL_VALUE_ACCESSOR],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ReferencesTagsComponent extends StatefulControlComponent> implements OnChanges {
diff --git a/frontend/app/shared/components/rich-editor.component.html b/frontend/app/shared/components/forms/rich-editor.component.html
similarity index 100%
rename from frontend/app/shared/components/rich-editor.component.html
rename to frontend/app/shared/components/forms/rich-editor.component.html
diff --git a/frontend/app/shared/components/rich-editor.component.scss b/frontend/app/shared/components/forms/rich-editor.component.scss
similarity index 65%
rename from frontend/app/shared/components/rich-editor.component.scss
rename to frontend/app/shared/components/forms/rich-editor.component.scss
index 401bc5174..019b776fd 100644
--- a/frontend/app/shared/components/rich-editor.component.scss
+++ b/frontend/app/shared/components/forms/rich-editor.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
.drop-container {
min-height: 401px;
}
diff --git a/frontend/app/shared/components/rich-editor.component.ts b/frontend/app/shared/components/forms/rich-editor.component.ts
similarity index 99%
rename from frontend/app/shared/components/rich-editor.component.ts
rename to frontend/app/shared/components/forms/rich-editor.component.ts
index 216272047..c603a1bc5 100644
--- a/frontend/app/shared/components/rich-editor.component.ts
+++ b/frontend/app/shared/components/forms/rich-editor.component.ts
@@ -38,7 +38,9 @@ const ImageTypes: ReadonlyArray = [
selector: 'sqx-rich-editor',
styleUrls: ['./rich-editor.component.scss'],
templateUrl: './rich-editor.component.html',
- providers: [SQX_RICH_EDITOR_CONTROL_VALUE_ACCESSOR],
+ providers: [
+ SQX_RICH_EDITOR_CONTROL_VALUE_ACCESSOR
+ ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RichEditorComponent extends StatefulControlComponent implements AfterViewInit, OnDestroy {
diff --git a/frontend/app/shared/components/help.component.scss b/frontend/app/shared/components/help.component.scss
deleted file mode 100644
index fbb752506..000000000
--- a/frontend/app/shared/components/help.component.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import '_vars';
-@import '_mixins';
\ No newline at end of file
diff --git a/frontend/app/shared/components/help-markdown.pipe.spec.ts b/frontend/app/shared/components/help/help-markdown.pipe.spec.ts
similarity index 100%
rename from frontend/app/shared/components/help-markdown.pipe.spec.ts
rename to frontend/app/shared/components/help/help-markdown.pipe.spec.ts
diff --git a/frontend/app/shared/components/help-markdown.pipe.ts b/frontend/app/shared/components/help/help-markdown.pipe.ts
similarity index 100%
rename from frontend/app/shared/components/help-markdown.pipe.ts
rename to frontend/app/shared/components/help/help-markdown.pipe.ts
diff --git a/frontend/app/shared/components/help.component.html b/frontend/app/shared/components/help/help.component.html
similarity index 100%
rename from frontend/app/shared/components/help.component.html
rename to frontend/app/shared/components/help/help.component.html
diff --git a/frontend/app/shared/components/help/help.component.scss b/frontend/app/shared/components/help/help.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/help.component.ts b/frontend/app/shared/components/help/help.component.ts
similarity index 100%
rename from frontend/app/shared/components/help.component.ts
rename to frontend/app/shared/components/help/help.component.ts
diff --git a/frontend/app/shared/components/history.component.scss b/frontend/app/shared/components/history.component.scss
deleted file mode 100644
index fbb752506..000000000
--- a/frontend/app/shared/components/history.component.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import '_vars';
-@import '_mixins';
\ No newline at end of file
diff --git a/frontend/app/shared/components/history-list.component.html b/frontend/app/shared/components/history/history-list.component.html
similarity index 100%
rename from frontend/app/shared/components/history-list.component.html
rename to frontend/app/shared/components/history/history-list.component.html
diff --git a/frontend/app/shared/components/history-list.component.scss b/frontend/app/shared/components/history/history-list.component.scss
similarity index 91%
rename from frontend/app/shared/components/history-list.component.scss
rename to frontend/app/shared/components/history/history-list.component.scss
index 8661d69ba..4259fe2f0 100644
--- a/frontend/app/shared/components/history-list.component.scss
+++ b/frontend/app/shared/components/history/history-list.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
:host ::ng-deep {
.user-ref {
font-weight: 500;
diff --git a/frontend/app/shared/components/history-list.component.ts b/frontend/app/shared/components/history/history-list.component.ts
similarity index 100%
rename from frontend/app/shared/components/history-list.component.ts
rename to frontend/app/shared/components/history/history-list.component.ts
diff --git a/frontend/app/shared/components/history.component.html b/frontend/app/shared/components/history/history.component.html
similarity index 100%
rename from frontend/app/shared/components/history.component.html
rename to frontend/app/shared/components/history/history.component.html
diff --git a/frontend/app/shared/components/history/history.component.scss b/frontend/app/shared/components/history/history.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/history.component.ts b/frontend/app/shared/components/history/history.component.ts
similarity index 100%
rename from frontend/app/shared/components/history.component.ts
rename to frontend/app/shared/components/history/history.component.ts
diff --git a/frontend/app/shared/components/history/pipes.ts b/frontend/app/shared/components/history/pipes.ts
new file mode 100644
index 000000000..57e896769
--- /dev/null
+++ b/frontend/app/shared/components/history/pipes.ts
@@ -0,0 +1,61 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+// tslint:disable:no-pipe-impure
+
+import { ChangeDetectorRef, OnDestroy, Pipe, PipeTransform } from '@angular/core';
+import { Subscription } from 'rxjs';
+
+import {
+ formatHistoryMessage,
+ HistoryEventDto,
+ UsersProviderService
+} from '@app/shared/internal';
+
+@Pipe({
+ name: 'sqxHistoryMessage',
+ pure: false
+})
+export class HistoryMessagePipe implements OnDestroy, PipeTransform {
+ private subscription: Subscription;
+ private lastMessage: string;
+ private lastValue: string | null = null;
+
+ constructor(
+ private readonly changeDetector: ChangeDetectorRef,
+ private readonly users: UsersProviderService
+ ) {
+ }
+
+ public ngOnDestroy() {
+ if (this.subscription) {
+ this.subscription.unsubscribe();
+ }
+ }
+
+ public transform(event: HistoryEventDto): string | null {
+ if (!event) {
+ return this.lastValue;
+ }
+
+ if (this.lastMessage !== event.message) {
+ this.lastMessage = event.message;
+
+ if (this.subscription) {
+ this.subscription.unsubscribe();
+ }
+
+ this.subscription = formatHistoryMessage(event.message, this.users).subscribe(value => {
+ this.lastValue = value;
+
+ this.changeDetector.markForCheck();
+ });
+ }
+
+ return this.lastValue;
+ }
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/pipes.ts b/frontend/app/shared/components/pipes.ts
index 00f9c32ff..37c0fec96 100644
--- a/frontend/app/shared/components/pipes.ts
+++ b/frontend/app/shared/components/pipes.ts
@@ -13,58 +13,10 @@ import { map } from 'rxjs/operators';
import {
ApiUrlConfig,
- AssetDto,
- formatHistoryMessage,
- HistoryEventDto,
- MathHelper,
UserDto,
UsersProviderService
} from '@app/shared/internal';
-@Pipe({
- name: 'sqxHistoryMessage',
- pure: false
-})
-export class HistoryMessagePipe implements OnDestroy, PipeTransform {
- private subscription: Subscription;
- private lastMessage: string;
- private lastValue: string | null = null;
-
- constructor(
- private readonly changeDetector: ChangeDetectorRef,
- private readonly users: UsersProviderService
- ) {
- }
-
- public ngOnDestroy() {
- if (this.subscription) {
- this.subscription.unsubscribe();
- }
- }
-
- public transform(event: HistoryEventDto): string | null {
- if (!event) {
- return this.lastValue;
- }
-
- if (this.lastMessage !== event.message) {
- this.lastMessage = event.message;
-
- if (this.subscription) {
- this.subscription.unsubscribe();
- }
-
- this.subscription = formatHistoryMessage(event.message, this.users).subscribe(value => {
- this.lastValue = value;
-
- this.changeDetector.markForCheck();
- });
- }
-
- return this.lastValue;
- }
-}
-
class UserAsyncPipe implements OnDestroy {
private lastUserId: string;
private lastValue: string | undefined = undefined;
@@ -219,67 +171,6 @@ export class UserPictureRefPipe extends UserAsyncPipe implements PipeTransform {
}
}
-@Pipe({
- name: 'sqxAssetUrl',
- pure: true
-})
-export class AssetUrlPipe implements PipeTransform {
- constructor(
- private readonly apiUrl: ApiUrlConfig
- ) {
- }
-
- public transform(asset: AssetDto): string {
- return `${asset.fullUrl(this.apiUrl)}&sq=${MathHelper.guid()}`;
- }
-}
-
-@Pipe({
- name: 'sqxAssetPreviewUrl',
- pure: true
-})
-export class AssetPreviewUrlPipe implements PipeTransform {
- constructor(
- private readonly apiUrl: ApiUrlConfig
- ) {
- }
-
- public transform(asset: AssetDto): string {
- return asset.fullUrl(this.apiUrl);
- }
-}
-
-@Pipe({
- name: 'sqxFileIcon',
- pure: true
-})
-export class FileIconPipe implements PipeTransform {
- public transform(asset: { mimeType: string, fileType: string }): string {
- const knownTypes = [
- 'doc',
- 'docx',
- 'pdf',
- 'ppt',
- 'pptx',
- 'video',
- 'xls',
- 'xlsx'
- ];
-
- let mimeIcon: string;
-
- const mimeParts = asset.mimeType.split('/');
-
- if (mimeParts.length === 2 && mimeParts[0].toLowerCase() === 'video') {
- mimeIcon = 'video';
- } else {
- mimeIcon = knownTypes.indexOf(asset.fileType) >= 0 ? asset.fileType : 'generic';
- }
-
- return `./images/asset_${mimeIcon}.svg`;
- }
-}
-
function split(token: string) {
const index = token.indexOf(':');
diff --git a/frontend/app/shared/components/queries/query-path.component.ts b/frontend/app/shared/components/queries/query-path.component.ts
deleted file mode 100644
index 6d152cf4c..000000000
--- a/frontend/app/shared/components/queries/query-path.component.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Squidex Headless CMS
- *
- * @license
- * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
- */
-
-import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
-
-import { QueryModel } from '@app/shared/internal';
-
-@Component({
- selector: 'sqx-query-path',
- template: `
-
-
-
-
-
{{model.fields[field].displayName}}
-
-
- {{model.fields[field].description}}
-
-
-
-
-
- {{model.fields[field].displayName}}
-
-
- `,
- changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class QueryPathComponent {
- @Output()
- public pathChange = new EventEmitter();
-
- @Input()
- public path: string;
-
- @Input()
- public model: QueryModel;
-}
\ No newline at end of file
diff --git a/frontend/app/shared/components/saved-queries.component.ts b/frontend/app/shared/components/saved-queries.component.ts
deleted file mode 100644
index d252e575b..000000000
--- a/frontend/app/shared/components/saved-queries.component.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Squidex Headless CMS
- *
- * @license
- * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
- */
-
-import { Component, EventEmitter, Input, Output } from '@angular/core';
-
-import { Queries } from '@app/shared/internal';
-import { SavedQuery } from '../state/queries';
-
-@Component({
- selector: 'sqx-shared-queries',
- template: `
-
-
-
-
-
- `
-})
-export class SavedQueriesComponent {
- @Output()
- public search = new EventEmitter();
-
- @Input()
- public queryUsed: (saved: SavedQuery) => boolean;
-
- @Input()
- public queries: Queries;
-
- @Input()
- public types: string;
-
- public isSelectedQuery(saved: SavedQuery) {
- return this.queryUsed && this.queryUsed(saved);
- }
-
- public trackByQuery(index: number, query: { name: string }) {
- return query.name;
- }
-}
\ No newline at end of file
diff --git a/frontend/app/shared/components/schema-category.component.scss b/frontend/app/shared/components/schema-category.component.scss
index 788d596ac..45155b172 100644
--- a/frontend/app/shared/components/schema-category.component.scss
+++ b/frontend/app/shared/components/schema-category.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
$drag-margin: -8px;
.col {
diff --git a/frontend/app/shared/components/schema-category.component.ts b/frontend/app/shared/components/schema-category.component.ts
index 5dbc5f61b..c3f684b8c 100644
--- a/frontend/app/shared/components/schema-category.component.ts
+++ b/frontend/app/shared/components/schema-category.component.ts
@@ -98,10 +98,6 @@ export class SchemaCategoryComponent extends StatefulComponent implements
}
}
- public emitRemove() {
- this.remove.emit();
- }
-
public trackBySchema(index: number, schema: SchemaDto) {
return schema.id;
}
diff --git a/frontend/app/shared/components/queries/filter-comparison.component.html b/frontend/app/shared/components/search/queries/filter-comparison.component.html
similarity index 99%
rename from frontend/app/shared/components/queries/filter-comparison.component.html
rename to frontend/app/shared/components/search/queries/filter-comparison.component.html
index e9adbf7fe..569b59f07 100644
--- a/frontend/app/shared/components/queries/filter-comparison.component.html
+++ b/frontend/app/shared/components/search/queries/filter-comparison.component.html
@@ -61,7 +61,7 @@
-
+
diff --git a/frontend/app/shared/components/queries/filter-comparison.component.scss b/frontend/app/shared/components/search/queries/filter-comparison.component.scss
similarity index 60%
rename from frontend/app/shared/components/queries/filter-comparison.component.scss
rename to frontend/app/shared/components/search/queries/filter-comparison.component.scss
index fe19e6460..16d712984 100644
--- a/frontend/app/shared/components/queries/filter-comparison.component.scss
+++ b/frontend/app/shared/components/search/queries/filter-comparison.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.path {
width: 10rem;
}
diff --git a/frontend/app/shared/components/queries/filter-comparison.component.ts b/frontend/app/shared/components/search/queries/filter-comparison.component.ts
similarity index 97%
rename from frontend/app/shared/components/queries/filter-comparison.component.ts
rename to frontend/app/shared/components/search/queries/filter-comparison.component.ts
index acba843f1..13227c73e 100644
--- a/frontend/app/shared/components/queries/filter-comparison.component.ts
+++ b/frontend/app/shared/components/search/queries/filter-comparison.component.ts
@@ -100,10 +100,6 @@ export class FilterComparisonComponent implements OnChanges {
this.fieldModel = newModel;
}
- public emitRemove() {
- this.remove.emit();
- }
-
public emitChange() {
this.change.emit();
}
diff --git a/frontend/app/shared/components/queries/filter-logical.component.html b/frontend/app/shared/components/search/queries/filter-logical.component.html
similarity index 98%
rename from frontend/app/shared/components/queries/filter-logical.component.html
rename to frontend/app/shared/components/search/queries/filter-logical.component.html
index 4ab99e218..73f5b4dc7 100644
--- a/frontend/app/shared/components/queries/filter-logical.component.html
+++ b/frontend/app/shared/components/search/queries/filter-logical.component.html
@@ -13,7 +13,7 @@
-
+
diff --git a/frontend/app/shared/components/queries/filter-logical.component.scss b/frontend/app/shared/components/search/queries/filter-logical.component.scss
similarity index 93%
rename from frontend/app/shared/components/queries/filter-logical.component.scss
rename to frontend/app/shared/components/search/queries/filter-logical.component.scss
index fa3b05e02..ba1c798e6 100644
--- a/frontend/app/shared/components/queries/filter-logical.component.scss
+++ b/frontend/app/shared/components/search/queries/filter-logical.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
$field-line: #e1e8ef;
.filters {
diff --git a/frontend/app/shared/components/queries/filter-logical.component.ts b/frontend/app/shared/components/search/queries/filter-logical.component.ts
similarity index 97%
rename from frontend/app/shared/components/queries/filter-logical.component.ts
rename to frontend/app/shared/components/search/queries/filter-logical.component.ts
index 768c12576..bf4b5ad4a 100644
--- a/frontend/app/shared/components/queries/filter-logical.component.ts
+++ b/frontend/app/shared/components/search/queries/filter-logical.component.ts
@@ -108,10 +108,6 @@ export class FilterLogicalComponent {
}
}
- public emitRemove() {
- this.remove.emit();
- }
-
public emitChange() {
this.change.emit();
}
diff --git a/frontend/app/shared/components/search/queries/filter-node.component.html b/frontend/app/shared/components/search/queries/filter-node.component.html
new file mode 100644
index 000000000..78a3332be
--- /dev/null
+++ b/frontend/app/shared/components/search/queries/filter-node.component.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/search/queries/filter-node.component.scss b/frontend/app/shared/components/search/queries/filter-node.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/queries/filter-node.component.ts b/frontend/app/shared/components/search/queries/filter-node.component.ts
similarity index 65%
rename from frontend/app/shared/components/queries/filter-node.component.ts
rename to frontend/app/shared/components/search/queries/filter-node.component.ts
index 53dd147b2..6d71635a3 100644
--- a/frontend/app/shared/components/queries/filter-node.component.ts
+++ b/frontend/app/shared/components/search/queries/filter-node.component.ts
@@ -17,19 +17,8 @@ import {
@Component({
selector: 'sqx-filter-node',
- template: `
-
-
-
-
-
-
-
-
-
- `,
+ styleUrls: ['./filter-node.component.scss'],
+ templateUrl: './filter-node.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FilterNodeComponent {
diff --git a/frontend/app/shared/components/search/queries/query-path.component.html b/frontend/app/shared/components/search/queries/query-path.component.html
new file mode 100644
index 000000000..34b9c33fc
--- /dev/null
+++ b/frontend/app/shared/components/search/queries/query-path.component.html
@@ -0,0 +1,16 @@
+
+
+
+
+
{{model.fields[field].displayName}}
+
+
+ {{model.fields[field].description}}
+
+
+
+
+
+ {{model.fields[field].displayName}}
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/search/queries/query-path.component.scss b/frontend/app/shared/components/search/queries/query-path.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/search/queries/query-path.component.ts b/frontend/app/shared/components/search/queries/query-path.component.ts
new file mode 100644
index 000000000..90faf1138
--- /dev/null
+++ b/frontend/app/shared/components/search/queries/query-path.component.ts
@@ -0,0 +1,27 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { QueryModel } from '@app/shared/internal';
+
+@Component({
+ selector: 'sqx-query-path',
+ styleUrls: ['./query-path.component.scss'],
+ templateUrl: './query-path.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class QueryPathComponent {
+ @Output()
+ public pathChange = new EventEmitter();
+
+ @Input()
+ public path: string;
+
+ @Input()
+ public model: QueryModel;
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/search/queries/query.component.html b/frontend/app/shared/components/search/queries/query.component.html
new file mode 100644
index 000000000..63f85d7fd
--- /dev/null
+++ b/frontend/app/shared/components/search/queries/query.component.html
@@ -0,0 +1,15 @@
+
+
+
+Sorting
+
+
+
+
+
+
+
+ Add Sorting
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/search/queries/query.component.scss b/frontend/app/shared/components/search/queries/query.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/queries/query.component.ts b/frontend/app/shared/components/search/queries/query.component.ts
similarity index 50%
rename from frontend/app/shared/components/queries/query.component.ts
rename to frontend/app/shared/components/search/queries/query.component.ts
index 6eace549b..7f3e7ad4b 100644
--- a/frontend/app/shared/components/queries/query.component.ts
+++ b/frontend/app/shared/components/search/queries/query.component.ts
@@ -11,28 +11,14 @@ import {
LanguageDto,
Query,
QueryModel,
- QuerySorting
+ QuerySorting,
+ Types
} from '@app/shared/internal';
@Component({
selector: 'sqx-query',
- template: `
-
-
-
- Sorting
-
-
-
-
-
-
-
- Add Sorting
-
- `,
+ styleUrls: ['./query.component.scss'],
+ templateUrl: './query.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class QueryComponent {
@@ -47,30 +33,10 @@ export class QueryComponent {
@Input()
public set query(query: Query) {
- if (!query) {
- query = {};
- }
-
- if (query) {
- if (!query.filter) {
- query.filter = {
- and: []
- };
- }
-
- if (!query.sort) {
- query.sort = [];
- }
-
- this.queryValue = query;
- }
+ this.queryValue = Types.clone(query);
}
- public queryValue: Query;
-
- constructor() {
- this.query = {};
- }
+ public queryValue: Query = {};
public addSorting() {
this.queryValue.sort!.push({ path: Object.keys(this.model.fields)[0], order: 'ascending' });
diff --git a/frontend/app/shared/components/search/queries/sorting.component.html b/frontend/app/shared/components/search/queries/sorting.component.html
new file mode 100644
index 000000000..3d7d62b6a
--- /dev/null
+++ b/frontend/app/shared/components/search/queries/sorting.component.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ ascending
+ descending
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/search/queries/sorting.component.scss b/frontend/app/shared/components/search/queries/sorting.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/queries/sorting.component.ts b/frontend/app/shared/components/search/queries/sorting.component.ts
similarity index 50%
rename from frontend/app/shared/components/queries/sorting.component.ts
rename to frontend/app/shared/components/search/queries/sorting.component.ts
index ccb337fc5..21ff5b97d 100644
--- a/frontend/app/shared/components/queries/sorting.component.ts
+++ b/frontend/app/shared/components/search/queries/sorting.component.ts
@@ -11,29 +11,8 @@ import { QueryModel, QuerySorting } from '@app/shared/internal';
@Component({
selector: 'sqx-sorting',
- template: `
-
-
-
-
-
-
-
- ascending
- descending
-
-
-
-
-
-
-
-
-
- `,
+ styleUrls: ['./sorting.component.scss'],
+ templateUrl: './sorting.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SortingComponent {
diff --git a/frontend/app/shared/components/search/query-list.component.html b/frontend/app/shared/components/search/query-list.component.html
new file mode 100644
index 000000000..1f86f38d4
--- /dev/null
+++ b/frontend/app/shared/components/search/query-list.component.html
@@ -0,0 +1,17 @@
+ 0; else noQuery">
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/search/query-list.component.scss b/frontend/app/shared/components/search/query-list.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/search/query-list.component.ts b/frontend/app/shared/components/search/query-list.component.ts
new file mode 100644
index 000000000..1244d585e
--- /dev/null
+++ b/frontend/app/shared/components/search/query-list.component.ts
@@ -0,0 +1,48 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
+
+import {
+ equalsQuery,
+ Query,
+ SavedQuery
+} from '@app/shared/internal';
+
+@Component({
+ selector: 'sqx-query-list',
+ styleUrls: ['./query-list.component.scss'],
+ templateUrl: './query-list.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class QueryListComponent {
+ @Output()
+ public search = new EventEmitter();
+
+ @Output()
+ public remove = new EventEmitter();
+
+ @Input()
+ public queryUsed: Query | undefined;
+
+ @Input()
+ public queries: ReadonlyArray;
+
+ @Input()
+ public canRemove: boolean;
+
+ @Input()
+ public types: string;
+
+ public isSelectedQuery(saved: SavedQuery) {
+ return equalsQuery(saved.query, this.queryUsed);
+ }
+
+ public trackByQuery(index: number, query: SavedQuery) {
+ return query.name;
+ }
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/search-form.component.html b/frontend/app/shared/components/search/search-form.component.html
similarity index 100%
rename from frontend/app/shared/components/search-form.component.html
rename to frontend/app/shared/components/search/search-form.component.html
diff --git a/frontend/app/shared/components/search-form.component.scss b/frontend/app/shared/components/search/search-form.component.scss
similarity index 95%
rename from frontend/app/shared/components/search-form.component.scss
rename to frontend/app/shared/components/search/search-form.component.scss
index a0c532932..e6f35bf63 100644
--- a/frontend/app/shared/components/search-form.component.scss
+++ b/frontend/app/shared/components/search/search-form.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.search-form {
display: inline-block;
}
diff --git a/frontend/app/shared/components/search-form.component.ts b/frontend/app/shared/components/search/search-form.component.ts
similarity index 100%
rename from frontend/app/shared/components/search-form.component.ts
rename to frontend/app/shared/components/search/search-form.component.ts
diff --git a/frontend/app/shared/components/search/shared-queries.component.html b/frontend/app/shared/components/search/shared-queries.component.html
new file mode 100644
index 000000000..a21679dec
--- /dev/null
+++ b/frontend/app/shared/components/search/shared-queries.component.html
@@ -0,0 +1,25 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/search/shared-queries.component.scss b/frontend/app/shared/components/search/shared-queries.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/search/shared-queries.component.ts b/frontend/app/shared/components/search/shared-queries.component.ts
new file mode 100644
index 000000000..83d1e4c0f
--- /dev/null
+++ b/frontend/app/shared/components/search/shared-queries.component.ts
@@ -0,0 +1,30 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
+
+import { Queries, Query } from '@app/shared/internal';
+
+@Component({
+ selector: 'sqx-shared-queries',
+ styleUrls: ['./shared-queries.component.scss'],
+ templateUrl: './shared-queries.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class SavedQueriesComponent {
+ @Output()
+ public search = new EventEmitter();
+
+ @Input()
+ public queryUsed: Query;
+
+ @Input()
+ public queries: Queries;
+
+ @Input()
+ public types: string;
+}
\ No newline at end of file
diff --git a/frontend/app/shared/components/table-header.component.html b/frontend/app/shared/components/table-header.component.html
new file mode 100644
index 000000000..a2ce0143e
--- /dev/null
+++ b/frontend/app/shared/components/table-header.component.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ {{text}}
+
+
+
+
+ {{text}}
+
\ No newline at end of file
diff --git a/frontend/app/shared/components/table-header.component.scss b/frontend/app/shared/components/table-header.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shared/components/table-header.component.ts b/frontend/app/shared/components/table-header.component.ts
index aa5045ef8..1beb901ac 100644
--- a/frontend/app/shared/components/table-header.component.ts
+++ b/frontend/app/shared/components/table-header.component.ts
@@ -10,25 +10,14 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Out
import {
LanguageDto,
Query,
- SortMode
+ SortMode,
+ Types
} from '@app/shared/internal';
@Component({
selector: 'sqx-table-header',
- template: `
-
-
-
-
-
- {{text}}
-
-
-
-
- {{text}}
-
- `,
+ styleUrls: ['./table-header.component.scss'],
+ templateUrl: './table-header.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TableHeaderComponent implements OnChanges {
@@ -76,11 +65,13 @@ export class TableHeaderComponent implements OnChanges {
this.order = 'descending';
}
- this.queryChange.emit(this.newQuery());
- }
- }
+ const newQuery = Types.clone(this.query);
+
+ newQuery.sort = [
+ { path: this.fieldPath, order: this.order! }
+ ];
- private newQuery() {
- return {...this.query, sort: [{ path: this.fieldPath, order: this.order! }] };
+ this.queryChange.emit(newQuery);
+ }
}
}
\ No newline at end of file
diff --git a/frontend/app/shared/declarations.ts b/frontend/app/shared/declarations.ts
index 9a3b9cbcf..33f7ff0df 100644
--- a/frontend/app/shared/declarations.ts
+++ b/frontend/app/shared/declarations.ts
@@ -6,38 +6,46 @@
*/
export * from './components/app-form.component';
-export * from './components/asset-dialog.component';
-export * from './components/asset-folder.component';
-export * from './components/asset-folder-form.component';
-export * from './components/asset-path.component';
-export * from './components/asset-uploader.component';
-export * from './components/asset.component';
-export * from './components/assets-list.component';
-export * from './components/assets-selector.component';
-export * from './components/comment.component';
-export * from './components/comments.component';
-export * from './components/geolocation-editor.component';
-export * from './components/help-markdown.pipe';
-export * from './components/help.component';
-export * from './components/history-list.component';
-export * from './components/history.component';
-export * from './components/language-selector.component';
-export * from './components/markdown-editor.component';
export * from './components/pipes';
-export * from './components/references-dropdown.component';
-export * from './components/references-tags.component';
-export * from './components/rich-editor.component';
-export * from './components/saved-queries.component';
export * from './components/schema-category.component';
-export * from './components/search-form.component';
export * from './components/table-header.component';
-export * from './components/queries/filter-comparison.component';
-export * from './components/queries/filter-logical.component';
-export * from './components/queries/filter-node.component';
-export * from './components/queries/query-path.component';
-export * from './components/queries/query.component';
-export * from './components/queries/sorting.component';
+export * from './components/assets/asset-dialog.component';
+export * from './components/assets/asset-folder-form.component';
+export * from './components/assets/asset-folder.component';
+export * from './components/assets/asset-path.component';
+export * from './components/assets/asset-uploader.component';
+export * from './components/assets/asset.component';
+export * from './components/assets/assets-list.component';
+export * from './components/assets/assets-selector.component';
+export * from './components/assets/pipes';
+
+export * from './components/comments/comment.component';
+export * from './components/comments/comments.component';
+
+export * from './components/forms/geolocation-editor.component';
+export * from './components/forms/language-selector.component';
+export * from './components/forms/markdown-editor.component';
+export * from './components/forms/references-dropdown.component';
+export * from './components/forms/references-tags.component';
+export * from './components/forms/rich-editor.component';
+
+export * from './components/help/help-markdown.pipe';
+export * from './components/help/help.component';
+
+export * from './components/history/history-list.component';
+export * from './components/history/history.component';
+export * from './components/history/pipes';
+
+export * from './components/search/queries/filter-comparison.component';
+export * from './components/search/queries/filter-logical.component';
+export * from './components/search/queries/filter-node.component';
+export * from './components/search/queries/query-path.component';
+export * from './components/search/queries/query.component';
+export * from './components/search/queries/sorting.component';
+export * from './components/search/query-list.component';
+export * from './components/search/search-form.component';
+export * from './components/search/shared-queries.component';
export * from './guards/app-must-exist.guard';
export * from './guards/content-must-exist.guard';
diff --git a/frontend/app/shared/module.ts b/frontend/app/shared/module.ts
index d205c5a73..6bcb0ff7b 100644
--- a/frontend/app/shared/module.ts
+++ b/frontend/app/shared/module.ts
@@ -75,6 +75,7 @@ import {
PlansService,
PlansState,
QueryComponent,
+ QueryListComponent,
QueryPathComponent,
ReferencesDropdownComponent,
ReferencesTagsComponent,
@@ -148,6 +149,7 @@ import {
LanguageSelectorComponent,
MarkdownEditorComponent,
QueryComponent,
+ QueryListComponent,
QueryPathComponent,
ReferencesDropdownComponent,
ReferencesTagsComponent,
@@ -188,6 +190,7 @@ import {
HistoryMessagePipe,
LanguageSelectorComponent,
MarkdownEditorComponent,
+ QueryListComponent,
ReferencesDropdownComponent,
ReferencesTagsComponent,
RichEditorComponent,
diff --git a/frontend/app/shared/services/assets.service.spec.ts b/frontend/app/shared/services/assets.service.spec.ts
index 9220633c9..bfd8af614 100644
--- a/frontend/app/shared/services/assets.service.spec.ts
+++ b/frontend/app/shared/services/assets.service.spec.ts
@@ -17,6 +17,7 @@ import {
AssetsDto,
AssetsService,
DateTime,
+ encodeQuery,
ErrorDto,
MathHelper,
Resource,
@@ -24,8 +25,6 @@ import {
Version
} from '@app/shared/internal';
-import { encodeQuery } from '../state/query';
-
describe('AssetsService', () => {
const version = new Version('1');
@@ -80,7 +79,9 @@ describe('AssetsService', () => {
assets = result;
});
- const req = httpMock.expectOne(`http://service/p/api/apps/my-app/assets?q=${encodeQuery({ take: 17, skip: 13 })}`);
+ const query = { take: 17, skip: 13 };
+
+ const req = httpMock.expectOne(`http://service/p/api/apps/my-app/assets?q=${encodeQuery(query)}`);
expect(req.request.method).toEqual('GET');
expect(req.request.headers.get('If-Match')).toBeNull();
@@ -157,7 +158,9 @@ describe('AssetsService', () => {
assetsService.getAssets('my-app', 17, 13, { fullText: 'my-query' }).subscribe();
- const req = httpMock.expectOne(`http://service/p/api/apps/my-app/assets?q=${encodeQuery({ filter: { and: [{ path: 'fileName', op: 'contains', value: 'my-query' }] }, take: 17, skip: 13 })}`);
+ const query = { filter: { and: [{ path: 'fileName', op: 'contains', value: 'my-query' }] }, take: 17, skip: 13 };
+
+ const req = httpMock.expectOne(`http://service/p/api/apps/my-app/assets?q=${encodeQuery(query)}`);
expect(req.request.method).toEqual('GET');
expect(req.request.headers.get('If-Match')).toBeNull();
@@ -170,7 +173,9 @@ describe('AssetsService', () => {
assetsService.getAssets('my-app', 17, 13, undefined, ['tag1']).subscribe();
- const req = httpMock.expectOne(`http://service/p/api/apps/my-app/assets?q=${encodeQuery({ filter: { and: [{ path: 'tags', op: 'eq', value: 'tag1' }] }, take: 17, skip: 13 })}`);
+ const query = { filter: { and: [{ path: 'tags', op: 'eq', value: 'tag1' }] }, take: 17, skip: 13 };
+
+ const req = httpMock.expectOne(`http://service/p/api/apps/my-app/assets?q=${encodeQuery(query)}`);
expect(req.request.method).toEqual('GET');
expect(req.request.headers.get('If-Match')).toBeNull();
diff --git a/frontend/app/shared/services/contents.service.spec.ts b/frontend/app/shared/services/contents.service.spec.ts
index 27a57724b..d52702a55 100644
--- a/frontend/app/shared/services/contents.service.spec.ts
+++ b/frontend/app/shared/services/contents.service.spec.ts
@@ -21,7 +21,7 @@ import {
Version,
Versioned
} from '@app/shared/internal';
-import { encodeQuery } from '../state/query';
+import { encodeQuery } from './../state/query';
describe('ContentsService', () => {
const version = new Version('1');
diff --git a/frontend/app/shared/services/workflows.service.spec.ts b/frontend/app/shared/services/workflows.service.spec.ts
index 46dbfc5e7..5b5a72148 100644
--- a/frontend/app/shared/services/workflows.service.spec.ts
+++ b/frontend/app/shared/services/workflows.service.spec.ts
@@ -20,7 +20,6 @@ import {
} from '@app/shared/internal';
describe('WorkflowsService', () => {
-
const version = new Version('1');
beforeEach(() => {
diff --git a/frontend/app/shared/state/apps.state.spec.ts b/frontend/app/shared/state/apps.state.spec.ts
index b85b7a1ae..5c115e1a2 100644
--- a/frontend/app/shared/state/apps.state.spec.ts
+++ b/frontend/app/shared/state/apps.state.spec.ts
@@ -15,7 +15,7 @@ import {
DialogService
} from '@app/shared/internal';
-import { createApp } from '../services/apps.service.spec';
+import { createApp } from './../services/apps.service.spec';
describe('AppsState', () => {
const app1 = createApp(1);
diff --git a/frontend/app/shared/state/apps.state.ts b/frontend/app/shared/state/apps.state.ts
index dbc60840e..830ac8bdc 100644
--- a/frontend/app/shared/state/apps.state.ts
+++ b/frontend/app/shared/state/apps.state.ts
@@ -162,7 +162,8 @@ export class AppsState extends State {
this.next(s => {
const apps = s.apps.replaceBy('id', updated);
- const selectedApp = s.selectedApp &&
+ const selectedApp =
+ s.selectedApp &&
s.selectedApp.id === app.id ?
updated :
s.selectedApp;
diff --git a/frontend/app/shared/state/assets.forms.ts b/frontend/app/shared/state/assets.forms.ts
index 81fb64861..90049637e 100644
--- a/frontend/app/shared/state/assets.forms.ts
+++ b/frontend/app/shared/state/assets.forms.ts
@@ -115,11 +115,11 @@ export class AnnotateAssetForm extends Form {
const {
@@ -106,7 +105,7 @@ describe('AssetsState', () => {
assetsState.toggleTag('tag1').subscribe();
assetsState.toggleTag('tag1').subscribe();
- expect(assetsState.isTagSelected('tag1')).toBeFalsy();
+ expect(assetsState.snapshot.tagsSelected).toEqual({});
});
it('should load without tags when tags reset', () => {
@@ -115,7 +114,7 @@ describe('AssetsState', () => {
assetsState.resetTags().subscribe();
- expect(assetsState.isTagSelectionEmpty()).toBeTruthy();
+ expect(assetsState.snapshot.tagsSelected).toEqual({});
});
it('should load with new pagination when paging', () => {
@@ -189,7 +188,7 @@ describe('AssetsState', () => {
assetsState.toggleTag('tag1').subscribe();
- expect(assetsState.isTagSelected('tag1')).toBeTruthy();
+ expect(assetsState.snapshot.tagsSelected).toEqual({ tag1: true });
});
it('should load with tags when tags selected', () => {
@@ -198,7 +197,7 @@ describe('AssetsState', () => {
assetsState.selectTags(['tag1', 'tag2']).subscribe();
- expect(assetsState.isTagSelected('tag1')).toBeTruthy();
+ expect(assetsState.snapshot.tagsSelected).toEqual({ tag1: true, tag2: true });
});
it('should load with query when searching', () => {
@@ -210,7 +209,6 @@ describe('AssetsState', () => {
assetsState.search(query).subscribe();
expect(assetsState.snapshot.assetsQuery).toEqual(query);
- expect(assetsState.isQueryUsed({ name: 'name', query, queryJson: encodeQuery(query) })).toBeTruthy();
});
});
diff --git a/frontend/app/shared/state/assets.state.ts b/frontend/app/shared/state/assets.state.ts
index 712f2d7f3..1a7f9ad11 100644
--- a/frontend/app/shared/state/assets.state.ts
+++ b/frontend/app/shared/state/assets.state.ts
@@ -28,13 +28,13 @@ import {
} from './../services/assets.service';
import { AppsState } from './apps.state';
-import { SavedQuery } from './queries';
-import { encodeQuery, Query } from './query';
+import { Query } from './query';
export type AssetPathItem = { id: string, folderName: string };
-type TagsAvailable = { [name: string]: number };
-type TagsSelected = { [name: string]: boolean };
+export type TagsAvailable = { [name: string]: number };
+export type TagsSelected = { [name: string]: boolean };
+export type Tag = { name: string, count: number; };
const EMPTY_FOLDERS: { canCreate: boolean, items: ReadonlyArray } = { canCreate: false, items: [] };
@@ -59,9 +59,6 @@ interface Snapshot {
// The query to filter assets.
assetsQuery?: Query;
- // The json of the assets query.
- assetsQueryJson: string;
-
// The folder path.
path: ReadonlyArray;
@@ -144,7 +141,6 @@ export class AssetsState extends State {
assetFolders: [],
assets: [],
assetsPager: Pager.fromLocalStore('assets', localStore, 30),
- assetsQueryJson: '',
path: ROOT_PATH,
tagsAvailable: {},
tagsSelected: {}
@@ -354,7 +350,6 @@ export class AssetsState extends State {
if (query !== null) {
newState.assetsQuery = query;
- newState.assetsQueryJson = encodeQuery(query);
}
if (tags) {
@@ -422,18 +417,6 @@ export class AssetsState extends State {
return this.searchInternal(query);
}
- public isQueryUsed(saved: SavedQuery) {
- return this.snapshot.assetsQueryJson === saved.queryJson;
- }
-
- public isTagSelected(tag: string) {
- return this.snapshot.tagsSelected[tag];
- }
-
- public isTagSelectionEmpty() {
- return Object.keys(this.snapshot.tagsSelected).length === 0;
- }
-
public get parentId() {
return this.snapshot.path.length > 0 ? this.snapshot.path[this.snapshot.path.length - 1].id : undefined;
}
diff --git a/frontend/app/shared/state/clients.state.spec.ts b/frontend/app/shared/state/clients.state.spec.ts
index 45cf9dac6..c235242f5 100644
--- a/frontend/app/shared/state/clients.state.spec.ts
+++ b/frontend/app/shared/state/clients.state.spec.ts
@@ -17,7 +17,7 @@ import {
versioned
} from '@app/shared/internal';
-import { createClients } from '../services/clients.service.spec';
+import { createClients } from './../services/clients.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/contents.forms.ts b/frontend/app/shared/state/contents.forms.ts
index 6190c9360..20995de45 100644
--- a/frontend/app/shared/state/contents.forms.ts
+++ b/frontend/app/shared/state/contents.forms.ts
@@ -18,9 +18,9 @@ import {
ValidatorsEx
} from '@app/framework';
-import { ContentDto, ContentReferencesValue } from '../services/contents.service';
-import { LanguageDto } from '../services/languages.service';
import { AppLanguageDto } from './../services/app-languages.service';
+import { ContentDto, ContentReferencesValue } from './../services/contents.service';
+import { LanguageDto } from './../services/languages.service';
import { FieldDto, RootFieldDto, SchemaDetailsDto, TableField } from './../services/schemas.service';
import {
ArrayFieldPropertiesDto,
@@ -500,13 +500,13 @@ export class EditContentForm extends Form {
public hasChanged() {
const currentValue = this.form.getRawValue();
- return !Types.jsJsonEquals(this.initialData, currentValue);
+ return !Types.equals(this.initialData, currentValue);
}
public hasChanges(changes: any) {
const currentValue = this.form.getRawValue();
- return !Types.jsJsonEquals(changes, currentValue);
+ return !Types.equals(changes, currentValue);
}
public arrayItemRemove(field: RootFieldDto, language: AppLanguageDto, index: number) {
diff --git a/frontend/app/shared/state/contents.state.ts b/frontend/app/shared/state/contents.state.ts
index 32025ef2d..e41e6a4e2 100644
--- a/frontend/app/shared/state/contents.state.ts
+++ b/frontend/app/shared/state/contents.state.ts
@@ -24,7 +24,7 @@ import { ContentDto, ContentsService, StatusInfo } from './../services/contents.
import { SchemaDto } from './../services/schemas.service';
import { AppsState } from './apps.state';
import { SavedQuery } from './queries';
-import { encodeQuery, Query } from './query';
+import { Query } from './query';
import { SchemasState } from './schemas.state';
interface Snapshot {
@@ -37,9 +37,6 @@ interface Snapshot {
// The query to filter and sort contents.
contentsQuery?: Query;
- // The raw content query.
- contentsQueryJson: string;
-
// Indicates if the contents are loaded.
isLoaded?: boolean;
@@ -97,7 +94,7 @@ export abstract class ContentsStateBase extends State {
this.project(x => x.statuses);
public statusQueries =
- this.projectFrom(this.statuses, x => buildQueries(x));
+ this.projectFrom(this.statuses, x => buildStatusQueries(x));
constructor(
private readonly appsState: AppsState,
@@ -107,8 +104,7 @@ export abstract class ContentsStateBase extends State {
) {
super({
contents: [],
- contentsPager: Pager.fromLocalStore('contents', localStore),
- contentsQueryJson: ''
+ contentsPager: Pager.fromLocalStore('contents', localStore)
});
this.contentsPager.subscribe(pager => {
@@ -313,7 +309,7 @@ export abstract class ContentsStateBase extends State {
}
public search(contentsQuery?: Query): Observable {
- this.next(s => ({ ...s, contentsPager: s.contentsPager.reset(), contentsQuery, contentsQueryJson: encodeQuery(contentsQuery) }));
+ this.next(s => ({ ...s, contentsPager: s.contentsPager.reset(), contentsQuery }));
return this.loadInternal(false);
}
@@ -323,11 +319,6 @@ export abstract class ContentsStateBase extends State {
return this.loadInternal(false);
}
-
- public isQueryUsed(saved: SavedQuery) {
- return this.snapshot.contentsQueryJson === saved.queryJson;
- }
-
private get appName() {
return this.appsState.appName;
}
@@ -383,13 +374,11 @@ export class ManualContentsState extends ContentsStateBase {
}
}
-export type ContentQuery = { color: string; } & SavedQuery;
-
-function buildQueries(statuses: ReadonlyArray | undefined): ReadonlyArray {
- return statuses ? statuses.map(s => buildQuery(s)) : [];
+function buildStatusQueries(statuses: ReadonlyArray | undefined): ReadonlyArray {
+ return statuses ? statuses.map(s => buildStatusQuery(s)) : [];
}
-function buildQuery(s: StatusInfo) {
+function buildStatusQuery(s: StatusInfo) {
const query = {
filter: {
and: [
@@ -398,5 +387,5 @@ function buildQuery(s: StatusInfo) {
}
};
- return ({ name: s.status, color: s.color, query, queryJson: encodeQuery(query) });
+ return ({ name: s.status, color: s.color, query });
}
diff --git a/frontend/app/shared/state/contributors.forms.ts b/frontend/app/shared/state/contributors.forms.ts
index 447079c4d..96f01e7bf 100644
--- a/frontend/app/shared/state/contributors.forms.ts
+++ b/frontend/app/shared/state/contributors.forms.ts
@@ -15,7 +15,7 @@ import {
value$
} from '@app/framework';
-import { AssignContributorDto } from '../services/contributors.service';
+import { AssignContributorDto } from './../services/contributors.service';
import { UserDto } from './../services/users.service';
diff --git a/frontend/app/shared/state/contributors.state.spec.ts b/frontend/app/shared/state/contributors.state.spec.ts
index d87a6c3d1..aec4e5708 100644
--- a/frontend/app/shared/state/contributors.state.spec.ts
+++ b/frontend/app/shared/state/contributors.state.spec.ts
@@ -20,7 +20,7 @@ import {
versioned
} from '@app/shared/internal';
-import { createContributors } from '../services/contributors.service.spec';
+import { createContributors } from './../services/contributors.service.spec';
import { ErrorDto } from '@app/framework';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/languages.state.spec.ts b/frontend/app/shared/state/languages.state.spec.ts
index c084c34ad..ed0fe34f7 100644
--- a/frontend/app/shared/state/languages.state.spec.ts
+++ b/frontend/app/shared/state/languages.state.spec.ts
@@ -19,7 +19,7 @@ import {
versioned
} from '@app/shared/internal';
-import { createLanguages } from '../services/app-languages.service.spec';
+import { createLanguages } from './../services/app-languages.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/patterns.state.spec.ts b/frontend/app/shared/state/patterns.state.spec.ts
index ea0d64533..9ba1775f6 100644
--- a/frontend/app/shared/state/patterns.state.spec.ts
+++ b/frontend/app/shared/state/patterns.state.spec.ts
@@ -17,7 +17,7 @@ import {
versioned
} from '@app/shared/internal';
-import { createPatterns } from '../services/patterns.service.spec';
+import { createPatterns } from './../services/patterns.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/queries.spec.ts b/frontend/app/shared/state/queries.spec.ts
index f2e8a2268..87e4acbfd 100644
--- a/frontend/app/shared/state/queries.spec.ts
+++ b/frontend/app/shared/state/queries.spec.ts
@@ -9,7 +9,6 @@ import { BehaviorSubject } from 'rxjs';
import { IMock, Mock, Times } from 'typemoq';
import {
- encodeQuery,
Queries,
SavedQuery,
UIState
@@ -60,17 +59,11 @@ describe('Queries', () => {
expect(converted!).toEqual([
{
- name: 'key1',
- query: { fullText: 'merged1' },
- queryJson: encodeQuery({ fullText: 'merged1' })
+ name: 'key1', query: { fullText: 'merged1' }
}, {
- name: 'key2',
- query: { fullText: 'merged2' },
- queryJson: encodeQuery({ fullText: 'merged2' })
+ name: 'key2', query: { fullText: 'merged2' }
}, {
- name: 'key3',
- query: undefined,
- queryJson: ''
+ name: 'key3', query: undefined
}
]);
});
@@ -84,9 +77,7 @@ describe('Queries', () => {
expect(converted!).toEqual([
{
- name: 'key1',
- query: { fullText: 'shared1' },
- queryJson: encodeQuery({ fullText: 'shared1' })
+ name: 'key1', query: { fullText: 'shared1' }
}
]);
});
@@ -100,9 +91,7 @@ describe('Queries', () => {
expect(converted!).toEqual([
{
- name: 'key1',
- query: { fullText: 'user1' },
- queryJson: encodeQuery({ fullText: 'user1' })
+ name: 'key1', query: { fullText: 'user1' }
}
]);
});
diff --git a/frontend/app/shared/state/queries.ts b/frontend/app/shared/state/queries.ts
index 86a2bc29d..479171885 100644
--- a/frontend/app/shared/state/queries.ts
+++ b/frontend/app/shared/state/queries.ts
@@ -8,21 +8,25 @@
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
-import { compareStrings, Types } from '@app/framework';
+import { compareStrings } from '@app/framework';
-import { UIState } from './ui.state';
+import {
+ decodeQuery,
+ equalsQuery,
+ Query
+} from './query';
-import { encodeQuery, Query } from './query';
+import { UIState } from './ui.state';
export interface SavedQuery {
+ // The optional color.
+ color?: string;
+
// The name of the query.
name: string;
// The deserialized value.
query?: Query;
-
- // The raw value of the query.
- queryJson?: string;
}
const OLDEST_FIRST: Query = {
@@ -37,8 +41,8 @@ export class Queries {
public queriesUser: Observable>;
public defaultQueries: ReadonlyArray = [
- { name: 'All (newest first)', queryJson: '' },
- { name: 'All (oldest first)', queryJson: encodeQuery(OLDEST_FIRST), query: OLDEST_FIRST }
+ { name: 'All (newest first)' },
+ { name: 'All (oldest first)', query: OLDEST_FIRST }
];
constructor(
@@ -78,12 +82,10 @@ export class Queries {
}
public getSaveKey(query: Query): Observable {
- const json = encodeQuery(query);
-
return this.queries.pipe(
map(queries => {
for (const saved of queries) {
- if (saved.queryJson === json) {
+ if (equalsQuery(saved.query, query)) {
return saved.name;
}
}
@@ -100,17 +102,7 @@ function parseQueries(settings: {}) {
}
export function parseStored(name: string, raw?: string) {
- if (Types.isString(raw)) {
- let query: Query;
-
- if (raw.indexOf('{') === 0) {
- query = JSON.parse(raw);
- } else {
- query = { fullText: raw };
- }
-
- return { name, query, queryJson: encodeQuery(query) };
- }
+ const query = decodeQuery(raw);
- return { name, query: undefined, queryJson: '' };
+ return { name, query };
}
\ No newline at end of file
diff --git a/frontend/app/shared/state/query.spec.ts b/frontend/app/shared/state/query.spec.ts
new file mode 100644
index 000000000..f2ead7f8b
--- /dev/null
+++ b/frontend/app/shared/state/query.spec.ts
@@ -0,0 +1,56 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { Query } from '@app/shared/internal';
+import { equalsQuery } from './query';
+
+describe('equalsQuery', () => {
+ it('should return true when comparing with empty query', () => {
+ const lhs: Query = {};
+
+ const rhs: Query = {
+ filter: {
+ and: []
+ },
+ sort: []
+ };
+
+ expect(equalsQuery(lhs, rhs)).toBeTruthy();
+ });
+
+ it('should return true when comparing without sort', () => {
+ const lhs: Query = {
+ filter: {
+ and: []
+ }
+ };
+
+ const rhs: Query = {
+ filter: {
+ and: []
+ },
+ sort: []
+ };
+
+ expect(equalsQuery(lhs, rhs)).toBeTruthy();
+ });
+
+ it('should return true when comparing without filter', () => {
+ const lhs: Query = {
+ sort: []
+ };
+
+ const rhs: Query = {
+ filter: {
+ and: []
+ },
+ sort: []
+ };
+
+ expect(equalsQuery(lhs, rhs)).toBeTruthy();
+ });
+});
\ No newline at end of file
diff --git a/frontend/app/shared/state/query.ts b/frontend/app/shared/state/query.ts
index 05ae4e24f..197bb655d 100644
--- a/frontend/app/shared/state/query.ts
+++ b/frontend/app/shared/state/query.ts
@@ -75,7 +75,7 @@ export interface FilterLogical {
// The child filters if the logical filter is a conjunction (AND).
and?: FilterNode[];
- // The child filters if the logical filter is a disjunction (OR).
+ // The child filters if the logical filter is a conjunction (AND).
or?: FilterNode[];
}
@@ -106,12 +106,17 @@ export interface Query {
skip?: number;
}
-export function encodeQuery(query?: Query) {
- if (Types.isEmpty(query)) {
- return '';
- }
+const DEFAULT_QUERY = {
+ filter: {
+ and: []
+ },
+ sort: []
+};
- query = { ...query };
+function santize(query?: Query) {
+ if (!query) {
+ return DEFAULT_QUERY;
+ }
if (!query.sort) {
query.sort = [];
@@ -121,7 +126,33 @@ export function encodeQuery(query?: Query) {
query.filter = { and: [] };
}
- return encodeURIComponent(JSON.stringify(query));
+ return query;
+}
+
+export function equalsQuery(lhs?: Query, rhs?: Query) {
+ return Types.equals(santize(lhs), santize(rhs));
+}
+
+export function encodeQuery(query?: Query) {
+ return encodeURIComponent(JSON.stringify(santize(query)));
+}
+
+export function decodeQuery(raw?: string): Query | undefined {
+ let query: Query | undefined = undefined;
+
+ try {
+ if (Types.isString(raw)) {
+ if (raw.indexOf('{') === 0) {
+ query = JSON.parse(raw);
+ } else {
+ query = { fullText: raw };
+ }
+ }
+ } catch (ex) {
+ query = undefined;
+ }
+
+ return query;
}
export function hasFilter(query?: Query) {
diff --git a/frontend/app/shared/state/roles.state.spec.ts b/frontend/app/shared/state/roles.state.spec.ts
index 555d276e5..03d5f7b38 100644
--- a/frontend/app/shared/state/roles.state.spec.ts
+++ b/frontend/app/shared/state/roles.state.spec.ts
@@ -17,7 +17,7 @@ import {
versioned
} from '@app/shared/internal';
-import { createRoles } from '../services/roles.service.spec';
+import { createRoles } from './../services/roles.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/rule-events.state.spec.ts b/frontend/app/shared/state/rule-events.state.spec.ts
index e17aac7a9..98b548be1 100644
--- a/frontend/app/shared/state/rule-events.state.spec.ts
+++ b/frontend/app/shared/state/rule-events.state.spec.ts
@@ -18,7 +18,7 @@ import {
RulesService
} from '@app/shared/internal';
-import { createRuleEvent } from '../services/rules.service.spec';
+import { createRuleEvent } from './../services/rules.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/rules.state.spec.ts b/frontend/app/shared/state/rules.state.spec.ts
index afc8afbe5..99109dfdd 100644
--- a/frontend/app/shared/state/rules.state.spec.ts
+++ b/frontend/app/shared/state/rules.state.spec.ts
@@ -18,7 +18,7 @@ import {
versioned
} from '@app/shared/internal';
-import { createRule } from '../services/rules.service.spec';
+import { createRule } from './../services/rules.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/schemas.state.spec.ts b/frontend/app/shared/state/schemas.state.spec.ts
index 6515f2732..87af44e05 100644
--- a/frontend/app/shared/state/schemas.state.spec.ts
+++ b/frontend/app/shared/state/schemas.state.spec.ts
@@ -20,7 +20,7 @@ import {
versioned
} from '@app/shared/internal';
-import { createSchema, createSchemaDetails } from '../services/schemas.service.spec';
+import { createSchema, createSchemaDetails } from './../services/schemas.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shared/state/table-fields.ts b/frontend/app/shared/state/table-fields.ts
index 1822d86f8..af17bcea6 100644
--- a/frontend/app/shared/state/table-fields.ts
+++ b/frontend/app/shared/state/table-fields.ts
@@ -14,7 +14,7 @@ import {
MetaFields,
SchemaDetailsDto,
TableField
-} from '../services/schemas.service';
+} from './../services/schemas.service';
import { UIState } from './ui.state';
diff --git a/frontend/app/shared/state/ui.state.ts b/frontend/app/shared/state/ui.state.ts
index 38249d292..451822764 100644
--- a/frontend/app/shared/state/ui.state.ts
+++ b/frontend/app/shared/state/ui.state.ts
@@ -10,7 +10,6 @@ import { distinctUntilChanged, map } from 'rxjs/operators';
import {
hasAnyLink,
- mergeInto,
State,
Types
} from '@app/framework';
@@ -272,9 +271,9 @@ function getContainer(settings: object, path: string) {
function updateSettings(state: Snapshot, update: Partial) {
const settings = {};
- mergeInto(settings, update.settingsCommon || state.settingsCommon);
- mergeInto(settings, update.settingsShared || state.settingsShared);
- mergeInto(settings, update.settingsUser || state.settingsUser);
+ Types.mergeInto(settings, update.settingsCommon || state.settingsCommon);
+ Types.mergeInto(settings, update.settingsShared || state.settingsShared);
+ Types.mergeInto(settings, update.settingsUser || state.settingsUser);
return { ...state, settings, ...update };
}
\ No newline at end of file
diff --git a/frontend/app/shared/state/workflows.state.spec.ts b/frontend/app/shared/state/workflows.state.spec.ts
index 343ff0bda..8bd7259a3 100644
--- a/frontend/app/shared/state/workflows.state.spec.ts
+++ b/frontend/app/shared/state/workflows.state.spec.ts
@@ -17,7 +17,7 @@ import {
WorkflowsState
} from '@app/shared/internal';
-import { createWorkflows } from '../services/workflows.service.spec';
+import { createWorkflows } from './../services/workflows.service.spec';
import { TestValues } from './_test-helpers';
diff --git a/frontend/app/shell/pages/app/app-area.component.scss b/frontend/app/shell/pages/app/app-area.component.scss
index d1951ab29..e69de29bb 100644
--- a/frontend/app/shell/pages/app/app-area.component.scss
+++ b/frontend/app/shell/pages/app/app-area.component.scss
@@ -1,2 +0,0 @@
-@import '_mixins';
-@import '_vars';
\ No newline at end of file
diff --git a/frontend/app/shell/pages/app/left-menu.component.scss b/frontend/app/shell/pages/app/left-menu.component.scss
index d1951ab29..e69de29bb 100644
--- a/frontend/app/shell/pages/app/left-menu.component.scss
+++ b/frontend/app/shell/pages/app/left-menu.component.scss
@@ -1,2 +0,0 @@
-@import '_mixins';
-@import '_vars';
\ No newline at end of file
diff --git a/frontend/app/shell/pages/forbidden/forbidden-page.component.html b/frontend/app/shell/pages/forbidden/forbidden-page.component.html
new file mode 100644
index 000000000..34f2cf6e2
--- /dev/null
+++ b/frontend/app/shell/pages/forbidden/forbidden-page.component.html
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shell/pages/forbidden/forbidden-page.component.scss b/frontend/app/shell/pages/forbidden/forbidden-page.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shell/pages/forbidden/forbidden-page.component.ts b/frontend/app/shell/pages/forbidden/forbidden-page.component.ts
index ea774b467..6bde5d3f0 100644
--- a/frontend/app/shell/pages/forbidden/forbidden-page.component.ts
+++ b/frontend/app/shell/pages/forbidden/forbidden-page.component.ts
@@ -10,15 +10,8 @@ import { Component } from '@angular/core';
@Component({
selector: 'sqx-forbidden-page',
- template: `
-
-
-
- `
+ styleUrls: ['./forbidden-page.component.scss'],
+ templateUrl: './forbidden-page.component.html'
})
export class ForbiddenPageComponent {
constructor(
diff --git a/frontend/app/shell/pages/home/home-page.component.scss b/frontend/app/shell/pages/home/home-page.component.scss
index ff429bbd1..6380c882c 100644
--- a/frontend/app/shell/pages/home/home-page.component.scss
+++ b/frontend/app/shell/pages/home/home-page.component.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
.card {
& {
position: relative;
diff --git a/frontend/app/shell/pages/internal/apps-menu.component.scss b/frontend/app/shell/pages/internal/apps-menu.component.scss
index f26f0ba08..c36fd6566 100644
--- a/frontend/app/shell/pages/internal/apps-menu.component.scss
+++ b/frontend/app/shell/pages/internal/apps-menu.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
$color-apps-border: #65a6ff;
$color-nav-shadow: rgba(26, 93, 184, .26);
diff --git a/frontend/app/shell/pages/internal/internal-area.component.scss b/frontend/app/shell/pages/internal/internal-area.component.scss
index c7c30c672..89ef6d739 100644
--- a/frontend/app/shell/pages/internal/internal-area.component.scss
+++ b/frontend/app/shell/pages/internal/internal-area.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.navbar {
@include box-shadow(0, 3px, 5px, .13);
display: block;
diff --git a/frontend/app/shell/pages/internal/logo.component.html b/frontend/app/shell/pages/internal/logo.component.html
new file mode 100644
index 000000000..45f21cbe7
--- /dev/null
+++ b/frontend/app/shell/pages/internal/logo.component.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shell/pages/internal/logo.component.scss b/frontend/app/shell/pages/internal/logo.component.scss
new file mode 100644
index 000000000..5238db8dd
--- /dev/null
+++ b/frontend/app/shell/pages/internal/logo.component.scss
@@ -0,0 +1,3 @@
+.loader {
+ @include absolute(12px, null, null, 40px);
+}
\ No newline at end of file
diff --git a/frontend/app/shell/pages/internal/logo.component.ts b/frontend/app/shell/pages/internal/logo.component.ts
index fc495e321..08834d965 100644
--- a/frontend/app/shell/pages/internal/logo.component.ts
+++ b/frontend/app/shell/pages/internal/logo.component.ts
@@ -9,16 +9,8 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
@Component({
selector: 'sqx-logo',
- template: `
-
-
-
- `,
- styles: [`
- .loader {
- position: absolute; top: 12px; left: 40px;
- }`
- ],
+ styleUrls: ['./logo.component.scss'],
+ templateUrl: './logo.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LogoComponent {
diff --git a/frontend/app/shell/pages/internal/notifications-menu.component.scss b/frontend/app/shell/pages/internal/notifications-menu.component.scss
index 8a8d11e5e..810dfdde1 100644
--- a/frontend/app/shell/pages/internal/notifications-menu.component.scss
+++ b/frontend/app/shell/pages/internal/notifications-menu.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.dropdown-menu {
left: auto;
max-height: 500px;
diff --git a/frontend/app/shell/pages/internal/profile-menu.component.scss b/frontend/app/shell/pages/internal/profile-menu.component.scss
index d4d050abf..e74a238a0 100644
--- a/frontend/app/shell/pages/internal/profile-menu.component.scss
+++ b/frontend/app/shell/pages/internal/profile-menu.component.scss
@@ -1,6 +1,3 @@
-@import '_vars';
-@import '_mixins';
-
.user-picture {
margin-right: .5rem;
}
diff --git a/frontend/app/shell/pages/not-found/not-found-page.component.html b/frontend/app/shell/pages/not-found/not-found-page.component.html
new file mode 100644
index 000000000..581416c33
--- /dev/null
+++ b/frontend/app/shell/pages/not-found/not-found-page.component.html
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/frontend/app/shell/pages/not-found/not-found-page.component.scss b/frontend/app/shell/pages/not-found/not-found-page.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/app/shell/pages/not-found/not-found-page.component.ts b/frontend/app/shell/pages/not-found/not-found-page.component.ts
index 55748b9e4..4df1b1a22 100644
--- a/frontend/app/shell/pages/not-found/not-found-page.component.ts
+++ b/frontend/app/shell/pages/not-found/not-found-page.component.ts
@@ -10,15 +10,8 @@ import { Component } from '@angular/core';
@Component({
selector: 'sqx-not-found-page',
- template: `
-
-
-
- `
+ styleUrls: ['./not-found-page.component.scss'],
+ templateUrl: './not-found-page.component.html'
})
export class NotFoundPageComponent {
constructor(
diff --git a/frontend/app/theme/_bootstrap.scss b/frontend/app/theme/_bootstrap.scss
index b1fb039fa..8e496e758 100644
--- a/frontend/app/theme/_bootstrap.scss
+++ b/frontend/app/theme/_bootstrap.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
@import './../../node_modules/bootstrap/scss/mixins/_buttons';
//
diff --git a/frontend/app/theme/_common.scss b/frontend/app/theme/_common.scss
index b7e42acf0..825861359 100644
--- a/frontend/app/theme/_common.scss
+++ b/frontend/app/theme/_common.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
body {
// Default body with padding for fixed navbar and sidebar.
& {
diff --git a/frontend/app/theme/_forms.scss b/frontend/app/theme/_forms.scss
index 7720c1cc6..635be9c4d 100644
--- a/frontend/app/theme/_forms.scss
+++ b/frontend/app/theme/_forms.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
//
// Support for Angular validation states.
//
diff --git a/frontend/app/theme/_lists.scss b/frontend/app/theme/_lists.scss
index 123c2383a..2eed758b6 100644
--- a/frontend/app/theme/_lists.scss
+++ b/frontend/app/theme/_lists.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
//
// Custom list that can either be used with a table or divs.
//
diff --git a/frontend/app/theme/_panels.scss b/frontend/app/theme/_panels.scss
index 5bbbad9a0..98c94f2c7 100644
--- a/frontend/app/theme/_panels.scss
+++ b/frontend/app/theme/_panels.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
@mixin panel-icon {
color: $color-border-dark;
cursor: pointer;
diff --git a/frontend/app/theme/_static.scss b/frontend/app/theme/_static.scss
index 31238cec0..897c2b75d 100644
--- a/frontend/app/theme/_static.scss
+++ b/frontend/app/theme/_static.scss
@@ -1,6 +1,3 @@
-@import '_mixins';
-@import '_vars';
-
//
// Noscript element with warning, when javascript is disabled.
//
diff --git a/frontend/tsconfig.app.json b/frontend/tsconfig.app.json
new file mode 100644
index 000000000..4560f5ea2
--- /dev/null
+++ b/frontend/tsconfig.app.json
@@ -0,0 +1,13 @@
+{
+ "extends": "./tsconfig.json",
+ "files": [
+ "app/app.ts",
+ "app/shims.ts"
+ ],
+ "include": [
+ "app/**/*.d.ts"
+ ],
+ "exclude": [
+ "app/**/*.spec.ts"
+ ]
+}
\ No newline at end of file
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index d048e00b5..27049ebb1 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -1,30 +1,36 @@
{
- "compilerOptions": {
- "allowSyntheticDefaultImports": true,
- "baseUrl": ".",
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "incremental": true,
- "importHelpers": true,
- "lib": ["es6", "esnext", "dom"],
- "moduleResolution": "node",
- "module": "esnext",
- "noEmitHelpers": true,
- "noImplicitAny": true,
- "noUnusedLocals": true,
- "noUnusedParameters": false,
- "removeComments": false,
- "sourceMap": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "target": "es5",
- "paths": {
- "@app*": [
- "app*"
- ]
+ "compilerOptions": {
+ "allowSyntheticDefaultImports": true,
+ "baseUrl": ".",
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "incremental": true,
+ "importHelpers": true,
+ "lib": [
+ "es6",
+ "esnext",
+ "dom"
+ ],
+ "moduleResolution": "node",
+ "module": "esnext",
+ "noEmitHelpers": true,
+ "noImplicitAny": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": false,
+ "removeComments": false,
+ "sourceMap": true,
+ "strictNullChecks": true,
+ "suppressImplicitAnyIndexErrors": true,
+ "target": "es5",
+ "paths": {
+ "@app*": [
+ "app*"
+ ]
+ },
+ },
+ "angularCompilerOptions": {
+ "fullTemplateTypeCheck": true,
+ // https://angular.io/guide/angular-compiler-options
+ "strictInjectionParameters": true
}
- },
- "angularCompilerOptions": {
- "fullTemplateTypeCheck": true
- }
}
\ No newline at end of file
diff --git a/frontend/tsconfig.spec.json b/frontend/tsconfig.spec.json
new file mode 100644
index 000000000..d6cc42f32
--- /dev/null
+++ b/frontend/tsconfig.spec.json
@@ -0,0 +1,3 @@
+{
+ "extends": "./tsconfig.json"
+}
\ No newline at end of file