Skip to content

Commit

Permalink
Merge pull request #24 from pennions/fix/flightkit-table-sorting
Browse files Browse the repository at this point in the history
fix: fixed sorting bug by removing joq dependency and rewriting sort
  • Loading branch information
jelmerveen authored Jul 3, 2024
2 parents 617647c + 29ee905 commit 88dbc15
Show file tree
Hide file tree
Showing 26 changed files with 244 additions and 661 deletions.
1 change: 0 additions & 1 deletion dist/flightkit-v0.0.6/flightkit.min.js

This file was deleted.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/flightkit-v0.0.7/flightkit.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/cdn/ibiss-v0.0.7/avian.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/cdn/ibiss-v0.0.7/flightkit.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/cdn/ibiss-v0.0.7/htmx-ibiss-ui.min.js

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

1 change: 1 addition & 0 deletions docs/cdn/ibiss-v0.0.7/rocket.min.js

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

2 changes: 1 addition & 1 deletion docs/js/flightkit.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions documentation/public/cdn/ibiss-v0.0.7/avian.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions documentation/public/cdn/ibiss-v0.0.7/flightkit.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions documentation/public/cdn/ibiss-v0.0.7/htmx-ibiss-ui.min.js

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

1 change: 1 addition & 0 deletions documentation/public/cdn/ibiss-v0.0.7/rocket.min.js

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

2 changes: 1 addition & 1 deletion documentation/public/js/flightkit.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion flightkit/components/draggable.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { returnEventWithTopLevelElement } from '../htmlbuilder/domTraversal';
import { returnEventWithTopLevelElement } from '../flightkit-functions/domTraversal';
import { BaseComponent } from './extensions/base_component';

