First version of line edit.

This commit is contained in:
James Cole
2024-03-16 22:00:25 +01:00
parent 845eaed8d7
commit f0fa21dead
10 changed files with 401 additions and 5 deletions

View File

@@ -0,0 +1,36 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "../../../../boot/axios";
import format from "date-fns/format";
export default class Put {
/**
*
* @param identifier
* @param params
* @returns {Promise<AxiosResponse<any>>}
*/
put(identifier, params) {
return api.put('/api/v2/accounts/' + identifier, params);
}
}

View File

@@ -28,6 +28,8 @@ import '@ag-grid-community/styles/ag-grid.css';
import '@ag-grid-community/styles/ag-theme-alpine.css';
import '../../css/grid-ff3-theme.css';
import Get from "../../api/v2/model/account/get.js";
import GenericEditor from "../../support/editable/GenericEditor.js";
import Put from "../../api/v2/model/account/put.js";
// set type from URL
const urlParts = window.location.href.split('/');
@@ -51,6 +53,7 @@ let index = function () {
enabled: true
},
},
editors: {},
sortingColumn: '',
sortDirection: '',
accounts: [],
@@ -75,7 +78,36 @@ let index = function () {
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
this.loadAccounts();
},
submitInlineEdit(e) {
e.preventDefault();
const newTarget = e.currentTarget;
const index = newTarget.dataset.index;
const newValue = document.querySelectorAll('[data-index="'+index+'input"]')[0].value ?? '';
if('' === newValue) {
return;
}
// submit the field in an update thing?
const fieldName = this.editors[index].options.field;
const params = {};
params[fieldName] = newValue;
console.log(params);
console.log('New value is ' + newValue + ' for account #' + this.editors[index].options.id);
(new Put()).put(this.editors[index].options.id, params);
},
cancelInlineEdit(e) {
const newTarget = e.currentTarget;
const index = newTarget.dataset.index;
this.editors[index].cancel();
},
triggerEdit(e) {
const target = e.currentTarget;
const index = target.dataset.index;
// get parent:
this.editors[index] = new GenericEditor();
this.editors[index].setElement(target);
this.editors[index].init();
this.editors[index].replace();
},
loadAccounts() {
this.notifications.wait.show = true;
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
@@ -100,13 +132,13 @@ let index = function () {
currency_code: current.attributes.currency_code,
native_current_balance: current.attributes.native_current_balance,
native_currency_code: current.attributes.native_currency_code,
last_activity: null === current.attributes.last_activity ? '' : format(new Date(current.attributes.last_activity),'P'),
last_activity: null === current.attributes.last_activity ? '' : format(new Date(current.attributes.last_activity), 'P'),
};
this.accounts.push(account);
}
}
this.notifications.wait.show = false;
// add click trigger thing.
});
},
}

View File

@@ -22,7 +22,7 @@ $color-mode-type: media-query;
$link-decoration: none !default;
$font-family-sans-serif: "Roboto", sans-serif;
$danger: #CD5029 !default;
$danger: #CD5029 !default;
$primary: #1E6581 !default;
$success: #64B624 !default;
@@ -43,7 +43,13 @@ $success: #64B624 !default;
// @import "~bootstrap-sass/assets/stylesheets/bootstrap";
// hover buttons
.hidden-edit-button {
cursor: pointer;
}
td:not(:hover) .hidden-edit-button {
visibility: hidden;
}

View File

@@ -0,0 +1,107 @@
/*
* GenericEditor.js
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
export default class GenericEditor {
setElement(element) {
console.log('GenericEditor.setElement()', element);
this.element = element;
this.parent = element.parentElement;
this.options = {};
}
init() {
// grab some options from element itself:
this.options.type = this.element.dataset.type;
this.options.id = this.element.dataset.id;
this.options.value = this.element.dataset.value;
this.options.index = this.element.dataset.index;
this.options.model = this.element.dataset.model;
this.options.field = this.element.dataset.field;
//this.options.field = this.element.dataset.type;
console.log('GenericEditor['+this.options.index+'].init()');
}
replace() {
console.log('GenericEditor['+this.options.index+'].replace()');
// save old HTML in data field (does that work, is it safe?)
this.options.original = this.element.parentElement.innerHTML;
if (this.options.type === 'text') {
this.replaceText();
}
}
replaceText() {
console.log('GenericEditor['+this.options.index+'].replaceText()');
let html = this.formStart() + this.rowStart();
// input field:
html += this.columnStart('7') + this.label() + this.textField() + this.closeDiv();
// add submit button
html += this.columnStart('5') + this.buttonGroup() + this.closeDiv();
// close column and form:
html += this.closeDiv() + this.closeForm();
this.element.parentElement.innerHTML = html;
}
textField() {
return '<input data-index="' + this.options.index + 'input" autocomplete="off" type="text" class="form-control form-control-sm" id="input" name="name" value="' + this.options.value + '" placeholder="' + this.options.value + '" autofocus>';
}
closeDiv() {
return '</div>';
}
closeForm() {
return '</form>';
}
formStart() {
return '<form class="form-inline">';
}
rowStart() {
return '<div class="row">';
}
columnStart(param) {
if ('' === param) {
return '<div class="col">';
}
return '<div class="col-' + param + '">';
}
label() {
return '<label class="sr-only" for="input">Field value</label>';
}
buttonGroup() {
return '<div class="btn-group btn-group-sm" role="group" aria-label="Options">'+
'<button data-index="'+this.options.index+'" type="button" @click="cancelInlineEdit" class="btn btn-danger"><em class="fa-solid fa-xmark text-white"></em></button>'+
'<button data-index="'+this.options.index+'" type="submit" @click="submitInlineEdit" class="btn btn-success"><em class="fa-solid fa-check"></em></button>' +
'</div>';
}
cancel() {
console.log('GenericEditor['+this.options.index+'].cancel()');
console.log(this.element);
console.log(this.parent);
this.parent.innerHTML = this.options.original;
}
submitInlineEdit(e) {
console.log('Submit?');
}
}

View File

@@ -99,6 +99,7 @@
<a :href="'./accounts/show/' + account.id">
<span x-text="account.name"></span>
</a>
<em :data-index="account.id + 'name'" @click="triggerEdit" data-type="text" data-model="Account" :data-id="account.id" data-field="name" :data-value="account.name" class="hidden-edit-button inline-edit-button fa-solid fa-pencil" data-id="1"></em>
</td>
<td>
<span x-text="account.type"></span>
@@ -147,6 +148,8 @@
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/assets/v2/pages/accounts/index.js'])