first-npm-package-nicule
Version:
This isi first npm package
109 lines (84 loc) • 4.03 kB
text/typescript
import { Injectable } from '@angular/core';
import { FormFieldComponent } from '../components/form-field.component';
()
export class OrderingService {
parse(orderString: string): Orderer {
const testRegex = /^ *(\*|(:?[a-zA-Z_0-9]+)|(:?group:[a-zA-Z_0-9]+)) *(:?, *(\*|(:?[a-zA-Z_0-9]+)|(:?group:[a-zA-Z_0-9]+)) *)*$/;
if (!testRegex.test(orderString)) {
throw new Error(`Invalid ordering string provided: ${orderString}`);
}
const orderConcept = orderString.split(',')
.map(section => section.trim());
return new Orderer(this.parseOrderConcept(orderConcept));
}
parseOrderConcept(orderConcept: Array<string>): Array<Array<string>> {
let lastRule;
let currentGroup = [];
const groups: Array<Array<string>> = [];
orderConcept.forEach((rule, index) => {
if (rule !== '*') {
if (lastRule === undefined) {
currentGroup.push('$start');
}
currentGroup.push(rule);
if (index === orderConcept.length - 1) {
currentGroup.push('$end');
groups.push(currentGroup);
currentGroup = [];
}
} else {
if (currentGroup.length > 0) {
groups.push(currentGroup);
currentGroup = [];
}
}
lastRule = rule;
});
return groups;
}
}
export class Orderer {
ordered: Array<FormFieldComponent> = [];
constructor(private _order: Array<Array<string>>) { }
order(source: Array<FormFieldComponent>): Array<FormFieldComponent> {
const ordered = [];
this._order.forEach(rule => {
if (rule[0] === '$start') {
for (let i = 1; i < rule.length; i++) {
const foundIndex = source.findIndex(({ baseField: { name: fallbackName }, name = fallbackName }) => name === rule[i]);
if (foundIndex >= 0) {
ordered.push(...source.splice(foundIndex, 1));
}
}
} else if (rule[rule.length - 1] === '$end') {
const last = [];
for (let i = 0; i < rule.length - 1; i++) {
const foundIndex = source.findIndex(({ baseField: { name: fallbackName }, name = fallbackName }) => name === rule[i]);
if (foundIndex >= 0) {
last.push(...source.splice(foundIndex, 1));
}
}
ordered.push(...source.splice(0, source.length)); // copy all remaining elements into ordered
ordered.push(...last);
} else {
let lastToCopyIndex = source.findIndex(({ baseField: { name: fallbackName }, name = fallbackName }) => name === rule[0]);
for (let i = 0; i < lastToCopyIndex; i++) {
if (!this._order.some(existingRule => existingRule.includes(source[i].name || source[i].baseField && source[i].baseField.name))) {
ordered.push(...source.splice(i, 1)); // copy into ordored, delete from concat
lastToCopyIndex--; // decrease index, we deleted an element
i--; // we must check the same index again
}
}
for (const member of rule) {
const foundIndex = source.findIndex(({ baseField: { name: fallbackName }, name = fallbackName }) => name === member);
if (foundIndex >= 0) {
ordered.push(...source.splice(foundIndex, 1));
}
}
}
});
ordered.push(...source);
this.ordered = ordered;
return ordered;
}
}