diff --git a/npm/ng-packs/packages/components/extensible/src/lib/models/actions.ts b/npm/ng-packs/packages/components/extensible/src/lib/models/actions.ts index 003979e452..40938aca44 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/models/actions.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/models/actions.ts @@ -1,5 +1,5 @@ import { InjectionToken, InjectOptions, Type } from '@angular/core'; -import { LinkedList } from '../utils/linked-list'; +import { LinkedList } from '@abp/utils'; export abstract class ActionList> extends LinkedList {} diff --git a/npm/ng-packs/packages/components/extensible/src/lib/models/props.ts b/npm/ng-packs/packages/components/extensible/src/lib/models/props.ts index 808d18db22..8a2a29e425 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/models/props.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/models/props.ts @@ -1,5 +1,5 @@ import { InjectionToken, InjectOptions, Type } from '@angular/core'; -import { LinkedList } from '../utils/linked-list'; +import { LinkedList } from '@abp/utils'; import { ePropType } from '../enums/props.enum'; import { FormPropTooltip } from './form-props'; diff --git a/npm/ng-packs/packages/components/extensible/src/lib/utils/linked-list.ts b/npm/ng-packs/packages/components/extensible/src/lib/utils/linked-list.ts deleted file mode 100644 index 9640b40674..0000000000 --- a/npm/ng-packs/packages/components/extensible/src/lib/utils/linked-list.ts +++ /dev/null @@ -1,410 +0,0 @@ -/** @description This file is referenced from here npm/packs/utils/projects/utils/src/lib/linked-list.ts */ - -/* eslint-disable prefer-spread */ -/* tslint:disable:no-non-null-assertion */ - -import compare from 'just-compare'; - -export class ListNode { - next: ListNode | undefined; - previous: ListNode | undefined; - constructor(public readonly value: T) {} -} - -export class LinkedList { - private first: ListNode | undefined; - private last: ListNode | undefined; - private size = 0; - - get head(): ListNode | undefined { - return this.first; - } - get tail(): ListNode | undefined { - return this.last; - } - get length(): number { - return this.size; - } - - private attach( - value: T, - previousNode: ListNode | undefined, - nextNode: ListNode | undefined, - ): ListNode { - if (!previousNode) return this.addHead(value); - - if (!nextNode) return this.addTail(value); - - const node = new ListNode(value); - node.previous = previousNode; - previousNode.next = node; - node.next = nextNode; - nextNode.previous = node; - - this.size++; - - return node; - } - - private attachMany( - values: T[], - previousNode: ListNode | undefined, - nextNode: ListNode | undefined, - ): ListNode[] { - if (!values.length) return []; - - if (!previousNode) return this.addManyHead(values); - - if (!nextNode) return this.addManyTail(values); - - const list = new LinkedList(); - list.addManyTail(values); - list.first!.previous = previousNode; - previousNode.next = list.first; - list.last!.next = nextNode; - nextNode.previous = list.last; - - this.size += values.length; - - return list.toNodeArray(); - } - - private detach(node: ListNode) { - if (!node.previous) return this.dropHead(); - - if (!node.next) return this.dropTail(); - - node.previous.next = node.next; - node.next.previous = node.previous; - - this.size--; - - return node; - } - - add(value: T) { - return { - after: (...params: [T] | [any, ListComparisonFn]) => - this.addAfter.call(this, value, ...params), - before: (...params: [T] | [any, ListComparisonFn]) => - this.addBefore.call(this, value, ...params), - byIndex: (position: number) => this.addByIndex(value, position), - head: () => this.addHead(value), - tail: () => this.addTail(value), - }; - } - - addMany(values: T[]) { - return { - after: (...params: [T] | [any, ListComparisonFn]) => - this.addManyAfter.call(this, values, ...params), - before: (...params: [T] | [any, ListComparisonFn]) => - this.addManyBefore.call(this, values, ...params), - byIndex: (position: number) => this.addManyByIndex(values, position), - head: () => this.addManyHead(values), - tail: () => this.addManyTail(values), - }; - } - - addAfter(value: T, previousValue: T): ListNode; - addAfter(value: T, previousValue: any, compareFn: ListComparisonFn): ListNode; - addAfter(value: T, previousValue: any, compareFn: ListComparisonFn = compare): ListNode { - const previous = this.find(node => compareFn(node.value, previousValue)); - - return previous ? this.attach(value, previous, previous.next) : this.addTail(value); - } - - addBefore(value: T, nextValue: T): ListNode; - addBefore(value: T, nextValue: any, compareFn: ListComparisonFn): ListNode; - addBefore(value: T, nextValue: any, compareFn: ListComparisonFn = compare): ListNode { - const next = this.find(node => compareFn(node.value, nextValue)); - - return next ? this.attach(value, next.previous, next) : this.addHead(value); - } - - addByIndex(value: T, position: number): ListNode { - if (position < 0) position += this.size; - else if (position >= this.size) return this.addTail(value); - - if (position <= 0) return this.addHead(value); - - const next = this.get(position)!; - - return this.attach(value, next.previous, next); - } - - addHead(value: T): ListNode { - const node = new ListNode(value); - - node.next = this.first; - - if (this.first) this.first.previous = node; - else this.last = node; - - this.first = node; - this.size++; - - return node; - } - - addTail(value: T): ListNode { - const node = new ListNode(value); - - if (this.first) { - node.previous = this.last; - this.last!.next = node; - this.last = node; - } else { - this.first = node; - this.last = node; - } - - this.size++; - - return node; - } - - addManyAfter(values: T[], previousValue: T): ListNode[]; - addManyAfter(values: T[], previousValue: any, compareFn: ListComparisonFn): ListNode[]; - addManyAfter( - values: T[], - previousValue: any, - compareFn: ListComparisonFn = compare, - ): ListNode[] { - const previous = this.find(node => compareFn(node.value, previousValue)); - - return previous ? this.attachMany(values, previous, previous.next) : this.addManyTail(values); - } - - addManyBefore(values: T[], nextValue: T): ListNode[]; - addManyBefore(values: T[], nextValue: any, compareFn: ListComparisonFn): ListNode[]; - addManyBefore( - values: T[], - nextValue: any, - compareFn: ListComparisonFn = compare, - ): ListNode[] { - const next = this.find(node => compareFn(node.value, nextValue)); - - return next ? this.attachMany(values, next.previous, next) : this.addManyHead(values); - } - - addManyByIndex(values: T[], position: number): ListNode[] { - if (position < 0) position += this.size; - - if (position <= 0) return this.addManyHead(values); - - if (position >= this.size) return this.addManyTail(values); - - const next = this.get(position)!; - - return this.attachMany(values, next.previous, next); - } - - addManyHead(values: T[]): ListNode[] { - return values.reduceRight[]>((nodes, value) => { - nodes.unshift(this.addHead(value)); - return nodes; - }, []); - } - - addManyTail(values: T[]): ListNode[] { - return values.map(value => this.addTail(value)); - } - - drop() { - return { - byIndex: (position: number) => this.dropByIndex(position), - byValue: (...params: [T] | [any, ListComparisonFn]) => - this.dropByValue.apply(this, params), - byValueAll: (...params: [T] | [any, ListComparisonFn]) => - this.dropByValueAll.apply(this, params), - head: () => this.dropHead(), - tail: () => this.dropTail(), - }; - } - - dropMany(count: number) { - return { - byIndex: (position: number) => this.dropManyByIndex(count, position), - head: () => this.dropManyHead(count), - tail: () => this.dropManyTail(count), - }; - } - - dropByIndex(position: number): ListNode | undefined { - if (position < 0) position += this.size; - - const current = this.get(position); - - return current ? this.detach(current) : undefined; - } - - dropByValue(value: T): ListNode | undefined; - dropByValue(value: any, compareFn: ListComparisonFn): ListNode | undefined; - dropByValue(value: any, compareFn: ListComparisonFn = compare): ListNode | undefined { - const position = this.findIndex(node => compareFn(node.value, value)); - - return position < 0 ? undefined : this.dropByIndex(position); - } - - dropByValueAll(value: T): ListNode[]; - dropByValueAll(value: any, compareFn: ListComparisonFn): ListNode[]; - dropByValueAll(value: any, compareFn: ListComparisonFn = compare): ListNode[] { - const dropped: ListNode[] = []; - - for (let current = this.first, position = 0; current; position++, current = current.next) { - if (compareFn(current.value, value)) { - dropped.push(this.dropByIndex(position - dropped.length)!); - } - } - - return dropped; - } - - dropHead(): ListNode | undefined { - const head = this.first; - - if (head) { - this.first = head.next; - - if (this.first) this.first.previous = undefined; - else this.last = undefined; - - this.size--; - - return head; - } - - return undefined; - } - - dropTail(): ListNode | undefined { - const tail = this.last; - - if (tail) { - this.last = tail.previous; - - if (this.last) this.last.next = undefined; - else this.first = undefined; - - this.size--; - - return tail; - } - - return undefined; - } - - dropManyByIndex(count: number, position: number): ListNode[] { - if (count <= 0) return []; - - if (position < 0) position = Math.max(position + this.size, 0); - else if (position >= this.size) return []; - - count = Math.min(count, this.size - position); - - const dropped: ListNode[] = []; - - while (count--) { - const current = this.get(position); - dropped.push(this.detach(current!)!); - } - - return dropped; - } - - dropManyHead(count: Exclude): ListNode[] { - if (count <= 0) return []; - - count = Math.min(count, this.size); - - const dropped: ListNode[] = []; - - while (count--) dropped.unshift(this.dropHead()!); - - return dropped; - } - - dropManyTail(count: Exclude): ListNode[] { - if (count <= 0) return []; - - count = Math.min(count, this.size); - - const dropped: ListNode[] = []; - - while (count--) dropped.push(this.dropTail()!); - - return dropped; - } - - find(predicate: ListIteratorFn): ListNode | undefined { - for (let current = this.first, position = 0; current; position++, current = current.next) { - if (predicate(current, position, this)) return current; - } - - return undefined; - } - - findIndex(predicate: ListIteratorFn): number { - for (let current = this.first, position = 0; current; position++, current = current.next) { - if (predicate(current, position, this)) return position; - } - - return -1; - } - - forEach(iteratorFn: ListIteratorFn) { - for (let node = this.first, position = 0; node; position++, node = node.next) { - iteratorFn(node, position, this); - } - } - - get(position: number): ListNode | undefined { - return this.find((_, index) => position === index); - } - - indexOf(value: T): number; - indexOf(value: any, compareFn: ListComparisonFn): number; - indexOf(value: any, compareFn: ListComparisonFn = compare): number { - return this.findIndex(node => compareFn(node.value, value)); - } - - toArray(): T[] { - const array = new Array(this.size); - - this.forEach((node, index) => (array[index!] = node.value)); - - return array; - } - - toNodeArray(): ListNode[] { - const array = new Array(this.size); - - this.forEach((node, index) => (array[index!] = node)); - - return array; - } - - toString(mapperFn: ListMapperFn = JSON.stringify): string { - return this.toArray() - .map(value => mapperFn(value)) - .join(' <-> '); - } - - // Cannot use Generator type because of ng-packagr - *[Symbol.iterator](): any { - for (let node = this.first, position = 0; node; position++, node = node.next) { - yield node.value; - } - } -} - -export type ListMapperFn = (value: T) => any; - -export type ListComparisonFn = (value1: T, value2: any) => boolean; - -export type ListIteratorFn = ( - node: ListNode, - index?: number, - list?: LinkedList, -) => R;