Skip to content

Commit 222d67c

Browse files
feat: also allow scss in custom style of application
* finished allow scss available on application custom styling * lint fixed * remove useless import of esri key * fix some issues with custom style edition * clean code --------- Co-authored-by: Antoine Hurard <[email protected]>
1 parent f8bc2cb commit 222d67c

File tree

3 files changed

+82
-23
lines changed

3 files changed

+82
-23
lines changed

apps/back-office/src/app/components/custom-style/custom-style.component.ts

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { Component, Output, EventEmitter, OnInit } from '@angular/core';
1+
import {
2+
Component,
3+
Output,
4+
EventEmitter,
5+
OnInit,
6+
OnDestroy,
7+
} from '@angular/core';
28
import { CommonModule } from '@angular/common';
39
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
410
import { MonacoEditorModule } from 'ngx-monaco-editor-v2';
@@ -7,6 +13,7 @@ import {
713
SafeApplicationService,
814
SafeUnsubscribeComponent,
915
SafeConfirmService,
16+
SafeRestService,
1017
} from '@oort-front/safe';
1118
import { firstValueFrom } from 'rxjs';
1219
import { takeUntil } from 'rxjs/operators';
@@ -15,6 +22,7 @@ import { UploadApplicationStyleMutationResponse } from './graphql/mutations';
1522
import { UPLOAD_APPLICATION_STYLE } from './graphql/mutations';
1623
import { TranslateModule, TranslateService } from '@ngx-translate/core';
1724
import { ButtonModule, SnackbarService, SpinnerModule } from '@oort-front/ui';
25+
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
1826

1927
/** Default css style example to initialize the form and editor */
2028
const DEFAULT_STYLE = '';
@@ -37,7 +45,7 @@ const DEFAULT_STYLE = '';
3745
})
3846
export class CustomStyleComponent
3947
extends SafeUnsubscribeComponent
40-
implements OnInit
48+
implements OnInit, OnDestroy
4149
{
4250
public formControl = new FormControl(DEFAULT_STYLE);
4351
public applicationId?: string;
@@ -48,7 +56,7 @@ export class CustomStyleComponent
4856
language: 'scss',
4957
fixedOverflowWidgets: true,
5058
};
51-
private styleApplied: HTMLStyleElement;
59+
private rawCustomStyle!: string;
5260
private savedStyle = '';
5361
public loading = false;
5462

@@ -60,33 +68,49 @@ export class CustomStyleComponent
6068
* @param apollo Apollo service
6169
* @param translate Angular translate service
6270
* @param confirmService Shared confirmation service
71+
* @param restService Shared rest service
6372
*/
6473
constructor(
6574
private applicationService: SafeApplicationService,
6675
private snackBar: SnackbarService,
6776
private apollo: Apollo,
6877
private translate: TranslateService,
69-
private confirmService: SafeConfirmService
78+
private confirmService: SafeConfirmService,
79+
private restService: SafeRestService
7080
) {
7181
super();
72-
this.styleApplied = document.createElement('style');
7382
// Updates the style when the value changes
74-
this.formControl.valueChanges.subscribe((value: any) => {
75-
this.applicationService.customStyleEdited = true;
76-
this.styleApplied.innerText = value;
77-
document.getElementsByTagName('body')[0].appendChild(this.styleApplied);
78-
this.style.emit(value);
79-
});
83+
this.formControl.valueChanges
84+
.pipe(debounceTime(1000), distinctUntilChanged())
85+
.subscribe((value: any) => {
86+
const scss = value as string;
87+
this.restService
88+
.post('style/scss-to-css', { scss }, { responseType: 'text' })
89+
.subscribe({
90+
next: (css) => {
91+
console.log(this.applicationService.customStyle);
92+
if (this.applicationService.customStyle) {
93+
this.applicationService.customStyle.innerText = css;
94+
}
95+
},
96+
});
97+
this.applicationService.customStyleEdited = true;
98+
this.rawCustomStyle = value;
99+
});
80100
}
81101

82102
ngOnInit(): void {
83-
if (this.applicationService.customStyle) {
84-
this.savedStyle = this.applicationService.customStyle.innerText;
85-
this.styleApplied = this.applicationService.customStyle;
86-
this.formControl.setValue(this.styleApplied.innerText);
103+
if (this.applicationService.rawCustomStyle) {
104+
this.savedStyle = this.applicationService.customStyle?.innerText || '';
105+
this.rawCustomStyle = this.applicationService.rawCustomStyle;
106+
this.formControl.setValue(this.rawCustomStyle, { emitEvent: false });
87107
this.formControl.markAsPristine();
88108
} else {
89-
this.applicationService.customStyle = this.styleApplied;
109+
const styleElement = document.createElement('style');
110+
styleElement.innerText = '';
111+
document.getElementsByTagName('head')[0].appendChild(styleElement);
112+
this.applicationService.rawCustomStyle = this.rawCustomStyle;
113+
this.applicationService.customStyle = styleElement;
90114
}
91115

92116
this.applicationService.application$
@@ -117,7 +141,11 @@ export class CustomStyleComponent
117141
.subscribe((confirm: any) => {
118142
if (confirm) {
119143
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
120-
this.applicationService.customStyle!.innerText = this.savedStyle;
144+
145+
if (this.applicationService.customStyle) {
146+
this.applicationService.customStyleEdited = false;
147+
this.applicationService.customStyle.innerText = this.savedStyle;
148+
}
121149
this.cancel.emit(true);
122150
}
123151
});
@@ -127,6 +155,7 @@ export class CustomStyleComponent
127155
/** Save application custom css styling */
128156
async onSave(): Promise<void> {
129157
this.loading = true;
158+
130159
const file = new File(
131160
[this.formControl.value as string],
132161
'customStyle.scss',
@@ -159,7 +188,8 @@ export class CustomStyleComponent
159188
);
160189
this.formControl.markAsPristine();
161190
this.applicationService.customStyleEdited = false;
162-
this.applicationService.customStyle = this.styleApplied;
191+
this.applicationService.rawCustomStyle = this.rawCustomStyle;
192+
this.savedStyle = this.applicationService.customStyle?.innerText || '';
163193
}
164194
this.loading = false;
165195
}
@@ -182,4 +212,15 @@ export class CustomStyleComponent
182212
}, 100);
183213
}
184214
}
215+
216+
override ngOnDestroy(): void {
217+
super.ngOnDestroy();
218+
if (
219+
this.applicationService.customStyleEdited &&
220+
this.applicationService.customStyle
221+
) {
222+
this.applicationService.customStyleEdited = false;
223+
this.applicationService.customStyle.innerText = this.savedStyle;
224+
}
225+
}
185226
}

libs/safe/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export * from './lib/services/paginator-translate'; // todo: update
2525
export * from './lib/services/context/context.service';
2626
export * from './lib/services/data-template/data-template.service';
2727
export * from './lib/services/editor/editor.service';
28+
export * from './lib/services/rest/rest.service';
2829

2930
// === DIRECTIVES ===
3031
export * from './lib/directives/skeleton/public-api';

libs/safe/src/lib/services/application/application.service.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ export class SafeApplicationService {
117117
private environment: any;
118118

119119
/** Application custom style */
120+
public rawCustomStyle?: string;
120121
public customStyle?: HTMLStyleElement;
121122
public customStyleEdited = false;
122123

@@ -270,7 +271,8 @@ export class SafeApplicationService {
270271
*/
271272
leaveApplication(): void {
272273
if (this.customStyle) {
273-
document.getElementsByTagName('body')[0].removeChild(this.customStyle);
274+
document.getElementsByTagName('head')[0].removeChild(this.customStyle);
275+
this.rawCustomStyle = undefined;
274276
this.customStyle = undefined;
275277
this.layoutService.closeRightSidenav = true;
276278
}
@@ -1912,11 +1914,26 @@ export class SafeApplicationService {
19121914
.then(async (res) => {
19131915
if (res.type === 'application/octet-stream') {
19141916
const styleFromFile = await res.text();
1917+
const scss = styleFromFile as string;
19151918
this.customStyle = document.createElement('style');
1916-
this.customStyle.innerText = styleFromFile;
1917-
document
1918-
.getElementsByTagName('body')[0]
1919-
.appendChild(this.customStyle);
1919+
this.restService
1920+
.post('style/scss-to-css', { scss }, { responseType: 'text' })
1921+
.subscribe({
1922+
next: (css) => {
1923+
if (this.customStyle) {
1924+
this.customStyle.innerText = css;
1925+
document
1926+
.getElementsByTagName('head')[0]
1927+
.appendChild(this.customStyle);
1928+
}
1929+
},
1930+
error: () => {
1931+
if (this.customStyle) {
1932+
this.customStyle.innerText = styleFromFile;
1933+
}
1934+
},
1935+
});
1936+
this.rawCustomStyle = styleFromFile;
19201937
}
19211938
})
19221939
.catch((err) => {

0 commit comments

Comments
 (0)