Compare commits
18 Commits
855cd6f34f
...
2.0.0-rc.3
| Author | SHA1 | Date | |
|---|---|---|---|
| 18b2cbc074 | |||
| 560c539b19 | |||
| 502955d32f | |||
| cfd77ae28d | |||
| 1daf4db167 | |||
| 3322f7e9bc | |||
| 4b9824c714 | |||
| 7ac6c5f9b8 | |||
| f9fc3d91d1 | |||
| f0de9961dc | |||
| 4ded8632e5 | |||
| b2af48463c | |||
| 0b72147e02 | |||
| d1b46cf894 | |||
| 7c45ef6112 | |||
| 2b17eb6854 | |||
| 7fae75be75 | |||
| b7de3ade65 |
@@ -39,34 +39,34 @@ jobs:
|
||||
push: true
|
||||
context: Backend
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
document-creator:
|
||||
name: Build Document Creator
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: git.letsstein.de
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: git.letsstein.de/tom/arbeitszeitmessung-doc-creator
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=pep440,pattern={{version}}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
context: Backend
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
# document-creator:
|
||||
# name: Build Document Creator
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v4
|
||||
# - name: Login to GitHub Container Registry
|
||||
# uses: docker/login-action@v3
|
||||
# with:
|
||||
# registry: git.letsstein.de
|
||||
# username: ${{ gitea.actor }}
|
||||
# password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
# - name: Set up QEMU
|
||||
# uses: docker/setup-qemu-action@v3
|
||||
# - name: Set up Docker Buildx
|
||||
# uses: docker/setup-buildx-action@v3
|
||||
# - name: Extract metadata (tags, labels) for Docker
|
||||
# id: meta
|
||||
# uses: docker/metadata-action@v5
|
||||
# with:
|
||||
# images: git.letsstein.de/tom/arbeitszeitmessung-doc-creator
|
||||
# tags: |
|
||||
# type=raw,value=latest
|
||||
# type=pep440,pattern={{version}}
|
||||
# - name: Build and push
|
||||
# uses: docker/build-push-action@v6
|
||||
# with:
|
||||
# platforms: linux/amd64,linux/arm64
|
||||
# push: true
|
||||
# context: DocumentCreator
|
||||
# tags: ${{ steps.meta.outputs.tags }}
|
||||
|
||||
@@ -14,9 +14,11 @@ COPY . .
|
||||
RUN go build -o server .
|
||||
|
||||
FROM alpine:3.22
|
||||
RUN apk add --no-cache tzdata
|
||||
RUN apk add --no-cache tzdata typst
|
||||
WORKDIR /app
|
||||
COPY --from=build /app/server /app/server
|
||||
COPY ./doc/static /doc/static
|
||||
COPY ./doc/templates /doc/templates
|
||||
|
||||
COPY /static /app/static
|
||||
ENTRYPOINT ["./server"]
|
||||
|
||||
@@ -12,5 +12,6 @@ live:
|
||||
live/templ:
|
||||
templ generate --watch --proxy="http://localhost:8080" --cmd="go run ." --open-browser=false
|
||||
|
||||
live/tailwind:
|
||||
npx --yes tailwindcss -i ./input.css -o ./assets/styles.css --minify --watch
|
||||
live/tailwindcss:
|
||||
npx --yes tailwindcss -i ./src/main.css -o ./static/css/styles.css --watch
|
||||
#--minify
|
||||
|
||||
@@ -5,7 +5,11 @@ import (
|
||||
"arbeitszeitmessung/models"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
@@ -19,3 +23,29 @@ func OpenDatabase() (models.IDatabase, error) {
|
||||
connStr := fmt.Sprintf("postgres://%s:%s@%s:5432/%s?sslmode=disable&TimeZone=%s", dbUser, dbPassword, dbHost, dbName, dbTz)
|
||||
return sql.Open("postgres", connStr)
|
||||
}
|
||||
|
||||
func Migrate() error {
|
||||
dbHost := helper.GetEnv("POSTGRES_HOST", "localhost")
|
||||
dbName := helper.GetEnv("POSTGRES_DB", "arbeitszeitmessung")
|
||||
// dbUser := helper.GetEnv("POSTGRES_USER", "api_nutzer")
|
||||
dbPassword := helper.GetEnv("POSTGRES_PASSWORD", "password")
|
||||
dbTz := helper.GetEnv("TZ", "Europe/Berlin")
|
||||
|
||||
migrations := helper.GetEnv("MIGRATIONS_PATH", "../migrations")
|
||||
|
||||
connStr := fmt.Sprintf("postgres://%s:%s@%s:5432/%s?sslmode=disable&TimeZone=%s", "migrate", dbPassword, dbHost, dbName, dbTz)
|
||||
m, err := migrate.New(fmt.Sprintf("file://%s", migrations), connStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("Connected to database. Running migrations now.")
|
||||
|
||||
// Migrate all the way up ...
|
||||
if err := m.Up(); err != nil && err != migrate.ErrNoChange {
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("Finished migrations starting webserver.")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
@@ -21,7 +21,7 @@ func LogoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func autoLogout(w http.ResponseWriter) {
|
||||
users, err := models.GetAllUsers()
|
||||
var logged_out_users []models.User
|
||||
var loggedOutUsers []models.User
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting user list %v\n", err)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func autoLogout(w http.ResponseWriter) {
|
||||
if err != nil {
|
||||
fmt.Printf("Error logging out user %v\n", err)
|
||||
} else {
|
||||
logged_out_users = append(logged_out_users, user)
|
||||
loggedOutUsers = append(loggedOutUsers, user)
|
||||
log.Printf("Automaticaly logged out user %s, %s ", user.Name, user.Vorname)
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,6 @@ func autoLogout(w http.ResponseWriter) {
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(logged_out_users)
|
||||
json.NewEncoder(w).Encode(loggedOutUsers)
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,11 @@ func convertDayToTypstDayParts(day models.IWorkDay, user models.User) []typstDay
|
||||
for i := 0; i < len(workDay.Bookings); i += 2 {
|
||||
var typstDayPart typstDayPart
|
||||
typstDayPart.BookingFrom = workDay.Bookings[i].Timestamp.Format("15:04")
|
||||
if i+1 < len(workDay.Bookings) {
|
||||
typstDayPart.BookingTo = workDay.Bookings[i+1].Timestamp.Format("15:04")
|
||||
} else {
|
||||
typstDayPart.BookingTo = workDay.Bookings[i].Timestamp.Format("15:04")
|
||||
}
|
||||
typstDayPart.WorkType = workDay.Bookings[i].BookingType.Name
|
||||
typstDayPart.IsWorkDay = true
|
||||
typstDayParts = append(typstDayParts, typstDayPart)
|
||||
@@ -91,7 +95,7 @@ func PDFCreateController(w http.ResponseWriter, r *http.Request) {
|
||||
employes, err := models.GetUserByPersonalNrMulti(personalNumbers)
|
||||
if err != nil {
|
||||
slog.Warn("Error getting employes!", slog.Any("Error", err))
|
||||
// return
|
||||
return
|
||||
}
|
||||
|
||||
n := 0
|
||||
@@ -102,9 +106,6 @@ func PDFCreateController(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
employes = employes[:n]
|
||||
if helper.GetEnv("GO_ENV", "production") == "debug" {
|
||||
employes = append(employes, user)
|
||||
}
|
||||
|
||||
reportData := createReports(employes, startDate)
|
||||
|
||||
@@ -197,8 +198,9 @@ func renderPDFSingle(data []typstData) (bytes.Buffer, error) {
|
||||
var markup bytes.Buffer
|
||||
var output bytes.Buffer
|
||||
|
||||
typstCLI := typst.DockerExec{
|
||||
ContainerName: helper.GetEnv("TYPST_CONTAINER", "arbeitszeitmessung-doc-creator"),
|
||||
typstCLI := typst.CLI{
|
||||
WorkingDirectory: "/doc/",
|
||||
// ContainerName: helper.GetEnv("TYPST_CONTAINER", "arbeitszeitmessung-doc-creator"),
|
||||
}
|
||||
|
||||
if err := typst.InjectValues(&markup, map[string]any{"data": data}); err != nil {
|
||||
@@ -224,8 +226,9 @@ func renderPDFSingle(data []typstData) (bytes.Buffer, error) {
|
||||
func renderPDFMulti(data []typstData) ([]bytes.Buffer, error) {
|
||||
var outputMulti []bytes.Buffer
|
||||
|
||||
typstRender := typst.DockerExec{
|
||||
ContainerName: helper.GetEnv("TYPST_CONTAINER", "arbeitszeitmessung-doc-creator"),
|
||||
typstRender := typst.CLI{
|
||||
WorkingDirectory: "/doc/",
|
||||
// ContainerName: helper.GetEnv("TYPST_CONTAINER", "arbeitszeitmessung-doc-creator"),
|
||||
}
|
||||
|
||||
for _, d := range data {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Relevant for arduino inputs -> creates new Booking from get and put method
|
||||
@@ -36,6 +37,7 @@ func createBooking(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
booking := (*models.Booking).FromUrlParams(nil, r.URL.Query())
|
||||
booking.Timestamp = time.Now()
|
||||
if booking.Verify() {
|
||||
err := booking.Insert()
|
||||
if errors.Is(models.SameBookingError{}, err) {
|
||||
|
||||
@@ -37,8 +37,18 @@ func AbsencHandler(w http.ResponseWriter, r *http.Request) {
|
||||
helper.SetCors(w)
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
err := updateAbsence(r)
|
||||
r.ParseForm()
|
||||
var err error
|
||||
switch r.FormValue("action") {
|
||||
case "insert":
|
||||
err = updateAbsence(r)
|
||||
case "delete":
|
||||
err = deleteAbsence(r)
|
||||
default:
|
||||
slog.Warn("No action found!")
|
||||
}
|
||||
if err != nil {
|
||||
slog.Warn("Error handling absence route ", "error", err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -84,7 +94,7 @@ func getBookings(w http.ResponseWriter, r *http.Request) {
|
||||
if day.Date().Before(lastSub) {
|
||||
continue
|
||||
}
|
||||
aggregatedOvertime += day.GetOvertime(user, models.WorktimeBaseDay, false)
|
||||
aggregatedOvertime += day.GetOvertime(user, models.WorktimeBaseDay, true)
|
||||
}
|
||||
if reportedOvertime, err := user.GetReportedOvertime(); err == nil {
|
||||
user.Overtime = (reportedOvertime + aggregatedOvertime).Round(time.Minute)
|
||||
@@ -104,6 +114,21 @@ func getBookings(w http.ResponseWriter, r *http.Request) {
|
||||
templates.TimePage([]models.WorkDay{}, lastSub).Render(ctx, w)
|
||||
}
|
||||
|
||||
func deleteAbsence(r *http.Request) error {
|
||||
r.ParseForm()
|
||||
pp := paramParser.New(r.Form)
|
||||
counterId, err := pp.ParseInt("aw_id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
absence, err := models.GetAbsenceById(counterId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return absence.Delete()
|
||||
}
|
||||
|
||||
func updateBooking(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
pp := paramParser.New(r.Form)
|
||||
@@ -135,19 +160,13 @@ func updateBooking(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
newBooking := (*models.Booking).New(nil, user.CardUID, 0, int16(check_in_out), 1)
|
||||
newBooking.Timestamp = timestamp
|
||||
if newBooking.Verify() {
|
||||
err = newBooking.InsertWithTimestamp()
|
||||
if err != nil {
|
||||
log.Printf("Error inserting booking %v -> %v\n", newBooking, err)
|
||||
}
|
||||
}
|
||||
case "change":
|
||||
// absenceType, err := strconv.Atoi(r.FormValue("absence"))
|
||||
// if err != nil {
|
||||
// log.Println("Error parsing absence type.", err)
|
||||
// absenceType = 0
|
||||
// }
|
||||
// if absenceType != 0 {
|
||||
// createAbsence(absenceType, user, loc, r)
|
||||
// }
|
||||
for index, possibleBooking := range r.PostForm {
|
||||
if len(index) > 7 && index[:7] == "booking" {
|
||||
booking_id, err := strconv.Atoi(index[8:])
|
||||
|
||||
@@ -4,8 +4,6 @@ github.com/Dadido3/go-typst v0.8.0 h1:uTLYprhkrBjwsCXRRuyYUFL0fpYHa2kIYoOB/CGqVN
|
||||
github.com/Dadido3/go-typst v0.8.0/go.mod h1:QYis9sT70u65kn1SkFfyPRmHsPxgoxWbAixwfPReOZA=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/a-h/templ v0.3.943 h1:o+mT/4yqhZ33F3ootBiHwaY4HM5EVaOJfIshvd5UNTY=
|
||||
github.com/a-h/templ v0.3.943/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=
|
||||
github.com/a-h/templ v0.3.960 h1:trshEpGa8clF5cdI39iY4ZrZG8Z/QixyzEyUnA7feTM=
|
||||
github.com/a-h/templ v0.3.960/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=
|
||||
github.com/alexedwards/scs/v2 v2.8.0 h1:h31yUYoycPuL0zt14c0gd+oqxfRwIj6SOjHdKRZxhEw=
|
||||
@@ -39,6 +37,8 @@ github.com/golang-migrate/migrate/v4 v4.18.3 h1:EYGkoOsvgHHfm5U/naS1RP/6PL/Xv3S4
|
||||
github.com/golang-migrate/migrate/v4 v4.18.3/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -78,7 +78,6 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/wlbr/feiertage v1.10.0/go.mod h1:wJOHvMa6sI5L1FkrTOX/GSoO0hpK3S2YqGLPi8Q84I0=
|
||||
github.com/wlbr/feiertage v1.17.0 h1:AEck/iUQu19iU0xNEoSQTeSTGXF1Ju0tbAwEi/Lmwqk=
|
||||
github.com/wlbr/feiertage v1.17.0/go.mod h1:TVZgmSZgGW/jSxexZ56qdlR6cDj+F/FO8bkw8U6kYxM=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"arbeitszeitmessung/helper"
|
||||
"arbeitszeitmessung/models"
|
||||
"context"
|
||||
"database/sql"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -17,7 +18,16 @@ import (
|
||||
func main() {
|
||||
var err error
|
||||
var logLevel slog.LevelVar
|
||||
switch helper.GetEnv("LOG_LEVEL", "warn") {
|
||||
case "debug":
|
||||
logLevel.Set(slog.LevelDebug)
|
||||
case "info":
|
||||
logLevel.Set(slog.LevelInfo)
|
||||
case "warn":
|
||||
logLevel.Set(slog.LevelWarn)
|
||||
case "error":
|
||||
logLevel.Set(slog.LevelError)
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: &logLevel}))
|
||||
slog.SetDefault(logger)
|
||||
@@ -35,6 +45,15 @@ func main() {
|
||||
models.DB, err = OpenDatabase()
|
||||
if err != nil {
|
||||
slog.Error("Error while opening the database", "Error", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer models.DB.(*sql.DB).Close()
|
||||
|
||||
err = Migrate()
|
||||
if err != nil {
|
||||
slog.Error("Failed to migrate the database to newest version", "Error", err)
|
||||
return
|
||||
}
|
||||
|
||||
fs := http.FileServer(http.Dir("./static"))
|
||||
@@ -61,6 +80,8 @@ func main() {
|
||||
|
||||
serverSessionMiddleware := endpoints.Session.LoadAndSave(server)
|
||||
|
||||
serverSessionMiddleware = loggingMiddleware(serverSessionMiddleware)
|
||||
|
||||
// starting the http server
|
||||
slog.Info("Server is running at http://localhost:8080")
|
||||
slog.Error("Error starting Server", "Error", http.ListenAndServe(":8080", serverSessionMiddleware))
|
||||
@@ -70,7 +91,24 @@ func ParamsMiddleware(next http.HandlerFunc) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
queryParams := r.URL.Query()
|
||||
ctx := context.WithValue(r.Context(), "urlParams", queryParams)
|
||||
if len(queryParams) > 0 {
|
||||
slog.Debug("ParamsMiddleware added urlParams", slog.Any("urlParams", queryParams))
|
||||
}
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
func loggingMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
start := time.Now()
|
||||
|
||||
// Log the method and the requested URL
|
||||
slog.Info("Started request", slog.String("Method", r.Method), slog.String("Path", r.URL.Path))
|
||||
|
||||
// Call the next handler in the chain
|
||||
next.ServeHTTP(w, r)
|
||||
|
||||
// Log how long it took
|
||||
slog.Info("Completet Request", slog.String("Time", time.Since(start).String()))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -294,3 +294,12 @@ func GetAbsenceTypeById(absenceTypeId int8) (AbsenceType, error) {
|
||||
}
|
||||
return absenceType, nil
|
||||
}
|
||||
|
||||
func (a *Absence) Delete() error {
|
||||
qStr, err := DB.Prepare("DELETE from abwesenheit WHERE counter_id = $1;")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = qStr.Exec(a.CounterId)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -128,6 +128,9 @@ func (b *Booking) InsertWithTimestamp() error {
|
||||
if b.Timestamp.IsZero() {
|
||||
return b.Insert()
|
||||
}
|
||||
if !checkLastBooking(*b) {
|
||||
return SameBookingError{}
|
||||
}
|
||||
stmt, err := DB.Prepare((`INSERT INTO anwesenheit (card_uid, geraet_id, check_in_out, anwesenheit_typ, timestamp) VALUES ($1, $2, $3, $4, $5) RETURNING counter_id`))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -242,12 +245,13 @@ func (b *Booking) Update(nb Booking) {
|
||||
|
||||
func checkLastBooking(b Booking) bool {
|
||||
var check_in_out int
|
||||
stmt, err := DB.Prepare((`SELECT check_in_out FROM "anwesenheit" WHERE "card_uid" = $1 ORDER BY "timestamp" DESC LIMIT 1;`))
|
||||
slog.Info("Checking with timestamp:", "timestamp", b.Timestamp.String())
|
||||
stmt, err := DB.Prepare((`SELECT check_in_out FROM "anwesenheit" WHERE "card_uid" = $1 AND "timestamp"::DATE <= $2::DATE ORDER BY "timestamp" DESC LIMIT 1;`))
|
||||
if err != nil {
|
||||
log.Fatalf("Error preparing query: %v", err)
|
||||
return false
|
||||
}
|
||||
err = stmt.QueryRow(b.CardUID).Scan(&check_in_out)
|
||||
err = stmt.QueryRow(b.CardUID, b.Timestamp).Scan(&check_in_out)
|
||||
if err == sql.ErrNoRows {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func (c *CompoundDay) GetWorkDay() WorkDay {
|
||||
|
||||
// IsEmpty implements [IWorkDay].
|
||||
func (c *CompoundDay) IsEmpty() bool {
|
||||
return len(c.DayParts) > 0
|
||||
return len(c.DayParts) == 0
|
||||
}
|
||||
|
||||
// Date implements [IWorkDay].
|
||||
@@ -47,12 +47,16 @@ func (c *CompoundDay) GetDayProgress(u User) int8 {
|
||||
|
||||
// GetOvertime implements [IWorkDay].
|
||||
func (c *CompoundDay) GetOvertime(u User, base WorktimeBase, includeKurzarbeit bool) time.Duration {
|
||||
work := c.GetWorktime(u, base, includeKurzarbeit)
|
||||
var targetHours time.Duration
|
||||
|
||||
var overtime time.Duration
|
||||
for _, day := range c.DayParts {
|
||||
overtime += day.GetOvertime(u, base, includeKurzarbeit)
|
||||
switch base {
|
||||
case WorktimeBaseDay:
|
||||
targetHours = u.ArbeitszeitProTagFrac(1)
|
||||
case WorktimeBaseWeek:
|
||||
targetHours = u.ArbeitszeitProWocheFrac(.2)
|
||||
}
|
||||
return overtime
|
||||
return (work - targetHours).Round(time.Minute)
|
||||
}
|
||||
|
||||
// GetPausetime implements [IWorkDay].
|
||||
|
||||
@@ -49,19 +49,16 @@ func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay
|
||||
}
|
||||
|
||||
for _, absentDay := range absences {
|
||||
// Kurzarbeit should be integrated in workday
|
||||
|
||||
// Check if there is already a day
|
||||
existingDay, ok := allDays[absentDay.Date().Format(time.DateOnly)]
|
||||
if !ok {
|
||||
allDays[absentDay.Date().Format(time.DateOnly)] = &absentDay
|
||||
continue
|
||||
}
|
||||
switch {
|
||||
case absentDay.AbwesenheitTyp.WorkTime < 0:
|
||||
if workDay, ok := allDays[absentDay.Date().Format(time.DateOnly)].(*WorkDay); ok {
|
||||
workDay.kurzArbeit = true
|
||||
workDay.kurzArbeitAbsence = absentDay
|
||||
}
|
||||
case !existingDay.IsEmpty():
|
||||
case ok && !existingDay.IsEmpty():
|
||||
allDays[absentDay.Date().Format(time.DateOnly)] = NewCompondDay(absentDay.Date(), existingDay, &absentDay)
|
||||
default:
|
||||
allDays[absentDay.Date().Format(time.DateOnly)] = &absentDay
|
||||
|
||||
@@ -175,21 +175,38 @@ func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay {
|
||||
qStr, err := DB.Prepare(`
|
||||
WITH all_days AS (
|
||||
SELECT generate_series($2::DATE, $3::DATE - INTERVAL '1 day', INTERVAL '1 day')::DATE AS work_date),
|
||||
ordered_bookings AS (
|
||||
normalized_bookings AS (
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT
|
||||
a.timestamp::DATE AS work_date,
|
||||
a.card_uid,
|
||||
a.timestamp,
|
||||
a.timestamp::DATE AS work_date,
|
||||
a.check_in_out,
|
||||
a.counter_id,
|
||||
a.anwesenheit_typ,
|
||||
sat.anwesenheit_name AS anwesenheit_typ_name,
|
||||
LAG(a.timestamp) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_timestamp,
|
||||
LAG(a.check_in_out) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_check
|
||||
LAG(a.check_in_out) OVER (
|
||||
PARTITION BY a.card_uid, a.timestamp::DATE
|
||||
ORDER BY a.timestamp
|
||||
) AS prev_check
|
||||
FROM anwesenheit a
|
||||
LEFT JOIN s_anwesenheit_typen sat ON a.anwesenheit_typ = sat.anwesenheit_id
|
||||
LEFT JOIN s_anwesenheit_typen sat
|
||||
ON a.anwesenheit_typ = sat.anwesenheit_id
|
||||
WHERE a.card_uid = $1
|
||||
AND a.timestamp::DATE >= $2
|
||||
AND a.timestamp::DATE <= $3
|
||||
) t
|
||||
WHERE prev_check IS NULL OR prev_check <> check_in_out
|
||||
),
|
||||
ordered_bookings AS (
|
||||
SELECT
|
||||
*,
|
||||
LAG(timestamp) OVER (
|
||||
PARTITION BY card_uid, work_date
|
||||
ORDER BY timestamp
|
||||
) AS prev_timestamp
|
||||
FROM normalized_bookings
|
||||
)
|
||||
SELECT
|
||||
d.work_date,
|
||||
@@ -228,6 +245,62 @@ func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay {
|
||||
GROUP BY d.work_date
|
||||
ORDER BY d.work_date ASC;`)
|
||||
|
||||
// qStr, err := DB.Prepare(`
|
||||
// WITH all_days AS (
|
||||
// SELECT generate_series($2::DATE, $3::DATE - INTERVAL '1 day', INTERVAL '1 day')::DATE AS work_date),
|
||||
// ordered_bookings AS (
|
||||
// SELECT
|
||||
// a.timestamp::DATE AS work_date,
|
||||
// a.timestamp,
|
||||
// a.check_in_out,
|
||||
// a.counter_id,
|
||||
// a.anwesenheit_typ,
|
||||
// sat.anwesenheit_name AS anwesenheit_typ_name,
|
||||
// LAG(a.timestamp) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_timestamp,
|
||||
// LAG(a.check_in_out) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_check
|
||||
// FROM anwesenheit a
|
||||
// LEFT JOIN s_anwesenheit_typen sat ON a.anwesenheit_typ = sat.anwesenheit_id
|
||||
// WHERE a.card_uid = $1
|
||||
// AND a.timestamp::DATE >= $2
|
||||
// AND a.timestamp::DATE <= $3
|
||||
// )
|
||||
// SELECT
|
||||
// d.work_date,
|
||||
// COALESCE(MIN(b.timestamp), NOW()) AS time_from,
|
||||
// COALESCE(MAX(b.timestamp), NOW()) AS time_to,
|
||||
// COALESCE(
|
||||
// EXTRACT(EPOCH FROM SUM(
|
||||
// CASE
|
||||
// WHEN b.prev_check IN (1, 3) AND b.check_in_out IN (2, 4, 254)
|
||||
// THEN b.timestamp - b.prev_timestamp
|
||||
// ELSE INTERVAL '0'
|
||||
// END
|
||||
// )), 0
|
||||
// ) AS total_work_seconds,
|
||||
// COALESCE(
|
||||
// EXTRACT(EPOCH FROM SUM(
|
||||
// CASE
|
||||
// WHEN b.prev_check IN (2, 4, 254) AND b.check_in_out IN (1, 3)
|
||||
// THEN b.timestamp - b.prev_timestamp
|
||||
// ELSE INTERVAL '0'
|
||||
// END
|
||||
// )), 0
|
||||
// ) AS total_pause_seconds,
|
||||
// COALESCE(jsonb_agg(jsonb_build_object(
|
||||
// 'check_in_out', b.check_in_out,
|
||||
// 'timestamp', b.timestamp,
|
||||
// 'counter_id', b.counter_id,
|
||||
// 'anwesenheit_typ', b.anwesenheit_typ,
|
||||
// 'anwesenheit_typ', jsonb_build_object(
|
||||
// 'anwesenheit_id', b.anwesenheit_typ,
|
||||
// 'anwesenheit_name', b.anwesenheit_typ_name
|
||||
// )
|
||||
// ) ORDER BY b.timestamp), '[]'::jsonb) AS bookings
|
||||
// FROM all_days d
|
||||
// LEFT JOIN ordered_bookings b ON d.work_date = b.work_date
|
||||
// GROUP BY d.work_date
|
||||
// ORDER BY d.work_date ASC;`)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Error preparing SQL statement", err)
|
||||
return workDays
|
||||
@@ -258,7 +331,7 @@ func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay {
|
||||
if len(workDay.Bookings) == 1 && workDay.Bookings[0].CounterId == 0 {
|
||||
workDay.Bookings = []Booking{}
|
||||
}
|
||||
if len(workDay.Bookings) > 1 || !helper.IsWeekend(workDay.Date()) {
|
||||
if len(workDay.Bookings) >= 1 || !helper.IsWeekend(workDay.Date()) {
|
||||
workDays = append(workDays, workDay)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
--color-red-700: oklch(50.5% 0.213 27.518);
|
||||
--color-orange-500: oklch(70.5% 0.213 47.604);
|
||||
--color-purple-600: oklch(55.8% 0.288 302.321);
|
||||
--color-slate-300: oklch(86.9% 0.022 252.894);
|
||||
--color-slate-600: oklch(44.6% 0.043 257.281);
|
||||
--color-slate-700: oklch(37.2% 0.044 257.287);
|
||||
--color-slate-800: oklch(27.9% 0.041 260.031);
|
||||
@@ -200,6 +199,12 @@
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
.sticky {
|
||||
position: sticky;
|
||||
}
|
||||
.top-0 {
|
||||
top: calc(var(--spacing) * 0);
|
||||
}
|
||||
.top-1 {
|
||||
top: calc(var(--spacing) * 1);
|
||||
}
|
||||
@@ -212,6 +217,12 @@
|
||||
.top-2\.5 {
|
||||
top: calc(var(--spacing) * 2.5);
|
||||
}
|
||||
.top-25 {
|
||||
top: calc(var(--spacing) * 25);
|
||||
}
|
||||
.top-26 {
|
||||
top: calc(var(--spacing) * 26);
|
||||
}
|
||||
.top-\[0\.125rem\] {
|
||||
top: 0.125rem;
|
||||
}
|
||||
@@ -230,6 +241,12 @@
|
||||
.left-1\/2 {
|
||||
left: calc(1/2 * 100%);
|
||||
}
|
||||
.z-10 {
|
||||
z-index: 10;
|
||||
}
|
||||
.z-100 {
|
||||
z-index: 100;
|
||||
}
|
||||
.col-span-2 {
|
||||
grid-column: span 2 / span 2;
|
||||
}
|
||||
@@ -402,6 +419,9 @@
|
||||
.h-8 {
|
||||
height: calc(var(--spacing) * 8);
|
||||
}
|
||||
.h-10 {
|
||||
height: calc(var(--spacing) * 10);
|
||||
}
|
||||
.h-\[100vh\] {
|
||||
height: 100vh;
|
||||
}
|
||||
@@ -617,12 +637,6 @@
|
||||
.border-neutral-600 {
|
||||
border-color: var(--color-neutral-600);
|
||||
}
|
||||
.border-slate-300 {
|
||||
border-color: var(--color-slate-300);
|
||||
}
|
||||
.border-slate-700 {
|
||||
border-color: var(--color-slate-700);
|
||||
}
|
||||
.border-slate-800 {
|
||||
border-color: var(--color-slate-800);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ function editWorkday(element, event, id, isWorkDay) {
|
||||
event.preventDefault();
|
||||
let form = document.getElementById(id);
|
||||
if (form == null) {
|
||||
form = element.closest(".grid-sub").querySelector(".all-booking-component > form");
|
||||
form = element
|
||||
.closest(".grid-sub")
|
||||
.querySelector(".all-booking-component > form");
|
||||
}
|
||||
|
||||
clearEditState();
|
||||
@@ -37,10 +39,21 @@ function editWorkday(element, event, id, isWorkDay) {
|
||||
const absenceForm = document.getElementById("absence_form");
|
||||
|
||||
if (id == 0) {
|
||||
absenceForm.querySelector("[name=date_from]").value = form.id.replace("time-", "");
|
||||
absenceForm.querySelector("[name=date_to]").value = form.id.replace("time-", "");
|
||||
absenceForm.querySelector("[name=date_from]").value = form.id.replace(
|
||||
"time-",
|
||||
"",
|
||||
);
|
||||
absenceForm.querySelector("[name=date_to]").value = form.id.replace(
|
||||
"time-",
|
||||
"",
|
||||
);
|
||||
} else {
|
||||
syncFields(form, absenceForm, ["date_from", "date_to", "aw_type", "aw_id"]);
|
||||
syncFields(form, absenceForm, [
|
||||
"date_from",
|
||||
"date_to",
|
||||
"aw_type",
|
||||
"aw_id",
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,11 +62,6 @@ function toggleAbsenceEdit(state) {
|
||||
const form = document.getElementById("absence_form");
|
||||
if (state) {
|
||||
form.classList.remove("hidden");
|
||||
form.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "start",
|
||||
inline: "nearest",
|
||||
});
|
||||
} else {
|
||||
form.classList.add("hidden");
|
||||
}
|
||||
@@ -85,3 +93,12 @@ function checkAll(pattern, state) {
|
||||
input.checked = state;
|
||||
}
|
||||
}
|
||||
|
||||
const bookingForms = document.querySelectorAll("form.bookings");
|
||||
for (let form of bookingForms) {
|
||||
let selectKommenInput = form.querySelector("input[name='select_kommen']");
|
||||
let kommenGehenSelector = form.querySelector("select");
|
||||
if (selectKommenInput) {
|
||||
kommenGehenSelector.value = selectKommenInput.value == "true" ? 3 : 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package templates
|
||||
|
||||
templ headerComponent() {
|
||||
// {{ user := ctx.Value("user").(models.User) }}
|
||||
<div class="flex flex-row justify-between md:mx-[10%] py-2 items-center">
|
||||
<a href="/time">Zeitverwaltung</a>
|
||||
<a href="/team">Abrechnung</a>
|
||||
<a href="/pdf">PDF</a>
|
||||
if true {
|
||||
<a href="/pdf">Monatsabrechnung</a>
|
||||
<a href="/presence">Anwesenheit</a>
|
||||
}
|
||||
<a href="/user/settings">Einstellungen</a>
|
||||
|
||||
@@ -29,12 +29,12 @@ func headerComponent() templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-row justify-between md:mx-[10%] py-2 items-center\"><a href=\"/time\">Zeitverwaltung</a> <a href=\"/team\">Abrechnung</a> <a href=\"/pdf\">PDF</a> ")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-row justify-between md:mx-[10%] py-2 items-center\"><a href=\"/time\">Zeitverwaltung</a> <a href=\"/team\">Abrechnung</a> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if true {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<a href=\"/presence\">Anwesenheit</a> ")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<a href=\"/pdf\">Monatsabrechnung</a> <a href=\"/presence\">Anwesenheit</a> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ templ PDFForm(teamMembers []models.User) {
|
||||
@headerComponent()
|
||||
<form class="grid-main divide-y-1" action="pdf/generate" method="get">
|
||||
<div class="grid-cell col-span-full bg-neutral-300">
|
||||
<h1 class="text-xl uppercase font-bold">PDF Abrechnung erstellen</h1>
|
||||
<h1 class="text-xl uppercase font-bold">Monatsabrechnung erstellen</h1>
|
||||
</div>
|
||||
<div class="grid-sub divide-x-1 responsive">
|
||||
<div class="grid-cell">Zeitraum wählen</div>
|
||||
@@ -46,9 +46,7 @@ templ PDFForm(teamMembers []models.User) {
|
||||
}
|
||||
|
||||
templ CheckboxComponent(pNr int, label string) {
|
||||
{{
|
||||
id := fmt.Sprintf("pdf-%d", pNr)
|
||||
}}
|
||||
{{ id := fmt.Sprintf("pdf-%d", pNr) }}
|
||||
<div class="inline-flex items-center">
|
||||
<label class="flex items-center cursor-pointer relative" for={ id }>
|
||||
<input type="checkbox" name="employe_list" value={ pNr } id={ id } class="peer h-5 w-5 cursor-pointer transition-all appearance-none rounded border border-slate-800 checked:bg-slate-800 checked:border-slate-800"/>
|
||||
|
||||
@@ -44,7 +44,7 @@ func PDFForm(teamMembers []models.User) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<form class=\"grid-main divide-y-1\" action=\"pdf/generate\" method=\"get\"><div class=\"grid-cell col-span-full bg-neutral-300\"><h1 class=\"text-xl uppercase font-bold\">PDF Abrechnung erstellen</h1></div><div class=\"grid-sub divide-x-1 responsive\"><div class=\"grid-cell\">Zeitraum wählen</div><div class=\"grid-cell col-span-3\"><label class=\"block mb-1 text-sm text-neutral-700\">Abrechnungsmonat</label> <input name=\"start_date\" type=\"date\" value=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<form class=\"grid-main divide-y-1\" action=\"pdf/generate\" method=\"get\"><div class=\"grid-cell col-span-full bg-neutral-300\"><h1 class=\"text-xl uppercase font-bold\">Monatsabrechnung erstellen</h1></div><div class=\"grid-sub divide-x-1 responsive\"><div class=\"grid-cell\">Zeitraum wählen</div><div class=\"grid-cell col-span-3\"><label class=\"block mb-1 text-sm text-neutral-700\">Abrechnungsmonat</label> <input name=\"start_date\" type=\"date\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func CheckboxComponent(pNr int, label string) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(id)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 53, Col: 67}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 51, Col: 67}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -151,7 +151,7 @@ func CheckboxComponent(pNr int, label string) templ.Component {
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(pNr)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 54, Col: 57}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 52, Col: 57}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -164,7 +164,7 @@ func CheckboxComponent(pNr int, label string) templ.Component {
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(id)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 54, Col: 67}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 52, Col: 67}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -177,7 +177,7 @@ func CheckboxComponent(pNr int, label string) templ.Component {
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(id)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 60, Col: 81}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 58, Col: 81}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -190,7 +190,7 @@ func CheckboxComponent(pNr int, label string) templ.Component {
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 60, Col: 91}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 58, Col: 91}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -318,7 +318,7 @@ func ColorDuration(d time.Duration, classes string) templ.Component {
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDurationFill(d, true))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 135, Col: 72}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 133, Col: 72}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
package templates
|
||||
|
||||
import "arbeitszeitmessung/models"
|
||||
import (
|
||||
"arbeitszeitmessung/helper"
|
||||
"arbeitszeitmessung/models"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
|
||||
@Base()
|
||||
@@ -22,3 +28,119 @@ templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
templ workWeekComponent(week models.WorkWeek, onlyAccept bool) {
|
||||
{{
|
||||
year, kw := week.WeekStart.ISOWeek()
|
||||
progress := (float32(week.WorktimeVirtual.Hours()) / week.User.ArbeitszeitPerWoche) * 100
|
||||
}}
|
||||
<div class="employeComponent grid-sub responsive lg:divide-x-1 max-md:divide-y-1 @container">
|
||||
<div class="grid-cell flex flex-col max-md:bg-neutral-300 gap-2">
|
||||
if !onlyAccept {
|
||||
<div class="lg:hidden">
|
||||
@weekPicker(week.WeekStart)
|
||||
</div>
|
||||
}
|
||||
<p class="font-bold uppercase">{ week.User.Vorname } { week.User.Name }</p>
|
||||
<div class="grid grid-cols-5 gap-2 lg:grid-cols-1">
|
||||
if !onlyAccept {
|
||||
<div class="col-span-2">
|
||||
<span class="flex flex-row gap-2 items-center">
|
||||
@statusCheckMark(week.CheckStatus(), models.WeekStatusSent)
|
||||
Gesendet
|
||||
</span>
|
||||
<span class="flex flex-row gap-2 items-center">
|
||||
@statusCheckMark(week.CheckStatus(), models.WeekStatusAccepted)
|
||||
Akzeptiert
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
<div class="flex flex-row gap-2 col-span-3">
|
||||
@timeGaugeComponent(int8(progress), false)
|
||||
<div>
|
||||
<p>Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)) }</p>
|
||||
<p>Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(week.Overtime, true)) }</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-cell col-span-3 flex flex-col @7xl:grid @7xl:grid-cols-5 gap-2 py-4 content-baseline">
|
||||
for _, day := range week.Days {
|
||||
@defaultWeekDayComponent(week.User, day)
|
||||
}
|
||||
</div>
|
||||
<div class="grid-cell flex flex-col gap-2 justify-between">
|
||||
if onlyAccept {
|
||||
<p class="text-sm"><span class="">Woche:</span> { fmt.Sprintf("%02d-%d", kw, year) }</p>
|
||||
} else {
|
||||
<div class="max-md:hidden">
|
||||
@weekPicker(week.WeekStart)
|
||||
</div>
|
||||
}
|
||||
<form method="post" class="flex flex-col gap-2">
|
||||
{{
|
||||
week.CheckStatus()
|
||||
method := "accept"
|
||||
if !onlyAccept {
|
||||
method = "send"
|
||||
}
|
||||
}}
|
||||
<input type="hidden" name="method" value={ method }/>
|
||||
<input type="hidden" name="user" value={ strconv.Itoa(week.User.PersonalNummer) }/>
|
||||
<input type="hidden" name="week" value={ week.WeekStart.Format(time.DateOnly) }/>
|
||||
if onlyAccept {
|
||||
if week.Status == models.WeekStatusDifferences {
|
||||
<p class="text-red-600 text-sm">Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen</p>
|
||||
}
|
||||
<button type="submit" disabled?={ week.Status == models.WeekStatusDifferences } class="btn">Bestätigen</button>
|
||||
} else {
|
||||
switch {
|
||||
case week.RequiresAction():
|
||||
<p class="text-sm text-red-500">bitte zuerst Buchungen anpassen</p>
|
||||
case time.Since(week.WeekStart) < 24*7*time.Hour:
|
||||
<p class="text-sm text-red-500">Die Woche kann erst am nächsten Montag gesendet werden!</p>
|
||||
case week.Status == models.WeekStatusNone:
|
||||
<p class="text-sm">an Vorgesetzten senden</p>
|
||||
case week.Status == models.WeekStatusSent:
|
||||
<p class="text-sm">an Vorgesetzten gesendet</p>
|
||||
case week.Status == models.WeekStatusAccepted:
|
||||
<p class="text-sm">vom Vorgesetzten bestätigt</p>
|
||||
}
|
||||
<button disabled?={ week.Status < models.WeekStatusSent } type="submit" class="btn">Korrigieren</button>
|
||||
<button disabled?={ time.Since(week.WeekStart) < 24*7*time.Hour || week.Status >= models.WeekStatusSent || week.RequiresAction() } type="submit" class="btn">Senden</button>
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ defaultWeekDayComponent(u models.User, day models.IWorkDay) {
|
||||
<div class="flex flex-row gap-2">
|
||||
@timeGaugeComponent(day.GetDayProgress(u), false)
|
||||
<div class="flex flex-col">
|
||||
<p class=""><span class="font-bold uppercase hidden md:inline">{ helper.FormatGermanDayOfWeek(day.Date()) }:</span> { day.Date().Format("02.01.2006") }</p>
|
||||
{{ work, pause, _ := day.GetTimes(u, models.WorktimeBaseDay, false) }}
|
||||
if day.IsWorkDay() || day.GetDayProgress(u) < 100 {
|
||||
<div class="flex flex-row gap-2">
|
||||
<span class="text-accent">{ helper.FormatDuration(work) }</span>
|
||||
<span class="text-neutral-500">{ helper.FormatDuration(pause) }</span>
|
||||
</div>
|
||||
}
|
||||
@weekDayTypeSwitcher(day)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ weekDayTypeSwitcher(day models.IWorkDay) {
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
{{ workDay, _ := day.(*models.WorkDay) }}
|
||||
@workDayWeekComponent(workDay)
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
@weekDayTypeSwitcher(c)
|
||||
}
|
||||
default:
|
||||
<div>{ day.ToString() }</div>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,13 @@ package templates
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "arbeitszeitmessung/models"
|
||||
import (
|
||||
"arbeitszeitmessung/helper"
|
||||
"arbeitszeitmessung/models"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
@@ -67,4 +73,473 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
|
||||
})
|
||||
}
|
||||
|
||||
func workWeekComponent(week models.WorkWeek, onlyAccept bool) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
year, kw := week.WeekStart.ISOWeek()
|
||||
progress := (float32(week.WorktimeVirtual.Hours()) / week.User.ArbeitszeitPerWoche) * 100
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<div class=\"employeComponent grid-sub responsive lg:divide-x-1 max-md:divide-y-1 @container\"><div class=\"grid-cell flex flex-col max-md:bg-neutral-300 gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !onlyAccept {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<div class=\"lg:hidden\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = weekPicker(week.WeekStart).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<p class=\"font-bold uppercase\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 44, Col: 53}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 44, Col: 72}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</p><div class=\"grid grid-cols-5 gap-2 lg:grid-cols-1\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !onlyAccept {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<div class=\"col-span-2\"><span class=\"flex flex-row gap-2 items-center\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = statusCheckMark(week.CheckStatus(), models.WeekStatusSent).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "Gesendet</span> <span class=\"flex flex-row gap-2 items-center\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = statusCheckMark(week.CheckStatus(), models.WeekStatusAccepted).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "Akzeptiert</span></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<div class=\"flex flex-row gap-2 col-span-3\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = timeGaugeComponent(int8(progress), false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<div><p>Arbeitszeit: ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 61, Col: 79}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</p><p>Überstunden: ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDurationFill(week.Overtime, true)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 62, Col: 90}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</p></div></div></div></div><div class=\"grid-cell col-span-3 flex flex-col @7xl:grid @7xl:grid-cols-5 gap-2 py-4 content-baseline\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, day := range week.Days {
|
||||
templ_7745c5c3_Err = defaultWeekDayComponent(week.User, day).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</div><div class=\"grid-cell flex flex-col gap-2 justify-between\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if onlyAccept {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<p class=\"text-sm\"><span class=\"\">Woche:</span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 74, Col: 86}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<div class=\"max-md:hidden\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = weekPicker(week.WeekStart).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<form method=\"post\" class=\"flex flex-col gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
week.CheckStatus()
|
||||
method := "accept"
|
||||
if !onlyAccept {
|
||||
method = "send"
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<input type=\"hidden\" name=\"method\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(method)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 88, Col: 53}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\"> <input type=\"hidden\" name=\"user\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(week.User.PersonalNummer))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 89, Col: 83}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "\"> <input type=\"hidden\" name=\"week\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(week.WeekStart.Format(time.DateOnly))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 90, Col: 81}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\"> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if onlyAccept {
|
||||
if week.Status == models.WeekStatusDifferences {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<p class=\"text-red-600 text-sm\">Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " <button type=\"submit\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if week.Status == models.WeekStatusDifferences {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, " class=\"btn\">Bestätigen</button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
switch {
|
||||
case week.RequiresAction():
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<p class=\"text-sm text-red-500\">bitte zuerst Buchungen anpassen</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case time.Since(week.WeekStart) < 24*7*time.Hour:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<p class=\"text-sm text-red-500\">Die Woche kann erst am nächsten Montag gesendet werden!</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case week.Status == models.WeekStatusNone:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<p class=\"text-sm\">an Vorgesetzten senden</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case week.Status == models.WeekStatusSent:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "<p class=\"text-sm\">an Vorgesetzten gesendet</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case week.Status == models.WeekStatusAccepted:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<p class=\"text-sm\">vom Vorgesetzten bestätigt</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " <button")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if week.Status < models.WeekStatusSent {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, " disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, " type=\"submit\" class=\"btn\">Korrigieren</button> <button")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if time.Since(week.WeekStart) < 24*7*time.Hour || week.Status >= models.WeekStatusSent || week.RequiresAction() {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, " disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, " type=\"submit\" class=\"btn\">Senden</button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</form></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func defaultWeekDayComponent(u models.User, day models.IWorkDay) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var11 == nil {
|
||||
templ_7745c5c3_Var11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<div class=\"flex flex-row gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = timeGaugeComponent(day.GetDayProgress(u), false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "<div class=\"flex flex-col\"><p class=\"\"><span class=\"font-bold uppercase hidden md:inline\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatGermanDayOfWeek(day.Date()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 121, Col: 108}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, ":</span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.Date().Format("02.01.2006"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 121, Col: 152}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
work, pause, _ := day.GetTimes(u, models.WorktimeBaseDay, false)
|
||||
if day.IsWorkDay() || day.GetDayProgress(u) < 100 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<div class=\"flex flex-row gap-2\"><span class=\"text-accent\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 125, Col: 60}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</span> <span class=\"text-neutral-500\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 126, Col: 66}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</span></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = weekDayTypeSwitcher(day).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func weekDayTypeSwitcher(day models.IWorkDay) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var16 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var16 == nil {
|
||||
templ_7745c5c3_Var16 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
workDay, _ := day.(*models.WorkDay)
|
||||
templ_7745c5c3_Err = workDayWeekComponent(workDay).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
templ_7745c5c3_Err = weekDayTypeSwitcher(c).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
default:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "<div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 string
|
||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(day.ToString())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reportPage.templ`, Line: 144, Col: 24}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"arbeitszeitmessung/helper"
|
||||
"arbeitszeitmessung/models"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -26,38 +24,7 @@ templ weekPicker(weekStart time.Time) {
|
||||
</form>
|
||||
}
|
||||
|
||||
templ defaultWeekDayComponent(u models.User, day models.IWorkDay) {
|
||||
<div class="flex flex-row gap-2">
|
||||
@timeGaugeComponent(day.GetDayProgress(u), false)
|
||||
<div class="flex flex-col">
|
||||
<p class=""><span class="font-bold uppercase hidden md:inline">{ helper.FormatGermanDayOfWeek(day.Date()) }:</span> { day.Date().Format("02.01.2006") }</p>
|
||||
{{ work, pause, _ := day.GetTimes(u, models.WorktimeBaseDay, false) }}
|
||||
<div class="flex flex-row gap-2">
|
||||
<span class="text-accent">{ helper.FormatDuration(work) }</span>
|
||||
<span class="text-neutral-500">{ helper.FormatDuration(pause) }</span>
|
||||
</div>
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
{{ workDay, _ := day.(*models.WorkDay) }}
|
||||
@workDayWeekComponent(workDay, u)
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
switch c.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
{{ workDay, _ := c.(*models.WorkDay) }}
|
||||
@workDayWeekComponent(workDay, u)
|
||||
default:
|
||||
<div>{ c.ToString() }</div>
|
||||
}
|
||||
}
|
||||
default:
|
||||
<div>{ day.ToString() }</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ workDayWeekComponent(workDay *models.WorkDay, u models.User) {
|
||||
templ workDayWeekComponent(workDay *models.WorkDay) {
|
||||
if !workDay.RequiresAction() {
|
||||
<div class="flex flex-row gap-2 items-center">
|
||||
<span class="icon-[material-symbols-light--schedule-outline] flex-shrink-0"></span>
|
||||
@@ -75,91 +42,6 @@ templ workDayWeekComponent(workDay *models.WorkDay, u models.User) {
|
||||
}
|
||||
}
|
||||
|
||||
templ workWeekComponent(week models.WorkWeek, onlyAccept bool) {
|
||||
{{
|
||||
year, kw := week.WeekStart.ISOWeek()
|
||||
progress := (float32(week.WorktimeVirtual.Hours()) / week.User.ArbeitszeitPerWoche) * 100
|
||||
}}
|
||||
<div class="employeComponent grid-sub responsive lg:divide-x-1 max-md:divide-y-1 @container">
|
||||
<div class="grid-cell flex flex-col max-md:bg-neutral-300 gap-2">
|
||||
if !onlyAccept {
|
||||
<div class="lg:hidden">
|
||||
@weekPicker(week.WeekStart)
|
||||
</div>
|
||||
}
|
||||
<p class="font-bold uppercase">{ week.User.Vorname } { week.User.Name }</p>
|
||||
<div class="grid grid-cols-5 gap-2 lg:grid-cols-1">
|
||||
if !onlyAccept {
|
||||
<div class="col-span-2">
|
||||
<span class="flex flex-row gap-2 items-center">
|
||||
@statusCheckMark(week.CheckStatus(), models.WeekStatusSent)
|
||||
Gesendet
|
||||
</span>
|
||||
<span class="flex flex-row gap-2 items-center">
|
||||
@statusCheckMark(week.CheckStatus(), models.WeekStatusAccepted)
|
||||
Akzeptiert
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
<div class="flex flex-row gap-2 col-span-3">
|
||||
@timeGaugeComponent(int8(progress), false)
|
||||
<div>
|
||||
<p>Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)) }</p>
|
||||
<p>Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(week.Overtime, true)) }</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-cell col-span-3 flex flex-col @7xl:grid @7xl:grid-cols-5 gap-2 py-4 content-baseline">
|
||||
for _, day := range week.Days {
|
||||
@defaultWeekDayComponent(week.User, day)
|
||||
}
|
||||
</div>
|
||||
<div class="grid-cell flex flex-col gap-2 justify-between">
|
||||
if onlyAccept {
|
||||
<p class="text-sm"><span class="">Woche:</span> { fmt.Sprintf("%02d-%d", kw, year) }</p>
|
||||
} else {
|
||||
<div class="max-md:hidden">
|
||||
@weekPicker(week.WeekStart)
|
||||
</div>
|
||||
}
|
||||
<form method="post" class="flex flex-col gap-2">
|
||||
{{
|
||||
week.CheckStatus()
|
||||
method := "accept"
|
||||
if !onlyAccept {
|
||||
method = "send"
|
||||
}
|
||||
}}
|
||||
<input type="hidden" name="method" value={ method }/>
|
||||
<input type="hidden" name="user" value={ strconv.Itoa(week.User.PersonalNummer) }/>
|
||||
<input type="hidden" name="week" value={ week.WeekStart.Format(time.DateOnly) }/>
|
||||
if onlyAccept {
|
||||
if week.Status == models.WeekStatusDifferences {
|
||||
<p class="text-red-600 text-sm">Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen</p>
|
||||
}
|
||||
<button type="submit" disabled?={ week.Status == models.WeekStatusDifferences } class="btn">Bestätigen</button>
|
||||
} else {
|
||||
switch {
|
||||
case week.RequiresAction():
|
||||
<p class="text-sm text-red-500">bitte zuerst Buchungen anpassen</p>
|
||||
case time.Since(week.WeekStart) < 24*7*time.Hour:
|
||||
<p class="text-sm text-red-500">Die Woche kann erst am nächsten Montag gesendet werden!</p>
|
||||
case week.Status == models.WeekStatusNone:
|
||||
<p class="text-sm">an Vorgesetzten senden</p>
|
||||
case week.Status == models.WeekStatusSent:
|
||||
<p class="text-sm">an Vorgesetzten gesendet</p>
|
||||
case week.Status == models.WeekStatusAccepted:
|
||||
<p class="text-sm">vom Vorgesetzten bestätigt</p>
|
||||
}
|
||||
<button disabled?={ week.Status < models.WeekStatusSent } type="submit" class="btn">Korrigieren</button>
|
||||
<button disabled?={ time.Since(week.WeekStart) < 24*7*time.Hour || week.Status >= models.WeekStatusSent || week.RequiresAction() } type="submit" class="btn">Senden</button>
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ userPresenceComponent(user models.User, present bool) {
|
||||
<div class="grid-cell group flex flex-row gap-2">
|
||||
if present {
|
||||
|
||||
@@ -9,10 +9,8 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"arbeitszeitmessung/helper"
|
||||
"arbeitszeitmessung/models"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -45,7 +43,7 @@ func weekPicker(weekStart time.Time) templ.Component {
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(weekStart.Format(time.DateOnly))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 14, Col: 98}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 12, Col: 98}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -75,7 +73,7 @@ func weekPicker(weekStart time.Time) templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d, %d", kw, year))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 20, Col: 69}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 18, Col: 69}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -116,7 +114,7 @@ func weekPicker(weekStart time.Time) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func defaultWeekDayComponent(u models.User, day models.IWorkDay) templ.Component {
|
||||
func workDayWeekComponent(workDay *models.WorkDay) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@@ -137,208 +135,55 @@ func defaultWeekDayComponent(u models.User, day models.IWorkDay) templ.Component
|
||||
templ_7745c5c3_Var6 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<div class=\"flex flex-row gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = timeGaugeComponent(day.GetDayProgress(u), false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<div class=\"flex flex-col\"><p class=\"\"><span class=\"font-bold uppercase hidden md:inline\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatGermanDayOfWeek(day.Date()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 33, Col: 108}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, ":</span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.Date().Format("02.01.2006"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 33, Col: 152}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
work, pause, _ := day.GetTimes(u, models.WorktimeBaseDay, false)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<div class=\"flex flex-row gap-2\"><span class=\"text-accent\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 36, Col: 59}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</span> <span class=\"text-neutral-500\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 37, Col: 65}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</span></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
workDay, _ := day.(*models.WorkDay)
|
||||
templ_7745c5c3_Err = workDayWeekComponent(workDay, u).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
switch c.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
workDay, _ := c.(*models.WorkDay)
|
||||
templ_7745c5c3_Err = workDayWeekComponent(workDay, u).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
default:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(c.ToString())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 50, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.ToString())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 54, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func workDayWeekComponent(workDay *models.WorkDay, u models.User) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var13 == nil {
|
||||
templ_7745c5c3_Var13 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if !workDay.RequiresAction() {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<div class=\"flex flex-row gap-2 items-center\"><span class=\"icon-[material-symbols-light--schedule-outline] flex-shrink-0\"></span> ")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<div class=\"flex flex-row gap-2 items-center\"><span class=\"icon-[material-symbols-light--schedule-outline] flex-shrink-0\"></span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
switch {
|
||||
case !workDay.TimeFrom.Equal(workDay.TimeTo):
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<span>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.TimeFrom.Format("15:04"))
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.TimeFrom.Format("15:04"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 66, Col: 45}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 33, Col: 45}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</span> <span>-</span> <span>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</span> <span>-</span> <span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.TimeTo.Format("15:04"))
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.TimeTo.Format("15:04"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 68, Col: 43}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 35, Col: 43}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "</span>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
default:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<p>Keine Anwesenheit</p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<p>Keine Anwesenheit</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "</div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "<p class=\"text-red-600\">Bitte anpassen</p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<p class=\"text-red-600\">Bitte anpassen</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -347,313 +192,6 @@ func workDayWeekComponent(workDay *models.WorkDay, u models.User) templ.Componen
|
||||
})
|
||||
}
|
||||
|
||||
func workWeekComponent(week models.WorkWeek, onlyAccept bool) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var16 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var16 == nil {
|
||||
templ_7745c5c3_Var16 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
year, kw := week.WeekStart.ISOWeek()
|
||||
progress := (float32(week.WorktimeVirtual.Hours()) / week.User.ArbeitszeitPerWoche) * 100
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<div class=\"employeComponent grid-sub responsive lg:divide-x-1 max-md:divide-y-1 @container\"><div class=\"grid-cell flex flex-col max-md:bg-neutral-300 gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !onlyAccept {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<div class=\"lg:hidden\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = weekPicker(week.WeekStart).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<p class=\"font-bold uppercase\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 string
|
||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 90, Col: 53}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var18 string
|
||||
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 90, Col: 72}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</p><div class=\"grid grid-cols-5 gap-2 lg:grid-cols-1\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !onlyAccept {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<div class=\"col-span-2\"><span class=\"flex flex-row gap-2 items-center\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = statusCheckMark(week.CheckStatus(), models.WeekStatusSent).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "Gesendet</span> <span class=\"flex flex-row gap-2 items-center\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = statusCheckMark(week.CheckStatus(), models.WeekStatusAccepted).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "Akzeptiert</span></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<div class=\"flex flex-row gap-2 col-span-3\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = timeGaugeComponent(int8(progress), false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<div><p>Arbeitszeit: ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var19 string
|
||||
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 107, Col: 79}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</p><p>Überstunden: ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var20 string
|
||||
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDurationFill(week.Overtime, true)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 108, Col: 90}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</p></div></div></div></div><div class=\"grid-cell col-span-3 flex flex-col @7xl:grid @7xl:grid-cols-5 gap-2 py-4 content-baseline\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, day := range week.Days {
|
||||
templ_7745c5c3_Err = defaultWeekDayComponent(week.User, day).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "</div><div class=\"grid-cell flex flex-col gap-2 justify-between\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if onlyAccept {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "<p class=\"text-sm\"><span class=\"\">Woche:</span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var21 string
|
||||
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 120, Col: 86}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<div class=\"max-md:hidden\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = weekPicker(week.WeekStart).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<form method=\"post\" class=\"flex flex-col gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
week.CheckStatus()
|
||||
method := "accept"
|
||||
if !onlyAccept {
|
||||
method = "send"
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "<input type=\"hidden\" name=\"method\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var22 string
|
||||
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(method)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 134, Col: 53}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\"> <input type=\"hidden\" name=\"user\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var23 string
|
||||
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(week.User.PersonalNummer))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 135, Col: 83}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "\"> <input type=\"hidden\" name=\"week\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var24 string
|
||||
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(week.WeekStart.Format(time.DateOnly))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 136, Col: 81}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "\"> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if onlyAccept {
|
||||
if week.Status == models.WeekStatusDifferences {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "<p class=\"text-red-600 text-sm\">Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, " <button type=\"submit\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if week.Status == models.WeekStatusDifferences {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, " disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, " class=\"btn\">Bestätigen</button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
switch {
|
||||
case week.RequiresAction():
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<p class=\"text-sm text-red-500\">bitte zuerst Buchungen anpassen</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case time.Since(week.WeekStart) < 24*7*time.Hour:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "<p class=\"text-sm text-red-500\">Die Woche kann erst am nächsten Montag gesendet werden!</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case week.Status == models.WeekStatusNone:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<p class=\"text-sm\">an Vorgesetzten senden</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case week.Status == models.WeekStatusSent:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<p class=\"text-sm\">an Vorgesetzten gesendet</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case week.Status == models.WeekStatusAccepted:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "<p class=\"text-sm\">vom Vorgesetzten bestätigt</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, " <button")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if week.Status < models.WeekStatusSent {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, " disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, " type=\"submit\" class=\"btn\">Korrigieren</button> <button")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if time.Since(week.WeekStart) < 24*7*time.Hour || week.Status >= models.WeekStatusSent || week.RequiresAction() {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, " type=\"submit\" class=\"btn\">Senden</button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "</form></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func userPresenceComponent(user models.User, present bool) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
@@ -670,53 +208,53 @@ func userPresenceComponent(user models.User, present bool) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var25 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var25 == nil {
|
||||
templ_7745c5c3_Var25 = templ.NopComponent
|
||||
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var9 == nil {
|
||||
templ_7745c5c3_Var9 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "<div class=\"grid-cell group flex flex-row gap-2\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<div class=\"grid-cell group flex flex-row gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if present {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<div class=\"h-8 bg-accent rounded-md group-hover:text-black md:text-transparent text-center p-1\">Anwesend</div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<div class=\"h-8 bg-accent rounded-md group-hover:text-black md:text-transparent text-center p-1\">Anwesend</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "<div class=\"h-8 bg-red-600 rounded-md group-hover:text-white md:text-transparent text-center p-1\">Abwesend</div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<div class=\"h-8 bg-red-600 rounded-md group-hover:text-white md:text-transparent text-center p-1\">Abwesend</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "<p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var26 string
|
||||
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname)
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 170, Col: 19}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 52, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, " ")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var27 string
|
||||
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 170, Col: 33}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 52, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</p></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "</p></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@ templ lineComponent() {
|
||||
}
|
||||
|
||||
templ changeButtonComponent(id string, workDay bool) {
|
||||
<button class="change-button-component btn w-auto group/button" type="button" onclick={ templ.JSFuncCall("editWorkday", templ.JSExpression("this"), templ.JSExpression("event"), id, workDay) }>
|
||||
<button class="h-10 change-button-component btn w-auto group/button" type="button" onclick={ templ.JSFuncCall("editWorkday", templ.JSExpression("this"), templ.JSExpression("event"), id, workDay) }>
|
||||
<p class="hidden md:block group-[.edit]/button:hidden">Ändern</p>
|
||||
<p class="hidden group-[.edit]/button:md:block">Absenden</p>
|
||||
<p class="hidden group-[.edit]/button:md:block">Speichern</p>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 md:hidden">
|
||||
<path class="group-[.edit]/button:hidden md:hidden" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325"></path>
|
||||
<path class="hidden group-[.edit]/button:block md:hidden" d="M12.736 3.97a.733.733 0 0 1 j1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="hidden group-[.edit]:flex btn basis-[content] items-center" onclick={ templ.JSFuncCall("clearEditState") }><span class="size-5 icon-[material-symbols-light--cancel-outline]"></span></button>
|
||||
<button class="h-10 hidden group-[.edit]:flex btn basis-[content] items-center" onclick={ templ.JSFuncCall("clearEditState") }><span class="size-5 icon-[material-symbols-light--cancel-outline]"></span></button>
|
||||
}
|
||||
|
||||
templ timeGaugeComponent(progress int8, today bool) {
|
||||
@@ -98,15 +98,16 @@ templ absentInput(a *models.Absence) {
|
||||
<input type="hidden" name="aw_id" value={ a.CounterId }/>
|
||||
}
|
||||
|
||||
templ newBookingComponent(d *models.WorkDay) {
|
||||
<div class="new-booking-component hidden group-[.edit]:flex flex-row gap-2 items-center edit-box border-dashed">
|
||||
//js function to select the right entry
|
||||
templ newBookingComponent(d models.IWorkDay) {
|
||||
<div class="new-booking-component hidden group-[.edit]:flex flex-row gap-2 items-center edit-box border-dashed" id={ "nb" + d.Date().Format(time.DateOnly) }>
|
||||
<input name="timestamp" type="time" value={ time.Now().Format("15:04") } class="text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm px-3 py-2 cursor-pointer"/>
|
||||
<input name="date" type="hidden" value={ d.Day.Format(time.DateOnly) }/>
|
||||
<input name="date" type="hidden" value={ d.Date().Format(time.DateOnly) }/>
|
||||
<div class="relative">
|
||||
<select class="cursor-pointer appearance-none" name="check_in_out">
|
||||
<option value="0" disabled>Kommen/Gehen</option>
|
||||
<option value="3" selected?={ len(d.Bookings) > 0 && d.Bookings[len(d.Bookings)-1].CheckInOut%2 == 0 }>Kommen</option>
|
||||
<option value="4" selected?={ len(d.Bookings) > 0 && d.Bookings[len(d.Bookings)-1].CheckInOut%2 == 1 }>Gehen</option>
|
||||
<option value="3">Kommen</option>
|
||||
<option value="4">Gehen</option>
|
||||
</select>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.2" stroke="currentColor" class="h-5 w-5 ml-1 absolute right-1 top-[0.125rem] text-slate-700">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"></path>
|
||||
|
||||
@@ -69,7 +69,7 @@ func changeButtonComponent(id string, workDay bool) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<button class=\"change-button-component btn w-auto group/button\" type=\"button\" onclick=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<button class=\"h-10 change-button-component btn w-auto group/button\" type=\"button\" onclick=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func changeButtonComponent(id string, workDay bool) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"><p class=\"hidden md:block group-[.edit]/button:hidden\">Ändern</p><p class=\"hidden group-[.edit]/button:md:block\">Absenden</p><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"w-4 h-4 md:hidden\"><path class=\"group-[.edit]/button:hidden md:hidden\" d=\"M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325\"></path> <path class=\"hidden group-[.edit]/button:block md:hidden\" d=\"M12.736 3.97a.733.733 0 0 1 j1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"></path></svg></button> ")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"><p class=\"hidden md:block group-[.edit]/button:hidden\">Ändern</p><p class=\"hidden group-[.edit]/button:md:block\">Speichern</p><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"w-4 h-4 md:hidden\"><path class=\"group-[.edit]/button:hidden md:hidden\" d=\"M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325\"></path> <path class=\"hidden group-[.edit]/button:block md:hidden\" d=\"M12.736 3.97a.733.733 0 0 1 j1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"></path></svg></button> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func changeButtonComponent(id string, workDay bool) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<button class=\"hidden group-[.edit]:flex btn basis-[content] items-center\" onclick=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<button class=\"h-10 hidden group-[.edit]:flex btn basis-[content] items-center\" onclick=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -455,7 +455,8 @@ func absentInput(a *models.Absence) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func newBookingComponent(d *models.WorkDay) templ.Component {
|
||||
// js function to select the right entry
|
||||
func newBookingComponent(d models.IWorkDay) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@@ -476,53 +477,46 @@ func newBookingComponent(d *models.WorkDay) templ.Component {
|
||||
templ_7745c5c3_Var24 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<div class=\"new-booking-component hidden group-[.edit]:flex flex-row gap-2 items-center edit-box border-dashed\"><input name=\"timestamp\" type=\"time\" value=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<div class=\"new-booking-component hidden group-[.edit]:flex flex-row gap-2 items-center edit-box border-dashed\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var25 string
|
||||
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(time.Now().Format("15:04"))
|
||||
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs("nb" + d.Date().Format(time.DateOnly))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 103, Col: 72}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 103, Col: 155}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\" class=\"text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm px-3 py-2 cursor-pointer\"> <input name=\"date\" type=\"hidden\" value=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\"><input name=\"timestamp\" type=\"time\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var26 string
|
||||
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(d.Day.Format(time.DateOnly))
|
||||
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(time.Now().Format("15:04"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 104, Col: 70}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 104, Col: 72}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "\"><div class=\"relative\"><select class=\"cursor-pointer appearance-none\" name=\"check_in_out\"><option value=\"0\" disabled>Kommen/Gehen</option> <option value=\"3\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "\" class=\"text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm px-3 py-2 cursor-pointer\"> <input name=\"date\" type=\"hidden\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if len(d.Bookings) > 0 && d.Bookings[len(d.Bookings)-1].CheckInOut%2 == 0 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, " selected")
|
||||
var templ_7745c5c3_Var27 string
|
||||
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(d.Date().Format(time.DateOnly))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 105, Col: 73}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, ">Kommen</option> <option value=\"4\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if len(d.Bookings) > 0 && d.Bookings[len(d.Bookings)-1].CheckInOut%2 == 1 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " selected")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, ">Gehen</option></select> <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.2\" stroke=\"currentColor\" class=\"h-5 w-5 ml-1 absolute right-1 top-[0.125rem] text-slate-700\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9\"></path></svg></div><div class=\"w-full\"></div><button name=\"action\" value=\"add\" type=\"submit\" class=\"hidden btn border-0 rounded-none grow-0 w-auto group-[.edit]:inline\"><span class=\"hidden md:inline\">Hinzufügen</span><span class=\"md:hidden\">+</span></button></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\"><div class=\"relative\"><select class=\"cursor-pointer appearance-none\" name=\"check_in_out\"><option value=\"0\" disabled>Kommen/Gehen</option> <option value=\"3\">Kommen</option> <option value=\"4\">Gehen</option></select> <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.2\" stroke=\"currentColor\" class=\"h-5 w-5 ml-1 absolute right-1 top-[0.125rem] text-slate-700\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9\"></path></svg></div><div class=\"w-full\"></div><button name=\"action\" value=\"add\" type=\"submit\" class=\"hidden btn border-0 rounded-none grow-0 w-auto group-[.edit]:inline\"><span class=\"hidden md:inline\">Hinzufügen</span><span class=\"md:hidden\">+</span></button></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -546,74 +540,74 @@ func bookingComponent(booking models.Booking) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var27 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var27 == nil {
|
||||
templ_7745c5c3_Var27 = templ.NopComponent
|
||||
templ_7745c5c3_Var28 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var28 == nil {
|
||||
templ_7745c5c3_Var28 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div><p class=\"text-neutral-500 edit-box\"><span class=\"text-black group-[.edit]:hidden inline\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var28 string
|
||||
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 123, Col: 91}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "</span> <input disabled name=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "<div><p class=\"text-neutral-500 edit-box\"><span class=\"text-black group-[.edit]:hidden inline\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var29 string
|
||||
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs("booking_" + strconv.Itoa(booking.CounterId))
|
||||
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 124, Col: 70}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 124, Col: 91}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "\" type=\"time\" value=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</span> <input disabled name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var30 string
|
||||
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04"))
|
||||
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs("booking_" + strconv.Itoa(booking.CounterId))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 124, Col: 126}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 125, Col: 70}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\" class=\"text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm px-3 py-2 cursor-pointer\"> ")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "\" type=\"time\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var31 string
|
||||
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType())
|
||||
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 125, Col: 29}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 125, Col: 126}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\" class=\"text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm px-3 py-2 cursor-pointer\"> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var32 string
|
||||
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 126, Col: 29}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if booking.IsSubmittedAndChecked() {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<p>submitted</p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<p>submitted</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -637,12 +631,12 @@ func LegendComponent() templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var32 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var32 == nil {
|
||||
templ_7745c5c3_Var32 = templ.NopComponent
|
||||
templ_7745c5c3_Var33 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var33 == nil {
|
||||
templ_7745c5c3_Var33 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "<div class=\"flex flex-row gap-4 md:mx-[10%] print:hidden\"><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-red-600\"></div><span>Fehler</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-orange-500\"></div><span>Arbeitszeit unter regulär</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-accent\"></div><span>Arbeitszeit vollständig</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-purple-600\"></div><span>Überstunden</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-neutral-400\"></div><span>Keine Buchungen</span></div></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<div class=\"flex flex-row gap-4 md:mx-[10%] print:hidden\"><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-red-600\"></div><span>Fehler</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-orange-500\"></div><span>Arbeitszeit unter regulär</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-accent\"></div><span>Arbeitszeit vollständig</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-purple-600\"></div><span>Überstunden</span></div><div class=\"flex flex-row items-center gap-2\"><div class=\"rounded-full size-4 bg-neutral-400\"></div><span>Keine Buchungen</span></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ templ inputForm() {
|
||||
urlParams := ctx.Value("urlParams").(url.Values)
|
||||
user := ctx.Value("user").(models.User)
|
||||
}}
|
||||
<div class="sticky top-0 z-100 grid-sub divide-y-1">
|
||||
<div class="grid-sub divide-x-1 bg-neutral-300 responsive">
|
||||
<div class="grid-cell md:col-span-1 max-md:grid grid-cols-2">
|
||||
<p class="font-bold uppercase">{ user.Vorname + " " + user.Name }</p>
|
||||
@@ -81,6 +82,7 @@ templ inputForm() {
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ defaultDayComponent(day models.IWorkDay) {
|
||||
@@ -113,7 +115,7 @@ templ defaultDayComponent(day models.IWorkDay) {
|
||||
if pause > 0 {
|
||||
<p class="text-neutral-500 flex flex-row items-center"><span class="icon-[material-symbols-light--motion-photos-paused-outline]"></span>{ helper.FormatDuration(pause) }</p>
|
||||
}
|
||||
if overtime != 0 && day.IsEmpty() == false {
|
||||
if !day.IsEmpty() && overtime != 0 {
|
||||
<p class="text-neutral-500 flex flex-row items-center">
|
||||
<span class="icon-[material-symbols-light--more-time]"></span>
|
||||
{ helper.FormatDuration(overtime) }
|
||||
@@ -125,52 +127,52 @@ templ defaultDayComponent(day models.IWorkDay) {
|
||||
</div>
|
||||
<div class="all-booking-component grid-cell flex flex-row md:col-span-3 col-span-2 gap-2 w-full">
|
||||
@lineComponent()
|
||||
<form id={ "time-" + day.Date().Format(time.DateOnly) } class={ "flex flex-col gap-2 w-full", justify } method="post">
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
{{ workDay, _ := day.(*models.WorkDay) }}
|
||||
@workdayComponent(workDay)
|
||||
<form id={ "time-" + day.Date().Format(time.DateOnly) } class={ "bookings flex flex-col gap-2 w-full", justify } method="post">
|
||||
if (day.GetDayProgress(user) < 100 || day.IsWorkDay()) {
|
||||
@newAbsenceComponent()
|
||||
case models.DayTypeAbsence:
|
||||
{{ absentDay, _ := day.(*models.Absence) }}
|
||||
@absenceComponent(absentDay, false)
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
switch c.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
{{ workDay, _ := c.(*models.WorkDay) }}
|
||||
@workdayComponent(workDay)
|
||||
@newAbsenceComponent()
|
||||
case models.DayTypeAbsence:
|
||||
{{ absentDay, _ := c.(*models.Absence) }}
|
||||
@absenceComponent(absentDay, false)
|
||||
default:
|
||||
<p>{ c.ToString() }</p>
|
||||
}
|
||||
}
|
||||
default:
|
||||
<p>{ day.ToString() }</p>
|
||||
@timeDayTypeSwitch(day, true)
|
||||
@newBookingComponent(day)
|
||||
} else {
|
||||
@timeDayTypeSwitch(day, true)
|
||||
}
|
||||
<input type="hidden" name="action" value="change"/> <!-- default action value for ändern button -->
|
||||
</form>
|
||||
</div>
|
||||
<div class="grid-cell flex flex-row gap-2 items-end">
|
||||
@changeButtonComponent("time-"+day.Date().Format(time.DateOnly), day.IsWorkDay())
|
||||
@changeButtonComponent("time-"+day.Date().Format(time.DateOnly), true)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ timeDayTypeSwitch(day models.IWorkDay, fromCompound bool) {
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
{{ workDay, _ := day.(*models.WorkDay) }}
|
||||
@workdayComponent(workDay)
|
||||
case models.DayTypeAbsence:
|
||||
{{ absentDay, _ := day.(*models.Absence) }}
|
||||
@absenceComponent(absentDay, fromCompound)
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
@timeDayTypeSwitch(c, true)
|
||||
}
|
||||
default:
|
||||
<p>{ day.ToString() }</p>
|
||||
}
|
||||
}
|
||||
|
||||
templ workdayComponent(workDay *models.WorkDay) {
|
||||
if len(workDay.Bookings) < 1 {
|
||||
<p class="text group-[.edit]:hidden">Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!</p>
|
||||
}
|
||||
} else {
|
||||
if workDay.IsKurzArbeit() && len(workDay.Bookings) > 0 {
|
||||
@absenceComponent(workDay.GetKurzArbeit(), true)
|
||||
}
|
||||
for _, booking := range workDay.Bookings {
|
||||
@bookingComponent(booking)
|
||||
}
|
||||
@newBookingComponent(workDay)
|
||||
<input type="hidden" name="select_kommen" value={ len(workDay.Bookings) > 0 && workDay.Bookings[len(workDay.Bookings)-1].CheckInOut%2 == 0 }/>
|
||||
}
|
||||
}
|
||||
|
||||
templ holidayComponent(d models.IWorkDay) {
|
||||
|
||||
@@ -105,14 +105,14 @@ func inputForm() templ.Component {
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
urlParams := ctx.Value("urlParams").(url.Values)
|
||||
user := ctx.Value("user").(models.User)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<div class=\"grid-sub divide-x-1 bg-neutral-300 responsive\"><div class=\"grid-cell md:col-span-1 max-md:grid grid-cols-2\"><p class=\"font-bold uppercase\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<div class=\"sticky top-0 z-100 grid-sub divide-y-1\"><div class=\"grid-sub divide-x-1 bg-neutral-300 responsive\"><div class=\"grid-cell md:col-span-1 max-md:grid grid-cols-2\"><p class=\"font-bold uppercase\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname + " " + user.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 34, Col: 66}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 35, Col: 67}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -125,7 +125,7 @@ func inputForm() templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(user.Overtime)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 37, Col: 42}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 38, Col: 43}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -146,7 +146,7 @@ func inputForm() templ.Component {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(urlParams.Get("time_from"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 43, Col: 57}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 44, Col: 58}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -159,7 +159,7 @@ func inputForm() templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(urlParams.Get("time_to"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 44, Col: 55}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 45, Col: 56}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -177,7 +177,7 @@ func inputForm() templ.Component {
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(int(absence.Id)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 61, Col: 51}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 62, Col: 52}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -190,7 +190,7 @@ func inputForm() templ.Component {
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(absence.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 61, Col: 68}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 62, Col: 69}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -201,7 +201,7 @@ func inputForm() templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</select> <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.2\" stroke=\"currentColor\" class=\"h-5 w-5 ml-1 absolute top-2.5 right-2.5 text-slate-700\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9\"></path></svg></div></div><div class=\"grid-cell\"><label class=\"block mb-1 text-sm text-neutral-700\">Abwesenheit ab</label> <input name=\"date_from\" type=\"date\" class=\"btn bg-neutral-100\"></div><div class=\"grid-cell border-r-1\"><label class=\"block mb-1 text-sm text-neutral-700\">Abwesenheit bis</label> <input name=\"date_to\" type=\"date\" class=\"btn bg-neutral-100\"></div><div class=\"grid-cell flex flex-row items-end\"><div class=\"flex flex-row gap-2 w-full\"><button name=\"action\" value=\"insert\" type=\"submit\" class=\"bg-neutral-100 btn hover:bg-neutral-700\">Speichern</button> <button name=\"action\" value=\"delete\" type=\"submit\" class=\"bg-neutral-100 btn hover:bg-red-700 flex basis-[content] items-center\"><span class=\"size-5 icon-[material-symbols-light--delete-outline]\"></span></button></div></div></form>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</select> <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.2\" stroke=\"currentColor\" class=\"h-5 w-5 ml-1 absolute top-2.5 right-2.5 text-slate-700\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9\"></path></svg></div></div><div class=\"grid-cell\"><label class=\"block mb-1 text-sm text-neutral-700\">Abwesenheit ab</label> <input name=\"date_from\" type=\"date\" class=\"btn bg-neutral-100\"></div><div class=\"grid-cell border-r-1\"><label class=\"block mb-1 text-sm text-neutral-700\">Abwesenheit bis</label> <input name=\"date_to\" type=\"date\" class=\"btn bg-neutral-100\"></div><div class=\"grid-cell flex flex-row items-end\"><div class=\"flex flex-row gap-2 w-full\"><button name=\"action\" value=\"insert\" type=\"submit\" class=\"bg-neutral-100 btn hover:bg-neutral-700\">Speichern</button> <button name=\"action\" value=\"delete\" type=\"submit\" class=\"bg-neutral-100 btn hover:bg-red-700 flex basis-[content] items-center\"><span class=\"size-5 icon-[material-symbols-light--delete-outline]\"></span></button></div></div></form></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -268,7 +268,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatGermanDayOfWeek(day.Date()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 99, Col: 98}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 101, Col: 98}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -281,7 +281,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.Date().Format("02.01.2006"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 99, Col: 142}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 101, Col: 142}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -308,7 +308,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 111, Col: 155}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 113, Col: 155}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -331,7 +331,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 114, Col: 173}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 116, Col: 173}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -346,7 +346,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if overtime != 0 && day.IsEmpty() == false {
|
||||
if !day.IsEmpty() && overtime != 0 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<p class=\"text-neutral-500 flex flex-row items-center\"><span class=\"icon-[material-symbols-light--more-time]\"></span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
@@ -354,7 +354,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
var templ_7745c5c3_Var16 string
|
||||
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(overtime))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 119, Col: 41}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 121, Col: 41}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -375,7 +375,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 = []any{"flex flex-col gap-2 w-full", justify}
|
||||
var templ_7745c5c3_Var17 = []any{"bookings flex flex-col gap-2 w-full", justify}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
@@ -387,7 +387,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
var templ_7745c5c3_Var18 string
|
||||
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs("time-" + day.Date().Format(time.DateOnly))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 128, Col: 56}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 130, Col: 56}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -410,10 +410,8 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
workDay, _ := day.(*models.WorkDay)
|
||||
templ_7745c5c3_Err = workdayComponent(workDay).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if day.GetDayProgress(user) < 100 || day.IsWorkDay() {
|
||||
templ_7745c5c3_Err = newAbsenceComponent().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -421,22 +419,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = newAbsenceComponent().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case models.DayTypeAbsence:
|
||||
absentDay, _ := day.(*models.Absence)
|
||||
templ_7745c5c3_Err = absenceComponent(absentDay, false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
switch c.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
workDay, _ := c.(*models.WorkDay)
|
||||
templ_7745c5c3_Err = workdayComponent(workDay).Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = timeDayTypeSwitch(day, true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -444,35 +427,72 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = newAbsenceComponent().Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = newBookingComponent(day).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = timeDayTypeSwitch(day, true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<input type=\"hidden\" name=\"action\" value=\"change\"><!-- default action value for ändern button --></form></div><div class=\"grid-cell flex flex-row gap-2 items-end\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = changeButtonComponent("time-"+day.Date().Format(time.DateOnly), true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func timeDayTypeSwitch(day models.IWorkDay, fromCompound bool) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var20 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var20 == nil {
|
||||
templ_7745c5c3_Var20 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
switch day.Type() {
|
||||
case models.DayTypeWorkday:
|
||||
workDay, _ := day.(*models.WorkDay)
|
||||
templ_7745c5c3_Err = workdayComponent(workDay).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case models.DayTypeAbsence:
|
||||
absentDay, _ := c.(*models.Absence)
|
||||
templ_7745c5c3_Err = absenceComponent(absentDay, false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
absentDay, _ := day.(*models.Absence)
|
||||
templ_7745c5c3_Err = absenceComponent(absentDay, fromCompound).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
default:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<p>")
|
||||
case models.DayTypeCompound:
|
||||
for _, c := range day.(*models.CompoundDay).DayParts {
|
||||
templ_7745c5c3_Err = timeDayTypeSwitch(c, true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var20 string
|
||||
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(c.ToString())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 148, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<p>")
|
||||
@@ -482,7 +502,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
var templ_7745c5c3_Var21 string
|
||||
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(day.ToString())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 152, Col: 25}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 160, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -493,18 +513,6 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<input type=\"hidden\" name=\"action\" value=\"change\"><!-- default action value for ändern button --></form></div><div class=\"grid-cell flex flex-row gap-2 items-end\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = changeButtonComponent("time-"+day.Date().Format(time.DateOnly), day.IsWorkDay()).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -531,11 +539,11 @@ func workdayComponent(workDay *models.WorkDay) templ.Component {
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if len(workDay.Bookings) < 1 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<p class=\"text group-[.edit]:hidden\">Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!</p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<p class=\"text group-[.edit]:hidden\">Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if workDay.IsKurzArbeit() && len(workDay.Bookings) > 0 {
|
||||
templ_7745c5c3_Err = absenceComponent(workDay.GetKurzArbeit(), true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -548,10 +556,24 @@ func workdayComponent(workDay *models.WorkDay) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = newBookingComponent(workDay).Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, " <input type=\"hidden\" name=\"select_kommen\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var23 string
|
||||
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(len(workDay.Bookings) > 0 && workDay.Bookings[len(workDay.Bookings)-1].CheckInOut%2 == 0)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 174, Col: 140}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -572,21 +594,21 @@ func holidayComponent(d models.IWorkDay) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var23 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var23 == nil {
|
||||
templ_7745c5c3_Var23 = templ.NopComponent
|
||||
templ_7745c5c3_Var24 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var24 == nil {
|
||||
templ_7745c5c3_Var24 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var24 string
|
||||
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(d.ToString())
|
||||
var templ_7745c5c3_Var25 string
|
||||
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(d.ToString())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 177, Col: 18}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 179, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
6
Cron/autoBackup.sh
Executable file
6
Cron/autoBackup.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
# cron-timing: 05 01 * * 1
|
||||
container_name="arbeitszeitmessung-main-db-1"
|
||||
filename=backup-$(date '+%d%m%Y').sql
|
||||
database_name=__DATABASE__
|
||||
docker exec $container_name pg_dump $database_name > /home/pi/arbeitszeitmessung-backup/$filename
|
||||
echo "created backup file: "$filename
|
||||
3
Cron/autoHolidays.sh
Executable file
3
Cron/autoHolidays.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
# Calls endpoint to write all public Holidays for the current year inside a database.
|
||||
port=__PORT__
|
||||
curl localhost:$port/auto/feiertage
|
||||
4
Cron/autoLogout.sh
Executable file
4
Cron/autoLogout.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
# cron-timing: 55 23 * * *
|
||||
# Calls endpoint to log out all users, still logged in for today
|
||||
port=__PORT__
|
||||
curl localhost:$port/auto/logout
|
||||
55
DB/initdb/01_create_user.sh
Executable file
55
DB/initdb/01_create_user.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
set -e # Exit on error
|
||||
|
||||
echo "Creating PostgreSQL user and setting permissions... $POSTGRES_USER for API user $POSTGRES_API_USER"
|
||||
|
||||
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
CREATE ROLE migrate LOGIN ENCRYPTED PASSWORD '$POSTGRES_PASSWORD';
|
||||
GRANT USAGE, CREATE ON SCHEMA public TO migrate;
|
||||
EOSQL
|
||||
|
||||
# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
|
||||
# GRANT SELECT, INSERT, UPDATE ON anwesenheit, abwesenheit, user_password, wochen_report, s_feiertage TO $POSTGRES_API_USER;
|
||||
# GRANT DELETE ON abwesenheit TO $POSTGRES_API_USER;
|
||||
# GRANT SELECT ON s_personal_daten, s_abwesenheit_typen, s_anwesenheit_typen, s_feiertage TO $POSTGRES_API_USER;
|
||||
# GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO $POSTGRES_API_USER;
|
||||
# EOSQL
|
||||
|
||||
echo "User creation and permissions setup complete!"
|
||||
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
|
||||
-- privilege roles
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'app_base') THEN
|
||||
CREATE ROLE app_base NOLOGIN;
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
|
||||
-- dynamic login role
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '$POSTGRES_API_USER') THEN
|
||||
CREATE ROLE $POSTGRES_API_USER
|
||||
LOGIN
|
||||
ENCRYPTED PASSWORD '$POSTGRES_API_PASS';
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
|
||||
-- grant base privileges
|
||||
GRANT app_base TO $POSTGRES_API_USER;
|
||||
GRANT CONNECT ON DATABASE $POSTGRES_DB TO $POSTGRES_API_USER;
|
||||
GRANT USAGE ON SCHEMA public TO $POSTGRES_API_USER;
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
EOSQL
|
||||
|
||||
# psql -v ON_ERROR_STOP=1 --username root --dbname arbeitszeitmessung
|
||||
@@ -1,8 +0,0 @@
|
||||
INSERT INTO "s_personal_daten" ("personal_nummer", "aktiv_beschaeftigt", "vorname", "nachname", "geburtsdatum", "plz", "adresse", "geschlecht", "card_uid", "hauptbeschaeftigungs_ort", "arbeitszeit_per_tag", "arbeitszeit_per_woche", "arbeitszeit_min_start", "arbeitszeit_max_ende", "vorgesetzter_pers_nr") VALUES
|
||||
(123, 't', 'Kim', 'Mustermensch', '2003-02-01', '08963', 'Altenburger Str. 44A', 1, 'aaaa-aaaa', 1, 8, 40, '07:00:00', '20:00:00', 0);
|
||||
|
||||
INSERT INTO "user_password" ("personal_nummer", "pass_hash") VALUES
|
||||
(123, crypt('max_pass', gen_salt('bf')));
|
||||
|
||||
INSERT INTO "s_anwesenheit_typen" ("anwesenheit_id", "anwesenheit_name") VALUES (1, 'Büro');
|
||||
INSERT INTO "s_abwesenheit_typen" ("abwesenheit_id", "abwesenheit_name", "arbeitszeit_equivalent") VALUES (1, 'Urlaub', 100), (2, 'Krank', 100), (3, 'Kurzarbeit', -1), (4, 'Urlaub untertags', 50);
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e # Exit on error
|
||||
|
||||
echo "Creating PostgreSQL user and setting permissions... $POSTGRES_USER for API user $POSTGRES_API_USER"
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
CREATE USER $POSTGRES_API_USER WITH ENCRYPTED PASSWORD '$POSTGRES_API_PASS';
|
||||
GRANT CONNECT ON DATABASE $POSTGRES_DB TO $POSTGRES_API_USER;
|
||||
GRANT USAGE ON SCHEMA public TO $POSTGRES_API_USER;
|
||||
GRANT SELECT, INSERT, UPDATE ON anwesenheit, abwesenheit, user_password, wochen_report, s_feiertage TO $POSTGRES_API_USER;
|
||||
GRANT SELECT ON s_personal_daten, s_abwesenheit_typen, s_anwesenheit_typen, s_feiertage TO $POSTGRES_API_USER;
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO $POSTGRES_API_USER;
|
||||
EOSQL
|
||||
|
||||
echo "User creation and permissions setup complete!"
|
||||
|
||||
# psql -v ON_ERROR_STOP=1 --username root --dbname arbeitszeitmessung
|
||||
@@ -3,7 +3,7 @@ services:
|
||||
db:
|
||||
volumes:
|
||||
- ${POSTGRES_PATH}:/var/lib/postgresql/data
|
||||
# - ${POSTGRES_PATH}/initdb:/docker-entrypoint-initdb.d
|
||||
- ${POSTGRES_PATH}/initdb:/docker-entrypoint-initdb.d
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
|
||||
@@ -25,12 +25,11 @@ services:
|
||||
- ${WEB_PORT}:8080
|
||||
depends_on:
|
||||
- db
|
||||
- document-creator
|
||||
volumes:
|
||||
- ../logs:/app/Backend/logs
|
||||
- ${LOG_PATH}:/app/logs
|
||||
restart: unless-stopped
|
||||
|
||||
document-creator:
|
||||
image: git.letsstein.de/tom/arbeitszeitmessung-doc-creator
|
||||
container_name: ${TYPST_CONTAINER}
|
||||
restart: unless-stopped
|
||||
# document-creator:
|
||||
# image: git.letsstein.de/tom/arbeitszeitmessung-doc-creator
|
||||
# container_name: ${TYPST_CONTAINER}
|
||||
# restart: unless-stopped
|
||||
|
||||
@@ -2,10 +2,12 @@ POSTGRES_USER=root # Postgres ADMIN Nutzername
|
||||
POSTGRES_PASSWORD=very_secure # Postgres ADMIN Passwort
|
||||
POSTGRES_API_USER=api_nutzer # Postgres API Nutzername (für Arbeitszeitmessung)
|
||||
POSTGRES_API_PASS=password # Postgres API Passwort (für Arbeitszeitmessung)
|
||||
POSTGRES_PATH=../DB # Datebank Pfad (relativ zu Docker Ordner oder absoluter pfad mit /...)
|
||||
POSTGRES_PATH=__ROOT__/DB # Datebank Pfad (relativ zu Docker Ordner oder absoluter pfad mit /...)
|
||||
POSTGRES_DB=arbeitszeitmessung # Postgres Datenbank Name
|
||||
POSTGRES_PORT=127.0.0.1:5432 # Postgres Port will not be exposed by default. regex:^[0-9]{1,5}$
|
||||
POSTGRES_PORT=127.0.0.1:5432 # Postgres Port normalerweise nicht freigegeben. regex:^[0-9]{1,5}$
|
||||
MIGRATIONS_PATH=__ROOT__/migrations # Pfad zu DB migrations (wenn nicht verändert wurde, bei default bleiben)
|
||||
TZ=Europe/Berlin # Zeitzone
|
||||
API_TOKEN=dont_access # API Token für ESP Endpoints
|
||||
WEB_PORT=8000 # Port from which Arbeitszeitmessung should be accessable regex:^[0-9]{1,5}$
|
||||
TYPST_CONTAINER=arbeitszeitmessung-doc-creator # Name of the pdf compiler container
|
||||
WEB_PORT=8000 # Port unter welchem Webserver erreichbar ist. regex:^[0-9]{1,5}$
|
||||
LOG_PATH=__ROOT__/logs # Pfad für Audit Logs
|
||||
LOG_LEVEL=warn # Welche Log-Nachrichten werden in der Konsole erscheinen
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
FROM ghcr.io/typst/typst:0.14.0
|
||||
|
||||
WORKDIR /app
|
||||
COPY ./templates /app/templates
|
||||
COPY ./static /app/static
|
||||
|
||||
ENTRYPOINT ["sh", "-c", "while true; do sleep 3600; done"]
|
||||
82
install.sh
82
install.sh
@@ -4,6 +4,10 @@ set -e
|
||||
envFile=Docker/.env
|
||||
envExample=Docker/env.example
|
||||
|
||||
autoBackupScript=Cron/autoBackup.sh
|
||||
autoHolidaysScript=Cron/autoHolidays.sh
|
||||
autoLogoutScript=Cron/autoLogout.sh
|
||||
|
||||
echo "Checking Docker installation..."
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "Docker not found. Install Docker? [y/N]"
|
||||
@@ -18,12 +22,16 @@ else
|
||||
echo "Docker is already installed."
|
||||
fi
|
||||
|
||||
###########################################################################
|
||||
|
||||
echo "Checking Docker Compose..."
|
||||
if ! docker compose version >/dev/null 2>&1; then
|
||||
echo "Docker Compose plugin missing. You may need to update Docker."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
###########################################################################
|
||||
|
||||
echo "Preparing .env file..."
|
||||
if [ ! -f $envFile ]; then
|
||||
if [ -f $envExample ]; then
|
||||
@@ -44,6 +52,9 @@ if [ ! -f $envFile ]; then
|
||||
raw_val=$(printf "%s" "$rest" | sed 's/ *#.*//')
|
||||
default_value=$(printf "%s" "$raw_val" | sed 's/"//g')
|
||||
|
||||
# Replace __ROOT__ with script pwd
|
||||
default_value="${default_value/__ROOT__/$(pwd)}"
|
||||
|
||||
regex=""
|
||||
if [[ "$comment" =~ regex:(.*)$ ]]; then
|
||||
regex="${BASH_REMATCH[1]}"
|
||||
@@ -96,13 +107,80 @@ else
|
||||
echo "Using existing .env. (found at $envFile)"
|
||||
fi
|
||||
|
||||
###########################################################################
|
||||
|
||||
LOG_PATH=$(grep -E '^LOG_PATH=' $envFile | cut -d= -f2)
|
||||
if [ -z "$LOG_PATH" ]; then
|
||||
echo "LOG_PATH not found in .env using default $(pwd)/logs"
|
||||
LOG_PATH=$(pwd)/logs
|
||||
else
|
||||
LOG_PATH=Docker/$LOG_PATH
|
||||
fi
|
||||
mkdir -p $LOG_PATH
|
||||
echo "Created logs folder at $LOG_PATH"
|
||||
|
||||
###########################################################################
|
||||
|
||||
echo -e "\n\n"
|
||||
echo "Start containers with docker compose up -d? [y/N]"
|
||||
read -r start_containers
|
||||
read -r start_containersmkdi
|
||||
if [[ "$start_containers" =~ ^[Yy]$ ]]; then
|
||||
|
||||
cd Docker
|
||||
mkdir ../logs
|
||||
docker compose up -d
|
||||
echo "Containers started."
|
||||
else
|
||||
echo "You can start them manually with: docker compose up -d"
|
||||
fi
|
||||
|
||||
###########################################################################
|
||||
|
||||
echo -e "\n\n"
|
||||
echo "Setup Crontab for automatic logout, backup and holiday creation? [y/N]"
|
||||
read -r setup_cron
|
||||
if [[ "$setup_cron" =~ ^[Yy]$ ]]; then
|
||||
WEB_PORT=$(grep -E '^WEB_PORT=' $envFile | cut -d= -f2)
|
||||
if [ -z "$WEB_PORT" ]; then
|
||||
echo "WEB_PORT not found in .env using default 8000"
|
||||
WEB_PORT=8000
|
||||
fi
|
||||
|
||||
POSTGRES_DB=$(grep -E '^POSTGRES_DB=' $envFile | cut -d= -f2)
|
||||
if [ -z "$POSTGRES_DB" ]; then
|
||||
echo "arbeitszeitmessung not found in .env using default arbeitszeitmessung"
|
||||
POSTGRES_DB="arbeitszeitmessung"
|
||||
fi
|
||||
|
||||
sed -i "s/__PORT__/$WEB_PORT/" $autoHolidaysScript
|
||||
sed -i "s/__PORT__/$WEB_PORT/" $autoLogoutScript
|
||||
sed -i "s/__DATABASE__/$POSTGRES_DB/" $autoBackupScript
|
||||
|
||||
chmod +x $autoBackupScript $autoHolidaysScript $autoLogoutScript
|
||||
|
||||
# echo "Scripts build with PORT=$WEB_PORT and DATABSE=$POSTGRES_DB!"
|
||||
echo "Adding rules to crontab."
|
||||
|
||||
cron_commands=$(mktemp /tmp/arbeitszeitmessung-cron.XXX)
|
||||
|
||||
for file in Cron/*; do
|
||||
cron_timing=$(grep -E '^# cron-timing:' "$file" | sed 's/^# cron-timing:[[:space:]]*//')
|
||||
|
||||
if [ -z "$cron_timing" ]; then
|
||||
echo "No cron-timing found in $file, so it's not added to crontab."
|
||||
continue
|
||||
fi
|
||||
|
||||
( crontab -l ; echo "$cron_timing $(pwd)/$file" )| awk '!x[$0]++' | crontab -
|
||||
echo "Added entry to crontab: $cron_timing $(pwd)/$file."
|
||||
done
|
||||
|
||||
if systemctl is-active --quiet cron.service ; then
|
||||
echo "cron.service is running. Everything should be fine now."
|
||||
else
|
||||
echo "cron.service is not running. Please start and enable cron.service."
|
||||
echo "For how to start a service, see: https://wiki.ubuntuusers.de/systemd/systemctl UNITNAME will be cron.service"
|
||||
fi
|
||||
|
||||
else
|
||||
echo "Please setup cron manually by executing crontab -e and adding all files from inside the Cron directory!"
|
||||
fi
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE migrate
|
||||
IN SCHEMA public
|
||||
GRANT SELECT ON TABLES TO app_base;
|
||||
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE migrate
|
||||
IN SCHEMA public
|
||||
GRANT USAGE, SELECT ON SEQUENCES TO app_base;
|
||||
|
||||
-- create "abwesenheit" table
|
||||
CREATE TABLE "abwesenheit" (
|
||||
"counter_id" bigserial NOT NULL,
|
||||
@@ -6,6 +14,7 @@ CREATE TABLE "abwesenheit" (
|
||||
"datum" timestamptz NULL DEFAULT (now())::date,
|
||||
PRIMARY KEY ("counter_id")
|
||||
);
|
||||
|
||||
-- create "anwesenheit" table
|
||||
CREATE TABLE "anwesenheit" (
|
||||
"counter_id" bigserial NOT NULL,
|
||||
@@ -55,3 +64,6 @@ CREATE TABLE "wochen_report" (
|
||||
PRIMARY KEY ("id"),
|
||||
CONSTRAINT "wochen_report_personal_nummer_woche_start_key" UNIQUE ("personal_nummer", "woche_start")
|
||||
);
|
||||
|
||||
GRANT INSERT, UPDATE ON abwesenheit, anwesenheit, wochen_report, user_password TO app_base;
|
||||
GRANT DELETE ON abwesenheit to app_base;
|
||||
|
||||
@@ -3,8 +3,3 @@
|
||||
DROP FUNCTION update_zuletzt_geandert;
|
||||
|
||||
DROP TRIGGER IF EXISTS pass_hash_update ON user_password;
|
||||
|
||||
|
||||
-- revert: Adds crypto extension
|
||||
|
||||
DROP EXTENSION IF EXISTS pgcrypto;
|
||||
|
||||
@@ -17,5 +17,3 @@ FOR EACH ROW
|
||||
EXECUTE FUNCTION update_zuletzt_geandert();
|
||||
|
||||
-- Adds crypto extension
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
@@ -11,3 +11,5 @@ CREATE TABLE "s_feiertage" (
|
||||
);
|
||||
-- create index "feiertage_unique_pro_jahr" to table: "s_feiertage"
|
||||
CREATE UNIQUE INDEX "feiertage_unique_pro_jahr" ON "s_feiertage" ((EXTRACT(year FROM datum)), "name");
|
||||
|
||||
GRANT INSERT, UPDATE ON s_feiertage TO app_base;
|
||||
|
||||
Reference in New Issue
Block a user