From 36e2ed3811425f89c3c12e9b7e2bb221838a6101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Eduardo=20Jer=C3=A9z=20Gir=C3=B3n?= Date: Sun, 8 Sep 2024 00:06:56 -0600 Subject: [PATCH] Add dropdown with table options on all lists --- .../js/alpine-components/options-dropdown.js | 47 +++++++++++++++++ .../view/static/js/init-alpine-components.js | 2 + .../view/web/component/options_dropdown.go | 50 +++++++++++++++++++ .../web/dashboard/backups/delete_backup.go | 16 +++--- .../view/web/dashboard/backups/edit_backup.go | 15 ++---- internal/view/web/dashboard/backups/index.go | 2 +- .../web/dashboard/backups/list_backups.go | 31 +++++------- .../view/web/dashboard/backups/manual_run.go | 16 +++--- .../dashboard/databases/delete_database.go | 16 +++--- .../web/dashboard/databases/edit_database.go | 15 ++---- .../view/web/dashboard/databases/index.go | 2 +- .../web/dashboard/databases/list_databases.go | 37 ++++++-------- .../destinations/delete_destination.go | 16 +++--- .../destinations/edit_destination.go | 15 ++---- .../view/web/dashboard/destinations/index.go | 2 +- .../destinations/list_destinations.go | 44 ++++++---------- .../view/web/dashboard/executions/index.go | 2 +- .../dashboard/executions/list_executions.go | 12 ++--- .../dashboard/executions/restore_execution.go | 14 ++---- .../dashboard/executions/show_execution.go | 14 ++---- .../view/web/dashboard/restorations/index.go | 2 +- .../restorations/list_restorations.go | 6 +-- .../web/dashboard/webhooks/delete_webhook.go | 16 +++--- .../web/dashboard/webhooks/edit_webhook.go | 15 ++---- internal/view/web/dashboard/webhooks/index.go | 2 +- .../web/dashboard/webhooks/list_webhooks.go | 16 +++--- .../web/dashboard/webhooks/run_webhook.go | 16 +++--- .../dashboard/webhooks/webhook_executions.go | 25 +++------- 28 files changed, 228 insertions(+), 238 deletions(-) create mode 100644 internal/view/static/js/alpine-components/options-dropdown.js create mode 100644 internal/view/web/component/options_dropdown.go diff --git a/internal/view/static/js/alpine-components/options-dropdown.js b/internal/view/static/js/alpine-components/options-dropdown.js new file mode 100644 index 0000000..b47aec7 --- /dev/null +++ b/internal/view/static/js/alpine-components/options-dropdown.js @@ -0,0 +1,47 @@ +export const optionsDropdown = { + name: 'options_dropdown', + fn: () => ({ + isOpen: false, + buttonEl: null, + contentEl: null, + closeTimeout: null, + + init () { + this.buttonEl = this.$refs.button + this.contentEl = this.$refs.content + }, + + open () { + this.isOpen = true + this.contentEl.classList.remove('hidden') + this.positionContent() + + if (this.closeTimeout) { + clearTimeout(this.closeTimeout) + this.closeTimeout = null + } + }, + + close () { + this.closeTimeout = setTimeout(() => { + this.isOpen = false + this.contentEl.classList.add('hidden') + }, 200) + }, + + positionContent () { + const buttonRect = this.buttonEl.getBoundingClientRect() + const contentHeight = this.contentEl.offsetHeight + const windowHeight = window.innerHeight + const moreSpaceBelow = (windowHeight - buttonRect.bottom) > buttonRect.top + + this.contentEl.style.left = `${buttonRect.left}px` + + if (moreSpaceBelow) { + this.contentEl.style.top = `${buttonRect.bottom}px` + } else { + this.contentEl.style.top = `${buttonRect.top - contentHeight}px` + } + } + }) +} diff --git a/internal/view/static/js/init-alpine-components.js b/internal/view/static/js/init-alpine-components.js index 653a498..1ef573a 100644 --- a/internal/view/static/js/init-alpine-components.js +++ b/internal/view/static/js/init-alpine-components.js @@ -2,6 +2,7 @@ import { changeThemeButton } from './alpine-components/change-theme-button.js' import { githubRepoInfo } from './alpine-components/github-repo-info.js' import { dashboardAsideItem } from './alpine-components/dashboard-aside-item.js' import { genericSlider } from './alpine-components/generic-slider.js' +import { optionsDropdown } from './alpine-components/options-dropdown.js' export function initAlpineComponents () { document.addEventListener('alpine:init', () => { @@ -9,5 +10,6 @@ export function initAlpineComponents () { Alpine.data(githubRepoInfo.name, githubRepoInfo.fn) Alpine.data(dashboardAsideItem.name, dashboardAsideItem.fn) Alpine.data(genericSlider.name, genericSlider.fn) + Alpine.data(optionsDropdown.name, optionsDropdown.fn) }) } diff --git a/internal/view/web/component/options_dropdown.go b/internal/view/web/component/options_dropdown.go new file mode 100644 index 0000000..b42dfed --- /dev/null +++ b/internal/view/web/component/options_dropdown.go @@ -0,0 +1,50 @@ +package component + +import ( + lucide "github.com/eduardolat/gomponents-lucide" + "github.com/eduardolat/pgbackweb/internal/view/web/alpine" + "github.com/maragudk/gomponents" + "github.com/maragudk/gomponents/components" + "github.com/maragudk/gomponents/html" +) + +func OptionsDropdown(children ...gomponents.Node) gomponents.Node { + return html.Div( + html.Class("inline-block"), + alpine.XData("options_dropdown"), + alpine.XOn("mouseenter", "open()"), + alpine.XOn("mouseleave", "close()"), + html.Button( + alpine.XRef("button"), + html.Class("btn btn-sm btn-ghost btn-square"), + alpine.XBind("class", "isOpen ? 'btn-active' : ''"), + lucide.EllipsisVertical( + html.Class("transition-transform"), + alpine.XBind("class", "isOpen ? 'rotate-90' : ''"), + ), + ), + html.Div( + alpine.XRef("content"), + components.Classes{ + "fixed hidden": true, + "bg-base-100 rounded-box border border-base-200": true, + "z-40 max-w-[250px] p-2 shadow-md": true, + }, + gomponents.Group(children), + ), + ) +} + +func OptionsDropdownButton(children ...gomponents.Node) gomponents.Node { + return html.Button( + html.Class("btn btn-neutral btn-ghost btn-sm w-full flex justify-start"), + gomponents.Group(children), + ) +} + +func OptionsDropdownA(children ...gomponents.Node) gomponents.Node { + return html.A( + html.Class("btn btn-neutral btn-ghost btn-sm w-full flex justify-start"), + gomponents.Group(children), + ) +} diff --git a/internal/view/web/dashboard/backups/delete_backup.go b/internal/view/web/dashboard/backups/delete_backup.go index 83d99a8..5107a8b 100644 --- a/internal/view/web/dashboard/backups/delete_backup.go +++ b/internal/view/web/dashboard/backups/delete_backup.go @@ -2,11 +2,11 @@ package backups import ( lucide "github.com/eduardolat/gomponents-lucide" + "github.com/eduardolat/pgbackweb/internal/view/web/component" "github.com/eduardolat/pgbackweb/internal/view/web/htmx" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/maragudk/gomponents" - "github.com/maragudk/gomponents/html" ) func (h *handlers) deleteBackupHandler(c echo.Context) error { @@ -25,14 +25,10 @@ func (h *handlers) deleteBackupHandler(c echo.Context) error { } func deleteBackupButton(backupID uuid.UUID) gomponents.Node { - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Delete backup"), - html.Button( - htmx.HxDelete("/dashboard/backups/"+backupID.String()), - htmx.HxConfirm("Are you sure you want to delete this backup?"), - html.Class("btn btn-error btn-square btn-sm btn-ghost"), - lucide.Trash(), - ), + return component.OptionsDropdownButton( + htmx.HxDelete("/dashboard/backups/"+backupID.String()), + htmx.HxConfirm("Are you sure you want to delete this backup?"), + lucide.Trash(), + component.SpanText("Delete backup"), ) } diff --git a/internal/view/web/dashboard/backups/edit_backup.go b/internal/view/web/dashboard/backups/edit_backup.go index a62c208..ec4564c 100644 --- a/internal/view/web/dashboard/backups/edit_backup.go +++ b/internal/view/web/dashboard/backups/edit_backup.go @@ -263,19 +263,12 @@ func editBackupButton(backup dbgen.BackupsServicePaginateBackupsRow) gomponents. }, }) - button := html.Button( - mo.OpenerAttr, - html.Class("btn btn-neutral btn-sm btn-square btn-ghost"), - lucide.Pencil(), - ) - return html.Div( - html.Class("inline-block"), mo.HTML, - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Edit backup"), - button, + component.OptionsDropdownButton( + mo.OpenerAttr, + lucide.Pencil(), + component.SpanText("Edit backup"), ), ) } diff --git a/internal/view/web/dashboard/backups/index.go b/internal/view/web/dashboard/backups/index.go index fec4be6..de8df40 100644 --- a/internal/view/web/dashboard/backups/index.go +++ b/internal/view/web/dashboard/backups/index.go @@ -34,7 +34,7 @@ func indexPage(reqCtx reqctx.Ctx) gomponents.Node { html.Class("table text-nowrap"), html.THead( html.Tr( - html.Th(component.SpanText("Actions")), + html.Th(html.Class("w-1")), html.Th(component.SpanText("Name")), html.Th(component.SpanText("Database")), html.Th(component.SpanText("Destination")), diff --git a/internal/view/web/dashboard/backups/list_backups.go b/internal/view/web/dashboard/backups/list_backups.go index 51e4081..ab58c26 100644 --- a/internal/view/web/dashboard/backups/list_backups.go +++ b/internal/view/web/dashboard/backups/list_backups.go @@ -67,27 +67,20 @@ func listBackups( trs := []gomponents.Node{} for _, backup := range backups { trs = append(trs, html.Tr( - html.Td( - html.Class("w-[40px]"), - html.Div( - html.Class("flex justify-start space-x-1"), - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Show executions"), - html.A( - html.Class("btn btn-sm btn-ghost btn-square"), - html.Href( - fmt.Sprintf("/dashboard/executions?backup=%s", backup.ID), - ), - html.Target("_blank"), - lucide.List(), - ), + html.Td(component.OptionsDropdown( + component.OptionsDropdownA( + html.Class("btn btn-sm btn-ghost btn-square"), + html.Href( + fmt.Sprintf("/dashboard/executions?backup=%s", backup.ID), ), - manualRunbutton(backup.ID), - editBackupButton(backup), - deleteBackupButton(backup.ID), + html.Target("_blank"), + lucide.List(), + component.SpanText("Show executions"), ), - ), + manualRunbutton(backup.ID), + editBackupButton(backup), + deleteBackupButton(backup.ID), + )), html.Td( html.Div( html.Class("flex items-center space-x-2"), diff --git a/internal/view/web/dashboard/backups/manual_run.go b/internal/view/web/dashboard/backups/manual_run.go index ed50f38..174e70a 100644 --- a/internal/view/web/dashboard/backups/manual_run.go +++ b/internal/view/web/dashboard/backups/manual_run.go @@ -4,11 +4,11 @@ import ( "context" lucide "github.com/eduardolat/gomponents-lucide" + "github.com/eduardolat/pgbackweb/internal/view/web/component" "github.com/eduardolat/pgbackweb/internal/view/web/htmx" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/maragudk/gomponents" - "github.com/maragudk/gomponents/html" ) func (h *handlers) manualRunHandler(c echo.Context) error { @@ -25,14 +25,10 @@ func (h *handlers) manualRunHandler(c echo.Context) error { } func manualRunbutton(backupID uuid.UUID) gomponents.Node { - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Run backup now"), - html.Button( - htmx.HxPost("/dashboard/backups/"+backupID.String()+"/run"), - htmx.HxDisabledELT("this"), - html.Class("btn btn-sm btn-ghost btn-square"), - lucide.Zap(), - ), + return component.OptionsDropdownButton( + htmx.HxPost("/dashboard/backups/"+backupID.String()+"/run"), + htmx.HxDisabledELT("this"), + lucide.Zap(), + component.SpanText("Run backup now"), ) } diff --git a/internal/view/web/dashboard/databases/delete_database.go b/internal/view/web/dashboard/databases/delete_database.go index cb574fc..5543d7f 100644 --- a/internal/view/web/dashboard/databases/delete_database.go +++ b/internal/view/web/dashboard/databases/delete_database.go @@ -2,11 +2,11 @@ package databases import ( lucide "github.com/eduardolat/gomponents-lucide" + "github.com/eduardolat/pgbackweb/internal/view/web/component" "github.com/eduardolat/pgbackweb/internal/view/web/htmx" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/maragudk/gomponents" - "github.com/maragudk/gomponents/html" ) func (h *handlers) deleteDatabaseHandler(c echo.Context) error { @@ -25,14 +25,10 @@ func (h *handlers) deleteDatabaseHandler(c echo.Context) error { } func deleteDatabaseButton(databaseID uuid.UUID) gomponents.Node { - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Delete database"), - html.Button( - htmx.HxDelete("/dashboard/databases/"+databaseID.String()), - htmx.HxConfirm("Are you sure you want to delete this database?"), - html.Class("btn btn-error btn-square btn-sm btn-ghost"), - lucide.Trash(), - ), + return component.OptionsDropdownButton( + htmx.HxDelete("/dashboard/databases/"+databaseID.String()), + htmx.HxConfirm("Are you sure you want to delete this database?"), + lucide.Trash(), + component.SpanText("Delete database"), ) } diff --git a/internal/view/web/dashboard/databases/edit_database.go b/internal/view/web/dashboard/databases/edit_database.go index afe5277..d52bac0 100644 --- a/internal/view/web/dashboard/databases/edit_database.go +++ b/internal/view/web/dashboard/databases/edit_database.go @@ -154,19 +154,12 @@ func editDatabaseButton( }, }) - button := html.Button( - mo.OpenerAttr, - html.Class("btn btn-neutral btn-sm btn-square btn-ghost"), - lucide.Pencil(), - ) - return html.Div( - html.Class("inline-block"), mo.HTML, - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Edit database"), - button, + component.OptionsDropdownButton( + mo.OpenerAttr, + lucide.Pencil(), + component.SpanText("Edit database"), ), ) } diff --git a/internal/view/web/dashboard/databases/index.go b/internal/view/web/dashboard/databases/index.go index 85a64e7..3158303 100644 --- a/internal/view/web/dashboard/databases/index.go +++ b/internal/view/web/dashboard/databases/index.go @@ -34,7 +34,7 @@ func indexPage(reqCtx reqctx.Ctx) gomponents.Node { html.Class("table text-nowrap"), html.THead( html.Tr( - html.Th(component.SpanText("Actions")), + html.Th(html.Class("w-1")), html.Th(component.SpanText("Name")), html.Th(component.SpanText("Version")), html.Th(component.SpanText("Connection string")), diff --git a/internal/view/web/dashboard/databases/list_databases.go b/internal/view/web/dashboard/databases/list_databases.go index b9654cd..2ec9a47 100644 --- a/internal/view/web/dashboard/databases/list_databases.go +++ b/internal/view/web/dashboard/databases/list_databases.go @@ -60,36 +60,27 @@ func listDatabases( trs := []gomponents.Node{} for _, database := range databases { trs = append(trs, html.Tr( - html.Td( - html.Class("w-[40px]"), + html.Td(component.OptionsDropdown( html.Div( - html.Class("flex justify-start space-x-1"), - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Show executions"), - html.A( - html.Class("btn btn-sm btn-ghost btn-square"), - html.Href( - fmt.Sprintf("/dashboard/executions?database=%s", database.ID), - ), - html.Target("_blank"), - lucide.List(), + html.Class("flex flex-col space-y-1"), + component.OptionsDropdownA( + html.Href( + fmt.Sprintf("/dashboard/executions?database=%s", database.ID), ), + html.Target("_blank"), + lucide.List(), + component.SpanText("Show executions"), ), editDatabaseButton(database), - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Test connection"), - html.Button( - htmx.HxPost("/dashboard/databases/"+database.ID.String()+"/test"), - htmx.HxDisabledELT("this"), - html.Class("btn btn-neutral btn-square btn-ghost btn-sm"), - lucide.DatabaseZap(), - ), + component.OptionsDropdownButton( + htmx.HxPost("/dashboard/databases/"+database.ID.String()+"/test"), + htmx.HxDisabledELT("this"), + lucide.DatabaseZap(), + component.SpanText("Test connection"), ), deleteDatabaseButton(database.ID), ), - ), + )), html.Td( html.Div( html.Class("flex items-center space-x-2"), diff --git a/internal/view/web/dashboard/destinations/delete_destination.go b/internal/view/web/dashboard/destinations/delete_destination.go index 683301b..8306fc8 100644 --- a/internal/view/web/dashboard/destinations/delete_destination.go +++ b/internal/view/web/dashboard/destinations/delete_destination.go @@ -2,11 +2,11 @@ package destinations import ( lucide "github.com/eduardolat/gomponents-lucide" + "github.com/eduardolat/pgbackweb/internal/view/web/component" "github.com/eduardolat/pgbackweb/internal/view/web/htmx" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/maragudk/gomponents" - "github.com/maragudk/gomponents/html" ) func (h *handlers) deleteDestinationHandler(c echo.Context) error { @@ -26,14 +26,10 @@ func (h *handlers) deleteDestinationHandler(c echo.Context) error { } func deleteDestinationButton(destinationID uuid.UUID) gomponents.Node { - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Delete destination"), - html.Button( - htmx.HxDelete("/dashboard/destinations/"+destinationID.String()), - htmx.HxConfirm("Are you sure you want to delete this destination?"), - html.Class("btn btn-error btn-square btn-sm btn-ghost"), - lucide.Trash(), - ), + return component.OptionsDropdownButton( + htmx.HxDelete("/dashboard/destinations/"+destinationID.String()), + htmx.HxConfirm("Are you sure you want to delete this destination?"), + lucide.Trash(), + component.SpanText("Delete destination"), ) } diff --git a/internal/view/web/dashboard/destinations/edit_destination.go b/internal/view/web/dashboard/destinations/edit_destination.go index be78a38..4706d5a 100644 --- a/internal/view/web/dashboard/destinations/edit_destination.go +++ b/internal/view/web/dashboard/destinations/edit_destination.go @@ -177,19 +177,12 @@ func editDestinationButton( }, }) - button := html.Button( - mo.OpenerAttr, - html.Class("btn btn-neutral btn-sm btn-square btn-ghost"), - lucide.Pencil(), - ) - return html.Div( - html.Class("inline-block"), mo.HTML, - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Edit destination"), - button, + component.OptionsDropdownButton( + mo.OpenerAttr, + lucide.Pencil(), + component.SpanText("Edit destination"), ), ) } diff --git a/internal/view/web/dashboard/destinations/index.go b/internal/view/web/dashboard/destinations/index.go index ddc0ae5..1bc6b6f 100644 --- a/internal/view/web/dashboard/destinations/index.go +++ b/internal/view/web/dashboard/destinations/index.go @@ -44,7 +44,7 @@ func indexPage(reqCtx reqctx.Ctx) gomponents.Node { html.Class("table text-nowrap"), html.THead( html.Tr( - html.Th(component.SpanText("Actions")), + html.Th(html.Class("w-1")), html.Th(component.SpanText("Name")), html.Th(component.SpanText("Bucket name")), html.Th(component.SpanText("Endpoint")), diff --git a/internal/view/web/dashboard/destinations/list_destinations.go b/internal/view/web/dashboard/destinations/list_destinations.go index 60337bf..22d3750 100644 --- a/internal/view/web/dashboard/destinations/list_destinations.go +++ b/internal/view/web/dashboard/destinations/list_destinations.go @@ -60,36 +60,24 @@ func listDestinations( trs := []gomponents.Node{} for _, destination := range destinations { trs = append(trs, html.Tr( - html.Td( - html.Class("w-[40px]"), - html.Div( - html.Class("flex justify-start space-x-1"), - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Show executions"), - html.A( - html.Class("btn btn-sm btn-ghost btn-square"), - html.Href( - fmt.Sprintf("/dashboard/executions?destination=%s", destination.ID), - ), - html.Target("_blank"), - lucide.List(), - ), + html.Td(component.OptionsDropdown( + component.OptionsDropdownA( + html.Href( + fmt.Sprintf("/dashboard/executions?destination=%s", destination.ID), ), - editDestinationButton(destination), - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Test connection"), - html.Button( - htmx.HxPost("/dashboard/destinations/"+destination.ID.String()+"/test"), - htmx.HxDisabledELT("this"), - html.Class("btn btn-neutral btn-square btn-ghost btn-sm"), - lucide.PlugZap(), - ), - ), - deleteDestinationButton(destination.ID), + html.Target("_blank"), + lucide.List(), + component.SpanText("Show executions"), ), - ), + editDestinationButton(destination), + component.OptionsDropdownButton( + htmx.HxPost("/dashboard/destinations/"+destination.ID.String()+"/test"), + htmx.HxDisabledELT("this"), + lucide.PlugZap(), + component.SpanText("Test connection"), + ), + deleteDestinationButton(destination.ID), + )), html.Td( html.Div( html.Class("flex items-center space-x-2"), diff --git a/internal/view/web/dashboard/executions/index.go b/internal/view/web/dashboard/executions/index.go index a2faed4..15cfaed 100644 --- a/internal/view/web/dashboard/executions/index.go +++ b/internal/view/web/dashboard/executions/index.go @@ -48,7 +48,7 @@ func indexPage(reqCtx reqctx.Ctx, queryData execsQueryData) gomponents.Node { html.Class("table text-nowrap"), html.THead( html.Tr( - html.Th(component.SpanText("Actions")), + html.Th(html.Class("w-1")), html.Th(component.SpanText("Status")), html.Th(component.SpanText("Backup")), html.Th(component.SpanText("Database")), diff --git a/internal/view/web/dashboard/executions/list_executions.go b/internal/view/web/dashboard/executions/list_executions.go index a8f1aca..43386a3 100644 --- a/internal/view/web/dashboard/executions/list_executions.go +++ b/internal/view/web/dashboard/executions/list_executions.go @@ -76,14 +76,10 @@ func listExecutions( trs := []gomponents.Node{} for _, execution := range executions { trs = append(trs, html.Tr( - html.Td( - html.Class("w-[50px]"), - html.Div( - html.Class("flex justify-start space-x-1"), - showExecutionButton(execution), - restoreExecutionButton(execution), - ), - ), + html.Td(component.OptionsDropdown( + showExecutionButton(execution), + restoreExecutionButton(execution), + )), html.Td(component.StatusBadge(execution.Status)), html.Td(component.SpanText(execution.BackupName)), html.Td(component.SpanText(execution.DatabaseName)), diff --git a/internal/view/web/dashboard/executions/restore_execution.go b/internal/view/web/dashboard/executions/restore_execution.go index dfccbbf..e2702e3 100644 --- a/internal/view/web/dashboard/executions/restore_execution.go +++ b/internal/view/web/dashboard/executions/restore_execution.go @@ -231,16 +231,12 @@ func restoreExecutionButton(execution dbgen.ExecutionsServicePaginateExecutionsR }, }) - button := html.Button( - mo.OpenerAttr, - html.Class("btn btn-square btn-sm btn-ghost"), - lucide.ArchiveRestore(), - ) - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Restore backup execution"), mo.HTML, - button, + component.OptionsDropdownButton( + mo.OpenerAttr, + lucide.ArchiveRestore(), + component.SpanText("Restore execution"), + ), ) } diff --git a/internal/view/web/dashboard/executions/show_execution.go b/internal/view/web/dashboard/executions/show_execution.go index ec4a218..c1eb4a9 100644 --- a/internal/view/web/dashboard/executions/show_execution.go +++ b/internal/view/web/dashboard/executions/show_execution.go @@ -134,16 +134,12 @@ func showExecutionButton( }, }) - button := html.Button( - mo.OpenerAttr, - html.Class("btn btn-square btn-sm btn-ghost"), - lucide.Eye(), - ) - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Show details"), mo.HTML, - button, + component.OptionsDropdownButton( + mo.OpenerAttr, + lucide.Eye(), + component.SpanText("Show details"), + ), ) } diff --git a/internal/view/web/dashboard/restorations/index.go b/internal/view/web/dashboard/restorations/index.go index dc87075..e27d074 100644 --- a/internal/view/web/dashboard/restorations/index.go +++ b/internal/view/web/dashboard/restorations/index.go @@ -47,7 +47,7 @@ func indexPage(reqCtx reqctx.Ctx, queryData resQueryData) gomponents.Node { html.Class("table text-nowrap"), html.THead( html.Tr( - html.Th(component.SpanText("Actions")), + html.Th(html.Class("w-1")), html.Th(component.SpanText("Status")), html.Th(component.SpanText("Backup")), html.Th(component.SpanText("Database")), diff --git a/internal/view/web/dashboard/restorations/list_restorations.go b/internal/view/web/dashboard/restorations/list_restorations.go index 5520436..9862a97 100644 --- a/internal/view/web/dashboard/restorations/list_restorations.go +++ b/internal/view/web/dashboard/restorations/list_restorations.go @@ -73,11 +73,7 @@ func listRestorations( for _, restoration := range restorations { trs = append(trs, html.Tr( html.Td( - html.Class("w-[50px]"), - html.Div( - html.Class("flex justify-start space-x-1"), - showRestorationButton(restoration), - ), + showRestorationButton(restoration), ), html.Td(component.StatusBadge(restoration.Status)), html.Td(component.SpanText(restoration.BackupName)), diff --git a/internal/view/web/dashboard/webhooks/delete_webhook.go b/internal/view/web/dashboard/webhooks/delete_webhook.go index 3c4987e..391f54c 100644 --- a/internal/view/web/dashboard/webhooks/delete_webhook.go +++ b/internal/view/web/dashboard/webhooks/delete_webhook.go @@ -2,11 +2,11 @@ package webhooks import ( lucide "github.com/eduardolat/gomponents-lucide" + "github.com/eduardolat/pgbackweb/internal/view/web/component" "github.com/eduardolat/pgbackweb/internal/view/web/htmx" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/maragudk/gomponents" - "github.com/maragudk/gomponents/html" ) func (h *handlers) deleteWebhookHandler(c echo.Context) error { @@ -25,14 +25,10 @@ func (h *handlers) deleteWebhookHandler(c echo.Context) error { } func deleteWebhookButton(webhookID uuid.UUID) gomponents.Node { - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Delete webhook"), - html.Button( - htmx.HxDelete("/dashboard/webhooks/"+webhookID.String()), - htmx.HxConfirm("Are you sure you want to delete this webhook?"), - html.Class("btn btn-error btn-square btn-sm btn-ghost"), - lucide.Trash(), - ), + return component.OptionsDropdownButton( + htmx.HxDelete("/dashboard/webhooks/"+webhookID.String()), + htmx.HxConfirm("Are you sure you want to delete this webhook?"), + lucide.Trash(), + component.SpanText("Delete webhook"), ) } diff --git a/internal/view/web/dashboard/webhooks/edit_webhook.go b/internal/view/web/dashboard/webhooks/edit_webhook.go index f084457..5b77c14 100644 --- a/internal/view/web/dashboard/webhooks/edit_webhook.go +++ b/internal/view/web/dashboard/webhooks/edit_webhook.go @@ -135,19 +135,12 @@ func editWebhookButton(webhookID uuid.UUID) gomponents.Node { }, }) - button := html.Button( - mo.OpenerAttr, - html.Class("btn btn-neutral btn-sm btn-square btn-ghost"), - lucide.Pencil(), - ) - return html.Div( - html.Class("inline-block"), mo.HTML, - html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Edit webhook"), - button, + component.OptionsDropdownButton( + mo.OpenerAttr, + lucide.Pencil(), + component.SpanText("Edit webhook"), ), ) } diff --git a/internal/view/web/dashboard/webhooks/index.go b/internal/view/web/dashboard/webhooks/index.go index bc69558..33b7c10 100644 --- a/internal/view/web/dashboard/webhooks/index.go +++ b/internal/view/web/dashboard/webhooks/index.go @@ -37,7 +37,7 @@ func indexPage(reqCtx reqctx.Ctx) gomponents.Node { html.Class("table text-nowrap"), html.THead( html.Tr( - html.Th(component.SpanText("Actions")), + html.Th(html.Class("w-1")), html.Th(component.SpanText("Name")), html.Th(component.SpanText("Event type")), html.Th(component.SpanText("Targets")), diff --git a/internal/view/web/dashboard/webhooks/list_webhooks.go b/internal/view/web/dashboard/webhooks/list_webhooks.go index 28e2dd4..1793717 100644 --- a/internal/view/web/dashboard/webhooks/list_webhooks.go +++ b/internal/view/web/dashboard/webhooks/list_webhooks.go @@ -60,16 +60,12 @@ func listWebhooks( trs := []gomponents.Node{} for _, whook := range whooks { trs = append(trs, html.Tr( - html.Td( - html.Class("w-[40px]"), - html.Div( - html.Class("flex justify-start space-x-1"), - webhookExecutionsButton(whook.ID), - runWebhookButton(whook.ID), - editWebhookButton(whook.ID), - deleteWebhookButton(whook.ID), - ), - ), + html.Td(component.OptionsDropdown( + webhookExecutionsButton(whook.ID), + runWebhookButton(whook.ID), + editWebhookButton(whook.ID), + deleteWebhookButton(whook.ID), + )), html.Td( html.Div( html.Class("flex items-center space-x-2"), diff --git a/internal/view/web/dashboard/webhooks/run_webhook.go b/internal/view/web/dashboard/webhooks/run_webhook.go index 2a64ed1..2756c5a 100644 --- a/internal/view/web/dashboard/webhooks/run_webhook.go +++ b/internal/view/web/dashboard/webhooks/run_webhook.go @@ -5,11 +5,11 @@ import ( lucide "github.com/eduardolat/gomponents-lucide" "github.com/eduardolat/pgbackweb/internal/logger" + "github.com/eduardolat/pgbackweb/internal/view/web/component" "github.com/eduardolat/pgbackweb/internal/view/web/htmx" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/maragudk/gomponents" - "github.com/maragudk/gomponents/html" ) func (h *handlers) runWebhookHandler(c echo.Context) error { @@ -41,14 +41,10 @@ func (h *handlers) runWebhookHandler(c echo.Context) error { } func runWebhookButton(webhookID uuid.UUID) gomponents.Node { - return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Run webhook now"), - html.Button( - htmx.HxPost("/dashboard/webhooks/"+webhookID.String()+"/run"), - htmx.HxDisabledELT("this"), - html.Class("btn btn-sm btn-ghost btn-square"), - lucide.Zap(), - ), + return component.OptionsDropdownButton( + htmx.HxPost("/dashboard/webhooks/"+webhookID.String()+"/run"), + htmx.HxDisabledELT("this"), + lucide.Zap(), + component.SpanText("Run webhook now"), ) } diff --git a/internal/view/web/dashboard/webhooks/webhook_executions.go b/internal/view/web/dashboard/webhooks/webhook_executions.go index 2076928..8388e75 100644 --- a/internal/view/web/dashboard/webhooks/webhook_executions.go +++ b/internal/view/web/dashboard/webhooks/webhook_executions.go @@ -74,12 +74,9 @@ func webhookExecutionsList( trs = append(trs, html.Tr( html.Td( - html.Div( - html.Class("flex items-center space-x-2"), - webhookExecutionDetailsButton(exec, duration), - component.SpanText(fmt.Sprintf("%d", exec.ResStatus.Int16)), - ), + webhookExecutionDetailsButton(exec, duration), ), + html.Td(component.SpanText(fmt.Sprintf("%d", exec.ResStatus.Int16))), html.Td(component.SpanText(exec.ReqMethod.String)), html.Td(component.SpanText(duration.String())), html.Td(component.SpanText( @@ -233,7 +230,7 @@ func webhookExecutionDetailsButton( return html.Div( html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Show webhook execution details"), + html.Data("tip", "More details"), mo.HTML, html.Button( html.Class("btn btn-error btn-square btn-sm btn-ghost"), @@ -252,12 +249,8 @@ func webhookExecutionsButton(webhookID uuid.UUID) gomponents.Node { html.Class("table"), html.THead( html.Tr( - html.Th( - html.Div( - html.Class("ml-10"), - component.SpanText("Status"), - ), - ), + html.Th(html.Class("w-1")), + html.Th(component.SpanText("Status")), html.Th(component.SpanText("Method")), html.Th(component.SpanText("Duration")), html.Th(component.SpanText("Date")), @@ -279,13 +272,11 @@ func webhookExecutionsButton(webhookID uuid.UUID) gomponents.Node { }) return html.Div( - html.Class("inline-block tooltip tooltip-right"), - html.Data("tip", "Show webhook executions"), mo.HTML, - html.Button( - html.Class("btn btn-error btn-square btn-sm btn-ghost"), - lucide.List(), + component.OptionsDropdownButton( mo.OpenerAttr, + lucide.List(), + component.SpanText("Show executions"), ), ) }