Skip to content

Commit

Permalink
added new property type for year numbers (without thousands separator)
Browse files Browse the repository at this point in the history
  • Loading branch information
heinerwalter committed Nov 23, 2024
1 parent 5b56a3f commit a47402f
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 161 deletions.
Original file line number Diff line number Diff line change
@@ -1,113 +1,7 @@
import { PEGlobalFunctions } from '../../controller/pe-global-functions';
import { Stringifier } from '../../controller/stringifier';
import { PropertyEditorMode } from './property-editor-mode';

export type PropertyType =
/** Boolean (true/false). */
'boolean' |
/** Boolean with indeterminate state (true/false/undefined). */
'boolean-indeterminate' |
/** Date (no time). */
'date' |
/** Date and time. */
'datetime' |
/** Time. */
'time' |
/** Month and year. */
'month' |
/** Number. */
'number' |
/** String edited using a single line text input. */
'string' |
/** For now same behavior as 'string'. Only for database ID properties 'id' should be used instead of 'string'. */
'id' |
/** String edited using a multiline textarea. */
'string-multiline' |
/** Internally a string property edited using a password input. */
'password' |
/** Internally a string property edited using a phone input. */
'tel' |
/** Internally a string property edited using an email address input. */
'email' |
/** Internally a string property edited using a URL input. */
'url' |
/** Internally a string property edited using a color picker. */
'color' |
/** Star rating. */
'rating' |
/** Select an item from a `dataSource`. */
'select' |
/**
* A button triggering the `setValueFunction`.
* The `label` is displayed as button text,
* the `routerLinkTooltip` is displayed as button tooltip,
* and the button is enabled when `editable`.
*/
'button';

/**
* Returns true, if the given property type requires boolean values.
* @param propertyType A property type.
*/
export function propertyTypeIsBoolean(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'boolean':
case 'boolean-indeterminate':
return true;
default:
return false;
}
}

/**
* Returns true, if the given property type requires date values.
* @param propertyType A property type.
*/
export function propertyTypeIsDate(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'date':
case 'datetime':
case 'time':
case 'month':
return true;
default:
return false;
}
}

/**
* Returns true, if the given property type requires numeric values.
* @param propertyType A property type.
*/
export function propertyTypeIsNumber(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'number':
case 'rating':
return true;
default:
return false;
}
}

/**
* Returns true, if the given property type requires string values.
* @param propertyType A property type.
*/
export function propertyTypeIsString(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'string':
case 'id':
case 'string-multiline':
case 'tel':
case 'email':
case 'url':
case 'color':
case 'password':
return true;
default:
return false;
}
}
import { generatePropertyTypeFromData, PropertyType } from './property-type';

/**
* Some properties of `PropertyConfiguration` can be defined as constant type or
Expand Down Expand Up @@ -758,51 +652,6 @@ export class PropertyConfigurationSeparator extends PropertyConfiguration {
export type PropertiesConfiguration = PropertyConfiguration[];


/**
* Automatically determins a property type for use in a `PropertyConfiguration`
* from the given value.
* @param propertyValue Value of a property.
* @returns Automatically detected property type matching the given value.
*/
export function generatePropertyTypeFromData(propertyValue: any): PropertyType | undefined {
// If the given value is an array with at least one element,
// generate the property type from the first element (and set `isArray` to true).
if (Array.isArray(propertyValue) && propertyValue?.length) {
propertyValue = propertyValue[0];
}

switch (typeof propertyValue) {
case 'boolean':
return 'boolean';
case 'number':
case 'bigint':
return 'number';
case 'string':
if (propertyValue.includes('\n'))
return 'string-multiline';
else if (propertyValue.includes('@'))
return 'email';
return 'string';

case 'object':
if (propertyValue instanceof Date)
return 'date';
return undefined;

case 'function':
try {
return generatePropertyTypeFromData(propertyValue());
} catch {
return undefined;
}

case 'undefined':
case 'symbol':
default:
return undefined;
}
}

/**
* Generates a `PropertiesConfiguration` from the properties of the given data object.
* @param data A data object to be displayed by a property table or property editor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</pe-date-input>
</ng-container>

<ng-container *ngIf="configuration.propertyType == 'number'">
<ng-container *ngIf="configuration.propertyType == 'number' || configuration.propertyType == 'year'">
<pe-number-input [id]="configuration.propertyName || id"
[name]="configuration.propertyName"
[noFormGroup]="noFormGroup"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@ export class PropertyInputComponent {
this.configuration?.setValue(this.data, undefined);
}

protected readonly undefined = undefined;
protected readonly undefined = undefined;

Check failure on line 62 in projects/ngx-property-editor/src/lib/components/property-views/property-input/property-input.component.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Duplicate identifier 'undefined'.

Check failure on line 62 in projects/ngx-property-editor/src/lib/components/property-views/property-input/property-input.component.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Duplicate identifier 'undefined'.

Check failure on line 62 in projects/ngx-property-editor/src/lib/components/property-views/property-input/property-input.component.ts

View workflow job for this annotation

GitHub Actions / build

Duplicate identifier 'undefined'.

Check failure on line 62 in projects/ngx-property-editor/src/lib/components/property-views/property-input/property-input.component.ts

View workflow job for this annotation

GitHub Actions / build

Duplicate identifier 'undefined'.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* Possible property types of property configurations.
*/
export type PropertyType =
/** Boolean (true/false). */
'boolean' |
/** Boolean with indeterminate state (true/false/undefined). */
'boolean-indeterminate' |
/** Date (no time). */
'date' |
/** Date and time. */
'datetime' |
/** Time. */
'time' |
/** Month and year. */
'month' |
/** Year number. */
'year' |
/** Number. */
'number' |
/** String edited using a single line text input. */
'string' |
/** For now same behavior as 'string'. Only for database ID properties 'id' should be used instead of 'string'. */
'id' |
/** String edited using a multiline textarea. */
'string-multiline' |
/** Internally a string property edited using a password input. */
'password' |
/** Internally a string property edited using a phone input. */
'tel' |
/** Internally a string property edited using an email address input. */
'email' |
/** Internally a string property edited using a URL input. */
'url' |
/** Internally a string property edited using a color picker. */
'color' |
/** Star rating. */
'rating' |
/** Select an item from a `dataSource`. */
'select' |
/**
* A button triggering the `setValueFunction`.
* The `label` is displayed as button text,
* the `routerLinkTooltip` is displayed as button tooltip,
* and the button is enabled when `editable`.
*/
'button';

