feat: добавление полей для описания текста (+коррекция в схему), рефакторинг кода
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
### 0.??.?
|
||||
|
||||
##### features
|
||||
- added checkboxes input form;
|
||||
- added button to reset data in forms;
|
||||
|
||||
191
app.R
191
app.R
@@ -54,7 +54,7 @@ SCHEME_MAIN <- readxl::read_xlsx(FILE_SCHEME) %>%
|
||||
|
||||
# get list of simple inputs
|
||||
inputs_simple_list <- SCHEME_MAIN %>%
|
||||
dplyr::filter(!form_type %in% c("inline_table", "description")) %>%
|
||||
dplyr::filter(!form_type %in% c("inline_table", "description", "description_header")) %>%
|
||||
dplyr::distinct(form_id, form_type) %>%
|
||||
tibble::deframe()
|
||||
|
||||
@@ -179,148 +179,9 @@ inline_tables <- purrr::map(
|
||||
}
|
||||
)
|
||||
|
||||
# создание объектов для ввода
|
||||
# функция
|
||||
# create_forms <- function(form_id, form_label, form_type) {
|
||||
# # check if have condition
|
||||
# condition <- dplyr::filter(SCHEME_MAIN, form_id == {{ form_id }}) %>%
|
||||
# dplyr::distinct(condition) %>%
|
||||
# dplyr::pull()
|
||||
|
||||
# choices <- dplyr::filter(SCHEME_MAIN, form_id == {{ form_id }}) %>%
|
||||
# dplyr::pull(choices)
|
||||
|
||||
# # simple text or number input
|
||||
# if (form_type %in% c("text", "number")) {
|
||||
# form <- shiny::textAreaInput(
|
||||
# inputId = form_id,
|
||||
# label = tags$span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
# rows = 1
|
||||
# )
|
||||
# }
|
||||
|
||||
# # simple date input
|
||||
# if (form_type == "date") {
|
||||
# # supress warning while trying keep data form empty by default
|
||||
# suppressWarnings({
|
||||
# form <- dateInput(
|
||||
# inputId = form_id,
|
||||
# label = tags$span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
# value = NA, # keep empty
|
||||
# format = "dd.mm.yyyy",
|
||||
# weekstart = 1,
|
||||
# language = "ru"
|
||||
# )
|
||||
# })
|
||||
# }
|
||||
|
||||
# # еденичный выбор
|
||||
# if (form_type == "select_one") {
|
||||
# form <- selectizeInput(
|
||||
# inputId = form_id,
|
||||
# label = tags$span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
# choices = choices,
|
||||
# selected = NULL,
|
||||
# options = list(
|
||||
# create = FALSE,
|
||||
# onInitialize = I('function() { this.setValue(""); }')
|
||||
# )
|
||||
# )
|
||||
# }
|
||||
|
||||
# # множественный выбор
|
||||
# if (form_type == "select_multiple") {
|
||||
# form <- selectizeInput(
|
||||
# inputId = form_id,
|
||||
# label = tags$span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
# choices = choices,
|
||||
# selected = NULL,
|
||||
# multiple = TRUE,
|
||||
# options = list(
|
||||
# create = FALSE,
|
||||
# onInitialize = I('function() { this.setValue(""); }')
|
||||
# )
|
||||
# )
|
||||
# }
|
||||
|
||||
# # множественный выбор
|
||||
# if (form_type == "radio") {
|
||||
# form <- radioButtons(
|
||||
# inputId = form_id,
|
||||
# label = tags$span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
# choices = choices,
|
||||
# selected = character(0)
|
||||
# )
|
||||
# }
|
||||
|
||||
# if (form_type == "checkbox") {
|
||||
# form <- checkboxGroupInput(
|
||||
# inputId = form_id,
|
||||
# # label = tags$span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
# label = h6(form_label),
|
||||
# choices = choices,
|
||||
# selected = character(0)
|
||||
# )
|
||||
# }
|
||||
|
||||
# # вложенная таблица
|
||||
# if (form_type == "inline_table") {
|
||||
# form <- rHandsontableOutput(outputId = form_id)
|
||||
# }
|
||||
|
||||
# # description part
|
||||
# if (form_type == "description") {
|
||||
# form <- div(HTML(form_label), style = "color:Gray;font-size: 90%;")
|
||||
# }
|
||||
|
||||
# # если есть условие создать кондитионал панель
|
||||
# if (!is.na(condition)) {
|
||||
# form <- conditionalPanel(
|
||||
# condition = condition,
|
||||
# form
|
||||
# )
|
||||
# }
|
||||
|
||||
# form
|
||||
# }
|
||||
|
||||
# GENERATE UI ==================================
|
||||
# functions for making cards
|
||||
# make_cards_fn <- function(sub_group) {
|
||||
|
||||
# subgroups_inputs <- df_forms %>%
|
||||
# dplyr::filter(subgroup == {{sub_group}}) %>%
|
||||
# dplyr::distinct(form_id, form_label, form_type)
|
||||
|
||||
# subgroups_inputs2 <- SCHEME_MAIN |>
|
||||
# dplyr::filter(subgroup == {{sub_group}}) %>%
|
||||
# dplyr::distinct(form_id, form_label, form_type, condition)
|
||||
|
||||
# print(subgroups_inputs2)
|
||||
|
||||
# bslib::card(
|
||||
# bslib::card_header(sub_group, container = htmltools::h5),
|
||||
# full_screen = TRUE,
|
||||
# width = "4000px",
|
||||
# bslib::card_body(
|
||||
# fill = TRUE,
|
||||
# # передаем все аргументы в функцию для создания елементов
|
||||
# purrr::pmap(
|
||||
# .l = subgroups_inputs,
|
||||
# .f = utils$create_forms,
|
||||
# scheme = SCHEME_MAIN
|
||||
# )
|
||||
# )
|
||||
# )
|
||||
# }
|
||||
|
||||
# get pages list
|
||||
pages_list <- unique(SCHEME_MAIN$part)
|
||||
|
||||
# # get all forms df
|
||||
# df_forms <- SCHEME_MAIN %>%
|
||||
# dplyr::distinct(part, subgroup, form_id, form_label, form_type)
|
||||
|
||||
# generate nav panels for each page
|
||||
nav_panels_list <- purrr::map(
|
||||
.x = pages_list,
|
||||
@@ -328,38 +189,6 @@ nav_panels_list <- purrr::map(
|
||||
main_scheme = SCHEME_MAIN
|
||||
)
|
||||
|
||||
# nav_panels_list <- purrr::map(
|
||||
# .x = pages_list,
|
||||
# .f = \(x_page) {
|
||||
|
||||
# # get info about inputs for current page
|
||||
# page_forms <- SCHEME_MAIN %>%
|
||||
# dplyr::filter(part == {{x_page}}) %>%
|
||||
# dplyr::distinct(subgroup, form_id, form_label, form_type)
|
||||
|
||||
# # get list of columns
|
||||
# cols_list <- unique(page_forms$subgroup)
|
||||
|
||||
# # making cards
|
||||
# cards <- purrr::map(
|
||||
# .x = cols_list,
|
||||
# .f = utils$make_cards_fn,
|
||||
# main_scheme = SCHEME_MAIN
|
||||
# )
|
||||
|
||||
# # make page wrap
|
||||
# page_wrap <- bslib::layout_column_wrap(
|
||||
# # width = "350px", height = NULL, #was 800
|
||||
# width = 1 / 4, height = NULL, # was 800
|
||||
# fixed_width = TRUE,
|
||||
# !!!cards # unpack list of cards
|
||||
# )
|
||||
|
||||
# # add panel wrap to nav_panel
|
||||
# bslib::nav_panel(x_page, page_wrap)
|
||||
# }
|
||||
# )
|
||||
|
||||
# UI =======================
|
||||
ui <- page_sidebar(
|
||||
title = config$header,
|
||||
@@ -371,7 +200,9 @@ ui <- page_sidebar(
|
||||
textOutput("status_message2"),
|
||||
actionButton("load_data_button", "Загрузить данные", icon("pencil", lib = "font-awesome")),
|
||||
downloadButton("downloadData", "Экспорт в .xlsx"),
|
||||
downloadButton("downloadDocx", "get .docx (test only)")
|
||||
downloadButton("downloadDocx", "get .docx (test only)"),
|
||||
position = "left",
|
||||
open = list(mobile = "always")
|
||||
),
|
||||
# list of rendered panels
|
||||
navset_card_underline(
|
||||
@@ -462,17 +293,20 @@ server <- function(input, output) {
|
||||
# for `number` type: if in `choices` column has values then parsing them to range validation
|
||||
# value `0; 250` -> transform to rule validation value from 0 to 250
|
||||
if (form_type == "number") {
|
||||
|
||||
iv$add_rule(x_input_id, function(x) {
|
||||
# exit if empty
|
||||
if (check_for_empty_data(x)) {
|
||||
return(NULL)
|
||||
}
|
||||
# check for numeric
|
||||
if (grepl("^[-]?(\\d*\\,\\d+|\\d+\\,\\d*|\\d+)$", x)) NULL else "Значение должно быть числом."
|
||||
# if (grepl("^[-]?(\\d*\\,\\d+|\\d+\\,\\d*|\\d+)$", x)) NULL else "Значение должно быть числом."
|
||||
if (grepl("^[+-]?\\d*[\\.|\\,]?\\d+$", x)) NULL else "Значение должно быть числом."
|
||||
})
|
||||
|
||||
# проверка на соответствие диапазону значений
|
||||
if (!is.na(choices)) {
|
||||
# разделить на числа
|
||||
# разделить на несколько елементов
|
||||
ranges <- as.integer(stringr::str_split_1(choices, "; "))
|
||||
|
||||
# проверка на кол-во значений
|
||||
@@ -482,12 +316,17 @@ server <- function(input, output) {
|
||||
iv$add_rule(
|
||||
x_input_id,
|
||||
function(x) {
|
||||
|
||||
# замена разделителя десятичных цифр
|
||||
x <- stringr::str_replace(x, ",", ".")
|
||||
|
||||
# exit if empty
|
||||
if (check_for_empty_data(x)) {
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
# check for currect value
|
||||
if (between(as.integer(x), ranges[1], ranges[2])) {
|
||||
if (between(as.double(x), ranges[1], ranges[2])) {
|
||||
NULL
|
||||
} else {
|
||||
glue::glue("Значение должно быть между {ranges[1]} и {ranges[2]}.")
|
||||
|
||||
Binary file not shown.
@@ -28,6 +28,7 @@ get_dummy_df <- function() {
|
||||
#'
|
||||
#' Needed for proper data validation.
|
||||
check_for_empty_data <- function(value_to_check) {
|
||||
|
||||
# for any 0-length
|
||||
if (length(value_to_check) == 0) return(TRUE)
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
'Module path: "', basename(box::file()), '"'
|
||||
)
|
||||
}
|
||||
# ================
|
||||
|
||||
# asdasd
|
||||
#' @export
|
||||
@@ -22,7 +21,7 @@ make_panels <- function(page_name, main_scheme) {
|
||||
# making cards
|
||||
cards <- purrr::map(
|
||||
.x = cols_list,
|
||||
.f = make_cards_fn,
|
||||
.f = render_cards_with_forms,
|
||||
main_scheme = main_scheme
|
||||
)
|
||||
|
||||
@@ -43,8 +42,27 @@ make_panels <- function(page_name, main_scheme) {
|
||||
}
|
||||
|
||||
# functions for making cards
|
||||
# DO THIS INSTEAD !!!
|
||||
#' @export
|
||||
make_cards_fn <- function(sub_group, main_scheme) {
|
||||
# make_forms_by_scheme <- function(tool_id, main_scheme, ns) {
|
||||
|
||||
# ns <- NS(ns(tool_id))
|
||||
|
||||
# main_scheme <<- main_scheme
|
||||
# subgroup_schema <- main_scheme |>
|
||||
# dplyr::filter(tool_id == {{tool_id}})
|
||||
|
||||
# purrr::pmap(
|
||||
# .l = dplyr::distinct(subgroup_schema, form_id, form_label, form_type),
|
||||
# .f = render_forms,
|
||||
# schema = subgroup_schema,
|
||||
# ns = ns
|
||||
# )
|
||||
# }
|
||||
|
||||
# functions for making cards
|
||||
#' @export
|
||||
render_cards_with_forms <- function(sub_group, main_scheme) {
|
||||
|
||||
main_scheme <<- main_scheme
|
||||
subgroups_inputs <- main_scheme |>
|
||||
@@ -54,13 +72,14 @@ make_cards_fn <- function(sub_group, main_scheme) {
|
||||
bslib::card(
|
||||
bslib::card_header(sub_group, container = htmltools::h5),
|
||||
full_screen = TRUE,
|
||||
fill = TRUE,
|
||||
width = "4000px",
|
||||
bslib::card_body(
|
||||
fill = TRUE,
|
||||
# передаем все аргументы в функцию для создания елементов
|
||||
purrr::pmap(
|
||||
.l = subgroups_inputs,
|
||||
.f = create_forms,
|
||||
.f = render_forms,
|
||||
main_scheme = main_scheme
|
||||
)
|
||||
)
|
||||
@@ -70,20 +89,52 @@ make_cards_fn <- function(sub_group, main_scheme) {
|
||||
# UI RELATED ============================
|
||||
#' @export
|
||||
#' @param TEST s
|
||||
create_forms <- function(
|
||||
render_forms <- function(
|
||||
form_id,
|
||||
form_label,
|
||||
form_type,
|
||||
main_scheme
|
||||
) {
|
||||
|
||||
filterd_line <- dplyr::filter(main_scheme, form_id == {{form_id}})
|
||||
|
||||
# check if have condition
|
||||
condition <- dplyr::filter(main_scheme, form_id == {{form_id}}) |>
|
||||
dplyr::distinct(condition) |>
|
||||
condition <- unique(filterd_line$condition)
|
||||
|
||||
# get choices from schema
|
||||
choices <- filterd_line$choices
|
||||
|
||||
# get choices from schema
|
||||
description <- unique(filterd_line) |>
|
||||
dplyr::filter(!is.na(form_description)) |>
|
||||
dplyr::distinct(form_description) |>
|
||||
dplyr::pull()
|
||||
|
||||
choices <- dplyr::filter(main_scheme, form_id == {{form_id}}) |>
|
||||
dplyr::pull(choices)
|
||||
# описание
|
||||
if (length(description) > 1) {
|
||||
rlang::abort(sprintf(
|
||||
"%s - более чем 1 уникальный вариант описания:\n%s", form_id, paste0(description, collapse = "\n")
|
||||
))
|
||||
} else if (length(description) == 0) {
|
||||
description <- NA
|
||||
}
|
||||
|
||||
# отдельно создаем заголовки
|
||||
label <- if (is.na(description) && is.na(form_label)) {
|
||||
NULL
|
||||
} else {
|
||||
shiny::tagList(
|
||||
if (!is.na(form_label)) {
|
||||
shiny::span(form_label, style = "color: #444444; font-weight: 550; line-height: 1.4;")
|
||||
# если в схеме есть поле с описанием - добавлеяем его следующей строчкой
|
||||
},
|
||||
if (!is.na(description) && !is.na(form_label)) shiny::br(),
|
||||
if (!is.na(description)) {
|
||||
shiny::span(shiny::markdown(description)) |> htmltools::tagAppendAttributes(style = "color:gray; font-size:small; line-height: 1.4;")
|
||||
# span(description, style = "color:gray; font-size:small;")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
# simple text or number input
|
||||
if (form_type == "text") {
|
||||
@@ -93,7 +144,7 @@ create_forms <- function(
|
||||
|
||||
form <- shiny::textAreaInput(
|
||||
inputId = form_id,
|
||||
label = shiny::span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
label = label,
|
||||
rows = rows_to_show
|
||||
)
|
||||
}
|
||||
@@ -101,7 +152,7 @@ create_forms <- function(
|
||||
if (form_type == "number") {
|
||||
form <- shiny::textAreaInput(
|
||||
inputId = form_id,
|
||||
label = shiny::span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
label = label,
|
||||
rows = 1
|
||||
)
|
||||
}
|
||||
@@ -112,7 +163,7 @@ create_forms <- function(
|
||||
suppressWarnings({
|
||||
form <- shiny::dateInput(
|
||||
inputId = form_id,
|
||||
label = shiny::span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
label = label,
|
||||
value = NA, # keep empty
|
||||
format = "dd.mm.yyyy",
|
||||
weekstart = 1,
|
||||
@@ -125,7 +176,7 @@ create_forms <- function(
|
||||
if (form_type == "select_one") {
|
||||
form <- shiny::selectizeInput(
|
||||
inputId = form_id,
|
||||
label = shiny::span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
label = label,
|
||||
choices = choices,
|
||||
selected = NULL,
|
||||
options = list(
|
||||
@@ -139,7 +190,7 @@ create_forms <- function(
|
||||
if (form_type == "select_multiple") {
|
||||
form <- shiny::selectizeInput(
|
||||
inputId = form_id,
|
||||
label = shiny::span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
label = label,
|
||||
choices = choices,
|
||||
selected = NULL,
|
||||
multiple = TRUE,
|
||||
@@ -154,7 +205,7 @@ create_forms <- function(
|
||||
if (form_type == "radio") {
|
||||
form <- shiny::radioButtons(
|
||||
inputId = form_id,
|
||||
label = shiny::span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
label = label,
|
||||
choices = choices,
|
||||
selected = character(0)
|
||||
)
|
||||
@@ -163,7 +214,7 @@ create_forms <- function(
|
||||
if (form_type == "checkbox") {
|
||||
form <- shiny::checkboxGroupInput(
|
||||
inputId = form_id,
|
||||
# label = shiny::span(style = "color: #444444; font-weight: 550;", form_label),
|
||||
# label = label,
|
||||
label = shiny::h6(form_label),
|
||||
choices = choices,
|
||||
selected = character(0)
|
||||
@@ -177,7 +228,18 @@ create_forms <- function(
|
||||
|
||||
# description part
|
||||
if (form_type == "description") {
|
||||
form <- shiny::div(shiny::HTML(form_label), style = "color:Gray;font-size: 90%;")
|
||||
if(is.na(form_label)) {
|
||||
form <- shiny::hr(style = "margin-bottom: -3px;")
|
||||
} else {
|
||||
form <- shiny::div(shiny::HTML(form_label), style = "color: Gray; font-size: 90%;")
|
||||
}
|
||||
}
|
||||
|
||||
if (form_type == "description_header") {
|
||||
form <- shiny::h5(
|
||||
label,
|
||||
style = "margin-bottom: -8px; margin-top: 10px;"
|
||||
)
|
||||
}
|
||||
|
||||
# если есть условие создать кондитионал панель
|
||||
@@ -187,6 +249,7 @@ create_forms <- function(
|
||||
form
|
||||
)
|
||||
}
|
||||
|
||||
form
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user