@@ -60,8 +60,9 @@ full_url <- function(session) {
6060 session $ clientData $ url_protocol ,
6161 " //" ,
6262 session $ clientData $ url_hostname ,
63- if (nzchar(session $ clientData $ url_port ))
64- paste0(" :" , session $ clientData $ url_port ),
63+ if (nzchar(session $ clientData $ url_port )) {
64+ paste0(" :" , session $ clientData $ url_port )
65+ },
6566 session $ clientData $ url_pathname
6667 )
6768}
@@ -746,10 +747,41 @@ server <- function(input, output, session) {
746747 paste0(" Updated " , format(usage_last_updated(), fmt ))
747748 })
748749
750+ # JavaScript for persisting search terms across table rerenders
751+ table_js <- "
752+ function(el, x) {
753+ const tableId = el.id;
754+ const storageKey = 'search_' + tableId;
755+
756+ // Clear search value when the page is refreshed
757+ window.addEventListener('beforeunload', function() {
758+ sessionStorage.removeItem(storageKey);
759+ });
760+
761+ const searchInput = el.querySelector('input.rt-search');
762+ if (!searchInput) return;
763+
764+ // Restore previous search if available
765+ const savedSearch = sessionStorage.getItem(storageKey);
766+
767+ if (savedSearch) {
768+ searchInput.value = savedSearch;
769+ if (window.Reactable && typeof window.Reactable.setSearch === 'function') {
770+ window.Reactable.setSearch(tableId, savedSearch);
771+ }
772+ }
773+
774+ // Save search terms as they're entered
775+ searchInput.addEventListener('input', function() {
776+ sessionStorage.setItem(storageKey, this.value);
777+ });
778+ }
779+ "
780+
749781 output $ content_usage_table <- renderReactable({
750782 data <- multi_content_table_data()
751783
752- reactable(
784+ table <- reactable(
753785 data ,
754786 defaultSortOrder = " desc" ,
755787 onClick = JS(
@@ -792,7 +824,9 @@ server <- function(input, output, session) {
792824 width = 32 ,
793825 sortable = FALSE ,
794826 cell = function (url ) {
795- if (is.na(url ) || url == " " ) return (" " )
827+ if (is.na(url ) || url == " " ) {
828+ return (" " )
829+ }
796830 HTML(as.character(tags $ div(
797831 onclick = " event.stopPropagation()" ,
798832 tags $ a(
@@ -864,6 +898,9 @@ server <- function(input, output, session) {
864898 )
865899 )
866900 )
901+
902+ # Apply any onRender JS for capturing search value
903+ htmlwidgets :: onRender(table , table_js )
867904 })
868905
869906 output $ export_raw_visits <- downloadHandler(
@@ -964,7 +1001,9 @@ server <- function(input, output, session) {
9641001 width = 32 ,
9651002 sortable = FALSE ,
9661003 cell = function (url ) {
967- if (is.na(url ) || url == " " ) return (" " )
1004+ if (is.na(url ) || url == " " ) {
1005+ return (" " )
1006+ }
9681007 subject <- glue :: glue(
9691008 " \" {selected_content_info()$title}\" on Posit Connect"
9701009 )
@@ -1020,8 +1059,11 @@ server <- function(input, output, session) {
10201059 users <- aggregated_visits_data() | >
10211060 filter(user_guid %in% input $ selected_users ) | >
10221061 pull(display_name )
1023- user_string <- if (length(users ) == 1 ) users else
1062+ user_string <- if (length(users ) == 1 ) {
1063+ users
1064+ } else {
10241065 " multiple selected users"
1066+ }
10251067 tagList(
10261068 HTML(glue :: glue(
10271069 " {nrow(hits)} visits from <b>{user_string}</b> between " ,
@@ -1121,8 +1163,11 @@ server <- function(input, output, session) {
11211163 type = " button" ,
11221164 class = " btn btn-sm btn-outline-secondary" ,
11231165 disabled = disabled ,
1124- onclick = if (is.null(disabled ))
1125- sprintf(" window.location.href='%s'" , mailto ) else NULL ,
1166+ onclick = if (is.null(disabled )) {
1167+ sprintf(" window.location.href='%s'" , mailto )
1168+ } else {
1169+ NULL
1170+ },
11261171 tagList(icon(" envelope" ), " Email Selected Visitors" )
11271172 )
11281173 })
0 commit comments