mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 08:17:18 +08:00
Merge 39d5185916
into 3e06d0f16a
This commit is contained in:
commit
5d7bec029f
5 changed files with 126 additions and 1 deletions
|
@ -31,6 +31,7 @@ import {FormatOptions, Formatter} from './formatter.model';
|
|||
import {CurrencyFormatter} from './currency/currency-formatter.service';
|
||||
import {DateFormatter} from './datetime/date-formatter.service';
|
||||
import {PhoneFormatter} from './phone/phone-formatter.service';
|
||||
import {TextFormatter} from "./text/text-formatter.service";
|
||||
|
||||
export interface TypeFormatterMap {
|
||||
[key: string]: Formatter;
|
||||
|
@ -49,6 +50,7 @@ export class DataTypeFormatter {
|
|||
protected dateFormatter: DateFormatter,
|
||||
protected datetimeFormatter: DatetimeFormatter,
|
||||
protected phoneFormatter: PhoneFormatter,
|
||||
protected text: TextFormatter,
|
||||
) {
|
||||
this.map.int = numberFormatter;
|
||||
this.map.float = numberFormatter;
|
||||
|
@ -56,6 +58,7 @@ export class DataTypeFormatter {
|
|||
this.map.datetime = datetimeFormatter;
|
||||
this.map.currency = currencyFormatter;
|
||||
this.map.phone = phoneFormatter;
|
||||
this.map.text = text;
|
||||
}
|
||||
|
||||
toUserFormat(dataType: string, value: string, options?: FormatOptions): string {
|
||||
|
|
|
@ -30,11 +30,13 @@ import {numberFormatterMock} from './number/number-formatter.spec.mock';
|
|||
import {datetimeFormatterMock} from './datetime/datetime-formatter.service.spec.mock';
|
||||
import {phoneFormatterMock} from './phone/phone-formatter.spec.mock';
|
||||
import {dateFormatterMock} from './datetime/date-formatter.service.spec.mock';
|
||||
import {textFormatterMock} from "./text/text-formatter.service.spec.mock";
|
||||
|
||||
export const dataTypeFormatterMock = new DataTypeFormatter(
|
||||
currencyFormatterMock,
|
||||
numberFormatterMock,
|
||||
dateFormatterMock,
|
||||
datetimeFormatterMock,
|
||||
phoneFormatterMock
|
||||
phoneFormatterMock,
|
||||
textFormatterMock
|
||||
);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SalesAgility Ltd.
|
||||
* Copyright (C) 2021 SalesAgility Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SALESAGILITY, SALESAGILITY DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
import { TextFormatter } from './text-formatter.service';
|
||||
import {FormControlUtils} from '../../../services/record/field/form-control.utils';
|
||||
import {userPreferenceStoreMock} from '../../../store/user-preference/user-preference.store.spec.mock';
|
||||
|
||||
export const textFormatterMock = new TextFormatter(userPreferenceStoreMock,new FormControlUtils(),'en_US');
|
85
core/app/core/src/lib/services/formatters/text/text-formatter.service.ts
Executable file
85
core/app/core/src/lib/services/formatters/text/text-formatter.service.ts
Executable file
|
@ -0,0 +1,85 @@
|
|||
import {Inject, Injectable, LOCALE_ID} from '@angular/core';
|
||||
import {FormatOptions, Formatter} from '../formatter.model';
|
||||
import { FormControlUtils } from '../../record/field/form-control.utils';
|
||||
import {UserPreferenceStore} from "../../../store/user-preference/user-preference.store";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TextFormatter implements Formatter {
|
||||
|
||||
private defaultMap: { [key: string]: string } = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'à': 'à', 'á': 'á', 'â': 'â', 'ã': 'ã', 'ä': 'ä',
|
||||
'è': 'è', 'é': 'é', 'ê': 'ê', 'ë': 'ë',
|
||||
'ì': 'ì', 'í': 'í', 'î': 'î', 'ï': 'ï',
|
||||
'ò': 'ò', 'ó': 'ó', 'ô': 'ô', 'õ': 'õ', 'ö': 'ö',
|
||||
'ù': 'ù', 'ú': 'ú', 'û': 'û', 'ü': 'ü',
|
||||
'ñ': 'ñ', 'Ñ': 'Ñ',
|
||||
'ç': 'ç', 'Ç': 'Ç',
|
||||
'€': '€',
|
||||
'¥': '¥',
|
||||
'£': '£',
|
||||
'¢': '¢',
|
||||
'©': '©',
|
||||
'®': '®',
|
||||
'™': '™',
|
||||
'§': '§',
|
||||
'¶': '¶',
|
||||
'•': '•',
|
||||
'…': '…',
|
||||
'–': '–',
|
||||
'—': '—',
|
||||
// ... add more characters as needed
|
||||
};
|
||||
|
||||
constructor(
|
||||
protected preferences: UserPreferenceStore,
|
||||
protected formUtils: FormControlUtils,
|
||||
@Inject(LOCALE_ID) public locale: string
|
||||
) {}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the value to a format suitable for display to the user.
|
||||
* Escapes HTML special characters.
|
||||
*/
|
||||
toUserFormat(value: string, options?: FormatOptions): string {
|
||||
// Reverse the map for decoding
|
||||
const decodeMap: { [key: string]: string } = Object.entries(this.defaultMap).reduce((acc, [char, entity]) => {
|
||||
acc[entity] = char;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Create a regex to match all entities in the text
|
||||
const entityRegex = new RegExp(Object.keys(decodeMap).join('|'), 'g');
|
||||
|
||||
// Recursively decode until no more encoded entities remain
|
||||
let decodedValue = value;
|
||||
let previousValue;
|
||||
|
||||
do {
|
||||
previousValue = decodedValue;
|
||||
decodedValue = decodedValue?.replace(entityRegex, (match) => decodeMap[match] || match);
|
||||
} while (decodedValue !== previousValue); // Repeat until no changes
|
||||
|
||||
return decodedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the user input back to the internal format.
|
||||
* Decodes HTML special characters.
|
||||
*/
|
||||
toInternalFormat(value): string {
|
||||
const formmatedValue = value?.replace(/[<>&"'\u00A0-\uFFFF]/g, (match) => {
|
||||
const encoded = this.defaultMap[match];
|
||||
return encoded !== undefined ? encoded : match;
|
||||
});
|
||||
return formmatedValue;
|
||||
}
|
||||
|
||||
}
|
|
@ -204,6 +204,10 @@ export class FieldBuilder {
|
|||
if (defaultValue) {
|
||||
field.default = defaultValue;
|
||||
}
|
||||
// issue #542 formmattedValue applied to value (only for text fields?)
|
||||
if(field.type == 'text'){
|
||||
field.value = formattedValue;
|
||||
}
|
||||
|
||||
field.defaultValueModes = viewField?.defaultValueModes ?? definition?.defaultValueModes ?? [];
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue