Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add individual parser files #79

Draft
wants to merge 3 commits into
base: parser
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions R/parser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Field Activity Parser

### Todo

Check the current todo list at - [todo.md](/todo.md)

## Overview

This project is a Shiny application that generates a dynamic user interface based on a JSON schema. It's designed to create forms for various field activities, with support for multiple languages, different input types, and validation support.

## Features

- Dynamic UI generation based on JSON schema
- Multi-language support (English, Finnish, Swedish)
- Support for various input types (select, number, string, textarea)
- Nested object and array handling
- Real-time UI updates on language change

## File Structure

- `fct_parser.R`: Contains functions for parsing the JSON schema
- `fct_ui.R`: Contains functions for creating UI elements
- `app_ui.R`: Defines the main UI structure of the Shiny app
- `app_server.R`: Defines the server-side logic of the Shiny app

## Key Functions

### fct_parser.R

- `flatten_schema()`: Flattens the JSON schema by resolving references
- `parse_json_schema()`: Parses the entire JSON schema
- `parse_event()`: Parses individual events from the schema
- `parse_property()`: Parses individual properties from the schema
- `get_multilingual_field()`: Extracts multilingual values for a given field

### fct_ui.R

- `create_ui()`: Creates UI elements based on the parsed schema
- `create_properties_ui()`: Creates UI elements for properties, handling nested structures
- `create_widget()`: Creates individual UI widgets based on property type
- `get_select_choices()`: Extracts choices for select inputs
- `update_ui_element()`: Updates existing UI elements (e.g., on language change)

### app_ui.R

- `app_ui()`: Defines the main UI structure of the Shiny app
- `golem_add_external_resources()`: Adds external resources to the Shiny app

### app_server.R

- `schema_file_path()`: Gets the path to the schema file
- `app_server()`: Defines the server-side logic of the Shiny app, including event handling and UI updates

## Usage

```R
golem::run_dev()
```
77 changes: 77 additions & 0 deletions R/parser/app_server.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#' Get the path to the schema file
#'
#' @return The path to the schema file
schema_file_path <- function() {
system.file("extdata", "schema.json", package = "fieldactivityParser")
}

#' The application server-side
#'
#' @param input,output,session Internal parameters for {shiny}.
#' DO NOT REMOVE.
#' @import shiny
#' @noRd
app_server <- function(input, output, session) {
# Load and parse the JSON schema
schema <- jsonlite::fromJSON(schema_file_path(), simplifyVector = FALSE)
parsed_schema <- parse_json_schema(schema)

event_data <- parsed_schema

# Function to generate event UI
generate_event_ui <- function(event, language) {
if (!is.null(event)) {
event_ui <- create_ui(list(event), ns = NS("dynamic"), language = language)
tagList(
h3(event$title[[language]]),
event_ui
)
} else {
p("No event data available.")
}
}

# Render the dynamic UI
output$dynamic_ui <- renderUI({
event <- event_data
generate_event_ui(event, input$language)
})



# Update UI elements when language changes
observeEvent(input$language, {
updateSelectInput(session, "selected_event",
choices = sapply(parsed_schema, function(event) event$title[[input$language]])
)

if (!is.null(input$selected_event)) {
# Find the event by matching the title
selected_event_title <- input$selected_event
event <- NULL
for (e in parsed_schema) {
if (e$title[[input$language]] == selected_event_title) {
event <- e
break
}
}

if (!is.null(event)) {
# Update UI elements for the selected event
lapply(names(event$properties), function(prop_name) {
element <- event$properties[[prop_name]]
if (!is.null(element) && !is.null(element$type)) {
tryCatch(
{
update_ui_element(session, element, NULL, input$language)
},
error = function(e) {
warning(paste("Error updating UI element:", prop_name, "-", e$message))
}
)
}
})
}
}
})
}
54 changes: 54 additions & 0 deletions R/parser/app_ui.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#' The application User-Interface
#'
#' This function creates the user interface for the Shiny application.
#' It defines the layout, input controls, and output elements that
#' users will interact with.
#'
#' @param request Internal parameter for `{shiny}`.
#' DO NOT REMOVE.
#'
#' @import shiny
#' @importFrom golem add_resource_path activate_js favicon bundle_resources


app_ui <- function(request) {
fluidPage(
shinyjs::useShinyjs(),
titlePanel("Field Activity Parser"),
sidebarLayout(
sidebarPanel(
selectInput("language", "Select Language", choices = c("en", "fi", "sv")),
# uiOutput("event_selector")
),
mainPanel(
uiOutput("dynamic_ui")
)
)
)
}


#' Add external Resources to the Application
#'
#' This function is internally used to add external
#' resources inside the Shiny application.
#'
#' @import shiny
#' @importFrom golem add_resource_path activate_js favicon bundle_resources
#' @noRd
golem_add_external_resources <- function() {
add_resource_path(
"www",
app_sys("app/www")
)

tags$head(
favicon(),
bundle_resources(
path = app_sys("app/www"),
app_title = "fieldactivityParser"
)
# Add here other external resources
# for example, you can add shinyalert::useShinyalert()
)
}
Loading