Compare commits

..

3 Commits

Author SHA1 Message Date
19600ac7bf Merge branch 'main' of https://gitea.tpsoft.org/TPsoft.org/BugReport 2025-10-11 16:50:11 +02:00
e63be43639 pridany Maintenance pre modul TPsoft\DBmodel,
pridane poznamky,
pridana konfiguracia pre DEV a PROD,
2025-10-11 16:49:46 +02:00
995e0e40a5 uprava zobrazenie API pre parametre,
fix cesty pre logo SVG,
nastavenie DEV servera VITE pre vsetky interface
2025-10-11 15:37:51 +02:00
9 changed files with 171 additions and 55 deletions

View File

@ -4,6 +4,7 @@ require __DIR__ . '/../vendor/autoload.php';
use \Exception; use \Exception;
use \TPsoft\DBmodel\DBmodel; use \TPsoft\DBmodel\DBmodel;
use \TPsoft\BugreportBackend\Maintenance;
global $dbh; global $dbh;
@ -14,20 +15,6 @@ if (Configuration::DB_TYPE == 'mysql') {
} else { } else {
throw new Exception('Unknown database type'); throw new Exception('Unknown database type');
} }
/*
$dbh->tables = [ $maintenance = new Maintenance($dbh);
'reports' => [ $maintenance->database();
'name' => 'reports',
'primary_key_name' => 'report_id',
'allow_attributes' => [
'report_id' => 'varchar()',
'report_title' => 'varchar()',
'report_description' => 'varchar()',
'report_status' => 'varchar()',
'report_group' => 'varchar()',
'report_priority' => 'varchar()',
'created_dt' => 'varchar()',
],
],
];
*/

View File

