Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -1,6 +1,20 @@
# v15.2.2 (2024-02-16)
* **grid** display margin shadow if scrollable
* **suggest** change default forceDisplayDropdownOverInput
* **grid** update filter options on lang change

# v15.2.1 (2024-02-16)
* **tree-select** add accessible props

# v15.2.0 (2024-07-02)
* **grid** add tests for high density mode
* **grid** add support for high density mode
* **grid** add tests for high density mode
* **grid** add support for high density mode

# v15.1.7 (2024-07-02)
* **grid** add nullish for set items

# v15.1.6 (2024-07-02)
* **grid** react on max filters count changes

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-components",
"version": "15.2.1",
"version": "15.2.2",
"author": {
"name": "UiPath Inc",
"url": "https://uipath.com"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ $ui-grid-header-pressed-color: var(--color-data-grid-pressed, #EAECED);
$header-background-color: var(--color-background-secondary, #f4f5f7);
$grid-actions-box-shadow: var(--color-background, #ffffff);
$highlighted-entity-color: var(--color-primary, #0067df);
$scroll-margin-shadow-color: var(--color-background-inverse, #182027);
12 changes: 12 additions & 0 deletions projects/angular/components/ui-grid/src/_ui-grid.theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,18 @@ $ui-grid-opacity-transition: opacity $ui-grid-default-transition;
background-color: $ui-grid-row-hover-color;
}
}

.grid-margin-shadow {
position: sticky;
right: 0;
height: 100%;

@if $is-dark {
box-shadow: -7px 20px 20px 4px #000000;
} @else {
box-shadow: -3px 5px 20px 1.6px $scroll-margin-shadow-color;
}
}
}

.ui-grid-sort-icon {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import {
isArray, isEqual,
isArray,
isEqual,
} from 'lodash-es';
import { BehaviorSubject } from 'rxjs';
import {
BehaviorSubject,
Subject,
takeUntil,
} from 'rxjs';

import {
Directive,
inject,
Input,
OnDestroy,
OnInit,
} from '@angular/core';
import { ISuggestValueData } from '@uipath/angular/components/ui-suggest';

import { UiGridIntl } from '../ui-grid.intl';
import { UiGridFilterDirective } from './ui-grid-filter';

/**
Expand Down Expand Up @@ -46,7 +54,7 @@ export type ISuggestDropdownValueData = ISuggestValueData<IDropdownOption['value
@Directive({
selector: '[uiGridDropdownFilter], ui-grid-dropdown-filter',
})
export class UiGridDropdownFilterDirective<T> extends UiGridFilterDirective<T> implements OnDestroy {
export class UiGridDropdownFilterDirective<T> extends UiGridFilterDirective<T> implements OnDestroy, OnInit {
/**
* The dropdown items.
*
Expand All @@ -56,9 +64,10 @@ export class UiGridDropdownFilterDirective<T> extends UiGridFilterDirective<T> i
this._items = value ?? [];
this.suggestItems = this._items.map((item, idx) => ({
id: idx + 1,
text: item.label,
text: this.intl.translateDropdownOption(item),
data: item.value,
}));
this._addNoFilterOption();
}
get items() { return this._items!; }

Expand Down Expand Up @@ -112,6 +121,7 @@ export class UiGridDropdownFilterDirective<T> extends UiGridFilterDirective<T> i
* @ignore
*/
visible$ = new BehaviorSubject(true);
intl = inject(UiGridIntl, { optional: true }) ?? new UiGridIntl();
suggestValue: ISuggestDropdownValueData[] = [];

/**
Expand All @@ -122,6 +132,21 @@ export class UiGridDropdownFilterDirective<T> extends UiGridFilterDirective<T> i
private _items: IDropdownOption[] = [];
private _value: FilterDropdownPossibleOption;
private _multi = false;
private _destroy$ = new Subject<void>();

ngOnInit() {
this._addNoFilterOption();

this.intl.changes.pipe(
takeUntil(this._destroy$),
).subscribe(() => {
this.items = this._items;
this.suggestValue = this.suggestValue.map(suggestValue => ({
...suggestValue,
text: this.intl.translateDropdownOption(this.findDropDownOptionBySuggestValue(suggestValue)!),
}));
});
}

/**
* Updates the dropdown value.
Expand Down Expand Up @@ -152,6 +177,8 @@ export class UiGridDropdownFilterDirective<T> extends UiGridFilterDirective<T> i
ngOnDestroy() {
super.ngOnDestroy();
this.filterChange.complete();
this._destroy$.complete();
this._destroy$.next();
}

findDropDownOptionBySuggestValue(suggestValue: ISuggestDropdownValueData) {
Expand All @@ -162,4 +189,18 @@ export class UiGridDropdownFilterDirective<T> extends UiGridFilterDirective<T> i
return this.value != null && ((!isArray(this.value) && this.value?.value !== undefined) ||
(isArray(this.value) && this.value.length));
}

private _addNoFilterOption() {
const allOption = {
id: -1,
text: this.intl.noFilterPlaceholder,
};
if (!this.multi && this.showAllOption) {
if (this.suggestItems[0]?.id !== allOption.id) {
this.suggestItems = [allOption, ...this.suggestItems];
}
} else {
this.suggestItems = this.suggestItems.filter(item => item.id !== allOption.id);
}
}
}
6 changes: 5 additions & 1 deletion projects/angular/components/ui-grid/src/test/column.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TestBed } from '@angular/core/testing';
import * as faker from 'faker';
import { of } from 'rxjs';

Expand All @@ -20,7 +21,10 @@ export const generateColumn = () => {
};

export const generateDropdownFilter = () => {
const dropdown = new UiGridDropdownFilterDirective<ITestEntity>();
let dropdown!: UiGridDropdownFilterDirective<ITestEntity>;
TestBed.runInInjectionContext(() => {
dropdown = new UiGridDropdownFilterDirective<ITestEntity>();
});

const items = faker.random.words(15)
.split(' ')
Expand Down
14 changes: 9 additions & 5 deletions projects/angular/components/ui-grid/src/ui-grid.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@
class="ui-grid-header-cell ui-grid-scroll-size-compensation-cell ui-grid-feature-cell">
</div>
<div *ngIf="refreshable"
[class.refresh-shadow]="shouldDisplayContainerShadow$ | async"
class="ui-grid-header-cell ui-grid-refresh-cell ui-grid-feature-cell"
role="columnheader">
<button [matTooltip]="intl.refreshTooltip"
Expand Down Expand Up @@ -565,9 +566,13 @@
class="ui-grid-cell ui-grid-refresh-cell ui-grid-feature-cell">
</div>

<div *ngIf="!actions && (shouldDisplayContainerShadow$ | async)"
class="grid-margin-shadow ui-grid-feature-cell"></div>

<div *ngIf="!isProjected &&
!!actions"
[class.ui-grid-sticky-element]="isScrollable"
[class.grid-margin-shadow]="shouldDisplayContainerShadow$ | async"
role="gridcell"
class="ui-grid-cell ui-grid-action-cell ui-grid-feature-cell">
<div [class.sticky-grid-action-cell-container]="isScrollable"
Expand Down Expand Up @@ -749,7 +754,7 @@
[searchable]="false"
[value]="suggestValue"
[placeholder]="column.title ?? ''"
[items]="mapFilterOptions(column.dropdown!.suggestItems, column)"
[items]="column.dropdown!.suggestItems"
[compactSummaryTemplate]="displayedFilterName"
[maxSelectionConfig]="{
count: (disableFilterSelection$ | async) && (column.dropdown!.multi || selectedFilters === undefined) ? suggestValue.length : Infinity,
Expand All @@ -768,10 +773,9 @@
<div class="flex">
<span class="text-ellipsis">
{{ (column.dropdown!.multi && selectedFilters?.length > 1)
? intl.translateMultiDropdownOptions(value?.[0]?.text, selectedFilters.length)
: value?.[0]
? intl.translateDropdownOption(column.dropdown!.findDropDownOptionBySuggestValue(value[0])!)
: intl.noFilterPlaceholder }}</span>
? intl.translateMultiDropdownOptions(value[0].text!, selectedFilters.length)
: value?.[0]?.text ?? intl.noFilterPlaceholder
}}</span>
</div>
</ng-template>
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,10 @@ ui-grid {
&.ui-grid-refresh-cell {
position: sticky;
right: 0;

&.refresh-shadow {
box-shadow: -16px 0px 16px -4px $ui-grid-row-hover-color;
}
}

&.ui-grid-action-cell {
Expand Down
43 changes: 40 additions & 3 deletions projects/angular/components/ui-grid/src/ui-grid.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1488,14 +1488,21 @@ describe('Component: UiGrid', () => {
let fixture: ComponentFixture<TestFixtureGridHeaderWithFilterComponent>;
let component: TestFixtureGridHeaderWithFilterComponent;
let grid: UiGridComponent<ITestEntity>;

let intl: UiGridIntl;
beforeEach(() => {
intl = new UiGridIntl();
TestBed.configureTestingModule({
imports: [
UiGridModule,
NoopAnimationsModule,
],
declarations: [TestFixtureGridHeaderWithFilterComponent],
providers: [
{
provide: UiGridIntl,
useValue: intl,
},
],
});

fixture = TestBed.createComponent(TestFixtureGridHeaderWithFilterComponent);
Expand All @@ -1521,6 +1528,28 @@ describe('Component: UiGrid', () => {
fixture.detectChanges();
});

it('should update translation for filter options when language changes', fakeAsync(() => {
intl.translateDropdownOption = () => 'voila la traduction';
intl.changes.next();
fixture.detectChanges();

const filterContainer = fixture.debugElement.query(By.css('.ui-grid-dropdown-filter-container'));
const filterButton = filterContainer.query(By.css(selectors.filterDropdown));
filterButton.nativeElement.dispatchEvent(EventGenerator.click);
fixture.detectChanges();
tick(1000);
fixture.detectChanges();

const filterCheckboxes = fixture.debugElement.queryAll(By.css('mat-list-item mat-checkbox'));
filterCheckboxes[0].nativeElement.dispatchEvent(EventGenerator.click);
filterCheckboxes[1].nativeElement.dispatchEvent(EventGenerator.click);
fixture.detectChanges();

const filterSpan = fixture.debugElement.query(By.css('.ui-grid-filter-suggest span.text-ellipsis'));
expect(filterSpan.nativeElement.innerText).toEqual('voila la traduction (+1 other)');
flush();
}));

it('should emit all selected filter options', fakeAsync(() => {
const filterContainer = fixture.debugElement.query(By.css('.ui-grid-dropdown-filter-container'));
const filterButton = filterContainer.query(By.css(selectors.filterDropdown));
Expand Down Expand Up @@ -4827,6 +4856,13 @@ describe('Component: UiGrid', () => {
expect(gridTable.nativeElement.style.minWidth).toBe(columnWidthSum + 'px');
}));

it('should display margin shadow when the grid has horizontal scroll', fakeAsync(() => {
const widths = [250, 1000, 330, 400, 100, 100]; // large enough too cause overflow
beforeConfig({ widths });
const tableMarginShadowDivs = fixture.debugElement.queryAll(By.css('.grid-margin-shadow'));
expect(tableMarginShadowDivs.length).toBe(widths.length);
}));

it('should increase the width of last column if default column width sum does not fill the table', fakeAsync(() => {
const widths = [50, 50, 0, 50, 50, 50];
const lastColumnIdx = 4; // refresh btn & 1 missing column
Expand Down Expand Up @@ -4999,13 +5035,13 @@ describe('Component: UiGrid', () => {
expect(+newMinWidth.replace('px', '')).toBeLessThan(+startingMinWidth.replace('px', ''));
}));

it(`should set overflow to visible if total width of columns does not exceed container width`, fakeAsync(() => {
it(`should set overflow to visible and hide margin shadow if total width of columns does not exceed container width`, fakeAsync(() => {
const gridTable = fixture.debugElement.query(By.css('.ui-grid-table'));
const options = fixture.debugElement
.queryAll(By.css('.ui-grid-toggle-panel .mat-mdc-option:not(.mdc-list-item--disabled)'));

expect(gridTable.styles.overflow).toEqual('visible');

expect(fixture.debugElement.queryAll(By.css('.grid-margin-shadow')).length).toBe(6);
options.forEach(o => {
const checkbox = o.query(By.css('.mat-pseudo-checkbox'));
checkbox.nativeElement.dispatchEvent(EventGenerator.click);
Expand All @@ -5015,6 +5051,7 @@ describe('Component: UiGrid', () => {
fixture.detectChanges();

expect(gridTable.styles.overflow).toEqual('hidden');
expect(fixture.debugElement.queryAll(By.css('.grid-margin-shadow')).length).toBe(0);
}));
});

Expand Down
Loading