mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-16968] Add boolean type (#8972)
* [AAE-16968] Update variable mapper service * Update DetaColumnComponent * [AAE-16968] Update DataColumnTypes interface * [AAE-16968] Handle boolean column on UI * [AAE-16968] Create BooleanCellComponent * [AAE-16968] Delete comment * [AAE-16968] Update BooleanCellComponent * [AAE-16968] Delete unnecessary css classes * [AAE-16968] Allow for string values * [AAE-16968] Update test for datatable * [AAE-16968] Update tests for boolean cell * [AAE-16968] Update tests for VariableMapperService * [AAE-16968] Add boolean pipe * [AAE-16968] Update pipe * [AAE-16968] Update code formatting * [AAE-16968] Add doc for the boolean pipe * [AAE-16968] Update DataColumnComponent doc * [AAE-16968] Delete unnecessary class * [AAE-16968] Fix title bug * [AAE-16968] Update BooleanCell tests * [AAE-16968] Update Boolean pipe * [AAE-16968] Update tests for variable mapper service * [AAE-16968] Update PipesModule * [AAE-16968] Small fix * [AAE-16968] Fix lint error
This commit is contained in:
committed by
GitHub
parent
cda12730f6
commit
b49c86fda5
@@ -59,9 +59,25 @@ Defines column properties for DataTable, Tasklist, Document List and other compo
|
|||||||
| sortingKey | `string` | | When using server side sorting the column used by the api call where the sorting will be performed |
|
| sortingKey | `string` | | When using server side sorting the column used by the api call where the sorting will be performed |
|
||||||
| srTitle | `string` | | Title to be used for screen readers. |
|
| srTitle | `string` | | Title to be used for screen readers. |
|
||||||
| title | `string` | "" | Display title of the column, typically used for column headers. You can use the i18n resource key to get it translated automatically. |
|
| title | `string` | "" | Display title of the column, typically used for column headers. You can use the i18n resource key to get it translated automatically. |
|
||||||
| type | `string` | "text" | Value type for the column. Possible settings are 'text', 'image', 'date', 'fileSize', 'location', and 'json'. |
|
| type | `string` | "text" | Value type for the column. Possible settings are 'text', 'boolean', 'icon', 'image', 'date', 'fileSize', 'location', and 'json'. |
|
||||||
| order | `number` | | Sets position of column. |
|
| order | `number` | | Sets position of column. |
|
||||||
|
|
||||||
|
## Properties configuration
|
||||||
|
|
||||||
|
### `type` Input
|
||||||
|
|
||||||
|
The `type` input allows us to specify the type of hosted values for a given column. The complete array of possible values is outlined below:
|
||||||
|
|
||||||
|
- `text` - The given values are represented as a strings (default option).
|
||||||
|
- `boolean` - The column expects true / false (boolean values) and in addition accepts two strings - 'false' and 'true'. Other values are not recognized by the column, and the cell remains empty.
|
||||||
|
- `icon` - TODO
|
||||||
|
- `image` - TODO
|
||||||
|
- `date` - TODO
|
||||||
|
- `fileSize` - TODO
|
||||||
|
- `location` - TODO
|
||||||
|
- `json` - TODO
|
||||||
|
- `currency` - This column is responsible for displaying currencies. It expects numerals represented by a string or a number. This type comes with `currencyConfig` (TODO: Add ref). The default setup use **USD** `code` with a **symbol** as a `display` option. Example output: $10.26 (for number 10.26)
|
||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
### Conditional visibility
|
### Conditional visibility
|
||||||
|
26
docs/core/pipes/boolean.pipe.md
Normal file
26
docs/core/pipes/boolean.pipe.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
Title: Boolean pipe
|
||||||
|
Added: v6.4.0
|
||||||
|
Status: Active
|
||||||
|
Last reviewed: 2023-10-12
|
||||||
|
---
|
||||||
|
|
||||||
|
# [Boolean pipe](../../../lib/core/src/lib/pipes/boolean.pipe.ts "Defined in boolean.pipe.ts")
|
||||||
|
|
||||||
|
Converts the received values to one of the possible strings: 'true', 'false' or ""(empty string).
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
<!-- {% raw %} -->
|
||||||
|
|
||||||
|
```HTML
|
||||||
|
<div>
|
||||||
|
Is available: {{ isAvailable | adfBoolean }}
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- {% endraw %} -->
|
||||||
|
|
||||||
|
## Details
|
||||||
|
|
||||||
|
This pipe is prepared for any input values. The value `'true'` will be returned if true (boolean) or 'true' (exact string) appears on the input. The situation is identical for the value `'false'` - it will be returned in the case of false(boolean) or 'false'. In other cases, we can expect an `empty string('')`.
|
@@ -0,0 +1,131 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { BooleanCellComponent } from './boolean-cell.component';
|
||||||
|
import { ObjectDataTableAdapter } from '../../data/object-datatable-adapter';
|
||||||
|
import { ObjectDataColumn } from '../../data/object-datacolumn.model';
|
||||||
|
|
||||||
|
describe('BooleanCellComponent', () => {
|
||||||
|
let component: BooleanCellComponent;
|
||||||
|
let fixture: ComponentFixture<BooleanCellComponent>;
|
||||||
|
const getBooleanCell = () => fixture.debugElement.nativeElement.querySelector('span');
|
||||||
|
const renderAndCheckResult = (value: any, expectedOccurrence: boolean, expectedLabel?: string) => {
|
||||||
|
component.value$.next(value);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const booleanCell = getBooleanCell();
|
||||||
|
|
||||||
|
expectedOccurrence ? expect(booleanCell).toBeTruthy() : expect(booleanCell).toBeFalsy();
|
||||||
|
if (expectedLabel) {
|
||||||
|
expect(booleanCell.textContent.trim()).toBe(expectedLabel);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [BooleanCellComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(BooleanCellComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Initialization', () => {
|
||||||
|
let rowData: any;
|
||||||
|
let columnData: any;
|
||||||
|
let dataTableAdapter: ObjectDataTableAdapter;
|
||||||
|
let nextSpy: jasmine.Spy;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
rowData = {
|
||||||
|
id: '1',
|
||||||
|
value: false
|
||||||
|
};
|
||||||
|
columnData = { type: 'boolean', key: 'value' };
|
||||||
|
dataTableAdapter = new ObjectDataTableAdapter([rowData], [new ObjectDataColumn(columnData)]);
|
||||||
|
nextSpy = spyOn(component.value$, 'next');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should setup inital value', () => {
|
||||||
|
component.column = dataTableAdapter.getColumns()[0];
|
||||||
|
component.row = dataTableAdapter.getRows()[0];
|
||||||
|
component.data = dataTableAdapter;
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(nextSpy).toHaveBeenCalledOnceWith(rowData.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT setup inital value', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(nextSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('UI', () => {
|
||||||
|
describe('should render "true" inside cell when', () => {
|
||||||
|
it('boolean value is true', () => {
|
||||||
|
renderAndCheckResult(true, true, 'true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exact string is provided', () => {
|
||||||
|
renderAndCheckResult('true', true, 'true');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should render "false" inside cell when', () => {
|
||||||
|
it('boolean value is false', () => {
|
||||||
|
renderAndCheckResult(false, true, 'false');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exact string is provided', () => {
|
||||||
|
renderAndCheckResult('false', true, 'false');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should NOT render value inside cell in case of', () => {
|
||||||
|
it('invalid string', () => {
|
||||||
|
renderAndCheckResult('tru', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('number', () => {
|
||||||
|
renderAndCheckResult(0, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('object', () => {
|
||||||
|
renderAndCheckResult({}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('null', () => {
|
||||||
|
renderAndCheckResult(null, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('undefined', () => {
|
||||||
|
renderAndCheckResult(undefined, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('empty string', () => {
|
||||||
|
renderAndCheckResult('', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('NaN', () => {
|
||||||
|
renderAndCheckResult(NaN, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,49 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ChangeDetectionStrategy, Component, OnInit, Optional, ViewEncapsulation } from '@angular/core';
|
||||||
|
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { DataTableService } from '../../services/datatable.service';
|
||||||
|
import { BooleanPipe } from '../../../pipes/boolean.pipe';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, BooleanPipe],
|
||||||
|
selector: 'adf-boolean-cell',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
template: `
|
||||||
|
<ng-container *ngIf="value$ | async | adfBoolean as value">
|
||||||
|
<span [title]="value">
|
||||||
|
{{ value }}
|
||||||
|
</span>
|
||||||
|
</ng-container>
|
||||||
|
`,
|
||||||
|
encapsulation: ViewEncapsulation.None,
|
||||||
|
host: { class: 'adf-datatable-content-cell' }
|
||||||
|
})
|
||||||
|
export class BooleanCellComponent extends DataTableCellComponent implements OnInit {
|
||||||
|
constructor(@Optional() dataTableService: DataTableService) {
|
||||||
|
super(dataTableService);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (this.column?.key && this.row && this.data) {
|
||||||
|
this.value$.next(this.data.getValue(this.row, this.column, this.resolverFn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -287,6 +287,16 @@
|
|||||||
[tooltip]="getCellTooltip(row, col)">
|
[tooltip]="getCellTooltip(row, col)">
|
||||||
</adf-datatable-cell>
|
</adf-datatable-cell>
|
||||||
</div>
|
</div>
|
||||||
|
<div *ngSwitchCase="'boolean'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value"
|
||||||
|
[attr.data-automation-id]="'boolean_' + data.getValue(row, col, resolverFn)">
|
||||||
|
<adf-boolean-cell
|
||||||
|
[data]="data"
|
||||||
|
[column]="col"
|
||||||
|
[row]="row"
|
||||||
|
[resolverFn]="resolverFn"
|
||||||
|
[tooltip]="getCellTooltip(row, col)">
|
||||||
|
</adf-boolean-cell>
|
||||||
|
</div>
|
||||||
<div *ngSwitchCase="'json'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value">
|
<div *ngSwitchCase="'json'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value">
|
||||||
<adf-json-cell
|
<adf-json-cell
|
||||||
[editable]="col.editable"
|
[editable]="col.editable"
|
||||||
|
@@ -33,6 +33,7 @@ import { matIconRegistryMock } from '../../../mock/mat-icon-registry-mock';
|
|||||||
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { mockCarsData, mockCarsSchemaDefinition } from '../mocks/datatable.mock';
|
||||||
|
|
||||||
@Component({ selector: 'adf-custom-column-template-component', template: ` <ng-template #tmplRef></ng-template> ` })
|
@Component({ selector: 'adf-custom-column-template-component', template: ` <ng-template #tmplRef></ng-template> ` })
|
||||||
class CustomColumnTemplateComponent {
|
class CustomColumnTemplateComponent {
|
||||||
@@ -1195,6 +1196,17 @@ describe('DataTable', () => {
|
|||||||
expect(rows3[0].isSelected).toBeFalsy();
|
expect(rows3[0].isSelected).toBeFalsy();
|
||||||
expect(rows3[1].isSelected).toBeTruthy();
|
expect(rows3[1].isSelected).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to display column of type boolean', () => {
|
||||||
|
dataTable.data = new ObjectDataTableAdapter(mockCarsData, mockCarsSchemaDefinition);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
const rows = dataTable.data.getRows();
|
||||||
|
|
||||||
|
expect(rows[0].getValue('is_available')).toBe('false');
|
||||||
|
expect(rows[1].getValue('is_available')).toBe('true');
|
||||||
|
expect(rows[2].getValue('is_available')).toBe('true');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Accesibility', () => {
|
describe('Accesibility', () => {
|
||||||
|
115
lib/core/src/lib/datatable/components/mocks/datatable.mock.ts
Normal file
115
lib/core/src/lib/datatable/components/mocks/datatable.mock.ts
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const mockCarsData: any = [
|
||||||
|
{
|
||||||
|
car_id: 1,
|
||||||
|
car_name: 'Fiat 126p (Process)',
|
||||||
|
car_price: 599.00,
|
||||||
|
is_available: 'false',
|
||||||
|
production_start: '1972-04-23',
|
||||||
|
description: 'The Fiat 126 (Type 126) is a four-passenger, rear-engine, city car manufactured and marketed by Fiat over a twenty-eight year production run from 1972 until 2000, over a single generation.',
|
||||||
|
icon: 'airport_shuttle',
|
||||||
|
wikipedia_link: 'https://en.wikipedia.org/wiki/Fiat_126'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
car_id: 2,
|
||||||
|
car_name: 'Citroen Xsara Picasso (Process)',
|
||||||
|
car_price: 10000,
|
||||||
|
is_available: 'true',
|
||||||
|
production_start: '2004-02-10T12:25:43.511Z',
|
||||||
|
description: 'The Citroën Xsara Picasso is a car produced by Citroën from 1999 to 2012. It has a five-seater five-door compact MPV design.',
|
||||||
|
icon: 'local_shipping',
|
||||||
|
wikipedia_link: 'https://en.wikipedia.org/wiki/Citro%C3%ABn_Xsara_Picasso'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
car_id: 3,
|
||||||
|
car_name: 'Audi A3 (Process)',
|
||||||
|
car_price: 15000.12345,
|
||||||
|
is_available: 'true',
|
||||||
|
production_start: '1998-06-25T12:25:20',
|
||||||
|
description: 'The Audi A3 is a subcompact executive/small family car (C-segment) manufactured and marketed by the German automaker Audi AG since September 1996, currently in its fourth generation.',
|
||||||
|
icon: 'directions_car',
|
||||||
|
wikipedia_link: 'https://en.wikipedia.org/wiki/Audi_A3'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const mockCarsSchemaDefinition: any[] = [
|
||||||
|
{
|
||||||
|
type: 'icon',
|
||||||
|
key: 'icon',
|
||||||
|
title: '',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
key: 'car_id',
|
||||||
|
title: 'Car ID',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
key: 'car_name',
|
||||||
|
title: 'Car Name',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'amount',
|
||||||
|
key: 'car_price',
|
||||||
|
title: 'Car Price',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true,
|
||||||
|
currencyConfig: {
|
||||||
|
code: 'USA',
|
||||||
|
display: 'code',
|
||||||
|
digitsInfo: '1.0-2',
|
||||||
|
locale: 'en-US'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'boolean',
|
||||||
|
key: 'is_available',
|
||||||
|
title: 'Available?',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'date',
|
||||||
|
key: 'production_start',
|
||||||
|
title: 'Production Start',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'json',
|
||||||
|
key: 'description',
|
||||||
|
title: 'Description',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'location',
|
||||||
|
format: '/somewhere',
|
||||||
|
key: 'wikipedia_link',
|
||||||
|
title: 'Wikipedia',
|
||||||
|
sortable: true,
|
||||||
|
draggable: true
|
||||||
|
}
|
||||||
|
];
|
@@ -18,6 +18,7 @@
|
|||||||
/* eslint-disable @angular-eslint/component-selector, @angular-eslint/no-input-rename */
|
/* eslint-disable @angular-eslint/component-selector, @angular-eslint/no-input-rename */
|
||||||
|
|
||||||
import { Component, ContentChild, Input, OnInit, TemplateRef } from '@angular/core';
|
import { Component, ContentChild, Input, OnInit, TemplateRef } from '@angular/core';
|
||||||
|
import { DataColumnType } from '../public-api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'data-column',
|
selector: 'data-column',
|
||||||
@@ -41,11 +42,11 @@ export class DataColumnComponent implements OnInit {
|
|||||||
customData: any;
|
customData: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value type for the column. Possible settings are 'text', 'image',
|
* Value type for the column. Possible settings are defined via DataColumnType.
|
||||||
* 'date', 'fileSize', 'location', and 'json'.
|
* Example types: `text`, `date`, `image`, `icon`, `boolean`.
|
||||||
*/
|
*/
|
||||||
@Input()
|
@Input()
|
||||||
type: string = 'text';
|
type: DataColumnType = 'text';
|
||||||
|
|
||||||
/** Value format (if supported by the parent component), for example format of the date. */
|
/** Value format (if supported by the parent component), for example format of the date. */
|
||||||
@Input()
|
@Input()
|
||||||
|
@@ -25,6 +25,8 @@ export interface DataColumnTypes {
|
|||||||
icon: string;
|
icon: string;
|
||||||
fileSize: string;
|
fileSize: string;
|
||||||
location: string;
|
location: string;
|
||||||
|
// eslint-disable-next-line id-blacklist
|
||||||
|
boolean: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DataColumnType = keyof DataColumnTypes;
|
export type DataColumnType = keyof DataColumnTypes;
|
||||||
|
@@ -53,6 +53,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { DataColumnComponent, DataColumnListComponent, DateColumnHeaderComponent } from './data-column';
|
import { DataColumnComponent, DataColumnListComponent, DateColumnHeaderComponent } from './data-column';
|
||||||
import { ResizableModule } from './directives/resizable/resizable.module';
|
import { ResizableModule } from './directives/resizable/resizable.module';
|
||||||
import { DataColumnModule } from './data-column/data-column.module';
|
import { DataColumnModule } from './data-column/data-column.module';
|
||||||
|
import { BooleanCellComponent } from './components/boolean-cell/boolean-cell.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -69,7 +70,8 @@ import { DataColumnModule } from './data-column/data-column.module';
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
ResizableModule,
|
ResizableModule,
|
||||||
DataColumnModule
|
DataColumnModule,
|
||||||
|
BooleanCellComponent
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
DataTableComponent,
|
DataTableComponent,
|
||||||
|
85
lib/core/src/lib/pipes/boolean.pipe.spec.ts
Normal file
85
lib/core/src/lib/pipes/boolean.pipe.spec.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { BooleanPipe } from './boolean.pipe';
|
||||||
|
|
||||||
|
describe('BooleanPipe', () => {
|
||||||
|
let pipe: BooleanPipe;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
pipe = new BooleanPipe();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should return "true" when', () => {
|
||||||
|
it('boolean value is true', () => {
|
||||||
|
expect(pipe.transform(true)).toBe('true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exact string is provided', () => {
|
||||||
|
expect(pipe.transform('true')).toBe('true');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should return "false" when', () => {
|
||||||
|
it('boolean value is false', () => {
|
||||||
|
expect(pipe.transform(false)).toBe('false');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exact string is provided', () => {
|
||||||
|
expect(pipe.transform('false')).toBe('false');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should return empty string in case of', () => {
|
||||||
|
it('invalid string', () => {
|
||||||
|
expect(pipe.transform('fal')).toBe('');
|
||||||
|
expect(pipe.transform('truee')).toBe('');
|
||||||
|
expect(pipe.transform('0')).toBe('');
|
||||||
|
expect(pipe.transform('1')).toBe('');
|
||||||
|
expect(pipe.transform('122')).toBe('');
|
||||||
|
expect(pipe.transform('TRUE')).toBe('');
|
||||||
|
expect(pipe.transform('FALSE')).toBe('');
|
||||||
|
expect(pipe.transform(' false')).toBe('');
|
||||||
|
expect(pipe.transform(' true ')).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('falsy value (excluding false)', () => {
|
||||||
|
expect(pipe.transform(null)).toBe('');
|
||||||
|
expect(pipe.transform(undefined)).toBe('');
|
||||||
|
expect(pipe.transform(false)).not.toBe('');
|
||||||
|
expect(pipe.transform(NaN)).toBe('');
|
||||||
|
expect(pipe.transform(0)).toBe('');
|
||||||
|
expect(pipe.transform(-0)).toBe('');
|
||||||
|
expect(pipe.transform(BigInt(0))).toBe('');
|
||||||
|
expect(pipe.transform('')).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('number', () => {
|
||||||
|
expect(pipe.transform(-20.5)).toBe('');
|
||||||
|
expect(pipe.transform(-1)).toBe('');
|
||||||
|
expect(pipe.transform(0)).toBe('');
|
||||||
|
expect(pipe.transform(1)).toBe('');
|
||||||
|
expect(pipe.transform(100)).toBe('');
|
||||||
|
expect(pipe.transform(100.5)).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('object', () => {
|
||||||
|
expect(pipe.transform({})).toBe('');
|
||||||
|
expect(pipe.transform({ value: 'true'})).toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
35
lib/core/src/lib/pipes/boolean.pipe.ts
Normal file
35
lib/core/src/lib/pipes/boolean.pipe.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'adfBoolean',
|
||||||
|
standalone: true
|
||||||
|
})
|
||||||
|
export class BooleanPipe implements PipeTransform {
|
||||||
|
transform(value: any): string {
|
||||||
|
if (typeof value === 'boolean') {
|
||||||
|
return value ? 'true' : 'false';
|
||||||
|
}
|
||||||
|
return this.isRecognizedAsBoolean(value) ? value : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
private isRecognizedAsBoolean(value: any): boolean {
|
||||||
|
return value === 'true' || value === 'false';
|
||||||
|
}
|
||||||
|
}
|
@@ -33,3 +33,4 @@ export * from './moment-datetime.pipe';
|
|||||||
export * from './date-time.pipe';
|
export * from './date-time.pipe';
|
||||||
export * from './filter-string.pipe';
|
export * from './filter-string.pipe';
|
||||||
export * from './filter-out-every-object-by-prop.pipe';
|
export * from './filter-out-every-object-by-prop.pipe';
|
||||||
|
export * from './boolean.pipe';
|
||||||
|
@@ -20,27 +20,31 @@ import { getProcessInstanceVariableMock } from '../mock/process-instance-variabl
|
|||||||
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
||||||
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
|
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
|
||||||
import { VariableMapperService } from './variable-mapper.sevice';
|
import { VariableMapperService } from './variable-mapper.sevice';
|
||||||
import { getDataColumnMock } from '@alfresco/adf-core';
|
import { DataColumn, getDataColumnMock } from '@alfresco/adf-core';
|
||||||
|
|
||||||
describe('VariableMapperService', () => {
|
describe('VariableMapperService', () => {
|
||||||
let service: VariableMapperService;
|
let service: VariableMapperService;
|
||||||
|
let variable: ProcessInstanceVariable;
|
||||||
|
let column: DataColumn<ProcessListDataColumnCustomData>;
|
||||||
|
let objectWithVariables: { variables: ProcessInstanceVariable[] };
|
||||||
|
const checkTypeMapping = (processVariableType: string, expectedColumnType: string) => {
|
||||||
|
variable.type = processVariableType;
|
||||||
|
|
||||||
|
const viewModel = service.mapVariablesByColumnTitle([objectWithVariables], [column]);
|
||||||
|
|
||||||
|
expect(viewModel[0].variablesMap[column.title].type).toEqual(expectedColumnType);
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service = new VariableMapperService();
|
service = new VariableMapperService();
|
||||||
});
|
|
||||||
|
|
||||||
it('should map variables by column title', () => {
|
variable = getProcessInstanceVariableMock({
|
||||||
const variable: ProcessInstanceVariable = getProcessInstanceVariableMock({
|
|
||||||
processDefinitionKey: 'processKey',
|
processDefinitionKey: 'processKey',
|
||||||
name: 'variableName'
|
name: 'variableName'
|
||||||
});
|
});
|
||||||
|
|
||||||
const objectWithVariables = {
|
column = getDataColumnMock<ProcessListDataColumnCustomData>({
|
||||||
variables: [variable]
|
title: 'Column Name',
|
||||||
};
|
|
||||||
|
|
||||||
const column = getDataColumnMock<ProcessListDataColumnCustomData>({
|
|
||||||
title: 'column name',
|
|
||||||
key: '',
|
key: '',
|
||||||
customData: {
|
customData: {
|
||||||
variableDefinitionsPayload: ['processKey/variableName'],
|
variableDefinitionsPayload: ['processKey/variableName'],
|
||||||
@@ -49,8 +53,12 @@ describe('VariableMapperService', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const viewModel = service.mapVariablesByColumnTitle([objectWithVariables], [column]);
|
objectWithVariables = {
|
||||||
|
variables: [variable]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should map variables by column title', () => {
|
||||||
const expectedObjectWithVariableMap = {
|
const expectedObjectWithVariableMap = {
|
||||||
...objectWithVariables,
|
...objectWithVariables,
|
||||||
variablesMap: {
|
variablesMap: {
|
||||||
@@ -58,6 +66,34 @@ describe('VariableMapperService', () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const viewModel = service.mapVariablesByColumnTitle([objectWithVariables], [column]);
|
||||||
|
|
||||||
expect(viewModel).toEqual([expectedObjectWithVariableMap]);
|
expect(viewModel).toEqual([expectedObjectWithVariableMap]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('should map correct column type according to process variable type in case of', () => {
|
||||||
|
it('date type', () => {
|
||||||
|
checkTypeMapping('boolean', 'boolean');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('integer type', () => {
|
||||||
|
checkTypeMapping('integer', 'text');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('string type', () => {
|
||||||
|
checkTypeMapping('string', 'text');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('date type', () => {
|
||||||
|
checkTypeMapping('date', 'date');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('datetime type', () => {
|
||||||
|
checkTypeMapping('datetime', 'date');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('other types', () => {
|
||||||
|
checkTypeMapping('custom', 'text');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -78,6 +78,7 @@ export class VariableMapperService {
|
|||||||
private mapProcessVariableTypes(variableType: string): DataColumnType {
|
private mapProcessVariableTypes(variableType: string): DataColumnType {
|
||||||
switch (variableType) {
|
switch (variableType) {
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
|
return 'boolean';
|
||||||
case 'integer':
|
case 'integer':
|
||||||
case 'string':
|
case 'string':
|
||||||
return 'text';
|
return 'text';
|
||||||
|
Reference in New Issue
Block a user