Browse Source

More editor options and orleans iframe fix.

pull/683/head
Sebastian 5 years ago
parent
commit
a8bc61ce08
  1. 56
      backend/src/Squidex/wwwroot/scripts/editor-dialogs.html
  2. 104
      backend/src/Squidex/wwwroot/scripts/editor-sdk.js
  3. 2
      frontend/app/features/administration/pages/cluster/cluster-page.component.html
  4. 1
      frontend/app/features/content/declarations.ts
  5. 2
      frontend/app/features/content/module.ts
  6. 5
      frontend/app/features/content/shared/forms/iframe-editor.component.html
  7. 0
      frontend/app/features/content/shared/forms/iframe-editor.component.scss
  8. 44
      frontend/app/features/content/shared/forms/iframe-editor.component.ts
  9. 1
      frontend/app/framework/declarations.ts
  10. 4
      frontend/app/framework/module.ts

56
backend/src/Squidex/wwwroot/scripts/editor-dialogs.html

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- Load the editor sdk from the local folder or https://cloud.squidex.io/scripts/editor-sdk.js -->
<script src="editor-sdk.js"></script>
</head>
<body>
<button id="alert">
ALERT
</button>
<button id="info">
INFO
</button>
<button id="confirm">
CONFIRM
</button>
<button id="pickAssets">
PICK ASSETS
</button>
<script>
// When the field is instantiated it notifies the UI that it has been loaded.
//
// Furthermore it sends the current size to the parent.
var field = new SquidexFormField();
document.getElementById('alert').addEventListener('click', function () {
field.notifyError('ERROR Text');
});
document.getElementById('info').addEventListener('click', function () {
field.notifyInfo('INFO Text');
});
document.getElementById('confirm').addEventListener('click', function () {
field.confirm('CONFIRM Title', 'CONFIRM Text', function (confirmed) {
console.log('CONFIRMED: ' + confirmed);
});
});
document.getElementById('pickAssets').addEventListener('click', function () {
field.pickAssets(function (assets) {
console.log('ASSETS: ' + JSON.stringify(assets, undefined, 2));
});
});
</script>
</body>
</html>

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

