├── LICENSE
├── .gitignore
├── BioC2020_workshops.xlsx
├── BioC2020_talks_posters.xlsx
├── assessr.Rproj
├── LICENSE.md
├── tour_info.txt
├── README.md
└── app.R
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2020
2 | COPYRIGHT HOLDER: Federico Marini
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 |
--------------------------------------------------------------------------------
/BioC2020_workshops.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bioconductor/assessr/devel/BioC2020_workshops.xlsx
--------------------------------------------------------------------------------
/BioC2020_talks_posters.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bioconductor/assessr/devel/BioC2020_talks_posters.xlsx
--------------------------------------------------------------------------------
/assessr.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2020 Federico Marini
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tour_info.txt:
--------------------------------------------------------------------------------
1 | element;intro
2 | #Welcome;Welcome to the interactive tour for assessr!
3 | #DT_abstracts;The main part is occupied here by the main DataTable, where all contributions are displayed.
4 | #submissionType + .selectize-control; Selecting the type of submission, you can choose if you are going to review Workshops or Talks and other contributions type (posters, shiny demos)
5 | #reviewer + .selectize-control; Use this selector to filter only the abstract which are assigned to you. Remember that you must review all the submissions assigned to you for all contribution types, but if you want, you can review also other submissions
6 | #cols_abstract + .selectize-control; Clicking on the elements in this selectize widget, you can edit its looks, by adding/removing/sorting the columns you display - you might want to use a minimal configuration, for example.
7 | #DT_abstracts;If you changed something in the previous widget, see how the aspect of the DT changes.
8 | #DT_abstracts;You can drill down the content of each abstract by clicking on any row of the DT table. Please do so before proceeding.
9 | #session_abstract;See how the content of each contribution are beautified and displayed in the right column of the app
10 | #launch_gform;Importantly: once you are ready to evaluate the contributed session, here's a comfy link for you to evaluate it in the Google Form for this.
11 | #launch_gform;If you click on this, this has a nice side effect: the Id of the contributed session is copied directly to the clipboard, so you can paste it in the Form
12 | #session_abstract;That's pretty much it. Please remember to evaluate all the contributed sessions you are assigned to, and of course to fill in the complete set of info in the evaluation form.
13 | #Thanks;Thank you for taking the tour of assessr!
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # assessr
5 |
6 |
7 |
8 |
9 |
10 | The `assessr` app can be used to display the contributed poster/talk/workshop sessions submitted for the [Bioconductor 2020](https://bioc2020.bioconductor.org/) conference.
11 |
12 | # Prerequisites
13 |
14 | ## Input file(s)
15 |
16 | Excel files with columns: "Id", "Title", "Description", "Session format", "Track", "Keywords (1-3)", "Link", "First time presenting this?", "Speaker Notes", "Reviewer1", "Reviewer2", "Reviewer3"
17 |
18 | Currently, files `BioC2020_workshops.xlsx` and `BioC2020_talks_posters.xlsx` are used. They contain data about workshops and talks/posters, respectively.
19 |
20 | ## Reviewer's working with the app
21 |
22 | - Select you name in the "Reviewer name" drop-down menu to see all posters assignned to you.
23 | - Click on each poster - the rightmost panel will display the full information about the submission, and the link to a Google form where one can enter evaluations.
24 |
25 | ## Output
26 |
27 | - Google forms for evaluation should be created _a priori_. Examples of forms are: [eRum 2020 - Workshop Sessions Evaluation](https://docs.google.com/forms/d/e/1FAIpQLScTMLTJ1ccfBmjdEPhZfk5CyQwqSAW5AUJyDkFxc7Q9ZW6VPQ/viewform?entry.840333480=), [eRum 2020 - Contributed Sessions Evaluation](https://docs.google.com/forms/d/e/1FAIpQLSezGbJ1JmgOwDI5BLl28gXp3YQfoFXq8GoMon3k9PZcePCF_w/viewform?entry.840333480=)
28 | - `assessr` will pre-populate the forms with the "Id|Title" string.
29 | - Complete your evaluation by submitting the form.
30 | - Return to `assessr` and complete other evaluations assigned to you.
31 |
32 |
33 | # Footnotes
34 |
35 | **Work in progress! The majority of things are hard-coded and need to be manually adjusted.**
36 |
--------------------------------------------------------------------------------
/app.R:
--------------------------------------------------------------------------------
1 | library(shiny)
2 | library(shinydashboard)
3 | library(clipr)
4 | library(rintrojs)
5 | library(dplyr)
6 |
7 | # URL(s) to Google Form(s) for Evaluation
8 | # workshop_form <- function(id) {
9 | # paste0("https://docs.google.com/forms/d/e/1FAIpQLScTMLTJ1ccfBmjdEPhZfk5CyQwqSAW5AUJyDkFxc7Q9ZW6VPQ/viewform?usp=pp_url&entry.840333480=",
10 | # id)
11 | # }
12 | # contribution_form <- function(id) {
13 | # paste0("https://docs.google.com/forms/d/e/1FAIpQLSezGbJ1JmgOwDI5BLl28gXp3YQfoFXq8GoMon3k9PZcePCF_w/viewform?usp=pp_url&entry.840333480=",
14 | # id)
15 | # }
16 |
17 | # To pre-populate an element in the evaluation form, drill down to this element
18 | # using Chrome developer tools and get element id as, e.g., name="entry.1845598857"
19 | workshop_form <- function(id) {
20 | paste0("https://docs.google.com/forms/d/e/1FAIpQLSc4iDxze_Xm8cnYuVuMDnR6rVI7kj7gjL8f5ow4hd2zDJk-mw/viewform?usp=pp_url&entry.1845598857=", id)
21 | }
22 |
23 | # Open link in a new window
24 | window_open <- function(form_link) {
25 | paste0("window.open('", form_link, "', '_blank')")
26 | }
27 | # Open link to evaluation table for a given type of evaluation, if multiple
28 | window_open_eval <- function(id, type) {
29 | if (type == "workshop") {
30 | link <- workshop_form(id)
31 | } else if (type == "contribution") {
32 | link <- contribution_form(id)
33 | }
34 | window_open(link)
35 | }
36 |
37 |
38 | # Excel file(s) with session information
39 | workshop_path <- "./Bioc2020 talks and posters review.xlsx"
40 | # contribution_path <- "./BioC2020_talks_posters.xlsx"
41 | #
42 | workshop_table <- readxl::read_excel(workshop_path)
43 | # contribution_table_raw <- readxl::read_excel(contribution_path)
44 | # contribution_table <- contribution_table_raw[!is.na(contribution_table_raw$Id),]
45 |
46 | # Alternatively, read directly from a GSheet that has been shared for view
47 | # library(gsheet) # install.packages("gsheet")
48 | # workshop_table <- gsheet2tbl("https://docs.google.com/spreadsheets/d/1kaYuJKlt7sNSiLumQYnZau5TgTx9W9SkSQsQa8xBCLM/edit?usp=sharing")
49 | # # Remove duplicate submissions, ignoring Timestamp
50 | # workshop_table <- workshop_table[!duplicated(workshop_table[, colnames(workshop_table) != "Timestamp"]), ]
51 |
52 | # Get unique reviewer's names
53 | reviewers_names <- workshop_table %>% dplyr::select(starts_with("Reviewer")) %>% unlist %>% unique()
54 | reviewers_names <- reviewers_names[!is.na(reviewers_names)] # Remove NA reviwers
55 |
56 | # Currently, all columns need to be manually recoded
57 | # colnames(workshop_table)
58 | # Which columns to display
59 | preselected_cols <- c("Name of presenter",
60 | "Affiliation of presenter",
61 | "Title of talk / poster",
62 | "What are you proposing to present?")
63 | # Compact table to display
64 | abstract_table_compact <- workshop_table[, preselected_cols]
65 |
66 | # UI definition -----------------------------------------------------------
67 | assessr_ui <- shinydashboard::dashboardPage(
68 | skin = "black",
69 | rintrojs::introjsUI(),
70 | # header definition -------------------------------------------------------
71 | header = shinydashboard::dashboardHeader(
72 | title = "assessr - BioC2020",
73 | titleWidth = 350
74 | ),
75 |
76 | # sidebar definition ------------------------------------------------------
77 | sidebar = shinydashboard::dashboardSidebar(
78 | width = 250,
79 | shinydashboard::menuItem(
80 | text = "Sessions Settings", icon = icon("cog"),
81 | startExpanded = TRUE,
82 | selectInput(
83 | inputId = "submissionType",
84 | label = "Type of contribution",
85 | # choices = c("Workshops" = "workshop", "Talks and other sessions" = "contribution"),
86 | choices = c("Abstracts" = "workshop"),
87 | selected = "Abstracts",
88 | multiple = FALSE
89 | ),
90 | selectInput(
91 | inputId = "cols_abstract",
92 | label = "Columns to display",
93 | choices = colnames(workshop_table),
94 | selected = preselected_cols,
95 | multiple = TRUE
96 | ),
97 | selectInput(
98 | inputId = "reviewer",
99 | label = "Reviewer name",
100 | choices = c("All", reviewers_names),
101 | selected = "All",
102 | multiple = FALSE
103 | ),
104 |
105 | actionButton(
106 | inputId = "tour_assessr",
107 | icon = icon("question-circle"),
108 | label = "How does assessr work?",
109 | class = "btn-info"
110 | ),
111 | HTML("")
112 | )
113 | ),
114 |
115 | # body definition ---------------------------------------------------------
116 | body = shinydashboard::dashboardBody(
117 | id = "main-app",
118 |
119 | fluidRow(
120 | column(
121 | width = 6,
122 | DT::dataTableOutput("DT_abstracts")
123 | ),
124 | column(
125 | width = 6,
126 | hr(),
127 | uiOutput("session_abstract")
128 | )
129 | )
130 | )
131 | )
132 |
133 | # Server definition -------------------------------------------------------
134 | assessr_server <- function(input, output, session) {
135 | abstract_table <- reactive({
136 | message("input$submissionType: ", input$submissionType)
137 | if (input$submissionType == "workshop") {
138 | abstract_t <- workshop_table
139 | } else if (input$submissionType == "contribution") {
140 | abstract_t <- contribution_table
141 | }
142 | abstract_t
143 | })
144 |
145 | current_dt <- reactive({
146 | message("input$reviewer: ", input$reviewer)
147 | # ToDo: Automate reviewers column selection
148 | mydt <- abstract_table()[abstract_table()$`Reviewer 1` %in% input$reviewer |
149 | abstract_table()$`Reviewer 2` %in% input$reviewer |
150 | abstract_table()$`Reviewer 3` %in% input$reviewer |
151 | abstract_table()$`Reviewer 4` %in% input$reviewer |
152 | abstract_table()$`Reviewer 5` %in% input$reviewer |
153 | abstract_table()$`Reviewer 6` %in% input$reviewer |
154 | abstract_table()$`Reviewer 7` %in% input$reviewer |
155 | abstract_table()$`Reviewer 8` %in% input$reviewer |
156 | abstract_table()$`Reviewer 9` %in% input$reviewer |
157 | abstract_table()$`Reviewer 10` %in% input$reviewer |
158 | abstract_table()$`Reviewer 11` %in% input$reviewer |
159 | abstract_table()$`Reviewer 12` %in% input$reviewer |
160 | "All" %in% input$reviewer,
161 | union(input$cols_abstract, "Timestamp")]
162 | return(mydt)
163 | })
164 |
165 | output$session_abstract <- renderUI({
166 | s <- input$DT_abstracts_rows_selected
167 | if(length(s) == 0)
168 | return(h3("Select an abstract from the table to display the full info"))
169 |
170 | search_id <- current_dt()[s, ]$Timestamp
171 | this_submission <- abstract_table()[abstract_table()$Timestamp == search_id, ]
172 | this_id <- this_submission$Timestamp
173 | this_title <- this_submission$`Title of talk / poster`
174 | this_authors <- this_submission$`List of authors`
175 | this_abstract <- this_submission$`Abstract (up to 300 words)`
176 | this_format <- this_submission$`What are you proposing to present?`
177 | this_keywords <- this_submission$`Keywords (up to 5, comma-separated)`
178 | this_link <- this_submission$`If you are presenting an R/Bioconductor package, please provide a URL to the package.`
179 |
180 | # form_id:
181 | s <- input$DT_abstracts_rows_selected
182 | if(length(s) == 0)
183 | return(NULL)
184 |
185 | this_submission <- current_dt()[s, ]
186 | this_author <- this_submission$`Name of presenter`
187 | this_title <- this_submission$`Title of talk / poster`
188 |
189 | form_id <- gsub( "'", "", paste(this_author, this_title, sep = "|"))
190 |
191 | message("type: ", input$submissionType)
192 | message("form_id(): ", form_id)
193 |
194 | return(
195 | tagList(
196 | h3("Title: "),
197 | tags$b(h2(this_title)),
198 | h4("Contribution identifier: "),
199 | tags$p(paste(this_author, this_title, sep = "|")),
200 | h3("Abstract: "),
201 | tags$p(this_abstract),
202 | h3("Format:"),
203 | p(this_format),
204 | h3("Keywords:"),
205 | tags$b(this_keywords),
206 | h3("Link:"),
207 | p(this_link),
208 |
209 | shiny::actionButton(
210 | inputId = "launch_gform", label = "Open the Google Form to insert your evaluation",
211 | icon = icon("database"),
212 | onclick =window_open_eval(form_id, input$submissionType),
213 | class = "btn-success"
214 | )
215 | )
216 | )
217 | })
218 |
219 | output$DT_abstracts <- DT::renderDataTable({
220 | DT::datatable(
221 | current_dt(),
222 | style = "bootstrap",
223 | rownames = FALSE,
224 | filter = "top",
225 | selection = list(mode = "single"),
226 | options = list(
227 | scrollX = TRUE,
228 | pageLength = 5,
229 | lengthMenu = c(5, 10, 25, 50, 100, nrow(current_dt()))
230 | )
231 | )
232 | })
233 |
234 | observeEvent(input$tour_assessr, {
235 | tour <- read.delim("tour_info.txt",
236 | sep = ";", stringsAsFactors = FALSE,
237 | row.names = NULL, quote = "")
238 | rintrojs::introjs(session, options = list(steps = tour))
239 | })
240 |
241 | }
242 |
243 | shinyApp(ui = assessr_ui, server = assessr_server)
244 |
245 |
--------------------------------------------------------------------------------