| |
| |
| |
|
|
|
|
| const PLACEHOLDER = '—';
|
|
|
| |
| |
| |
|
|
| export function formatNumber(
|
| value: unknown,
|
| opts?: { decimals?: number; suffix?: string; prefix?: string }
|
| ): string {
|
| const { decimals = 2, suffix = '', prefix = '' } = opts || {};
|
|
|
|
|
| if (value === null || value === undefined) {
|
| return PLACEHOLDER;
|
| }
|
|
|
|
|
| if (value === '') {
|
| return PLACEHOLDER;
|
| }
|
|
|
|
|
| let num: number;
|
| if (typeof value === 'number') {
|
| num = value;
|
| } else if (typeof value === 'string') {
|
| num = parseFloat(value);
|
| } else {
|
| return PLACEHOLDER;
|
| }
|
|
|
|
|
| if (!isFinite(num) || isNaN(num)) {
|
| return PLACEHOLDER;
|
| }
|
|
|
|
|
| const formatted = num.toFixed(decimals);
|
| return `${prefix}${formatted}${suffix}`;
|
| }
|
|
|
| |
| |
| |
| |
|
|
| export function formatArrayNumber(
|
| value: unknown,
|
| opts?: { decimals?: number; suffix?: string; prefix?: string; selectMin?: boolean }
|
| ): string {
|
| const { selectMin = false } = opts || {};
|
|
|
|
|
| if (value === null || value === undefined) {
|
| return PLACEHOLDER;
|
| }
|
|
|
|
|
| if (Array.isArray(value)) {
|
| if (value.length === 0) {
|
| return PLACEHOLDER;
|
| }
|
|
|
|
|
| const numbers = value
|
| .map(v => (typeof v === 'number' ? v : parseFloat(v)))
|
| .filter(n => isFinite(n) && !isNaN(n));
|
|
|
| if (numbers.length === 0) {
|
| return PLACEHOLDER;
|
| }
|
|
|
|
|
| const selected = selectMin ? Math.min(...numbers) : numbers[0];
|
| return formatNumber(selected, opts);
|
| }
|
|
|
|
|
| return formatNumber(value, opts);
|
| }
|
|
|
| |
| |
|
|
| export function formatText(value: unknown, placeholder: string = PLACEHOLDER): string {
|
| if (value === null || value === undefined) {
|
| return placeholder;
|
| }
|
|
|
| if (typeof value === 'string') {
|
| const trimmed = value.trim();
|
| return trimmed === '' ? placeholder : trimmed;
|
| }
|
|
|
| if (typeof value === 'number') {
|
| return String(value);
|
| }
|
|
|
| if (typeof value === 'boolean') {
|
| return value ? 'Yes' : 'No';
|
| }
|
|
|
|
|
| return placeholder;
|
| }
|
|
|
| |
| |
|
|
| export function formatTemperature(value: unknown): string {
|
| return formatNumber(value, { decimals: 1, suffix: ' K' });
|
| }
|
|
|
| |
| |
|
|
| export function formatPH(value: unknown): string {
|
| return formatNumber(value, { decimals: 1 });
|
| }
|
|
|
| |
| |
|
|
| export function formatResolution(value: unknown): string {
|
| return formatArrayNumber(value, { decimals: 2, suffix: ' Å', selectMin: true });
|
| }
|
|
|
| |
| |
|
|
| export function truncateText(text: string, maxLength: number = 120): string {
|
| if (!text || text.length <= maxLength) {
|
| return text;
|
| }
|
| return text.substring(0, maxLength) + '...';
|
| }
|
|
|