Merge pull request #3013 from shubhamkumar9199/fix/templates-dark-mode

WEB-552: fix(templates) fix TinyMCE editor dark mode styling
This commit is contained in:
Jose Alberto Hernandez
2026-01-19 10:15:15 -05:00
committed by GitHub
3 changed files with 182 additions and 71 deletions
@@ -99,14 +99,16 @@
<label for="template-text-editor" class="required-label required-label-editor"> <label for="template-text-editor" class="required-label required-label-editor">
{{ 'labels.inputs.Text' | translate }} <span class="required-asterisk">*</span> {{ 'labels.inputs.Text' | translate }} <span class="required-asterisk">*</span>
</label> </label>
<editor @if (editorVisible) {
id="template-text-editor" <editor
#tinymceEditor id="template-text-editor"
[init]="tinymceConfig" #tinymceEditor
[initialValue]="templateData.template?.text || ''" [init]="tinymceConfig"
licenseKey="gpl" [initialValue]="templateData.template?.text || ''"
[formControl]="templateForm.controls.text" licenseKey="gpl"
></editor> [formControl]="templateForm.controls.text"
></editor>
}
</div> </div>
</mat-card-content> </mat-card-content>
@@ -7,7 +7,8 @@
*/ */
/** Angular Imports */ /** Angular Imports */
import { Component, OnInit, ViewChild, inject } from '@angular/core'; import { Component, OnInit, ViewChild, inject, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { import {
UntypedFormGroup, UntypedFormGroup,
UntypedFormBuilder, UntypedFormBuilder,
@@ -23,6 +24,7 @@ import { clientParameterLabels, loanParameterLabels, repaymentParameterLabels }
/** Custom Services */ /** Custom Services */
import { TemplatesService } from '../templates.service'; import { TemplatesService } from '../templates.service';
import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { ThemingService } from 'app/shared/theme-toggle/theming.service';
import { EditorComponent, EditorModule, TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular'; import { EditorComponent, EditorModule, TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular';
import { import {
MatAccordion, MatAccordion,
@@ -60,22 +62,34 @@ export class CreateEditComponent implements OnInit {
private route = inject(ActivatedRoute); private route = inject(ActivatedRoute);
private router = inject(Router); private router = inject(Router);
private templateService = inject(TemplatesService); private templateService = inject(TemplatesService);
private themingService = inject(ThemingService);
private destroyRef = inject(DestroyRef);
/** TinyMCE instance configuration */ themeKey = 'light';
tinymceConfig = {
base_url: 'assets/tinymce', editorVisible = true;
suffix: '.min',
menubar: false, get tinymceConfig() {
branding: false, const isDark = this.themeKey === 'dark-theme';
height: 320, return {
forced_root_block: false, base_url: 'assets/tinymce',
statusbar: false, suffix: '.min',
elementpath: false, menubar: false,
resize: false, branding: false,
plugins: 'lists link table media codesample', height: 320,
toolbar: forced_root_block: false,
'undo redo | blocks | bold italic underline | link | numlist bullist outdent indent | alignleft aligncenter alignright alignjustify | table media | removeformat' statusbar: false,
}; elementpath: false,
resize: false,
skin: isDark ? 'oxide-dark' : 'oxide',
content_css: isDark ? 'dark' : 'default',
content_style: isDark ? 'body { background-color: transparent !important; }' : '',
body_class: isDark ? 'dark-theme' : '',
plugins: 'lists link table media codesample',
toolbar:
'undo redo | blocks | bold italic underline | link | numlist bullist outdent indent | alignleft aligncenter alignright alignjustify | table media | removeformat'
};
}
/** TinyMCE component reference */ /** TinyMCE component reference */
@ViewChild('tinymceEditor', { static: false }) tinymceEditor: EditorComponent; @ViewChild('tinymceEditor', { static: false }) tinymceEditor: EditorComponent;
@@ -105,16 +119,24 @@ export class CreateEditComponent implements OnInit {
* @param {TemplateService} templateService Templates Service * @param {TemplateService} templateService Templates Service
*/ */
constructor() { constructor() {
this.route.data.subscribe((data: { templateData: any; mode: 'create' | 'edit' }) => { this.route.data
this.templateData = data.templateData; .pipe(takeUntilDestroyed(this.destroyRef))
this.mode = data.mode; .subscribe((data: { templateData: any; mode: 'create' | 'edit' }) => {
if (this.mode === 'edit') { this.templateData = data.templateData;
this.mappers = this.templateData.template.mappers.map((mapper: any) => ({ this.mode = data.mode;
mappersorder: mapper.mapperorder, if (this.mode === 'edit') {
mapperskey: new UntypedFormControl(mapper.mapperkey), this.mappers = this.templateData.template.mappers.map((mapper: any) => ({
mappersvalue: new UntypedFormControl(mapper.mappervalue) mappersorder: mapper.mapperorder,
})); mapperskey: new UntypedFormControl(mapper.mapperkey),
} mappersvalue: new UntypedFormControl(mapper.mappervalue)
}));
}
});
this.themingService.theme.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((theme) => {
this.themeKey = theme;
this.editorVisible = false;
setTimeout(() => (this.editorVisible = true));
}); });
} }
@@ -173,25 +195,30 @@ export class CreateEditComponent implements OnInit {
*/ */
buildDependencies() { buildDependencies() {
const tenantIdentifier = 'default'; // update once global settings are setup. const tenantIdentifier = 'default'; // update once global settings are setup.
this.templateForm.get('entity').valueChanges.subscribe((value: any) => { this.templateForm
if (value === 0) { .get('entity')
// client .valueChanges.pipe(takeUntilDestroyed(this.destroyRef))
this.mappers.splice(0, 1, { .subscribe((value: any) => {
mappersorder: 0, if (value === 0) {
mapperskey: new UntypedFormControl('client'), // client
mappersvalue: new UntypedFormControl('clients/{{clientId}}?tenantIdentifier=' + tenantIdentifier) this.mappers.splice(0, 1, {
}); mappersorder: 0,
} else { mapperskey: new UntypedFormControl('client'),
// loan mappersvalue: new UntypedFormControl('clients/{{clientId}}?tenantIdentifier=' + tenantIdentifier)
this.mappers.splice(0, 1, { });
mappersorder: 0, } else {
mapperskey: new UntypedFormControl('loan'), // loan
mappersvalue: new UntypedFormControl('loans/{{loanId}}?associations=all&tenantIdentifier=' + tenantIdentifier) this.mappers.splice(0, 1, {
}); mappersorder: 0,
} mapperskey: new UntypedFormControl('loan'),
this.setEditorContent(''); mappersvalue: new UntypedFormControl(
this.templateForm.get('text').setValue(''); 'loans/{{loanId}}?associations=all&tenantIdentifier=' + tenantIdentifier
}); )
});
}
this.setEditorContent('');
this.templateForm.get('text').setValue('');
});
if (this.mode === 'create') { if (this.mode === 'create') {
this.templateForm.get('entity').patchValue(0); this.templateForm.get('entity').patchValue(0);
} }
+100 -18
View File
@@ -147,7 +147,7 @@
} }
.responsive-column { .responsive-column {
@media (width <= 768px) { @media (width <=768px) {
flex-direction: column; flex-direction: column;
} }
} }
@@ -235,13 +235,13 @@
} }
.layout-gt-sm-row { .layout-gt-sm-row {
@media (width >= 600px) { @media (width >=600px) {
flex-direction: row; flex-direction: row;
} }
} }
.align-gt-sm-start-center { .align-gt-sm-start-center {
@media (width >= 600px) { @media (width >=600px) {
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
} }
@@ -369,7 +369,7 @@
flex: 0 0 48%; flex: 0 0 48%;
} }
@media (width <= 768px) { @media (width <=768px) {
.hide-lt-md { .hide-lt-md {
display: none !important; display: none !important;
} }
@@ -442,21 +442,21 @@
flex: 0 0 96%; flex: 0 0 96%;
} }
@media screen and (width <= 599px) { @media screen and (width <=599px) {
.flex-xs-15 { .flex-xs-15 {
flex: 0 0 15%; flex: 0 0 15%;
max-width: 15%; max-width: 15%;
} }
} }
@media screen and (width >= 600px) and (width <= 959px) { @media screen and (width >=600px) and (width <=959px) {
.flex-sm-10 { .flex-sm-10 {
flex: 0 0 10%; flex: 0 0 10%;
max-width: 10%; max-width: 10%;
} }
} }
@media screen and (width >= 960px) and (width <= 1279px) { @media screen and (width >=960px) and (width <=1279px) {
.flex-md-5 { .flex-md-5 {
flex: 0 0 5%; flex: 0 0 5%;
max-width: 5%; max-width: 5%;
@@ -464,7 +464,7 @@
} }
.hide-lt-sm { .hide-lt-sm {
@media (width <= 599px) { @media (width <=599px) {
display: none !important; display: none !important;
} }
} }
@@ -548,24 +548,24 @@
} }
.flex-gt-sm-30 { .flex-gt-sm-30 {
@media (width >= 600px) { @media (width >=600px) {
flex: 1 0 30%; flex: 1 0 30%;
} }
} }
@media (width <= 1199px) { @media (width <=1199px) {
.hide-lt-lg { .hide-lt-lg {
display: none !important; display: none !important;
} }
} }
@media (width <= 768px) { @media (width <=768px) {
.flex-25 { .flex-25 {
flex: 0 0 50%; flex: 0 0 50%;
} }
} }
@media (width <= 599px) { @media (width <=599px) {
.layout-xs-column { .layout-xs-column {
flex-direction: column; flex-direction: column;
} }
@@ -584,19 +584,19 @@
} }
.layout-lt-md-column { .layout-lt-md-column {
@media (width <= 768px) { @media (width <=768px) {
flex-direction: column; flex-direction: column;
} }
} }
.layout-column.lt-md { .layout-column.lt-md {
@media (width <= 599px) { @media (width <=599px) {
flex-direction: column !important; flex-direction: column !important;
} }
} }
.responsive-flex-full { .responsive-flex-full {
@media (width <= 768px) { @media (width <=768px) {
flex: 0 0 100% !important; flex: 0 0 100% !important;
} }
} }
@@ -617,19 +617,19 @@
} }
} }
@media (width <= 768px) { @media (width <=768px) {
.flex-lt-md-50 { .flex-lt-md-50 {
flex: 0 0 50%; flex: 0 0 50%;
} }
} }
@media (width <= 768px) { @media (width <=768px) {
.flex-50-lt-md { .flex-50-lt-md {
flex: 0 0 50%; flex: 0 0 50%;
} }
} }
@media (width <= 599px) { @media (width <=599px) {
.layout-column-xs { .layout-column-xs {
flex-direction: column !important; flex-direction: column !important;
} }
@@ -719,3 +719,85 @@ mat-card {
overflow: hidden; overflow: hidden;
} }
} }
.dark-theme {
.tox.tox-tinymce {
border-color: #444 !important;
}
.tox .tox-editor-header,
.tox .tox-toolbar-overlord,
.tox .tox-toolbar,
.tox .tox-toolbar__overflow,
.tox .tox-toolbar__primary {
background-color: #303135 !important;
}
.tox .tox-tbtn {
background-color: transparent !important;
color: rgb(255 255 255 / 87%) !important;
svg {
fill: rgb(255 255 255 / 87%) !important;
}
&:hover {
background-color: rgb(255 255 255 / 12%) !important;
}
&:focus {
background-color: rgb(255 255 255 / 8%) !important;
}
}
.tox .tox-tbtn--bevel {
background: transparent !important;
}
.tox .tox-tbtn--select {
background-color: transparent !important;
}
.tox .tox-split-button {
background-color: transparent !important;
&:hover {
box-shadow: none !important;
}
}
.tox .tox-edit-area {
background-color: #303135 !important;
iframe {
background-color: transparent !important;
}
}
.tox .tox-sidebar-wrap {
background-color: #303135 !important;
}
.tox .tox-menubar {
background-color: #303135 !important;
}
.tox .tox-menu {
background-color: #303135 !important;
border-color: #444 !important;
}
.tox .tox-collection__item {
color: rgb(255 255 255 / 87%) !important;
&:hover {
background-color: rgb(255 255 255 / 8%) !important;
}
}
.tox .tox-statusbar {
background-color: #303135 !important;
border-color: #444 !important;
color: rgb(255 255 255 / 60%) !important;
}
}