Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(grid): expose editorOptions for the default editors and improve built-in editing for date/time cols (input formats) #14465

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
77a8696
feat(date-time-util): logic to identify numeric formats for editing
ddaribo Jul 3, 2024
705de49
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Jul 3, 2024
334cba2
chore(date-time-util): formatting fixes
ddaribo Jul 3, 2024
3648659
Merge branch 'bpachilova/grid-editor-options-feat-14009' of https://g…
ddaribo Jul 3, 2024
e24c974
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Jul 12, 2024
82c1fd3
fix(esf-styles): small margin fix for time picker
ddaribo Jul 12, 2024
602d25d
feat(grid-interface): add editorOptions property on the ColumnType an…
ddaribo Jul 12, 2024
282c896
feat(grid-column): get/set editorOptions and dateTimeFormat
ddaribo Jul 12, 2024
ca0f4f5
feat(grid-cells): use editorOptions.dateTimeFormat; add locale where …
ddaribo Jul 12, 2024
78e76c1
feat(grid-filters): use editorOptions.dateTimeFormat and locale on fi…
ddaribo Jul 12, 2024
6c8e88e
test(grid-column-and-filtering): editors input formats
ddaribo Jul 12, 2024
913a7cd
chore(grid-cells): delete leftover inputFormat bindings
ddaribo Jul 12, 2024
fb063af
chore(column-test): fix time col format test check
ddaribo Jul 12, 2024
d5264e1
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Jul 15, 2024
dcd9517
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Jul 15, 2024
017fdfb
feat(date-time-util): default locale-based format for time and date-t…
ddaribo Jul 17, 2024
4c0b4fa
feat(date-time-editors): handle default inputFormat based on locale
ddaribo Jul 17, 2024
cac8366
feat(date-time-util): localize predefined formats used for input; ref…
ddaribo Jul 19, 2024
6cee547
feat(date-range): handle inputFormat when locale is changed
ddaribo Jul 19, 2024
360bc67
feat(dte-dir,pickers): handle locale change and display/input formats
ddaribo Jul 19, 2024
26708b2
refactor(column): do not handle format transformations here
ddaribo Jul 19, 2024
8e1196b
refactor(qb): editorOptions.defaultDateTimeFormat setting
ddaribo Jul 19, 2024
b06fe16
refactor(filtering-ui-test): adjust according to latest changes
ddaribo Jul 19, 2024
02cbe4c
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Jul 19, 2024
b08258c
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ChronosSF Aug 5, 2024
c9b5331
refactor(column): address comment - simplify editorOptions assignment
ddaribo Aug 9, 2024
45ddab0
chore(column): remove unused import
ddaribo Aug 9, 2024
8ce97fa
chore(docs): update changelog, grid feature readme
ddaribo Aug 13, 2024
a65d264
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Aug 15, 2024
14a6984
chore(*): fixing lint error
ddaribo Aug 15, 2024
188e1ac
chore(docs): move changelog entry under 18.2.0
ddaribo Aug 21, 2024
90018ee
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Aug 21, 2024
d90f85f
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Sep 2, 2024
98cac6b
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ChronosSF Sep 12, 2024
fcd02f4
chore(date-time.util): use formatDate method instead of new date pipe
ddaribo Sep 27, 2024
09d3978
chore(date-time.util): not set options for DateParts.AmPm (def locale…
ddaribo Sep 27, 2024
a2f2c8e
chore(date-time-tests): normalize expected string values
ddaribo Sep 30, 2024
8b71c7c
fix(date-time.util): remove 'narrow' time option
ddaribo Sep 30, 2024
f3e2a97
chore(picker-base): discard the userSetFormat internal prop
ddaribo Sep 30, 2024
14bdd91
fix(date-time-editors): do not overwrite the set inputFormat
ddaribo Sep 30, 2024
42715e7
chore(date-time-editors-tests): refactor according to the feature specs
ddaribo Sep 30, 2024
51ebb75
refactor(date-time-editors): if not set, infer input format from disp…
ddaribo Sep 30, 2024
6492941
refactor(*): if not set, infer date-time cells input format from display
ddaribo Oct 1, 2024
4ca1812
refactor(interfaces): change name to IFieldEditorOptions and alias fo…
ddaribo Oct 1, 2024
90ab1ed
chore(grid-tests): adjust tests to focus the target editor in edit mode
ddaribo Oct 1, 2024
ce5b19e
chore(dater-range-picker-test): use variable to check expectation as …
ddaribo Oct 1, 2024
72123ac
chore(changelog): edit features description
ddaribo Oct 1, 2024
e676e81
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Oct 1, 2024
ad76d3f
chore(gird-filtering-tests): fix input checks
ddaribo Oct 1, 2024
fe9d959
chore(grid-filtering-tests): edit input and display format props check
ddaribo Oct 1, 2024
2bb44ad
chore(query-builder): clear redundant logic after changes
ddaribo Oct 3, 2024
a7ffbb5
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Oct 3, 2024
e675433
fix(dte-dir): upd display value for locale wh input+display format ar…
ddaribo Oct 4, 2024
5ddf08a
chore(tests): address comments
ddaribo Oct 4, 2024
9dce296
chore(date-time.util): address comments
ddaribo Oct 4, 2024
989bde0
fix(column): do not trigger grid pipes on editorOptions set
ddaribo Oct 4, 2024
daed5c0
chore(picker-base): address comments - allow falsy value as input format
ddaribo Oct 4, 2024
567df5b
chore(date-range): address comments
ddaribo Oct 4, 2024
9b78357
chore(dte-dir): comment - allow falsy format, default is date format
ddaribo Oct 4, 2024
7df2a6c
chore(changelog): edit description
ddaribo Oct 4, 2024
625b9b7
chore(picker, date-range): refactor per comments
ddaribo Oct 4, 2024
870a5b2
chore(column.spec): refactor tests related to focusing the cell editor
ddaribo Oct 7, 2024
bbdc60b
feat(date-time-editor.directive): add defaultInputFormatType property
ddaribo Oct 7, 2024
7ace78c
feat(*): set defaultInputFormatType on dateTimeEditor in grid editors…
ddaribo Oct 7, 2024
ec9d6fb
Merge branch 'master' into bpachilova/grid-editor-options-feat-14009
ddaribo Oct 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ For Firefox users, we provide limited scrollbar styling options through the foll
- `--sb-thumb-bg-color`: Sets the background color of the scrollbar thumb.
- `--sb-track-bg-color`: Sets the background color of the scrollbar track.

#### Column editor options
- `ColumnType`, `IgxColumn`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are at least two new features here, if not 3.
You have a general grid localiation of the input format used in editors (Edit, Filtering, etc UI), auto sync from the display format (pipeArgs.format) where applicable and then the new option to override the inferred format from either of the previous two.
Oh, and technically, those seem to be features baked into all date time editors and pickers too, right? (though how we describe that based on the current comments is TBD)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and I guess we should include the Query Builder in the components getting the new functionality

Copy link
Member

@damyanpetev damyanpetev Oct 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ddaribo I'd still describe the auto localized input format and infer from the display(pipe) format as a separate (first) point. That could even be more impactful for more people than the new option which is an override if the new functionality doesn't produce quite what you'd like :)

- Added a new `editorOptions` property that allows to pass optional parameters to control properties of the default column editors. Accepts an `IColumnEditorOptions` object with the `dateTimeFormat` property, that would be used as input format for the editors of
`date`, `dateTime` and `time` column data types:
```ts
const editorOptions: IColumnEditorOptions = {
dateTimeFormat: 'MM/dd/YYYY',
}
```
```html
<igx-column field="sampleDate" dataType="date" [editorOptions]="editorOptions"></igx-column>
```
If not set, the `dateTimeFormat` resolves to the `pipeArgs.displayFormat` property of the column, in case it is set and contains only numeric date-time parts or such that can be handled by the editors. Alternatively, a fallback input format as per the `IgxGrid`'s `locale` is used.

### General
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`, `IgxPivotGrid`
- **Breaking Change** The `shouldGenerate` property have been deprecated and will be removed in a future version. Use `autoGenerate` instead. Automatic migration to this is available and will be applied on `ng update`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@
margin: rem(16px) 0;

~ igx-input-group,
~ igx-date-picker {
~ igx-date-picker,
~ igx-time-picker {
margin-inline-start: rem(16px);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { IGX_INPUT_GROUP_TYPE, IgxInputGroupType } from '../input-group/inputGro
import { IgxPrefixDirective } from '../directives/prefix/prefix.directive';
import { IgxSuffixDirective } from '../directives/suffix/suffix.directive';
import { IgxInputGroupComponent } from '../input-group/input-group.component';
import { DateTimeUtil } from './util/date-time.util';
import { DataType } from '../data-operations/data-util';

@Directive()
export abstract class PickerBaseDirective implements IToggleView, EditorProvider, AfterViewInit, AfterContentChecked, OnDestroy {
Expand All @@ -29,15 +31,23 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider
*
* @remarks
* Also used as a placeholder when none is provided.
* Default is `"'MM/dd/yyyy'"`
*
* @example
* ```html
* <igx-date-picker inputFormat="dd/MM/yy"></igx-date-picker>
* ```
*/
@Input()
public inputFormat: string;
public set inputFormat(value: string) {
if (value) {
this._userSetFormat = value;
this._inputFormat = DateTimeUtil.getNumericInputFormat(this.locale, value);
damyanpetev marked this conversation as resolved.
Show resolved Hide resolved
}
}

public get inputFormat(): string {
return this._inputFormat || this._defaultInputFormat;
}

/**
* The format used to display the picker's value when it's not being edited.
Expand Down Expand Up @@ -128,6 +138,9 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider
} catch (e) {
this._locale = this._localeId;
}
// reassign the inputFormat in case the original one needs to be localized
this.inputFormat = this._userSetFormat;
damyanpetev marked this conversation as resolved.
Show resolved Hide resolved
this.updateDefaultFormat();
}

/**
Expand Down Expand Up @@ -251,9 +264,12 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider

protected _locale: string;
protected _collapsed = true;
protected _defaultInputFormat: string;
protected _inputFormat: string;
protected _type: IgxInputGroupType;
protected _minValue: Date | string;
protected _maxValue: Date | string;
protected _userSetFormat: string;
protected _weekStart: WEEKDAYS | number;

/**
Expand Down Expand Up @@ -318,6 +334,10 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider
});
}

protected updateDefaultFormat(): void {
this._defaultInputFormat = DateTimeUtil.getDefaultInputFormat(this.locale, DataType.Date);
}

public abstract select(value: Date | DateRange | string): void;
public abstract open(settings?: OverlaySettings): void;
public abstract toggle(settings?: OverlaySettings): void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { DateTimeUtil } from './date-time.util';
import { DatePart, DatePartInfo } from '../../directives/date-time-editor/date-time-editor.common';
import { registerLocaleData } from '@angular/common';
import localeBg from '@angular/common/locales/bg';
import { DataType } from '../../data-operations/data-util';

const reduceToDictionary = (parts: DatePartInfo[]) => parts.reduce((obj, x) => {
obj[x.type] = x;
Expand Down Expand Up @@ -233,6 +236,30 @@ describe(`DateTimeUtil Unit tests`, () => {
expect(result).toEqual('MM/dd/yyyy');
});

it('should properly build input formats based on locale for dateTime data type ', () => {
spyOn(DateTimeUtil, 'getDefaultInputFormat').and.callThrough();
damyanpetev marked this conversation as resolved.
Show resolved Hide resolved
let result = DateTimeUtil.getDefaultInputFormat('en-US', DataType.DateTime);
expect(result).toEqual('MM/dd/yyyy, hh:mm:ss tt');

result = DateTimeUtil.getDefaultInputFormat('bg-BG', DataType.DateTime);
expect(result.normalize('NFKC')).toEqual('dd.MM.yyyy г., HH:mm:ss');

result = DateTimeUtil.getDefaultInputFormat('fr-FR', DataType.DateTime);
expect(result).toEqual('dd/MM/yyyy HH:mm:ss');
});

it('should properly build input formats based on locale for time data type ', () => {
spyOn(DateTimeUtil, 'getDefaultInputFormat').and.callThrough();
let result = DateTimeUtil.getDefaultInputFormat('en-US', DataType.Time);
expect(result).toEqual('hh:mm tt');

result = DateTimeUtil.getDefaultInputFormat('bg-BG', DataType.Time);
expect(result.normalize('NFKC')).toEqual('HH:mm');

result = DateTimeUtil.getDefaultInputFormat('fr-FR', DataType.Time);
expect(result).toEqual('HH:mm');
});

it('should correctly distinguish date from time characters', () => {
expect(DateTimeUtil.isDateOrTimeChar('d')).toBeTrue();
expect(DateTimeUtil.isDateOrTimeChar('M')).toBeTrue();
Expand Down Expand Up @@ -628,4 +655,60 @@ describe(`DateTimeUtil Unit tests`, () => {
expect(DateTimeUtil.isValidDate(false)).toBeFalse();
expect(DateTimeUtil.isValidDate(true)).toBeFalse();
});

it('should correctly identify formats that would resolve to only numeric parts (and period) for the date/time parts', () => {
// test with locale covering non-ASCII characters as well
registerLocaleData(localeBg, 'bg');
damyanpetev marked this conversation as resolved.
Show resolved Hide resolved
const locale = 'bg';

const numericFormats = ['y', 'yy', 'yyy', 'yyyy', 'M', 'MM', 'd', 'dd', 'h', 'hh',
'H', 'HH', 'm', 'mm', 's', 'ss', 'S', 'SS', 'SSS',
'dd-MM-yyyy', 'dd/M/yyyy HH:mm:ss tt', 'dd/M/yyyy HH:mm:ss:SS a',
// literals are allowed in the format
'dd/MM/yyyy test hh:mm'
];
numericFormats.forEach(format => {
expect(DateTimeUtil.isFormatNumeric(locale, format)).withContext(`Format: ${format}`).toBeTrue();
});

const nonNumericFormats = ['MMM', 'MMMM', 'MMMMM', 'medium', 'long', 'full', 'mediumDate',
'longDate', 'fullDate', 'longTime', 'fullTime', 'dd-MMM-yyyy', 'E', 'EE'];

nonNumericFormats.forEach(format => {
expect(DateTimeUtil.isFormatNumeric(locale, format)).withContext(`Format: ${format}`).toBeFalse();
});
});

it('getNumericInputFormat should return formats with date parts that the date-time editors can handle', () => {
let locale = 'en-US';

// returns the equivalent of the predefined numeric formats as date parts
// should be transformed as inputFormats for editing (numeric year, 2-digit parts for the rest)
expect(DateTimeUtil.getNumericInputFormat(locale, 'short')).toBe('MM/dd/yyyy, hh:mm tt');
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortDate')).toBe('MM/dd/yyyy');
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortTime').normalize('NFKD')).toBe('hh:mm tt');
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumTime').normalize('NFKD')).toBe('hh:mm:ss tt');

// handle the predefined formats for different locales
locale = 'bg-BG';
expect(DateTimeUtil.getNumericInputFormat(locale, 'short').normalize('NFKD')).toBe('dd.MM.yyyy г., HH:mm');
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortDate').normalize('NFKD')).toBe('dd.MM.yyyy г.');
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortTime').normalize('NFKD')).toBe('HH:mm');
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumTime').normalize('NFKD')).toBe('HH:mm:ss');

locale = 'ja-JP';
expect(DateTimeUtil.getNumericInputFormat(locale, 'short')).toBe('yyyy/MM/dd HH:mm');
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortDate')).toBe('yyyy/MM/dd');
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortTime').normalize('NFKD')).toBe('HH:mm');
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumTime').normalize('NFKD')).toBe('HH:mm:ss');

// returns the same format if it is custom and numeric
expect(DateTimeUtil.getNumericInputFormat(locale, 'dd-MM-yyyy')).toBe('dd-MM-yyyy');
expect(DateTimeUtil.getNumericInputFormat(locale, 'dd/M/yyyy hh:mm:ss:SS aa')).toBe('dd/M/yyyy hh:mm:ss:SS aa');

// returns empty string if predefined and not among the numeric ones
expect(DateTimeUtil.getNumericInputFormat(locale, 'medium')).toBe('');
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumDate')).toBe('');
expect(DateTimeUtil.getNumericInputFormat(locale, 'longTime')).toBe('');
});
});
Loading
Loading