Compare commits
7 Commits
feature/st
...
feature/ti
| Author | SHA1 | Date | |
|---|---|---|---|
| 462d0bb66e | |||
| 56b79e1ecf | |||
| 72cb91f865 | |||
| 3833f2f978 | |||
| 5e0b59bacf | |||
| 55f5a663fe | |||
| 8197a0796c |
@@ -10,6 +10,7 @@ import TimeRecorder from './TimeRecorder.svelte';
|
||||
let key = $state(null);
|
||||
const router = useTinyRouter();
|
||||
const modules = $state([]);
|
||||
let expand = $state(false);
|
||||
|
||||
async function fetchModules(){
|
||||
const url = `${location.protocol}//${location.host.replace('5173','8080')}/legacy/user/modules`;
|
||||
@@ -27,6 +28,7 @@ async function fetchModules(){
|
||||
|
||||
function onclick(e){
|
||||
e.preventDefault();
|
||||
expand = false;
|
||||
let href = e.target.getAttribute('href');
|
||||
if (href) router.navigate(href);
|
||||
return false;
|
||||
@@ -34,6 +36,7 @@ function onclick(e){
|
||||
|
||||
async function search(e){
|
||||
e.preventDefault();
|
||||
expand = false;
|
||||
router.navigate(`/search?key=${key}`);
|
||||
return false;
|
||||
}
|
||||
@@ -47,11 +50,12 @@ onMount(fetchModules);
|
||||
}
|
||||
</style>
|
||||
|
||||
<nav>
|
||||
<nav class={expand?"":"collapsed"}>
|
||||
<form onsubmit={search}>
|
||||
<input type="text" bind:value={key} />
|
||||
<button type="submit">{t('search')}</button>
|
||||
</form>
|
||||
<button class="symbol" onclick={e => expand = !expand}></button>
|
||||
<a href="/user" {onclick} class="user">{t('users')}</a>
|
||||
<a href="/company" {onclick} class="company">{t('companies')}</a>
|
||||
<a href="/project" {onclick} class="project">{t('projects')}</a>
|
||||
@@ -72,7 +76,7 @@ onMount(fetchModules);
|
||||
{#if module.name.trim()}<a href={module.url}>{module.name}</a>{/if}
|
||||
{/each}
|
||||
{#if user.name }
|
||||
<a onclick={logout}>{t('logout_user',{user:user.name})}</a>
|
||||
<a class="logout" onclick={logout}>{t('logout_user',{user:user.name})}</a>
|
||||
{/if}
|
||||
<TimeRecorder />
|
||||
</nav>
|
||||
|
||||
@@ -14,6 +14,23 @@
|
||||
} = $props();
|
||||
|
||||
let editable = $derived(document.state == 1);
|
||||
let sums = $derived.by(calcSums);
|
||||
|
||||
function calcSums(){
|
||||
let data = {}
|
||||
let net = 0;
|
||||
let gross = 0;
|
||||
for (let pos of Object.values(document.positions)){
|
||||
let net_price = pos.unit_price * pos.amount;
|
||||
let tax = +pos.tax;
|
||||
data[tax] = net_price + (data[tax] ? data[tax] : 0);
|
||||
net += net_price;
|
||||
}
|
||||
for (let [tax, price] of Object.entries(data)) gross += price * (+tax+100)/100;
|
||||
data['net'] = net/100;
|
||||
data['gross'] = (gross/100).toFixed(2);
|
||||
return data;
|
||||
}
|
||||
|
||||
async function updatePositions(resp){
|
||||
let json = await resp.json();
|
||||
@@ -22,7 +39,7 @@
|
||||
}
|
||||
|
||||
async function movePos(number,step){
|
||||
const url = api(`document/${document.id}/position`);
|
||||
const url = api(`document/${document.id}/position`);
|
||||
const resp = await fetch(url,{
|
||||
method : 'PATCH',
|
||||
credentials: 'include',
|
||||
@@ -38,7 +55,7 @@
|
||||
async function drop(number){
|
||||
let confirmed = confirm(t('confirm_deletion').replace('{pos}',document.positions[number].item));
|
||||
if (!confirmed) return;
|
||||
const url = api(`document/${document.id}/position`);
|
||||
const url = api(`document/${document.id}/position`);
|
||||
const resp = await fetch(url,{
|
||||
method : 'DELETE',
|
||||
credentials: 'include',
|
||||
@@ -73,9 +90,9 @@
|
||||
<tr class="sums">
|
||||
<td colspan="2"></td>
|
||||
<td>{t('net_sum')}</td>
|
||||
<td>{document.net_sum/100} {document.currency}</td>
|
||||
<td>{sums['net']} {document.currency}</td>
|
||||
<td colspan="2">{t('gross_sum')}</td>
|
||||
<td>{document.gross_sum/100} {document.currency}</td>
|
||||
<td>{sums['gross']} {document.currency}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -307,4 +307,11 @@ tr:hover .taglist .tag button {
|
||||
|
||||
.easylist .filter{
|
||||
background: black;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
#app nav a{
|
||||
background: black;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
@@ -426,6 +426,48 @@ a.wikilink{
|
||||
float: right;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 900px) {
|
||||
#app nav button.symbol{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
body{
|
||||
padding-top: 13px;
|
||||
}
|
||||
#app nav{
|
||||
grid-template-columns: 33% 34% 33%;
|
||||
display: grid;
|
||||
padding: 0 10px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
}
|
||||
#app nav form{
|
||||
grid-column-end: span 2;
|
||||
}
|
||||
#app nav .logout{
|
||||
grid-column-end: 4;
|
||||
}
|
||||
|
||||
#app nav.collapsed a{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#app nav a {
|
||||
font-size: 19px !important;
|
||||
display: grid;
|
||||
text-align: center;
|
||||
border: 1px solid;
|
||||
margin: 5px;
|
||||
padding: 15px 0;
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.grid2{
|
||||
display: grid;
|
||||
@@ -455,6 +497,15 @@ a.wikilink{
|
||||
.easylist input{
|
||||
font-size: 20px;
|
||||
}
|
||||
#app nav{
|
||||
grid-template-columns: auto auto;
|
||||
}
|
||||
#app nav form{
|
||||
grid-column-end: span 1;
|
||||
}
|
||||
#app nav .logout{
|
||||
grid-column-end: 3;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset.vcard{
|
||||
|
||||
@@ -297,4 +297,11 @@ tr:hover .taglist .tag button {
|
||||
|
||||
.easylist .filter{
|
||||
background: black;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
#app nav a{
|
||||
background: black;
|
||||
color: orange;
|
||||
}
|
||||
}
|
||||
@@ -504,6 +504,50 @@ a.wikilink{
|
||||
float: right;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 900px) {
|
||||
#app nav button.symbol{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
body{
|
||||
padding-top: 30px;
|
||||
}
|
||||
#app nav{
|
||||
grid-template-columns: 33% 34% 33%;
|
||||
display: grid;
|
||||
padding: 0 10px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
#app nav form{
|
||||
grid-column-end: span 2;
|
||||
}
|
||||
#app nav .logout{
|
||||
grid-column-end: 4;
|
||||
}
|
||||
|
||||
#app nav.collapsed a{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#app nav a {
|
||||
font-size: 19px !important;
|
||||
display: grid;
|
||||
text-align: center;
|
||||
border: 1px solid;
|
||||
margin: 5px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
#app nav a::before {
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.grid2{
|
||||
display: grid;
|
||||
@@ -533,6 +577,15 @@ a.wikilink{
|
||||
.easylist input{
|
||||
font-size: 20px;
|
||||
}
|
||||
#app nav{
|
||||
grid-template-columns: auto auto;
|
||||
}
|
||||
#app nav form{
|
||||
grid-column-end: span 1;
|
||||
}
|
||||
#app nav .logout{
|
||||
grid-column-end: 3;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset.vcard{
|
||||
|
||||
@@ -282,4 +282,11 @@ tr:hover .taglist .tag button {
|
||||
.easylist fieldset {
|
||||
border-color: blue;
|
||||
color: blue;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
#app nav a{
|
||||
background: white;
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
@@ -426,6 +426,48 @@ a.wikilink{
|
||||
float: right;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 900px) {
|
||||
#app nav button.symbol{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
body{
|
||||
padding-top: 13px;
|
||||
}
|
||||
#app nav{
|
||||
grid-template-columns: 33% 34% 33%;
|
||||
display: grid;
|
||||
padding: 0 10px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
}
|
||||
#app nav form{
|
||||
grid-column-end: span 2;
|
||||
}
|
||||
#app nav .logout{
|
||||
grid-column-end: 4;
|
||||
}
|
||||
|
||||
#app nav.collapsed a{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#app nav a {
|
||||
font-size: 19px !important;
|
||||
display: grid;
|
||||
text-align: center;
|
||||
border: 1px solid;
|
||||
margin: 5px;
|
||||
padding: 15px 0;
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.grid2{
|
||||
display: grid;
|
||||
@@ -455,6 +497,15 @@ a.wikilink{
|
||||
.easylist input{
|
||||
font-size: 20px;
|
||||
}
|
||||
#app nav{
|
||||
grid-template-columns: auto auto;
|
||||
}
|
||||
#app nav form{
|
||||
grid-column-end: span 1;
|
||||
}
|
||||
#app nav .logout{
|
||||
grid-column-end: 3;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset.vcard{
|
||||
|
||||
Reference in New Issue
Block a user