rollback
This commit is contained in:
78
README.md
78
README.md
@@ -67,12 +67,65 @@ Die Anwendung berechnet automatisch die Pausenzeiten gemäß deutschem Arbeitsze
|
|||||||
- `DELETE /api/entries/:id` - Eintrag löschen
|
- `DELETE /api/entries/:id` - Eintrag löschen
|
||||||
- `GET /api/export?from=YYYY-MM-DD&to=YYYY-MM-DD` - Einträge als CSV exportieren
|
- `GET /api/export?from=YYYY-MM-DD&to=YYYY-MM-DD` - Einträge als CSV exportieren
|
||||||
|
|
||||||
## Lokale Ausführung
|
## Installation & Ausführung
|
||||||
|
|
||||||
### Voraussetzungen
|
### Repository klonen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.fx-se.de/maggot/timetracker.git
|
||||||
|
cd timetracker
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 1: Mit Docker Compose (Empfohlen)
|
||||||
|
|
||||||
|
**Voraussetzungen:**
|
||||||
|
- Docker und Docker Compose installiert
|
||||||
|
|
||||||
|
**Starten:**
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
**Logs ansehen:**
|
||||||
|
```bash
|
||||||
|
docker-compose logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
**Stoppen:**
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
**Stoppen und Daten löschen:**
|
||||||
|
```bash
|
||||||
|
docker-compose down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
Die Anwendung läuft auf:
|
||||||
|
```
|
||||||
|
http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Mit Docker (manuell)
|
||||||
|
|
||||||
|
**Docker-Image erstellen:**
|
||||||
|
```bash
|
||||||
|
docker build -t zeiterfassung .
|
||||||
|
```
|
||||||
|
|
||||||
|
**Container starten:**
|
||||||
|
```bash
|
||||||
|
docker run -p 3000:3000 -v $(pwd)/db:/app/db zeiterfassung
|
||||||
|
```
|
||||||
|
|
||||||
|
Das `-v` Flag bindet das Datenbankverzeichnis ein, um Daten zwischen Container-Neustarts zu erhalten.
|
||||||
|
|
||||||
|
### Option 3: Lokale Ausführung (ohne Docker)
|
||||||
|
|
||||||
|
**Voraussetzungen:**
|
||||||
- Node.js 18+ installiert
|
- Node.js 18+ installiert
|
||||||
|
|
||||||
### Installation
|
**Installation:**
|
||||||
|
|
||||||
1. Abhängigkeiten installieren:
|
1. Abhängigkeiten installieren:
|
||||||
```bash
|
```bash
|
||||||
@@ -89,25 +142,6 @@ npm start
|
|||||||
http://localhost:3000
|
http://localhost:3000
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ausführung mit Docker
|
|
||||||
|
|
||||||
### Docker-Image erstellen:
|
|
||||||
```bash
|
|
||||||
docker build -t zeiterfassung .
|
|
||||||
```
|
|
||||||
|
|
||||||
### Container starten:
|
|
||||||
```bash
|
|
||||||
docker run -p 3000:3000 -v $(pwd)/db:/app/db zeiterfassung
|
|
||||||
```
|
|
||||||
|
|
||||||
Das `-v` Flag bindet das Datenbankverzeichnis ein, um Daten zwischen Container-Neustarts zu erhalten.
|
|
||||||
|
|
||||||
### Anwendung aufrufen:
|
|
||||||
```
|
|
||||||
http://localhost:3000
|
|
||||||
```
|
|
||||||
|
|
||||||
## CSV-Export-Format
|
## CSV-Export-Format
|
||||||
|
|
||||||
Die exportierte CSV-Datei enthält folgende Spalten:
|
Die exportierte CSV-Datei enthält folgende Spalten:
|
||||||
|
|||||||
27
docker-compose.yml
Normal file
27
docker-compose.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
timetracker:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: timetracker-app
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
# Persistent volume for SQLite database
|
||||||
|
- timetracker-data:/app/db
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3000
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
start_period: 5s
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
timetracker-data:
|
||||||
|
driver: local
|
||||||
@@ -1462,7 +1462,9 @@ async function bulkSetLocation(location) {
|
|||||||
for (const id of selectedEntries) {
|
for (const id of selectedEntries) {
|
||||||
const entry = entries.find(e => e.id === id);
|
const entry = entries.find(e => e.id === id);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
const success = await updateEntry(id, entry.date, entry.startTime, entry.endTime, entry.pauseMinutes, location);
|
// Convert date from YYYY-MM-DD to DD.MM.YYYY for updateEntry
|
||||||
|
const formattedDate = formatDateDisplay(entry.date);
|
||||||
|
const success = await updateEntry(id, formattedDate, entry.startTime, entry.endTime, entry.pauseMinutes, location);
|
||||||
if (success) {
|
if (success) {
|
||||||
updated++;
|
updated++;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user