From 13163426b4aac62605d5bcb8bc70223044d85281 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Mon, 5 Dec 2022 21:00:03 +0100 Subject: [PATCH 1/3] Small screen improvements (#947) * Typings for editor SDK. * Fix line height and cut text. * Improve integrated documentation for .NET SDK * Add access token to preview URL. * Improve layout system for small screens. --- backend/i18n/frontend_en.json | 4 + backend/i18n/frontend_it.json | 4 + backend/i18n/frontend_nl.json | 4 + backend/i18n/frontend_zh.json | 4 + backend/i18n/source/backend_en.json | 2 +- backend/i18n/source/frontend_en.json | 4 + .../Contents/Queries/ContentQueryParser.cs | 52 +++-- backend/src/Squidex.Shared/Texts.it.resx | 6 +- backend/src/Squidex.Shared/Texts.nl.resx | 6 +- backend/src/Squidex.Shared/Texts.resx | 6 +- backend/src/Squidex.Shared/Texts.zh.resx | 6 +- .../Squidex/wwwroot/scripts/editor-sdk.d.ts | 199 ++++++++++++++++ .../pages/users/user-page.component.html | 2 +- .../comments/comments-page.component.html | 2 +- .../content-history-page.component.html | 2 +- .../shared/list/content.component.scss | 2 +- .../shared/preview-button.component.ts | 9 +- .../references/reference-item.component.html | 8 +- .../client-connect-form.component.html | 55 ++++- .../client-connect-form.component.scss | 6 + .../clients/client-connect-form.component.ts | 34 +-- .../angular/language-selector.stories.tsx | 2 +- .../angular/layout-container.directive.ts | 17 +- .../framework/angular/layout.component.html | 32 ++- .../app/framework/angular/layout.component.ts | 106 ++++++--- .../app/framework/angular/layout.stories.tsx | 216 ++++++++++++++++++ .../app/framework/angular/loader.stories.ts | 2 +- .../framework/angular/status-icon.stories.tsx | 4 +- .../forms/markdown-editor.component.scss | 1 - .../components/help/help.component.html | 2 +- .../components/history/history.component.html | 2 +- frontend/src/app/theme/_mixins.scss | 20 +- frontend/src/app/theme/_panels2.scss | 70 ++++-- frontend/src/app/theme/_vars.scss | 10 +- frontend/src/config/webpack.config.js | 6 +- 35 files changed, 742 insertions(+), 165 deletions(-) create mode 100644 backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts create mode 100644 frontend/src/app/framework/angular/layout.stories.tsx diff --git a/backend/i18n/frontend_en.json b/backend/i18n/frontend_en.json index 69dcec1d9..255a2c651 100644 --- a/backend/i18n/frontend_en.json +++ b/backend/i18n/frontend_en.json @@ -188,12 +188,16 @@ "clients.connectWizard.manuallyTokenHint": "Tokens usally expire after 30days, but you can request multiple tokens.", "clients.connectWizard.postManDocs": "Start with the Postman tutorial in the [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", "clients.connectWizard.sdk": "Connect to your App with SDK", + "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "You need another SDK?", "clients.connectWizard.sdkHelpLink": "Contact us in the Support Forum", "clients.connectWizard.sdkHint": "Download an SDK and establish a connection to this app.", "clients.connectWizard.sdkStep1": "Install the .NET SDK", "clients.connectWizard.sdkStep1Download": "The SDK is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", "clients.connectWizard.sdkStep2": "Create a client manager", + "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Setup client", "clients.connectWizard.step1Title": "Choose connection method", "clients.connectWizard.step2Title": "Connect", diff --git a/backend/i18n/frontend_it.json b/backend/i18n/frontend_it.json index 017d15e91..bf5fcd697 100644 --- a/backend/i18n/frontend_it.json +++ b/backend/i18n/frontend_it.json @@ -188,12 +188,16 @@ "clients.connectWizard.manuallyTokenHint": "Solitamente i Token scadono dopo 30 giorni, ma puoi richiedere token multipli.", "clients.connectWizard.postManDocs": "Per il tutorial Postman inizia da questo link [Documentazione](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", "clients.connectWizard.sdk": "Connetti la tua APP utilizzando SDK", + "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "Hai bisogno di un altro SDK?", "clients.connectWizard.sdkHelpLink": "Contattaci nel Forum di assistenza", "clients.connectWizard.sdkHint": "Scarica l'SDK e connetti quest'app.", "clients.connectWizard.sdkStep1": "Installa .NET SDK", "clients.connectWizard.sdkStep1Download": "L'SDK è disponibile su [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", "clients.connectWizard.sdkStep2": "Crea un client manager", + "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Setup client", "clients.connectWizard.step1Title": "Scegli la tipologia di connessione", "clients.connectWizard.step2Title": "Collega", diff --git a/backend/i18n/frontend_nl.json b/backend/i18n/frontend_nl.json index 67b81d8be..6cfcc8cb4 100644 --- a/backend/i18n/frontend_nl.json +++ b/backend/i18n/frontend_nl.json @@ -188,12 +188,16 @@ "clients.connectWizard.manuallyTokenHint": "Tokens vervallen gewoonlijk na 30 dagen, maar je kunt meerdere tokens aanvragen.", "clients.connectWizard.postManDocs": "Begin met de Postman-tutorial in de [Documentatie] (https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", "clients.connectWizard.sdk": "Maak verbinding met uw app met SDK", + "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "Heb je een andere SDK nodig?", "clients.connectWizard.sdkHelpLink": "Neem contact met ons op in het ondersteuningsforum", "clients.connectWizard.sdkHint": "Download een SDK en maak verbinding met deze app.", "clients.connectWizard.sdkStep1": "Installeer de .NET SDK", "clients.connectWizard.sdkStep1Download": "De SDK is beschikbaar op [nuget] (https://www.nuget.org/packages/Squidex.ClientLibrary/)", "clients.connectWizard.sdkStep2": "Maak een klantenbeheerder", + "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Client instellen", "clients.connectWizard.step1Title": "Kies verbindingsmethode", "clients.connectWizard.step2Title": "Verbinden", diff --git a/backend/i18n/frontend_zh.json b/backend/i18n/frontend_zh.json index 7b6f0be35..fde0b2fa9 100644 --- a/backend/i18n/frontend_zh.json +++ b/backend/i18n/frontend_zh.json @@ -188,12 +188,16 @@ "clients.connectWizard.manuallyTokenHint": "令牌通常会在 30 天后过期,但您可以请求多个令牌。", "clients.connectWizard.postManDocs": "从 [文档](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman) 中的 Postman 教程开始。", "clients.connectWizard.sdk": "使用 SDK 连接到您的应用程序", + "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "你需要另一个 SDK?", "clients.connectWizard.sdkHelpLink": "在支持论坛联系我们", "clients.connectWizard.sdkHint": "下载 SDK 并建立与此应用程序的连接。", "clients.connectWizard.sdkStep1": "安装.NET SDK", "clients.connectWizard.sdkStep1Download": "SDK 可在 [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", "clients.connectWizard.sdkStep2": "创建客户端管理器", + "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "设置客户端", "clients.connectWizard.step1Title": "选择连接方式", "clients.connectWizard.step2Title": "连接", diff --git a/backend/i18n/source/backend_en.json b/backend/i18n/source/backend_en.json index 3f302b4dd..80c7318bf 100644 --- a/backend/i18n/source/backend_en.json +++ b/backend/i18n/source/backend_en.json @@ -215,6 +215,7 @@ "history.apps.clientAdded": "added client {[Id]} to app", "history.apps.clientRevoked": "revoked client {[Id]}", "history.apps.clientUpdated": "updated client {[Id]}", + "history.apps.common.updated": "updated general settings", "history.apps.contributoreAssigned": "assigned {user:[Contributor]} as {[Role]}", "history.apps.contributoreRemoved": "removed {user:[Contributor]} from app", "history.apps.created": "created the app.", @@ -231,7 +232,6 @@ "history.apps.roleUpdated": "updated role {[Name]}", "history.apps.settingsUpdated": "updated UI settings", "history.apps.transfered": "updated app to client", - "history.apps.updated": "updated general settings", "history.apps.workflowAdded": "added workflow {[Name]}.", "history.apps.workflowDeleted": "deleted a workflow.", "history.apps.workflowUpdated": "updated a workflow.", diff --git a/backend/i18n/source/frontend_en.json b/backend/i18n/source/frontend_en.json index 69dcec1d9..255a2c651 100644 --- a/backend/i18n/source/frontend_en.json +++ b/backend/i18n/source/frontend_en.json @@ -188,12 +188,16 @@ "clients.connectWizard.manuallyTokenHint": "Tokens usally expire after 30days, but you can request multiple tokens.", "clients.connectWizard.postManDocs": "Start with the Postman tutorial in the [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", "clients.connectWizard.sdk": "Connect to your App with SDK", + "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "You need another SDK?", "clients.connectWizard.sdkHelpLink": "Contact us in the Support Forum", "clients.connectWizard.sdkHint": "Download an SDK and establish a connection to this app.", "clients.connectWizard.sdkStep1": "Install the .NET SDK", "clients.connectWizard.sdkStep1Download": "The SDK is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", "clients.connectWizard.sdkStep2": "Create a client manager", + "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Setup client", "clients.connectWizard.step1Title": "Choose connection method", "clients.connectWizard.step2Title": "Connect", diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs index 821b2a81f..1546c3128 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs @@ -80,38 +80,40 @@ public class ContentQueryParser query.Filter = await GeoQueryTransformer.TransformAsync(query.Filter, context, schema, textIndex); } - if (!string.IsNullOrWhiteSpace(query.FullText)) + if (string.IsNullOrWhiteSpace(query.FullText)) { - if (schema == null) - { - ThrowHelper.InvalidOperationException(); - return; - } + return; + } - var textQuery = new TextQuery(query.FullText, 1000) - { - PreferredSchemaId = schema.Id - }; + if (schema == null) + { + ThrowHelper.InvalidOperationException(); + return; + } - var fullTextIds = await textIndex.SearchAsync(context.App, textQuery, context.Scope()); - var fullTextFilter = ClrFilter.Eq("id", "__notfound__"); + var textQuery = new TextQuery(query.FullText, 1000) + { + PreferredSchemaId = schema.Id + }; - if (fullTextIds?.Any() == true) - { - fullTextFilter = ClrFilter.In("id", fullTextIds.Select(x => x.ToString()).ToList()); - } + var fullTextIds = await textIndex.SearchAsync(context.App, textQuery, context.Scope()); + var fullTextFilter = ClrFilter.Eq("id", "__notfound__"); - if (query.Filter != null) - { - query.Filter = ClrFilter.And(query.Filter, fullTextFilter); - } - else - { - query.Filter = fullTextFilter; - } + if (fullTextIds?.Any() == true) + { + fullTextFilter = ClrFilter.In("id", fullTextIds.Select(x => x.ToString()).ToList()); + } - query.FullText = null; + if (query.Filter != null) + { + query.Filter = ClrFilter.And(query.Filter, fullTextFilter); } + else + { + query.Filter = fullTextFilter; + } + + query.FullText = null; } private async Task ParseClrQueryAsync(Context context, Q q, ISchemaEntity? schema) diff --git a/backend/src/Squidex.Shared/Texts.it.resx b/backend/src/Squidex.Shared/Texts.it.resx index 61a98269c..b0b521fc0 100644 --- a/backend/src/Squidex.Shared/Texts.it.resx +++ b/backend/src/Squidex.Shared/Texts.it.resx @@ -730,6 +730,9 @@ Aggiornato client {[Id]} + + updated general settings + Associato {user:[Contributor]} al ruolo {[Role]} @@ -778,9 +781,6 @@ updated app to client - - updated general settings - added workflow {[Name]}. diff --git a/backend/src/Squidex.Shared/Texts.nl.resx b/backend/src/Squidex.Shared/Texts.nl.resx index 0a686470c..f2f2cb5ce 100644 --- a/backend/src/Squidex.Shared/Texts.nl.resx +++ b/backend/src/Squidex.Shared/Texts.nl.resx @@ -730,6 +730,9 @@ bijgewerkte client {[Id]} + + updated general settings + heeft {user:[Contributor]} toegewezen als {[Role]} @@ -778,9 +781,6 @@ updated app to client - - updated general settings - added workflow {[Name]}. diff --git a/backend/src/Squidex.Shared/Texts.resx b/backend/src/Squidex.Shared/Texts.resx index 257f258ac..a8c6b3f3c 100644 --- a/backend/src/Squidex.Shared/Texts.resx +++ b/backend/src/Squidex.Shared/Texts.resx @@ -730,6 +730,9 @@ updated client {[Id]} + + updated general settings + assigned {user:[Contributor]} as {[Role]} @@ -778,9 +781,6 @@ updated app to client - - updated general settings - added workflow {[Name]}. diff --git a/backend/src/Squidex.Shared/Texts.zh.resx b/backend/src/Squidex.Shared/Texts.zh.resx index 9c84b1442..af0013190 100644 --- a/backend/src/Squidex.Shared/Texts.zh.resx +++ b/backend/src/Squidex.Shared/Texts.zh.resx @@ -730,6 +730,9 @@ 更新的客户端 {[Id]} + + updated general settings + 已分配 {user:[Contributor]} 作为 {[Role]} @@ -778,9 +781,6 @@ updated app to client - - updated general settings - added workflow {[Name]}. diff --git a/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts b/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts new file mode 100644 index 000000000..51e76a843 --- /dev/null +++ b/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts @@ -0,0 +1,199 @@ +declare class EditorPlugin { + /** + * Get the current context. + */ + getContext(): any; + + /** + * Notifies the parent to navigate to the path. + */ + navigate(url: string): void; + + /** + * Register an function that is called when the sidebar is initialized. + * + * @param {Function} callback: The callback to invoke. + */ + onInit(callback: () => void): void; + + /** + * Register an function that is called whenever the value of the content has changed. + * + * @param {Function} callback: The callback to invoke. Argument 1: Content value (any). + */ + onContentChanged(callback: (content: any) => void): void; + + /** + * Clean the editor SDK. + */ + clean(): void; +} + +declare class SquidexFormField { + /** + * Get the current value. + */ + getValue(): any; + + /** + * Get the current value. + */ + getContext(): any; + + /** + * Get the current form value. + */ + getFormValue(): any; + + /** + * Get the current field language. + */ + getLanguage(): string | undefined | null; + + /** + * Get the current index when the field is an array item. + */ + getIndex(): number | undefined | null; + + /** + * Get the disabled state. + */ + isDisabled(): boolean; + + /** + * Get the fullscreen state. + */ + isFullscreen(): boolean; + /** + * Get the expanded state. + */ + isExpanded(): boolean; + + /** + * Notifies the control container that the editor has been touched. + */ + touched(): void; + + /** + * Notifies the parent to navigate to the path. + * + * @param {string} url: The url to navigate to. + */ + navigate(url: string): void; + + /** + * Notifies the parent to go to fullscreen mode. + */ + toggleFullscreen(): void; + + /** + * Notifies the parent to go to expanded mode. + */ + toggleExpanded(): void; + + /** + * Notifies the control container that the value has been changed. + * + * @param {any} newValue: The new field value. + */ + valueChanged(newValue: any): void; + + /** + * Shows an info alert. + * + * @param {string} text: The info text. + */ + notifyInfo(text: string): void; + + /** + * Shows an error alert. + * + * @param {string} text: error info text. + */ + notifyError(text: string): void; + + /** + * Shows an confirm dialog. + * + * @param {string} title The title of the dialog. + * @param {string} text The text of the dialog. + * @param {function} callback The callback to invoke when the dialog is completed or closed. + */ + confirm(title: string, text: string, callback: (result: boolean) => void): void; + + /** + * Shows the dialog to pick assets. + * + * @param {function} callback The callback to invoke when the dialog is completed or closed. + */ + pickAssets(callback: (assets: any[]) => void): void; + + /** + * Shows the dialog to pick contents. + * + * @param {string} schemas: The list of schema names. + * @param {function} callback The callback to invoke when the dialog is completed or closed. + */ + pickContents(schemas: string[], callback: (assets: any[]) => void): void; + + /** + * Register an function that is called when the field is initialized. + * + * @param {Function} callback: The callback to invoke. + */ + onInit(callback: () => void): void; + + /** + * Register an function that is called when the field is moved. + * + * @param {Function} callback: The callback to invoke. Argument 1: New position (number). + */ + onMoved(callback: (index: number) => void): void; + + /** + * Register an function that is called whenever the field is disabled or enabled. + * + * @param {Function} callback: The callback to invoke. Argument 1: New disabled state (boolean, disabled = true, enabled = false). + */ + onDisabled(callback: (isDisabled: boolean) => void): void; + + /** + * Register an function that is called whenever the field language is changed. + * + * @param {Function} callback: The callback to invoke. Argument 1: Language code (string). + */ + onLanguageChanged(callback: (language: string) => void): void; + + /** + * Register an function that is called whenever the value of the field has changed. + * + * @param {Function} callback: The callback to invoke. Argument 1: Field value (any). + */ + onValueChanged(callback: (value: any) => void): void; + + /** + * Register an function that is called whenever the value of the content has changed. + * + * @param {Function} callback: The callback to invoke. Argument 1: Content value (any). + */ + onFormValueChanged(callback: (value: any) => void): void; + + /** + * Register an function that is called whenever the fullscreen mode has changed. + * + * @param {Function} callback: The callback to invoke. Argument 1: Fullscreen state (boolean, fullscreen on = true, fullscreen off = false). + */ + onFullscreen(callback: (isFullscreen: boolean) => void): void; + + /** + * Register an function that is called whenever the expanded mode has changed. + * + * @param {Function} callback: The callback to invoke. Argument 1: Expanded state (boolean, expanded on = true, expanded off = false). + */ + onExpanded(callback: (isExpanded: boolean) => void): void; + + /** + * Clean the editor SDK. + */ + clean(): void; +} \ No newline at end of file diff --git a/frontend/src/app/features/administration/pages/users/user-page.component.html b/frontend/src/app/features/administration/pages/users/user-page.component.html index 770417c9c..a80fa5a58 100644 --- a/frontend/src/app/features/administration/pages/users/user-page.component.html +++ b/frontend/src/app/features/administration/pages/users/user-page.component.html @@ -2,7 +2,7 @@
- + diff --git a/frontend/src/app/features/content/pages/comments/comments-page.component.html b/frontend/src/app/features/content/pages/comments/comments-page.component.html index 1686fcc64..a412160a5 100644 --- a/frontend/src/app/features/content/pages/comments/comments-page.component.html +++ b/frontend/src/app/features/content/pages/comments/comments-page.component.html @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/frontend/src/app/features/content/pages/content/content-history-page.component.html b/frontend/src/app/features/content/pages/content/content-history-page.component.html index 25556315e..14c986205 100644 --- a/frontend/src/app/features/content/pages/content/content-history-page.component.html +++ b/frontend/src/app/features/content/pages/content/content-history-page.component.html @@ -1,4 +1,4 @@ - +
diff --git a/frontend/src/app/features/content/shared/list/content.component.scss b/frontend/src/app/features/content/shared/list/content.component.scss index a9615d8a6..95ef1f57f 100644 --- a/frontend/src/app/features/content/shared/list/content.component.scss +++ b/frontend/src/app/features/content/shared/list/content.component.scss @@ -19,7 +19,7 @@ tr { } td { - border-bottom: 1px solid $color-border; + border-bottom: .7px solid $color-border; border-left: 1px solid $color-white; border-top: 0 !important; position: relative; diff --git a/frontend/src/app/features/content/shared/preview-button.component.ts b/frontend/src/app/features/content/shared/preview-button.component.ts index 8da47700c..2568b0273 100644 --- a/frontend/src/app/features/content/shared/preview-button.component.ts +++ b/frontend/src/app/features/content/shared/preview-button.component.ts @@ -8,7 +8,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; -import { ContentDto, interpolate, LocalStoreService, ModalModel, SchemaDto, Settings, StatefulComponent } from '@app/shared'; +import { AuthService, ContentDto, interpolate, LocalStoreService, ModalModel, SchemaDto, Settings, StatefulComponent } from '@app/shared'; interface State { // The name of the selected preview config. @@ -37,6 +37,7 @@ export class PreviewButtonComponent extends StatefulComponent implements public dropdown = new ModalModel(); constructor(changeDetector: ChangeDetectorRef, + private readonly authService: AuthService, private readonly localStore: LocalStoreService, ) { super(changeDetector, { @@ -74,7 +75,11 @@ export class PreviewButtonComponent extends StatefulComponent implements } private navigateTo(name: string) { - const url = interpolate(this.schema.previewUrls[name], this.content, 'iv'); + const vars = { ...this.content }; + + vars['accessToken'] = this.authService.user?.accessToken; + + const url = interpolate(this.schema.previewUrls[name], vars, 'iv'); window.open(url, '_blank'); } diff --git a/frontend/src/app/features/content/shared/references/reference-item.component.html b/frontend/src/app/features/content/shared/references/reference-item.component.html index 32c63be56..386dc88bd 100644 --- a/frontend/src/app/features/content/shared/references/reference-item.component.html +++ b/frontend/src/app/features/content/shared/references/reference-item.component.html @@ -49,10 +49,6 @@ - - - - + + + +
diff --git a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html index 4e6609126..7bc5747ba 100644 --- a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html +++ b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html @@ -69,7 +69,15 @@
1 {{ 'clients.connectWizard.manuallyStep1' | sqxTranslate }}

- {{connectHttpText}} + +

$ curl
+
-X POST '{{apiUrl.buildUrl('/identity-server/connect/token')}}'
+
-H 'Content-Type: application/x-www-form-urlencoded'
+
-d 'grant_type=client_credentials&
+
client_id={{appName}}:{{client.id}}
+
client_secret={{client.secret}}
+
scope=squidex-api'
+

@@ -77,7 +85,7 @@
2 {{ 'clients.connectWizard.manuallyStep2' | sqxTranslate }}

- {{connectToken?.accessToken}} + {{appToken?.accessToken}}

@@ -129,6 +137,12 @@
+
+ + {{ 'clients.connectWizard.sdkDocumentation' | sqxTranslate }} {{ 'common.documentation' | sqxTranslate }} + +
+
1 {{ 'clients.connectWizard.sdkStep1' | sqxTranslate }}
@@ -143,7 +157,42 @@
2 {{ 'clients.connectWizard.sdkStep2' | sqxTranslate }}

- {{connectLibraryText}} + +

var clientManager = new SquidexClientManager(new SquidexOptions
+
{{'{'}}
+
AppName = {{appName}},
+
ClientId = {{appName}}:{{client.id}},
+
ClientSecret = {{client.secret}},
+
Url = {{apiUrl.value}}
+
});
+ +

+
+ + +
+
3 {{ 'clients.connectWizard.sdkStep3' | sqxTranslate }}
+ +
+ +

+ dotnet add package Squidex.ClientLibrary.ServiceExtensions +

+
+ +
+
4 {{ 'clients.connectWizard.sdkStep4' | sqxTranslate }}
+ +

+ +

services.AddSquidex(options =>
+
{{'{'}}
+
options.AppName = {{appName}};
+
options.ClientId = {{appName}}:{{client.id}};
+
options.ClientSecret = {{client.secret}};
+
options.Url = {{apiUrl.value}};
+
});
+

diff --git a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss index 645b642f2..9bf1100f4 100644 --- a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss +++ b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss @@ -43,4 +43,10 @@ font-size: $font-smallest; font-weight: normal; } +} + +sqx-code { + pre { + white-space: pre; + } } \ No newline at end of file diff --git a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts index 21fcaafee..95693cc71 100644 --- a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts +++ b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts @@ -21,10 +21,7 @@ export class ClientConnectFormComponent implements OnInit { public client!: ClientDto; public appName!: string; - - public connectToken?: AccessTokenDto; - public connectHttpText = ''; - public connectLibraryText = ''; + public appToken?: AccessTokenDto; public step = 'Start'; @@ -44,13 +41,10 @@ export class ClientConnectFormComponent implements OnInit { public ngOnInit() { this.appName = this.appsState.appName; - this.connectHttpText = connectHttpText(this.apiUrl, this.appName, this.client); - this.connectLibraryText = connectLibrary(this.apiUrl, this.appName, this.client); - this.clientsService.createToken(this.appsState.appName, this.client) .subscribe({ next: dto => { - this.connectToken = dto; + this.appToken = dto; this.changeDetector.detectChanges(); }, @@ -63,26 +57,4 @@ export class ClientConnectFormComponent implements OnInit { public go(step: string) { this.step = step; } -} - -function connectHttpText(apiUrl: ApiUrlConfig, app: string, client: { id: string; secret: string }) { - const url = apiUrl.buildUrl('identity-server/connect/token'); - - return `$ curl - -X POST '${url}' - -H 'Content-Type: application/x-www-form-urlencoded' - -d 'grant_type=client_credentials& - client_id=${app}:${client.id}& - client_secret=${client.secret}& - scope=squidex-api'`; -} - -function connectLibrary(apiUrl: ApiUrlConfig, app: string, client: { id: string; secret: string }) { - const url = apiUrl.value; - - return `var clientManager = new SquidexClientManager( - "${url}", - "${app}", - "${app}:${client.id}", - "${client.secret}")`; -} +} \ No newline at end of file diff --git a/frontend/src/app/framework/angular/language-selector.stories.tsx b/frontend/src/app/framework/angular/language-selector.stories.tsx index 37a2930e1..71e82b176 100644 --- a/frontend/src/app/framework/angular/language-selector.stories.tsx +++ b/frontend/src/app/framework/angular/language-selector.stories.tsx @@ -15,7 +15,7 @@ export default { component: LanguageSelectorComponent, argTypes: { size: { - control: 'enum', + control: 'select', options: [ 'sm', 'md', diff --git a/frontend/src/app/framework/angular/layout-container.directive.ts b/frontend/src/app/framework/angular/layout-container.directive.ts index 6f8a5138c..2639679c3 100644 --- a/frontend/src/app/framework/angular/layout-container.directive.ts +++ b/frontend/src/app/framework/angular/layout-container.directive.ts @@ -63,13 +63,14 @@ export class LayoutContainerDirective implements AfterViewInit { } let currentSize = 0; + let layoutWidth = this.containerWidth; let layoutsWidthSpread = 0; for (const layout of layouts) { - if (layout.desiredWidth > 0) { - const layoutWidth = layout.desiredWidth; + const desiredWidth = layout.computeDesiredWidth(layouts.length, layoutWidth); - layout.measure(`${layoutWidth}rem`); + if (desiredWidth >= 0) { + layout.measure(`${desiredWidth}rem`); currentSize += layout.renderWidth; } else { @@ -77,10 +78,12 @@ export class LayoutContainerDirective implements AfterViewInit { } } - const spreadWidth = (this.containerWidth - currentSize) / layoutsWidthSpread; + const spreadWidth = (layoutWidth - currentSize) / layoutsWidthSpread; for (const layout of layouts) { - if (layout.desiredWidth <= 0) { + const desiredWidth = layout.computeDesiredWidth(layouts.length, layoutWidth); + + if (desiredWidth < 0) { layout.measure(`${spreadWidth}px`); currentSize += layout.renderWidth; @@ -97,8 +100,10 @@ export class LayoutContainerDirective implements AfterViewInit { currentLayer -= 10; } - const diff = Math.max(0, currentPosition - this.containerWidth); + const diff = Math.max(0, currentPosition - layoutWidth); + this.renderer.setStyle(this.element.nativeElement, 'overflow-x', diff > 1 ? 'auto' : 'hidden'); + this.renderer.setStyle(this.element.nativeElement, 'overflow-y', 'hidden'); this.renderer.setProperty(this.element.nativeElement, 'scrollLeft', diff); } } diff --git a/frontend/src/app/framework/angular/layout.component.html b/frontend/src/app/framework/angular/layout.component.html index f52f59f27..1455e24c8 100644 --- a/frontend/src/app/framework/angular/layout.component.html +++ b/frontend/src/app/framework/angular/layout.component.html @@ -1,8 +1,8 @@ -
- -
-
-
+
+ +
+
+

{{ titleText | sqxTranslate }}

@@ -13,9 +13,21 @@
+ + + + + + + + + + + +
-
-
+
+
@@ -23,7 +35,7 @@ -
+

@@ -37,7 +49,7 @@

- @@ -75,7 +87,7 @@