Files
homekeeper/beekeeper/R/screen_colonies.R
T
2026-07-06 19:25:38 +02:00

146 lines
5.1 KiB
R
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
screen_colonies_ui <- function(id) {
ns <- NS(id)
shiny::tagList(
shiny::uiOutput(ns("status_filters")),
shiny::uiOutput(ns("cards")),
shiny::br(),
shiny::div(class = "d-flex gap-2 mb-2",
shiny::actionButton(ns("quick_insp_btn"),
shiny::tagList(shiny::icon("bolt"), " Schnelldurchsicht"),
class = "btn btn-outline-primary w-100"
),
shiny::actionButton(ns("bulk_action_btn"),
shiny::tagList(shiny::icon("layer-group"), " Sammelmaßnahme"),
class = "btn btn-outline-secondary w-100"
)
),
shiny::div(class = "d-flex gap-2 mb-2",
shiny::actionButton(ns("lineage_btn"),
shiny::tagList(shiny::icon("sitemap"), " Stammbaum"),
class = "btn btn-outline-secondary w-100"
)
),
shiny::actionButton(ns("add_btn"), shiny::tagList(shiny::icon("plus"), " Neues Volk"),
class = "add-dashed btn", style = "width:100%;min-height:80px"
)
)
}
screen_colonies_server <- function(id, db, nav) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
reload <- reactiveVal(0)
status_filter <- reactiveVal("")
colonies <- reactive({
req(nav$apiary_id)
reload()
db_colonies_list(db, apiary_id = nav$apiary_id, include_closed = FALSE)
})
output$status_filters <- renderUI({
statuses <- c("Alle" = "", COLONY_STATUSES[names(COLONY_STATUSES) != "Eingegangen"])
shiny::div(class = "d-flex gap-2 mb-3 flex-wrap",
lapply(seq_along(statuses), function(i) {
val <- statuses[[i]]
active <- identical(status_filter(), val)
shiny::actionButton(
ns(paste0("sf_", i)), names(statuses)[i],
class = if (active) "btn btn-primary btn-sm" else "btn btn-outline-secondary btn-sm"
)
})
)
})
observe({
statuses <- c("Alle" = "", COLONY_STATUSES[names(COLONY_STATUSES) != "Eingegangen"])
lapply(seq_along(statuses), function(i) {
local({
li <- i; val <- statuses[[i]]
observeEvent(input[[paste0("sf_", li)]], status_filter(val), ignoreInit = TRUE)
})
})
})
filtered <- reactive({
cols <- colonies()
sf <- status_filter()
if (!is.null(sf) && sf != "") cols[cols$status == sf, ] else cols
})
output$cards <- renderUI({
cols <- filtered()
if (nrow(cols) == 0) return(shiny::p(class = "text-muted", "Keine Völker gefunden."))
lapply(seq_len(nrow(cols)), function(i) {
row <- cols[i, ]
days_ago <- if (!is.na(row$last_inspection_date)) {
d <- as.integer(Sys.Date() - as.Date(row$last_inspection_date))
if (d == 0) "heute" else if (d == 1) "gestern" else paste0("vor ", d, " Tagen")
} else "keine Durchsicht"
shiny::div(
class = "card tap-card mb-2",
onclick = sprintf("Shiny.setInputValue('%s', %d, {priority:'event'})",
ns("select"), row$id),
bslib::card_body(
class = "d-flex justify-content-between align-items-center py-2",
shiny::div(
shiny::tags$strong(row$name),
shiny::tags$p(class = "text-muted small mb-0", days_ago)
),
shiny::HTML(colony_status_badge(row$status))
)
)
})
})
observeEvent(input$select, {
nav$colony_id <- input$select
nav$screen <- "colony"
})
observeEvent(input$quick_insp_btn, { nav$screen <- "quick_inspection" })
observeEvent(input$bulk_action_btn, { nav$screen <- "bulk_action" })
observeEvent(input$lineage_btn, { nav$screen <- "lineage" })
# ---- Add colony modal ---------------------------------------------------
observeEvent(input$add_btn, {
cols <- db_colonies_list(db, include_closed = FALSE)
shiny::showModal(shiny::modalDialog(
title = "Neues Volk",
footer = shiny::tagList(
shiny::modalButton("Abbrechen"),
shiny::actionButton(ns("confirm_add"), "Anlegen", class = "btn-primary")
),
shiny::textInput(ns("new_name"), "Name *"),
shiny::selectInput(ns("new_status"), "Status",
choices = COLONY_STATUSES[names(COLONY_STATUSES) != "Eingegangen"],
selected = "wirtschaftsvolk"
),
shiny::selectInput(ns("new_parent"), "Muttervolk (optional)",
choices = c("" = "", setNames(cols$id, cols$name))
),
shiny::textAreaInput(ns("new_notes"), "Notizen", rows = 2)
))
})
observeEvent(input$confirm_add, {
if (nchar(trimws(input$new_name)) == 0) {
shiny::showNotification("Bitte einen Namen eingeben.", type = "warning", duration = 3)
return()
}
req(nav$apiary_id)
parent <- if (!is.null(input$new_parent) && input$new_parent != "")
as.integer(input$new_parent) else NA
db_colonies_insert(db,
name = trimws(input$new_name),
apiary_id = as.integer(nav$apiary_id),
status = input$new_status,
parent_colony_id = parent,
notes = input$new_notes
)
shiny::removeModal(); reload(reload() + 1L)
})
})
}