add sorting and utility types
This commit is contained in:
parent
4004c4c8f9
commit
bb7b3af13e
@ -24,7 +24,8 @@
|
|||||||
"prefix": "iqser",
|
"prefix": "iqser",
|
||||||
"style": "kebab-case"
|
"style": "kebab-case"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"no-param-reassign": "error"
|
||||||
},
|
},
|
||||||
"plugins": ["@angular-eslint/eslint-plugin", "@typescript-eslint"]
|
"plugins": ["@angular-eslint/eslint-plugin", "@typescript-eslint"]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -11,3 +11,6 @@ export * from './lib/filtering/filter-utils';
|
|||||||
export * from './lib/filtering/models/filter-group.model';
|
export * from './lib/filtering/models/filter-group.model';
|
||||||
export * from './lib/filtering/models/nested-filter.model';
|
export * from './lib/filtering/models/nested-filter.model';
|
||||||
export * from './lib/filtering/models/filter.model';
|
export * from './lib/filtering/models/filter.model';
|
||||||
|
export * from './lib/sorting/sorting.service';
|
||||||
|
export * from './lib/sorting/models/sorting-option.model';
|
||||||
|
export * from './lib/sorting/models/sorting-order.type';
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, On
|
|||||||
import { MatTooltip } from '@angular/material/tooltip';
|
import { MatTooltip } from '@angular/material/tooltip';
|
||||||
import { CircleButtonType, CircleButtonTypes } from './circle-button.type';
|
import { CircleButtonType, CircleButtonTypes } from './circle-button.type';
|
||||||
import { Required } from '../../utils/decorators/required.decorator';
|
import { Required } from '../../utils/decorators/required.decorator';
|
||||||
import { TooltipPositionsType, TooltipPositionsTypes } from '../../utils/types/tooltip-positions.type';
|
import { IqserTooltipPosition, IqserTooltipPositions } from '../../utils/types/tooltip-positions.type';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'iqser-circle-button',
|
selector: 'iqser-circle-button',
|
||||||
@ -17,7 +17,7 @@ export class CircleButtonComponent implements OnInit {
|
|||||||
@Input() tooltip?: string;
|
@Input() tooltip?: string;
|
||||||
@Input() tooltipClass?: string;
|
@Input() tooltipClass?: string;
|
||||||
@Input() showDot = false;
|
@Input() showDot = false;
|
||||||
@Input() tooltipPosition: TooltipPositionsType = TooltipPositionsTypes.above;
|
@Input() tooltipPosition: IqserTooltipPosition = IqserTooltipPositions.above;
|
||||||
@Input() disabled = false;
|
@Input() disabled = false;
|
||||||
@Input() type: CircleButtonType = CircleButtonTypes.default;
|
@Input() type: CircleButtonType = CircleButtonTypes.default;
|
||||||
@Input() removeTooltip = false;
|
@Input() removeTooltip = false;
|
||||||
|
|||||||
6
src/lib/sorting/models/sorting-option.model.ts
Normal file
6
src/lib/sorting/models/sorting-option.model.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { SortingOrder } from './sorting-order.type';
|
||||||
|
|
||||||
|
export interface SortingOption {
|
||||||
|
readonly order: SortingOrder;
|
||||||
|
readonly column: string;
|
||||||
|
}
|
||||||
14
src/lib/sorting/models/sorting-order.type.ts
Normal file
14
src/lib/sorting/models/sorting-order.type.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { NonFunctionKeys } from '../../utils/types/utility-types';
|
||||||
|
|
||||||
|
function inverseOf(order?: SortingOrder) {
|
||||||
|
if (order === undefined) return SortingOrders.asc;
|
||||||
|
return order === SortingOrders.asc ? SortingOrders.desc : SortingOrders.asc;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SortingOrders = {
|
||||||
|
asc: 'asc',
|
||||||
|
desc: 'desc',
|
||||||
|
inverseOf: inverseOf
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type SortingOrder = NonFunctionKeys<typeof SortingOrders>;
|
||||||
42
src/lib/sorting/sorting.service.ts
Normal file
42
src/lib/sorting/sorting.service.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { orderBy } from 'lodash';
|
||||||
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
import { SortingOption } from './models/sorting-option.model';
|
||||||
|
import { SortingOrder, SortingOrders } from './models/sorting-order.type';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SortingService {
|
||||||
|
private readonly _sortingOption$ = new BehaviorSubject<SortingOption | undefined>(undefined);
|
||||||
|
readonly sortingOption$ = this._sortingOption$.asObservable();
|
||||||
|
|
||||||
|
get sortingOption(): SortingOption | undefined {
|
||||||
|
return this._sortingOption$.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
setSortingOption(value: SortingOption): void {
|
||||||
|
this._sortingOption$.next(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort<T>(values: T[], order?: SortingOrder, column?: string): T[] {
|
||||||
|
if (!values || values.length <= 1 || !order) return values;
|
||||||
|
|
||||||
|
if (!column) {
|
||||||
|
/** sort 1d array */
|
||||||
|
const result = [...values].sort();
|
||||||
|
return order === SortingOrders.asc ? result : result.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderBy(values, [column], [order]);
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultSort<T>(values: T[]): T[] {
|
||||||
|
return this.sort(values, this.sortingOption?.order, this.sortingOption?.column);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleSort(column: string): void {
|
||||||
|
const sameColumn = this.sortingOption?.column === column;
|
||||||
|
const order = sameColumn ? SortingOrders.inverseOf(this.sortingOption?.order) : SortingOrders.asc;
|
||||||
|
|
||||||
|
this._sortingOption$.next({ column, order });
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
export function Required(message?: string) {
|
export function Required(message?: string): PropertyDecorator {
|
||||||
return function (target: Object, propertyKey: PropertyKey) {
|
return function (target: Object, propertyKey: PropertyKey) {
|
||||||
Object.defineProperty(target, propertyKey, {
|
Object.defineProperty(target, propertyKey, {
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
export const TooltipPositionsTypes = {
|
import { KeysOf } from './utility-types';
|
||||||
|
|
||||||
|
export const IqserTooltipPositions = {
|
||||||
below: 'below',
|
below: 'below',
|
||||||
above: 'above',
|
above: 'above',
|
||||||
before: 'before',
|
before: 'before',
|
||||||
after: 'after'
|
after: 'after'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type TooltipPositionsType = keyof typeof TooltipPositionsTypes;
|
export type IqserTooltipPosition = KeysOf<typeof IqserTooltipPositions>;
|
||||||
|
|||||||
38
src/lib/utils/types/utility-types.ts
Normal file
38
src/lib/utils/types/utility-types.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
export type KeysOf<T> = keyof T;
|
||||||
|
|
||||||
|
export type ValuesOf<T extends object> = T[KeysOf<T>];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NonUndefined
|
||||||
|
* @desc Exclude undefined from set `A`
|
||||||
|
* @example
|
||||||
|
* // Expect: "string | null"
|
||||||
|
* SymmetricDifference<string | null | undefined>;
|
||||||
|
*/
|
||||||
|
export type NonUndefined<T> = T extends undefined ? never : T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FunctionKeys
|
||||||
|
* @desc Get union type of keys that are functions in object type `T`
|
||||||
|
* @example
|
||||||
|
* type MixedProps = {name: string; setName: (name: string) => void; someKeys?: string; someFn?: (...args: any) => any;};
|
||||||
|
*
|
||||||
|
* // Expect: "setName | someFn"
|
||||||
|
* type Keys = FunctionKeys<MixedProps>;
|
||||||
|
*/
|
||||||
|
export type FunctionKeys<T extends object> = {
|
||||||
|
[K in keyof T]-?: NonUndefined<T[K]> extends Function ? K : never;
|
||||||
|
}[keyof T];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NonFunctionKeys
|
||||||
|
* @desc Get union type of keys that are non-functions in object type `T`
|
||||||
|
* @example
|
||||||
|
* type MixedProps = {name: string; setName: (name: string) => void; someKeys?: string; someFn?: (...args: any) => any;};
|
||||||
|
*
|
||||||
|
* // Expect: "name | someKey"
|
||||||
|
* type Keys = NonFunctionKeys<MixedProps>;
|
||||||
|
*/
|
||||||
|
export type NonFunctionKeys<T extends object> = {
|
||||||
|
[K in keyof T]-?: NonUndefined<T[K]> extends Function ? never : K;
|
||||||
|
}[keyof T];
|
||||||
Loading…
x
Reference in New Issue
Block a user