249 lines
9.7 KiB
HTML
249 lines
9.7 KiB
HTML
{# vim: set filetype=html :#}
|
|
<!DOCTYPE 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/>.
|
|
-->
|
|
|
|
<html>
|
|
<head lang="en">
|
|
<meta name="author" content="Johannes Randerath" />
|
|
<meta charset="utf-8" />
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
|
<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">
|
|
<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 %}
|
|
</head>
|
|
<body>
|
|
<nav class='navbar navbar-expand-lg bg-body bg-body-tertiary'>
|
|
<div class='container-fluid'>
|
|
<a class='navbar-brand' href='/'>Inventory</a>
|
|
<button class='navbar-toggler' type='button' data-bs-toggle='collapse' data-bs-target='#navbarSupportedContent' aria-controls='navbarSupportedContent' aria-expanded='false' aria-label='Toggle navigation'>
|
|
<span class='navbar-toggler-icon'></span>
|
|
</button>
|
|
<div class='collapse navbar-collapse' id='navbarSupportedContent'>
|
|
<ul class='navbar-nav me-auto mb-2 mb-lg-0'>
|
|
<li class='nav-item dropdown'>
|
|
<a class='nav-link dropdown-toggle' role='button' data-bs-toggle='dropdown' aria-expanded='false'>
|
|
Choose Table
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
{% for tid in tids %}
|
|
<li class="dropdown-option"><a class="nav-link" href="/table/{{ tid }}">{{ tnames[loop.index0] }}</a></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" role="button" data-bs-toggle="modal" data-bs-target="#new_table">
|
|
<i class="bi bi-plus-lg"></i>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" role="button" data-bs-toggle="modal" data-bs-target="#import_table">
|
|
<i class="bi bi-folder2-open"></i>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</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>
|
|
|
|
<!-- 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>
|
|
</html>
|