/**
* Returns true, if the given property type requires boolean values.
* @param propertyType A property type.
*/
export function propertyTypeIsBoolean(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'boolean':
case 'boolean-indeterminate':
return true;
default:
return false;
}
}

/**
* Returns true, if the given property type requires date values.
* @param propertyType A property type.
*/
export function propertyTypeIsDate(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'date':
case 'datetime':
case 'time':
case 'month':
return true;
default:
return false;
}
}

/**
* Returns true, if the given property type requires numeric values.
* @param propertyType A property type.
*/
export function propertyTypeIsNumber(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'number':
case 'rating':
case 'year':
return true;
default:
return false;
}
}

/**
* Returns true, if the given property type requires string values.
* @param propertyType A property type.
*/
export function propertyTypeIsString(propertyType: PropertyType): boolean {
switch (propertyType) {
case 'string':
case 'id':
case 'string-multiline':
case 'tel':
case 'email':
case 'url':
case 'color':
case 'password':
return true;
default:
return false;
}
}

/**
* Automatically determines a property type for use in a `PropertyConfiguration`
* from the given value.
* @param propertyValue Value of a property.
* @returns Automatically detected property type matching the given value.
*/
export function generatePropertyTypeFromData(propertyValue: any): PropertyType | undefined {
// If the given value is an array with at least one element,
// generate the property type from the first element (and set `isArray` to true).
if (Array.isArray(propertyValue) && propertyValue?.length) {
propertyValue = propertyValue[0];
}

switch (typeof propertyValue) {
case 'boolean':
return 'boolean';
case 'number':
case 'bigint':
return 'number';
case 'string':
if (propertyValue.includes('\n'))
return 'string-multiline';
else if (propertyValue.includes('@'))
return 'email';
return 'string';

case 'object':
if (propertyValue instanceof Date)
return 'date';
return undefined;

case 'function':
try {
return generatePropertyTypeFromData(propertyValue());
} catch {
return undefined;
}

case 'undefined':
case 'symbol':
default:
return undefined;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ describe('Stringifier', () => {
expect(Stringifier.numberToString(42)).toEqual('42');
expect(Stringifier.numberToString(-11)).toEqual('-11');

expect(Stringifier.numberToString(10245893)).toEqual('10.245.893');
expect(Stringifier.numberToString(10245893, true)).toEqual('10.245.893');
expect(Stringifier.numberToString(10245893, false)).toEqual('10245893');

expect(Stringifier.numberToString(BigInt(12))).toEqual('12');
expect(Stringifier.numberToString(BigInt('12345678901234567890'))).toEqual(BigInt('12345678901234567890').toLocaleString());
});
Expand Down
14 changes: 9 additions & 5 deletions projects/ngx-property-editor/src/lib/controller/stringifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import { $localize } from '@angular/localize/init';
import {
PropertyType,
propertyTypeIsBoolean,
PropertyType, propertyTypeIsBoolean,
propertyTypeIsDate,
propertyTypeIsNumber,
propertyTypeIsString,
} from '../components/property-views/property-configuration';
} from '../components/property-views/property-type';

export module Stringifier {

Expand Down Expand Up @@ -159,12 +158,15 @@ export module Stringifier {
/**
* Returns the given number as locale string.
* @param value Convert this number to a string.
* @param useGrouping Should the returned string contain thousands separators?
* Use undefined for default.
*/
export function numberToString(value: number | bigint | undefined): string {
export function numberToString(value: number | bigint | undefined,
useGrouping: boolean | undefined = undefined): string {
if ((typeof value !== 'number' && typeof value !== 'bigint') ||
(typeof value === 'number' && isNaN(value)))
return '';
return value.toLocaleString();
return value.toLocaleString(undefined, { useGrouping: useGrouping });
}

/**
Expand Down Expand Up @@ -747,6 +749,8 @@ export module Stringifier {
case 'number':
case 'rating':
return numberToString(value);
case 'year':
return numberToString(value, false);

case 'string':
case 'id':
Expand Down
Loading

0 comments on commit a47402f

Please sign in to comment.