js-rest-aktionen #6
@@ -0,0 +1,2 @@
|
|||||||
|
# Url ohne abschlißenden Slash
|
||||||
|
API_URL= http://localhost:8080
|
||||||
@@ -3,3 +3,4 @@ node_modules
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
public
|
public
|
||||||
|
/.env
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"@rollup/plugin-commonjs": "^15.0.0",
|
"@rollup/plugin-commonjs": "^15.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^9.0.0",
|
"@rollup/plugin-node-resolve": "^9.0.0",
|
||||||
"@rollup/plugin-replace": "^2.3.0",
|
"@rollup/plugin-replace": "^2.3.0",
|
||||||
|
"dotenv": "^8.2.0",
|
||||||
"npm-run-all": "^4.1.3",
|
"npm-run-all": "^4.1.3",
|
||||||
"rollup": "^2.30.0",
|
"rollup": "^2.30.0",
|
||||||
"rollup-plugin-svelte": "^6.0.0",
|
"rollup-plugin-svelte": "^6.0.0",
|
||||||
|
|||||||
+3
-1
@@ -3,6 +3,7 @@ import replace from '@rollup/plugin-replace';
|
|||||||
import resolve from '@rollup/plugin-node-resolve';
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
import commonjs from '@rollup/plugin-commonjs';
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
import { terser } from 'rollup-plugin-terser';
|
import { terser } from 'rollup-plugin-terser';
|
||||||
|
import {config} from 'dotenv';
|
||||||
|
|
||||||
const production = !process.env.ROLLUP_WATCH;
|
const production = !process.env.ROLLUP_WATCH;
|
||||||
|
|
||||||
@@ -35,7 +36,8 @@ export default {
|
|||||||
commonjs(),
|
commonjs(),
|
||||||
|
|
||||||
replace({
|
replace({
|
||||||
'process.env.NODE_ENV': JSON.stringify(production ? 'production' : 'development')
|
'process.env.NODE_ENV': JSON.stringify(production ? 'production' : 'development'),
|
||||||
|
'env': JSON.stringify({...config().parsed /* attached the .env config*/})
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// If we're building for production (npm run build
|
// If we're building for production (npm run build
|
||||||
|
|||||||
@@ -45,52 +45,12 @@
|
|||||||
addEventListener('pushstate', track);
|
addEventListener('pushstate', track);
|
||||||
addEventListener('popstate', track);
|
addEventListener('popstate', track);
|
||||||
|
|
||||||
|
|
||||||
let w = {
|
|
||||||
"period": "2020#01",
|
|
||||||
"workingDays": 20,
|
|
||||||
"totalHours": "99:00:00",
|
|
||||||
"overtime": "10:22:00"
|
|
||||||
};
|
|
||||||
let weekly = {
|
|
||||||
"title" : "Wochenansicht",
|
|
||||||
"records" : [w, w]
|
|
||||||
};
|
|
||||||
let m = {
|
|
||||||
"period": "2020-01",
|
|
||||||
"workingDays": 20,
|
|
||||||
"totalHours": "99:00:00",
|
|
||||||
"overtime": "10:22:00"
|
|
||||||
};
|
|
||||||
let monthly = {
|
|
||||||
"title" : "Monatsansicht",
|
|
||||||
"records" : [m, m]
|
|
||||||
};
|
|
||||||
let y = {
|
|
||||||
"period": "2020",
|
|
||||||
"workingDays": 20,
|
|
||||||
"totalHours": "99:00:00",
|
|
||||||
"overtime": "10:22:00"
|
|
||||||
};
|
|
||||||
let yearly = {
|
|
||||||
"title" : "Jahresansicht",
|
|
||||||
"records" : [y, y]
|
|
||||||
};
|
|
||||||
let r = {
|
|
||||||
"workingDay": "2020-01-15",
|
|
||||||
"workingTime": "09:00:00"
|
|
||||||
};
|
|
||||||
let records = {
|
|
||||||
"title" : "Einträge",
|
|
||||||
"records" : [r, r]
|
|
||||||
};
|
|
||||||
|
|
||||||
const router = Navaid('/')
|
const router = Navaid('/')
|
||||||
.on('/', () => run(import('../routes/Home.svelte'), weekly))
|
.on('/', () => run(import('../routes/Home.svelte')))
|
||||||
.on('/views/weekly', () => run(import('../routes/Views.svelte'), weekly))
|
.on('/views/weekly', () => run(import('../routes/WeeklyViews.svelte')))
|
||||||
.on('/views/monthly', () => run(import('../routes/Views.svelte'), monthly))
|
.on('/views/monthly', () => run(import('../routes/MonthlyViews.svelte')))
|
||||||
.on('/views/yearly', () => run(import('../routes/Views.svelte'), yearly))
|
.on('/views/yearly', () => run(import('../routes/YearlyViews.svelte')))
|
||||||
.on('/working-hours', () => run(import('../routes/WorkingHours.svelte'), records))
|
.on('/working-hours', () => run(import('../routes/WorkingHours.svelte')))
|
||||||
.listen();
|
.listen();
|
||||||
|
|
||||||
onDestroy(router.unlisten);
|
onDestroy(router.unlisten);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<Views {params} />
|
<Views />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Views from "./Views.svelte";
|
import Views from "./WeeklyViews.svelte";
|
||||||
export let params;
|
|
||||||
</script>
|
</script>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<script>
|
||||||
|
import Views from "./Views.svelte";
|
||||||
|
export let params;
|
||||||
|
params = {
|
||||||
|
title: 'Monatsansicht',
|
||||||
|
records: [],
|
||||||
|
isLoading: true
|
||||||
|
}
|
||||||
|
const View = {
|
||||||
|
'browse': () => {
|
||||||
|
fetch(env.API_URL + '/views/working-hours/monthly')
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Fail!');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
params.records = data;
|
||||||
|
params.isLoading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
params.isLoading = false;
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
View.browse();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Views {params} />
|
||||||
+23
-18
@@ -1,5 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
export let params;
|
export let params;
|
||||||
|
console.log(params)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@@ -11,25 +12,29 @@
|
|||||||
<h1>{params.title}</h1>
|
<h1>{params.title}</h1>
|
||||||
</header>
|
</header>
|
||||||
<article>
|
<article>
|
||||||
<table>
|
{#if params.isLoading === true}
|
||||||
<thead>
|
<p>Loading...</p>
|
||||||
<tr>
|
{:else}
|
||||||
<th>Zeitraum</th>
|
<table>
|
||||||
<th>Arbeitstage</th>
|
<thead>
|
||||||
<th>Arbeitsstunden</th>
|
|
||||||
<th>Über- / Unterstunden</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{#each params.records as record}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{record.period}</td>
|
<th>Zeitraum</th>
|
||||||
<td>{record.workingDays}</td>
|
<th>Arbeitstage</th>
|
||||||
<td>{record.totalHours}</td>
|
<th>Arbeitsstunden</th>
|
||||||
<td>{record.overtime}</td>
|
<th>Über- / Unterstunden</th>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
{#each params.records as record}
|
||||||
|
<tr>
|
||||||
|
<td>{record.period}</td>
|
||||||
|
<td>{record.workingDays}</td>
|
||||||
|
<td>{record.totalHours}</td>
|
||||||
|
<td>{record.overtime}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<script>
|
||||||
|
import Views from "./Views.svelte";
|
||||||
|
export let params;
|
||||||
|
params = {
|
||||||
|
title: 'Wochenansicht',
|
||||||
|
records: [],
|
||||||
|
isLoading: true
|
||||||
|
}
|
||||||
|
const View = {
|
||||||
|
'browse': () => {
|
||||||
|
fetch(env.API_URL + '/views/working-hours/weekly')
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Fail!');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
params.records = data;
|
||||||
|
params.isLoading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
params.isLoading = false;
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
View.browse();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Views {params} />
|
||||||
@@ -3,10 +3,136 @@
|
|||||||
let title = "Bearbeitung Einträge"
|
let title = "Bearbeitung Einträge"
|
||||||
import IconifyIcon from '@iconify/svelte';
|
import IconifyIcon from '@iconify/svelte';
|
||||||
import wrenchIcon from '@iconify-icons/oi/wrench';
|
import wrenchIcon from '@iconify-icons/oi/wrench';
|
||||||
import trashIcon from '@iconify-icons/oi/trash';
|
|
||||||
import checkIcon from '@iconify-icons/oi/check';
|
import checkIcon from '@iconify-icons/oi/check';
|
||||||
import xIcon from '@iconify-icons/oi/x';
|
import xIcon from '@iconify-icons/oi/x';
|
||||||
|
import documentIcon from '@iconify-icons/oi/document';
|
||||||
let activeRecord = null;
|
let activeRecord = null;
|
||||||
|
let newRecord = false;
|
||||||
|
params = {
|
||||||
|
title: 'Einträge',
|
||||||
|
records: [],
|
||||||
|
isLoading: true
|
||||||
|
}
|
||||||
|
const Records = {
|
||||||
|
'browse': () => {
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
fetch(env.API_URL + '/working-hours')
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Fail!');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
Controller.cancelActiveRecord();
|
||||||
|
params.records = data;
|
||||||
|
params.isLoading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
params.isLoading = false;
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'read': date => {
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
fetch(env.API_URL + '/working-hours/' + date)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Fail!');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
activeRecord = data;
|
||||||
|
if (date === null) {
|
||||||
|
Controller.listRecords();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'add': record => {
|
||||||
|
console.log(record);
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
fetch(env.API_URL + '/working-hours', {
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'no-cors',
|
||||||
|
cache: 'no-cache',
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
redirect: 'follow',
|
||||||
|
referrerPolicy: 'no-referrer',
|
||||||
|
body: JSON.stringify(record)
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Fail!');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
Controller.listRecords();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'update': (date, record) => {
|
||||||
|
console.log(record);
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
fetch(env.API_URL + '/working-hours/' + date, {
|
||||||
|
method: 'PUT',
|
||||||
|
mode: 'no-cors',
|
||||||
|
cache: 'no-cache',
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
redirect: 'follow',
|
||||||
|
referrerPolicy: 'no-referrer',
|
||||||
|
body: JSON.stringify(record)
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Fail!');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
Controller.listRecords();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Controller = {
|
||||||
|
'listRecords': () => {
|
||||||
|
Controller.cancelActiveRecord();
|
||||||
|
Records.browse();
|
||||||
|
},
|
||||||
|
'newRecord': () => {
|
||||||
|
activeRecord = {workingTime: '00:00:00'};
|
||||||
|
newRecord = true;
|
||||||
|
},
|
||||||
|
'saveRecord': () => {
|
||||||
|
if (newRecord === true) {
|
||||||
|
Records.add(activeRecord);
|
||||||
|
} else {
|
||||||
|
Records.update(activeRecord.workingDay, activeRecord);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'selectActiveRecord': record => Records.read(record.workingDay),
|
||||||
|
'cancelActiveRecord': () => {
|
||||||
|
activeRecord = null;
|
||||||
|
newRecord = false;
|
||||||
|
}
|
||||||
|
TorstenHettstedt marked this conversation as resolved
Outdated
|
|||||||
|
};
|
||||||
|
const initSite = () => {
|
||||||
|
Controller.listRecords()
|
||||||
|
};
|
||||||
|
initSite()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@@ -19,27 +145,40 @@
|
|||||||
<h1>{title}</h1>
|
<h1>{title}</h1>
|
||||||
</header>
|
</header>
|
||||||
<article>
|
<article>
|
||||||
<table>
|
{#if params.isLoading === true}
|
||||||
<thead>
|
<p>Loading...</p>
|
||||||
<tr>
|
{:else}
|
||||||
<th>Datum</th>
|
<!--suppress HtmlUnknownTarget -->
|
||||||
<th>Arbeitsstunden</th>
|
<form action="/working-hours">
|
||||||
<th>Aktionen</th>
|
<fieldset>
|
||||||
</tr>
|
<button on:click={Controller.newRecord}>Neuer Eintrag
|
||||||
</thead>
|
<IconifyIcon icon={documentIcon}/>
|
||||||
<tbody>
|
</button>
|
||||||
{#each params.records as record}
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{record.workingDay}</td>
|
<th>Datum</th>
|
||||||
<td>{record.workingTime}</td>
|
<th>Arbeitsstunden</th>
|
||||||
<td>
|
<th>Aktionen</th>
|
||||||
<button>Bearbeiten <IconifyIcon icon={wrenchIcon} /></button>
|
|
||||||
<button>Löschen <IconifyIcon icon={trashIcon} color="red" /></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
{#each params.records as record}
|
||||||
|
<tr>
|
||||||
|
<td>{record.workingDay}</td>
|
||||||
|
<td>{record.workingTime}</td>
|
||||||
|
TorstenHettstedt marked this conversation as resolved
Outdated
TorstenHettstedt
commented
Es sollte das aktuelle Datum als Defaultwert genommen werden. Es sollte das aktuelle Datum als Defaultwert genommen werden.
TorstenHettstedt
commented
Wird leider nicht unterstützt. Wird leider nicht unterstützt.
|
|||||||
|
<td>
|
||||||
|
<button on:click={() => Controller.selectActiveRecord(record)}>Bearbeiten
|
||||||
|
<IconifyIcon icon={wrenchIcon}/>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
TorstenHettstedt marked this conversation as resolved
TorstenHettstedt
commented
Es sollten auch die Sekunden eintragbar sein und der Defaultwert sollte '00:00:00' sein. Es sollten auch die Sekunden eintragbar sein und der Defaultwert sollte '00:00:00' sein.
|
|||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -53,18 +192,22 @@
|
|||||||
<fieldset name="record-data">
|
<fieldset name="record-data">
|
||||||
<div>
|
<div>
|
||||||
<label for="workingDay">Arbeitstag</label>
|
<label for="workingDay">Arbeitstag</label>
|
||||||
<!--suppress JSUnresolvedVariable -->
|
<input bind:value={activeRecord.workingDay} type="date"
|
||||||
<input bind:value={activeRecord.workingDay} placeholder="Arbeitstag" type="date" id="workingDay">
|
id="workingDay" required pattern="\d{4}-\d{2}-\d{2}">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="workingTime">Arbeitszeit</label>
|
<label for="workingTime">Arbeitszeit</label>
|
||||||
<!--suppress JSUnresolvedVariable -->
|
<input bind:value={activeRecord.workingTime} placeholder="Arbeitszeit" type="time"
|
||||||
<input bind:value={activeRecord.workingTime} placeholder="Arbeitszeit" type="time" id="workingTime">
|
id="workingTime" required pattern="[0-5]\d:[0-5]\d:[0-5]\d">
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset name="buttons">
|
<fieldset name="buttons">
|
||||||
<button>Übernehmen <IconifyIcon icon={checkIcon} color="green" /></button>
|
<button on:click={Controller.saveRecord}>Übernehmen
|
||||||
<button>Abbrechen <IconifyIcon icon={xIcon} /></button>
|
<IconifyIcon icon={checkIcon} color="green"/>
|
||||||
|
</button>
|
||||||
|
<button on:click={Controller.cancelActiveRecord}>Abbrechen
|
||||||
|
<IconifyIcon icon={xIcon}/>
|
||||||
|
</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<script>
|
||||||
|
import Views from "./Views.svelte";
|
||||||
|
export let params;
|
||||||
|
params = {
|
||||||
|
title: 'Jahresansicht',
|
||||||
|
records: [],
|
||||||
|
isLoading: true
|
||||||
|
}
|
||||||
|
const View = {
|
||||||
|
'browse': () => {
|
||||||
|
fetch(env.API_URL + '/views/working-hours/yearly')
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Fail!');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
params.records = data;
|
||||||
|
params.isLoading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
params.isLoading = false;
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
View.browse();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Views {params} />
|
||||||
Reference in New Issue
Block a user
Es ist eine Überlegung wert, die einzelnen anonymen Funktionen zu einem Objekt zusammenzufassen.