From 2919209c5def8dbd8144869c42afdc8b32310e8a Mon Sep 17 00:00:00 2001 From: Giulio Benedetti Date: Fri, 29 Nov 2024 13:39:42 +0200 Subject: [PATCH 1/5] Update second Dockerfile --- inst/Dockerfile | 2 +- inst/app.R | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 inst/app.R diff --git a/inst/Dockerfile b/inst/Dockerfile index b5a506e..d92532e 100644 --- a/inst/Dockerfile +++ b/inst/Dockerfile @@ -13,4 +13,4 @@ ADD . /app EXPOSE 1234 # Run the script that launches the Shiny app -CMD Rscript app.R +CMD ["R", "-e", "library(miaDash); app <- miaDash(); shiny::runApp(app, port = 1234, host = '0.0.0.0')"] \ No newline at end of file diff --git a/inst/app.R b/inst/app.R deleted file mode 100644 index 6b00826..0000000 --- a/inst/app.R +++ /dev/null @@ -1,10 +0,0 @@ -timestamp() -message("* Started") - -library(miaDash) - -app <- miaDash() -shiny::runApp(app, port = 1234, host = "0.0.0.0") - -message("* Completed") -timestamp() From 39c178270a1e0f1f482b78c51593dbb8a040f72c Mon Sep 17 00:00:00 2001 From: Giulio Benedetti Date: Fri, 29 Nov 2024 14:15:17 +0200 Subject: [PATCH 2/5] Switch to dashboard --- NAMESPACE | 11 ++- R/landing_page.R | 212 +++++++++++++++++++++++++---------------------- 2 files changed, 116 insertions(+), 107 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 4521e8c..594f082 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -41,15 +41,12 @@ importFrom(scater,runMDS) importFrom(scater,runPCA) importFrom(shiny,actionButton) importFrom(shiny,checkboxInput) -importFrom(shiny,column) importFrom(shiny,conditionalPanel) importFrom(shiny,downloadButton) importFrom(shiny,downloadHandler) importFrom(shiny,fileInput) -importFrom(shiny,fluidPage) importFrom(shiny,fluidRow) importFrom(shiny,isolate) -importFrom(shiny,mainPanel) importFrom(shiny,modalDialog) importFrom(shiny,numericInput) importFrom(shiny,observe) @@ -62,17 +59,19 @@ importFrom(shiny,req) importFrom(shiny,selectInput) importFrom(shiny,showModal) importFrom(shiny,showNotification) -importFrom(shiny,sidebarLayout) -importFrom(shiny,sidebarPanel) importFrom(shiny,sliderInput) importFrom(shiny,tabPanel) importFrom(shiny,tabsetPanel) importFrom(shiny,textInput) -importFrom(shiny,titlePanel) importFrom(shiny,updateNumericInput) importFrom(shiny,updateSelectInput) importFrom(shiny,verbatimTextOutput) importFrom(shiny,wellPanel) +importFrom(shinydashboard,box) +importFrom(shinydashboard,dashboardBody) +importFrom(shinydashboard,dashboardHeader) +importFrom(shinydashboard,dashboardPage) +importFrom(shinydashboard,dashboardSidebar) importFrom(shinyjs,disable) importFrom(shinyjs,enable) importFrom(stats,as.formula) diff --git a/R/landing_page.R b/R/landing_page.R index 8fd248d..84d2e38 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -10,11 +10,12 @@ #' @keywords internal #' @rdname landing_page -#' @importFrom shiny actionButton fluidPage titlePanel sidebarLayout column -#' sidebarPanel mainPanel tabPanel tabsetPanel renderUI selectInput +#' @importFrom shiny actionButton tabPanel tabsetPanel renderUI selectInput #' sliderInput textInput wellPanel fluidRow reactiveValues radioButtons #' numericInput fileInput checkboxInput verbatimTextOutput downloadButton #' conditionalPanel +#' @importFrom shinydashboard dashboardPage dashboardHeader dashboardSidebar +#' dashboardBody box #' @importFrom shinyjs disable #' @importFrom utils data .landing_page <- function(FUN, input, output, session) { @@ -24,15 +25,18 @@ output$allPanels <- renderUI({ - fluidPage( + dashboardPage( - fluidRow(column(4, wellPanel(id = "import.panel", - - titlePanel("Import"), - + dashboardHeader(disable = TRUE), + dashboardSidebar(disable = TRUE), + dashboardBody( + + fluidRow(box(id = "import.panel", title = "Import", width = 4, + status = "primary", solidHeader = TRUE, + tabsetPanel(id = "format", - tabPanel(title = "Dataset", value = "dataset", + tabPanel(title = "Dataset", value = "dataset", br(), selectInput(inputId = "data", label = "Dataset:", choices = mia_datasets, @@ -40,14 +44,14 @@ ), - tabPanel(title = "R Object", value = "rds", + tabPanel(title = "R Object", value = "rds", br(), fileInput(inputId = "file", label = "RDS:", accept = ".rds") ), - tabPanel(title = "Raw Data", value = "raw", + tabPanel(title = "Raw Data", value = "raw", br(), fileInput(inputId = "assay", label = "Assays:", accept = ".csv", multiple = TRUE), @@ -60,7 +64,7 @@ ), - tabPanel(title = "Foreign", value = "foreign", + tabPanel(title = "Foreign", value = "foreign", br(), radioButtons(inputId = "ftype", label = "Type:", choices = list("biom", "QZA", @@ -97,121 +101,120 @@ actionButton("import", "Upload", class = "btn-success", style = .actionbutton_biocstyle) - )), + ), - column(4, wellPanel(id = "manipulate.panel", - - titlePanel("Manipulate"), - - tabsetPanel(id = "manipulate", + box(id = "manipulate.panel", title = "Manipulate", width = 4, + status = "primary", solidHeader = TRUE, + + tabsetPanel(id = "manipulate", - tabPanel(title = "Subset", value = "subset", + tabPanel(title = "Subset", value = "subset", br(), - radioButtons(inputId = "subkeep", label = "Keep:", - choices = c("prevalent", "rare"), inline = TRUE), + radioButtons(inputId = "subkeep", label = "Keep:", + choices = c("prevalent", "rare"), inline = TRUE), - selectInput(inputId = "subassay", label = "Assay:", - choices = NULL), + selectInput(inputId = "subassay", label = "Assay:", + choices = NULL), - sliderInput(inputId = "prevalence", value = 0, - label = "Prevalence threshold:", step = 0.01, - min = 0, max = 1), + sliderInput(inputId = "prevalence", value = 0, + label = "Prevalence threshold:", step = 0.01, + min = 0, max = 1), - numericInput(inputId = "detection", value = 0, - label = "Detection threshold:", min = 0, step = 1) + numericInput(inputId = "detection", value = 0, + label = "Detection threshold:", min = 0, step = 1) - ), + ), - tabPanel(title = "Agglomerate", value = "agglomerate", + tabPanel(title = "Agglomerate", value = "agglomerate", br(), - selectInput(inputId = "taxrank", - label = "Taxonomic rank:", choices = NULL) + selectInput(inputId = "taxrank", + label = "Taxonomic rank:", choices = NULL) - ), + ), - tabPanel(title = "Transform", value = "transform", + tabPanel(title = "Transform", value = "transform", br(), - selectInput(inputId = "assay.type", label = "Assay:", - choices = NULL), + selectInput(inputId = "assay.type", label = "Assay:", + choices = NULL), - selectInput(inputId = "trans.method", label = "Method:", - choices = c("relabundance", "clr", "standardize")), + selectInput(inputId = "trans.method", label = "Method:", + choices = c("relabundance", "clr", "standardize")), - checkboxInput(inputId = "pseudocount", - label = "Pseudocount"), + checkboxInput(inputId = "pseudocount", + label = "Pseudocount"), - textInput(inputId = "assay.name", label = "Name:"), + textInput(inputId = "assay.name", label = "Name:"), - radioButtons(inputId = "margin", label = "Margin:", - choices = c("samples", "features"), inline = TRUE) + radioButtons(inputId = "margin", label = "Margin:", + choices = c("samples", "features"), inline = TRUE) - )), + ) + + ), - actionButton("apply", "Apply", class = "btn-success", - style = .actionbutton_biocstyle) + actionButton("apply", "Apply", class = "btn-success", + style = .actionbutton_biocstyle) - )), + ), - column(4, wellPanel(id = "estimate.panel", - - titlePanel("Estimate"), - - tabsetPanel(id = "estimate", + box(id = "estimate.panel", title = "Estimate", width = 4, + status = "primary", solidHeader = TRUE, + + tabsetPanel(id = "estimate", - tabPanel(title = "Alpha", value = "alpha", + tabPanel(title = "Alpha", value = "alpha", br(), - selectInput(inputId = "alpha.assay", label = "Assay:", - choices = NULL), + selectInput(inputId = "alpha.assay", label = "Assay:", + choices = NULL), - selectInput(inputId = "alpha.index", label = "Metric:", - choices = c("coverage", "shannon", "faith"), - multiple = TRUE), + selectInput(inputId = "alpha.index", label = "Metric:", + choices = c("coverage", "shannon", "faith"), + multiple = TRUE), - textInput(inputId = "alpha.name", label = "Name:") + textInput(inputId = "alpha.name", label = "Name:") - ), + ), - tabPanel(title = "Beta", value = "beta", + tabPanel(title = "Beta", value = "beta", br(), - radioButtons(inputId = "bmethod", label = "Method:", - choices = c("MDS", "NMDS", "PCA", "RDA"), - inline = TRUE), + radioButtons(inputId = "bmethod", label = "Method:", + choices = c("MDS", "NMDS", "PCA", "RDA"), + inline = TRUE), - selectInput(inputId = "beta.assay", label = "Assay:", - choices = NULL), + selectInput(inputId = "beta.assay", label = "Assay:", + choices = NULL), - conditionalPanel( - condition = "input.bmethod != 'PCA'", - - selectInput(inputId = "beta.index", label = "Metric:", - choices = c("euclidean", "bray", "jaccard", "unifrac")), - ), - - conditionalPanel( - condition = "input.bmethod == 'RDA'", - - textInput(inputId = "rda.formula", label = "Formula:", - placeholder = "data ~ var1 + var2 * var3"), - ), + conditionalPanel( + condition = "input.bmethod != 'PCA'", + + selectInput(inputId = "beta.index", label = "Metric:", + choices = c("euclidean", "bray", "jaccard", "unifrac")), + ), - numericInput(inputId = "ncomponents", value = 5, - label = "Number of components:", min = 1, step = 1), + conditionalPanel( + condition = "input.bmethod == 'RDA'", + + textInput(inputId = "rda.formula", label = "Formula:", + placeholder = "data ~ var1 + var2 * var3"), + ), - textInput(inputId = "beta.name", label = "Name:") - - ) + numericInput(inputId = "ncomponents", value = 5, + label = "Number of components:", min = 1, step = 1), + + textInput(inputId = "beta.name", label = "Name:") + + ) - ), + ), - actionButton("compute", "Compute", class = "btn-success", - style = .actionbutton_biocstyle) + actionButton("compute", "Compute", class = "btn-success", + style = .actionbutton_biocstyle) - ))), + )), - fluidRow(column(4, wellPanel(id = "visualise.panel", - - titlePanel("Visualise"), - + fluidRow(box(id = "visualise.panel", title = "Visualise", width = 4, + status = "primary", solidHeader = TRUE, + selectInput(inputId = "panels", label = "Panels:", choices = c(default_panels, other_panels), multiple = TRUE, selected = c(default_panels)), @@ -219,12 +222,11 @@ actionButton("launch", "Launch iSEE", class = "btn-success", style = .actionbutton_biocstyle) - )), - - column(8, wellPanel(id = "output.panel", - - titlePanel("Output"), + ), + box(id = "output.panel", title = "Output", width = 8, + status = "primary", solidHeader = TRUE, + verbatimTextOutput(outputId = "object"), downloadButton(outputId = "download", label = "Download", @@ -248,12 +250,20 @@ observe({ .print_message( - title = "Welcome to the Microbiome Analysis Dashboard!", - "miaDash is actively maintained, so we are happy to receive", - "feedback from you. Feature requests, bug reports and other", - "comments can be submitted", + title = "Welcome to the Microbiome Analysis Dashboard! 🦠", + "miaDash is actively maintained by the", + tags$a(href = "https://datascience.utu.fi/", + "Turku Data Science Group", target = "_blank", .noWS = "after"), + ", so we are happy to receive feedback from you. Feature requests,", + "bug reports and other comments can be submitted", tags$a(href = "https://github.com/microbiome/miaDash/issues", - "here", target = "_blank", .noWS = "after"), ".", + "here", target = "_blank", .noWS = "after"), HTML(".

