ACTION_TYPES <- c( "Mittelwand geben" = "mittelwand", "Fütterung" = "futterung", "Ablegerbildung" = "ablegerbildung", "Brutentnahme" = "brutentnahme", "Standwechsel" = "standwechsel", "Völkervereinigung" = "vereinigung", "Zwischenbödenableger" = "zwischenbodenableger", "Sonstiges" = "sonstig" ) screen_bulk_action_ui <- function(id) { ns <- NS(id) shiny::tagList( section_card(NULL, shiny::div(class = "py-2", shiny::dateInput(ns("date"), "Datum", value = Sys.Date(), language = "de", weekstart = 1), shiny::selectInput(ns("type"), "Maßnahme", choices = ACTION_TYPES), shiny::textAreaInput(ns("notes"), "Notizen", rows = 2, width = "100%") ) ), section_card("Völker", shiny::div(class = "d-flex gap-2 py-2 border-bottom", shiny::tags$button( type = "button", class = "btn btn-outline-secondary btn-sm", onclick = sprintf("Shiny.setInputValue('%s', Date.now(), {priority:'event'})", ns("sel_all")), "Alle" ), shiny::tags$button( type = "button", class = "btn btn-outline-secondary btn-sm", onclick = sprintf("Shiny.setInputValue('%s', Date.now(), {priority:'event'})", ns("sel_none")), "Keine" ) ), shiny::uiOutput(ns("colony_checkboxes")) ), shiny::div(class = "d-grid mt-2 mb-5", shiny::actionButton(ns("save"), "Speichern", class = "btn btn-primary btn-lg") ) ) } screen_bulk_action_server <- function(id, db, nav) { moduleServer(id, function(input, output, session) { ns <- session$ns colonies <- reactive({ req(nav$apiary_id, nav$screen == "bulk_action") db_colonies_list(db, apiary_id = nav$apiary_id, include_closed = FALSE) }) colony_choices <- reactive({ cols <- colonies() if (nrow(cols) == 0) return(character(0)) setNames(as.character(cols$id), cols$name) }) output$colony_checkboxes <- renderUI({ ch <- colony_choices() if (length(ch) == 0) return(shiny::p(class = "text-muted py-2", "Keine aktiven Völker.")) shiny::checkboxGroupInput(ns("selected"), NULL, choices = ch, selected = ch) }) observeEvent(input$sel_all, { shiny::updateCheckboxGroupInput(session, "selected", selected = colony_choices()) }, ignoreNULL = TRUE, ignoreInit = TRUE) observeEvent(input$sel_none, { shiny::updateCheckboxGroupInput(session, "selected", selected = character(0)) }, ignoreNULL = TRUE, ignoreInit = TRUE) observeEvent(input$save, { selected <- input$selected if (is.null(selected) || length(selected) == 0) { shiny::showNotification("Kein Volk ausgewählt.", type = "warning", duration = 3) return() } notes <- trimws(input$notes %||% "") n_saved <- 0L for (cid_str in selected) { cid <- as.integer(cid_str) tryCatch({ db_actions_insert(db, colony_id = cid, date = input$date, type = input$type, notes = if (nchar(notes) > 0) notes else NA_character_ ) n_saved <- n_saved + 1L log_debug("bulk_action_saved", colony_id = cid, type = input$type) }, error = function(e) { log_error("bulk_action_error", colony_id = cid, msg = conditionMessage(e)) }) } if (n_saved > 0) shiny::showNotification( sprintf("Maßnahme für %d Volk/Völker gespeichert.", n_saved), type = "message", duration = 3 ) nav$screen <- "colonies" }) }) }