add homekeeper stack
This commit is contained in:
@@ -0,0 +1,490 @@
|
||||
screen_colony_ui <- function(id) {
|
||||
ns <- NS(id)
|
||||
shiny::tagList(
|
||||
shiny::uiOutput(ns("header_card")),
|
||||
shiny::div(
|
||||
class = "row g-2 mb-4",
|
||||
lapply(list(
|
||||
list(id = "btn_insp", label = "Durchsicht", icon = "clipboard-list", cls = "btn-primary", screen = "inspection"),
|
||||
list(id = "btn_varroa", label = "Varroa", icon = "bug", cls = "btn-warning", screen = "varroa"),
|
||||
list(id = "btn_harvest",label = "Ernte", icon = "jar", cls = "btn-success", screen = "harvest"),
|
||||
list(id = "btn_queen", label = "Königin", icon = "crown", cls = "btn-info", screen = "queens"),
|
||||
list(id = "btn_check", label = "Checkliste", icon = "list-check", cls = "btn-secondary", screen = "checklists"),
|
||||
list(id = "btn_actions", label = "Maßnahmen", icon = "bolt", cls = "btn-info", screen = "actions"),
|
||||
list(id = "btn_edit", label = "Bearbeiten", icon = "pencil", cls = "btn-outline-secondary", screen = NULL)
|
||||
), function(b) {
|
||||
shiny::div(class = "col-6 col-md-4",
|
||||
shiny::actionButton(ns(b$id),
|
||||
shiny::tagList(shiny::icon(b$icon), shiny::tags$br(), b$label),
|
||||
class = paste("btn action-btn w-100", b$cls)
|
||||
)
|
||||
)
|
||||
})
|
||||
),
|
||||
shiny::uiOutput(ns("activity_log"))
|
||||
)
|
||||
}
|
||||
|
||||
screen_colony_server <- function(id, db, nav) {
|
||||
moduleServer(id, function(input, output, session) {
|
||||
ns <- session$ns
|
||||
reload <- reactiveVal(0)
|
||||
edit_insp_id <- reactiveVal(NULL)
|
||||
log_filter <- reactiveVal("alle")
|
||||
log_sel_type <- reactiveVal(NULL)
|
||||
log_sel_id <- reactiveVal(NULL)
|
||||
|
||||
observeEvent(nav$screen, {
|
||||
if (nav$screen == "colony") {
|
||||
reload(reload() + 1L)
|
||||
log_filter("alle")
|
||||
}
|
||||
}, ignoreInit = TRUE)
|
||||
|
||||
lapply(c("alle", "durchsicht", "varroa", "massnahme", "ernte"), function(f) {
|
||||
observeEvent(input[[paste0("log_filter_", f)]], {
|
||||
log_filter(f)
|
||||
}, ignoreInit = TRUE)
|
||||
})
|
||||
|
||||
colony <- reactive({
|
||||
req(nav$colony_id); reload()
|
||||
db_colonies_get(db, nav$colony_id)
|
||||
})
|
||||
|
||||
output$header_card <- renderUI({
|
||||
co <- colony()
|
||||
req(nrow(co) > 0)
|
||||
last <- db_inspections_last(db, nav$colony_id)
|
||||
bslib::card(
|
||||
class = "mb-3",
|
||||
bslib::card_body(
|
||||
shiny::div(class = "d-flex justify-content-between align-items-start mb-2",
|
||||
shiny::div(
|
||||
shiny::tags$p(class = "text-muted small mb-0", co$apiary_name %||% ""),
|
||||
if (!is.na(co$parent_name)) shiny::tags$p(class = "text-muted small mb-0",
|
||||
paste("Abstammung:", co$parent_name))
|
||||
),
|
||||
shiny::uiOutput(ns("status_selector"))
|
||||
),
|
||||
if (nrow(last) > 0)
|
||||
shiny::div(class = "border-top pt-2 mt-2",
|
||||
shiny::tags$small(class = "text-muted",
|
||||
paste0("Letzte Durchsicht: ", last$date[1]),
|
||||
shiny::tags$br(),
|
||||
paste0(
|
||||
if (!is.na(last$brood_frames)) paste(last$brood_frames, "BW") else "",
|
||||
if (!is.na(last$honey_frames)) paste0(" ", last$honey_frames, " HW") else "",
|
||||
if (!is.na(last$colony_strength)) paste0(" Stärke ", last$colony_strength) else "",
|
||||
if (last$queen_seen) " ♛ gesehen" else ""
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
output$status_selector <- renderUI({
|
||||
co <- colony()
|
||||
req(nrow(co) > 0)
|
||||
shiny::div(
|
||||
class = "d-flex flex-wrap gap-1",
|
||||
lapply(seq_along(COLONY_STATUSES), function(i) {
|
||||
s <- COLONY_STATUSES[[i]]
|
||||
lbl <- names(COLONY_STATUSES)[i]
|
||||
cls <- if (co$status == s) {
|
||||
paste("btn btn-sm", paste0("btn-", colony_status_color(s)))
|
||||
} else "btn btn-sm btn-outline-secondary"
|
||||
shiny::actionButton(ns(paste0("status_", i)), lbl, class = cls)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
observe({
|
||||
lapply(seq_along(COLONY_STATUSES), function(i) {
|
||||
local({
|
||||
li <- i; s <- COLONY_STATUSES[[i]]
|
||||
observeEvent(input[[paste0("status_", li)]], {
|
||||
req(nav$colony_id)
|
||||
if (s == "eingegangen") {
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = "Volk als eingegangen markieren?",
|
||||
footer = shiny::tagList(
|
||||
shiny::modalButton("Abbrechen"),
|
||||
shiny::actionButton(ns("confirm_close"), "Bestätigen", class = "btn-danger")
|
||||
),
|
||||
shiny::p("Das Volk wird als eingegangen markiert.")
|
||||
))
|
||||
} else {
|
||||
db_colonies_update(db,
|
||||
id = nav$colony_id,
|
||||
name = isolate(colony()$name),
|
||||
apiary_id = isolate(colony()$apiary_id),
|
||||
status = s,
|
||||
notes = isolate(colony()$notes)
|
||||
)
|
||||
reload(reload() + 1L)
|
||||
}
|
||||
}, ignoreInit = TRUE)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
observeEvent(input$confirm_close, {
|
||||
db_colonies_close(db, nav$colony_id)
|
||||
shiny::removeModal()
|
||||
nav$screen <- "colonies"
|
||||
})
|
||||
|
||||
# Action button navigation
|
||||
observeEvent(input$btn_insp, nav$screen <- "inspection")
|
||||
observeEvent(input$btn_varroa, nav$screen <- "varroa")
|
||||
observeEvent(input$btn_harvest, nav$screen <- "harvest")
|
||||
observeEvent(input$btn_queen, nav$screen <- "queens")
|
||||
observeEvent(input$btn_check, nav$screen <- "checklists")
|
||||
observeEvent(input$btn_actions, nav$screen <- "actions")
|
||||
|
||||
# Edit colony modal
|
||||
observeEvent(input$btn_edit, {
|
||||
co <- colony()
|
||||
ap <- db_apiaries_list(db)
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = paste("Volk bearbeiten:", co$name),
|
||||
footer = shiny::tagList(
|
||||
shiny::modalButton("Abbrechen"),
|
||||
shiny::actionButton(ns("confirm_edit"), "Speichern", class = "btn-primary")
|
||||
),
|
||||
shiny::textInput(ns("edit_name"), "Name *", value = co$name),
|
||||
shiny::selectInput(ns("edit_apiary"), "Bienenstand",
|
||||
choices = setNames(ap$id, ap$name),
|
||||
selected = co$apiary_id
|
||||
),
|
||||
shiny::textAreaInput(ns("edit_notes"), "Notizen", rows = 2,
|
||||
value = co$notes %||% "")
|
||||
))
|
||||
})
|
||||
observeEvent(input$confirm_edit, {
|
||||
req(nchar(trimws(input$edit_name)) > 0)
|
||||
co <- isolate(colony())
|
||||
db_colonies_update(db,
|
||||
id = nav$colony_id,
|
||||
name = trimws(input$edit_name),
|
||||
apiary_id = as.integer(input$edit_apiary),
|
||||
status = co$status,
|
||||
notes = input$edit_notes
|
||||
)
|
||||
shiny::removeModal(); reload(reload() + 1L)
|
||||
})
|
||||
|
||||
output$activity_log <- renderUI({
|
||||
reload()
|
||||
req(nav$colony_id)
|
||||
log <- db_colony_log(db, nav$colony_id)
|
||||
flt <- log_filter()
|
||||
|
||||
type_label <- c(
|
||||
durchsicht = "Durchsicht",
|
||||
kontrolle = "Kontrolle",
|
||||
behandlung = "Behandlung",
|
||||
nachkontrolle = "Nachkontrolle",
|
||||
ernte = "Ernte",
|
||||
massnahme = "Maßnahme"
|
||||
)
|
||||
type_badge <- c(
|
||||
durchsicht = "bg-primary",
|
||||
kontrolle = "bg-warning text-dark",
|
||||
behandlung = "bg-danger",
|
||||
nachkontrolle = "bg-secondary",
|
||||
ernte = "bg-success",
|
||||
massnahme = "bg-info text-dark"
|
||||
)
|
||||
|
||||
filter_cats <- list(
|
||||
list(id = "alle", label = "Alle"),
|
||||
list(id = "durchsicht", label = "Durchsicht"),
|
||||
list(id = "varroa", label = "Varroa"),
|
||||
list(id = "massnahme", label = "Maßnahmen"),
|
||||
list(id = "ernte", label = "Ernte")
|
||||
)
|
||||
chips <- shiny::div(class = "d-flex flex-wrap gap-1 px-3 pt-3 pb-2",
|
||||
lapply(filter_cats, function(f) {
|
||||
cls <- if (flt == f$id) "btn btn-sm btn-primary" else "btn btn-sm btn-outline-secondary"
|
||||
shiny::actionButton(ns(paste0("log_filter_", f$id)), f$label, class = cls)
|
||||
})
|
||||
)
|
||||
|
||||
if (nrow(log) > 0 && flt != "alle") {
|
||||
keep <- switch(flt,
|
||||
durchsicht = log$type == "durchsicht",
|
||||
varroa = log$type %in% c("kontrolle", "behandlung", "nachkontrolle"),
|
||||
massnahme = log$type == "massnahme",
|
||||
ernte = log$type == "ernte",
|
||||
rep(TRUE, nrow(log))
|
||||
)
|
||||
log <- log[keep, , drop = FALSE]
|
||||
}
|
||||
|
||||
items <- if (nrow(log) == 0) {
|
||||
shiny::div(class = "px-3 py-2 text-muted small", "Keine Einträge.")
|
||||
} else {
|
||||
shiny::tags$ul(class = "list-group list-group-flush",
|
||||
lapply(seq_len(nrow(log)), function(i) {
|
||||
r <- log[i, ]
|
||||
is_insp <- r$type == "durchsicht"
|
||||
onclick_val <- if (is_insp)
|
||||
sprintf("Shiny.setInputValue('%s', %s, {priority:'event'})",
|
||||
ns("insp_select"), r$ref_id)
|
||||
else
|
||||
sprintf("Shiny.setInputValue('%s', '%s:%s', {priority:'event'})",
|
||||
ns("log_select"), r$type, r$ref_id)
|
||||
shiny::tags$li(
|
||||
class = "list-group-item py-2 px-3 tap-card",
|
||||
onclick = onclick_val,
|
||||
shiny::div(class = "d-flex justify-content-between align-items-center gap-2",
|
||||
shiny::div(class = "d-flex align-items-center gap-2 min-width-0",
|
||||
shiny::tags$span(class = paste("badge flex-shrink-0", type_badge[r$type]),
|
||||
type_label[r$type]),
|
||||
shiny::tags$span(class = "small text-truncate", r$summary)
|
||||
),
|
||||
shiny::div(class = "d-flex align-items-center gap-1 flex-shrink-0",
|
||||
shiny::tags$span(class = "text-muted small", r$date),
|
||||
shiny::icon("chevron-right", class = "text-muted small")
|
||||
)
|
||||
)
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
bslib::card(
|
||||
class = "mb-3",
|
||||
bslib::card_header("Aktivitätslog"),
|
||||
bslib::card_body(class = "p-0", chips, items)
|
||||
)
|
||||
})
|
||||
|
||||
observeEvent(input$insp_select, {
|
||||
id <- as.integer(input$insp_select)
|
||||
insp <- db_inspections_get(db, id)
|
||||
req(nrow(insp) > 0)
|
||||
traits_df <- db_inspections_traits(db, id)
|
||||
get_trait <- function(tval) {
|
||||
s <- traits_df$score[traits_df$trait == tval]
|
||||
if (length(s) > 0 && !is.na(s[1])) as.character(s[1]) else ""
|
||||
}
|
||||
edit_insp_id(id)
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = paste("Durchsicht", insp$date),
|
||||
size = "l",
|
||||
footer = shiny::tagList(
|
||||
shiny::modalButton("Abbrechen"),
|
||||
shiny::actionButton(ns("confirm_insp_edit"), "Speichern", class = "btn-primary"),
|
||||
shiny::actionButton(ns("confirm_insp_delete"), "Löschen", class = "btn-danger ms-auto")
|
||||
),
|
||||
shiny::div(class = "row g-2",
|
||||
shiny::div(class = "col-6",
|
||||
shiny::dateInput(ns("ei_date"), "Datum", value = as.Date(insp$date), language = "de", weekstart = 1)
|
||||
),
|
||||
shiny::div(class = "col-6",
|
||||
shiny::textInput(ns("ei_inspector"), "Imker/in", value = insp$inspector %||% "")
|
||||
)
|
||||
),
|
||||
shiny::div(class = "row g-2 mt-1",
|
||||
shiny::div(class = "col-4",
|
||||
shiny::numericInput(ns("ei_brood"), "Brutwaben", value = insp$brood_frames, min = 0, step = 1)
|
||||
),
|
||||
shiny::div(class = "col-4",
|
||||
shiny::numericInput(ns("ei_honey"), "Honigwaben", value = insp$honey_frames, min = 0, step = 1)
|
||||
),
|
||||
shiny::div(class = "col-4",
|
||||
shiny::numericInput(ns("ei_food"), "Futter (kg)", value = insp$food_stores_kg, min = 0, step = 0.5)
|
||||
)
|
||||
),
|
||||
shiny::div(class = "row g-2 mt-1",
|
||||
shiny::div(class = "col-6",
|
||||
shiny::selectInput(ns("ei_strength"), "Volksstärke",
|
||||
choices = c("–" = "", setNames(as.character(1:9), 1:9)),
|
||||
selected = if (!is.na(insp$colony_strength)) as.character(insp$colony_strength) else ""
|
||||
)
|
||||
),
|
||||
shiny::div(class = "col-6",
|
||||
shiny::numericInput(ns("ei_qcells"), "Weiselzellen", value = insp$queen_cells_count %||% 0, min = 0, step = 1)
|
||||
)
|
||||
),
|
||||
shiny::div(class = "d-flex gap-4 mt-2 mb-2",
|
||||
shiny::checkboxInput(ns("ei_queen"), "Königin gesehen", value = isTRUE(insp$queen_seen == 1)),
|
||||
shiny::checkboxInput(ns("ei_eggs"), "Eier / Stifte gesehen", value = isTRUE(insp$eggs_seen == 1))
|
||||
),
|
||||
shiny::div(class = "row g-2",
|
||||
lapply(names(TRAITS), function(tname) {
|
||||
tval <- TRAITS[[tname]]
|
||||
shiny::div(class = "col-6",
|
||||
shiny::selectInput(ns(paste0("ei_t_", tval)), tname,
|
||||
choices = c("–" = "", setNames(as.character(1:4), 1:4)),
|
||||
selected = get_trait(tval)
|
||||
)
|
||||
)
|
||||
})
|
||||
),
|
||||
shiny::textAreaInput(ns("ei_notes"), "Notizen / Auffälligkeiten",
|
||||
value = insp$notes %||% "", rows = 3, width = "100%")
|
||||
))
|
||||
})
|
||||
|
||||
observeEvent(input$confirm_insp_edit, {
|
||||
id <- edit_insp_id(); req(id)
|
||||
traits <- setNames(
|
||||
lapply(TRAITS, function(tval) {
|
||||
v <- input[[paste0("ei_t_", tval)]]
|
||||
if (!is.null(v) && v != "") as.integer(v) else NA_integer_
|
||||
}),
|
||||
TRAITS
|
||||
)
|
||||
db_inspections_update(db,
|
||||
id = id,
|
||||
date = input$ei_date,
|
||||
inspector = input$ei_inspector,
|
||||
brood_frames = input$ei_brood,
|
||||
honey_frames = input$ei_honey,
|
||||
food_stores_kg = input$ei_food,
|
||||
colony_strength = if (!is.null(input$ei_strength) && input$ei_strength != "")
|
||||
as.integer(input$ei_strength) else NA_integer_,
|
||||
queen_seen = isTRUE(input$ei_queen),
|
||||
eggs_seen = isTRUE(input$ei_eggs),
|
||||
queen_cells_count = as.integer(input$ei_qcells %||% 0L),
|
||||
notes = input$ei_notes,
|
||||
traits = traits
|
||||
)
|
||||
shiny::removeModal(); reload(reload() + 1L)
|
||||
})
|
||||
|
||||
observeEvent(input$confirm_insp_delete, {
|
||||
id <- edit_insp_id(); req(id)
|
||||
db_inspections_delete(db, id)
|
||||
shiny::removeModal(); reload(reload() + 1L)
|
||||
})
|
||||
|
||||
observeEvent(input$log_select, {
|
||||
parts <- strsplit(input$log_select, ":", fixed = TRUE)[[1]]
|
||||
type <- parts[1]
|
||||
id <- as.integer(parts[2])
|
||||
log_sel_type(type); log_sel_id(id)
|
||||
|
||||
footer <- shiny::tagList(
|
||||
shiny::modalButton("Abbrechen"),
|
||||
shiny::actionButton(ns("confirm_log_save"), "Speichern", class = "btn-primary"),
|
||||
shiny::actionButton(ns("confirm_log_delete"), "Löschen", class = "btn-danger ms-auto")
|
||||
)
|
||||
|
||||
if (type == "kontrolle") {
|
||||
vc <- db_varroa_counts_get(db, id); req(nrow(vc) > 0)
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = paste("Varroa-Kontrolle", vc$date), footer = footer,
|
||||
shiny::div(class = "row g-2",
|
||||
shiny::div(class = "col-6",
|
||||
shiny::dateInput(ns("el_date_from"), "Von",
|
||||
value = if (!is.na(vc$date_from)) as.Date(vc$date_from) else NA,
|
||||
language = "de", weekstart = 1)
|
||||
),
|
||||
shiny::div(class = "col-6",
|
||||
shiny::dateInput(ns("el_date"), "Bis",
|
||||
value = as.Date(vc$date), language = "de", weekstart = 1)
|
||||
)
|
||||
),
|
||||
shiny::numericInput(ns("el_count"), "Anzahl Milben", value = vc$count, min = 0, step = 1, width = "100%"),
|
||||
shiny::selectInput(ns("el_method"), "Methode", choices = VARROA_METHODS, selected = vc$method),
|
||||
shiny::textAreaInput(ns("el_notes"), "Notizen", value = vc$notes %||% "", rows = 2, width = "100%")
|
||||
))
|
||||
|
||||
} else if (type == "behandlung") {
|
||||
vt <- db_varroa_treatments_get(db, id); req(nrow(vt) > 0)
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = paste("Varroa-Behandlung", vt$date), footer = footer,
|
||||
shiny::dateInput(ns("el_date"), "Datum", value = as.Date(vt$date), language = "de", weekstart = 1),
|
||||
shiny::selectizeInput(ns("el_product"), "Mittel",
|
||||
choices = c("Mittel wählen…" = "", VARROA_PRODUCTS),
|
||||
selected = vt$product, options = list(create = TRUE)),
|
||||
shiny::textInput(ns("el_method_txt"), "Anwendung", value = vt$method %||% ""),
|
||||
shiny::textInput(ns("el_dosage"), "Dosierung", value = vt$dosage %||% ""),
|
||||
shiny::textAreaInput(ns("el_notes"), "Notizen", value = vt$notes %||% "", rows = 2, width = "100%")
|
||||
))
|
||||
|
||||
} else if (type == "nachkontrolle") {
|
||||
vc2 <- db_varroa_controls_get(db, id); req(nrow(vc2) > 0)
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = paste("Nachkontrolle", vc2$date), footer = footer,
|
||||
shiny::dateInput(ns("el_date"), "Datum", value = as.Date(vc2$date), language = "de", weekstart = 1),
|
||||
shiny::textInput(ns("el_result"), "Ergebnis / Befund", value = vc2$result %||% ""),
|
||||
shiny::textAreaInput(ns("el_notes"), "Notizen", value = vc2$notes %||% "", rows = 2, width = "100%")
|
||||
))
|
||||
|
||||
} else if (type == "ernte") {
|
||||
h <- db_harvests_get(db, id); req(nrow(h) > 0)
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = paste("Honigernte", h$date), footer = footer,
|
||||
shiny::dateInput(ns("el_date"), "Datum", value = as.Date(h$date), language = "de", weekstart = 1),
|
||||
shiny::numericInput(ns("el_weight"), "Gewicht (kg)", value = h$weight_kg, min = 0, step = 0.1, width = "100%"),
|
||||
shiny::textAreaInput(ns("el_notes"), "Notizen", value = h$notes %||% "", rows = 2, width = "100%")
|
||||
))
|
||||
|
||||
} else if (type == "massnahme") {
|
||||
ac <- db_actions_get(db, id); req(nrow(ac) > 0)
|
||||
shiny::showModal(shiny::modalDialog(
|
||||
title = paste("Maßnahme", ac$date), footer = footer,
|
||||
shiny::dateInput(ns("el_date"), "Datum", value = as.Date(ac$date), language = "de", weekstart = 1),
|
||||
shiny::selectInput(ns("el_action_type"), "Maßnahme",
|
||||
choices = COLONY_ACTION_TYPES, selected = ac$type),
|
||||
shiny::textAreaInput(ns("el_notes"), "Notizen", value = ac$notes %||% "", rows = 2, width = "100%")
|
||||
))
|
||||
}
|
||||
})
|
||||
|
||||
observeEvent(input$confirm_log_save, {
|
||||
type <- log_sel_type(); id <- log_sel_id(); req(type, id)
|
||||
if (type == "kontrolle") {
|
||||
db_varroa_counts_update(db, id,
|
||||
date_from = input$el_date_from,
|
||||
date = input$el_date,
|
||||
method = input$el_method,
|
||||
count = input$el_count,
|
||||
notes = input$el_notes)
|
||||
} else if (type == "behandlung") {
|
||||
db_varroa_treatments_update(db, id,
|
||||
date = input$el_date,
|
||||
product = input$el_product,
|
||||
method = input$el_method_txt,
|
||||
dosage = input$el_dosage,
|
||||
notes = input$el_notes)
|
||||
} else if (type == "nachkontrolle") {
|
||||
db_varroa_controls_update(db, id,
|
||||
date = input$el_date,
|
||||
result = input$el_result,
|
||||
notes = input$el_notes)
|
||||
} else if (type == "ernte") {
|
||||
db_harvests_update(db, id,
|
||||
date = input$el_date,
|
||||
weight_kg = input$el_weight,
|
||||
notes = input$el_notes)
|
||||
} else if (type == "massnahme") {
|
||||
db_actions_update(db, id,
|
||||
date = input$el_date,
|
||||
type = input$el_action_type,
|
||||
notes = input$el_notes)
|
||||
}
|
||||
shiny::removeModal(); reload(reload() + 1L)
|
||||
})
|
||||
|
||||
observeEvent(input$confirm_log_delete, {
|
||||
type <- log_sel_type(); id <- log_sel_id(); req(type, id)
|
||||
switch(type,
|
||||
kontrolle = db_varroa_counts_delete(db, id),
|
||||
behandlung = db_varroa_treatments_delete(db, id),
|
||||
nachkontrolle = db_varroa_controls_delete(db, id),
|
||||
ernte = db_harvests_delete(db, id),
|
||||
massnahme = db_actions_delete(db, id)
|
||||
)
|
||||
shiny::removeModal(); reload(reload() + 1L)
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user