@ -76,7 +76,7 @@ function SquidexPlugin() {
return context; return context;
}, },
/* /**
* Notifies the parent to navigate to the path. * Notifies the parent to navigate to the path.
*/ */
navigate: function (url) { navigate: function (url) {
@ -134,6 +134,8 @@ function SquidexFormField() {
var language; var language;
var formValueHandler; var formValueHandler;
var formValue; var formValue;
var currentConfirm;
var currentPickAssets;
var context; var context;
var timer; var timer;
@ -204,6 +206,22 @@ function SquidexFormField() {
context = event.data.context; context = event.data.context;
raiseInit(); 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; return formValue;
}, },
/* /**
* Get the current field language. * Get the current field language.
*/ */
getLanguage: function () { getLanguage: function () {
return language; return language;
}, },
/* /**
* Get the disabled state. * Get the disabled state.
*/ */
isDisabled: function () { isDisabled: function () {
return disabled; return disabled;
}, },
/* /**
* Get the fullscreen state. * Get the fullscreen state.
*/ */
isFullscreen: function () { isFullscreen: function () {
@ -264,10 +282,10 @@ function SquidexFormField() {
} }
}, },
/* /**
* Notifies the parent to navigate to the path. * 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) { navigate: function (url) {
if (window.parent) { if (window.parent) {
@ -275,10 +293,8 @@ function SquidexFormField() {
} }
}, },
/* /**
* Notifies the parent to go to fullscreen mode. * Notifies the parent to go to fullscreen mode.
*
* @params mode: boolean: The fullscreen mode.
*/ */
toggleFullscreen: function () { toggleFullscreen: function () {
if (window.parent) { if (window.parent) {
@ -289,7 +305,7 @@ function SquidexFormField() {
/** /**
* Notifies the control container that the value has been changed. * 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) { valueChanged: function (newValue) {
value = 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. * Register an function that is called when the field is initialized.
*/ */

2
frontend/app/features/administration/pages/cluster/cluster-page.component.html

@ -2,6 +2,6 @@
<sqx-panel desiredWidth="*" minWidth="50rem" isFullSize="true"> <sqx-panel desiredWidth="*" minWidth="50rem" isFullSize="true">
<div inner> <div inner>
<iframe src="/orleans"></iframe> <iframe src="./orleans"></iframe>
</div> </div>
</sqx-panel> </sqx-panel>

1
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/array-section.component';
export * from './shared/forms/assets-editor.component'; export * from './shared/forms/assets-editor.component';
export * from './shared/forms/field-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/forms/stock-photo-editor.component';
export * from './shared/list/content-list-cell.directive'; export * from './shared/list/content-list-cell.directive';
export * from './shared/list/content-list-field.component'; export * from './shared/list/content-list-field.component';

2
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 { 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 { 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 { ContentExtensionComponent } from './shared/content-extension.component';
import { IFrameEditorComponent } from './shared/forms/iframe-editor.component';
const routes: Routes = [ const routes: Routes = [
{ {
@ -114,6 +115,7 @@ const routes: Routes = [
DueTimeSelectorComponent, DueTimeSelectorComponent,
FieldEditorComponent, FieldEditorComponent,
FieldLanguagesComponent, FieldLanguagesComponent,
IFrameEditorComponent,
PreviewButtonComponent, PreviewButtonComponent,
ReferenceItemComponent, ReferenceItemComponent,
ReferencesEditorComponent, ReferencesEditorComponent,

5
frontend/app/framework/angular/forms/editors/iframe-editor.component.html → frontend/app/features/content/shared/forms/iframe-editor.component.html

@ -4,3 +4,8 @@
</div> </div>
</div> </div>
<ng-container *sqxModal="assetsDialog">
<sqx-assets-selector
(select)="pickAssets($event)">
</sqx-assets-selector>
</ng-container>

0
frontend/app/framework/angular/forms/editors/iframe-editor.component.scss → frontend/app/features/content/shared/forms/iframe-editor.component.scss

44
frontend/app/framework/angular/forms/editors/iframe-editor.component.ts → 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 { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnChanges, OnDestroy, Renderer2, SimpleChanges, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Router } from '@angular/router'; 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 = { export const SQX_IFRAME_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => IFrameEditorComponent), multi: true provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => IFrameEditorComponent), multi: true
@ -31,6 +32,7 @@ interface State {
export class IFrameEditorComponent extends StatefulControlComponent<State, any> implements OnChanges, OnDestroy, AfterViewInit { export class IFrameEditorComponent extends StatefulControlComponent<State, any> implements OnChanges, OnDestroy, AfterViewInit {
private value: any; private value: any;
private isInitialized = false; private isInitialized = false;
private assetsCorrelationId: any;
@ViewChild('iframe', { static: false }) @ViewChild('iframe', { static: false })
public iframe: ElementRef<HTMLIFrameElement>; public iframe: ElementRef<HTMLIFrameElement>;
@ -53,9 +55,12 @@ export class IFrameEditorComponent extends StatefulControlComponent<State, any>
@Input() @Input()
public url: string; public url: string;
public assetsDialog = new DialogModel();
public fullscreen: boolean; public fullscreen: boolean;
constructor(changeDetector: ChangeDetectorRef, constructor(changeDetector: ChangeDetectorRef,
private readonly dialogs: DialogService,
private readonly renderer: Renderer2, private readonly renderer: Renderer2,
private readonly router: Router private readonly router: Router
) { ) {
@ -129,6 +134,33 @@ export class IFrameEditorComponent extends StatefulControlComponent<State, any>
} }
} else if (type === 'touched') { } else if (type === 'touched') {
this.callTouched(); 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(); this.detectChanges();
@ -136,6 +168,16 @@ export class IFrameEditorComponent extends StatefulControlComponent<State, any>
})); }));
} }
public pickAssets(assets: ReadonlyArray<AssetDto>) {
if (this.assetsCorrelationId) {
this.sendMessage('pickAssetsResult', { correlationId: this.assetsCorrelationId, result: assets });
this.assetsCorrelationId = null;
}
this.assetsDialog.hide();
}
public writeValue(obj: any) { public writeValue(obj: any) {
this.value = obj; this.value = obj;

1
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/color-picker.component';
export * from './angular/forms/editors/date-time-editor.component'; export * from './angular/forms/editors/date-time-editor.component';
export * from './angular/forms/editors/dropdown.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/localized-input.component';
export * from './angular/forms/editors/stars.component'; export * from './angular/forms/editors/stars.component';
export * from './angular/forms/editors/tag-editor.component'; export * from './angular/forms/editors/tag-editor.component';

4
frontend/app/framework/module.ts

@ -12,7 +12,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ModuleWithProviders, NgModule } from '@angular/core'; import { ModuleWithProviders, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ColorPickerModule } from 'ngx-color-picker'; 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({ @NgModule({
imports: [ imports: [
@ -52,7 +52,6 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc
FullDateTimePipe, FullDateTimePipe,
HighlightPipe, HighlightPipe,
HoverBackgroundDirective, HoverBackgroundDirective,
IFrameEditorComponent,
ImageSourceDirective, ImageSourceDirective,
IndeterminateValueDirective, IndeterminateValueDirective,
ISODatePipe, ISODatePipe,
@ -132,7 +131,6 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc
FullDateTimePipe, FullDateTimePipe,
HighlightPipe, HighlightPipe,
HoverBackgroundDirective, HoverBackgroundDirective,
IFrameEditorComponent,
ImageSourceDirective, ImageSourceDirective,
IndeterminateValueDirective, IndeterminateValueDirective,
ISODatePipe, ISODatePipe,

Loading…
Cancel
Save