First attempt at comma based preference collector

This commit is contained in:
James Cole
2024-04-26 05:31:02 +02:00
parent 565409b486
commit feabfe54f0
5 changed files with 213 additions and 71 deletions

View File

@@ -32,6 +32,7 @@ use FireflyIII\Models\Preference;
use FireflyIII\Transformers\PreferenceTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
@@ -97,6 +98,32 @@ class PreferencesController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
/**
* TODO This endpoint is not documented.
*
* Return a single preference by name.
*/
public function showList(Collection $collection): JsonResponse
{
$manager = $this->getManager();
$count = $collection->count();
$pageSize = $this->parameters->get('limit');
$preferences = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($preferences, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.preferences.show-list').$this->buildParams());
/** @var PreferenceTransformer $transformer */
$transformer = app(PreferenceTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($preferences, $transformer, self::RESOURCE_KEY);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/storePreference

View File

@@ -72,6 +72,12 @@ let index = function () {
page: 1,
filters: {
active: 'both',
name: null,
},
pageOptions: {
groupedAccounts: true,
sortingColumn: sortingColumn,
sortDirection: sortDirection,
},
// available columns:
@@ -131,8 +137,6 @@ let index = function () {
},
},
editors: {},
sortingColumn: sortingColumn,
sortDirection: sortDirection,
accounts: [],
accountRole(roleName) {
@@ -140,12 +144,20 @@ let index = function () {
},
sort(column) {
this.sortingColumn = column;
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
const url = './accounts/' + type + '?column=' + column + '&direction=' + this.sortDirection;
this.pageOptions.sortingColumn = column;
this.pageOptions.sortDirection = this.pageOptions.sortDirection === 'asc' ? 'desc' : 'asc';
const url = './accounts/' + type + '?column=' + column + '&direction=' + this.pageOptions.sortDirection;
window.history.pushState({}, "", url);
// get sort column
// TODO variable name in better place
const columnKey = 'acc_index_' + type + '_sc';
const directionKey = 'acc_index_' + type + '_sd';
setVariable(columnKey, this.pageOptions.sortingColumn);
setVariable(directionKey, this.pageOptions.sortDirection);
this.loadAccounts();
return false;
},
@@ -165,23 +177,53 @@ let index = function () {
}
}
console.log('New settings', newSettings);
setVariable('accts_columns_' + type, newSettings);
setVariable('acc_index_' + type + '_columns', newSettings);
},
init() {
this.notifications.wait.show = true;
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
this.notifications.wait.text = i18next.t('firefly.wait_loading_data');
const key = 'accts_columns_' + type;
// get column preference
// TODO key in better variable
const key = 'acc_index_' + type + '_columns';
const defaultValue = {"drag_and_drop": false};
// get sort column
const columnKey = 'acc_index_' + type + '_sc';
const columnDefault = '';
// get sort direction
const directionKey = 'acc_index_' + type + '_sd';
const directionDefault = '';
getVariable(key, defaultValue).then((response) => {
for (let k in response) {
if (response.hasOwnProperty(k) && this.tableColumns.hasOwnProperty(k)) {
this.tableColumns[k].enabled = response[k] ?? true;
}
}
}).then(() => {
}).
// get sorting preference, and overrule it if is not "" twice
then(() => {
return getVariable(columnKey, columnDefault).then((response) => {
console.log('Sorting column is "' + response + '"');
this.pageOptions.sortingColumn = '' === this.pageOptions.sortingColumn ? response : this.pageOptions.sortingColumn;
})
})
.
// get sorting preference, and overrule it if is not "" twice
then(() => {
return getVariable(directionKey, directionDefault).then((response) => {
console.log('Sorting direction is "' + response + '"');
this.pageOptions.sortDirection = '' === this.pageOptions.sortDirection ? response : this.pageOptions.sortDirection;
})
}).
then(() => {
this.loadAccounts();
});
@@ -230,7 +272,7 @@ let index = function () {
loadAccounts() {
// sort instructions
const sorting = [{column: this.sortingColumn, direction: this.sortDirection}];
const sorting = [{column: this.pageOptions.sortingColumn, direction: this.pageOptions.sortDirection}];
// get start and end from the store:
const start = new Date(window.store.get('start'));

View File

@@ -39,6 +39,10 @@ export function getVariable(name, defaultValue = null) {
return getter.getByName(name).then((response) => {
return Promise.resolve(parseResponse(name, response));
}).catch((error) => {
if('' === defaultValue) {
// do not try to store empty strings.
return Promise.resolve(defaultValue);
}
// preference does not exist (yet).
// POST it and then return it anyway.
let poster = (new Post);

View File

@@ -59,68 +59,103 @@
<td x-show="tableColumns.drag_and_drop.visible && tableColumns.drag_and_drop.enabled">
&nbsp;
</td>
<td x-show="tableColumns.active.visible && tableColumns.active.enabled">
<a href="#" x-on:click.prevent="sort('active')">Active?</a>
<em x-show="sortingColumn === 'active' && sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="sortingColumn === 'active' && sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
</td>
<td x-show="tableColumns.active.visible && tableColumns.active.enabled">&nbsp;</td>
<td x-show="tableColumns.name.visible && tableColumns.name.enabled">
<a href="#" x-on:click.prevent="sort('name')">Name</a>
<em x-show="sortingColumn === 'name' && sortDirection === 'asc'"
class="fa-solid fa-arrow-down-z-a"></em>
<em x-show="sortingColumn === 'name' && sortDirection === 'desc'"
class="fa-solid fa-arrow-up-z-a"></em>
<em>"Filtered"</em>
</td>
<td x-show="tableColumns.type.visible && tableColumns.type.enabled">Type</td>
<td x-show="tableColumns.type.visible && tableColumns.type.enabled">&nbsp;</td>
<td x-show="tableColumns.liability_type.visible && tableColumns.liability_type.enabled">
Liability type
&nbsp;
</td>
<td x-show="tableColumns.liability_direction.visible && tableColumns.liability_direction.enabled">
Liability direction
&nbsp;
</td>
<td x-show="tableColumns.liability_interest.visible && tableColumns.liability_interest.enabled">
Liability interest
&nbsp;
</td>
<td x-show="tableColumns.number.visible && tableColumns.number.enabled">
<a href="#" x-on:click.prevent="sort('iban')">Account number</a>
<em x-show="sortingColumn === 'iban' && sortDirection === 'asc'"
class="fa-solid fa-arrow-down-z-a"></em>
<em x-show="sortingColumn === 'iban' && sortDirection === 'desc'"
class="fa-solid fa-arrow-up-z-a"></em>
&nbsp;
</td>
<td x-show="tableColumns.current_balance.visible && tableColumns.current_balance.enabled">
<a href="#" x-on:click.prevent="sort('balance')">Current balance</a>
<em x-show="sortingColumn === 'balance' && sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="sortingColumn === 'balance' && sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
&nbsp;
</td>
<td x-show="tableColumns.amount_due.visible && tableColumns.amount_due.enabled">
<a href="#" x-on:click.prevent="sort('amount_due')">Amount due</a>
<em x-show="sortingColumn === 'amount_due' && sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="sortingColumn === 'amount_due' && sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
&nbsp;
</td>
<td x-show="tableColumns.last_activity.visible && tableColumns.last_activity.enabled">
<a href="#" x-on:click.prevent="sort('last_activity')">Last activity</a>
<em x-show="sortingColumn === 'last_activity' && sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="sortingColumn === 'last_activity' && sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
&nbsp;
</td>
<td x-show="tableColumns.balance_difference.visible && tableColumns.balance_difference.enabled">
<a href="#" x-on:click.prevent="sort('balance_difference')">Balance
difference</a>
<em x-show="sortingColumn === 'balance_difference' && sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="sortingColumn === 'balance_difference' && sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
&nbsp;
</td>
<td x-show="tableColumns.menu.visible && tableColumns.menu.enabled">&nbsp;</td>
</tr>
<tr>
<th x-show="tableColumns.drag_and_drop.visible && tableColumns.drag_and_drop.enabled">
&nbsp;
</th>
<th x-show="tableColumns.active.visible && tableColumns.active.enabled">
<a href="#" x-on:click.prevent="sort('active')">Active?</a>
<em x-show="pageOptions.sortingColumn === 'active' && pageOptions.sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="pageOptions.sortingColumn === 'active' && pageOptions.sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
</th>
<th x-show="tableColumns.name.visible && tableColumns.name.enabled">
<a href="#" x-on:click.prevent="sort('name')">Name</a>
<em x-show="pageOptions.sortingColumn === 'name' && pageOptions.sortDirection === 'asc'"
class="fa-solid fa-arrow-down-a-z"></em>
<em x-show="pageOptions.sortingColumn === 'name' && pageOptions.sortDirection === 'desc'"
class="fa-solid fa-arrow-down-z-a"></em>
</th>
<th x-show="tableColumns.type.visible && tableColumns.type.enabled">Type</th>
<th x-show="tableColumns.liability_type.visible && tableColumns.liability_type.enabled">
Liability type
</th>
<th x-show="tableColumns.liability_direction.visible && tableColumns.liability_direction.enabled">
Liability direction
</th>
<th x-show="tableColumns.liability_interest.visible && tableColumns.liability_interest.enabled">
Liability interest
</th>
<th x-show="tableColumns.number.visible && tableColumns.number.enabled">
<a href="#" x-on:click.prevent="sort('iban')">Account number</a>
<em x-show="pageOptions.sortingColumn === 'iban' && pageOptions.sortDirection === 'asc'"
class="fa-solid fa-arrow-down-z-a"></em>
<em x-show="pageOptions.sortingColumn === 'iban' && pageOptions.sortDirection === 'desc'"
class="fa-solid fa-arrow-up-z-a"></em>
</th>
<th x-show="tableColumns.current_balance.visible && tableColumns.current_balance.enabled">
<a href="#" x-on:click.prevent="sort('balance')">Current balance</a>
<em x-show="pageOptions.sortingColumn === 'balance' && pageOptions.sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="pageOptions.sortingColumn === 'balance' && pageOptions.sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
</th>
<th x-show="tableColumns.amount_due.visible && tableColumns.amount_due.enabled">
<a href="#" x-on:click.prevent="sort('amount_due')">Amount due</a>
<em x-show="pageOptions.sortingColumn === 'amount_due' && pageOptions.sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="pageOptions.sortingColumn === 'amount_due' && pageOptions.sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
</th>
<th x-show="tableColumns.last_activity.visible && tableColumns.last_activity.enabled">
<a href="#" x-on:click.prevent="sort('last_activity')">Last activity</a>
<em x-show="pageOptions.sortingColumn === 'last_activity' && pageOptions.sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="pageOptions.sortingColumn === 'last_activity' && pageOptions.sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
</th>
<th x-show="tableColumns.balance_difference.visible && tableColumns.balance_difference.enabled">
<a href="#" x-on:click.prevent="sort('balance_difference')">Balance
difference</a>
<em x-show="pageOptions.sortingColumn === 'balance_difference' && pageOptions.sortDirection === 'asc'"
class="fa-solid fa-arrow-down-wide-short"></em>
<em x-show="pageOptions.sortingColumn === 'balance_difference' && pageOptions.sortDirection === 'desc'"
class="fa-solid fa-arrow-up-wide-short"></em>
</th>
<th x-show="tableColumns.menu.visible && tableColumns.menu.enabled">&nbsp;</th>
</tr>
</thead>
<tbody>
<template x-for="(account, index) in accounts" :key="index">
@@ -268,30 +303,63 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<h5>Visible columns</h5>
<div class="mb-2">
<template x-for="(column, key) in tableColumns" :key="key">
<div class="form-check" x-show="column.visible">
<div class="row mb-3">
<label for="inputEmail3" class="col-sm-4 col-form-label">Visible columns</label>
<div class="col-sm-8">
<template x-for="(column, key) in tableColumns" :key="key">
<div class="form-check form-switch form-check-inline" x-show="column.visible">
<label>
<input class="form-check-input" type="checkbox" x-model="column.enabled"
@change="saveColumnSettings"> <span
x-text="$t('list.'+key)"></span>
</label>
</div>
</template>
</div>
</div>
<div class="row mb-3">
<label for="inputEmail3" class="col-sm-4 col-form-label">Active accounts?</label>
<div class="col-sm-8">
<select x-model="filters.active" class="form-control">
<option value="active" label="Active accounts">Active accounts only</option>
<option value="inactive" label="Inactive accounts">Inactive accounts only
</option>
<option value="both" label="Both">All accounts</option>
</select>
<div id="emailHelp" class="form-text">TODO Bla bla bla.</div>
</div>
</div>
<div class="row mb-3">
<label for="inputEmail3" class="col-sm-4 col-form-label">Group accounts</label>
<div class="col-sm-8">
<div class="form-check form-switch">
<label>
<input class="form-check-input" type="checkbox" x-model="column.enabled"
@change="saveColumnSettings"> <span x-text="$t('list.'+key)"></span>
<input class="form-check-input" type="checkbox"
x-model="pageOptions.groupedAccounts"><span>Group accounts</span>
</label>
</div>
</template>
</div>
</div>
<h5>Options</h5>
<div class="mb-2">
<select x-model="filters.active" class="form-control">
<option value="active" label="Active accounts">Active accounts</option>
<option value="inactive" label="Inactive accounts">Inactive accounts</option>
<option value="both" label="Both">Both</option>
</select>
<div class="row mb-3">
<label for="inputEmail3" class="col-sm-4 col-form-label">Show info boxes</label>
<div class="col-sm-8">
<div class="form-check form-switch form-check-inline">
<label>
<input class="form-check-input" type="checkbox"> <span>Box A</span>
</label>
</div>
<div class="form-check form-switch form-check-inline">
<label>
<input class="form-check-input" type="checkbox"> <span>Box B</span>
</label>
</div>
<div class="form-check form-switch form-check-inline">
<label>
<input class="form-check-input" type="checkbox"> <span>Box C</span>
</label>
</div>
</div>
</div>
- Group accounts <br>
- default sort field<br>
- default sort direction<br>
- show info boxes (once they contain info)<br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>

View File

@@ -818,6 +818,7 @@ Route::group(
static function (): void {
Route::get('', ['uses' => 'PreferencesController@index', 'as' => 'index']);
Route::post('', ['uses' => 'PreferencesController@store', 'as' => 'store']);
//Route::get('{preferenceList}', ['uses' => 'PreferencesController@showList', 'as' => 'show-list'])->where('preferenceList', ',+');
Route::get('{preference}', ['uses' => 'PreferencesController@show', 'as' => 'show']);
Route::put('{preference}', ['uses' => 'PreferencesController@update', 'as' => 'update']);
}