diff --git a/backend/src/Squidex/wwwroot/scripts/editor-dialogs.html b/backend/src/Squidex/wwwroot/scripts/editor-dialogs.html
new file mode 100644
index 000000000..d983224c0
--- /dev/null
+++ b/backend/src/Squidex/wwwroot/scripts/editor-dialogs.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/src/Squidex/wwwroot/scripts/editor-sdk.js b/backend/src/Squidex/wwwroot/scripts/editor-sdk.js
index 34bbc0260..95e2216a0 100644
--- a/backend/src/Squidex/wwwroot/scripts/editor-sdk.js
+++ b/backend/src/Squidex/wwwroot/scripts/editor-sdk.js
@@ -76,7 +76,7 @@ function SquidexPlugin() {
return context;
},
- /*
+ /**
* Notifies the parent to navigate to the path.
*/
navigate: function (url) {
@@ -134,6 +134,8 @@ function SquidexFormField() {
var language;
var formValueHandler;
var formValue;
+ var currentConfirm;
+ var currentPickAssets;
var context;
var timer;
@@ -199,11 +201,27 @@ function SquidexFormField() {
} else if (type === 'languageChanged') {
language = event.data.language;
- raiseLanguageChanged();
+ raiseLanguageChanged();
} else if (type === 'init') {
context = event.data.context;
raiseInit();
+ } else if (type === 'confirmResult') {
+ var correlationId = event.data.correlationId;
+
+ if (currentConfirm && currentConfirm.correlationId === correlationId) {
+ if (typeof currentConfirm.callback === 'function') {
+ currentConfirm.callback(event.data.result);
+ }
+ }
+ } else if (type === 'pickAssetsResult') {
+ var correlationId = event.data.correlationId;
+
+ if (currentPickAssets && currentPickAssets.correlationId === correlationId) {
+ if (typeof currentPickAssets.callback === 'function') {
+ currentPickAssets.callback(event.data.result);
+ }
+ }
}
}
}
@@ -234,21 +252,21 @@ function SquidexFormField() {
return formValue;
},
- /*
+ /**
* Get the current field language.
*/
getLanguage: function () {
return language;
},
- /*
+ /**
* Get the disabled state.
*/
isDisabled: function () {
return disabled;
},
- /*
+ /**
* Get the fullscreen state.
*/
isFullscreen: function () {
@@ -264,10 +282,10 @@ function SquidexFormField() {
}
},
- /*
+ /**
* Notifies the parent to navigate to the path.
*
- * @params url: string: The url to navigate to.
+ * @param {string} url: The url to navigate to.
*/
navigate: function (url) {
if (window.parent) {
@@ -275,10 +293,8 @@ function SquidexFormField() {
}
},
- /*
+ /**
* Notifies the parent to go to fullscreen mode.
- *
- * @params mode: boolean: The fullscreen mode.
*/
toggleFullscreen: function () {
if (window.parent) {
@@ -289,7 +305,7 @@ function SquidexFormField() {
/**
* Notifies the control container that the value has been changed.
*
- * @params newValue: any: The new field value.
+ * @param {any} newValue: The new field value.
*/
valueChanged: function (newValue) {
value = newValue;
@@ -299,6 +315,74 @@ function SquidexFormField() {
}
},
+ /**
+ * Shows an info alert.
+ *
+ * @param {string} text: The info text.
+ */
+ notifyInfo: function (text) {
+ if (window.parent) {
+ window.parent.postMessage({ type: 'notifyInfo', text: text }, '*');
+ }
+ },
+
+ /**
+ * Shows an error alert.
+ *
+ * @param {string} text: error info text.
+ */
+ notifyError: function (text) {
+ if (window.parent) {
+ window.parent.postMessage({ type: 'notifyError', text: text }, '*');
+ }
+ },
+
+ /**
+ * 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: function (title, text, callback) {
+ if (!callback || typeof callback !== 'function') {
+ return;
+ }
+
+ var correlationId = new Date().getTime().toString();
+
+ currentConfirm = {
+ correlationId: correlationId,
+ callback: callback
+ };
+
+ if (window.parent) {
+ window.parent.postMessage({ type: 'confirm', title: title, text: text, correlationId: correlationId }, '*');
+ }
+ },
+
+ /**
+ * Shows the dialog to pick assets.
+ *
+ * @param {function} callback The callback to invoke when the dialog is completed or closed.
+ */
+ pickAssets: function (callback) {
+ if (!callback || typeof callback !== 'function') {
+ return;
+ }
+
+ var correlationId = new Date().getTime().toString();
+
+ currentPickAssets = {
+ correlationId: correlationId,
+ callback: callback
+ };
+
+ if (window.parent) {
+ window.parent.postMessage({ type: 'pickAssets', correlationId: correlationId }, '*');
+ }
+ },
+
/**
* Register an function that is called when the field is initialized.
*/
diff --git a/frontend/app/features/administration/pages/cluster/cluster-page.component.html b/frontend/app/features/administration/pages/cluster/cluster-page.component.html
index 017f7d501..52dd84476 100644
--- a/frontend/app/features/administration/pages/cluster/cluster-page.component.html
+++ b/frontend/app/features/administration/pages/cluster/cluster-page.component.html
@@ -2,6 +2,6 @@
-
+
\ No newline at end of file
diff --git a/frontend/app/features/content/declarations.ts b/frontend/app/features/content/declarations.ts
index bd4a97fb3..d97edc633 100644
--- a/frontend/app/features/content/declarations.ts
+++ b/frontend/app/features/content/declarations.ts
@@ -27,6 +27,7 @@ export * from './shared/forms/array-item.component';
export * from './shared/forms/array-section.component';
export * from './shared/forms/assets-editor.component';
export * from './shared/forms/field-editor.component';
+export * from './shared/forms/iframe-editor.component';
export * from './shared/forms/stock-photo-editor.component';
export * from './shared/list/content-list-cell.directive';
export * from './shared/list/content-list-field.component';
diff --git a/frontend/app/features/content/module.ts b/frontend/app/features/content/module.ts
index 15c14c6ba..062d34ccc 100644
--- a/frontend/app/features/content/module.ts
+++ b/frontend/app/features/content/module.ts
@@ -12,6 +12,7 @@ import { RouterModule, Routes } from '@angular/router';
import { CanDeactivateGuard, ContentMustExistGuard, LoadLanguagesGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SqxFrameworkModule, SqxSharedModule, UnsetContentGuard } from '@app/shared';
import { ArrayEditorComponent, ArrayItemComponent, ArraySectionComponent, AssetsEditorComponent, CommentsPageComponent, ContentComponent, ContentCreatorComponent, ContentEditorComponent, ContentEventComponent, ContentFieldComponent, ContentHistoryPageComponent, ContentListCellDirective, ContentListFieldComponent, ContentListHeaderComponent, ContentListWidthPipe, ContentPageComponent, ContentReferencesComponent, ContentsColumnsPipe, ContentSectionComponent, ContentSelectorComponent, ContentSelectorItemComponent, ContentsFiltersPageComponent, ContentsPageComponent, ContentStatusComponent, ContentValueComponent, ContentValueEditorComponent, CustomViewEditorComponent, DueTimeSelectorComponent, FieldEditorComponent, FieldLanguagesComponent, PreviewButtonComponent, ReferenceItemComponent, ReferencesEditorComponent, SchemasPageComponent, SidebarPageComponent, StockPhotoEditorComponent } from './declarations';
import { ContentExtensionComponent } from './shared/content-extension.component';
+import { IFrameEditorComponent } from './shared/forms/iframe-editor.component';
const routes: Routes = [
{
@@ -114,6 +115,7 @@ const routes: Routes = [
DueTimeSelectorComponent,
FieldEditorComponent,
FieldLanguagesComponent,
+ IFrameEditorComponent,
PreviewButtonComponent,
ReferenceItemComponent,
ReferencesEditorComponent,
diff --git a/frontend/app/framework/angular/forms/editors/iframe-editor.component.html b/frontend/app/features/content/shared/forms/iframe-editor.component.html
similarity index 51%
rename from frontend/app/framework/angular/forms/editors/iframe-editor.component.html
rename to frontend/app/features/content/shared/forms/iframe-editor.component.html
index 706adf00c..c67d47698 100644
--- a/frontend/app/framework/angular/forms/editors/iframe-editor.component.html
+++ b/frontend/app/features/content/shared/forms/iframe-editor.component.html
@@ -4,3 +4,8 @@
+
+
+
+
diff --git a/frontend/app/framework/angular/forms/editors/iframe-editor.component.scss b/frontend/app/features/content/shared/forms/iframe-editor.component.scss
similarity index 100%
rename from frontend/app/framework/angular/forms/editors/iframe-editor.component.scss
rename to frontend/app/features/content/shared/forms/iframe-editor.component.scss
diff --git a/frontend/app/framework/angular/forms/editors/iframe-editor.component.ts b/frontend/app/features/content/shared/forms/iframe-editor.component.ts
similarity index 76%
rename from frontend/app/framework/angular/forms/editors/iframe-editor.component.ts
rename to frontend/app/features/content/shared/forms/iframe-editor.component.ts
index 354776a58..8a4420472 100644
--- a/frontend/app/framework/angular/forms/editors/iframe-editor.component.ts
+++ b/frontend/app/features/content/shared/forms/iframe-editor.component.ts
@@ -8,7 +8,8 @@
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnChanges, OnDestroy, Renderer2, SimpleChanges, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Router } from '@angular/router';
-import { StatefulControlComponent, Types } from '@app/framework/internal';
+import { DialogModel, DialogService, StatefulControlComponent, Types } from '@app/framework/internal';
+import { AssetDto } from '@app/shared';
export const SQX_IFRAME_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => IFrameEditorComponent), multi: true
@@ -31,6 +32,7 @@ interface State {
export class IFrameEditorComponent extends StatefulControlComponent implements OnChanges, OnDestroy, AfterViewInit {
private value: any;
private isInitialized = false;
+ private assetsCorrelationId: any;
@ViewChild('iframe', { static: false })
public iframe: ElementRef;
@@ -53,9 +55,12 @@ export class IFrameEditorComponent extends StatefulControlComponent
@Input()
public url: string;
+ public assetsDialog = new DialogModel();
+
public fullscreen: boolean;
constructor(changeDetector: ChangeDetectorRef,
+ private readonly dialogs: DialogService,
private readonly renderer: Renderer2,
private readonly router: Router
) {
@@ -129,6 +134,33 @@ export class IFrameEditorComponent extends StatefulControlComponent
}
} else if (type === 'touched') {
this.callTouched();
+ } else if (type === 'notifyInfo') {
+ const { text } = event.data;
+
+ if (Types.isString(text)) {
+ this.dialogs.notifyInfo(text);
+ }
+ } else if (type === 'notifyError') {
+ const { text } = event.data;
+
+ if (Types.isString(text)) {
+ this.dialogs.notifyError(text);
+ }
+ } else if (type === 'confirm') {
+ const { text, title, correlationId } = event.data;
+
+ if (Types.isString(text) && Types.isString(title) && correlationId) {
+ this.dialogs.confirm(title, text).subscribe(result => {
+ this.sendMessage('confirmResult', { correlationId, result });
+ });
+ }
+ } else if (type === 'pickAssets') {
+ const { correlationId } = event.data;
+
+ if (correlationId) {
+ this.assetsCorrelationId = correlationId;
+ this.assetsDialog.show();
+ }
}
this.detectChanges();
@@ -136,6 +168,16 @@ export class IFrameEditorComponent extends StatefulControlComponent
}));
}
+ public pickAssets(assets: ReadonlyArray) {
+ if (this.assetsCorrelationId) {
+ this.sendMessage('pickAssetsResult', { correlationId: this.assetsCorrelationId, result: assets });
+
+ this.assetsCorrelationId = null;
+ }
+
+ this.assetsDialog.hide();
+ }
+
public writeValue(obj: any) {
this.value = obj;
diff --git a/frontend/app/framework/declarations.ts b/frontend/app/framework/declarations.ts
index 78ff55ff0..304bd4651 100644
--- a/frontend/app/framework/declarations.ts
+++ b/frontend/app/framework/declarations.ts
@@ -18,7 +18,6 @@ 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/localized-input.component';
export * from './angular/forms/editors/stars.component';
export * from './angular/forms/editors/tag-editor.component';
diff --git a/frontend/app/framework/module.ts b/frontend/app/framework/module.ts
index a140e33c8..e27bf788a 100644
--- a/frontend/app/framework/module.ts
+++ b/frontend/app/framework/module.ts
@@ -12,7 +12,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ModuleWithProviders, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ColorPickerModule } from 'ngx-color-picker';
-import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterceptor, CanDeactivateGuard, CheckboxGroupComponent, ClipboardService, CodeComponent, CodeEditorComponent, ColorPickerComponent, ConfirmClickDirective, ControlErrorsComponent, CopyDirective, DarkenPipe, DatePipe, DateTimeEditorComponent, DayOfWeekPipe, DayPipe, DialogRendererComponent, DialogService, DisplayNamePipe, DropdownComponent, DurationPipe, EditableTitleComponent, ExternalLinkDirective, FileDropDirective, FileSizePipe, FocusOnInitDirective, FormAlertComponent, FormErrorComponent, FormHintComponent, FromNowPipe, FullDateTimePipe, HighlightPipe, HoverBackgroundDirective, IFrameEditorComponent, ImageSourceDirective, IndeterminateValueDirective, ISODatePipe, KeysPipe, KNumberPipe, LanguageSelectorComponent, LightenPipe, ListViewComponent, LoadingInterceptor, LoadingService, LocalizedInputComponent, LocalStoreService, MarkdownInlinePipe, MarkdownPipe, MessageBus, ModalDialogComponent, ModalDirective, ModalPlacementDirective, MoneyPipe, MonthPipe, OnboardingService, OnboardingTooltipComponent, PagerComponent, PanelComponent, PanelContainerDirective, ParentLinkDirective, PopupLinkDirective, ProgressBarComponent, ResizedDirective, ResizeService, ResourceLoaderService, RootViewComponent, SafeHtmlPipe, SafeUrlPipe, ScrollActiveDirective, ShortcutComponent, ShortcutService, ShortDatePipe, ShortTimePipe, StarsComponent, StatusIconComponent, StopClickDirective, SyncScollingDirective, SyncWidthDirective, TabRouterlinkDirective, TagEditorComponent, TemplateWrapperDirective, TempService, TitleComponent, TitleService, ToggleComponent, TooltipDirective, TransformInputDirective, TranslatePipe, VideoPlayerComponent } from './declarations';
+import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterceptor, CanDeactivateGuard, CheckboxGroupComponent, ClipboardService, CodeComponent, CodeEditorComponent, ColorPickerComponent, ConfirmClickDirective, ControlErrorsComponent, CopyDirective, DarkenPipe, DatePipe, DateTimeEditorComponent, DayOfWeekPipe, DayPipe, DialogRendererComponent, DialogService, DisplayNamePipe, DropdownComponent, DurationPipe, EditableTitleComponent, ExternalLinkDirective, FileDropDirective, FileSizePipe, FocusOnInitDirective, FormAlertComponent, FormErrorComponent, FormHintComponent, FromNowPipe, FullDateTimePipe, HighlightPipe, HoverBackgroundDirective, ImageSourceDirective, IndeterminateValueDirective, ISODatePipe, KeysPipe, KNumberPipe, LanguageSelectorComponent, LightenPipe, ListViewComponent, LoadingInterceptor, LoadingService, LocalizedInputComponent, LocalStoreService, MarkdownInlinePipe, MarkdownPipe, MessageBus, ModalDialogComponent, ModalDirective, ModalPlacementDirective, MoneyPipe, MonthPipe, OnboardingService, OnboardingTooltipComponent, PagerComponent, PanelComponent, PanelContainerDirective, ParentLinkDirective, PopupLinkDirective, ProgressBarComponent, ResizedDirective, ResizeService, ResourceLoaderService, RootViewComponent, SafeHtmlPipe, SafeUrlPipe, ScrollActiveDirective, ShortcutComponent, ShortcutService, ShortDatePipe, ShortTimePipe, StarsComponent, StatusIconComponent, StopClickDirective, SyncScollingDirective, SyncWidthDirective, TabRouterlinkDirective, TagEditorComponent, TemplateWrapperDirective, TempService, TitleComponent, TitleService, ToggleComponent, TooltipDirective, TransformInputDirective, TranslatePipe, VideoPlayerComponent } from './declarations';
@NgModule({
imports: [
@@ -52,7 +52,6 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc
FullDateTimePipe,
HighlightPipe,
HoverBackgroundDirective,
- IFrameEditorComponent,
ImageSourceDirective,
IndeterminateValueDirective,
ISODatePipe,
@@ -132,7 +131,6 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc
FullDateTimePipe,
HighlightPipe,
HoverBackgroundDirective,
- IFrameEditorComponent,
ImageSourceDirective,
IndeterminateValueDirective,
ISODatePipe,