Skip to content

Commit

Permalink
#26900 Allow pass field variables to Monaco's Binary Field And JSON F…
Browse files Browse the repository at this point in the history
…ield (#27388)

* feat(edit-content) add to binary-field and json-field use custom FieldVariable of Monaco Editor

* feat(edit-content) type fixes

* Update core-web/libs/edit-content/src/lib/fields/dot-edit-content-binary-field/components/dot-binary-field-editor/dot-binary-field-editor.component.ts

Make signal private.

Co-authored-by: Rafael Velazco <[email protected]>

* fix(edit-content) fix comments

* fix(edit-content) add properties to sonarqube config

---------

Co-authored-by: Rafael Velazco <[email protected]>
  • Loading branch information
2 people authored and dsolistorres committed Feb 9, 2024
1 parent d213638 commit c71d221
Show file tree
Hide file tree
Showing 18 changed files with 429 additions and 132,100 deletions.
5 changes: 3 additions & 2 deletions core-web/apps/dotcms-binary-field-builder/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
"namedChunks": true,
"watch": true
},
"tomcat": {
"outputPath": "../../tomcat9/webapps/ROOT/dotcms-binary-field-builder",
Expand All @@ -83,7 +84,7 @@
"buildTarget": "dotcms-binary-field-builder:build:development"
}
},
"defaultConfiguration": "development"
"defaultConfiguration": "production"
},
"extract-i18n": {
"executor": "@angular-devkit/build-angular:extract-i18n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,7 @@ import { catchError, map, pluck, take } from 'rxjs/operators';

import { DotHttpErrorManagerService } from '@dotcms/data-access';
import { CoreWebService } from '@dotcms/dotcms-js';

export interface DotCMSTempFile {
fileName: string;
folder: string;
id: string;
image: boolean;
length: number;
mimeType: string;
referenceUrl: string;
thumbnailUrl: string;
}
import { DotCMSTempFile } from '@dotcms/dotcms-models';

@Injectable()
export class DotTempFileUploadService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
}}</label>
<input
id="file-name"
type="text"
pInputText
formControlName="name"
autocomplete="off"
formControlName="name"
pInputText
placeholder="Ex. template.html" />
placeholder="Ex. template.html"
type="text" />
<div class="error-message">
<dot-field-validation-message
[patternErrorMessage]="'dot.binary.field.error.type.file.not.extension'"
[field]="form.get('name')"
[patternErrorMessage]="'dot.binary.field.error.type.file.not.extension'"
data-testId="error-message"></dot-field-validation-message>
</div>
</div>
Expand All @@ -23,10 +22,10 @@
class="binary-field__code-editor"
#editorRef
[ngClass]="{ 'binary-field__code-editor--disabled': form.disabled }"
[options]="editorOptions"
[options]="monacoOptions()"
(init)="onEditorInit()"
formControlName="content"
data-testId="code-editor"></ngx-monaco-editor>
data-testId="code-editor"
formControlName="content"></ngx-monaco-editor>

<div class="editor-mode__helper" [ngClass]="{ 'editor-mode__helper--visible': mimeType }">
<i class="pi pi-info-circle"></i>
Expand All @@ -37,15 +36,15 @@
<p-button
[label]="'dot.common.cancel' | dm"
(click)="cancel.emit()"
styleClass="p-button-outlined"
type="button"
aria-label="Cancel button"
data-testId="cancel-button"></p-button>
data-testId="cancel-button"
styleClass="p-button-outlined"
type="button"></p-button>

<p-button
[label]="'dot.common.save' | dm"
type="submit"
aria-label="Import button"
data-testId="import-button"></p-button>
data-testId="import-button"
type="submit"></p-button>
</div>
</form>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MonacoEditorComponent, MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
import { Spectator, byTestId, createComponentFactory } from '@ngneat/spectator';
import { byTestId, createComponentFactory, Spectator } from '@ngneat/spectator';
import { MockComponent } from 'ng-mocks';

import { fakeAsync, tick } from '@angular/core/testing';
Expand All @@ -8,6 +8,7 @@ import { ButtonModule } from 'primeng/button';
import { InputTextModule } from 'primeng/inputtext';

import { DotMessageService, DotUploadService } from '@dotcms/data-access';
import { DEFAULT_BINARY_FIELD_MONACO_CONFIG } from '@dotcms/edit-content';
import { DotFieldValidationMessageComponent, DotMessagePipe } from '@dotcms/ui';

