Skip to content

Commit ee82480

Browse files
authored
Merge pull request #10638 from IgniteUI/13.0.x
Mass merge from 13.0.x to master
2 parents 02b0cb2 + 241667f commit ee82480

File tree

13 files changed

+799
-66
lines changed

13 files changed

+799
-66
lines changed

projects/igniteui-angular/src/lib/accordion/accordion.component.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,29 @@ describe('Rendering Tests', () => {
166166
expect(accordion.panelCollapsed.emit).toHaveBeenCalledTimes(5);
167167
}));
168168

169+
it(`Should collapse all expanded and not disabled panels except for the last one when setting singleBranchExpand to true`, () => {
170+
expect(accordion.panels[0].collapsed).toBeTrue();
171+
expect(accordion.panels[1].collapsed).toBeTrue();
172+
expect(accordion.panels[2].collapsed).toBeFalse();
173+
expect(accordion.panels[3].collapsed).toBeFalse();
174+
175+
accordion.panels[1].collapsed = false;
176+
fix.detectChanges();
177+
178+
expect(accordion.panels[0].collapsed).toBeTrue();
179+
expect(accordion.panels[1].collapsed).toBeFalse();
180+
expect(accordion.panels[2].collapsed).toBeFalse();
181+
expect(accordion.panels[3].collapsed).toBeFalse();
182+
183+
accordion.singleBranchExpand = true;
184+
fix.detectChanges();
185+
186+
expect(accordion.panels[0].collapsed).toBeTrue();
187+
expect(accordion.panels[1].collapsed).toBeTrue();
188+
expect(accordion.panels[2].collapsed).toBeFalse();
189+
expect(accordion.panels[3].collapsed).toBeFalse();
190+
});
191+
169192
it('Should emit ing and ed events when expand panel state is toggled', fakeAsync(() => {
170193
spyOn(accordion.panelExpanded, 'emit').and.callThrough();
171194
spyOn(accordion.panelExpanding, 'emit').and.callThrough();

projects/igniteui-angular/src/lib/accordion/accordion.component.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AfterContentInit, AfterViewInit, Component, ContentChildren, EventEmitter,
1+
import { AfterContentInit, AfterViewInit, ChangeDetectorRef, Component, ContentChildren, EventEmitter,
22
HostBinding, Input, OnDestroy, Output, QueryList } from '@angular/core';
33
import { fromEvent, Subject } from 'rxjs';
44
import { takeUntil } from 'rxjs/operators';
@@ -113,7 +113,16 @@ export class IgxAccordionComponent implements AfterContentInit, AfterViewInit, O
113113
* ```
114114
*/
115115
@Input()
116-
public singleBranchExpand = false;
116+
public get singleBranchExpand(): boolean {
117+
return this._singleBranchExpand;
118+
}
119+
120+
public set singleBranchExpand(val: boolean) {
121+
this._singleBranchExpand = val;
122+
if (val) {
123+
this.collapseAllExceptLast();
124+
}
125+
}
117126

118127
/**
119128
* Emitted before a panel is expanded.
@@ -200,12 +209,16 @@ export class IgxAccordionComponent implements AfterContentInit, AfterViewInit, O
200209
private _destroy$ = new Subject<void>();
201210
private _unsubChildren$ = new Subject<void>();
202211
private _enabledPanels!: IgxExpansionPanelComponent[];
212+
private _singleBranchExpand = false;
203213

204-
constructor() { }
214+
constructor(private cdr: ChangeDetectorRef) { }
205215

206216
/** @hidden @internal **/
207217
public ngAfterContentInit(): void {
208218
this.updatePanelsAnimation();
219+
if (this.singleBranchExpand) {
220+
this.collapseAllExceptLast();
221+
}
209222
}
210223

211224
/** @hidden @internal **/
@@ -256,6 +269,16 @@ export class IgxAccordionComponent implements AfterContentInit, AfterViewInit, O
256269
this.panels.forEach(panel => panel.collapse());
257270
}
258271

272+
private collapseAllExceptLast(): void {
273+
const lastExpanded = this.panels?.filter(p => !p.collapsed && !p.header.disabled).pop();
274+
this.panels?.forEach((p: IgxExpansionPanelComponent) => {
275+
if (p !== lastExpanded && !p.header.disabled) {
276+
p.collapsed = true;
277+
}
278+
});
279+
this.cdr.detectChanges();
280+
}
281+
259282
private handleKeydown(event: KeyboardEvent, panel: IgxExpansionPanelComponent): void {
260283
const key = event.key.toLowerCase();
261284
if (!(ACCORDION_NAVIGATION_KEYS.has(key))) {

projects/igniteui-angular/src/lib/combo/combo.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ describe('igxCombo', () => {
9595
get: mockNgControl
9696
});
9797
mockSelection.get.and.returnValue(new Set([]));
98-
const mockIconService = new IgxIconService(null, null, null);
98+
const mockIconService = new IgxIconService(null, null, null, null);
9999
it('should correctly implement interface methods - ControlValueAccessor ', () => {
100100
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
101101
mockIconService, null, null, mockInjector);

projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,7 @@
11171117
z-index: 10000;
11181118

11191119
%igx-grid__hierarchical-expander--empty {
1120-
border-#{$right}: 1px solid transparent;
1120+
border-#{$right}: rem(1px) solid var-get($theme, 'header-border-color');
11211121
}
11221122
}
11231123

projects/igniteui-angular/src/lib/grids/filtering/base/grid-filtering-row.component.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy {
7272
this.expression.searchVal = null;
7373
const index = this.expressionsList.findIndex(item => item.expression === this.expression);
7474
if (index === 0 && this.expressionsList.length === 1) {
75-
this.clearFiltering();
75+
this.filteringService.clearFilter(this.column.field);
76+
77+
if (this.expression.condition.isUnary) {
78+
this.resetExpression();
79+
}
80+
7681
return;
7782
}
7883
} else {

projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,6 +2064,33 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => {
20642064
expect(grid.filteredData).toBeNull();
20652065
}));
20662066

2067+
it('should not reset expression when input is cleared', fakeAsync(() => {
2068+
grid.filter('ProductName', 'I', IgxStringFilteringOperand.instance().condition('startsWith'));
2069+
fix.detectChanges();
2070+
2071+
GridFunctions.clickFilterCellChip(fix, 'ProductName');
2072+
2073+
grid.filteringRow.onClearClick();
2074+
tick(100);
2075+
fix.detectChanges();
2076+
2077+
expect(grid.filteringRow.expression.condition.name).toEqual('startsWith');
2078+
}));
2079+
2080+
it('should reset expression when the condition is unary', fakeAsync(() => {
2081+
GridFunctions.clickFilterCellChip(fix, 'ProductName');
2082+
2083+
// iterate over unary conditions
2084+
// empty
2085+
GridFunctions.openFilterDDAndSelectCondition(fix, 6);
2086+
2087+
grid.filteringRow.onClearClick();
2088+
tick(100);
2089+
fix.detectChanges();
2090+
2091+
expect(grid.filteringRow.expression.condition.name).toEqual('contains');
2092+
}));
2093+
20672094
it('Should filter by cells formatted data when using FormattedValuesFilteringStrategy', fakeAsync(() => {
20682095
const formattedStrategy = new FormattedValuesFilteringStrategy(['Downloads']);
20692096
grid.filterStrategy = formattedStrategy;
@@ -6640,8 +6667,6 @@ const emitFilteringDoneOnInputClear = (fix, grid, filterVal, columnName, conditi
66406667

66416668
GridFunctions.clickFilterCellChip(fix, columnName);
66426669

6643-
// spyOn(grid.filteringDone, 'emit');
6644-
66456670
grid.filteringRow.onClearClick();
66466671
tick(100);
66476672
fix.detectChanges();

projects/igniteui-angular/src/lib/icon/icon.service.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
33
import { DOCUMENT } from '@angular/common';
44
import { HttpClient } from '@angular/common/http';
55
import { Observable, Subject } from 'rxjs';
6+
import { PlatformUtil } from '../core/utils';
67

78
/**
89
* Event emitted when a SVG icon is loaded through
@@ -48,14 +49,19 @@ export class IgxIconService {
4849
private _familyAliases = new Map<string, string>();
4950
private _cachedSvgIcons = new Map<string, Map<string, SafeHtml>>();
5051
private _iconLoaded = new Subject<IgxIconLoadedEvent>();
51-
private _domParser = new DOMParser();
52+
private _domParser: DOMParser;
5253

5354
constructor(
5455
@Optional() private _sanitizer: DomSanitizer,
5556
@Optional() private _httpClient: HttpClient,
56-
@Optional() @Inject(DOCUMENT) private _document: any
57+
@Optional() private _platformUtil: PlatformUtil,
58+
@Optional() @Inject(DOCUMENT) private _document: any,
5759
) {
5860
this.iconLoaded = this._iconLoaded.asObservable();
61+
62+
if(this._platformUtil?.isBrowser) {
63+
this._domParser = new DOMParser();
64+
}
5965
}
6066

6167
/**
@@ -188,7 +194,7 @@ export class IgxIconService {
188194
private cacheSvgIcon(name: string, value: string, family = this._family, stripMeta: boolean) {
189195
family = !!family ? family : this._family;
190196

191-
if (name && value) {
197+
if (this._platformUtil?.isBrowser && name && value) {
192198
const doc = this._domParser.parseFromString(value, 'image/svg+xml');
193199
const svg = doc.querySelector('svg') as SVGElement;
194200

0 commit comments

Comments
 (0)