js-rest-aktionen #6

Merged
TorstenHettstedt merged 9 commits from js-rest-aktionen into master 2021-04-12 14:11:32 +02:00
11 changed files with 299 additions and 93 deletions
+2
View File
@@ -0,0 +1,2 @@
# Url ohne abschlißenden Slash
API_URL= http://localhost:8080
+1
View File
@@ -3,3 +3,4 @@ node_modules
package-lock.json package-lock.json
yarn.lock yarn.lock
public public
/.env
+1
View File
@@ -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
View File
@@ -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
+5 -45
View File
@@ -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);
+2 -3
View File
@@ -1,6 +1,5 @@
<Views {params} /> <Views />
<script> <script>
import Views from "./Views.svelte"; import Views from "./WeeklyViews.svelte";
export let params;
</script> </script>
+31
View File
@@ -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
View File
@@ -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>
+31
View File
@@ -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} />
+169 -26
View File
@@ -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
Outdated
Review

Es ist eine Überlegung wert, die einzelnen anonymen Funktionen zu einem Objekt zusammenzufassen.

Es ist eine Überlegung wert, die einzelnen anonymen Funktionen zu einem Objekt zusammenzufassen.
};
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
Outdated
Review

Es sollte das aktuelle Datum als Defaultwert genommen werden.

Es sollte das aktuelle Datum als Defaultwert genommen werden.
Outdated
Review

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
Review

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}
1
@@ -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>
+31
View File
@@ -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} />