import { DotBinaryFieldEditorComponent } from './dot-binary-field-editor.component';
Expand Down Expand Up @@ -126,17 +127,23 @@ describe('DotBinaryFieldEditorComponent', () => {

describe('Editor', () => {
it('should set editor language', fakeAsync(() => {
const expectedMonacoOptions = {
...DEFAULT_BINARY_FIELD_MONACO_CONFIG,
language: 'javascript'
};

spectator.detectChanges();

component.form.setValue({
name: 'script.js',
content: 'test'
});

tick(1000);
spectator.detectComponentChanges();

expect(component.editorOptions).toEqual({
...component.editorOptions,
language: 'javascript'
});
tick(355); //due to debounceTime

expect(component.monacoOptions()).toEqual(expectedMonacoOptions);
expect(component.mimeType).toBe('text/javascript');
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
computed,
EventEmitter,
HostListener,
inject,
Input,
OnInit,
Output,
ViewChild,
inject
signal,
ViewChild
} from '@angular/core';
import {
FormControl,
Expand All @@ -33,25 +35,12 @@ import { debounceTime } from 'rxjs/operators';

import { DotMessageService, DotUploadService } from '@dotcms/data-access';
import { DotCMSTempFile } from '@dotcms/dotcms-models';
import { DEFAULT_BINARY_FIELD_MONACO_CONFIG } from '@dotcms/edit-content';
import { DotFieldValidationMessageComponent, DotMessagePipe } from '@dotcms/ui';

import { DotBinaryFieldValidatorService } from '../../service/dot-binary-field-validator/dot-binary-field-validator.service';

const EDITOR_CONFIG: MonacoEditorConstructionOptions = {
theme: 'vs',
minimap: {
enabled: false
},
cursorBlinking: 'solid',
overviewRulerBorder: false,
mouseWheelZoom: false,
lineNumbers: 'on',
roundedSelection: false,
automaticLayout: true,
language: 'text',
fontSize: 14
};

const DEFAULT_FILE_TYPE = 'text';
@Component({
selector: 'dot-dot-binary-field-editor',
standalone: true,
Expand All @@ -72,29 +61,39 @@ const EDITOR_CONFIG: MonacoEditorConstructionOptions = {
export class DotBinaryFieldEditorComponent implements OnInit {
@Input() fileName = '';
@Input() fileContent = '';

@Output() readonly tempFileUploaded = new EventEmitter<DotCMSTempFile>();
@Output() readonly cancel = new EventEmitter<void>();

@ViewChild('editorRef', { static: true }) editorRef!: MonacoEditorComponent;

readonly form = new FormGroup({
name: new FormControl('', [Validators.required, Validators.pattern(/^[^.]+\.[^.]+$/)]),
content: new FormControl('')
});
mimeType = '';
private readonly languageType = signal(DEFAULT_FILE_TYPE);
private readonly cd: ChangeDetectorRef = inject(ChangeDetectorRef);
private readonly dotUploadService: DotUploadService = inject(DotUploadService);
private readonly dotMessageService: DotMessageService = inject(DotMessageService);
private readonly dotBinaryFieldValidatorService: DotBinaryFieldValidatorService = inject(
DotBinaryFieldValidatorService
);

private extension = '';
private invalidFileMessage = '';
private editor: monaco.editor.IStandaloneCodeEditor;
readonly form = new FormGroup({
name: new FormControl('', [Validators.required, Validators.pattern(/^[^.]+\.[^.]+$/)]),
content: new FormControl('')

private _userMonacoOptions = signal<MonacoEditorConstructionOptions>({});

monacoOptions = computed(() => {
return {
...DEFAULT_BINARY_FIELD_MONACO_CONFIG,
...this._userMonacoOptions(),
language: this.languageType()
};
});

editorOptions = EDITOR_CONFIG;
mimeType = '';
@Input()
set userMonacoOptions(customMonacoOptions: MonacoEditorConstructionOptions) {
this._userMonacoOptions.set(customMonacoOptions);
}

get name(): FormControl {
return this.form.get('name') as FormControl;
Expand Down Expand Up @@ -198,10 +197,7 @@ export class DotBinaryFieldEditorComponent implements OnInit {
}

private updateEditorLanguage(languageId: string = 'text') {
this.editorOptions = {
...this.editorOptions,
language: languageId
};
this.languageType.set(languageId);
}

private disableEditor() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { byTestId, createHostFactory, SpectatorHost } from '@ngneat/spectator';
import { mockProvider } from '@ngneat/spectator/jest';
import { MockComponent } from 'ng-mocks';

import { CommonModule } from '@angular/common';
import { HttpClientTestingModule } from '@angular/common/http/testing';
Expand All @@ -8,12 +9,19 @@ import { DotMessagePipe } from '@dotcms/ui';

import { DotBinaryFieldUiMessageComponent } from './dot-binary-field-ui-message.component';

import { DotBinaryFieldEditorComponent } from '../dot-binary-field-editor/dot-binary-field-editor.component';

describe('DotBinaryFieldUiMessageComponent', () => {
let spectator: SpectatorHost<DotBinaryFieldUiMessageComponent>;

const createHost = createHostFactory({
component: DotBinaryFieldUiMessageComponent,
imports: [CommonModule, DotMessagePipe, HttpClientTestingModule],
imports: [
CommonModule,
DotMessagePipe,
HttpClientTestingModule,
MockComponent(DotBinaryFieldEditorComponent)
],
providers: [mockProvider(DotMessagePipe)]
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
<dot-drop-zone
[accept]="accept"
[maxFileSize]="maxFileSize"
(fileDragOver)="setDropZoneActiveState(true)"
(fileDragLeave)="setDropZoneActiveState(false)"
(fileDragOver)="setDropZoneActiveState(true)"
(fileDropped)="handleFileDrop($event)"
data-testId="dropzone">
<dot-binary-field-ui-message [uiMessage]="vm.uiMessage">
<button
class="binary-field__drop-zone-btn"
(click)="openFilePicker()"
type="button"
data-testId="choose-file-btn">
data-testId="choose-file-btn"
type="button">
{{ 'dot.binary.field.action.choose.file' | dm }}
</button>
</dot-binary-field-ui-message>
Expand All @@ -30,23 +30,23 @@
#inputFile
[accept]="accept.join(',')"
(change)="handleFileSelection($event)"
type="file"
data-testId="binary-field__file-input" />
data-testId="binary-field__file-input"
type="file" />
</div>

<div class="binary-field__actions">
<p-button
[label]="'dot.binary.field.action.import.from.url' | dm"
(click)="openDialog(BinaryFieldMode.URL)"
data-testId="action-url-btn"
styleClass="p-button-link p-button-secondary p-button-sm"
icon="pi pi-link"></p-button>
icon="pi pi-link"
styleClass="p-button-link p-button-secondary p-button-sm"></p-button>
<p-button
[label]="'dot.binary.field.action.create.new.file' | dm"
(click)="openDialog(BinaryFieldMode.EDITOR)"
data-testId="action-editor-btn"
styleClass="p-button-link p-button-secondary p-button-sm"
icon="pi pi-code"></p-button>
icon="pi pi-code"
styleClass="p-button-link p-button-secondary p-button-sm"></p-button>
</div>
</ng-container>

Expand All @@ -57,36 +57,37 @@
<dot-binary-field-preview
*ngIf="vm.status === BinaryFieldStatus.PREVIEW"
[contentlet]="vm.contentlet"
[tempFile]="vm.tempFile"
[editableImage]="vm.isEnterprise && imageEditor"
(removeFile)="removeFile()"
[tempFile]="vm.tempFile"
(editFile)="onEditFile()"
(editImage)="onEditImage()"
(removeFile)="removeFile()"
data-testId="preview"></dot-binary-field-preview>

<p-dialog
[(visible)]="dialogOpen"
[appendTo]="'body'"
[closeOnEscape]="false"
[draggable]="false"
[header]="dialogHeaderMap[vm.mode] | dm"
[keepInViewport]="false"
[maskStyleClass]="'p-dialog-mask-transparent'"
[modal]="true"
[header]="dialogHeaderMap[vm.mode] | dm"
[draggable]="false"
[resizable]="false"
[closeOnEscape]="false"
[appendTo]="'body'"
[maskStyleClass]="'p-dialog-mask-transparent'"
[style]="vm.mode === BinaryFieldMode.EDITOR ? dialogFullScreenStyles : {}">
<ng-container [ngSwitch]="vm.mode">
<dot-dot-binary-field-url-mode
*ngSwitchCase="BinaryFieldMode.URL"
(tempFileUploaded)="setTempFile($event)"
(cancel)="closeDialog()"
(tempFileUploaded)="setTempFile($event)"
data-testId="url-mode"></dot-dot-binary-field-url-mode>
<dot-dot-binary-field-editor
*ngSwitchCase="BinaryFieldMode.EDITOR"
[fileName]="vm.tempFile?.fileName || vm.contentlet?.name"
[fileContent]="vm.tempFile?.content || vm.contentlet?.content"
(tempFileUploaded)="setTempFile($event)"
[fileName]="vm.tempFile?.fileName || vm.contentlet?.name"
[userMonacoOptions]="customMonacoOptions()"
(cancel)="closeDialog()"
(tempFileUploaded)="setTempFile($event)"
data-testId="editor-mode"></dot-dot-binary-field-editor>
</ng-container>
</p-dialog>
Expand Down
Loading

0 comments on commit c71d221

Please sign in to comment.