Browse Source

Graphql fixes2 (#944)

* Fix referencing queries and improve tests.

* Another test.

* Tests fixed.

* Fix inputs

* A few fixes

* GraphQL subscription tests

* Remove log.

* Fix asset-selector naming.
pull/947/head
Sebastian Stehle 4 years ago
committed by GitHub
parent
commit
80b83b549c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs
  2. 51
      backend/src/Squidex/wwwroot/scripts/editor-sdk.js
  3. 2
      backend/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs
  4. 144
      backend/tools/TestSuite/TestSuite.ApiTests/GraphQLSubscriptionTests.cs
  5. 2
      backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj
  6. 11
      frontend/package-lock.json
  7. 2
      frontend/package.json
  8. 22
      frontend/src/app/_theme.html
  9. 2
      frontend/src/app/features/administration/pages/users/user-page.component.html
  10. 2
      frontend/src/app/features/assets/pages/asset-tag-dialog.component.html
  11. 2
      frontend/src/app/features/content/shared/forms/assets-editor.component.html
  12. 11
      frontend/src/app/features/content/shared/forms/field-editor.component.html
  13. 17
      frontend/src/app/features/content/shared/forms/iframe-editor.component.html
  14. 11
      frontend/src/app/features/content/shared/forms/iframe-editor.component.scss
  15. 43
      frontend/src/app/features/content/shared/forms/iframe-editor.component.ts
  16. 2
      frontend/src/app/features/content/shared/forms/stock-photo-editor.component.html
  17. 2
      frontend/src/app/features/rules/shared/triggers/content-changed-trigger.component.html
  18. 6
      frontend/src/app/features/schemas/pages/schema/common/schema-edit-form.component.html
  19. 2
      frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.html
  20. 6
      frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-common.component.html
  21. 2
      frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.html
  22. 2
      frontend/src/app/features/schemas/pages/schema/fields/types/boolean-ui.component.html
  23. 4
      frontend/src/app/features/schemas/pages/schema/fields/types/date-time-ui.component.html
  24. 2
      frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.html
  25. 2
      frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.html
  26. 8
      frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.html
  27. 2
      frontend/src/app/features/schemas/pages/schema/fields/types/tags-ui.component.html
  28. 4
      frontend/src/app/features/schemas/pages/schema/preview/schema-preview-urls-form.component.html
  29. 2
      frontend/src/app/features/schemas/pages/schema/rules/schema-field-rules-form.component.html
  30. 2
      frontend/src/app/features/schemas/pages/schemas/schema-form.component.html
  31. 2
      frontend/src/app/features/settings/pages/clients/client-add-form.component.html
  32. 6
      frontend/src/app/features/settings/pages/more/more-page.component.html
  33. 2
      frontend/src/app/features/settings/pages/roles/role-add-form.component.html
  34. 10
      frontend/src/app/features/settings/pages/settings/settings-page.component.html
  35. 2
      frontend/src/app/features/settings/pages/workflows/workflow-add-form.component.html
  36. 2
      frontend/src/app/features/teams/pages/more/more-page.component.html
  37. 2
      frontend/src/app/framework/angular/forms/editable-title.component.html
  38. 2
      frontend/src/app/framework/angular/forms/editors/autocomplete.component.html
  39. 4
      frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html
  40. 2
      frontend/src/app/framework/angular/forms/editors/dropdown.component.html
  41. 2
      frontend/src/app/framework/angular/forms/editors/tag-editor.component.html
  42. 2
      frontend/src/app/shared/components/app-form.component.html
  43. 8
      frontend/src/app/shared/components/assets/asset-dialog.component.html
  44. 2
      frontend/src/app/shared/components/assets/asset-folder-dialog.component.html
  45. 0
      frontend/src/app/shared/components/assets/asset-selector.component.html
  46. 0
      frontend/src/app/shared/components/assets/asset-selector.component.scss
  47. 8
      frontend/src/app/shared/components/assets/asset-selector.component.ts
  48. 4
      frontend/src/app/shared/components/contents/content-value-editor.component.html
  49. 2
      frontend/src/app/shared/components/forms/geolocation-editor.component.html
  50. 4
      frontend/src/app/shared/components/forms/markdown-editor.component.html
  51. 4
      frontend/src/app/shared/components/forms/rich-editor.component.html
  52. 11
      frontend/src/app/shared/components/references/content-selector.component.ts
  53. 2
      frontend/src/app/shared/components/references/reference-input.component.html
  54. 4
      frontend/src/app/shared/components/search/queries/filter-comparison.component.html
  55. 2
      frontend/src/app/shared/components/search/search-form.component.html
  56. 2
      frontend/src/app/shared/components/team-form.component.html
  57. 2
      frontend/src/app/shared/declarations.ts
  58. 6
      frontend/src/app/shared/module.ts
  59. 10
      frontend/src/app/theme/_bootstrap.scss
  60. 1034
      frontend/src/app/theme/icomoon/demo.html

2
backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs

@ -43,8 +43,6 @@ public sealed class ContentsSharedController : ApiController
/// <remarks>
/// You can read the generated documentation for your app at /api/content/{appName}/docs.
/// </remarks>
[HttpGet]
[HttpPost]
[Route("content/{app}/graphql/")]
[Route("content/{app}/graphql/batch")]
[ApiPermissionOrAnonymous]

51
backend/src/Squidex/wwwroot/scripts/editor-sdk.js

@ -39,6 +39,20 @@ function isFunction(value) {
return typeof value === 'function';
}
function isArrayOfStrings(value) {
if (!Array.isArray(value)) {
return false;
}
for (var i = 0; i < value.length; i++) {
if (!isString(value[i])) {
return false;
}
}
return true;
}
function SquidexPlugin() {
var initHandler;
var initCalled = false;
@ -82,7 +96,7 @@ function SquidexPlugin() {
var editor = {
/**
* Get the current value.
* Get the current context.
*/
getContext: function () {
return context;
@ -140,13 +154,13 @@ function SquidexPlugin() {
};
return editor;
}
function SquidexFormField() {
var context;
var currentConfirm;
var currentPickAssets;
var currentPickContents;
var disabled = false;
var disabledHandler;
var formValue;
@ -218,6 +232,8 @@ function SquidexFormField() {
if (event.source !== window) {
var type = event.data.type;
console.log('Received Message: ' + type);
if (type === 'disabled') {
var newDisabled = event.data.isDisabled;
@ -278,6 +294,14 @@ function SquidexFormField() {
currentPickAssets.callback(event.data.result);
}
}
} else if (type === 'pickContentsResult') {
var correlationId = event.data.correlationId;
if (currentPickContents && currentPickContents.correlationId === correlationId) {
if (typeof currentPickContents.callback === 'function') {
currentPickContents.callback(event.data.result);
}
}
}
}
}
@ -462,6 +486,29 @@ function SquidexFormField() {
}
},
/**
* Shows the dialog to pick assets.
*
* @param {string} schemas: The list of schema names.
* @param {function} callback The callback to invoke when the dialog is completed or closed.
*/
pickContents: function (schemas, callback) {
if (!isFunction(callback) || !isArrayOfStrings(schemas)) {
return;
}
var correlationId = new Date().getTime().toString();
currentPickContents = {
correlationId: correlationId,
callback: callback
};
if (window.parent) {
window.parent.postMessage({ type: 'pickContents', correlationId: correlationId, schemas: schemas }, '*');
}
},
/**
* Register an function that is called when the field is initialized.
*

2
backend/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs

@ -762,7 +762,7 @@ public class AssetTests : IClassFixture<CreatedAppFixture>
if (remaining < buffer.Length)
{
buffer = buffer[..(int)remaining];
buffer = buffer[.. (int)remaining];
}
var bytesRead = await base.ReadAsync(buffer, cancellationToken);

144
backend/tools/TestSuite/TestSuite.ApiTests/GraphQLSubscriptionTests.cs

@ -0,0 +1,144 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Reactive.Linq;
using GraphQL;
using GraphQL.Client.Http;
using GraphQL.Client.Serializer.Newtonsoft;
using Squidex.ClientLibrary;
using Squidex.ClientLibrary.Management;
using TestSuite.Model;
namespace TestSuite.ApiTests;
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row
public class GraphQLSubscriptionTests : IClassFixture<ContentFixture>
{
public ContentFixture _ { get; set; }
public GraphQLSubscriptionTests(ContentFixture fixture)
{
_ = fixture;
}
private sealed class ContentChangesResult
{
public ContentChanges ContentChanges { get; set; }
}
private sealed class ContentChanges
{
public string Id { get; set; }
}
private sealed class AssetChangesResult
{
public AssetChanges AssetChanges { get; set; }
}
private sealed class AssetChanges
{
public string Id { get; set; }
}
[Fact]
public async Task Should_listen_to_content_changes()
{
var client = await CreateClient();
// STEP 1: Subscribe to changes.
var contentChanges = new GraphQLRequest
{
Query = @"
subscription {
contentChanges {
id
}
}"
};
var contentId = Guid.NewGuid().ToString();
var subscriptionStream
= client.CreateSubscriptionStream<ContentChangesResult>(contentChanges);
var publishedContent =
subscriptionStream.Where(x => x.Data.ContentChanges.Id == contentId).Timeout(TimeSpan.FromSeconds(30))
.FirstOrDefaultAsync();
// STEP 2: Create Content.
await _.Contents.CreateAsync(new TestEntityData(), new ContentCreateOptions { Id = contentId });
// STEP 3: Wait for publication.
var publishedResult = await publishedContent;
Assert.Equal(contentId, publishedResult.Data.ContentChanges.Id);
}
[Fact]
public async Task Should_listen_to_asset_changes()
{
var client = await CreateClient();
// STEP 1: Subscribe to changes.
var assetChanges = new GraphQLRequest
{
Query = @"
subscription {
assetChanges {
id
}
}"
};
var assetId = Guid.NewGuid().ToString();
var subscriptionStream
= client.CreateSubscriptionStream<AssetChangesResult>(assetChanges);
var publishedAsset =
subscriptionStream.Where(x => x.Data.AssetChanges.Id == assetId).Timeout(TimeSpan.FromSeconds(30))
.FirstOrDefaultAsync();
// STEP 2: Create asset.
var fileParameter = FileParameter.FromPath("Assets/SampleVideo_1280x720_1mb.mp4");
await using (fileParameter.Data)
{
await _.Assets.UploadAssetAsync(_.AppName, fileParameter, new AssetUploadOptions { Id = assetId });
}
// STEP 3: Wait for publication.
var publishedResult = await publishedAsset;
Assert.Equal(assetId, publishedResult.Data.AssetChanges.Id);
}
private async Task<GraphQLHttpClient> CreateClient()
{
var accessToken = await _.ClientManager.Options.Authenticator.GetBearerTokenAsync(_.AppName, default);
var options = new GraphQLHttpClientOptions
{
EndPoint = new Uri(_.ClientManager.GenerateUrl($"/api/content/{_.AppName}/graphql?access_token={accessToken}"))
};
var client = new GraphQLHttpClient(options, new NewtonsoftJsonSerializer());
await client.InitializeWebsocketConnection();
return client;
}
}

2
backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj

@ -15,6 +15,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Codeuctivity.ImageSharpCompare" Version="2.0.76" />
<PackageReference Include="GraphQL.Client" Version="5.1.0" />
<PackageReference Include="GraphQL.Client.Serializer.Newtonsoft" Version="5.1.0" />
<PackageReference Include="Meziantou.Analyzer" Version="1.0.750">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

11
frontend/package-lock.json

@ -28,7 +28,7 @@
"angular-mentions": "1.5.0",
"angular2-chartjs": "0.5.1",
"babel-polyfill": "6.26.0",
"bootstrap": "5.2.2",
"bootstrap": "5.2.3",
"core-js": "3.25.5",
"cropperjs": "2.0.0-alpha.1",
"date-fns": "2.29.3",
@ -14773,7 +14773,9 @@
"license": "ISC"
},
"node_modules/bootstrap": {
"version": "5.2.2",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz",
"integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==",
"funding": [
{
"type": "github",
@ -14784,7 +14786,6 @@
"url": "https://opencollective.com/bootstrap"
}
],
"license": "MIT",
"peerDependencies": {
"@popperjs/core": "^2.11.6"
}
@ -42433,7 +42434,9 @@
"dev": true
},
"bootstrap": {
"version": "5.2.2",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz",
"integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==",
"requires": {}
},
"boxen": {

2
frontend/package.json

@ -35,7 +35,7 @@
"angular-mentions": "1.5.0",
"angular2-chartjs": "0.5.1",
"babel-polyfill": "6.26.0",
"bootstrap": "5.2.2",
"bootstrap": "5.2.3",
"core-js": "3.25.5",
"cropperjs": "2.0.0-alpha.1",
"date-fns": "2.29.3",

22
frontend/src/app/_theme.html

@ -100,7 +100,7 @@
</ul>
<form class="d-flex">
<input class="form-control me-2" type="text" placeholder="Search">
<input class="form-control me-2" placeholder="Search">
<button type="button" class="btn btn-secondary">Search</button>
</form>
@ -131,7 +131,7 @@
</ul>
<form class="d-flex">
<input class="form-control me-2" type="text" placeholder="Search">
<input class="form-control me-2" placeholder="Search">
<button type="button" class="btn btn-secondary">Search</button>
</form>
@ -676,19 +676,19 @@
<div class="form-group">
<label>Disabled input</label>
<input class="form-control" type="text" placeholder="Disabled input here..." disabled>
<input class="form-control" placeholder="Disabled input here..." disabled>
</div>
<div class="form-group">
<label>Readonly input</label>
<input class="form-control" type="text" placeholder="Disabled input here..." readonly>
<input class="form-control" placeholder="Disabled input here..." readonly>
</div>
<div class="form-group has-success">
<label>Input with success</label>
<input type="text" class="form-control is-valid">
<input class="form-control is-valid">
<div class="valid-feedback">Success! You've done it.</div>
</div>
@ -696,7 +696,7 @@
<div class="form-group has-warning">
<label>Input with warning</label>
<input type="text" class="form-control is-invalid">
<input class="form-control is-invalid">
<div class="invalid-feedback">Shucks, try again.</div>
</div>
@ -708,13 +708,13 @@
<div class="errors">You have entered an invalid value.</div>
</div>
<input type="text" class="form-control is-invalid">
<input class="form-control is-invalid">
</div>
<div class="form-group has-warning">
<label>Input with hint</label>
<input type="text" class="form-control">
<input class="form-control">
<div class="alert alert-hint mt-2">
<i class="icon-info-outline"></i> The app name cannot be changed later.
@ -730,7 +730,7 @@
<div class="form-group">
<label>Default input</label>
<input type="text" class="form-control">
<input class="form-control">
</div>
<div class="form-group">
@ -745,7 +745,7 @@
<div class="input-group mb-3">
<span class="input-group-text">$</span>
<input type="text" class="form-control"
<input class="form-control"
aria-label="Amount (to the nearest dollar)">
<span class="input-group-text">.00</span>
@ -758,7 +758,7 @@
<div class="input-group mb-3">
<button class="btn btn-outline-secondary">Button</button>
<input type="text" class="form-control"
<input class="form-control"
aria-label="Amount (to the nearest dollar)">
<button class="btn btn-outline-secondary">Button</button>

2
frontend/src/app/features/administration/pages/users/user-page.component.html

@ -46,7 +46,7 @@
<sqx-control-errors for="displayName"></sqx-control-errors>
<input type="text" class="form-control" id="displayName" maxlength="100" formControlName="displayName" autocomplete="off" spellcheck="false">
<input class="form-control" id="displayName" maxlength="100" formControlName="displayName" autocomplete="off" spellcheck="false">
</div>
<div class="form-group form-group-section">

2
frontend/src/app/features/assets/pages/asset-tag-dialog.component.html

@ -12,7 +12,7 @@
<sqx-control-errors for="tagName"></sqx-control-errors>
<input type="text" class="form-control" id="tagName" formControlName="tagName" autocomplete="off" sqxFocusOnInit>
<input class="form-control" id="tagName" formControlName="tagName" autocomplete="off" sqxFocusOnInit>
</div>
</ng-container>

2
frontend/src/app/features/content/shared/forms/assets-editor.component.html

@ -80,5 +80,5 @@
</div>
<ng-container *sqxModal="assetsDialog">
<sqx-assets-selector (select)="selectAssets($event)"></sqx-assets-selector>
<sqx-asset-selector (select)="selectAssets($event)"></sqx-asset-selector>
</ng-container>

11
frontend/src/app/features/content/shared/forms/field-editor.component.html

@ -28,13 +28,14 @@
<ng-container *ngIf="field.properties.editorUrl; else noEditor">
<sqx-iframe-editor [url]="field.properties.editorUrl" #editor
[context]="formContext"
[expanded]="isExpanded"
(expandedChange)="toggleExpanded()"
[isExpanded]="isExpanded"
(isExpandedChange)="toggleExpanded()"
[formControlBinding]="$any(fieldForm)"
[formValue]="form.valueChanges | async"
[formIndex]="index"
[formField]="formModel.field.name"
[language]="language.iso2Code">
[language]="language"
[languages]="languages">
</sqx-iframe-editor>
</ng-container>
@ -173,10 +174,10 @@
<ng-container *ngSwitchCase="'String'">
<ng-container [ngSwitch]="field.rawProperties.editor">
<ng-container *ngSwitchCase="'Input'">
<input class="form-control" type="text" [formControl]="$any(fieldForm)" [placeholder]="field.displayPlaceholder">
<input class="form-control" [formControl]="$any(fieldForm)" [placeholder]="field.displayPlaceholder">
</ng-container>
<ng-container *ngSwitchCase="'Slug'">
<input class="form-control" type="text" [formControl]="$any(fieldForm)" [placeholder]="field.displayPlaceholder" sqxTransformInput="Slugify">
<input class="form-control" [formControl]="$any(fieldForm)" [placeholder]="field.displayPlaceholder" sqxTransformInput="Slugify">
</ng-container>
<ng-container *ngSwitchCase="'TextArea'">
<textarea class="form-control" [formControl]="$any(fieldForm)" [placeholder]="field.displayPlaceholder" rows="5"></textarea>

17
frontend/src/app/features/content/shared/forms/iframe-editor.component.html

@ -1,11 +1,20 @@
<div #container>
<div #inner [class.fullscreen]="snapshot.isFullscreen">
<iframe #iframe scrolling="no" width="100%" [style.height]="0" [attr.src]="computedUrl | sqxSafeResourceUrl"></iframe>
<div #inner [class.fullscreen]="snapshot.isFullscreen" [class.expanded]="isExpanded">
<iframe #iframe [scrolling]="!isExpanded ? 'no' : 'yes'" width="100%" [style.height]="0" [attr.src]="computedUrl | sqxSafeResourceUrl"></iframe>
</div>
</div>
<ng-container *sqxModal="assetsDialog">
<sqx-assets-selector
<sqx-asset-selector
(select)="pickAssets($event)">
</sqx-assets-selector>
</sqx-asset-selector>
</ng-container>
<ng-container *sqxModal="contentsDialog">
<sqx-content-selector
(select)="pickContents($event)"
[language]="language"
[languages]="languages"
[schemaNames]="contentsSchemas">
</sqx-content-selector>
</ng-container>

11
frontend/src/app/features/content/shared/forms/iframe-editor.component.scss

@ -17,4 +17,15 @@ iframe {
iframe {
height: 100% !important;
}
}
.expanded {
@include absolute(50px, 0, 0, 0);
overflow: hidden;
iframe {
height: 100% !important;
overflow-x: auto !important;
overflow-y: auto !important;
}
}

43
frontend/src/app/features/content/shared/forms/iframe-editor.component.ts

@ -9,7 +9,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Even
import { AbstractControl } from '@angular/forms';
import { Router } from '@angular/router';
import { DialogModel, DialogService, disabled$, StatefulComponent, Types, value$ } from '@app/framework';
import { AppsState, AssetDto, computeEditorUrl } from '@app/shared';
import { AppLanguageDto, AppsState, AssetDto, computeEditorUrl, ContentDto } from '@app/shared';
interface State {
// True, when the editor is shown as fullscreen.
@ -17,7 +17,7 @@ interface State {
}
@Component({
selector: 'sqx-iframe-editor[context][formField][formIndex][formValue][formControlBinding]',
selector: 'sqx-iframe-editor[context][formField][formIndex][formValue][formControlBinding][language][languages]',
styleUrls: ['./iframe-editor.component.scss'],
templateUrl: './iframe-editor.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
@ -26,7 +26,6 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
private value: any;
private isInitialized = false;
private isDisabled = false;
private assetsCorrelationId: any;
@ViewChild('iframe', { static: false })
public iframe!: ElementRef<HTMLIFrameElement>;
@ -38,10 +37,10 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
public inner!: ElementRef<HTMLElement>;
@Output()
public expandedChange = new EventEmitter();
public isExpandedChange = new EventEmitter();
@Input()
public expanded = false;
public isExpanded = false;
@Input()
public context: any = {};
@ -56,7 +55,10 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
public formIndex?: number | null;
@Input()
public language?: string | null;
public language!: AppLanguageDto;
@Input()
public languages!: ReadonlyArray<AppLanguageDto>;
@Input()
public formControlBinding!: AbstractControl;
@ -73,8 +75,13 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
public computedUrl = '';
public assetsCorrelationId: any;
public assetsDialog = new DialogModel();
public contentsCorrelationId: any;
public contentsSchemas?: string[];
public contentsDialog = new DialogModel();
constructor(changeDetector: ChangeDetectorRef,
private readonly appsState: AppsState,
private readonly dialogs: DialogService,
@ -161,8 +168,8 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
} else if (type === 'expanded') {
const { mode } = event.data;
if (mode !== this.expanded) {
this.expandedChange.emit();
if (mode !== this.isExpanded) {
this.isExpandedChange.emit();
}
} else if (type === 'valueChanged') {
const { value } = event.data;
@ -201,6 +208,14 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
this.assetsCorrelationId = correlationId;
this.assetsDialog.show();
}
} else if (type === 'pickContents') {
const { correlationId, schemas } = event.data;
if (correlationId) {
this.contentsCorrelationId = correlationId;
this.contentsSchemas = schemas;
this.contentsDialog.show();
}
}
this.detectChanges();
@ -217,6 +232,16 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
this.assetsDialog.hide();
}
public pickContents(contents: ReadonlyArray<ContentDto>) {
if (this.contentsCorrelationId) {
this.sendMessage('pickContentsResult', { correlationId: this.contentsCorrelationId, result: contents });
this.contentsCorrelationId = null;
}
this.contentsDialog.hide();
}
public updateValue(obj: any) {
if (!Types.equals(obj, this.value)) {
this.value = obj;
@ -250,7 +275,7 @@ export class IFrameEditorComponent extends StatefulComponent<State> implements O
}
private sendExpanded() {
this.sendMessage('expandedChanged', { expanded: this.expanded });
this.sendMessage('expandedChanged', { expanded: this.isExpanded });
}
private sendDisabled() {

2
frontend/src/app/features/content/shared/forms/stock-photo-editor.component.html

@ -8,7 +8,7 @@
<i class="icon-search"></i>
</button>
<input class="form-control" [formControl]="valueControl" readonly>
<input readonly [disabled]="true" class="form-control" [formControl]="valueControl">
</div>
<div *ngIf="stockPhotoThumbnail | async; let url;" class="preview mt-1" [class.hidden-important]="snapshot.thumbnailStatus === 'Failed'">

2
frontend/src/app/features/rules/shared/triggers/content-changed-trigger.component.html

@ -21,7 +21,7 @@
<span class="truncate">{{triggerSchema.schema.displayName}}</span>
</td>
<td class="text-center">
<input type="text" class="form-control code" placeholder="{{ 'rules.conditionHint' | sqxTranslate }}"
<input class="form-control code" placeholder="{{ 'rules.conditionHint' | sqxTranslate }}"
[disabled]="triggerForm.form.disabled"
[ngModelOptions]="{ updateOn: 'blur' }"
[ngModel]="triggerSchema.condition"

6
frontend/src/app/features/schemas/pages/schema/common/schema-edit-form.component.html

@ -7,7 +7,7 @@
<div class="form-group">
<label for="name">{{ 'common.name' | sqxTranslate }}</label>
<input type="text" class="form-control" id="name" readonly [ngModel]="schema.name" [ngModelOptions]="{ standalone: true }">
<input readonly class="form-control" id="name" [ngModel]="schema.name" [ngModelOptions]="{ standalone: true }">
</div>
<div class="form-group">
@ -15,7 +15,7 @@
<sqx-control-errors for="label"></sqx-control-errors>
<input type="text" class="form-control" id="label" formControlName="label">
<input class="form-control" id="label" formControlName="label">
<sqx-form-hint>{{ 'schemas.schemaLabelHint' | sqxTranslate }}</sqx-form-hint>
</div>
@ -25,7 +25,7 @@
<sqx-control-errors for="hints"></sqx-control-errors>
<textarea type="text" class="form-control" id="hints" formControlName="hints" rows="4"></textarea>
<textarea class="form-control" id="hints" formControlName="hints" rows="4"></textarea>
<sqx-form-hint>{{ 'schemas.schemaHintsHint' | sqxTranslate }}</sqx-form-hint>
</div>

2
frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.html

@ -53,7 +53,7 @@
<div class="form-group">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" formControlName="name" maxlength="40" #nameInput placeholder="{{ 'schemas.field.namePlaceholder' | sqxTranslate }}" sqxFocusOnInit>
<input class="form-control" formControlName="name" maxlength="40" #nameInput placeholder="{{ 'schemas.field.namePlaceholder' | sqxTranslate }}" sqxFocusOnInit>
</div>
<div class="form-group" *ngIf="schema.type !== 'Component' && !parent && (addFieldForm.isContentField | async)">

6
frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-common.component.html

@ -3,7 +3,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldName">{{ 'common.name' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldName" readonly [ngModel]="field.name" [ngModelOptions]="{ standalone: true }">
<input readonly class="form-control" id="{{field.fieldId}}_fieldName" [ngModel]="field.name" [ngModelOptions]="{ standalone: true }">
<sqx-form-hint>
{{ 'schemas.field.nameHint' | sqxTranslate }}
@ -17,7 +17,7 @@
<div class="col-9">
<sqx-control-errors for="label"></sqx-control-errors>
<input type="text" class="form-control" id="{{field.fieldId}}_fieldLabel" maxlength="100" formControlName="label">
<input class="form-control" id="{{field.fieldId}}_fieldLabel" maxlength="100" formControlName="label">
<sqx-form-hint>
{{ 'schemas.field.labelHint' | sqxTranslate }}
@ -31,7 +31,7 @@
<div class="col-9">
<sqx-control-errors for="hints"></sqx-control-errors>
<input type="text" class="form-control" id="{{field.fieldId}}_fieldHints" maxlength="1000" formControlName="hints">
<input class="form-control" id="{{field.fieldId}}_fieldHints" maxlength="1000" formControlName="hints">
<sqx-form-hint>
{{ 'schemas.field.hintsHint' | sqxTranslate }}

2
frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.html

@ -60,6 +60,6 @@
</sqx-field-form-ui>
</div>
<div class="table-items-row-details-tab" [class.hidden]="selectedTab !== 3">
<div class="table-items-row-details-tab" *ngIf="selectedTab === 3">
<sqx-json-more [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-json-more>
</div>

2
frontend/src/app/features/schemas/pages/schema/fields/types/boolean-ui.component.html

@ -3,7 +3,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPlaceholder">{{ 'schemas.field.placeholder' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<input class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<sqx-form-hint>
{{ 'schemas.field.placeholderHint' | sqxTranslate }}

4
frontend/src/app/features/schemas/pages/schema/fields/types/date-time-ui.component.html

@ -3,7 +3,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPlaceholder">{{ 'schemas.field.placeholder' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<input class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<sqx-form-hint>
{{ 'schemas.field.placeholderHint' | sqxTranslate }}
@ -14,7 +14,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldFormat">{{ 'schemas.fieldTypes.dateTime.format' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldFormat" maxlength="100" formControlName="format">
<input class="form-control" id="{{field.fieldId}}_fieldFormat" maxlength="100" formControlName="format">
<sqx-form-hint>
<span [innerHTML]="'schemas.fieldTypes.dateTime.formatHint' | sqxTranslate | sqxMarkdownInline | sqxSafeHtml"></span>

2
frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.html

@ -3,7 +3,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPlaceholder">{{ 'schemas.field.placeholder' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<input class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<sqx-form-hint>
{{ 'schemas.field.placeholderHint' | sqxTranslate }}

2
frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.html

@ -3,7 +3,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPlaceholder">{{ 'schemas.field.placeholder' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<input class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<sqx-form-hint>
{{ 'schemas.field.placeholderHint' | sqxTranslate }}

8
frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.html

@ -32,7 +32,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPattern">{{ 'common.pattern' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldPattern" formControlName="pattern" placeholder="{{ 'schemas.fieldTypes.string.pattern' | sqxTranslate }}" #inputPattern autocomplete="off" autocorrect="off" autocapitalize="off" (focus)="patternsModal.show()">
<input class="form-control" id="{{field.fieldId}}_fieldPattern" formControlName="pattern" placeholder="{{ 'schemas.fieldTypes.string.pattern' | sqxTranslate }}" #inputPattern autocomplete="off" autocorrect="off" autocapitalize="off" (focus)="patternsModal.show()">
<ng-container *ngIf="settings.patterns.length > 0 && (showPatternSuggestions | async)">
<ng-container *sqxModal="patternsModal">
@ -57,7 +57,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPatternMessage">{{ 'schemas.fieldTypes.string.patternMessage' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldPatternMessage" formControlName="patternMessage">
<input class="form-control" id="{{field.fieldId}}_fieldPatternMessage" formControlName="patternMessage">
</div>
</div>
@ -119,7 +119,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldDefaultValue">{{ 'schemas.field.defaultValue' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldDefaultValue" formControlName="defaultValue">
<input class="form-control" id="{{field.fieldId}}_fieldDefaultValue" formControlName="defaultValue">
</div>
</div>
@ -127,7 +127,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldDefaultValues">{{ 'schemas.field.defaultValues' | sqxTranslate }}</label>
<div class="col-9">
<sqx-localized-input type="text" [languages]="languages" formControlName="defaultValues" id="{{field.fieldId}}_fieldDefaultValues"></sqx-localized-input>
<sqx-localized-input [languages]="languages" formControlName="defaultValues" id="{{field.fieldId}}_fieldDefaultValues"></sqx-localized-input>
<sqx-form-hint>
{{ 'schemas.field.defaultValuesHint' | sqxTranslate }}

2
frontend/src/app/features/schemas/pages/schema/fields/types/tags-ui.component.html

@ -3,7 +3,7 @@
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPlaceholder">{{ 'schemas.field.placeholder' | sqxTranslate }}</label>
<div class="col-9">
<input type="text" class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<input class="form-control" id="{{field.fieldId}}_fieldPlaceholder" maxlength="100" formControlName="placeholder">
<sqx-form-hint>
{{ 'schemas.field.placeholderHint' | sqxTranslate }}

4
frontend/src/app/features/schemas/pages/schema/preview/schema-preview-urls-form.component.html

@ -16,13 +16,13 @@
<div class="col col-name">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'schemas.previewUrls.namePlaceholder' | sqxTranslate }}">
<input class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'schemas.previewUrls.namePlaceholder' | sqxTranslate }}">
</div>
<div class="col">
<sqx-control-errors for="url"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="url" placeholder="{{ 'schemas.previewUrls.urlPlaceholder' | sqxTranslate }}">
<input class="form-control" maxlength="1000" formControlName="url" placeholder="{{ 'schemas.previewUrls.urlPlaceholder' | sqxTranslate }}">
</div>
<div class="col-auto">

2
frontend/src/app/features/schemas/pages/schema/rules/schema-field-rules-form.component.html

@ -32,7 +32,7 @@
<div class="col">
<sqx-control-errors for="condition"></sqx-control-errors>
<input type="text" class="form-control" formControlName="condition" placeholder="{{ 'schemas.rules.condition' | sqxTranslate }}">
<input class="form-control" formControlName="condition" placeholder="{{ 'schemas.rules.condition' | sqxTranslate }}">
</div>
<div class="col-auto">

2
frontend/src/app/features/schemas/pages/schemas/schema-form.component.html

@ -18,7 +18,7 @@
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" id="name" formControlName="name" autocomplete="off" sqxTransformInput="LowerCase" sqxFocusOnInit>
<input class="form-control" id="name" formControlName="name" autocomplete="off" sqxTransformInput="LowerCase" sqxFocusOnInit>
<sqx-form-hint>
{{ 'schemas.schemaNameHint' | sqxTranslate }}

2
frontend/src/app/features/settings/pages/clients/client-add-form.component.html

@ -6,7 +6,7 @@
<div class="col">
<sqx-control-errors for="id"></sqx-control-errors>
<input type="text" class="form-control" formControlName="id" maxlength="40" placeholder="{{ 'clients.clientNamePlaceholder' | sqxTranslate }}" autocomplete="off" sqxTransformInput="LowerCase">
<input class="form-control" formControlName="id" maxlength="40" placeholder="{{ 'clients.clientNamePlaceholder' | sqxTranslate }}" autocomplete="off" sqxTransformInput="LowerCase">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-success" [disabled]="addClientForm.hasNoId | async">

6
frontend/src/app/features/settings/pages/more/more-page.component.html

@ -12,7 +12,7 @@
<div class="form-group">
<label for="email">{{ 'common.name' | sqxTranslate }}</label>
<input type="text" class="form-control" disabled readonly [value]="app.name">
<input readonly class="form-control" [value]="app.name">
</div>
<div class="form-group">
@ -20,7 +20,7 @@
<sqx-control-errors for="label"></sqx-control-errors>
<input type="text" class="form-control" id="label" maxlength="100" formControlName="label">
<input class="form-control" id="label" maxlength="100" formControlName="label">
</div>
<div class="form-group">
@ -28,7 +28,7 @@
<sqx-control-errors for="description"></sqx-control-errors>
<input type="text" class="form-control" id="description" maxlength="100" formControlName="description">
<input class="form-control" id="description" maxlength="100" formControlName="description">
</div>
</div>

2
frontend/src/app/features/settings/pages/roles/role-add-form.component.html

@ -7,7 +7,7 @@
<div class="col">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" formControlName="name" maxlength="40" placeholder="{{ 'roles.roleNamePlaceholder' | sqxTranslate }}" autocomplete="off">
<input class="form-control" formControlName="name" maxlength="40" placeholder="{{ 'roles.roleNamePlaceholder' | sqxTranslate }}" autocomplete="off">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-success" [disabled]="addRoleForm.hasNoName | async">

10
frontend/src/app/features/settings/pages/settings/settings-page.component.html

@ -29,19 +29,19 @@
<div class="col-3">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'common.name' | sqxTranslate }}">
<input class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'common.name' | sqxTranslate }}">
</div>
<div class="col">
<sqx-control-errors for="regex"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="regex" placeholder="{{ 'common.pattern' | sqxTranslate }}">
<input class="form-control" maxlength="1000" formControlName="regex" placeholder="{{ 'common.pattern' | sqxTranslate }}">
</div>
<div class="col-4">
<sqx-control-errors for="message"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="message" placeholder="{{ 'common.message' | sqxTranslate }}">
<input class="form-control" maxlength="1000" formControlName="message" placeholder="{{ 'common.message' | sqxTranslate }}">
</div>
<div class="col-auto">
@ -93,13 +93,13 @@
<div class="col-3 ">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'common.name' | sqxTranslate }}">
<input class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'common.name' | sqxTranslate }}">
</div>
<div class="col ">
<sqx-control-errors for="url"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="url" placeholder="{{ 'common.url' | sqxTranslate }}">
<input class="form-control" maxlength="1000" formControlName="url" placeholder="{{ 'common.url' | sqxTranslate }}">
</div>
<div class="col-auto">

2
frontend/src/app/features/settings/pages/workflows/workflow-add-form.component.html

@ -7,7 +7,7 @@
<div class="col">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" formControlName="name" maxlength="40" placeholder="{{ 'workflows.workflowNamePlaceholder' | sqxTranslate }}" autocomplete="off">
<input class="form-control" formControlName="name" maxlength="40" placeholder="{{ 'workflows.workflowNamePlaceholder' | sqxTranslate }}" autocomplete="off">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-success" [disabled]="addWorkflowForm.hasNoName | async">

2
frontend/src/app/features/teams/pages/more/more-page.component.html

@ -14,7 +14,7 @@
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" id="name" maxlength="100" formControlName="name">
<input class="form-control" id="name" maxlength="100" formControlName="name">
</div>
</div>

2
frontend/src/app/framework/angular/forms/editable-title.component.html

@ -5,7 +5,7 @@
<div class="form-group me-2">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" [formControl]="renameForm" [maxLength]="maxLength" sqxFocusOnInit (keydown)="onKeyDown($event)" spellcheck="false">
<input class="form-control" [formControl]="renameForm" [maxLength]="maxLength" sqxFocusOnInit (keydown)="onKeyDown($event)" spellcheck="false">
</div>
</div>
<div class="col-auto">

2
frontend/src/app/framework/angular/forms/editors/autocomplete.component.html

@ -1,5 +1,5 @@
<div class="control-container">
<input type="text" class="form-control" (blur)="blur()" (keydown)="onKeyDown($event)" #input
<input class="form-control" (blur)="blur()" (keydown)="onKeyDown($event)" #input
[sqxFocusOnInit]="autoFocus"
[name]="inputName"
[placeholder]="placeholder"

4
frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html

@ -9,11 +9,11 @@
</button>
</div>
<div class="input-group flex-grow">
<input type="text" class="form-control form-date" [formControl]="dateControl" placeholder="{{ 'common.date' | sqxTranslate }}"
<input class="form-control form-date" [formControl]="dateControl" placeholder="{{ 'common.date' | sqxTranslate }}"
[class.with-buttons]="isDateTimeMode && shouldShowDateTimeModeButton"
(blur)="callTouched()" maxlength="10" #dateInput>
<input type="text" class="form-control form-time" [formControl]="timeControl" placeholder="{{ 'common.time' | sqxTranslate }}" (blur)="callTouched()" *ngIf="isDateTimeMode">
<input class="form-control form-time" [formControl]="timeControl" placeholder="{{ 'common.time' | sqxTranslate }}" (blur)="callTouched()" *ngIf="isDateTimeMode">
</div>
<button type="button" class="btn btn-text-secondary btn-sm btn-clear" [class.hidden]="!hasValue"

2
frontend/src/app/framework/angular/forms/editors/dropdown.component.html

@ -1,5 +1,5 @@
<div class="selection">
<input type="text" class="form-select" [disabled]="snapshot.isDisabled" (click)="openModal()" readonly (keydown)="onKeyDown($event)" #input
<input readonly class="form-select" [disabled]="snapshot.isDisabled" (click)="openModal()" (keydown)="onKeyDown($event)" #input
autocomplete="off"
autocorrect="off"
autocapitalize="off">

2
frontend/src/app/framework/angular/forms/editors/tag-editor.component.html

@ -14,7 +14,7 @@
{{item}} <i class="icon-close" (click)="remove(i)"></i>
</span>
<input type="text" class="blank text-input" #input
<input class="blank text-input" #input
(blur)="markTouched()" (copy)="onCopy($event)" (cut)="onCut($event)" (focus)="focus()" (keydown)="onKeyDown($event)" (paste)="onPaste($event)"
[name]="inputName"
[placeholder]="placeholder | sqxTranslate"

2
frontend/src/app/shared/components/app-form.component.html

@ -18,7 +18,7 @@
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" id="name" formControlName="name" autocomplete="off" sqxTransformInput="LowerCase" sqxFocusOnInit>
<input class="form-control" id="name" formControlName="name" autocomplete="off" sqxTransformInput="LowerCase" sqxFocusOnInit>
<sqx-form-hint>
{{ 'apps.appNameHint' | sqxTranslate }}

8
frontend/src/app/shared/components/assets/asset-dialog.component.html

@ -110,7 +110,7 @@
<sqx-control-errors for="fileName"></sqx-control-errors>
<input type="text" class="form-control" id="fileName" formControlName="fileName" spellcheck="false">
<input class="form-control" id="fileName" formControlName="fileName" spellcheck="false">
</div>
<div class="form-group">
@ -118,7 +118,7 @@
<sqx-control-errors for="slug"></sqx-control-errors>
<input type="text" class="form-control slug" id="slug" formControlName="slug" sqxTransformInput="Slugify" spellcheck="false">
<input class="form-control slug" id="slug" formControlName="slug" sqxTransformInput="Slugify" spellcheck="false">
<button type="button" class="btn btn-text-secondary btn-sm slug-generate" (click)="generateSlug()">
{{ 'common.generate' | sqxTranslate }}
@ -140,13 +140,13 @@
<div class="col col-name pe-1">
<sqx-control-errors for="name" fieldName="Name"></sqx-control-errors>
<input type="text" class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'common.name' | sqxTranslate }}" spellcheck="false">
<input class="form-control" maxlength="1000" formControlName="name" placeholder="{{ 'common.name' | sqxTranslate }}" spellcheck="false">
</div>
<div class="col pe-1">
<sqx-control-errors for="value" fieldName="Value"></sqx-control-errors>
<input type="text" class="form-control" formControlName="value" placeholder="{{ 'common.value' | sqxTranslate }}">
<input class="form-control" formControlName="value" placeholder="{{ 'common.value' | sqxTranslate }}">
</div>
<div class="col-auto col-options">

2
frontend/src/app/shared/components/assets/asset-folder-dialog.component.html

@ -17,7 +17,7 @@
<sqx-control-errors for="folderName"></sqx-control-errors>
<input type="text" class="form-control" id="folderName" formControlName="folderName" autocomplete="off" sqxFocusOnInit>
<input class="form-control" id="folderName" formControlName="folderName" autocomplete="off" sqxFocusOnInit>
</div>
<div class="form-group">

0
frontend/src/app/shared/components/assets/assets-selector.component.html → frontend/src/app/shared/components/assets/asset-selector.component.html

0
frontend/src/app/shared/components/assets/assets-selector.component.scss → frontend/src/app/shared/components/assets/asset-selector.component.scss

8
frontend/src/app/shared/components/assets/assets-selector.component.ts → frontend/src/app/shared/components/assets/asset-selector.component.ts

@ -21,15 +21,15 @@ interface State {
}
@Component({
selector: 'sqx-assets-selector',
styleUrls: ['./assets-selector.component.scss'],
templateUrl: './assets-selector.component.html',
selector: 'sqx-asset-selector',
styleUrls: ['./asset-selector.component.scss'],
templateUrl: './asset-selector.component.html',
providers: [
ComponentAssetsState,
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AssetsSelectorComponent extends StatefulComponent<State> implements OnInit {
export class AssetSelectorComponent extends StatefulComponent<State> implements OnInit {
@Output()
public select = new EventEmitter<ReadonlyArray<AssetDto>>();

4
frontend/src/app/shared/components/contents/content-value-editor.component.html

@ -19,10 +19,10 @@
<ng-container *ngSwitchCase="'String'">
<ng-container [ngSwitch]="field.rawProperties.editor">
<ng-container *ngSwitchCase="'Input'">
<input class="form-control" type="text" [formControlName]="field.name" [placeholder]="field.displayPlaceholder">
<input class="form-control" [formControlName]="field.name" [placeholder]="field.displayPlaceholder">
</ng-container>
<ng-container *ngSwitchCase="'Slug'">
<input class="form-control" type="text" [formControlName]="field.name" [placeholder]="field.displayPlaceholder" sqxTransformInput="Slugify">
<input class="form-control" [formControlName]="field.name" [placeholder]="field.displayPlaceholder" sqxTransformInput="Slugify">
</ng-container>
<ng-container *ngSwitchCase="'Dropdown'">
<select class="form-select" [formControlName]="field.name">

2
frontend/src/app/shared/components/forms/geolocation-editor.component.html

@ -5,7 +5,7 @@
<form [class.hidden]="snapshot.isMapHidden">
<div class="editor" #editor></div>
<input [class.hidden]="!isGoogleMaps" class="form-control search-control" type="text" [disabled]="snapshot.isDisabled" placeholder="{{ 'common.searchGoogleMaps' | sqxTranslate }}" #searchBox>
<input [class.hidden]="!isGoogleMaps" class="form-control search-control" [disabled]="snapshot.isDisabled" placeholder="{{ 'common.searchGoogleMaps' | sqxTranslate }}" #searchBox>
</form>
<div class="row mt-2">

4
frontend/src/app/shared/components/forms/markdown-editor.component.html

@ -7,9 +7,9 @@
</div>
<ng-container *sqxModal="assetsDialog">
<sqx-assets-selector
<sqx-asset-selector
(select)="insertAssets($event)">
</sqx-assets-selector>
</sqx-asset-selector>
</ng-container>
<ng-container *sqxModal="contentsDialog">

4
frontend/src/app/shared/components/forms/rich-editor.component.html

@ -3,9 +3,9 @@
</div>
<ng-container *sqxModal="assetsDialog">
<sqx-assets-selector
<sqx-asset-selector
(select)="insertAssets($event)">
</sqx-assets-selector>
</sqx-asset-selector>
</ng-container>
<ng-container *sqxModal="contentsDialog">

11
frontend/src/app/shared/components/references/content-selector.component.ts

@ -33,6 +33,9 @@ export class ContentSelectorComponent extends ResourceOwner implements OnInit {
@Input()
public schemaIds?: ReadonlyArray<string>;
@Input()
public schemaNames?: ReadonlyArray<string>;
@Input()
public language!: LanguageDto;
@ -80,10 +83,14 @@ export class ContentSelectorComponent extends ResourceOwner implements OnInit {
this.updateModel();
}));
this.schemas = this.schemasState.snapshot.schemas.filter(x => x.canReadContents);
this.schemas = this.schemasState.snapshot.schemas.filter(x => x.type === 'Default' && x.canReadContents);
if (this.schemaIds && this.schemaIds.length > 0) {
this.schemas = this.schemas.filter(x => x.type === 'Default' && x.canReadContents && this.schemaIds!.includes(x.id));
this.schemas = this.schemas.filter(x => this.schemaIds!.includes(x.id));
}
if (this.schemaNames && this.schemaNames.length > 0) {
this.schemas = this.schemas.filter(x => this.schemaNames!.includes(x.name));
}
this.selectSchema(this.schemas[0]);

2
frontend/src/app/shared/components/references/reference-input.component.html

@ -1,5 +1,5 @@
<div class="input-group">
<input class="form-control" readonly [ngModel]="snapshot.selectedName" (click)="openDialog()" />
<input readonly class="form-control" [ngModel]="snapshot.selectedName" (click)="openDialog()" />
<button type="button" class="btn btn-outline-secondary" [disabled]="snapshot.isDisabled" (click)="selectContent()" sqxStopClick>
<i class="icon-close"></i>

4
frontend/src/app/shared/components/search/queries/filter-comparison.component.html

@ -69,7 +69,7 @@
</sqx-dropdown>
</ng-container>
<ng-container *ngSwitchCase="'String'">
<input type="text" class="form-control" *ngIf="!field.schema.extra"
<input class="form-control" *ngIf="!field.schema.extra"
[ngModel]="filter.value"
(ngModelChange)="changeValue($event)" />
</ng-container>
@ -94,7 +94,7 @@
</sqx-dropdown>
</ng-container>
<ng-template #noPermission>
<input type="text" class="form-control"
<input class="form-control"
[ngModel]="filter.value"
(ngModelChange)="changeValue($event)" />
</ng-template>

2
frontend/src/app/shared/components/search/search-form.component.html

@ -120,7 +120,7 @@
<div class="form-group mt-2">
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" id="appName" formControlName="name" autocomplete="off" sqxFocusOnInit>
<input class="form-control" id="appName" formControlName="name" autocomplete="off" sqxFocusOnInit>
</div>
<div class="form-check">

2
frontend/src/app/shared/components/team-form.component.html

@ -12,7 +12,7 @@
<sqx-control-errors for="name"></sqx-control-errors>
<input type="text" class="form-control" id="name" formControlName="name" autocomplete="off" sqxTransformInput="LowerCase" sqxFocusOnInit>
<input class="form-control" id="name" formControlName="name" autocomplete="off" sqxTransformInput="LowerCase" sqxFocusOnInit>
<sqx-form-hint>
{{ 'teams.teamNameHint' | sqxTranslate }}

2
frontend/src/app/shared/declarations.ts

@ -13,11 +13,11 @@ export * from './components/assets/asset-folder-dropdown.component';
export * from './components/assets/asset-folder.component';
export * from './components/assets/asset-history.component';
export * from './components/assets/asset-path.component';
export * from './components/assets/asset-selector.component';
export * from './components/assets/asset-text-editor.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/image-cropper.component';
export * from './components/assets/image-focus-point.component';
export * from './components/assets/pipes';

6
frontend/src/app/shared/module.ts

@ -13,7 +13,7 @@ import { MentionModule } from 'angular-mentions';
import { ChartModule } from 'angular2-chartjs';
import { NgxDocViewerModule } from 'ngx-doc-viewer';
import { SqxFrameworkModule } from '@app/framework';
import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCardComponent, ApiTrafficCardComponent, ApiTrafficSummaryCardComponent, AppFormComponent, AppLanguagesService, AppMustExistGuard, AppsService, AppsState, AssetComponent, AssetDialogComponent, AssetFolderComponent, AssetFolderDialogComponent, AssetFolderDropdownComponent, AssetFolderDropdownItemComponent, AssetHistoryComponent, AssetPathComponent, AssetPreviewUrlPipe, AssetScriptsState, AssetsListComponent, AssetsSelectorComponent, AssetsService, AssetsState, AssetTextEditorComponent, AssetUploaderComponent, AssetUploaderState, AssetUploadsCountCardComponent, AssetUploadsSizeCardComponent, AssetUploadsSizeSummaryCardComponent, AssetUrlPipe, AuthInterceptor, AuthService, AutoSaveService, BackupsService, BackupsState, ClientsService, ClientsState, CommentComponent, CommentsComponent, CommentsService, ContentListCellDirective, ContentListCellResizeDirective, ContentListFieldComponent, ContentListHeaderComponent, ContentListWidthDirective, ContentMustExistGuard, ContentsColumnsPipe, ContentSelectorComponent, ContentSelectorItemComponent, ContentsService, ContentsState, ContentStatusComponent, ContentValueComponent, ContentValueEditorComponent, ContributorsService, ContributorsState, FileIconPipe, FilterComparisonComponent, FilterLogicalComponent, FilterNodeComponent, FilterOperatorPipe, GeolocationEditorComponent, HelpComponent, HelpMarkdownPipe, HelpService, HistoryComponent, HistoryListComponent, HistoryMessagePipe, HistoryService, IFrameCardComponent, ImageCropperComponent, ImageFocusPointComponent, LanguagesService, LanguagesState, LoadAppsGuard, LoadLanguagesGuard, LoadSchemasGuard, LoadTeamsGuard, MarkdownEditorComponent, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard, NewsService, NotifoComponent, PlansService, PlansState, PreviewableType, QueryComponent, QueryListComponent, QueryPathComponent, RandomCatCardComponent, RandomDogCardComponent, ReferenceInputComponent, RichEditorComponent, RolesService, RolesState, RuleEventsState, RuleMustExistGuard, RuleSimulatorState, RulesService, RulesState, SavedQueriesComponent, SchemaCategoryComponent, SchemaMustExistGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SchemasService, SchemasState, SchemaTagSource, SearchFormComponent, SearchService, SortingComponent, StockPhotoService, SupportCardComponent, TableHeaderComponent, TeamFormComponent, TeamMustExistGuard, TeamsService, TeamsState, TemplatesService, TemplatesState, TranslationsService, TranslationStatusComponent, UIService, UIState, UnsetAppGuard, UnsetTeamGuard, UsagesService, UserDtoPicture, UserIdPicturePipe, UserNamePipe, UserNameRefPipe, UserPicturePipe, UserPictureRefPipe, UsersProviderService, UsersService, WatchingUsersComponent, WorkflowsService, WorkflowsState } from './declarations';
import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCardComponent, ApiTrafficCardComponent, ApiTrafficSummaryCardComponent, AppFormComponent, AppLanguagesService, AppMustExistGuard, AppsService, AppsState, AssetComponent, AssetDialogComponent, AssetFolderComponent, AssetFolderDialogComponent, AssetFolderDropdownComponent, AssetFolderDropdownItemComponent, AssetHistoryComponent, AssetPathComponent, AssetPreviewUrlPipe, AssetScriptsState, AssetsListComponent, AssetSelectorComponent, AssetsService, AssetsState, AssetTextEditorComponent, AssetUploaderComponent, AssetUploaderState, AssetUploadsCountCardComponent, AssetUploadsSizeCardComponent, AssetUploadsSizeSummaryCardComponent, AssetUrlPipe, AuthInterceptor, AuthService, AutoSaveService, BackupsService, BackupsState, ClientsService, ClientsState, CommentComponent, CommentsComponent, CommentsService, ContentListCellDirective, ContentListCellResizeDirective, ContentListFieldComponent, ContentListHeaderComponent, ContentListWidthDirective, ContentMustExistGuard, ContentsColumnsPipe, ContentSelectorComponent, ContentSelectorItemComponent, ContentsService, ContentsState, ContentStatusComponent, ContentValueComponent, ContentValueEditorComponent, ContributorsService, ContributorsState, FileIconPipe, FilterComparisonComponent, FilterLogicalComponent, FilterNodeComponent, FilterOperatorPipe, GeolocationEditorComponent, HelpComponent, HelpMarkdownPipe, HelpService, HistoryComponent, HistoryListComponent, HistoryMessagePipe, HistoryService, IFrameCardComponent, ImageCropperComponent, ImageFocusPointComponent, LanguagesService, LanguagesState, LoadAppsGuard, LoadLanguagesGuard, LoadSchemasGuard, LoadTeamsGuard, MarkdownEditorComponent, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard, NewsService, NotifoComponent, PlansService, PlansState, PreviewableType, QueryComponent, QueryListComponent, QueryPathComponent, RandomCatCardComponent, RandomDogCardComponent, ReferenceInputComponent, RichEditorComponent, RolesService, RolesState, RuleEventsState, RuleMustExistGuard, RuleSimulatorState, RulesService, RulesState, SavedQueriesComponent, SchemaCategoryComponent, SchemaMustExistGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SchemasService, SchemasState, SchemaTagSource, SearchFormComponent, SearchService, SortingComponent, StockPhotoService, SupportCardComponent, TableHeaderComponent, TeamFormComponent, TeamMustExistGuard, TeamsService, TeamsState, TemplatesService, TemplatesState, TranslationsService, TranslationStatusComponent, UIService, UIState, UnsetAppGuard, UnsetTeamGuard, UsagesService, UserDtoPicture, UserIdPicturePipe, UserNamePipe, UserNameRefPipe, UserPicturePipe, UserPictureRefPipe, UsersProviderService, UsersService, WatchingUsersComponent, WorkflowsService, WorkflowsState } from './declarations';
@NgModule({
imports: [
@ -40,8 +40,8 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard
AssetHistoryComponent,
AssetPathComponent,
AssetPreviewUrlPipe,
AssetSelectorComponent,
AssetsListComponent,
AssetsSelectorComponent,
AssetTextEditorComponent,
AssetUploaderComponent,
AssetUploadsCountCardComponent,
@ -115,8 +115,8 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard
AssetFolderDropdownComponent,
AssetPathComponent,
AssetPreviewUrlPipe,
AssetSelectorComponent,
AssetsListComponent,
AssetsSelectorComponent,
AssetUploaderComponent,
AssetUploadsCountCardComponent,
AssetUploadsSizeCardComponent,

10
frontend/src/app/theme/_bootstrap.scss

@ -675,3 +675,13 @@ $icon-size: 4.5rem;
border-bottom-width: 1px;
}
}
.form-control {
&[readonly] {
color: $input-disabled-color;
background-color: $input-disabled-bg;
border-color: $input-disabled-border-color;
border-radius: inherit;
opacity: 1;
}
}

1034
frontend/src/app/theme/icomoon/demo.html

File diff suppressed because it is too large
Loading…
Cancel
Save