Webgui: filter and pagination working

This commit is contained in:
2026-07-15 19:42:55 +02:00
parent 2177834b39
commit a183a4725f
33 changed files with 2088 additions and 750 deletions
+2
View File
@@ -1,3 +1,5 @@
*~
__pycache__/
compare_*
*.txt
+9 -4
View File
@@ -1,4 +1,4 @@
YMS Installation
Yacht Management Software (YMS) Installation
1. Install requirements
@@ -6,12 +6,12 @@ YMS Installation
- MariaDB
- Python 3
- python3-bcrypt
- python3-mysqldb
- optional
- gettext
- mupdf-tools for extended pdf file management
1.2 Native GUI
- python3-mysqldb
- Python GTK3
- python3-gi
- gir1.2-gtk-3.0
@@ -29,7 +29,12 @@ the privileges for accessing and modifying it.
CREATE DATABASE yms;
Create database-user for application with minimum necessary rights.
Create system user for native gui.
CREATE USER 'ymssys'@'localhost' IDENTIFIED BY '********';
GRANT SELECT, INSERT, UPDATE, DELETE ON yms.* TO 'ymssys'@'localhost';
Create database-user for web application with minimum necessary rights.
CREATE USER 'ymsweb'@'localhost' IDENTIFIED BY '********';
GRANT SELECT, INSERT, UPDATE, DELETE ON yms.* TO 'ymsweb'@'localhost';
@@ -72,7 +77,7 @@ file.
5.2. Create and edit webgui config file
Rename sample configfile config.php-sample:
Rename sample configfile config.inc-sample:
mv config.inc-sample config.inc
+5
View File
@@ -6,3 +6,8 @@ Use at your own risk!
If inserting a new user you have also to insert a setting value
to assign boat 0.
To set your own passwords via console there is a helper script
ymspass.py
Use it to get an SQL-statement for changing passwords.
+95 -52
View File
@@ -3,6 +3,11 @@
/* MariaDB Scheme
Version: 1 */
/* User
userid is signed because nevative values are required for settings
The user table must not be writeable by the webgui user!
*/
CREATE TABLE user (
userid smallint(6) NOT NULL AUTO_INCREMENT,
login varchar(20) NOT NULL,
@@ -13,7 +18,7 @@ CREATE TABLE user (
language char(2) NOT NULL DEFAULT 'en',
PRIMARY KEY (userid),
UNIQUE INDEX ix_login (login)
);
) ENGINE=InnoDB;
/* Settings
E.g. the currently selected boat. Users logged in via the web are allowed
@@ -36,11 +41,12 @@ CREATE TABLE settings (
valstr varchar(200) DEFAULT NULL,
valint int(10) DEFAULT NULL,
PRIMARY KEY (userid, sno)
);
) ENGINE=InnoDB;
/* ddid=0 is list of lists, not editable
flags: fixed=not deletable, value not changeable
locked=not editable */
locked=not editable
*/
CREATE TABLE dropdown (
ddid tinyint(3) UNSIGNED NOT NULL,
ddval tinyint(3) NOT NULL,
@@ -50,13 +56,14 @@ CREATE TABLE dropdown (
color char(6) DEFAULT NULL,
flags enum('locked','fixed') DEFAULT NULL,
PRIMARY KEY (ddid, ddval)
);
) ENGINE=InnoDB;
CREATE TABLE vessel (
vid smallint(10) NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL AUTO_INCREMENT,
vtype enum('mono','cat','tri') NOT NULL DEFAULT 'mono',
vesselname varchar(40) NOT NULL,
model varchar(20) DEFAULT NULL,
shipyard smallint(6) DEFAULT NULL,
loa float(4,2) UNSIGNED DEFAULT NULL,
lwl float(4,2) UNSIGNED DEFAULT NULL,
beam float(4,2) UNSIGNED DEFAULT NULL,
@@ -69,10 +76,10 @@ CREATE TABLE vessel (
shapefile varchar(40) DEFAULT NULL,
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (vid)
);
) ENGINE=InnoDB;
CREATE TABLE storage (
sid smallint(6) NOT NULL AUTO_INCREMENT,
sid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
sname varchar(40) NOT NULL,
stype tinyint(3) NOT NULL DEFAULT 0,
@@ -88,34 +95,31 @@ CREATE TABLE storage (
color char(6) DEFAULT NULL,
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (sid)
);
/* TODO define cabins? CREATE TABLE cabin ... */
) ENGINE=InnoDB;
CREATE TABLE tag (
tagid smallint(6) NOT NULL AUTO_INCREMENT,
tagid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
tagname varchar(20) NOT NULL,
color char(6) DEFAULT NULL,
description varchar(80) DEFAULT NULL,
PRIMARY KEY (tagid),
UNIQUE INDEX ix_tagname (tagname)
);
) ENGINE=InnoDB;
CREATE TABLE tagref (
tagid smallint(6) NOT NULL,
objid smallint(6) NOT NULL,
tagid smallint(6) UNSIGNED NOT NULL,
objid int(10) UNSIGNED NOT NULL,
objtype enum('equip','inv','prov','doc', 'proj', 'task', 'maint') NOT NULL,
PRIMARY KEY (tagid, objid, objtype)
);
) ENGINE=InnoDB;
/* TODO Boxes can be nested via parent
TODO boxsize: (LxWxH) in cm? */
CREATE TABLE box (
boxid smallint(6) NOT NULL AUTO_INCREMENT,
sid smallint(6) NOT NULL,
boxid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
sid smallint(6) UNSIGNED NOT NULL,
boxtype tinyint(3) DEFAULT NULL,
parent int(10) DEFAULT NULL,
parent smallint(6) UNSIGNED DEFAULT NULL,
label varchar(20) DEFAULT NULL,
color char(6) DEFAULT NULL,
content varchar(60) DEFAULT NULL,
@@ -123,33 +127,33 @@ CREATE TABLE box (
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (boxid),
INDEX ix_label (label)
);
) ENGINE=InnoDB;
CREATE TABLE equipment (
eid smallint(6) NOT NULL AUTO_INCREMENT,
eid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
ename varchar(80) NOT NULL,
shortname varchar(20) DEFAULT NULL,
model varchar(40),
ecat tinyint(3) DEFAULT NULL,
serial varchar(30),
serial varchar(30) DEFAULT NULL,
supplier smallint(6) DEFAULT NULL,
manufacturer smallint(6) DEFAULT NULL, // -3: original; -4: own built
manufacturer smallint(6) DEFAULT NULL, -- -1: unknown; -3: own built
purchdate date DEFAULT NULL,
price decimal(12,2) DEFAULT NULL,
weight float(5,2) UNSIGNED DEFAULT NULL,
remarks varchar(150) DEFAULT NULL,
flags set('ordered','removed','deleted') DEFAULT NULL,
PRIMARY KEY(eid)
);
) ENGINE=InnoDB;
CREATE TABLE inventory (
invid int(10) NOT NULL AUTO_INCREMENT,
invid int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
invname varchar(80) NOT NULL,
conttype enum('storage','box') NOT NULL DEFAULT 'storage',
sid smallint(6) NOT NULL DEFAULT 1,
boxid smallint(6) NOT NULL DEFAULT 1,
eid smallint(6) DEFAULT NULL,
sid smallint(6) UNSIGNED NOT NULL DEFAULT 1,
boxid smallint(6) UNSIGNED NOT NULL DEFAULT 1,
eid smallint(6) UNSIGNED DEFAULT NULL,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
weight float(5,2) UNSIGNED DEFAULT NULL,
price decimal(12,2) DEFAULT NULL,
@@ -158,30 +162,64 @@ CREATE TABLE inventory (
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (invid),
INDEX ix_invname (invname)
);
) ENGINE=InnoDB;
CREATE TABLE cable (
cableid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
cablename varchar(80) NOT NULL,
cabletype varchar(40) DEFAULT NULL, -- e.g. H07RN-F
length float(5,2) UNSIGNED NOT NULL DEFAULT 0, -- total length in m
conductors TINYINT(3) UNSIGNED NOT NULL DEFAULT 1,
diameter float(5,2) UNSIGNED DEFAULT NULL, -- outer diameter in mm
xsection float(5,2) UNSIGNED DEFAULT NULL, -- cross section in mm²
weight float(5,2) UNSIGNED DEFAULT NULL, -- kg/meter
color char(6) DEFAULT NULL,
supplier smallint(6) DEFAULT NULL,
manufacturer smallint(6) DEFAULT NULL,
cablecond enum('unknown','new','good','normal','bad','repairable','defect') NOT NULL default 'unknown',
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (cableid),
INDEX ix_cablename (vid, cablename)
) ENGINE=InnoDB;
CREATE table fuse (
fuseid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
fnumber smallint(6) NOT NULL,
ftype tinyint(3) DEFAULT 0, -- from dropdown id 7
current float(5,2) UNSIGNED NOT NULL, -- in A
cableid smallint(6) UNSIGNED DEFAULT NULL,
eid smallint(6) UNSIGNED DEFAULT NULL,
location tinyint(3) DEFAULT 0, -- from dropdown id 10
description varchar(60) DEFAULT NULL,
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (fuseid),
UNIQUE INDEX ix_fusenumber (vid, fnumber)
) ENGINE=InnoDB;
CREATE TABLE measurement (
mid smallint(6) NOT NULL AUTO_INCREMENT,
mtype enum('generic','cable','fuse') NOT NULL default 'generic',
mname varchar(80) NOT NULL,
vid smallint(6) NOT NULL DEFAULT 1,
nval tinyint(1) UNSIGNED NOT NULL DEFAULT 1,
val1 int(10) NOT NULL,
val2 int(10) NOT NULL,
val3 int(10) NOT NULL,
val2 int(10) DEFAULT NULL,
val3 int(10) DEFAULT NULL,
unit tinyint(3) NOT NULL DEFAULT 1,
accuracy enum('unknown','precise','normal','rough','estimated') NOT NULL DEFAULT 'unknown',
mdate date DEFAULT NULL,
note varchar(80) DEFAULT NULL,
eid smallint(6) DEFAULT NULL,
eid smallint(6) UNSIGNED DEFAULT NULL,
PRIMARY KEY (mid)
);
) ENGINE=InnoDB;
CREATE TABLE provisions (
provid int(10) NOT NULL AUTO_INCREMENT,
provname varchar(40) NOT NULL,
provcat tinyint(3) DEFAULT NULL,
sid smallint(6) DEFAULT NULL,
boxid smallint(6) NOT NULL DEFAULT 1,
sid smallint(6) UNSIGNED DEFAULT NULL,
boxid smallint(6) UNSIGNED NOT NULL DEFAULT 1,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
weight float(5,2) UNSIGNED DEFAULT NULL,
weight_net float(5,2) UNSIGNED DEFAULT NULL,
@@ -189,8 +227,13 @@ CREATE TABLE provisions (
storedate date DEFAULT CURRENT_DATE,
shelflife date DEFAULT NULL,
PRIMARY KEY (provid)
);
) ENGINE=InnoDB;
/* TODO
- distinction between
docdate - e.g. invoicedate
doctime -> uploadtime
*/
CREATE TABLE document (
docid smallint(6) NOT NULL AUTO_INCREMENT,
doctype enum('generic','manual','invoice','drawing','picture') NOT NULL DEFAULT 'generic',
@@ -200,6 +243,7 @@ CREATE TABLE document (
hash varchar(32) NOT NULL,
docsize int(10) unsigned NOT NULL,
doctime datetime DEFAULT NULL,
docdate date DEFAULT NULL, -- e.g. invoice date
title varchar(40) DEFAULT NULL,
pages smallint(6) unsigned NOT NULL DEFAULT 1,
remarks varchar(150) DEFAULT NULL,
@@ -224,10 +268,10 @@ CREATE TABLE docref (
CREATE TABLE company (
compid smallint(6) NOT NULL AUTO_INCREMENT,
compname varchar(60) NOT NULL,
comptype tinyint(3) NOT NULL DEFAULT 1,
comptype2 tinyint(3) DEFAULT NULL,
comptype tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
comptype2 tinyint(3) UNSIGNED DEFAULT NULL,
shortname varchar(20) DEFAULT NULL,
street varchar(30),
street varchar(40),
zip varchar(10),
city varchar(30),
country varchar(30),
@@ -240,20 +284,19 @@ CREATE TABLE company (
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (compid),
UNIQUE INDEX ix_compname (compname, comptype)
);
) ENGINE=InnoDB;
/* TODO optional field: plan date, target date, completion date */
CREATE TABLE maintenance (
maintid int(10) NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
eid smallint(6) DEFAULT NULL,
eid smallint(6) UNSIGNED DEFAULT NULL,
series smallint(6) DEFAULT NULL,
activities varchar(40) NOT NULL,
remarks varchar(150) DEFAULT NULL,
maintstate enum('new','planned','ongoing','done') NOT NULL DEFAULT 'new',
PRIMARY KEY (maintid)
);
) ENGINE=InnoDB;
/* TODO? time recording */
@@ -269,7 +312,7 @@ CREATE TABLE project (
remarks varchar(150) DEFAULT NULL,
projstate enum('new','plan','ongoing','paused','finished') NOT NULL DEFAULT 'new',
PRIMARY KEY (projid)
);
) ENGINE=InnoDB;
CREATE TABLE task (
taskid int(10) NOT NULL AUTO_INCREMENT,
@@ -286,16 +329,16 @@ CREATE TABLE task (
responsible smallint(6) NOT NULL,
/* TODO executed_by : company or user? or both? */
PRIMARY KEY (taskid)
);
) ENGINE=InnoDB;
// Notes can be assigned to tasks,maintenances and equipment
/* Notes can be assigned to tasks,maintenances and equipment */
CREATE TABLE note (
noteid int(10) NOT NULL AUTO_INCREMENT,
notetype enum('task','maint','equip') NOT NULL DEFAULT 'task',
refid smallint(6) NOT NULL,
annotation text NOT NULL,
PRIMARY KEY (noteid)
);
) ENGINE=InnoDB;
CREATE TABLE checklist (
clid smallint(6) NOT NULL AUTO_INCREMENT,
@@ -303,7 +346,7 @@ CREATE TABLE checklist (
parent smallint(6) DEFAULT NULL,
clstate enum('new','open','closed') NOT NULL DEFAULT 'new',
PRIMARY KEY (clid)
);
) ENGINE=InnoDB;
CREATE TABLE checkitem (
checkid int(10) NOT NULL AUTO_INCREMENT,
@@ -311,17 +354,17 @@ CREATE TABLE checkitem (
groupid tinyint(3) DEFAULT NULL,
checkresult enum('unchecked','checked','unused') NOT NULL DEFAULT 'unused',
PRIMARY KEY (checkid)
);
) ENGINE=InnoDB;
CREATE TABLE checkref (
clid smallint(6) NOT NULL,
checkid int(10) NOT NULL,
sort smallint(6) DEFAULT NULL,
PRIMARY KEY (clid, checkid)
);
) ENGINE=InnoDB;
CREATE TABLE checkgroup (
groupid int(10) NOT NULL,
title varchar(30) NOT NULL,
PRIMARY KEY (groupid)
);
) ENGINE=InnoDB;
+9 -2
View File
@@ -36,6 +36,8 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 108, 'company sorting order'),
(-1, 109, 'document sorting order'),
(-1, 110, 'tag sorting order'),
(-1, 111, 'cable sorting order'),
(-1, 112, 'fuse sorting order'),
(-1, 200, 'equipment filter json'),
(-1, 201, 'inventory filter json'),
(-1, 202, 'provision filter json'),
@@ -46,7 +48,9 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 207, 'measurement filter json'),
(-1, 208, 'company filter json'),
(-1, 209, 'document filter json'),
(-1, 210, 'tag filter json');
(-1, 210, 'tag filter json'),
(-1, 211, 'cable filter json'),
(-1, 212, 'fuse filter json');
/* Liste der Listen wird immer benötigt */
INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
@@ -59,11 +63,14 @@ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
(0, 6, 'Provianteinheiten'),
(0, 7, 'Sicherungstypen'),
(0, 8, 'Einheiten'),
(0, 9, 'Kistentypen');
(0, 9, 'Kistentypen'),
(0, 10, 'Sicherungsblöcke'), -- fuse locations
(0, 11, 'Kabeltypen');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
(2, 1, 'Lieferant', 'fixed'),
(2, 2, 'Hersteller', 'fixed'),
(2, 3, 'Werft', 'fixed'), -- to store yacht manufacturer
(2, 9, 'Sonstiges', 'fixed');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
+19 -5
View File
@@ -13,12 +13,18 @@ INSERT INTO user (userid, login, pass, displayname, role) VALUES
INSERT INTO settings (userid, sno, valint) VALUES
(0, 0, 1), -- Database schema version
(0, 1, 0), -- No vessel for SYSTEM
(1, 1, 0); -- No vessel for captain
(0, 1, 0), -- No vessel assignment to SYSTEM
(1, 1, 0), -- No vessel assignment to user "captain"
(0, 20, 1280), -- Image width limit
(0, 21, 1024); -- Image height limit
/* setting descriptions */
INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 1, 'vessel id'),
(-1, 2, 'date format'),
(-1, 10, 'rows in table'),
(-1, 20, 'maximum image width'),
(-1, 21, 'maximum image height'),
(-1, 100, 'equipment sorting order'),
(-1, 101, 'inventory sorting order'),
(-1, 102, 'provision sorting order'),
@@ -30,6 +36,8 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 108, 'company sorting order'),
(-1, 109, 'document sorting order'),
(-1, 110, 'tag sorting order'),
(-1, 111, 'cable sorting order'),
(-1, 112, 'fuse sorting order'),
(-1, 200, 'equipment filter json'),
(-1, 201, 'inventory filter json'),
(-1, 202, 'provision filter json'),
@@ -40,9 +48,11 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 207, 'measurement filter json'),
(-1, 208, 'company filter json'),
(-1, 209, 'document filter json'),
(-1, 210, 'tag filter json');
(-1, 210, 'tag filter json'),
(-1, 211, 'cable filter json'),
(-1, 212, 'fuse filter json');
/* list of lists needed */
/* list of lists always needed */
INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
(0, 0, 'list of lists'),
(0, 1, 'hull type'),
@@ -53,12 +63,16 @@ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
(0, 6, 'provision unit'),
(0, 7, 'fuse type'),
(0, 8 , 'unit');
(0, 9, 'box types'),
(0.10, 'fuse blocks'),
(0,11, 'cable types');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
(2, 1, 'Supplier', 'fixed'),
(2, 2, 'Manufacturer', 'fixed'),
(2, 3, 'Shipyard', fixed),
(2, 9, 'Generic', 'fixed');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
(3, 0, 'Generic', 'fixed'),
(3, 0, 'Generic storage', 'fixed'),
(3, 1, 'Tank', 'fixed');
+2
View File
@@ -6,4 +6,6 @@ mv /var/www/html/config.inc-sample /var/www/html/config.inc
chmod 640 /var/www/html/config.inc
chgrp www-data /var/www/html/config.inc
rm /var/www/html/index.html
rm /var/www/html/README
rm /var/www/html/TODO
rm /var/www/html/locale/de_DE.po
+305
View File
@@ -0,0 +1,305 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
require 'lib/gpc.inc';
$pagetitle = _('Cables');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_cabletype = db_get_options(11);
$opt_cablecond = db_load_enum('cable', 'cablecond', true, true);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'add': $action = ACT_ADD; break;
case 'view': $action = ACT_VIEW; break;
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 211);
$action = ACT_DEFAULT;
break;
case 'freset':
db_clear_filter(211);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':cablename'] = gpc_get_string($_POST, 'cablename');
$p[':length'] = gpc_get_float($_POST, 'length');
$p[':conductors'] = gpc_get_int($_POST, 'conductors');
$p[':xsection'] = gpc_get_float($_POST, 'xsection');
$id = db_exec_insert('cable', $p);
$action = ACT_VIEW;
break;
case 'update':
$p[':cableid'] = $id;
$p[':cablename'] = gpc_get_string($_POST, 'cablename');
$p[':cabletype'] = gpc_get_int($_POST, 'cabletype');
$p[':length'] = gpc_get_float($_POST, 'length');
$p[':conductors'] = gpc_get_int($_POST, 'conductors');
$p[':xsection'] = gpc_get_float($_POST, 'xsection');
$p[':diameter'] = gpc_get_float($_POST, 'diameter');
$p[':weight'] = gpc_get_float($_POST, 'weight');
$p[':color'] = gpc_get_color($_POST, 'color');
$p[':cablecond'] = gpc_get_string($_POST, 'cablecond');
$p[':remarks'] = gpc_get_string($_POST, 'remarks');
db_exec_update('cable', $p, 'cableid');
$action = ACT_VIEW;
break;
case 'delete':
// Security token needed!
if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
$g_error->Add(_('Delete prohibited, invalid security token!'));
$action = ACT_VIEW;
break;
}
// TODO
$action = ACT_DEFAULT;
break;
default:
$g_error->Add(sprintf(_('Unknown function!'), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// load filter from db
$flt = db_get_filter($user->id, 211);
echo "<h1>$pagetitle</h1>\n";
// Filter
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body d-flex flex-wrap gap-3">
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" class="form-control" name="flt_txt" maxlength="30" value="<?=$flt->txt ?? ''?>">
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div>
</form>
<?php
$sql = "SELECT cableid, cablename, conductors, length, xsection, color, cablecond "
. "FROM cable "
. "ORDER BY cablename";
$sth = $pdo->query($sql);
$res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', _('Cable'), "</th>";
echo '<th>', _('Name'), "</th>";
echo '<th>', _('Conductors'), "</th>";
echo '<th>', _('Length'), "</th>";
echo '<th>', _('Cross section'), "</th>";
echo '<th>', _('Color'), "</th>";
echo '<th>', _('Condition'), "</th>";
echo "<th></th>";
echo "</tr>\n";
echo "</thead>\n";
$i = 0;
foreach ($res as $row) {
$i++; // record number
echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['cableid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", $row['cableid'], "</td>\n";
echo "<td>", $row['cablename'], "</td>\n";
echo "<td>", $row['conductors'], "</td>\n";
echo "<td>", $row['length'], "m</td>\n";
echo "<td>", $row['xsection'], "mm²</td>\n";
echo "<td>", format_color($row['color']), "</td>\n";
echo "<td>", $row['condition'], "</td>\n";
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['cableid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n";
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
echo '<h2>', _('Add Cable'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<div class="mb-3">
<label for="tagname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="cablename" name="cablename" required autofocus>
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Length, m')?></label>
<input type="text" class="form-control" id="length" name="length">
</div>
<?php
form_create_select('cabletype', _('Type'), $g_opt_none + $opt_cabletype);
?>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Conductors')?></label>
<input type="text" class="form-control" id="conductors" name="conductors">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Cross section, mm²')?></label>
<input type="text" class="form-control" id="xsection" name="xsection">
</div>
<?php
form_new_buttons($g_scriptname);
echo "</form>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT cablename, cabletype, length, conductors, diameter, xsection,"
. " weight, color, supplier, manufacturer, cablecond, remarks "
. "FROM cable "
. "WHERE cableid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$cable = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('View cable'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Cable'),"</th><td>", $cable->cablename, "</td></tr>\n";
echo '<tr><th>', _('Type'),"</th><td>", $opt_cabletype[$cable->cabletype], "</td></tr>\n";
echo '<tr><th>', _('Length'),"</th><td>", format_float($cable->length, 1, 'm'), "</td></tr>\n";
echo '<tr><th>', _('Conductors'),"</th><td>", $cable->conductors, "</td></tr>\n";
echo '<tr><th>', _('Diameter'),"</th><td>", format_float($cable->diameter, 1, 'mm'), "</td></tr>\n";
echo '<tr><th>', _('Cross section'),"</th><td>", format_float($cable->xsection, 1, 'mm²'), "</td></tr>\n";
echo '<tr><th>', _('Weight'),"</th><td>", format_float($cable->weight, 2, 'kg/m'), "</td></tr>\n";
echo '<tr><th>', _('Color'),"</th><td>", format_color($cable->color), "</td></tr>\n";
echo '<tr><th>', _('Condition'),"</th><td>", $opt_cablecond[$cable->cablecond], "</td></tr>\n";
echo "<tr><th>", _('Remarks'), "</th><td>", nl2br($cable->remarks), "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT cablename, cabletype, length, conductors, diameter, xsection,"
. " weight, color, supplier, manufacturer, cablecond, remarks "
. "FROM cable "
. "WHERE cableid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$cable = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Edit cable'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<div class="mb-3">
<label for="mname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="cablename" name="cablename" value="<?=$cable->cablename;?>">
</div>
<?php
form_create_select('cabletype', _('Type'), $g_opt_none + $opt_cabletype, $cable->cabletype);
?>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Length, m')?></label>
<input type="text" class="form-control" id="length" name="length" value="<?=format_float($cable->length, 1);?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Conductors')?></label>
<input type="text" class="form-control" id="conductors" name="conductors" value="<?=$cable->conductors;?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Diameter, mm')?></label>
<input type="text" class="form-control" id="diameter" name="diameter" value="<?=format_float($cable->diameter, 1);?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Cross section, mm²')?></label>
<input type="text" class="form-control" id="xsection" name="xsection" value="<?=format_float($cable->xsection, 1);?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Weight, kg/m')?></label>
<input type="text" class="form-control" id="weight" name="weight" value="<?=$cable->weight;?>">
</div>
<div class="mb-3">
<label for="color" class="form-label"><?=_('Color')?></label>
<input type="color" name="color" id="color" class="form-control" value="#<?=$cable->color;?>">
</div>
<?php
form_create_select('cablecond', _('Condition'), $opt_cablecond, $cable->cablecond);
?>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$cable->remarks ?></textarea>
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
echo '<h2>', _('Delete cable'), "</h2>\n";
$sql = "SELECT objid, objtype FROM tagref WHERE tagid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
}
} else {
echo _('Tag is not used anywhere');
$_SESSION['token'] = bin2hex(random_bytes(8));
form_delete_buttons($g_scriptname, $id, $_SESSION['token']);
}
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+14 -7
View File
@@ -51,7 +51,8 @@ switch ($submit = form_get_action()) {
$p[':shortname'] = gpc_get_string($_POST, 'shortname', 20);
$p[':comptype'] = gpc_get_int($_POST, 'comptype');
$p[':comptype2'] = gpc_get_int($_POST, 'comptype2');
$p[':street'] = gpc_get_string($_POST, 'street', 30);
if ($p[':comptype2'] <= 0) $p[':comptype2'] = NULL;
$p[':street'] = gpc_get_string($_POST, 'street', 40);
$p[':zip'] = gpc_get_string($_POST, 'zip', 10);
$p[':city'] = gpc_get_string($_POST, 'city', 30);
$p[':country'] = gpc_get_string($_POST, 'country', 30);
@@ -98,7 +99,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 208);
$flt = db_get_filter($user->id, 208, ['type','txt']);
$w = array();
$p = array();
@@ -132,7 +133,7 @@ try {
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT compid, compname, comptype, remarks "
@@ -141,7 +142,7 @@ if ($where) $sql .= ' WHERE ' . $where;
$sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
try {
@@ -161,9 +162,10 @@ $opt_special = array(
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body">
<div class="card-body d-flex flex-wrap gap-3">
<div class="d-flex flex-nowrap gap-2">
<label for="flt_type">Type</label>
<select id="flt_type" name="flt_type">
<select id="flt_type" class="form-select" name="flt_type">
<?php
foreach ($opt_special + $opt_comptype as $k => $v) {
echo '<option value="', $k,'"';
@@ -174,8 +176,13 @@ foreach ($opt_special + $opt_comptype as $k => $v) {
}
?>
</select>
</div>
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<input type="text" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt;?>">
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
+2 -1
View File
@@ -1,7 +1,7 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
*****************************************************************************/
@@ -11,6 +11,7 @@
define('APP_TITLE', 'Yacht Management Software');
define('APP_TITLE_SHORT', 'YMS');
define('APP_SESSION', 'yms');
define('APP_ILLUSTRATION', 'sailboat.svg');
// ========== GLOBAL VARIABLES ================================================
+6 -6
View File
@@ -229,7 +229,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 209);
$flt = db_get_filter($user->id, 209, ['doctype','reftype','txt']);
// $w = array('(vid=:vid OR vid IS NULL)');
// $p = array(':vid' => $user->vid);
@@ -289,7 +289,7 @@ try {
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT d.docid, d.doctype, d.filename, d.title, COUNT(r.drid) AS refcount "
@@ -299,7 +299,7 @@ $sql .= " GROUP BY d.docid, d.doctype, d.filename, d.title";
if ($order) $sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
$sth->execute($p);
@@ -635,7 +635,7 @@ foreach ($sth->fetchAll() as $row) {
<input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="equipment">
<label for="eid"><?=_('Equipment')?></label>
<select name="refid" id="eid">
<select class="form-select mb-2" name="refid" id="eid">
<?php
foreach ($opt_equipment as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n";
@@ -665,7 +665,7 @@ foreach ($sth->fetchAll() as $row) {
<input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="company">
<label for="compid"><?=_('Company')?></label>
<select name="refid" id="compid">
<select class="form-select mb-2" name="refid" id="compid">
<?php
foreach ($opt_company as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n";
@@ -691,7 +691,7 @@ foreach ($sth->fetchAll() as $row) {
<input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="vessel">
<label for="vid"><?=_('Vessel')?></label>
<select name="refid" id="vid">
<select class="form-select mb-2" name="refid" id="vid">
<?php
foreach ($opt_vessel as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n";
+8 -3
View File
@@ -148,14 +148,19 @@ echo '<tr>';
echo '<th>#</th>';
echo '<th>', _('Description'),'</th>';
echo '<th>', _('Number'),'</th>';
echo '<td></td>';
echo '<th></th>';
echo '</tr>';
echo '</thead>';
foreach ($sth->fetchAll() as $row) {
echo '<tr><td>', $row['ddval'],'</td>';
echo '<tr><td>', $row['ddval'];
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['ddval'], '"><i class="bi bi-eye ms-2"></i></a>';
echo '</td>';
echo '<td>', $row['ddtext'], '</td>';
echo '<td>', $num[$row['ddval']] ?? 0, '</td>';
form_action_buttons($g_scriptname, $row['ddval']);
// form_action_buttons($g_scriptname, $row['ddval']);
echo "<td>";
echo '<a class="text-nowrap" title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['ddval'], '"><i class="bi bi-pencil ms-2"></i></a>';
echo "</td>\n";
echo "</tr>\n";
}
echo "</table>\n";
+7 -8
View File
@@ -14,8 +14,8 @@ $pagetitle = _('Equipment');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_supplier = db_get_opt_supp(array(-1 => _('--- unknown ---')));
$opt_manufacturer = db_get_opt_manuf(array(-1 => _('--- unknown ---')));
$opt_supplier = db_get_opt_supp($g_opt_unknown);
$opt_manufacturer = db_get_opt_manuf($g_opt_unknown);
$opt_ecat = db_get_options(4); // Equipment categories
$opt_unit = db_get_options(8);
@@ -232,7 +232,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 200);
$flt = db_get_filter($user->id, 200, ['cat','manuf','supp','txt','flags']);
$sort = array(
1 => 'ename',
2 => 'ename DESC'
@@ -288,10 +288,9 @@ try {
$g_error->PrintOut();
}
$numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1);
// TODO check against allowed values for rows per page
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT eid, ename, manufacturer, model, serial, remarks, flags,"
. " TIMESTAMPDIFF(MONTH, purchdate, NOW()) AS age_mon "
@@ -464,7 +463,7 @@ echo "</table>\n";
echo '</div>'; // Column break
echo '<div class="col">', "\n";
echo '<div class="card">', "\n";
echo '<div class="card mb-2">', "\n";
echo '<div class="card-header">', _('Images and documents'), "</div>\n";
echo '<div class="card-body d-flex flex-wrap gap-3">', "\n";
@@ -669,7 +668,7 @@ $equipment = $sth->fetch(PDO::FETCH_OBJ);
</div>
<?php
form_create_select('supplier', _('Supplier'), $opt_supplier, $equipment->supplier);
form_create_select('category', _('Category'), [-1 => _('--- unknown ---')] + $opt_ecat, $equipment->ecat);
form_create_select('category', _('Category'), $g_opt_unknown + $opt_ecat, $equipment->ecat);
?>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
+1 -1
View File
@@ -1,5 +1,5 @@
<footer class="bg-body-tertiary text-center">
<p>Prototyp YMS v0.1</p>
<p>Prototyp YMS <?=$g_version?></p>
</footer>
</div><?php /* Main container */?>
+297
View File
@@ -0,0 +1,297 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
require 'lib/gpc.inc';
$pagetitle = _('Fuses');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_ftype = db_get_options(7);
$opt_location = db_get_options(10);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'add': $action = ACT_ADD; break;
case 'view': $action = ACT_VIEW; break;
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['location'] = gpc_get_int($_POST, 'flt_location');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 212);
$action = ACT_DEFAULT;
break;
case 'freset':
db_clear_filter(212);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':vid'] = $user->vid;
$p[':fnumber'] = gpc_get_int($_POST, 'fnumber');;
$p[':ftype'] = gpc_get_int($_POST, 'ftype');;
$p[':current'] = gpc_get_int($_POST, 'current');;
$p[':location'] = gpc_get_int($_POST, 'location');;
$p[':description'] = gpc_get_string($_POST, 'description');
$id = db_exec_insert('fuse', $p);
$action = ACT_VIEW;
break;
case 'update':
$p[':fuseid'] = $id;
$p[':fnumber'] = gpc_get_string($_POST, 'fuseid');
$p[':current'] = gpc_get_float($_POST, 'current');
$p[':cableid'] = gpc_get_int($_POST, 'cableid');
$p[':eid'] = gpc_get_int($_POST, 'id');
$p[':weight'] = min(gpc_get_float($_POST, 'weight'), 9.99); // limit max value
$p[':location'] = gpc_get_int($_POST, 'location');
$p[':description'] = gpc_get_string($_POST, 'description');
$p[':remarks'] = gpc_get_string($_POST, 'remarks');
db_exec_update('tag', $p, 'tagid');
$action = ACT_VIEW;
break;
case 'delete':
// Security token needed!
if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
$g_error->Add(_('Delete prohibited, invalid security token!'));
$action = ACT_VIEW;
break;
}
// tagref have to be empty
// TODO
$action = ACT_DEFAULT;
break;
default:
$g_error->Add(sprintf(_('Unknown function!'), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// lookup tables
$opt_ftype_short = db_get_options(7, '', true);
// load filter from db
$flt = db_get_filter($user->id, 212);
$w = array('vid=:vid');
$p = array(':vid' => $user->vid);
if ($flt->location == -1) {
$w[] = 'location IS NULL';
} elseif ($flt->location > 0) {
$w[] = 'location=:location';
$p[':location'] = $flt->location;
}
if (strlen($flt->txt) > 1) {
$w[] = 'description LIKE :txt';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY fnumber';
echo "<h1>$pagetitle</h1>\n";
// Filter
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body d-flex flex-wrap gap-3">
<?php
filter_create_select('flt_location', _('Location'), $g_opt_all + $g_opt_none + $opt_location, $flt->location);
?>
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt"><?=_('Description')?></label>
<input type="text" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?? ''?>">
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div>
</form>
<?php
$sql = "SELECT fuseid, fnumber, ftype, location, current, description "
. "FROM fuse";
$sql .= ' WHERE ' . $where;
$sql .= $order;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', pgettext('number', 'Number'), "</th>";
echo '<th>', _('Type'), "</th>";
echo '<th>', _('Current'), "</th>";
echo '<th>', _('Location'), "</th>";
echo '<th>', _('Description'), "</th>";
echo "<th></th>";
echo "</tr>\n";
echo "</thead>\n";
$i = 1;
foreach ($res as $row) {
echo "<tr>\n";
echo '<td>', $i++;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['fuseid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>F", $row['fnumber'], "</td>\n";
echo "<td>",$opt_ftype_short[$row['ftype']], "</td>\n";
echo "<td>", $row['current'], "A</td>\n";
echo "<td>", $opt_location[$row['location']], "</td>\n";
echo "<td>", $row['description'], "</td>\n";
// Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['fusevid'], '"><i class="bi bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n";
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
echo '<h2>', _('Add fuse'), "</h2>\n";
// calc next free fuse number for convenience
$sql = "SELECT max(fnumber) FROM fuse WHERE vid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$user->vid]);
$fnumber = $sth->fetchColumn() + 1;
?>
<form method="post" action="<?=$g_scriptname?>">
<div class="mb-3">
<label for="fnumber" class="form-label"><?=_('Fuse number')?></label>
<input type="text" class="form-control" id="fnumber" name="fnumber" value="<?=$fnumber?>" required>
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Description')?></label>
<input type="text" class="form-control" id="description" name="description" autofocus>
</div>
<?php form_create_select('ftype', _('Type'), $opt_ftype); ?>
<div class="mb-3">
<label for="current" class="form-label"><?=_('Current, Ampere')?></label>
<input type="text" class="form-control" id="current" name="current" required>
</div>
<?php form_create_select('location', _('Location'), $g_opt_none + $opt_location); ?>
<?php
form_new_buttons($g_scriptname);
echo "</form>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT fnumber, ftype, current, cableid, eid, location, description, remarks "
. "FROM fuse "
. "WHERE fuseid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$fuse = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('View fuse'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Fuse'),"</th><td>F", $fuse->fnumber, "</td></tr>\n";
echo '<tr><th>', _('Description'),"</th><td>", $fuse->description, "</td></tr>\n";
echo '<tr><th>', _('Type'),"</th><td>", $opt_ftype[$fuse->ftype], "</td></tr>\n";
echo '<tr><th>', _('Current'),"</th><td>", $fuse->current, "A</td></tr>\n";
echo '<tr><th>', _('Location'),"</th><td>", $opt_location[$fuse->location], "</td></tr>\n";
echo '<tr><th>', _('Cable'),"</th><td>", $fuse->cableid, "</td></tr>\n";
echo '<tr><th>', _('Equipment'),"</th><td>", $fuse->eid, "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", nl2br($fuse->remarks), "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT fnumber, description "
. "FROM fuse "
. "WHERE fuseid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$fuse = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Edit fuse'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<div class="mb-3">
<label for="mname" class="form-label"><?=pgettext('number', 'Number')?></label>
<input type="text" class="form-control" id="fnumber" name="fnumber" value="<?=$fuse->fnumber ?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Description')?></label>
<input type="text" class="form-control" id="description" name="description" value="<?=$fuse->description ?>">
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
echo '<h2>', _('Delete fuse'), "</h2>\n";
$sql = "SELECT fusename, description FROM fuse WHERE fuseid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
}
} else {
echo _('Fuse is not used anywhere');
$_SESSION['token'] = bin2hex(random_bytes(8));
form_delete_buttons($g_scriptname, $id, $_SESSION['token']);
}
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+117 -11
View File
@@ -41,6 +41,9 @@ define ('ACT_VIEW_LIST', 13);
// ========== PAGE START CODE =================================================
// global version string
$g_version = 'v0.1.1';
$g_scriptname = basename($_SERVER['SCRIPT_NAME']);
require 'config.inc';
@@ -113,6 +116,7 @@ $user = User::GetInstance(); // There can be only one
if ($g_scriptname != 'login.php') {
$user->init_from_session();
$user->load_vessel();
$user->load_settings();
}
$action = NULL;
@@ -124,6 +128,7 @@ $g_doc_mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf
// form option lists
$g_opt_all = array(-2 => _('&horbar; all &horbar;'));
$g_opt_none = array(-1 => _('&horbar; none &horbar;'));
$g_opt_unknown = array(-1 => _('&horbar; unknown &horbar;'));
// Initialize message system
$g_message = new Message;
@@ -227,13 +232,18 @@ class User {
public $flags;
public $vid; // current selected vessel
public $vessel; // name of current vessel
public $datefmt;
public $rows_pp;
private function __construct() {
global $g_rows_pp;
$this->loggedin = FALSE;
$this->errormessage = NULL;
$this->flags = [];
$this->vid = 1;
$this->vessel = 'Yacht';
$this->datefmt = 'Y-m-d';
$this->rows_pp = $g_rows_pp;
}
public static function getInstance() {
@@ -300,10 +310,10 @@ class User {
$sth = $pdo->prepare($sql);
$sth->execute([$this->id]);
$row = $sth->fetch();
if ($row) {
$this->displayname = $row['displayname'];
$this->role = $row['role'];
//$this->displayname = $sth->fetchColumn();
}
}
function load_vessel() {
@@ -314,9 +324,32 @@ class User {
$sth = $pdo->prepare($sql);
$sth->execute([$this->id]);
$row = $sth->fetch();
if ($row) {
$this->vid = $row['vid'];
$this->vessel = $row['vesselname'];
}
}
function load_settings() {
global $pdo;
// additional user settings
// date format from user settings
$sql = "SELECT valstr FROM settings WHERE userid=? AND sno=2";
$sth = $pdo->prepare($sql);
$sth->execute([$this->id]);
$user_datefmt = $sth->fetchColumn();
if ($user_datefmt) {
$this->datefmt = $user_datefmt;
}
// pagination rows from user settings
$sql = "SELECT valint FROM settings WHERE userid=? AND sno=10";
$sth = $pdo->prepare($sql);
$sth->execute([$this->id]);
$user_rows_pp = $sth->fetchColumn();
if ($user_rows_pp) {
$this->rows_pp = $user_rows_pp;
}
}
function get_last_error() {
return $this->errormessage;
@@ -643,6 +676,46 @@ function db_save_taglist($objtype, $objid, $taglist) {
}
}
function db_get_tag_target($objtype, $objid) {
// get page name and desctiption e.g. for link creation
global $pdo;
global $g_error;
switch ($objtype) {
case 'equip':
$sql = "SELECT ename FROM equipment WHERE eid=?";
$target = "equipment.php";
break;
case 'inv':
$sql = "SELECT invname FROM inventory WHERE invid=?";
$target = "inventory.php";
break;
case 'prov':
$sql = "SELECT provname FROM provisions WHERE provvid=?";
$target = "provisions.php";
break;
case 'doc':
$sql = "SELECT title FROM document WHERE docid=?";
$target = "documents.php";
break;
case 'proj':
$sql = "SELECT projname FROM project WHERE projid=?";
$target = "projects.php";
break;
case 'task':
$sql = "SELECT taskname FROM task WHERE taskid=?";
$target = "task.php";
break;
case 'maint':
$sql = "SELECT activities FROM maintenance WHERE maintid=?";
$target = 'maintenance.php';
break;
}
$sth = $pdo->prepare($sql);
$sth->execute([$objid]);
$desc = $sth->fetchColumn();
return [$target, $desc];
}
function db_get_ddtext($ddid, $ddval) {
// returns single value for dropdown
global $pdo;
@@ -660,14 +733,20 @@ function db_get_ddtext($ddid, $ddval) {
// Functions to get option lists (key/value)
function db_get_options($ddid, $orderby = '', $default = NULL) {
function db_get_options($ddid, $orderby = '', $short = False, $default = NULL) {
// returns list for dropdown
// if short is set the short value will be returned
global $pdo;
$list = array();
if ($default != NULL) {
$list[0] = $default;
}
$sql = "SELECT ddval, ddtext FROM dropdown WHERE ddid=?";
if ($short) {
$sql = "SELECT ddval, ddshort";
} else {
$sql = "SELECT ddval, ddtext";
}
$sql .= " FROM dropdown WHERE ddid=?";
if ($orderby == 'ddtext') {
$sql .= ' ORDER BY ddtext';
} elseif ($orderby == 'sort') {
@@ -819,7 +898,8 @@ function db_get_opt_proj($vid, $default=NULL) {
return $list;
}
function db_get_filter($user, $sno) {
function db_get_filter($user, $sno, $fields = []) {
// if fields supplied empting missing field are created
global $pdo;
global $g_warning;
$flt = new stdClass();
@@ -827,15 +907,22 @@ function db_get_filter($user, $sno) {
try {
$sth->execute([$user, $sno]);
$json = $sth->fetchColumn();
if (!$json) {
if ($json === false) {
// no settings record. create empty one for later updates
$sth = $pdo->prepare("INSERT INTO settings (userid, sno, valstr) VALUES (?, ?, '{}')");
$sth->execute([$user, $sno]);
} else {
$flt = json_decode($json);
}
// create missing fields
foreach ($fields as $f) {
if (!property_exists($flt, $f)) {
$flt->$f = null;
}
}
} catch (PDOexception $e) {
$g_warning->Add('SQL-Error: '. $e->getMessage());
$g_warning->PrintOut();
}
return $flt;
}
@@ -1155,7 +1242,7 @@ function get_color_brightness($color, $default=0.5) {
function page_caption_search($caption) {
// print page caption with searchbox
?>
<div class="row align-items-center">
<div class="row row align-items-center justify-content-between">
<div class="col">
<h1><?=$caption?></h1>
</div>
@@ -1193,8 +1280,8 @@ function get_pagination($script, $param, $page, $lastpage, $small=false) {
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p=1">'. _('First'). '</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. ($page - 1). '">'. _('Previous'). '</a></li>'. "\n";
} else {
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('First'). '</a></li>'. "\n";
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('Previous'). '</a></li>'. "\n";
$out .= '<li class="page-item disabled"><span class="page-link">'. _('First'). '</span></li>'. "\n";
$out .= '<li class="page-item disabled"><span class="page-link">'. _('Previous'). '</span></li>'. "\n";
}
if ($lastpage < 10) {
@@ -1205,6 +1292,25 @@ function get_pagination($script, $param, $page, $lastpage, $small=false) {
}
} else {
// start working with ... dots
$start = max(2, $page - 2);
$end = min($lastpage - 1, $page + 2);
$out .= '<li class="page-item"><a class="page-link';
if ($page == 1) $out .= ' active';
$out .= '" href="'. $script. $psep. 'p=1">1</a></li>'. "\n";
if ($start > 2) {
$out .= '<li class="page-item disabled"><span class="page-link">...</span></li>'. "\n";
}
for ($n = $start; $n <= $end; $n++) {
$out .='<li class="page-item"><a class="page-link';
if ($n == $page) $out .= ' active';
$out .= '" href="'. $script. $psep. 'p='. $n. '">'. $n. '</a></li>'. "\n";
}
if ($end < $lastpage - 1) {
$out .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
}
$out .= '<li class="page-item"><a class="page-link';
if ($page == $lastpage) $out .= ' active';
$out .= '" href="'. $script. $psep. 'p='. $lastpage. '">'. $lastpage. '</a></li>'. "\n";
}
if ($page < $lastpage) {
@@ -1212,8 +1318,8 @@ function get_pagination($script, $param, $page, $lastpage, $small=false) {
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. ($page + 1). '">'. _('Next'). '</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. $lastpage. '">'. _('Last'). '</a></li>'. "\n";
} else {
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('Next'). '</a></li>'. "\n";
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('Last'). '</a></li>'. "\n";
$out .= '<li class="page-item disabled"><span class="page-link">'. _('Next'). '</span></li>'. "\n";
$out .= '<li class="page-item disabled"><span class="page-link">'. _('Last'). '</span></li>'. "\n";
}
// idea: small entry to input page number
+64 -29
View File
@@ -78,6 +78,7 @@ switch ($submit = form_get_action()) {
if ($p[':shapefile'] == '-1') {
$p[':shapefile'] = NULL;
}
$p[':shipyard'] = gpc_get_int($_POST, 'shipyard');
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('vessel', $p, 'vid');
$action = ACT_DEFAULT;
@@ -109,44 +110,68 @@ $sth->execute([$user->id]);
$res = $sth->fetch(PDO::FETCH_NUM);
$vid = ($res[0]);
// Switch between vessels
$sth = $pdo->query("SELECT vid, vesselname, model FROM vessel ORDER BY vid");
$res = $sth->fetchAll();
echo '<form class="row align-items-center" method="post">', "\n";
echo '<div class="col-1">', "\n";
echo '<label class="form-label" for="vid">Yacht:</label>';
echo "</div>\n";
echo '<div class="col-4">', "\n";
echo '<select class="form-select" name="vid" id="vid">', "\n";
foreach ($res as $row) {
echo '<option value="', $row['vid'], '"', ($row['vid'] == $vid ? ' selected>' : '>');
echo $row['vesselname'], ' - ', $row['model'];
echo "</option>\n";
}
echo "</select>\n";
echo "</div>\n";
echo '<div class="col">', "\n";
echo '<button type="submit" class="btn btn-secondary" name="submit[select]">', _('Select'), '</button>', "\n";
echo '<button type="submit" class="btn btn-secondary" name="submit[add]">', _('Add yacht'), '</button>', "\n";
echo "</div>\n";
echo "</form>\n";
// Get current vessel data
$sql = "SELECT vesselname, model, loa, lwl, beam, draught, draught_min,"
. " displacement, ballast, beltpos_aft, beltpos_bow, shapefile,"
. " remarks "
. " shipyard, remarks "
. "FROM vessel "
. "WHERE vid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$vid]);
$vessel = $sth->fetch(PDO::FETCH_OBJ);
// Show remarks first
if (strlen($vessel->remarks) > 0) {
echo "<p>";
echo nl2br($vessel->remarks);
echo "</p>\n";
echo '<div class="container-fluid">', "\n"; // head block
// Switch between vessels
?>
<form class="row align-items-center" method="post" action="<?=$g_scriptname?>">
<div class="col-1">
<label class="form-label" for="vid">Yacht:</label>
</div>
<div class="col-4">
<select class="form-select" name="vid" id="vid">', "\n";
<?php
$sth = $pdo->query("SELECT vid, vesselname, model FROM vessel ORDER BY vid");
$res = $sth->fetchAll();
foreach ($res as $row) {
echo ' <option value="', $row['vid'], '"', ($row['vid'] == $vid ? ' selected>' : '>');
echo $row['vesselname'], ' - ', $row['model'];
echo "</option>\n";
}
?>
</select>
</div>
<div class="col">
<?php
echo ' <button type="submit" class="btn btn-secondary" name="submit[select]">', _('Select'), '</button>', "\n";
echo ' <button type="submit" class="btn btn-secondary" name="submit[add]">', _('Add yacht'), '</button>', "\n";
?>
</div>
</form>
<?php
// Show additional yacht info
echo '<div class="row my-2">', "\n";
echo '<div class="col-1"></div>', "\n";
echo '<div class="col">';
if ($vessel->shipyard) {
if ($vessel->shipyard == -3) {
echo _('Custom-build');
} else {
$sql = "SELECT compname FROM company WHERE compid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$vessel->shipyard]);
echo sprintf(_('Built by %s'), $sth->fetchColumn());
// TODO year of build?
}
}
if (strlen($vessel->remarks) > 0) {
echo nl2br($vessel->remarks);
}
echo "</div>\n";
echo "</div>\n"; // row 2
echo "</div>\n"; // end of yacht head block
// get vessel shape
// test for predefined base shape
@@ -377,6 +402,8 @@ echo "</table>\n";
<li class="list-group-item"><a href="settings.php"><?=_('Settings')?></a></li>
<li class="list-group-item"><a href="task.php"><?=_('Tasks')?></a></li>
<li class="list-group-item"><a href="measurement.php"><?=_('Measurements')?></a></li>
<li class="list-group-item"><a href="cable.php"><?=_('Cables')?></a></li>
<li class="list-group-item"><a href="fuse.php"><?=_('Fuses')?></a></li>
<li class="list-group-item"><a href="checklist.php"><?=_('Checklists')?></a></li>
</ul>
</div>
@@ -426,9 +453,16 @@ foreach (glob($g_shapedir.'/*.svg') as $f) {
$opt_shapefiles[$f] = $f;
}
$opt_shipyard = $g_opt_none + [-3 => _('&horbar; Custom-built &horbar;')];
$sql = "SELECT compid, compname FROM company WHERE comptype=3 ORDER BY compname";
$sth = $pdo->query($sql);
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) {
$opt_shipyard[$row[0]] = $row[1];
}
$sql = "SELECT vesselname, vtype, model, loa, lwl, beam, draught, draught_min,"
. " displacement, ballast, beltpos_aft, beltpos_bow, shapefile,"
. " remarks "
. " shipyard, remarks "
. "FROM vessel "
. "WHERE vid=?";
$sth = $pdo->prepare($sql);
@@ -488,6 +522,7 @@ $vessel = $sth->fetch(PDO::FETCH_OBJ);
<input type="text" class="form-control" id="shapefile" name="shapefile" value="<?=$vessel->shapefile ?>">
</div> */
form_create_select('shapefile', _('Shape file'), $opt_shapefiles, $vessel->shapefile);
form_create_select('shipyard', _('Shipyard'), $opt_shipyard, $vessel->shipyard);
?>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
+3 -3
View File
@@ -103,7 +103,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 201);
$flt = db_get_filter($user->id, 201, ['cond','name','txt']);
/*
The only way to find out whether the inventory is on the current boat is to use
@@ -144,7 +144,7 @@ try {
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT i.invid, i.invname, i.number, i.invcond, i.eid, s.sname AS container "
@@ -157,7 +157,7 @@ $sql .= ' WHERE ' . $where;
$sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
try {
+17
View File
@@ -0,0 +1,17 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************
*/
// ========== SVG-FUNCTIONS ===================================================
function svg_create_box($cx, $cy, $w, $h, $fg, $bg) {
}
+691 -512
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+1 -1
View File
@@ -47,7 +47,7 @@ $(document).ready(function(){
</div>
<div class="row my-3">
<div class="col">
<img src="sailboat.svg" class="img-fluid rounded-start" alt="sailboat">
<img src="<?=APP_ILLUSTRATION?>" class="img-fluid rounded-start" alt="sailboat">
</div>
<div class="col">
<div class="card-body">
+23 -3
View File
@@ -79,7 +79,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 204);
$flt = db_get_filter($user->id, 204, ['equip','txt']);
// Filter
$opt_special = array(
@@ -140,6 +140,20 @@ if (strlen($flt->txt) > 1) {
$where = join(' AND ', $w);
$order = ' ORDER BY m.maintid';
$sql = "SELECT COUNT(*) FROM maintenance AS m WHERE " . $where;
$sth = $pdo->prepare($sql);
try {
$sth->execute($p);
} catch(PDOException $e) {
$g_error->Add($e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($p, true));
$g_error->PrintOut();
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT m.maintid, m.activities, m.remarks, e.ename "
. "FROM maintenance AS m LEFT OUTER JOIN equipment AS e USING (eid)";
@@ -147,12 +161,16 @@ $sql .= ' WHERE ' . $where;
$sql .= $order;
// if pagination:
// $sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
@@ -182,10 +200,12 @@ foreach ($res as $row) {
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo '<tr><td colspan="6">', sprintf(_('Records %d to %d of %d'), $i0, $i, $numrows), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
echo $pagination;
form_add_button($g_scriptname);
+1 -1
View File
@@ -16,7 +16,7 @@ require 'header.php';
<p class="p-3 mb-3 bg-info-subtle border border-info-subtle rounded">
<i class="bi bi-info-circle-fill me-2"></i>
Hinweis: Es handelt sich hier um einen Prototypen!
Hinweis: Es handelt sich hier um einen Prototypen (Version <?=$g_version?>)!<br>
Einige Funktionen sind noch nicht oder nicht vollständig implementiert.
Rückmeldungen sind immer willkommen!</p>
+70 -35
View File
@@ -9,20 +9,23 @@
require 'globals.inc';
require 'lib/gpc.inc';
// TODO move to somewhere else
function format_vals($n, $v1, $v2, $v3) {
if ($n == 1) {
return $v1;
} elseif ($n == 2) {
return $v1 . 'x'. $v2;
} else {
return $v1 . 'x'. $v2 . 'x' . $v3;
}
}
$pagetitle = _('Measurements');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_mtype = db_load_enum('measurement', 'mtype', true, false);
$opt_unit = db_get_options(8);
// TODO use enum function
$opt_accuracy = array(
'unknown' => _('Unknown'),
'precise' => _('Precise'),
'normal' => _('Normal'),
'rough' => _('Rough'),
'estimated' => _('Estimated')
);
$opt_accuracy = db_load_enum('measurement', 'accuracy', true, true);
$opt_dimensions = array(
1 => _('1D'),
2 => _('2D'),
@@ -54,9 +57,13 @@ switch ($submit = form_get_action()) {
$action = ACT_DEFAULT;
break;
case 'freset':
db_clear_filter(207);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':mname'] = gpc_get_string($_POST, 'mname');
$p[':mtype'] = gpc_get_string($_POST, 'mtype');
$p[':note'] = gpc_get_string($_POST, 'note');
$p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions
$p[':val1'] = gpc_get_int($_POST, 'val1');
@@ -81,7 +88,6 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':mid'] = $id;
$p[':mname'] = gpc_get_string($_POST, 'mname');
$p[':mtype'] = gpc_get_string($_POST, 'mtype');
$p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions
$p[':val1'] = gpc_get_int($_POST, 'val1');
$p[':val2'] = NULL;
@@ -130,20 +136,37 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 207);
$flt = db_get_filter($user->id, 207, ['txt']);
function format_vals($n, $v1, $v2, $v3) {
if ($n == 1) {
return $v1;
} elseif ($n == 2) {
return $v1 . 'x'. $v2;
} else {
return $v1 . 'x'. $v2 . 'x' . $v3;
}
}
$w = array('(vid=:vid OR vid IS NULL)');
$p = array(':vid' => $user->vid);
echo "<h1>$pagetitle</h1>\n";
// TODO precision additionally as filter
if (strlen($flt->txt) > 1) {
$w[] = 'mname LIKE :txt';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY mname';
$sql = "SELECT COUNT(*) FROM measurement WHERE " . $where;
$sth = $pdo->prepare($sql);
try {
$sth->execute($p);
} catch(PDOException $e) {
$g_error->Add($e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($p, true));
$g_error->PrintOut();
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
// Filter
$opt_special = array(
@@ -154,23 +177,36 @@ $opt_special = array(
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body">
<?php
filter_create_select('flt_mtype', _('Type'), $g_opt_all + $g_opt_none + $opt_mtype);
?>
<div class="card-body d-flex flex-wrap gap-3">
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<input type="text" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?>">
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div>
</form>
<?php
$sql = "SELECT mid, mname, nval, val1, val2, val3, unit, accuracy, mdate, note, eid "
. "FROM measurement "
. "ORDER BY mname";
$sth = $pdo->query($sql);
. "FROM measurement ";
$sql .= ' WHERE ' . $where;
$sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
@@ -206,6 +242,8 @@ echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>'
echo "</tfoot>\n";
echo "</table>\n";
echo $pagination;
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
@@ -224,7 +262,6 @@ echo '<h2>', _('Add measurement'), "</h2>\n";
<input type="text" class="form-control" id="note" name="note">
</div>
<?php
form_create_select('mtype', _('Type'), $opt_mtype);
form_create_select('nval', _('Dimensions'), $opt_dimensions);
?>
<div class="mb-3">
@@ -254,7 +291,7 @@ form_create_select('eid', _('Equipment'), $opt_equipment, $id);
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT mname, mtype, unit, nval, val1, val2, val3, accuracy, mdate, note, eid "
$sql = "SELECT mname, unit, nval, val1, val2, val3, accuracy, mdate, note, eid "
. "FROM measurement "
. "WHERE mid=?";
$sth = $pdo->prepare($sql);
@@ -265,7 +302,6 @@ echo '<h2>', _('Measurement'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Name'),"</th><td>", $measurement->mname, "</td></tr>\n";
echo '<tr><th>', _('Type'),"</th><td>", $opt_mtype[$measurement->mtype], "</td></tr>\n";
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$measurement->unit], "</td></tr>\n";
echo '<tr><th>', _('Values'),"</th><td>$measurement->nval</td></tr>\n";
echo '<tr><th>', _('Value 1'),"</th><td>$measurement->val1</td></tr>\n";
@@ -283,7 +319,7 @@ form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT mname, mtype, nval, val1, val2, val3, unit, accuracy, note, eid "
$sql = "SELECT mname, nval, val1, val2, val3, unit, accuracy, note, eid "
. "FROM measurement "
. "WHERE mid=?";
$sth = $pdo->prepare($sql);
@@ -303,7 +339,6 @@ echo '<h2>', _('Edit measurement'), "</h2>\n";
<input type="text" class="form-control" id="note" name="note" value="<?=$measurement->note ?>">
</div>
<?php
form_create_select('mtype', _('Type'), $opt_mtype, $measurement->mtype);
form_create_select('nval', _('Dimensions'), $opt_dimensions, $measurement->nval);
?>
<div class="mb-3">
+2 -1
View File
@@ -176,7 +176,8 @@ $note = $sth->fetch(PDO::FETCH_OBJ);
// list where annotaion used
echo '<table class="table">', "\n";
echo '<tr><th>', _('Referenz'),"</th><td>", $note->refid, "</td></tr>\n";
echo '<tr><th>', _('Annotation'),"</th><td>", $note->annotation, "</td></tr>\n";
echo '<tr><th>', _('Type'),"</th><td>", $note->notetype, "</td></tr>\n";
echo '<tr><th>', _('Annotation'),"</th><td>", nl2br($note->annotation), "</td></tr>\n";
echo "</table>\n";
+27 -15
View File
@@ -47,7 +47,7 @@ switch ($submit = form_get_action()) {
case 'filter':
$flt = array();
$flt['name'] = gpc_get_string($_POST, 'flt_name');
$flt['state'] = $_POST['flt_state']; // Array! gpc_get_string($_POST, 'flt_state');
$flt['state'] = gpc_get_string($_POST, 'flt_state'); // TODO perhaps change to checkboxes
$flt['remarks'] = gpc_get_string($_POST, 'flt_remarks');
db_save_filter($flt, 205);
$action = ACT_DEFAULT;
@@ -107,16 +107,22 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 205);
// name, status, text
$flt = db_get_filter($user->id, 205, ['name','state','remarks']);
$w = array('vid=:vid');
$p = array(':vid' => $user->vid);
if (strlen($flt->txt) > 1) {
$w[] = '(projname LIKE :txt OR remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
if ($flt->state > 0) {
$w[] = 'projstate=:state';
$p[':state'] = $flt->state;
}
if (strlen($flt->name) > 1) {
$w[] = '(projname LIKE :name)';
$p[':name'] = '%'.$flt->name.'%';
}
if (strlen($flt->remarks) > 1) {
$w[] = '(remarks LIKE :remarks)';
$p[':remarks'] = '%'.$flt->remarks.'%';
}
$where = join(' AND ', $w);
@@ -134,7 +140,7 @@ try {
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
// $grandtotal = $pdo->query("SELECT COUNT(*) FROM project WHERE " . $where)->fetchColumn();
@@ -145,7 +151,7 @@ $sql .= " WHERE " . $where;
$sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
$sth->execute($p);
@@ -158,15 +164,15 @@ $res = $sth->fetchAll();
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body d-flex flex-wrap gap-3">
<div class="d-flex flex-nowrap gap-2">
<label for="flt_name">Name</label>
<input type="text" class="form-control" name="flt_name" size="15" maxlength="30" value="<?=$flt->name;?>">
<label for="flt_name"><?=_('Name')?></label>
<input type="text" class="form-control" name="flt_name" size="15" maxlength="30" value="<?=$flt->name ?? '';?>">
</div>
<?php
filter_create_select('flt_state[]', _('State'), $g_opt_all + $opt_state, $flt->state, FALSE);
filter_create_select('flt_state', _('State'), $g_opt_all + $opt_state, $flt->state ?? -2, FALSE);
?>
<div class="d-flex flex-nowrap gap-2">
<label for="flt_remarks">Text</label>
<input type="text" class="form-control" name="flt_remarks" size="15" maxlength="30" value="<?=$flt->remarks ?>">
<label for="flt_remarks"><?=_('Remarks')?></label>
<input type="text" class="form-control" name="flt_remarks" size="15" maxlength="30" value="<?=$flt->remarks ?? '' ?>">
</div>
</div>
<div class="card-footer">
@@ -177,6 +183,9 @@ filter_create_select('flt_state[]', _('State'), $g_opt_all + $opt_state, $flt->s
</form>
<?php
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
echo '<table class="table table-striped">'. "\n";
echo "<thead>\n";
@@ -210,11 +219,14 @@ foreach ($res as $row) {
echo "</tr>\n";
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="5">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo '<tr><td colspan="6">', sprintf(_('Records %d to %d of %d'), $i0, $i, $numrows), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
echo $pagination;
form_add_button($g_scriptname);
echo "<h1>", _('Generic Tasks'), "</h1>\n";
+2 -2
View File
@@ -127,7 +127,7 @@ try {
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
// provisions can be assigned to a store or be free
@@ -218,7 +218,7 @@ foreach ($res as $row) {
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="8">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo '<tr><td colspan="8">', sprintf(_('Records %d to %d of %d'), $i0, $i, $numrows), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
+137
View File
@@ -0,0 +1,137 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
require 'lib/gpc.inc';
$pagetitle = _('Settings');
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'update':
$pk = ['userid', 'sno'];
// global settings
if ($user->role == 'captain') {
$p[':userid'] = 0;
$p[':sno'] = 20;
$p[':valint'] = gpc_get_int($_POST, 'maximgx');
db_exec_update('settings', $p, $pk);
$p[':sno'] = 21;
$p[':valint'] = gpc_get_int($_POST, 'maximgy');
db_exec_update('settings', $p, $pk);
}
// user settings
$p[':userid'] = $user->id;
$p[':sno'] = 2; // date format
$p[':valint'] = NULL;
$p[':valstr'] = gpc_get_string($_POST, 'datefmt');
db_exec_update('settings', $p, $pk);
$p[':sno'] = 10; // rows pp
$p[':valstr'] = NULL;
$p[':valint'] = gpc_get_int($_POST, 'rowspp');
db_exec_update('settings', $p, $pk);
break;
default:
$g_error->Add(sprintf(_("Unknown function '%s'!"), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo '<h1>', $pagetitle, "</h1>\n";
$datefmt = 'Y-m-d';
$sql = "SELECT valstr FROM settings WHERE userid=? AND sno=2";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id]);
if ($res = $sth->fetch(PDO::FETCH_NUM)) {
$datefmt = $res[0];
} else {
// create missing record in settings table
$sql = "INSERT INTO settings (userid, sno, valstr) VALUES (?, 2, ?)";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id, $datefmt]);
}
$curdate = new DateTime();
$opt_datefmt = array(
'Y-m-d' => _('YYYY-MM-DD'). $curdate->format(' - Y-m-d'),
'Y/m/d' => _('YYYY/MM/DD'). $curdate->format(' - Y/m/d'),
'd.m.Y' => _('DD.MM.YYYY'). $curdate->format(' - d.m.Y'),
'd/m/Y' => _('DD/MM/YYYY'). $curdate->format(' - d/m/Y'),
'm-d-Y' => _('MM/DD/YYYY'). $curdate->format(' - m-d-Y')
);
$rowspp = 10;
$sql = "SELECT valint FROM settings WHERE userid=? AND sno=10";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id]);
if ($res = $sth->fetch(PDO::FETCH_NUM)) {
$rowspp = $res[0];
} else {
// create missing record in settings table
$sql = "INSERT INTO settings (userid, sno, valint) VALUES (?, 10, ?)";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id, $rowspp]);
}
$maximgx = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=20")->fetchColumn();
$maximgy = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=21")->fetchColumn();
?>
<form method="post" action="<?=$g_scriptname?>">
<h2>for current user</h2>
<?php
form_create_select('datefmt', _('Date format'), $opt_datefmt, $datefmt);
?>
<div class="mb-3">
<label for="rowspp" class="form-label"><?=_('Number of rows per page')?></label>
<input type="text" class="form-control" id="rowspp" name="rowspp" maxlength="3" value=<?=$rowspp?>>
</div>
<?php
// limit global settings for captain only
if ($user->role == 'captain'):
?>
<h2>global for all users</h2>
<div class="mb-3">
<label for="maximgx" class="form-label"><?=_('Maximal image width')?></label>
<input type="text" class="form-control" id="maximgx" name="maximgx" maxlength="4" value=<?=$maximgx?>>
</div>
<div class="mb-3">
<label for="maximgy" class="form-label"><?=_('Maximal image height')?></label>
<input type="text" class="form-control" id="maximgy" name="maximgy" maxlength="4" value=<?=$maximgy?>>
</div>
<?php
endif;
?>
<div class="container-fluid px-0 my-3">
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
<a href="index.php" class="btn btn-secondary"><?=_('Back')?></a>
</div>
</form>
<?php
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+11 -10
View File
@@ -13,7 +13,7 @@ $pagetitle = _('Storage');
$id = gpc_get_int($_REQUEST, 'id', 0);
$stype = db_get_options(3);
$opt_stype = db_get_options(3);
// ========== ACTIONS START ===================================================
@@ -37,6 +37,7 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':sid'] = $id;
$p[':sname'] = gpc_get_string($_POST, 'sname');
$p[':stype'] = gpc_get_string($_POST, 'stype');
$p[':x'] = gpc_get_int($_POST, 'x');
$p[':y'] = gpc_get_int($_POST, 'y');
$p[':z'] = gpc_get_int($_POST, 'z');
@@ -73,9 +74,12 @@ switch ($submit = form_get_action()) {
$action = ACT_VIEW;
break;
}
$sth = $pdo->prepare("SELECT sname FROM storage WHERE sid=?");
$sth->execute([$id]);
$storagename = $sth->fetchcolumn();
$sth = $pdo->prepare("DELETE FROM storage WHERE sid=?");
$sth->execute([$id]);
$g_message->Add(sprintf(_('Deleted storage no. %d'), $id));
$g_message->Add(sprintf(_('Deleted storage no. %d (%s)'), $id, $storagename));
$action = ACT_DEFAULT;
break;
@@ -194,15 +198,9 @@ echo '<h2>', _('Add Storage'), "</h2>\n";
<label for="sname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="sname" name="sname">
</div>
<div class="mb-3">
<select name="stype" class="form-control">
<?php
foreach ($stype as $k => $v) {
echo '<option value="', $k ,'">', $v, "</option>\n";
}
form_create_select('stype', _('Type'), $opt_stype);
?>
</select>
</div>
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
</form>
@@ -223,7 +221,7 @@ $storage = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', $storage->sname, "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:33%">', _('Typ'),"</th><td>", $stype[$storage->stype], "</td></tr>\n";
echo '<tr><th style="width:33%">', _('Typ'),"</th><td>", $opt_stype[$storage->stype], "</td></tr>\n";
echo '<tr><th>', _('Capacity'),"</th><td>", $storage->capacity, ' ', $storage->capaunit, "</td></tr>\n";
echo '<tr><th>', _('Location (x, y, z)'),"</th><td>(", $storage->x, ', ', $storage->y, ', ', $storage->z, ")</td></tr>\n";
echo '<tr><th>', _('Width (wx, wy, wz)'),"</th><td>(", $storage->wx, ', ', $storage->wy, ', ', $storage->wz, ")</td></tr>\n";
@@ -294,6 +292,9 @@ $storage = $sth->fetch(PDO::FETCH_OBJ);
<label for="sname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="sname" name="sname" value="<?=$storage->sname ?>">
</div>
<?php
form_create_select('stype', _('Type'), $opt_stype, $storage->stype);
?>
<div class="mb-3">
<label class="form-label"><?=_('Position (x, y, z) in mm')?></label>
<div class="row">
+58 -18
View File
@@ -80,7 +80,7 @@ if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// load filter from db
$flt = db_get_filter($user->id, 210);
$flt = db_get_filter($user->id, 210, ['txt']);
echo "<h1>$pagetitle</h1>\n";
@@ -91,10 +91,13 @@ echo "<h1>$pagetitle</h1>\n";
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body">
<div class="card-body d-flex flex-wrap gap-3">
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?? ''?>">
<input type="text" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?? ''?>">
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
@@ -110,20 +113,29 @@ $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', _('Tag'), "</th>";
echo '<th>', _('Description'), "</th>";
echo '<th>', _('Color'), "</th>";
echo "<th></th>";
echo "</tr>\n";
echo "</thead>\n";
$i = 0;
foreach ($res as $row) {
$i++; // record number
echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['tagid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", $row['tagname'], "</td>\n";
echo "<td>", $row['description'], "</td>\n";
echo "<td>", format_color($row['color']), "</td>\n";
echo "<td>";
// Action buttons
form_action_buttons($g_scriptname, $row['tagid']);
// Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['tagid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</td>\n";
echo "</tr>\n";
}
@@ -179,19 +191,47 @@ $sql = "SELECT objid, objtype FROM tagref WHERE tagid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$link = array(
'equip' => 'equipment.php',
'inv' => 'inventory.php',
'prov' => 'provisions.php',
'doc' => 'documents.php',
'proj' => 'projects.php',
'task' => 'task.php',
'maint' => 'maintenance.php'
);
echo '<p>';
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
$res = $sth->fetchAll();
foreach ($res as $row) {
// select object name or description depending on objecttype
// TODO function db_get_tag_target($objtype, $objid);
/*switch ($row['objtype']) {
case 'equip':
$sql = "SELECT ename FROM equipment WHERE eid=?";
$target = "equipment.php";
break;
case 'inv':
$sql = "SELECT invname FROM inventory WHERE invid=?";
$target = "inventory.php";
break;
case 'prov':
$sql = "SELECT provname FROM provisions WHERE provvid=?";
$target = "provisions.php";
break;
case 'doc':
$sql = "SELECT title FROM document WHERE docid=?";
$target = "documents.php";
break;
case 'proj':
$sql = "SELECT projname FROM project WHERE projid=?";
$target = "projects.php";
break;
case 'task':
$sql = "SELECT taskname FROM task WHERE taskid=?";
$target = "task.php";
break;
case 'maint':
$sql = "SELECT activities FROM maintenance WHERE maintid=?";
$target = 'maintenance.php';
break;
}
$sth = $pdo->prepare($sql);
$sth->execute([$row['objid']]);
$desc = $sth->fetchColumn(); */
[$target, $desc] = db_get_tag_target($row['objtype'], $row['objid']);
echo '<a href="', $target, '?f=view&id=', $row['objid'], '">', $desc, ' (', $row['objid'], '/', $row['objtype'], ")</a>\n";
}
} else {
echo _('Tag is not used anywhere');
@@ -242,7 +282,7 @@ $sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
echo '<a href="', [$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
}
} else {
echo _('Tag is not used anywhere');
+18 -6
View File
@@ -124,7 +124,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 206);
$flt = db_get_filter($user->id, 206, ['txt','prio', 'stat']);
$w = array('(t.vid=:vid OR t.vid IS NULL)');
$p = array(':vid' => $user->vid);
@@ -170,7 +170,8 @@ $sql = "SELECT t.taskid, t.vid, t.projid, t.taskname, t.priority, t.taskstate,"
if ($order) $sql .= $order;
// if pagination:
// $sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
try {
$sth->execute($p);
@@ -186,20 +187,28 @@ $res = $sth->fetchAll();
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body">
<div class="card-body d-flex flex-wrap gap-3">
<?php
filter_create_select('flt_prio', _('Priority'), $g_opt_all + $g_opt_none + $opt_priority, $flt->prio);
filter_create_select('flt_stat', _('State'), $g_opt_all + $opt_state, $flt->stat);
?>
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<input type="text" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?>">
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<input type="reset" class="btn btn-sm btn-secondary" value="<?=_('Clear')?>">
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div>
</form>
<?php
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
@@ -237,6 +246,9 @@ echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>'
echo "</tfoot>\n";
echo "</table>\n";
// additional pagination at bottom
echo $pagination;
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
@@ -301,7 +313,7 @@ if ($sth->rowCount() > 0) {
$n = 0;
foreach ($sth->fetchAll() as $row) {
$n += 1;
echo "<p>($n) {$row['annotation']}";
echo "<p>($n) ", nl2br($row['annotation']);
echo ' <a title="', _('Edit'), '" href="note.php?f=edit&id=', $row['noteid'], '"><i class="bi-pencil"></i></a>';
echo "</p>\n";
}
Executable
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/python3
import os
import sys
import configparser
from yms import database
from getpass import getpass
import bcrypt
cfg = {
'cfgfile': '~/.config/ymsgui.conf',
'host': 'localhost',
'db': 'yms',
'user': 'yms'
}
def set_pass():
newpass = getpass('New Password: ')
cryptpass = bcrypt.hashpw(newpass.encode(), bcrypt.gensalt())
print(cryptpass.decode())
sql = "UPDATE user SET pass=%s WHERE userid=%s"
def get_user():
username = input('Username: ')
sql = "SELECT userid FROM user WHERE login=%s"
db.cur.execute(sql, (username,))
row = db.cur.fetchone()
if not row:
print("User not found")
return -1
else:
return row[0]
if __name__ == "__main__":
config = configparser.ConfigParser()
configfile = os.path.expanduser(cfg['cfgfile']);
if not config.read(configfile):
print(f"Configuration file '{configfile}' not found.")
else:
cfg['host'] = config.get('DB', 'host')
cfg['db'] = config.get('DB', 'db')
cfg['user'] = config.get('DB', 'user')
cfg['pass'] = config.get('DB', 'pass')
db = database.Database(cfg['host'], cfg['db'])
if db.connect(cfg['user'], cfg['pass']):
print("Connected to database")
print(get_user())
db.disconnect()
else:
print("Cannot connect to database {}@{}".format(cfg['db'], cfg['host']))