This commit is contained in:
James Cole committed 2026-10-11 10:41:45 +02:00
1 parent 0dff6560cf
commit ae9f465f09
3 files changed
+85 -142

No files matched your search

+28 -59
View File
@@ -22,14 +22,14 @@ import "../../boot/bootstrap.js";
import sidebar from "../shared/sidebar.js";
import dates from "../shared/dates.js";
import Alpine from "@alpinejs/csp";
import { getVariable } from "../../store/get-variable.js";
import {getVariable} from "../../store/get-variable.js";
import Put from "../../api/model/account/put.js";
import Get from "../../api/model/account/get.js";
import formatDate from "../../util/format-date.js";
import formatMoney from "../../util/format-money.js";
import i18next from "i18next";
import { addDrag } from "../shared/drag-and-droppable-rows.js";
import { sortableTable, storeFilterAndSort, updateHistory } from "../shared/sortable-tables.js";
import {addDrag} from "../shared/drag-and-droppable-rows.js";
import {initFromLocalStorage, initFromQueryParams, sortableTable, storeFilterAndSort, updateHistory, respondToSortChange} from "../shared/sortable-tables.js";
window.enableDates = true;
@@ -53,81 +53,54 @@ let index = function () {
// functions
formatMoney: formatMoney,
// default settings for sorting
// default settings for sortable tables.
storageKey: "",
defaultSortColumn: "order",
defaultSortDirection: "asc",
// variables necessary for sorting tables.
// variables necessary for sortable tables.
pageNavUrl: "./accounts/",
sortColumn: "order", // used in GET request.
sortDirection: "asc", // used in GET request.
filter: {},
sortColumn: "order", // used in GET request. TODO needs change when doing multiple tables.
sortDirection: "asc", // used in GET request. TODO needs change when doing multiple tables.
filter: {}, // TODO needs change when doing multiple tables.
// sort functions, imported
updateHistory: updateHistory,
initFromLocalStorage: initFromLocalStorage,
initFromQueryParams: initFromQueryParams,
storeFilterAndSort: storeFilterAndSort,
respondToSortChange: respondToSortChange,
sortableTable: null,
init() {
this.sortableTable = new sortableTable("main");
// prepare some variables:
// initialize sortable table.
this.storageKey = "accounts-" + this.objectType + (this.active ? "-active" : "-inactive");
this.defaultSortColumn = "expense" === this.objectType || "revenue" === this.objectType ? "name" : this.defaultSortColumn;
this.initFromLocalStorage();
this.initFromQueryParams();
// create sortable table.
this.sortableTable = new sortableTable("main");
// prepare some variables. Has nothing to do with sortable table.
const address = window.location.href.split("?")[0].split("/");
this.objectType = address[address.length - 1].substring(0, 15);
this.i18next = i18next;
this.anonymous = window.store.get("anonymous");
this.storageKey = "accounts-" + this.objectType + (this.active ? "-active" : "-inactive");
this.pageNavUrl = "./accounts/" + this.objectType;
this.defaultSortColumn =
"expense" === this.objectType || "revenue" === this.objectType ? "name" : this.defaultSortColumn;
this.active = "inactive-accounts" !== address[address.length - 2];
// todo make function:
// grab state from localStorage.
let fromStore = window.store.get(this.storageKey);
if (fromStore) {
this.defaultSortColumn = fromStore.column;
this.defaultSortDirection = fromStore.direction;
this.filter = fromStore.filter;
//console.log('Restore from store:', fromStore);
}
// todo make function
// grab state from URL params.
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
this.page = parseInt(params.page || "1");
this.defaultSortColumn = params.column ?? this.defaultSortColumn;
this.defaultSortDirection = params.direction ?? this.defaultSortDirection;
this.sortColumn = this.defaultSortColumn;
this.sortDirection = this.defaultSortDirection;
console.log("Restore from params:", {
page: this.page,
column: this.defaultSortColumn,
direction: this.defaultSortDirection,
});
// configure sortable table with final result (not filter).
this.sortableTable.sortColumn = this.defaultSortColumn;
this.sortableTable.sortDirection = this.defaultSortDirection;
this.sortableTable.storageKey = this.storageKey;
this.sortableTable.page = this.page;
// initialize sortable table.
this.sortableTable.init(this);
// todo make function
// watch for changes in the sortable table instructions.
document.addEventListener("sortable-table-sort-change", (event) => {
console.log("sortable-table-sort-change", event.detail);
this.sortColumn = event.detail.sortColumn;
this.sortDirection = event.detail.sortDirection;
this.sortableTable.sortColumn = this.sortColumn;
this.sortableTable.sortDirection = this.sortDirection;
this.updateHistory(this.page, this.sortColumn, this.sortDirection, this.filter);
this.storeFilterAndSort(this.storageKey, this.sortColumn, this.sortDirection, this.filter);
this.downloadObjects();
});
document.addEventListener("sortable-table-sort-change", this.respondToSortChange.bind(this));
this.downloadObjects();
// respond to drag and drop.
@@ -140,7 +113,7 @@ let index = function () {
let item = e.detail[i];
if (item.order !== item.currentOrder) {
// PUT new order to system.
new Put().put({ order: item.order }, { id: item.id });
new Put().put({order: item.order}, {id: item.id});
// save new order as current order in the row.
document
@@ -152,6 +125,7 @@ let index = function () {
});
});
},
prepareSumArrays(code) {
let keys = ["sums", "differences", "debts"];
for (let i = 0; i < keys.length; i++) {
@@ -187,15 +161,10 @@ let index = function () {
},
downloadObjects() {
this.sortableTable.loadingNewSort = true;
let sort =
"asc" === this.sortableTable.sortDirection
? this.sortableTable.sortColumn
: "-" + this.sortableTable.sortColumn;
console.log("downloadObjects:", { page: this.page, sort: sort });
let sort = "asc" === this.sortableTable.sortDirection ? this.sortableTable.sortColumn : "-" + this.sortableTable.sortColumn;
let start = window.store.get("start");
let end = window.store.get("end");
this.convertToPrimary = window.store.get("convert_to_primary");
// console.log("Download accounts using", JSON.parse(JSON.stringify(this.filter)));
new Get()
.list({
active: this.active,
@@ -239,12 +208,12 @@ let index = function () {
}
let lastActivity = formatDate(
current.attributes.last_activity,
i18next.t("config.date_time_fns_short", { lng: locale }),
i18next.t("config.date_time_fns_short", {lng: locale}),
locale,
);
let noLastActivity = false;
if ("" === lastActivity) {
if (null === current.attributes.last_activity) {
lastActivity = i18next.t("firefly.never");
noLastActivity = true;
}
@@ -25,10 +25,11 @@ import Alpine from "@alpinejs/csp";
import formatMoney from "../../util/format-money.js";
import formatDate from "../../util/format-date.js";
import i18next from "i18next";
window.enableDates = false;
import { sortableTable, storeFilterAndSort, updateHistory } from "../shared/sortable-tables.js";
import {initFromLocalStorage, initFromQueryParams, sortableTable, storeFilterAndSort, updateHistory, respondToSortChange} from "../shared/sortable-tables.js";
import Get from "../../api/model/category/get.js";
window.enableDates = false;
let index = function () {
return {
categories: [],
@@ -44,79 +45,47 @@ let index = function () {
formatDate: formatDate,
// default settings for sorting
filter: {},
pageNavUrl: "./categories/",
storageKey: "categories-index",
defaultSortColumn: "name",
defaultSortDirection: "asc",
sortColumn: "name", // used in GET request.
sortDirection: "asc", // used in GET request.
filter: {},
// sort functions, imported
updateHistory: updateHistory,
storeFilterAndSort: storeFilterAndSort,
initFromLocalStorage: initFromLocalStorage,
initFromQueryParams: initFromQueryParams,
respondToSortChange: respondToSortChange,
sortableTable: null,
init() {
console.log("init");
this.initFromLocalStorage();
this.initFromQueryParams();
// create sortable table.
this.sortableTable = new sortableTable("main");
// prepare some vars
this.i18next = i18next;
this.anonymous = window.store.get("anonymous");
// todo make function:
// grab state from localStorage.
let fromStore = window.store.get(this.storageKey);
if (fromStore) {
this.defaultSortColumn = fromStore.column;
this.defaultSortDirection = fromStore.direction;
this.filter = fromStore.filter;
//console.log('Restore from store:', fromStore);
}
// todo make function
// grab state from URL params.
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
this.page = parseInt(params.page || "1");
this.defaultSortColumn = params.column ?? this.defaultSortColumn;
this.defaultSortDirection = params.direction ?? this.defaultSortDirection;
this.sortColumn = this.defaultSortColumn;
this.sortDirection = this.defaultSortDirection;
console.log("Restore from params:", {
page: this.page,
column: this.defaultSortColumn,
direction: this.defaultSortDirection,
});
// configure sortable table with final result (not filter).
this.sortableTable.sortColumn = this.defaultSortColumn;
this.sortableTable.sortDirection = this.defaultSortDirection;
this.sortableTable.storageKey = this.storageKey;
this.sortableTable.page = this.page;
// initialize sortable table.
this.sortableTable.init(this);
// todo make function
// watch for changes in the sortable table instructions.
document.addEventListener("sortable-table-sort-change", (event) => {
console.log("sortable-table-sort-change", event.detail);
this.sortColumn = event.detail.sortColumn;
this.sortDirection = event.detail.sortDirection;
this.sortableTable.sortColumn = this.sortColumn;
this.sortableTable.sortDirection = this.sortDirection;
this.updateHistory(this.page, this.sortColumn, this.sortDirection, this.filter);
this.storeFilterAndSort(this.storageKey, this.sortColumn, this.sortDirection, this.filter);
this.downloadObjects();
});
document.addEventListener("sortable-table-sort-change", this.respondToSortChange.bind(this));
this.downloadObjects();
},
downloadObjects() {
this.sortableTable.loadingNewSort = true;
let sort =
"asc" === this.sortableTable.sortDirection
? this.sortableTable.sortColumn
: "-" + this.sortableTable.sortColumn;
let sort = "asc" === this.sortableTable.sortDirection ? this.sortableTable.sortColumn : "-" + this.sortableTable.sortColumn;
this.convertToPrimary = window.store.get("convert_to_primary");
let locale = window.store.get("locale");
new Get()
@@ -133,7 +102,6 @@ let index = function () {
for (let i = 0; i < response.data.data.length; i++) {
if (Object.hasOwn(response.data.data, i)) {
let current = response.data.data[i];
console.log(current);
let lastActivity = i18next.t("firefly.never");
let noLastActivity = true;
if (null !== current.attributes.last_activity) {
@@ -51,19 +51,6 @@ export class sortableTable {
get: (searchParams, prop) => searchParams.get(prop),
});
// add a watch for sortColumn, sortDirection and page
// parent.$watch('sortColumn', (newValue, oldValue) => {
// console.log('sortColumn changed from "' + oldValue + '" to "' + newValue + '"');
// this.updateHeaderClasses();
// });
// parent.$watch('sortDirection', (newValue, oldValue) => {
// console.log('sortDirection changed from "' + oldValue + '" to "' + newValue + '"');
// });
// parent.$watch('page', (newValue, oldValue) => {
// console.log('page changed from "' + oldValue + '" to "' + newValue + '"');
// });
// loop all filtered columns and watch those values.
document
.querySelectorAll('table[data-sort-identifier="' + this.tableId + '"] thead th[data-filter-column]')
.forEach((th) => {
@@ -77,11 +64,9 @@ export class sortableTable {
let storeValue = fromStore ? (fromStore.filter[column] ?? null) : null;
let valueToUse = null !== urlValue ? urlValue : storeValue;
// we do this in the parent because Alpine has the watch function that is needed.
this.parent.$watch("filter." + column, (newValue, oldValue) => {
// parent.filter[column] = newValue;
console.log(
'filter for column "' + column + '" changed from "' + oldValue + '" to "' + newValue + '"',
);
console.log('filter for column "' + column + '" changed from "' + oldValue + '" to "' + newValue + '"',);
this.fireSortChangeEvent();
if ("" !== newValue) {
showSearchBox(th);
@@ -89,20 +74,18 @@ export class sortableTable {
});
if (null !== valueToUse && "" !== valueToUse) {
// console.log('DISABLE refresh');
this.disableRefresh = true;
this.parent.isFiltering = true;
// console.log('Setting initial filter value for column "' + column + '" to "' + valueToUse + '"');
this.parent.filter[column] = valueToUse;
// make sure the button is visible.
setTimeout(() => {
queueMicrotask(() => {
showSearchBox(th);
}, 50);
});
}
});
}
capturePageNavigation() {
console.log("capturePageNavigation()");
// console.log("capturePageNavigation()");
document.querySelectorAll("a.page-link").forEach((el) => {
el.removeEventListener("click", this.handleFunc);
el.addEventListener("click", this.handleFunc);
@@ -120,8 +103,6 @@ export class sortableTable {
this.sortColumn = newColumn;
}
this.fireSortChangeEvent();
//this.updateHistory();
//this.downloadAccounts();
}
handlePageClick(e) {
@@ -135,8 +116,7 @@ export class sortableTable {
this.page = page;
this.parent.page = page;
// some sort of trigger to parent?
// console.warn('Here be push to parent!');
this.parent.updateHistory(page, this.sortColumn, this.sortDirection, this.parent.filter);
this.parent.updateHistory(page, this.sortColumn, this.sortDirection);
this.parent.downloadObjects();
e.preventDefault();
queueMicrotask(() => {
@@ -254,13 +234,9 @@ export class sortableTable {
}
updateHeaderClasses() {
// console.log('updateHeaderClasses()', this.sortColumn, this.sortDirection);
document
.querySelectorAll('table[data-sort-identifier="' + this.tableId + '"] thead th[data-sort-column]')
document.querySelectorAll('table[data-sort-identifier="' + this.tableId + '"] thead th[data-sort-column]')
.forEach((th) => {
// console.log(th);
if (this.sortColumn === th.dataset.sortColumn) {
// th.classList.add('sortable');
th.classList.add("sortable_sorted");
if ("asc" === this.sortDirection) {
th.classList.add("sortable_sorted_asc");
@@ -320,15 +296,45 @@ function objectToQueryString(obj, prefix) {
.join("&");
}
export function updateHistory(page, column, direction, filter) {
export function initFromLocalStorage() {
// grab state from localStorage.
let fromStore = window.store.get(this.storageKey);
if (fromStore) {
this.defaultSortColumn = fromStore.column;
this.defaultSortDirection = fromStore.direction;
this.defaultFilter = fromStore.filter;
}
}
export function initFromQueryParams() {
// grab state from URL params.
// Filter is not part of this because the code does not know which columns are filterable.
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
this.page = parseInt(params.page || "1");
this.defaultSortColumn = params.column ?? this.defaultSortColumn;
this.defaultSortDirection = params.direction ?? this.defaultSortDirection;
}
export function respondToSortChange(event) {
console.log("sortable-table-sort-change", event.detail);
this.sortableTable.sortColumn = event.detail.sortColumn;
this.sortableTable.sortDirection = event.detail.sortDirection;
this.updateHistory(this.page, event.detail.sortColumn, event.detail.sortDirection);
this.storeFilterAndSort(this.storageKey, event.detail.sortColumn, event.detail.sortDirection, this.filter);
this.downloadObjects();
}
export function updateHistory(page, column, direction) {
if (history.pushState) {
let obj = {
page: page,
column: column,
direction: direction,
filter: JSON.parse(JSON.stringify(filter)),
filter: JSON.parse(JSON.stringify(this.filter)),
};
if (filter.length > 0) {
if (this.filter.length > 0) {
this.isFiltering = true;
this.loadingPage = true;
}