Skip to content

Commit 8abc808

Browse files
authored
Merge branch 'master' into mkirova/fix-7257
2 parents 34f1929 + 49489a0 commit 8abc808

File tree

16 files changed

+196
-19
lines changed

16 files changed

+196
-19
lines changed

.github/workflows/stale.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Mark stale issues and pull requests
2+
3+
on:
4+
schedule:
5+
- cron: "0 0 * * *"
6+
7+
jobs:
8+
stale:
9+
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- uses: actions/stale@v1
14+
with:
15+
repo-token: ${{ secrets.GITHUB_TOKEN }}
16+
stale-issue-message: 'There has been no recent activity and this issue has been marked inactive.'
17+
stale-pr-message: 'There has been no recent activity and this PR has been marked inactive.'
18+
stale-issue-label: 'status: inactive'
19+
stale-pr-label: 'status: inactive'

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ All notable changes for each version of this project will be documented in this
162162
- Added `tabIndex` input so it can support change detection as well.
163163

164164

165+
- `IgxHighlightDirective`
166+
- New `metadata` property was introduced, which allows adding additional, custom logic to the activation condition of a highlighted element.
167+
165168
### RTL Support
166169
- `igxSlider` have full right-to-left (RTL) support.
167170

projects/igniteui-angular/src/lib/core/utils.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,31 @@ export function resizeObservable(target: HTMLElement): Observable<ResizeObserver
355355
return unsubscribe;
356356
});
357357
}
358+
359+
/**
360+
* @hidden
361+
* @internal
362+
*
363+
* Compares two maps.
364+
*/
365+
export function compareMaps(map1: Map<any, any>, map2: Map<any, any>): boolean {
366+
if (!map2) {
367+
return !map1 ? true : false;
368+
}
369+
if (map1.size !== map2.size) {
370+
return false;
371+
}
372+
let match = true;
373+
const keys = Array.from(map2.keys());
374+
for (const key of keys) {
375+
if (map1.has(key)) {
376+
match = map1.get(key) === map2.get(key);
377+
} else {
378+
match = false;
379+
}
380+
if (!match) {
381+
break;
382+
}
383+
}
384+
return match;
385+
}

projects/igniteui-angular/src/lib/date-range-picker/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,15 @@ With projected inputs:
108108
### Inputs
109109
| Name | Type | Description |
110110
|:-----------------|:-------------------|:------------|
111-
| mode | InteractionMode | Sets whether `IgxDateRangePickerComponent` is in dialog or dropdown mode. Default is `dialog` |
112-
| monthsViewNumber | number | Sets the number displayed month views. Default is `2`. |
111+
| doneButtonText | string | Changes the default text of the `done` button. It will show up only in `dialog` mode. Default value is `Done`. |
112+
| formatter | function => string | Applies a custom formatter function on the selected or passed date. |
113113
| hideOutsideDays | boolean | Sets whether dates that are not part of the current month will be displayed. Default value is `false`. |
114-
| weekStart | number | Sets the start day of the week. Can be assigned to a numeric value or to `WEEKDAYS` enum value. |
115114
| locale | string | Gets the `locale` of the calendar. Default value is `"en"`. |
116-
| formatter | function => string | Applies a custom formatter function on the selected or passed date. |
117-
| doneButtonText | string | Changes the default text of the `done` button. It will show up only in `dialog` mode. Default value is `Done`. |
118115
| overlaySettings | OverlaySettings | Changes the default overlay settings used by the `IgxDateRangePickerComponent`. |
116+
| mode | InteractionMode | Sets whether `IgxDateRangePickerComponent` is in dialog or dropdown mode. Default is `dialog` |
117+
| monthsViewNumber | number | Sets the number displayed month views. Default is `2`. |
118+
| placeholder | string | Sets the `placeholder` for single-input `IgxDateRangePickerComponent`. |
119+
| weekStart | number | Sets the start day of the week. Can be assigned to a numeric value or to `WEEKDAYS` enum value. |
119120

120121
### Outputs
121122
| Name | Type | Description |

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,15 @@ describe('IgxDateRangePicker', () => {
262262
});
263263

