-
Notifications
You must be signed in to change notification settings - Fork 3
Feat: Add Theming with config.yml #15
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
base: main
Are you sure you want to change the base?
Changes from all commits
8089895
ac42cd1
df18d7e
2250cfa
b33ef11
5543096
d6eb5ff
c583c89
cc4ba3a
1bd9d78
d8cb1c0
f2d48df
d12bdcc
9e1a293
9937baa
3a226a7
8f88ddd
937c239
70d1163
7ff93c2
56a3dba
1b22202
ebe6d6b
54a06fa
86b1d69
3de3d6b
b634e10
687c311
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| linters: | ||
| linters_with_defaults( | ||
| line_length_linter = line_length_linter(100), | ||
| object_usage_linter = NULL # Does not work with `box::use()`. | ||
| defaults = box.linters::rhino_default_linters, | ||
| line_length_linter = line_length_linter(100) | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,64 @@ | ||
| box::use( | ||
| base64enc[ | ||
| base64encode | ||
| ], | ||
| shiny[ | ||
| div, | ||
| img, | ||
| p, | ||
| renderUI | ||
| ], | ||
| ) | ||
|
|
||
| #' @description Function to generate an empty state UI | ||
| #' @param text Text to display in the empty state | ||
| #' @param image_path Path to the image to display in the empty state | ||
| #' @param color Color to use for the image | ||
| #' @export | ||
| generate_empty_state_ui <- function( | ||
| text = "Select an application and a job to view logs", | ||
| image_path = "static/illustrations/empty_state.svg" | ||
| image_path = "static/illustrations/empty_state.svg", | ||
| color = "#0099f9" | ||
| ) { | ||
| div( | ||
| class = "empty-state-container", | ||
| p( | ||
| class = "empty-state-text", | ||
| text | ||
| ), | ||
| img( | ||
| src = image_path, | ||
| class = "empty-state-image", | ||
| replace_svg_fill( | ||
| color = color, | ||
| svg_path = image_path, | ||
| alt = text | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| #' Function to replace fill color in SVG | ||
| #' @param color Character. The color to replace | ||
| #' @param svg_path Character. The path to the SVG file | ||
| #' @param placeholder Character. The placeholder. Default is "PRIMARY" | ||
| #' @param alt Character. The alt text for the image | ||
| #' @return an image tag with the SVG content | ||
| replace_svg_fill <- function( | ||
| color, | ||
| svg_path = "", | ||
| placeholder = "PRIMARY", | ||
| alt = "", | ||
| class = "empty-state-image" | ||
| ) { | ||
| svg_content <- readLines(svg_path) | ||
| svg_content <- paste(svg_content, collapse = "\n") | ||
| svg_content <- gsub( | ||
| placeholder, | ||
| color, | ||
| svg_content | ||
| ) | ||
| img( | ||
| class = class, | ||
| src = paste0( | ||
| "data:image/svg+xml;base64,", | ||
| base64encode(charToRaw(svg_content)) | ||
| ), | ||
| alt = alt | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,9 @@ | ||
| box::use( | ||
| purrr[ | ||
| map_chr | ||
| ], | ||
| ) | ||
|
|
||
| #' Function to check if a string of log text has error keywords | ||
| #' | ||
| #' @param text Character. The log string | ||
|
|
@@ -37,3 +43,24 @@ format_timestamp <- function( | |
| format = to | ||
| ) | ||
| } | ||
|
|
||
| #' Generate CSS variables from config.yml | ||
| #' @param config the config file | ||
| #' @return a string of CSS variables within :root {} | ||
| #' @export | ||
| generate_css_variables <- function( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it is a good moment to start adding unit tests? This function looks like an opportunity :)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added tests for all the |
||
| config | ||
| ) { | ||
| css_lines <- map_chr( | ||
| names(config$colors), | ||
| function(name) { | ||
| color_value <- config$colors[[name]] | ||
| sprintf(" --%s: %s;", name, color_value) | ||
| } | ||
| ) | ||
| paste0( | ||
| ":root {\n", | ||
| paste(css_lines, collapse = "\n"), | ||
| "\n}" | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| box::use( | ||
| config[ | ||
| get | ||
| ], | ||
| ellmer, #nolint: we do use this package just in a separate notation [[ ]] | ||
| glue[ | ||
| glue | ||
| ], | ||
| ) | ||
|
|
||
| #' Check if LLM is enabled | ||
| #' | ||
| #' This function checks the LLM configuration and returns TRUE if enabled, FALSE otherwise. | ||
| #' @return Logical indicating if LLM is enabled | ||
| #' @export | ||
| is_llm_enabled <- function() { | ||
| get("llm")$enabled %||% FALSE | ||
| } | ||
|
|
||
| #' Get valid LLM providers | ||
| #' @return A character vector of valid LLM providers | ||
| get_valid_providers <- function( | ||
| ) { | ||
| ellmer_functions <- ls(ellmer)[ | ||
| grepl( | ||
| pattern = "^chat_", | ||
| x = ls(ellmer) | ||
| ) | ||
| ] | ||
| sub( | ||
| pattern = "^chat_", | ||
| replacement = "", | ||
| x = ellmer_functions | ||
| ) | ||
| } | ||
|
|
||
| #' Check if the provider is valid | ||
| #' @param provider The LLM provider to check | ||
| #' @param valid_providers A character vector of valid LLM providers | ||
| #' @return Logical indicating if the provider is valid | ||
| verify_provider <- function( | ||
| provider, | ||
| valid_providers = get_valid_providers() | ||
| ) { | ||
| if (!provider %in% valid_providers) { | ||
| stop( | ||
| glue( | ||
| "Invalid LLM provider '{provider}'. ", | ||
| "Valid providers are: {paste(valid_providers, collapse = ', ')}" | ||
| ) | ||
| ) | ||
| } | ||
| TRUE | ||
| } | ||
|
|
||
| #' Get LLM configuration | ||
| #' | ||
| #' Returns the LLM configuration if LLM is enabled. Otherwise, throws an error. | ||
| #' @return A list containing the LLM configuration | ||
| get_llm_config <- function() { | ||
| if (!is_llm_enabled()) { | ||
| stop("Oops! LLM is not enabled in config.yml!") | ||
| } | ||
| verify_provider( | ||
| get("llm")$provider, | ||
| get_valid_providers() | ||
| ) | ||
| get("llm") | ||
| } | ||
|
|
||
| #' Get the LLM function based on the provider | ||
| #' | ||
| #' Extracts the chat function dynamically from the `ellmer` module. | ||
| #' @param llm_config Optional configuration for the LLM | ||
| #' @return A function to create a chat object | ||
| get_llm_function <- function( | ||
| llm_config = get_llm_config() | ||
| ) { | ||
| ellmer[[glue("chat_{llm_config$provider}")]] | ||
| } | ||
|
|
||
| #' Create a chat object | ||
| #' | ||
| #' Uses the configured LLM provider and model to create a chat object. | ||
| #' @param llm_config Optional configuration for the LLM | ||
| #' @return A chat object | ||
| #' @export | ||
| create_chat_object <- function( | ||
| llm_config = get_llm_config() | ||
| ) { | ||
| fun <- get_llm_function(llm_config) | ||
| fun( | ||
| api_key = llm_config$api_key, | ||
| model = llm_config$model, | ||
| system_prompt = llm_config$system_prompt, | ||
| seed = 42, | ||
| api_args = list( | ||
| temperature = 0 | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| #' Invoke LLM help with the logs data.frame | ||
| #' @param logs_data A data frame containing log data | ||
| #' @return A response from the LLM | ||
| #' @export | ||
| get_llm_help <- function( | ||
| logs_data | ||
| ) { | ||
| chat <- create_chat_object() | ||
| chat$chat( | ||
| concatenate_logs( | ||
| logs_data | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| #' Concatenate logs | ||
| #' @param processed_logs A data frame containing log data | ||
| #' @return A string with concatenated log entries | ||
| concatenate_logs <- function( | ||
| processed_logs | ||
| ) { | ||
| paste( | ||
| processed_logs$entries.data, | ||
| collapse = "\n" | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest expanding this with some description of what particular colors do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! I've added a few points explaining how the colors work. It should at least indicate the user what colors affect what values.