export class FlightkitDraggable extends HTMLElement {
Expand Down
4 changes: 2 additions & 2 deletions flightkit/components/dropdown.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { returnEventWithTopLevelElement } from '../htmlbuilder/domTraversal';
import { chevronDownIcon, chevronUpIcon, rehydrateSvg } from '../htmlbuilder/icons';
import { returnEventWithTopLevelElement } from '../flightkit-functions/domTraversal';
import { chevronDownIcon, chevronUpIcon, rehydrateSvg } from '../flightkit-functions/icons';
import { BaseComponent } from './extensions/base_component';

export class FlightkitDropdown extends HTMLElement {
Expand Down
4 changes: 2 additions & 2 deletions flightkit/components/extensions/base_component.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { returnEventWithTopLevelElement } from '../../htmlbuilder/domTraversal';
import { uuidv4 } from '../../htmlbuilder/uuid_v4';
import { returnEventWithTopLevelElement } from '../../flightkit-functions/domTraversal';
import { uuidv4 } from '../../flightkit-functions/uuid_v4';

export class BaseComponent {

Expand Down
2 changes: 1 addition & 1 deletion flightkit/components/modal.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { returnEventWithTopLevelElement } from '../htmlbuilder/domTraversal';
import { returnEventWithTopLevelElement } from '../flightkit-functions/domTraversal';
import { BaseComponent } from './extensions/base_component';

export class FlightkitModal extends HTMLElement {
Expand Down
21 changes: 8 additions & 13 deletions flightkit/components/table.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import JOQ from '@pennions/joq';
import { sortJsonArray } from '../flightkit-functions/sorting';
import { BaseComponent } from './extensions/base_component';
import { returnEventWithTopLevelElement, returnDataSetValue } from '../htmlbuilder/domTraversal';
import { sortAscendingIcon, sortDescendingIcon } from '../htmlbuilder/icons';
import { returnEventWithTopLevelElement, returnDataSetValue } from '../flightkit-functions/domTraversal';
import { sortAscendingIcon, sortDescendingIcon } from '../flightkit-functions/icons';

export class FlightkitTable extends HTMLElement {
base;
Expand Down Expand Up @@ -48,7 +48,7 @@ export class FlightkitTable extends HTMLElement {

set contents(newValue) {
this.analyzeData(newValue);
this._contents = new JOQ(newValue);
this._contents = newValue;
}

get orderBy() {
Expand Down Expand Up @@ -166,14 +166,10 @@ export class FlightkitTable extends HTMLElement {

createHtml() {
const tableElement = document.createElement('table');
let tableData = this.contents;

/** because of JOQ */
if (this.orderBy.length) {
this.contents.sort(this.orderBy);
}
else {
/** reset if no order */
this.contents.sort([]);
tableData = sortJsonArray(this.contents, this.orderBy);
}

const tableHead = this.createHead();
Expand All @@ -183,10 +179,9 @@ export class FlightkitTable extends HTMLElement {
tableElement.append(this._createElement('caption'));
}

const orderedData = this.contents.execute();
let filteredData = []
if (this.filter.length) {
for (const data of orderedData) {
for (const data of tableData) {
let valuesInData = Object.values(data).join(" ").toLowerCase();

if (valuesInData.includes(this.filter)) {
Expand All @@ -195,7 +190,7 @@ export class FlightkitTable extends HTMLElement {
}
}
else {
filteredData = orderedData
filteredData = tableData
}


Expand Down
4 changes: 2 additions & 2 deletions flightkit/components/tree-navigation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { folderListIcon, fileListIcon, databaseListIcon, tableListIcon, columnListIcon } from '../htmlbuilder/icons';
import { returnDataSetValue, returnEventWithTopLevelElement } from '../htmlbuilder/domTraversal';
import { folderListIcon, fileListIcon, databaseListIcon, tableListIcon, columnListIcon } from '../flightkit-functions/icons';
import { returnDataSetValue, returnEventWithTopLevelElement } from '../flightkit-functions/domTraversal';
import { BaseComponent } from './extensions/base_component';

export class FlightkitTreeNavigation extends HTMLElement {
Expand Down
File renamed without changes.
File renamed without changes.
144 changes: 144 additions & 0 deletions flightkit/flightkit-functions/sorting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**
* @param {*} jsonArray
* @param {Object} sortDetails ( propertyName: string, direction: 'asc' | 'desc' )
* @returns
*/
export function sortJsonArray(jsonArray, sortDetails) {
if (!sortDetails || sortDetails.length === 0) return jsonArray;

/** need to make a copy, sort is in-place. Else original order would be lost */
const newJsonArray = Object.assign([], jsonArray);

if (Array.isArray(newJsonArray[0])) {
sortGroupedJsonArray(newJsonArray, sortDetails);
}
else {
newJsonArray.sort(sortFunction(sortDetails));
}

return newJsonArray;
};

export const sortGroupedJsonArray = (groupedJsonArray, sortDetails) => {
const result = [];
for (const jsonArray of groupedJsonArray) {
result.push(jsonArray.sort(sortFunction(sortDetails)));
}
return result;
};

function extractNumber(value) {
let testString = value.toString()
let match = testString.match(/^\d+|\d+$/);
return match ? parseInt(match[0]) : null;
}

function isBoolean(value) {
if (typeof value === 'boolean') return true;

if (typeof value === 'string') {
const comparison = value.toLocaleLowerCase();
return comparison === 'true' || comparison === 'false'
}
return false;
}

function getBooleanValue(value) {
if (typeof value === 'boolean') return value;
return value.toLocaleLowerCase() === 'true'
}

function sortFunction(applicableSorters, index = 0) {
return function (a, b) {

const { propertyName, direction } = applicableSorters[index];

/** if it is undefined, just make it a string. */
let valueA = a[propertyName] === null || a[propertyName] === undefined ? '' : a[propertyName];
let valueB = b[propertyName] === null || b[propertyName] === undefined ? '' : b[propertyName];

const dateRegex = /^(\d{1,4}-\d{1,4}-\d{1,4}(T)?)/gim;

const valuesAreDates = (valueA instanceof Date && valueB instanceof Date) || (dateRegex.test(valueA) && dateRegex.test(valueB));
if (valuesAreDates) {
valueA = valueA instanceof Date ? valueA.valueOf() : new Date(Date.parse(valueA));
valueB = valueB instanceof Date ? valueB.valueOf() : new Date(Date.parse(valueB));
}

/** need to check for booleans, else valueA and valueB become NaN */
const valuesAreBooleans = isBoolean(valueA) && isBoolean(valueB);
const valuesAreNumbers = !valuesAreBooleans && !isNaN(valueA) && !isNaN(valueB);

const valueAHasNumber = extractNumber(valueA)
const valueBHasNumber = extractNumber(valueB)

if (valuesAreNumbers) {
valueA = parseFloat(valueA).toPrecision(12);
valueB = parseFloat(valueB).toPrecision(12);
}
else if (valueAHasNumber !== null && valueBHasNumber !== null) {
valueA = parseFloat(valueAHasNumber).toPrecision(12);
valueB = parseFloat(valueBHasNumber).toPrecision(12);
}

if (valuesAreBooleans) {
valueA = getBooleanValue(valueA);
valueB = getBooleanValue(valueB);
}

/** set the values genericly */
let leftHandValue, rightHandValue;

switch (direction) {
case 'descending':
case 'desc': {
leftHandValue = valueB;
rightHandValue = valueA;
break;
}
default: {
leftHandValue = valueA;
rightHandValue = valueB;
break;
}
}

// check if -1 or 1, 0. if 0 then check again.
let comparisonValue = 0;

if (valuesAreBooleans || valuesAreDates || valuesAreNumbers) {
/** Yes this works for all these things. :D */
comparisonValue = leftHandValue - rightHandValue;
}
else {
leftHandValue = leftHandValue.toString().trim().toLowerCase();
rightHandValue = rightHandValue.toString().trim().toLowerCase();

const digitRegex = /\d/gmi;

/** use this for the additional options in localeCompare */
const valuesAreAlphaNumeric = digitRegex.test(valueA) && digitRegex.test(valueB);

if (valuesAreAlphaNumeric) {
comparisonValue = leftHandValue.localeCompare(rightHandValue, undefined, {
numeric: true,
sensitivity: 'base'
});
}
else {
comparisonValue = leftHandValue.localeCompare(rightHandValue);
}
}

const nextSorterIndex = index + 1;

/** the value is the same for this property and we have more sorters then go to the next */
if (comparisonValue === 0 && nextSorterIndex < applicableSorters.length) {
const sortWrapper = sortFunction(applicableSorters, nextSorterIndex);
return sortWrapper(a, b);
}
else {
return comparisonValue;
}
};
}
File renamed without changes.
Loading

0 comments on commit 88dbc15

Please sign in to comment.