264264
describe('Properties & events tests', () => {
265+
it('should show date picker with placeholder', () => {
266+
fixture.detectChanges();
267+
expect(singleInputElement.nativeElement.placeholder).toEqual('MM/dd/yyyy - MM/dd/yyyy');
268+
269+
const placeholder = 'Some placeholder';
270+
fixture.componentInstance.dateRange.placeholder = placeholder;
271+
fixture.detectChanges();
272+
expect(singleInputElement.nativeElement.placeholder).toEqual(placeholder);
273+
});
265274
it('should close the calendar with the "Done" button', fakeAsync(() => {
266275
fixture.componentInstance.mode = InteractionMode.Dialog;
267276
fixture.detectChanges();
@@ -809,4 +818,7 @@ export class DateRangeDefaultCustomLabelComponent extends DateRangeTestComponent
809818
</igx-date-range-picker>
810819
`
811820
})
812-
export class DateRangeDefaultComponent extends DateRangeTestComponent { }
821+
export class DateRangeDefaultComponent extends DateRangeTestComponent {
822+
@ViewChild(IgxDateRangePickerComponent)
823+
public dateRange: IgxDateRangePickerComponent;
824+
}

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
270270
@Input()
271271
public disabled: boolean;
272272

273+
/**
274+
* Sets the `placeholder` for single-input `IgxDateRangePickerComponent`.
275+
* @example
276+
* ```html
277+
* <igx-date-range-picker [placeholder]="'Choose your dates'"></igx-date-range-picker>
278+
* ```
279+
*/
280+
@Input()
281+
public placeholder = '';
282+
273283
/**
274284
* Emitted when a range is selected.
275285
*
@@ -369,6 +379,9 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
369379
return this.formatter(this.value);
370380
}
371381
if (!this.hasProjectedInputs) {
382+
if (this.placeholder !== '') {
383+
return this.placeholder;
384+
}
372385
// TODO: use displayFormat - see how shortDate, longDate can be defined
373386
return this.inputFormat
374387
? `${this.inputFormat} - ${this.inputFormat}`

projects/igniteui-angular/src/lib/directives/text-highlight/text-highlight.directive.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { takeUntil } from 'rxjs/operators';
1515
import { Subject } from 'rxjs';
1616
import { DeprecateProperty } from '../../core/deprecateDecorators';
17+
import { compareMaps } from '../../core/utils';
1718

1819
interface ISearchInfo {
1920
searchedText: string;
@@ -39,6 +40,10 @@ export interface IActiveHighlightInfo {
3940
* The index of the highlight.
4041
*/
4142
index: number;
43+
/**
44+
* Additional, custom checks to perform prior an element highlighting.
45+
*/
46+
metadata?: Map<string, any>;
4247
}
4348

4449
@Directive({
@@ -163,6 +168,27 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke
163168
@Input('column')
164169
public column: any;
165170

171+
/**
172+
* A map that contains all aditional conditions, that you need to activate a highlighted
173+
* element. To activate the condition, you will have to add a new metadata key to
174+
* the `metadata` property of the IActiveHighlightInfo interface.
175+
*
176+
* @example
177+
* ```typescript
178+
* // Set a property, which would disable the highlight for a given element on a cetain condition
179+
* const metadata = new Map<string, any>();
180+
* metadata.set('highlightElement', false);
181+
* ```
182+
* ```html
183+
* <div
184+
* igxTextHighlight
185+
* [metadata]="metadata">
186+
* </div>
187+
* ```
188+
*/
189+
@Input()
190+
public metadata: Map<string, any>;
191+
166192
/**
167193
* @hidden
168194
*/
@@ -317,7 +343,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke
317343
public activateIfNecessary(): void {
318344
const group = IgxTextHighlightDirective.highlightGroupsMap.get(this.groupName);
319345

320-
if (group.column === this.column && group.row === this.row) {
346+
if (group.column === this.column && group.row === this.row && compareMaps(this.metadata, group.metadata)) {
321347
this.activate(group.index);
322348
}
323349
}

projects/igniteui-angular/src/lib/grids/cell.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<ng-template #defaultCell>
55
<div igxTextHighlight style="pointer-events: none" [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
66
[value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value"
7-
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'"
7+
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata"
88
class="igx-grid__td-text">{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal:
99
grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }}</div>
1010
</ng-template>

projects/igniteui-angular/src/lib/grids/cell.component.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,4 +899,14 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
899899
return Math.max(...Array.from(this.nativeElement.children)
900900
.map((child) => getNodeSizeViaRange(range, child)));
901901
}
902+
903+
/**
904+
* @hidden
905+
* @internal
906+
*/
907+
public get searchMetadata() {
908+
const meta = new Map<string, any>();
909+
meta.set('pinned', this.grid.isRecordPinnedByViewIndex(this.row.index));
910+
return meta;
911+
}
902912
}

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ import {
3030
import ResizeObserver from 'resize-observer-polyfill';
3131
import { Subject, pipe } from 'rxjs';
3232
import { takeUntil, first, filter, throttleTime, map } from 'rxjs/operators';
33-
import { cloneArray, flatten, mergeObjects, isIE } from '../core/utils';
33+
import { cloneArray, flatten, mergeObjects, isIE, compareMaps } from '../core/utils';
3434
import { DataType } from '../data-operations/data-util';
3535
import { FilteringLogic, IFilteringExpression } from '../data-operations/filtering-expression.interface';
3636
import { IGroupByRecord } from '../data-operations/groupby-record.interface';
3737
import { ISortingExpression } from '../data-operations/sorting-expression.interface';
3838
import { IForOfState, IgxGridForOfDirective } from '../directives/for-of/for_of.directive';
39-
import { IgxTextHighlightDirective } from '../directives/text-highlight/text-highlight.directive';
39+
import { IgxTextHighlightDirective, IActiveHighlightInfo } from '../directives/text-highlight/text-highlight.directive';
4040
import {
4141
AbsoluteScrollStrategy,
4242
HorizontalAlignment,
@@ -2723,14 +2723,31 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
27232723
}
27242724

27252725
/**
2726+
* Returns whether the record is pinned or not.
2727+
*
2728+
* @param rowIndex Index of the record in the `dataView` collection.
2729+
*
27262730
* @hidden
27272731
* @internal
27282732
*/
2729-
public isRecordPinnedByIndex(rowIndex: number) {
2733+
public isRecordPinnedByViewIndex(rowIndex: number) {
27302734
return this.hasPinnedRecords && (this.isRowPinningToTop && rowIndex < this.pinnedDataView.length) ||
27312735
(!this.isRowPinningToTop && rowIndex >= this.unpinnedDataView.length);
27322736
}
27332737

2738+
/**
2739+
* Returns whether the record is pinned or not.
2740+
*
2741+
* @param rowIndex Index of the record in the `filteredSortedData` collection.
2742+
*
2743+
* @hidden
2744+
* @internal
2745+
*/
2746+
public isRecordPinnedByIndex(rowIndex: number) {
2747+
return this.hasPinnedRecords && (this.isRowPinningToTop && rowIndex < this._filteredSortedPinnedData.length) ||
2748+
(!this.isRowPinningToTop && rowIndex >= this._filteredSortedUnpinnedData.length);
2749+
}
2750+
27342751
/**
27352752
* @hidden
27362753
* @internal
@@ -4336,7 +4353,8 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
43364353
this.lastSearchInfo.matchInfoCache.forEach((match, i) => {
43374354
if (match.column === activeInfo.column &&
43384355
match.row === activeInfo.row &&
4339-
match.index === activeInfo.index) {
4356+
match.index === activeInfo.index &&
4357+
compareMaps(match.metadata, activeInfo.metadata)) {
43404358
this.lastSearchInfo.activeMatchIndex = i;
43414359
}
43424360
});
@@ -5858,6 +5876,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
58585876
column: matchInfo.column,
58595877
row: matchInfo.row,
58605878
index: matchInfo.index,
5879+
metadata: matchInfo.metadata,
58615880
});
58625881

58635882
} else {
@@ -5996,7 +6015,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
59966015

59976016
const numberPipe = new IgxDecimalPipeComponent(this.locale);
59986017
const datePipe = new IgxDatePipeComponent(this.locale);
5999-
data.forEach((dataRow) => {
6018+
data.forEach((dataRow, rowIndex) => {
60006019
columnItems.forEach((c) => {
60016020
const value = c.formatter ? c.formatter(dataRow[c.field]) :
60026021
c.dataType === 'number' ? numberPipe.transform(dataRow[c.field], this.locale) :
@@ -6007,21 +6026,27 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
60076026

60086027
if (exactMatch) {
60096028
if (searchValue === searchText) {
6029+
const metadata = new Map<string, any>();
6030+
metadata.set('pinned', this.isRecordPinnedByIndex(rowIndex));
60106031
this.lastSearchInfo.matchInfoCache.push({
60116032
row: dataRow,
60126033
column: c.field,
60136034
index: 0,
6035+
metadata: metadata,
60146036
});
60156037
}
60166038
} else {
60176039
let occurenceIndex = 0;
60186040
let searchIndex = searchValue.indexOf(searchText);
60196041

60206042
while (searchIndex !== -1) {
6043+
const metadata = new Map<string, any>();
6044+
metadata.set('pinned', this.isRecordPinnedByIndex(rowIndex));
60216045
this.lastSearchInfo.matchInfoCache.push({
60226046
row: dataRow,
60236047
column: c.field,
60246048
index: occurenceIndex++,
6049+
metadata: metadata,
60256050
});
60266051

60276052
searchValue = searchValue.substring(searchIndex + searchText.length);

0 commit comments

Comments
 (0)