Lots of refactoring. More, smaller files.

This commit is contained in:
Johannes Randerath
2024-08-29 16:30:19 +02:00
parent 36e0ec3ad1
commit 9dafd7504b
15 changed files with 1052 additions and 760 deletions

View File

@@ -17,96 +17,22 @@
-- 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/>.
-->
<html>
<head lang="en">
<meta name="author" content="Johannes Randerath" />
<meta charset="utf-8" />
<!-- Bootstrap css -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Bootstrap icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Papaparse for csv import -->
<script src="https://unpkg.com/papaparse@latest/papaparse.min.js"></script>
<title>Inventory - {% block pagename %}{% endblock pagename %}</title>
<script>
let todelete = "";
function create_table() {
document.getElementById('create_table').submit().reset();
document.getElementById('dynamic_columns').innerHTML = "";
ncol = 1;
}
function set_modal_target(modal_target) {
document.getElementById('modal_caller').innerHTML = modal_target;
}
function start_ajax(path, listener) {
let req = new XMLHttpRequest();
req.open('GET', path, true);
req.send();
req.onReadyStateChange = function() {
if (req.readyState == XMLHttpRequest.DONE) {
callback();
}
};
};
function import_table() {
console.log("1");
Papa.parse(document.getElementById('import_file').files[0], {
complete: function process(result) {
console.log("2");
let csv = result.data;
let req = new XMLHttpRequest();
req.open("POST", "/table/import", true);
req.responseType = 'blob';
req.setRequestHeader('Content-Type', 'application/json');
let cols = csv[0];
let rows = csv.slice(1);
if (rows[rows.length - 1].length != cols.length) {
rows = rows.slice(0, rows.length-1);
}
req.send(JSON.stringify({
name: document.getElementById('import_name').value,
columns: cols,
rows: rows,
}));
req.onload = function(resp) {
if (this.readyState == 4) {
window.location.href = req.responseURL;
}
};
}
});
};
function add_column() {
ncol += 1;
document.getElementById('dynamic_columns').innerHTML += `
<div class='row mt-3' id='columns'>
<div class='col-auto align-bottom'>
<div class='form-text me-1' id='field_index'>
<strong>${ncol}</strong>
</div>
</div>
<div class='col-auto'>
<input type='text' class='form-control' name='field_names' id='field_name' aria-describedby='field_name_label'>
</div>
<div class='col-auto'>
<select class='form-select' aria-label='data type' name='field_types'>
<option value='0' selected>Text</option>
<option value='1'>Number</option>
</select>
</div>
</div>`;
};
function confirm_delete(form) {
document.getElementById(`form_edit_${form}`).reset();
$('#confirm_delete_modal').modal('show');
document.getElementById('confirm_delete_modal_entity').innerHTML = form;
document.getElementById('confirm_delete_modal_button').onclick = function () {
document.getElementById(`form_delete_${form}`).submit();
}
}
</script>
{% block script %}{% endblock script %}
<script type="text/javascript" src="/js/base.js"></script>
</head>
<body>
<!-- Navbar -->
<nav class='navbar navbar-expand-lg bg-body bg-body-tertiary'>
<div class='container-fluid'>
<a class='navbar-brand' href='/'>Inventory</a>
@@ -141,108 +67,17 @@
</nav>
{% block body %}{% endblock body %}
<!-- Modals -->
<!-- Create new table -->
<div class="modal fade" id="new_table" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">New table</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="create_table" method="post" action="/table/create">
<div class="mb-3">
<label for="new_table_name" class="form-label">Name</label>
<input type="text" class="form-control" name="name" aria-describedby="new_table_name_label">
<div id="new_table_name_label" class="form-text">Name of the new table</div>
</div>
<div class="mb-3">
<div class="row" id="columns">
<div class="col-auto align-bottom me-1">
<label for="field_index" class="form-label">#</label>
<div class="form-text" id="field_index"><strong>1</strong></div>
</div>
<div class="col-auto">
<label for="fields" class="form-label">Column name</label>
<input type="text" class="form-control" id="field_name" aria-describedby="field_name_label" name="field_names">
</div>
<div class="col-auto">
<label for="field_type" class="form-label">Data type</label>
<select class="form-select" aria-label="data type" name="field_types">
<option value="0" selected>Text</option>
<option value="1">Number</option>
</select>
</div>
</div>
</div>
<div id="dynamic_columns">
<!-- Columns added using plus button -->
</div>
</form>
<div class="row justify-content-center mb-3 mt-3">
<div class="col-auto">
<button class="btn btn-primary" type="button" onclick="add_column()"><i class="bi bi-plus-lg"></i></button>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Close</button>
<button class="btn btn-primary" type="button" onclick="create_table()">Create</button>
</div>
</form>
</div>
</div>
</div>
<!-- Base modals -->
{% include "base_modals" %}
{% block modals %}{% endblock modals %}
<!-- Import new table -->
<div class="modal fade" id="import_table" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Import new table</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="/table/import" method="post" id="form_import_table">
<label for="import_name" class="form-label">Name</label>
<input type="text" class="form-control" id="import_name" name="name">
<label for="import_file" class="form-label">File</label>
<input id="import_columns" name="columns" hidden>
<input id="import_rows" name="rows" hidden>
</form>
<input type="file" class="form-control" id="import_file" name="name" accept="text/csv">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Close</button>
<button class="btn btn-primary" type="button" onclick="import_table();">Import</button>
</div>
</div>
</div>
</div>
<!-- Confirm delete -->
<div class="modal fade" id="confirm_delete_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Confirm deletion</h1>
</div>
<div class="modal-body">
<h5>Are you sure you want to delete this <span id="confirm_delete_modal_entity"></span>?</h5>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button"><i class="bi bi-x"></i></button>
<button class="btn btn-danger" type="button" data-bs-dismiss="modal" id="confirm_delete_modal_button"><i class="bi bi-trash3-fill"></i></button>
</div>
</div>
</div>
</div>
{% block more_modals %}{% endblock more_modals %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</body>
{% block script %}{% endblock script %}
<!-- Bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<!-- JQuery -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</body>
</html>

View File

@@ -0,0 +1,120 @@
{# This file is part of inventur.
# inventur is a simple web app using rocket to help maintain inventory data.
# Copyright (C) 2024 Johannes Randerath
#
# 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/>.
#}
{% block modal_new_table %}
<!-- Create new table -->
<div class="modal fade" id="new_table" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">New table</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="form_create_table" method="post" action="/table/create">
<div class="mb-3">
<label for="new_table_name" class="form-label">Name</label>
<input type="text" class="form-control" name="name" aria-describedby="new_table_name_label">
<div id="new_table_name_label" class="form-text">Name of the new table</div>
</div>
<div class="mb-3">
<div class="row" id="columns">
<div class="col-auto align-bottom me-1">
<label for="field_index" class="form-label">#</label>
<div class="form-text" id="field_index"><strong>1</strong></div>
</div>
<div class="col-auto">
<label for="fields" class="form-label">Column name</label>
<input type="text" class="form-control" id="field_name" aria-describedby="field_name_label" name="field_names">
</div>
<div class="col-auto">
<label for="field_type" class="form-label">Data type</label>
<select class="form-select" aria-label="data type" name="field_types">
<option value="0" selected>Text</option>
<option value="1">Number</option>
</select>
</div>
</div>
</div>
<div id="dynamic_columns">
<!-- Columns added using plus button -->
</div>
</form>
<div class="row justify-content-center mb-3 mt-3">
<div class="col-auto">
<button class="btn btn-primary" type="button" onclick="add_column()"><i class="bi bi-plus-lg"></i></button>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Close</button>
<button class="btn btn-primary" type="button" onclick="create_table()">Create</button>
</div>
</div>
</div>
</div>
{% endblock modal_new_table %}
{% block modal_import_table %}
<!-- Import new table -->
<div class="modal fade" id="import_table" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Import new table</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="/table/import" method="post" id="form_import_table">
<label for="import_name" class="form-label">Name</label>
<input type="text" class="form-control" id="import_name" name="name">
<label for="import_file" class="form-label">File</label>
<input id="import_columns" name="columns" hidden>
<input id="import_rows" name="rows" hidden>
</form>
<input type="file" class="form-control" id="import_file" name="name" accept="text/csv">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Close</button>
<button class="btn btn-primary" type="button" onclick="import_table();">Import</button>
</div>
</div>
</div>
</div>
{% endblock modal_import_table %}
{% block modal_confirm_delete %}
<!-- Confirm delete -->
<div class="modal fade" id="confirm_delete_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Confirm deletion</h1>
</div>
<div class="modal-body">
<h5>Are you sure you want to delete this <span id="confirm_delete_modal_entity"></span>?</h5>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button"><i class="bi bi-x"></i></button>
<button class="btn btn-danger" type="button" data-bs-dismiss="modal" id="confirm_delete_modal_button"><i class="bi bi-trash3-fill"></i></button>
</div>
</div>
</div>
</div>
{% endblock modal_confirm_delete %}

View File

@@ -1,24 +1,26 @@
{# vim: set filetype=html: #}
<!-- This file is part of inventur.
-- inventur is a simple web app using rocket to help maintain inventory data.
-- Copyright (C) 2024 Johannes Randerath
--
-- 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/>.
-->
{% extends "base" %}
{# This file is part of inventur.
# inventur is a simple web app using rocket to help maintain inventory data.
# Copyright (C) 2024 Johannes Randerath
#
# 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/>.
#}
{% block body %}
<!-- Accordions of owned tables to get a preview and to choos -->
<div class="accordion" id="my_tables">
{% for tname in tnames %}
{% set clms = columns[loop.index0] %}
@@ -35,6 +37,7 @@
<div class="row justify-content-between">
<div class="col-auto"><h3>{{ tname }}</h3></div><div class="col-auto"><a class="btn btn-primary" href="/table/{{ tid }}">Open</a></div>
</div>
<!-- Preview -->
<table class="table table-striped">
<thead>
<tr>

View File

@@ -1,108 +1,48 @@
{# vim: set filetype=html: #}
<!-- This file is part of inventur.
-- inventur is a simple web app using rocket to help maintain inventory data.
-- Copyright (C) 2024 Johannes Randerath
--
-- 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/>.
-->
{% extends "base" %}
{# This file is part of inventur.
# inventur is a simple web app using rocket to help maintain inventory data.
# Copyright (C) 2024 Johannes Randerath
#
# 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/>.
#}
{% block pagename %}Table{% endblock pagename %}
{% block script %}
<script type="text/javascript">
let ncol = 1;
let edit_mode = false;
let column_names = [{% for col in column_names %} '{{ col }}', {% endfor %}];
let column_types = [{% for col in column_types %} {{ col }}, {% endfor %}];
document.addEventListener("DOMContentLoaded", (event) => {
let rows = document.getElementById("content_table").getElementsByTagName('tbody')[0].rows;
for (let i = 0; i < rows.length; i++)
{
let row = rows[i];
let createClickHandler = function(r)
{
return function()
{
$('#edit_entry_modal').modal('show');
document.getElementById('modal_caller').innerHTML = i+1;
document.getElementById('form_edit_entry_rowpos').value = i+1;
document.getElementById('form_delete_entry_rowpos').value = i+1;
let cells = row.cells;
for (let j = 1; j < cells.length; j++) {
document.getElementById(`form_edit_entry_${j}`).value = cells[j].innerHTML;
}
};
};
row.onclick = createClickHandler(row);
}
});
function toggle_edit_tname() {
let span = document.getElementById('tname');
if (!edit_mode) {
span.innerHTML = `
<div class='row'>
<div class='col-auto ml-1 p-2'>
<form id='form_edit_table' action='/table/name/edit' method='post'>
<input name='tblid' value='{{ tblid }}' hidden />
<input type='text' class='form-control' id='tname_edit' name='new_name' value='{{ tblname }}' />
</form>
</div>
<div class='col-auto mt-0 pt-0 pr-1'>
<div class="btn-group" role="group">
<button class="btn btn-secondary" onclick="toggle_edit_tname();" type="button"><i class="bi bi-x"></i></button>
<button class='btn btn-success' type='button' onclick='edit_tname()'>
<i class='bi bi-check'></i>
</button>
</div>
<button class='btn btn-danger' type="button" onclick='confirm_delete("table");'><i class="bi bi-trash3-fill"></i></button>
</div>
<form id="form_delete_table" action="/table/delete" method="post">
<input value="{{ tblid}}" name="tblid" hidden />
</form>`;
edit_mode = true;
document.getElementById('pencil_button_edit_tname').hidden = true;
} else {
document.getElementById('pencil_button_edit_tname').hidden = false;
span.innerHTML = '{{ tblname }}';
edit_mode = false;
}
}
function edit_tname() {
document.getElementById('form_edit_tname').submit();
toggle_edit_tname();
}
function edit_column(clmn_index) {
document.getElementById('form_edit_column_name').value = column_names[clmn_index];
document.getElementById('form_edit_column_type').value = column_types[clmn_index];
document.getElementById('modal_caller').innerHTML = column_names[clmn_index];
document.getElementById('form_delete_column_idintbl').value = clmn_index + 1;
document.getElementById('form_edit_column_idintbl').value = clmn_index + 1;
}
</script>
{% endblock script %}
{% block body %}
<!-- Table header and editing -->
<div class="row justify-content-between">
<div class="col-auto">
<h1><div class='input-group'><span id="tname">{{ tblname }}</span><button class="btn" type="button" onclick="toggle_edit_tname();" id="pencil_button_edit_tname"><i class="bi bi-pencil"></i></button></div></h1>
<h1>
<div class='input-group'>
<span id="tname">{{ tblname }}</span>
<button class="btn" type="button" onclick="toggle_edit_tname();" id="pencil_button_edit_tname">
<i class="bi bi-pencil"></i>
</button>
</div>
</h1>
</div>
<!-- Search bar -->
<div class="col-auto">
<div class="btn-toolbar mt-2" role="toolbar">
<div class="btn-group me-2">
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#create_entry_modal"><i class="bi bi-plus-lg"></i></button>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#create_entry_modal">
<i class="bi bi-plus-lg"></i>
</button>
</div>
<form method="get" action="/table/{{ tblid }}">
<div class="input-group">
@@ -113,20 +53,27 @@
<button class="btn btn-outline-primary" type="submit"><i class="bi bi-search"></i></button>
<ul class="dropdown-menu">
<select name="search_fields" class="form-select" multiple>
<li><option disabled class="dropdown-header">Search in</option></li>
<option disabled class="dropdown-header">Search in</option>
{% for column in column_names %}
<li><option class="dropdown-option" value="{{ loop.index - 1 }}" {% if (loop.index - 1) in search_fields %}selected{% endif %}>{{ column }}</option></li>
<option class="dropdown-option" value="{{ loop.index - 1 }}" {% if (loop.index - 1) in search_fields %}selected{% endif %}>{{ column }}</option>
{% endfor %}
</select>
</ul>
</div>
</form>
</div>
</div>
</div>
<br>
<!-- Table contents -->
<table id="content_table" class="table table-striped table-hover table-responsive table-bordered mt-2">
<!-- column headings -->
<thead>
<tr>
<!-- Index (#) column -->
<th style="width:7%">
<div class="row justify-content-between">
<div class="col-auto">
@@ -134,8 +81,8 @@
</div>
<div class="col-auto">
<div class="btn-toolbar">
<button class="btn" data-bs-toggle="modal" data-bs-target="#create_column_modal" type="button" onclick=""><i class="bi bi-bookmark-plus"></i></button>
<form method="GET" action="/table/{{ tblid }}">
<button class="btn" data-bs-toggle="modal" data-bs-target="#create_column_modal" type="button"><i class="bi bi-bookmark-plus"></i></button>
<form method="get" action="/table/{{ tblid }}">
<input value="0" name="sort_field" hidden />
<input value="{% if sort_field == 0 %}{{ (sort_dir + 1) % 2}}{% else %}0{% endif %}" name="sort_dir" hidden />
{% if sort_field == 0 and sort_dir == 0 %}
@@ -149,6 +96,7 @@
</div>
</div>
</th>
<!-- individual columns -->
{% for column in column_names %}
<th>
<div class="row justify-content-between">
@@ -175,6 +123,8 @@
{% endfor %}
</tr>
</thead>
<!-- Table rows -->
<tbody>
{% for row in rows %}
<tr>
@@ -186,179 +136,20 @@
</tbody>
</table>
{% endblock body %}
{% block modals %}
<!-- Table specific modals -->
{% include "table_modals" %}
{% endblock modals %}
{% block more_modals %}
<!-- Add new item -->
<div class="modal fade" id="create_entry_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Add entry</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.getElementById('form_edit_entry').reset();"></button>
</div>
<div class="modal-body">
<h5>Cell values:</h5>
<br>
<form id="form_add_entry" action="/row/new" method="post">
<input name="tblid" value="{{ tblid }}" hidden />
{% for column in column_names %}
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="entry_value_{{ column }}" class="form-label" >{{ column }}:</label>
</div>
<div class="col-auto">
<input type="text" class="form-control" name="cells" id="entry_value_{{column}}" />
</div>
</div>
</div>
{% endfor %}
</form>
</div>
<div class="modal-footer">
<div class="container row justify-content-between">
<div class="col-auto">
</div>
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_add_entry').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="document.getElementById('form_add_entry').submit().reset();"><i class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
{% block script %}
<!-- table specific values -->
<script type="text/javascript">
const column_names = [{% for col in column_names %} '{{ col }}', {% endfor %}];
const column_types = [{% for col in column_types %} {{ col }}, {% endfor %}];
const tblid = {{ tblid }};
const tblname = '{{ tblname }}';
</script>
<!-- Table specific functionality -->
<script type="text/javascript" src="/js/table.js"></script>
{% endblock script %}
<!-- Edit entry -->
<div class="modal fade" id="edit_entry_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5"><div class="row"><div class="col-auto">Row <span id="modal_caller"></span></div><div class="col-auto"><i class="bi bi-pencil-fill"></i></div></div></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.getElementById('form_edit_entry').reset();"></button>
</div>
<div class="modal-body">
<form action="/row/edit" method="post" id="form_edit_entry">
<input name="tblid" value="{{ tblid }}" hidden>
<input name="row_pos" id="form_edit_entry_rowpos" hidden>
{% for column in column_names %}
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="form_edit_entry_{{ loop.index }}" class="form-label">{{ column }}</label>
</div>
<div class="col-auto">
<input type="text" class="form-control" name="cells" id="form_edit_entry_{{ loop.index }}" />
</div>
</div>
</div>
{% endfor %}
</form>
</div>
<div class="modal-footer">
<div class="container row justify-content-between">
<div class="col-auto">
<form action="/row/delete" method="post" id="form_delete_entry">
<input name="tblid" value="{{ tblid }}" hidden>
<input id="form_delete_entry_rowpos" name="row_pos" hidden>
<button class="btn btn-danger" data-bs-dismiss="modal" type="button" onclick="confirm_delete('entry');"><i class="bi bi-trash3-fill"></i></button>
</form>
</div>
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_edit_entry').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="document.getElementById('form_edit_entry').submit().reset();"><i class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Add column -->
<div class="modal fade" id="create_column_modal" tabindex="-1" aria-hidden="true" onclick="document.getElementById('form_edit_entry').reset();">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">New column</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="/column/create" method="post" id="form_create_column">
<input name="tblid" value="{{ tblid }}" hidden>
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="form_create_column_name" class="form-label">Name:</label>
<input type="text" class="form-control" name="name" id="form_create_column_name" />
</div>
<div class="col-auto">
<label for="form_create_column_type" class="form-label">Type</label>
<select class="form-select" name="column_type" id="form_create_column_type">
<option value="0">Text</option>
<option value="1">Number</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_create_column').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="document.getElementById('form_create_column').submit().reset();"><i class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
<!-- Edit column -->
<div class="modal fade" id="edit_column_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5"><div class="row"><div class="col-auto"><span id="modal_caller"></span></div><div class="col-auto"><i class="bi bi-pencil-fill"></i></div></div></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="/column/edit" method="post" id="form_edit_column">
<input name="tblid" value="{{ tblid }}" hidden>
<input name="id_in_table" id="form_edit_column_idintbl" hidden>
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="form_edit_column_name" class="form-label">Name:</label>
<input type="text" class="form-control" name="name" id="form_edit_column_name" />
</div>
<div class="col-auto">
<label for="form_edit_column_type" class="form-label">Type</label>
<select class="form-select" name="column_type" id="form_edit_column_type">
<option value="0">Text</option>
<option value="1">Number</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<div class="container row justify-content-between">
<div class="col-auto">
<form action="/column/delete" method="post" id="form_delete_column">
<input name="id_in_table" id="form_delete_column_idintbl" hidden>
<input name="tblid" value="{{ tblid }}" hidden>
<button class="btn btn-danger" data-bs-dismiss="modal" type="button" onclick="confirm_delete('column');"><i class="bi bi-trash3-fill"></i></button>
</form>
</div>
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_edit_column').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="document.getElementById('form_edit_column').submit().reset();"><i class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock more_modals %}

View File

@@ -0,0 +1,197 @@
{# This file is part of inventur.
# inventur is a simple web app using rocket to help maintain inventory data.
# Copyright (C) 2024 Johannes Randerath
#
# 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/>.
#}
{% block modal_new_entry %}
<!-- Add new item -->
<div class="modal fade" id="create_entry_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Add entry</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.getElementById('form_create_entry').reset();"></button>
</div>
<div class="modal-body">
<h5>Cell values:</h5>
<br>
<form id="form_create_entry" action="/row/new" method="post">
<input name="tblid" value="{{ tblid }}" hidden />
{% for column in column_names %}
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="entry_value_{{ column }}" class="form-label" >{{ column }}:</label>
</div>
<div class="col-auto">
<input type="text" class="form-control" name="cells" id="entry_value_{{column}}" />
</div>
</div>
</div>
{% endfor %}
</form>
</div>
<div class="modal-footer">
<div class="container row justify-content-between">
<div class="col-auto">
</div>
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_create_entry').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="document.getElementById('form_create_entry').submit().reset();"><i class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock modal_new_entry %}
{% block modal_edit_entry %}
<!-- Edit entry -->
<div class="modal fade" id="edit_entry_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5"><div class="row"><div class="col-auto">Row <span id="modal_caller"></span></div><div class="col-auto"><i class="bi bi-pencil-fill"></i></div></div></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.getElementById('form_edit_entry').reset();"></button>
</div>
<div class="modal-body">
<form action="/row/edit" method="post" id="form_edit_entry">
<input name="tblid" value="{{ tblid }}" hidden>
<input name="row_pos" id="form_edit_entry_rowpos" hidden>
{% for column in column_names %}
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="form_edit_entry_{{ loop.index }}" class="form-label">{{ column }}</label>
</div>
<div class="col-auto">
<input type="text" class="form-control" name="cells" id="form_edit_entry_{{ loop.index }}" />
</div>
</div>
</div>
{% endfor %}
</form>
</div>
<div class="modal-footer">
<div class="container row justify-content-between">
<div class="col-auto">
<form action="/row/delete" method="post" id="form_delete_entry">
<input name="tblid" value="{{ tblid }}" hidden>
<input id="form_delete_entry_rowpos" name="row_pos" hidden>
<button class="btn btn-danger" data-bs-dismiss="modal" type="button" onclick="confirm_delete('entry');"><i class="bi bi-trash3-fill"></i></button>
</form>
</div>
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_edit_entry').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="submit_and_reset('form_edit_entry');" class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock modal_edit_entry %}
{% block modal_new_column %}
<!-- Add column -->
<div class="modal fade" id="create_column_modal" tabindex="-1" aria-hidden="true" onclick="document.getElementById('form_create_column').reset();">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">New column</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="/column/create" method="post" id="form_create_column">
<input name="tblid" value="{{ tblid }}" hidden>
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="form_create_column_name" class="form-label">Name:</label>
<input type="text" class="form-control" name="name" id="form_create_column_name" />
</div>
<div class="col-auto">
<label for="form_create_column_type" class="form-label">Type</label>
<select class="form-select" name="column_type" id="form_create_column_type">
<option value="0">Text</option>
<option value="1">Number</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_create_column').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="submit_and_reset('form_create_column');"><i class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
{% endblock modal_new_column %}
{% block modal_edit_column %}
<!-- Edit column -->
<div class="modal fade" id="edit_column_modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5"><div class="row"><div class="col-auto"><span id="modal_caller"></span></div><div class="col-auto"><i class="bi bi-pencil-fill"></i></div></div></h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="/column/edit" method="post" id="form_edit_column">
<input name="tblid" value="{{ tblid }}" hidden>
<input name="id_in_table" id="form_edit_column_idintbl" hidden>
<div class="mb-3">
<div class="row">
<div class="col-auto">
<label for="form_edit_column_name" class="form-label">Name:</label>
<input type="text" class="form-control" name="name" id="form_edit_column_name" />
</div>
<div class="col-auto">
<label for="form_edit_column_type" class="form-label">Type</label>
<select class="form-select" name="column_type" id="form_edit_column_type">
<option value="0">Text</option>
<option value="1">Number</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<div class="container row justify-content-between">
<div class="col-auto">
<form action="/column/delete" method="post" id="form_delete_column">
<input name="id_in_table" id="form_delete_column_idintbl" hidden>
<input name="tblid" value="{{ tblid }}" hidden>
<button class="btn btn-danger" data-bs-dismiss="modal" type="button" onclick="confirm_delete('column');"><i class="bi bi-trash3-fill"></i></button>
</form>
</div>
<div class="col-auto">
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_edit_column').reset();"><i class="bi bi-x"></i></button>
<button class="btn btn-primary" type="button" onclick="submit_and_reset('form_edit_column');"><i class="bi bi-check-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock modal_edit_column %}