@ -0,0 +1,81 @@
<?php
namespace TPsoft\BugreportBackend;
class Maintenance extends \TPsoft\DBmodel\Maintenance
{
public function database()
{
if (!$this->existsTable('options')) {
$this->checkDBTable('options', '
`key` VARCHAR(255) NOT NULL PRIMARY KEY,
`value` VARCHAR(255) NOT NULL
');
$this->dbver(1);
}
$dbver = $this->dbver();
if ($dbver == 1) {
$this->checkDBTable('reports', '
`report_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`report_title` varchar(255) DEFAULT NULL,
`report_description` text DEFAULT NULL,
`report_status` int(11) DEFAULT NULL,
`report_group` varchar(255) NOT NULL,
`report_priority` int(11) DEFAULT NULL,
`ordnum` int(11) DEFAULT NULL,
`created_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
');
$this->dbver(2);
$dbver = 2;
}
if ($dbver == 2) {
$this->checkDBTable('attachments', '
`attachment_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`report_id` int(11) NOT NULL,
`attachment_type` varchar(255) DEFAULT NULL,
`attachment_content` text DEFAULT NULL,
`created_dt` datetime DEFAULT NULL,
`updated_dt` datetime DEFAULT NULL
');
$this->dbver(3);
$dbver = 3;
}
}
protected function settings(string $key, ?string $value = null): string|false
{
if (is_null($value)) {
return $this->dbh->getOne(sprintf('SELECT `value` FROM `options` WHERE `key` = %s', $this->dbh->quote($key)));
} else {
$db_type = $this->dbh->getDBtype();
switch ($db_type) {
case 'mysql':
return $this->dbh->query(sprintf(
'INSERT INTO `options` (`key`, `value`) VALUES (%s, %s) ON DUPLICATE KEY UPDATE `value` = %s',
$this->dbh->quote($key),
$this->dbh->quote($value),
$this->dbh->quote($value)
)) !== false;
break;
case 'sqlite':
return $this->dbh->query(sprintf(
'INSERT INTO `options` (`key`, `value`) VALUES (%s, %s) ON CONFLICT(`key`) DO UPDATE SET `value` = %s',
$this->dbh->quote($key),
$this->dbh->quote($value),
$this->dbh->quote($value)
)) !== false;
break;
default:
new \Exception('Unknown DB type: ' . $db_type);
return false;
break;
}
}
}
protected function dbver(?string $ver = null)
{
return $this->settings('version', $ver);
}
}

21
doc/notes.txt Normal file
View File

@ -0,0 +1,21 @@
projekt/
├── backend/ # PHP časť (API, logika, DB)
│ ├── public/ # root pre webserver (index.php, assets)
│ │ └── index.php
│ ├── src/ # zdrojový PHP kód (kontroléry, modely, služby)
│ ├── vendor/ # Composer balíčky (gitignore!)
│ ├── composer.json
│ └── composer.lock
├── frontend/ # Vue časť
│ ├── src/ # Vue komponenty, views, store
│ ├── public/ # statické súbory (favicon, index.html template)
│ ├── dist/ # build výstup (gitignore!) → deploy do backend/public
│ ├── package.json
│ ├── package-lock.json
│ └── vite.config.js / vue.config.js
├── docker/ (voliteľné) # ak používaš Docker (Nginx, PHP-FPM, Node build)
└── README.md

View File

@ -0,0 +1 @@
VITE_BACKENDAPI_URL="https://192.168.0.101/BugReport/backend/public/API.php"

1
frontend/.env.production Normal file
View File

@ -0,0 +1 @@
VITE_BACKENDAPI_URL="/API.php"

View File

@ -2,7 +2,7 @@
<div id="header"> <div id="header">
<div class="logo"> <div class="logo">
<router-link to="/"> <router-link to="/">
<img src="/public/bugreport.svg" height="48" width="48" /> <img src="/bugreport.svg" height="48" width="48" />
</router-link> </router-link>
<router-link to="/"> <router-link to="/">
<h1>Bug Report</h1> <h1>Bug Report</h1>

View File

@ -462,6 +462,36 @@ button:focus-visible,
padding: 10px; padding: 10px;
text-align: justify; text-align: justify;
} }
#api ul li {
margin-bottom: 5px;
}
#api .param-type {
background-color: var(--color-bg0);
margin: 0px;
padding: 2px 5px;
text-align: center;
border-radius: 5px;
margin-left: 10px;
}
#api .param-optional {
background-color: var(--color-bg1);
margin: 0px;
padding: 2px 5px;
text-align: center;
border-radius: 5px;
margin-left: 10px;
}
#api .param-default {
background-color: var(--color-bg2);
margin: 0px;
padding: 2px 5px;
text-align: center;
border-radius: 5px;
margin-left: 10px;
}
#api .param-doc {
color: var(--color-text3);
}
/* ---------------------------------------------------- /* ----------------------------------------------------
07 - ABOUT 07 - ABOUT

View File

@ -24,51 +24,42 @@
<h4>Parametre</h4> <h4>Parametre</h4>
<p v-if="Object.keys(action.params).length == 0"> <p v-if="Object.keys(action.params).length == 0">
<font-awesome-icon :icon="['fas', 'circle-info']" /> <font-awesome-icon :icon="['fas', 'circle-info']" />
&nbsp; &nbsp; Ziadne parametre
Ziadne parametre
</p> </p>
<ul> <ul>
<li v-for="(param_desc, param_name) in action.params" :key="param_name"> <li v-for="param in action.params" :key="param_name">
<strong>{{ param_name }}</strong> <strong>{{ param.name }}</strong>
&ndash; <span class="param-type">{{ param.type }}</span>
{{ param_desc }} <span v-if="param.optional" class="param-optional">optional</span>
<span v-if="param.default != null" class="param-default">{{
param.default
}}</span>
<br />
<span class="param-doc">{{ param.doc }}</span>
</li> </li>
</ul> </ul>
<p>
<strong>Return</strong>
<span class="param-type">{{ action.return }}</span>
</p>
</div> </div>
</div> </div>
</template> </template>
<script> <script setup>
import { onMounted, ref } from "vue";
import backend from "../backend"; import backend from "../backend";
export default { const api_endpoint = ref(backend.endpont);
name: "API", const help = ref({ actions: {} });
components: {},
data() { onMounted(() => {
return { loadHelp();
api_endpoint: backend.endpont,
help: {
actions: {
help: {
name: "help",
description: "This help",
params: {
foo: "bar",
},
},
},
},
};
},
mounted() {
this.loadHelp();
},
methods: {
loadHelp() {
backend.help().then((response) => {
this.help = response;
}); });
},
}, function loadHelp() {
}; backend.help().then((response) => {
help.value = response;
});
}
</script> </script>

View File

@ -25,6 +25,10 @@ export default defineConfig(({ command, mode }) => {
__IS_BUILD__: JSON.stringify(isBuild), __IS_BUILD__: JSON.stringify(isBuild),
__IS_DEV__: JSON.stringify(isDev), __IS_DEV__: JSON.stringify(isDev),
}, },
server: {
host: true,
port: 5173
},
build: { build: {
outDir: "dist", outDir: "dist",
chunkSizeWarningLimit: 1000, // zvýšenie limitu na 1000 kB chunkSizeWarningLimit: 1000, // zvýšenie limitu na 1000 kB