"), + "If you are new here, you can learn how to use the app with", + tags$a(href = "https://microbiome.github.io/miaDash/articles/miaDash.html", + "this short tutorial", target = "_blank", .noWS = "after"), + ". Technical support can be obtained on", + tags$a(href = "https://app.gitter.im/#/room/#microbiome_miaverse:gitter.im", + "our Gitter channel", target = "_blank", .noWS = "after"), "." ) }) From c7ba90797028f1b4cea545dba0a11bfd4b28a809 Mon Sep 17 00:00:00 2001 From: Giulio Benedetti Date: Fri, 29 Nov 2024 14:39:31 +0200 Subject: [PATCH 3/5] Bump version and add sinydashboard to description --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5594ae5..a12c5c9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: miaDash -Version: 0.99.1 +Version: 0.99.2 Authors@R: c(person(given = "Giulio", family = "Benedetti", role = c("aut", "cre"), email = "giulio.benedetti@utu.fi", @@ -30,6 +30,7 @@ Imports: rintrojs, scater, shiny, + shinydashboard, shinyjs, S4Vectors, SingleCellExperiment, From a19843ed757c8c7051d3c25920d917f7b61043fd Mon Sep 17 00:00:00 2001 From: Giulio Benedetti Date: Fri, 29 Nov 2024 15:21:24 +0200 Subject: [PATCH 4/5] Replace non-ASCII character with code --- R/landing_page.R | 2 +- R/miaDash.R | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/R/landing_page.R b/R/landing_page.R index 84d2e38..fefc915 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -250,7 +250,7 @@ observe({ .print_message( - title = "Welcome to the Microbiome Analysis Dashboard! 🦠", + title = "Welcome to the Microbiome Analysis Dashboard! \U0001f9a0", "miaDash is actively maintained by the", tags$a(href = "https://datascience.utu.fi/", "Turku Data Science Group", target = "_blank", .noWS = "after"), diff --git a/R/miaDash.R b/R/miaDash.R index e57ed22..f0d63ac 100644 --- a/R/miaDash.R +++ b/R/miaDash.R @@ -27,7 +27,8 @@ miaDash <- function() { iSEE( landingPage = .landing_page, - appTitle = sprintf("Microbiome Analysis Dashboard - v%s", packageVersion("miaDash")) + appTitle = paste0("Microbiome Analysis Dashboard \U0001f9a0 - ", + packageVersion("miaDash")) ) } From 12f17ce0de2a180809515d0d75018e8fae3c5fc7 Mon Sep 17 00:00:00 2001 From: Giulio Benedetti Date: Fri, 29 Nov 2024 16:04:40 +0200 Subject: [PATCH 5/5] Add htmltools to deps --- DESCRIPTION | 1 + NAMESPACE | 3 + R/landing_page.R | 152 +++++++++++++++++++---------------------------- 3 files changed, 65 insertions(+), 91 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a12c5c9..7eb5286 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,6 +24,7 @@ Depends: iSEE Imports: biomformat, + htmltools, iSEEtree, methods, mia, diff --git a/NAMESPACE b/NAMESPACE index 594f082..560a42a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -13,6 +13,9 @@ importFrom(TreeSummarizedExperiment,colLinks) importFrom(TreeSummarizedExperiment,rowLinks) importFrom(TreeSummarizedExperiment,rowTree) importFrom(biomformat,read_biom) +importFrom(htmltools,HTML) +importFrom(htmltools,br) +importFrom(htmltools,tags) importFrom(iSEE,ColumnDataTable) importFrom(iSEE,ComplexHeatmapPlot) importFrom(iSEE,ReducedDimensionPlot) diff --git a/R/landing_page.R b/R/landing_page.R index fefc915..36fa601 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -10,12 +10,13 @@ #' @keywords internal #' @rdname landing_page -#' @importFrom shiny actionButton tabPanel tabsetPanel renderUI selectInput -#' sliderInput textInput wellPanel fluidRow reactiveValues radioButtons +#' @importFrom shiny actionButton fluidRow tabPanel tabsetPanel renderUI +#' selectInput sliderInput textInput wellPanel reactiveValues radioButtons #' numericInput fileInput checkboxInput verbatimTextOutput downloadButton #' conditionalPanel #' @importFrom shinydashboard dashboardPage dashboardHeader dashboardSidebar #' dashboardBody box +#' @importFrom htmltools HTML br tags #' @importFrom shinyjs disable #' @importFrom utils data .landing_page <- function(FUN, input, output, session) { @@ -30,7 +31,7 @@ dashboardHeader(disable = TRUE), dashboardSidebar(disable = TRUE), dashboardBody( - + fluidRow(box(id = "import.panel", title = "Import", width = 4, status = "primary", solidHeader = TRUE, @@ -40,16 +41,12 @@ selectInput(inputId = "data", label = "Dataset:", choices = mia_datasets, - selected = mia_datasets[1]) - - ), + selected = mia_datasets[1])), tabPanel(title = "R Object", value = "rds", br(), fileInput(inputId = "file", label = "RDS:", - accept = ".rds") - - ), + accept = ".rds")), tabPanel(title = "Raw Data", value = "raw", br(), @@ -60,9 +57,7 @@ accept = ".csv"), fileInput(inputId = "rowdata", label = "rowData:", - accept = ".csv") - - ), + accept = ".csv")), tabPanel(title = "Foreign", value = "foreign", br(), @@ -81,27 +76,19 @@ label = "Remove taxa prefixes"), checkboxInput(inputId = "rank.from.pref", - label = "Derive taxa from prefixes") - ), + label = "Derive taxa from prefixes")), conditionalPanel( condition = "input.ftype == 'MetaPhlAn'", - fileInput(inputId = "col.data", label = "colData:", - accept = ".tsv"), + fileInput(inputId = "col.data", + label = "colData:", accept = ".tsv"), - fileInput(inputId = "tree.file", label = "Tree:", - accept = ".tree") - ) - - ) - - ), + fileInput(inputId = "tree.file", + label = "Tree:", accept = ".tree")))), actionButton("import", "Upload", class = "btn-success", - style = .actionbutton_biocstyle) - - ), + style = .actionbutton_biocstyle)), box(id = "manipulate.panel", title = "Manipulate", width = 4, status = "primary", solidHeader = TRUE, @@ -111,7 +98,8 @@ tabPanel(title = "Subset", value = "subset", br(), radioButtons(inputId = "subkeep", label = "Keep:", - choices = c("prevalent", "rare"), inline = TRUE), + choices = c("prevalent", "rare"), + inline = TRUE), selectInput(inputId = "subassay", label = "Assay:", choices = NULL), @@ -121,24 +109,24 @@ min = 0, max = 1), numericInput(inputId = "detection", value = 0, - label = "Detection threshold:", min = 0, step = 1) - - ), + label = "Detection threshold:", min = 0, + step = 1)), - tabPanel(title = "Agglomerate", value = "agglomerate", br(), + tabPanel(title = "Agglomerate", value = "agglomerate", + + br(), selectInput(inputId = "taxrank", - label = "Taxonomic rank:", choices = NULL) - - ), + label = "Taxonomic rank:", choices = NULL)), tabPanel(title = "Transform", value = "transform", br(), - selectInput(inputId = "assay.type", label = "Assay:", - choices = NULL), + selectInput(inputId = "assay.type", + label = "Assay:", choices = NULL), - selectInput(inputId = "trans.method", label = "Method:", - choices = c("relabundance", "clr", "standardize")), + selectInput(inputId = "trans.method", + label = "Method:", choices = c("relabundance", + "clr", "standardize")), checkboxInput(inputId = "pseudocount", label = "Pseudocount"), @@ -146,16 +134,11 @@ textInput(inputId = "assay.name", label = "Name:"), radioButtons(inputId = "margin", label = "Margin:", - choices = c("samples", "features"), inline = TRUE) - - ) - - ), + choices = c("samples", "features"), + inline = TRUE))), actionButton("apply", "Apply", class = "btn-success", - style = .actionbutton_biocstyle) - - ), + style = .actionbutton_biocstyle)), box(id = "estimate.panel", title = "Estimate", width = 4, status = "primary", solidHeader = TRUE, @@ -164,16 +147,14 @@ tabPanel(title = "Alpha", value = "alpha", br(), - selectInput(inputId = "alpha.assay", label = "Assay:", - choices = NULL), + selectInput(inputId = "alpha.assay", + label = "Assay:", choices = NULL), - selectInput(inputId = "alpha.index", label = "Metric:", - choices = c("coverage", "shannon", "faith"), - multiple = TRUE), + selectInput(inputId = "alpha.index", + label = "Metric:", multiple = TRUE, + choices = c("coverage", "shannon", "faith")), - textInput(inputId = "alpha.name", label = "Name:") - - ), + textInput(inputId = "alpha.name", label = "Name:")), tabPanel(title = "Beta", value = "beta", br(), @@ -181,60 +162,49 @@ choices = c("MDS", "NMDS", "PCA", "RDA"), inline = TRUE), - selectInput(inputId = "beta.assay", label = "Assay:", - choices = NULL), + selectInput(inputId = "beta.assay", + label = "Assay:", choices = NULL), conditionalPanel( condition = "input.bmethod != 'PCA'", - selectInput(inputId = "beta.index", label = "Metric:", - choices = c("euclidean", "bray", "jaccard", "unifrac")), - ), + selectInput(inputId = "beta.index", + label = "Metric:", choices = c("euclidean", + "bray", "jaccard", "unifrac"))), conditionalPanel( condition = "input.bmethod == 'RDA'", - textInput(inputId = "rda.formula", label = "Formula:", - placeholder = "data ~ var1 + var2 * var3"), - ), + textInput(inputId = "rda.formula", + label = "Formula:", + placeholder = "data ~ var1 + var2 * var3")), numericInput(inputId = "ncomponents", value = 5, - label = "Number of components:", min = 1, step = 1), + label = "Number of components:", min = 1, + step = 1), - textInput(inputId = "beta.name", label = "Name:") - - ) - - ), + textInput(inputId = "beta.name", label = "Name:"))), actionButton("compute", "Compute", class = "btn-success", - style = .actionbutton_biocstyle) - - )), - - fluidRow(box(id = "visualise.panel", title = "Visualise", width = 4, - status = "primary", solidHeader = TRUE, - - selectInput(inputId = "panels", label = "Panels:", - choices = c(default_panels, other_panels), - multiple = TRUE, selected = c(default_panels)), + style = .actionbutton_biocstyle))), - actionButton("launch", "Launch iSEE", class = "btn-success", - style = .actionbutton_biocstyle) + fluidRow(box(id = "visualise.panel", title = "Visualise", + width = 4, status = "primary", solidHeader = TRUE, + + selectInput(inputId = "panels", label = "Panels:", + choices = c(default_panels, other_panels), + multiple = TRUE, selected = c(default_panels)), - ), + actionButton("launch", "Launch iSEE", class = "btn-success", + style = .actionbutton_biocstyle)), - box(id = "output.panel", title = "Output", width = 8, - status = "primary", solidHeader = TRUE, + box(id = "output.panel", title = "Output", width = 8, + status = "primary", solidHeader = TRUE, - verbatimTextOutput(outputId = "object"), - - downloadButton(outputId = "download", label = "Download", - style = .actionbutton_biocstyle) + verbatimTextOutput(outputId = "object"), - )) - )) - }) + downloadButton(outputId = "download", label = "Download", + style = .actionbutton_biocstyle)))))}) ## Disable navbar buttons that are not linked to any observer yet disable("iSEE_INTERNAL_organize_panels") # organize panels @@ -258,7 +228,7 @@ "bug reports and other comments can be submitted", tags$a(href = "https://github.com/microbiome/miaDash/issues", "here", target = "_blank", .noWS = "after"), HTML(".

"), - "If you are new here, you can learn how to use the app with", + "If you are new to this app, you can learn how to use it with", tags$a(href = "https://microbiome.github.io/miaDash/articles/miaDash.html", "this short tutorial", target = "_blank", .noWS = "after"), ". Technical support can be obtained on",