8 Commits
23 changed files with 78804 additions and 178 deletions
+6
View File
@@ -24,3 +24,9 @@ services:
volumes:
- ./api:/var/www
- logs:/var/www/logs
ui:
build: ./ui/
ports:
- 80:80
depends_on:
- api
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
install_api_dependence() {
cd api/ || exit 2
composer install
cd ..
}
build_ui() {
cd ui/ || exit 2
npm run build
cd ..
}
test_unit() {
pwd
cd api/ || exit 2
./vendor/bin/codecept run unit
cd ..
}
test_api() {
cd api/ || exit 2
./vendor/bin/codecept run api
cd ..
}
composer_run() {
docker-compose up -d
}
install_api_dependence && build_ui && test_unit && composer_run && test_api
+3
View File
@@ -0,0 +1,3 @@
FROM httpd:2.4
COPY ./public/ /usr/local/apache2/htdocs/
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.
Binary file not shown.
+71
View File
@@ -0,0 +1,71 @@
<script context="module">
const MyFetch = {
'post': async (rest_url, request_body) => {
return MyFetch._fetch(rest_url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'omit',
headers: {
'Content-Type': 'application/json',
},
body: request_body,
}, {})
},
'put': async (rest_url, http_body) => {
return MyFetch._fetch(rest_url, {
method: 'PUT',
mode: 'cors',
cache: 'no-cache',
credentials: 'omit',
headers: {
'Content-Type': 'application/json',
},
body: http_body,
}, {})
},
'get': async (rest_url, query_parameters) => {
if (query_parameters !== null) {
let filter = []
for (let parameter in query_parameters) {
filter.push(parameter + '=' + query_parameters[parameter])
}
if (filter.length > 0) {
rest_url += '?' + filter.join('&')
}
}
return MyFetch._fetch(rest_url, {})
},
'_fetch': async (rest_url, request_options) => {
// noinspection JSUnresolvedVariable
let response = await fetch(env.API_URL + rest_url, request_options).catch(err => {
console.error(err)
return null
})
if (!response.ok) {
throw new Error('Fail!')
}
return response.json()
}
}
export class WorkingHoursRepository {
static 'browse'() {
return MyFetch.get('/working-hours')
}
static 'read'(date) {
return MyFetch.get('/working-hours/' + date)
}
static async 'add'(record) {
console.debug(record);
return MyFetch.post('/working-hours', JSON.stringify(record))
}
static async 'update'(date, record) {
console.debug(record);
return MyFetch.put('/working-hours/' + date, JSON.stringify(record))
}
}
</script>
+29 -124
View File
@@ -1,128 +1,49 @@
<script>
export let params;
let title = "Bearbeitung Einträge"
const TITLE = "Bearbeitung Einträge";
import IconifyIcon from '@iconify/svelte';
import wrenchIcon from '@iconify-icons/oi/wrench';
import checkIcon from '@iconify-icons/oi/check';
import xIcon from '@iconify-icons/oi/x';
import documentIcon from '@iconify-icons/oi/document';
import {WorkingHoursRepository} from '../components/Repositories.svelte'
import NewByDay from "./working-hours/NewByDay.svelte";
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();
const Controller = {
'listRecords': () => {
WorkingHoursRepository.browse().then(data => {
activeRecord = null;
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': async record => {
console.log(record);
// noinspection JSUnresolvedVariable
await fetch(env.API_URL + '/working-hours', {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'omit',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(record)
})
.then(res => {
if (!res.ok) {
throw new Error('Fail!');
}
})
.then(() => {
Controller.listRecords();
})
.catch(err => {
console.log(err);
});
},
'update': async (date, record) => {
console.log(record);
// noinspection JSUnresolvedVariable
await fetch(env.API_URL + '/working-hours/' + date, {
method: 'PUT',
mode: 'cors',
cache: 'no-cache',
credentials: 'omit',
headers: {
'Content-Type': 'application/json'
},
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;
activeRecord = {workingTime: '00:00:00', workingDay: null};
},
'saveRecord': () => {
if (newRecord === true) {
Records.add(activeRecord);
if (activeRecord.workingDay === null) {
WorkingHoursRepository.add(activeRecord).then(() => {
Controller.listRecords()
});
} else {
Records.update(activeRecord.workingDay, activeRecord);
WorkingHoursRepository.update(activeRecord.workingDay, activeRecord).then(() => {
Controller.listRecords()
})
}
},
'selectActiveRecord': record => Records.read(record.workingDay),
'selectActiveRecord': record => WorkingHoursRepository.read(record.workingDay).then(data => {
activeRecord = data;
if (activeRecord === null) {
Controller.listRecords()
}
}),
'cancelActiveRecord': () => {
activeRecord = null;
newRecord = false;
}
};
const initSite = () => {
@@ -132,14 +53,14 @@
</script>
<svelte:head>
<title>{title}</title>
<title>{TITLE}</title>
</svelte:head>
{#if activeRecord === null}
<section id="list-records">
<section id="list-records">
<header>
<h1>{title}</h1>
<h1>{TITLE}</h1>
</header>
{#if activeRecord === null}
<article>
{#if params.isLoading === true}
<p>Loading...</p>
@@ -181,27 +102,11 @@
</table>
{/if}
</article>
</section>
{:else}
<section id="edit-record">
<header>
<h1>{title}</h1>
</header>
{:else}
<article>
<!--suppress HtmlUnknownTarget -->
<form action="/working-hours" name="editRecord">
<fieldset name="record-data">
<div>
<label for="workingDay">Arbeitstag</label>
<input bind:value={activeRecord.workingDay} type="date"
id="workingDay" required pattern="\d\{4}-[0-1]\d-[0-3]\d\">
</div>
<div>
<label for="workingTime">Arbeitszeit</label>
<input bind:value={activeRecord.workingTime} placeholder="Arbeitszeit" type="time"
id="workingTime" required pattern="[0-5]\d:[0-5]\d:[0-5]\d">
</div>
</fieldset>
<NewByDay activeRecord="{activeRecord}"/>
<fieldset name="buttons">
<button on:click={Controller.saveRecord} type="button">Übernehmen
<IconifyIcon icon={checkIcon} color="green"/>
@@ -212,5 +117,5 @@
</fieldset>
</form>
</article>
</section>
{/if}
{/if}
</section>
@@ -0,0 +1,17 @@
<script>
export let activeRecord
</script>
<fieldset name="record-data">
<div>
<label for="workingDay">Arbeitstag</label>
<input bind:value={activeRecord.workingDay} type="date"
id="workingDay" required pattern="\d\{4}-[0-1]\d-[0-3]\d\">
</div>
<div>
<label for="workingTime">Arbeitszeit</label>
<input bind:value={activeRecord.workingTime} placeholder="Arbeitszeit" type="time"
id="workingTime" required pattern="[0-5]\d:[0-5]\d:[0-5]\d">
</div>
</fieldset>