diff --git a/backend/pkg/api/data_access/dummy.go b/backend/pkg/api/data_access/dummy.go index d40236929..b3743d335 100644 --- a/backend/pkg/api/data_access/dummy.go +++ b/backend/pkg/api/data_access/dummy.go @@ -486,6 +486,11 @@ func (d *DummyService) UpdateNotificationSettingsPairedDevice(ctx context.Contex func (d *DummyService) DeleteNotificationSettingsPairedDevice(ctx context.Context, userId uint64, pairedDeviceId string) error { return nil } + +func (d *DummyService) UpdateNotificationSettingsClients(ctx context.Context, userId uint64, clientId uint64, IsSubscribed bool) (*t.NotificationSettingsClient, error) { + return getDummyStruct[t.NotificationSettingsClient]() +} + func (d *DummyService) GetNotificationSettingsDashboards(ctx context.Context, userId uint64, cursor string, colSort t.Sort[enums.NotificationSettingsDashboardColumn], search string, limit uint64) ([]t.NotificationSettingsDashboardsTableRow, *t.Paging, error) { r, p, err := getDummyWithPaging[t.NotificationSettingsDashboardsTableRow]() for i, n := range r { diff --git a/backend/pkg/api/data_access/notifications.go b/backend/pkg/api/data_access/notifications.go index 7e5ae9d50..d8e637244 100644 --- a/backend/pkg/api/data_access/notifications.go +++ b/backend/pkg/api/data_access/notifications.go @@ -25,6 +25,7 @@ type NotificationsRepository interface { UpdateNotificationSettingsNetworks(ctx context.Context, userId uint64, chainId uint64, settings t.NotificationSettingsNetwork) error UpdateNotificationSettingsPairedDevice(ctx context.Context, userId uint64, pairedDeviceId string, name string, IsNotificationsEnabled bool) error DeleteNotificationSettingsPairedDevice(ctx context.Context, userId uint64, pairedDeviceId string) error + UpdateNotificationSettingsClients(ctx context.Context, userId uint64, clientId uint64, IsSubscribed bool) (*t.NotificationSettingsClient, error) GetNotificationSettingsDashboards(ctx context.Context, userId uint64, cursor string, colSort t.Sort[enums.NotificationSettingsDashboardColumn], search string, limit uint64) ([]t.NotificationSettingsDashboardsTableRow, *t.Paging, error) UpdateNotificationSettingsValidatorDashboard(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, settings t.NotificationSettingsValidatorDashboard) error UpdateNotificationSettingsAccountDashboard(ctx context.Context, dashboardId t.VDBIdPrimary, groupId uint64, settings t.NotificationSettingsAccountDashboard) error @@ -72,6 +73,9 @@ func (d *DataAccessService) UpdateNotificationSettingsPairedDevice(ctx context.C func (d *DataAccessService) DeleteNotificationSettingsPairedDevice(ctx context.Context, userId uint64, pairedDeviceId string) error { return d.dummy.DeleteNotificationSettingsPairedDevice(ctx, userId, pairedDeviceId) } +func (d *DataAccessService) UpdateNotificationSettingsClients(ctx context.Context, userId uint64, clientId uint64, IsSubscribed bool) (*t.NotificationSettingsClient, error) { + return d.dummy.UpdateNotificationSettingsClients(ctx, userId, clientId, IsSubscribed) +} func (d *DataAccessService) GetNotificationSettingsDashboards(ctx context.Context, userId uint64, cursor string, colSort t.Sort[enums.NotificationSettingsDashboardColumn], search string, limit uint64) ([]t.NotificationSettingsDashboardsTableRow, *t.Paging, error) { return d.dummy.GetNotificationSettingsDashboards(ctx, userId, cursor, colSort, search, limit) } diff --git a/backend/pkg/api/handlers/internal.go b/backend/pkg/api/handlers/internal.go index 78d998856..bf3e347fe 100644 --- a/backend/pkg/api/handlers/internal.go +++ b/backend/pkg/api/handlers/internal.go @@ -609,6 +609,10 @@ func (h *HandlerService) InternalDeleteUserNotificationSettingsPairedDevices(w h h.PublicDeleteUserNotificationSettingsPairedDevices(w, r) } +func (h *HandlerService) InternalPutUserNotificationSettingsClient(w http.ResponseWriter, r *http.Request) { + h.PublicPutUserNotificationSettingsClient(w, r) +} + func (h *HandlerService) InternalGetUserNotificationSettingsDashboards(w http.ResponseWriter, r *http.Request) { h.PublicGetUserNotificationSettingsDashboards(w, r) } diff --git a/backend/pkg/api/handlers/public.go b/backend/pkg/api/handlers/public.go index c7364d041..53e20447f 100644 --- a/backend/pkg/api/handlers/public.go +++ b/backend/pkg/api/handlers/public.go @@ -269,7 +269,7 @@ func (h *HandlerService) PublicGetValidatorDashboard(w http.ResponseWriter, r *h // @Security ApiKeyInHeader || ApiKeyInQuery // @Tags Validator Dashboard Management // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Success 204 "Dashboard deleted successfully." // @Failure 400 {object} types.ApiErrorResponse "Bad Request" // @Router /validator-dashboards/{dashboard_id} [delete] @@ -295,7 +295,7 @@ func (h *HandlerService) PublicDeleteValidatorDashboard(w http.ResponseWriter, r // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Param request body handlers.PublicPutValidatorDashboardName.request true "request" // @Success 200 {object} types.ApiDataResponse[types.VDBPostReturnData] // @Failure 400 {object} types.ApiErrorResponse @@ -334,7 +334,7 @@ func (h *HandlerService) PublicPutValidatorDashboardName(w http.ResponseWriter, // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Param request body handlers.PublicPostValidatorDashboardGroups.request true "request" // @Success 201 {object} types.ApiDataResponse[types.VDBPostCreateGroupData] // @Failure 400 {object} types.ApiErrorResponse @@ -398,8 +398,8 @@ func (h *HandlerService) PublicPostValidatorDashboardGroups(w http.ResponseWrite // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." +// @Param dashboard_id path integer true "The ID of the dashboard." +// @Param group_id path integer true "The ID of the group." // @Param request body handlers.PublicPutValidatorDashboardGroups.request true "request" // @Success 200 {object} types.ApiDataResponse[types.VDBPostCreateGroupData] // @Failure 400 {object} types.ApiErrorResponse @@ -451,8 +451,8 @@ func (h *HandlerService) PublicPutValidatorDashboardGroups(w http.ResponseWriter // @Security ApiKeyInHeader || ApiKeyInQuery // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." +// @Param dashboard_id path integer true "The ID of the dashboard." +// @Param group_id path integer true "The ID of the group." // @Success 204 "Group deleted successfully." // @Failure 400 {object} types.ApiErrorResponse // @Router /validator-dashboards/{dashboard_id}/groups/{group_id} [delete] @@ -494,7 +494,7 @@ func (h *HandlerService) PublicDeleteValidatorDashboardGroup(w http.ResponseWrit // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Param request body handlers.PublicPostValidatorDashboardValidators.request true "`group_id`: (optional) Provide a single group id, to which all validators get added to. If omitted, the default group will be used.

To add validators or update their group, only one of the following fields can be set:" // @Success 201 {object} types.ApiDataResponse[[]types.VDBPostValidatorsData] "Returns a list of added validators." // @Failure 400 {object} types.ApiErrorResponse @@ -640,7 +640,7 @@ func (h *HandlerService) PublicPostValidatorDashboardValidators(w http.ResponseW // @Tags Validator Dashboard // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id query string false "The ID of the group." +// @Param group_id query integer false "The ID of the group." // @Param limit query string false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." Enums(index, public_key, balance, status, withdrawal_credentials) // @Param search query string false "Search for Address, ENS." @@ -681,7 +681,7 @@ func (h *HandlerService) PublicGetValidatorDashboardValidators(w http.ResponseWr // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Param request body handlers.PublicDeleteValidatorDashboardValidators.request true "`validators`: Provide an array of validator indices or public keys that should get removed from the dashboard." // @Success 204 "Validators removed successfully." // @Failure 400 {object} types.ApiErrorResponse @@ -723,7 +723,7 @@ func (h *HandlerService) PublicDeleteValidatorDashboardValidators(w http.Respons // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Param request body handlers.PublicPostValidatorDashboardPublicIds.request true "`name`: Provide a public name for the dashboard
`share_settings`:" // @Success 201 {object} types.ApiDataResponse[types.VDBPublicId] // @Failure 400 {object} types.ApiErrorResponse @@ -777,7 +777,7 @@ func (h *HandlerService) PublicPostValidatorDashboardPublicIds(w http.ResponseWr // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Param public_id path string true "The ID of the public ID." // @Param request body handlers.PublicPutValidatorDashboardPublicId.request true "`name`: Provide a public name for the dashboard
`share_settings`:" // @Success 200 {object} types.ApiDataResponse[types.VDBPublicId] @@ -832,7 +832,7 @@ func (h *HandlerService) PublicPutValidatorDashboardPublicId(w http.ResponseWrit // @Security ApiKeyInHeader || ApiKeyInQuery // @Tags Validator Dashboard Management // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." +// @Param dashboard_id path integer true "The ID of the dashboard." // @Param public_id path string true "The ID of the public ID." // @Success 204 "Public ID deleted successfully." // @Failure 400 {object} types.ApiErrorResponse @@ -872,8 +872,8 @@ func (h *HandlerService) PublicDeleteValidatorDashboardPublicId(w http.ResponseW // @Tags Validator Dashboard Management // @Accept json // @Produce json -// @Param dashboard_id path string true "The ID of the dashboard." -// @Param request body handlers.PublicPutValidatorDashboardArchiving.request true "request" +// @Param dashboard_id path integer true "The ID of the dashboard." +// @Param request body handlers.PublicPutValidatorDashboardArchiving.request true "`is_archived`: Set to `true` to archive the dashboard, or `false` to unarchive it." // @Success 200 {object} types.ApiDataResponse[types.VDBPostArchivingReturnData] // @Failure 400 {object} types.ApiErrorResponse // @Failure 409 {object} types.ApiErrorResponse "Conflict. The request could not be performed by the server because the authenticated user has already reached their subscription limit." @@ -1052,7 +1052,7 @@ func (h *HandlerService) PublicGetValidatorDashboardSummary(w http.ResponseWrite // @Tags Validator Dashboard // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." +// @Param group_id path integer true "The ID of the group." // @Param period query string true "Time period to get data for." Enums(all_time, last_30d, last_7d, last_24h, last_1h) // @Param modes query string false "Provide a comma separated list of protocol modes which should be respected for validator calculations. Possible values are `rocket_pool``." // @Success 200 {object} types.GetValidatorDashboardGroupSummaryResponse @@ -1151,7 +1151,7 @@ func (h *HandlerService) PublicGetValidatorDashboardSummaryChart(w http.Response // @Tags Validator Dashboard // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id query string false "The ID of the group." +// @Param group_id query integer false "The ID of the group." // @Param duty query string false "Validator duty to get data for." Enums(none, sync, slashed, proposal) Default(none) // @Param period query string true "Time period to get data for." Enums(all_time, last_30d, last_7d, last_24h, last_1h) // @Success 200 {object} types.GetValidatorDashboardSummaryValidatorsResponse @@ -1255,8 +1255,8 @@ func (h *HandlerService) PublicGetValidatorDashboardRewards(w http.ResponseWrite // @Tags Validator Dashboard // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." -// @Param epoch path string true "The epoch to get data for." +// @Param group_id path integer true "The ID of the group." +// @Param epoch path integer true "The epoch to get data for." // @Param modes query string false "Provide a comma separated list of protocol modes which should be respected for validator calculations. Possible values are `rocket_pool``." // @Success 200 {object} types.GetValidatorDashboardGroupRewardsResponse // @Failure 400 {object} types.ApiErrorResponse @@ -1331,8 +1331,8 @@ func (h *HandlerService) PublicGetValidatorDashboardRewardsChart(w http.Response // @Tags Validator Dashboard // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param epoch path string true "The epoch to get data for." -// @Param group_id query string false "The ID of the group." +// @Param epoch path integer true "The epoch to get data for." +// @Param group_id query integer false "The ID of the group." // @Param cursor query string false "Return data for the given cursor value. Pass the `paging.next_cursor`` value of the previous response to navigate to forward, or pass the `paging.prev_cursor`` value of the previous response to navigate to backward." // @Param limit query string false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." Enums(validator, reward) @@ -1469,8 +1469,8 @@ func (h *HandlerService) PublicGetValidatorDashboardHeatmap(w http.ResponseWrite // @Tags Validator Dashboard // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." -// @Param timestamp path string true "The timestamp to get data for." +// @Param group_id path integer true "The ID of the group." +// @Param timestamp path integer true "The timestamp to get data for." // @Param modes query string false "Provide a comma separated list of protocol modes which should be respected for validator calculations. Possible values are `rocket_pool``." // @Param aggregation query string false "Aggregation type to get data for." Enums(epoch, hourly, daily, weekly) Default(hourly) // @Success 200 {object} types.GetValidatorDashboardGroupHeatmapResponse @@ -1912,7 +1912,7 @@ func (h *HandlerService) PublicGetUserNotifications(w http.ResponseWriter, r *ht // @Produce json // @Param networks query string false "If set, results will be filtered to only include networks given. Provide a comma separated list." // @Param cursor query string false "Return data for the given cursor value. Pass the `paging.next_cursor`` value of the previous response to navigate to forward, or pass the `paging.prev_cursor`` value of the previous response to navigate to backward." -// @Param limit query string false "The maximum number of results that may be returned." +// @Param limit query integer false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." " Enums(chain_id, timestamp, dashboard_id) // @Param search query string false "Search for Dashboard, Group" // @Success 200 {object} types.InternalGetUserNotificationDashboardsResponse @@ -1940,7 +1940,7 @@ func (h *HandlerService) PublicGetUserNotificationDashboards(w http.ResponseWrit } response := types.InternalGetUserNotificationDashboardsResponse{ Data: data, - Paging: *paging, + Paging: *paging, // @Param epoch path strings } returnOk(w, r, response) } @@ -1952,8 +1952,8 @@ func (h *HandlerService) PublicGetUserNotificationDashboards(w http.ResponseWrit // @Tags Notifications // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." -// @Param epoch path string true "The epoch of the notification." +// @Param group_id path integer true "The ID of the group." +// @Param epoch path integer true "The epoch of the notification." // @Success 200 {object} types.InternalGetUserNotificationsValidatorDashboardResponse // @Failure 400 {object} types.ApiErrorResponse // @Router /users/me/notifications/validator-dashboards/{dashboard_id}/groups/{group_id}/epochs/{epoch} [get] @@ -1985,8 +1985,8 @@ func (h *HandlerService) PublicGetUserNotificationsValidatorDashboard(w http.Res // @Tags Notifications // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." -// @Param epoch path string true "The epoch of the notification." +// @Param group_id path integer true "The ID of the group." +// @Param epoch path integer true "The epoch of the notification." // @Success 200 {object} types.InternalGetUserNotificationsAccountDashboardResponse // @Failure 400 {object} types.ApiErrorResponse // @Router /users/me/notifications/account-dashboards/{dashboard_id}/groups/{group_id}/epochs/{epoch} [get] @@ -2018,7 +2018,7 @@ func (h *HandlerService) PublicGetUserNotificationsAccountDashboard(w http.Respo // @Tags Notifications // @Produce json // @Param cursor query string false "Return data for the given cursor value. Pass the `paging.next_cursor`` value of the previous response to navigate to forward, or pass the `paging.prev_cursor`` value of the previous response to navigate to backward." -// @Param limit query string false "The maximum number of results that may be returned." +// @Param limit query integer false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." Enums(machine_name, threshold, event_type, timestamp) // @Param search query string false "Search for Machine" // @Success 200 {object} types.InternalGetUserNotificationMachinesResponse @@ -2057,7 +2057,7 @@ func (h *HandlerService) PublicGetUserNotificationMachines(w http.ResponseWriter // @Tags Notifications // @Produce json // @Param cursor query string false "Return data for the given cursor value. Pass the `paging.next_cursor`` value of the previous response to navigate to forward, or pass the `paging.prev_cursor`` value of the previous response to navigate to backward." -// @Param limit query string false "The maximum number of results that may be returned." +// @Param limit query integer false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." Enums(client_name, timestamp) // @Param search query string false "Search for Client" // @Success 200 {object} types.InternalGetUserNotificationClientsResponse @@ -2096,7 +2096,7 @@ func (h *HandlerService) PublicGetUserNotificationClients(w http.ResponseWriter, // @Tags Notifications // @Produce json // @Param cursor query string false "Return data for the given cursor value. Pass the `paging.next_cursor`` value of the previous response to navigate to forward, or pass the `paging.prev_cursor`` value of the previous response to navigate to backward." -// @Param limit query string false "The maximum number of results that may be returned." +// @Param limit query integer false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." Enums(timestamp, event_type, node_address) // @Param search query string false "Search for TODO" // @Success 200 {object} types.InternalGetUserNotificationRocketPoolResponse @@ -2135,7 +2135,7 @@ func (h *HandlerService) PublicGetUserNotificationRocketPool(w http.ResponseWrit // @Tags Notifications // @Produce json // @Param cursor query string false "Return data for the given cursor value. Pass the `paging.next_cursor`` value of the previous response to navigate to forward, or pass the `paging.prev_cursor`` value of the previous response to navigate to backward." -// @Param limit query string false "The maximum number of results that may be returned." +// @Param limit query integer false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." Enums(timestamp, event_type) // @Param search query string false "Search for TODO" // @Success 200 {object} types.InternalGetUserNotificationNetworksResponse @@ -2199,7 +2199,7 @@ func (h *HandlerService) PublicGetUserNotificationSettings(w http.ResponseWriter // @Tags Notification Settings // @Accept json // @Produce json -// @Param request body types.NotificationSettingsGeneral true "Notification settings" +// @Param request body types.NotificationSettingsGeneral true "Description TODO" // @Success 200 {object} types.InternalPutUserNotificationSettingsGeneralResponse // @Failure 400 {object} types.ApiErrorResponse // @Router /users/me/notifications/settings/general [put] @@ -2220,7 +2220,6 @@ func (h *HandlerService) PublicPutUserNotificationSettingsGeneral(w http.Respons checkMinMax(&v, req.MachineMemoryUsageThreshold, 0, 1, "machine_memory_usage_threshold") checkMinMax(&v, req.RocketPoolMaxCollateralThreshold, 0, 1, "rocket_pool_max_collateral_threshold") checkMinMax(&v, req.RocketPoolMinCollateralThreshold, 0, 1, "rocket_pool_min_collateral_threshold") - // TODO: check validity of clients if v.hasErrors() { handleErr(w, r, v) return @@ -2244,7 +2243,7 @@ func (h *HandlerService) PublicPutUserNotificationSettingsGeneral(w http.Respons // @Accept json // @Produce json // @Param network path string true "The networks name or chain ID." -// @Param request body types.NotificationSettingsNetwork true "Notification settings" +// @Param request body types.NotificationSettingsNetwork true "Description Todo" // @Success 200 {object} types.InternalPutUserNotificationSettingsNetworksResponse // @Failure 400 {object} types.ApiErrorResponse // @Router /users/me/notifications/settings/networks/{network} [put] @@ -2289,7 +2288,7 @@ func (h *HandlerService) PublicPutUserNotificationSettingsNetworks(w http.Respon // @Accept json // @Produce json // @Param paired_device_id path string true "The paired device ID." -// @Param request body handlers.PublicPutUserNotificationSettingsPairedDevices.request true "Notification settings" +// @Param request body handlers.PublicPutUserNotificationSettingsPairedDevices.request true "Description TODO" // @Success 200 {object} types.InternalPutUserNotificationSettingsPairedDevicesResponse // @Failure 400 {object} types.ApiErrorResponse // @Router /users/me/notifications/settings/paired-devices/{paired_device_id} [put] @@ -2364,6 +2363,49 @@ func (h *HandlerService) PublicDeleteUserNotificationSettingsPairedDevices(w htt returnNoContent(w, r) } +// PublicPutUserNotificationSettingsClient godoc +// +// @Description Update client notification settings for the authenticated user. When a client is subscribed, notifications will be sent when a new version is available. +// @Security ApiKeyInHeader || ApiKeyInQuery +// @Tags Notification Settings +// @Accept json +// @Produce json +// @Param client_id path integer true "The ID of the client." +// @Param request body handlers.PublicPutUserNotificationSettingsClient.request true "`is_subscribed`: Set to `true` to subscribe to notifications; set to `false` to unsubscribe." +// @Success 200 {object} types.InternalPutUserNotificationSettingsClientResponse +// @Failure 400 {object} types.ApiErrorResponse +// @Router /users/me/notifications/settings/clients/{client_id} [put] +func (h *HandlerService) PublicPutUserNotificationSettingsClient(w http.ResponseWriter, r *http.Request) { + var v validationError + userId, err := GetUserIdByContext(r) + if err != nil { + handleErr(w, r, err) + return + } + type request struct { + IsSubscribed bool `json:"is_subscribed"` + } + var req request + if err := v.checkBody(&req, r); err != nil { + handleErr(w, r, err) + return + } + clientId := v.checkUint(mux.Vars(r)["client_id"], "client_id") + if v.hasErrors() { + handleErr(w, r, v) + return + } + data, err := h.dai.UpdateNotificationSettingsClients(r.Context(), userId, clientId, req.IsSubscribed) + if err != nil { + handleErr(w, r, err) + return + } + response := types.InternalPutUserNotificationSettingsClientResponse{ + Data: *data, + } + returnOk(w, r, response) +} + // PublicGetUserNotificationSettingsDashboards godoc // // @Description Get a list of notification settings for the dashboards of the authenticated user. @@ -2371,7 +2413,7 @@ func (h *HandlerService) PublicDeleteUserNotificationSettingsPairedDevices(w htt // @Tags Notification Settings // @Produce json // @Param cursor query string false "Return data for the given cursor value. Pass the `paging.next_cursor`` value of the previous response to navigate to forward, or pass the `paging.prev_cursor`` value of the previous response to navigate to backward." -// @Param limit query string false "The maximum number of results that may be returned." +// @Param limit query integer false "The maximum number of results that may be returned." // @Param sort query string false "The field you want to sort by. Append with `:desc` for descending order." Enums (dashboard_id, group_name) // @Param search query string false "Search for Dashboard, Group" // @Success 200 {object} types.InternalGetUserNotificationSettingsDashboardsResponse @@ -2411,7 +2453,7 @@ func (h *HandlerService) PublicGetUserNotificationSettingsDashboards(w http.Resp // @Accept json // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." +// @Param group_id path integer true "The ID of the group." // @Param request body types.NotificationSettingsValidatorDashboard true "Notification settings" // @Success 200 {object} types.InternalPutUserNotificationSettingsValidatorDashboardResponse // @Failure 400 {object} types.ApiErrorResponse @@ -2450,7 +2492,7 @@ func (h *HandlerService) PublicPutUserNotificationSettingsValidatorDashboard(w h // @Accept json // @Produce json // @Param dashboard_id path string true "The ID of the dashboard." -// @Param group_id path string true "The ID of the group." +// @Param group_id path integer true "The ID of the group." // @Param request body handlers.PublicPutUserNotificationSettingsAccountDashboard.request true "Notification settings" // @Success 200 {object} types.InternalPutUserNotificationSettingsAccountDashboardResponse // @Failure 400 {object} types.ApiErrorResponse diff --git a/backend/pkg/api/router.go b/backend/pkg/api/router.go index c9202848a..e15ad87cb 100644 --- a/backend/pkg/api/router.go +++ b/backend/pkg/api/router.go @@ -331,6 +331,7 @@ func addNotificationRoutes(hs *handlers.HandlerService, publicRouter, internalRo {http.MethodPut, "/settings/networks/{network}", hs.PublicPutUserNotificationSettingsNetworks, hs.InternalPutUserNotificationSettingsNetworks}, {http.MethodPut, "/settings/paired-devices/{paired_device_id}", hs.PublicPutUserNotificationSettingsPairedDevices, hs.InternalPutUserNotificationSettingsPairedDevices}, {http.MethodDelete, "/settings/paired-devices/{paired_device_id}", hs.PublicDeleteUserNotificationSettingsPairedDevices, hs.InternalDeleteUserNotificationSettingsPairedDevices}, + {http.MethodPut, "/settings/clients/{client_id}", hs.PublicPutUserNotificationSettingsClient, hs.InternalPutUserNotificationSettingsClient}, {http.MethodGet, "/settings/dashboards", hs.PublicGetUserNotificationSettingsDashboards, hs.InternalGetUserNotificationSettingsDashboards}, {http.MethodPost, "/test-email", hs.PublicPostUserNotificationsTestEmail, hs.InternalPostUserNotificationsTestEmail}, {http.MethodPost, "/test-push", hs.PublicPostUserNotificationsTestPush, hs.InternalPostUserNotificationsTestPush}, diff --git a/backend/pkg/api/types/notifications.go b/backend/pkg/api/types/notifications.go index cd75f21fe..183164040 100644 --- a/backend/pkg/api/types/notifications.go +++ b/backend/pkg/api/types/notifications.go @@ -163,6 +163,15 @@ type NotificationPairedDevice struct { } type InternalPutUserNotificationSettingsPairedDevicesResponse ApiDataResponse[NotificationPairedDevice] +type NotificationSettingsClient struct { + Id uint64 `json:"id"` + Name string `json:"name"` + Category string `json:"category"` + IsSubscribed bool `json:"is_subscribed"` +} + +type InternalPutUserNotificationSettingsClientResponse ApiDataResponse[NotificationSettingsClient] + type NotificationSettingsGeneral struct { DoNotDisturbTimestamp int64 `json:"do_not_disturb_timestamp"` // notifications are disabled until this timestamp IsEmailNotificationsEnabled bool `json:"is_email_notifications_enabled"` @@ -176,18 +185,18 @@ type NotificationSettingsGeneral struct { IsMachineMemoryUsageSubscribed bool `json:"is_machine_memory_usage_subscribed"` MachineMemoryUsageThreshold float64 `json:"machine_memory_usage_threshold" faker:"boundary_start=0, boundary_end=1"` - SubscribedClients []string `json:"subscribed_clients"` - IsRocketPoolNewRewardRoundSubscribed bool `json:"is_rocket_pool_new_reward_round_subscribed"` - IsRocketPoolMaxCollateralSubscribed bool `json:"is_rocket_pool_max_collateral_subscribed"` - RocketPoolMaxCollateralThreshold float64 `json:"rocket_pool_max_collateral_threshold" faker:"boundary_start=0, boundary_end=1"` - IsRocketPoolMinCollateralSubscribed bool `json:"is_rocket_pool_min_collateral_subscribed"` - RocketPoolMinCollateralThreshold float64 `json:"rocket_pool_min_collateral_threshold" faker:"boundary_start=0, boundary_end=1"` + IsRocketPoolNewRewardRoundSubscribed bool `json:"is_rocket_pool_new_reward_round_subscribed"` + IsRocketPoolMaxCollateralSubscribed bool `json:"is_rocket_pool_max_collateral_subscribed"` + RocketPoolMaxCollateralThreshold float64 `json:"rocket_pool_max_collateral_threshold" faker:"boundary_start=0, boundary_end=1"` + IsRocketPoolMinCollateralSubscribed bool `json:"is_rocket_pool_min_collateral_subscribed"` + RocketPoolMinCollateralThreshold float64 `json:"rocket_pool_min_collateral_threshold" faker:"boundary_start=0, boundary_end=1"` } type InternalPutUserNotificationSettingsGeneralResponse ApiDataResponse[NotificationSettingsGeneral] type NotificationSettings struct { - GeneralSettings NotificationSettingsGeneral `json:"general_settings"` - Networks []NotificationNetwork `json:"networks"` - PairedDevices []NotificationPairedDevice `json:"paired_devices"` + GeneralSettings NotificationSettingsGeneral `json:"general_settings"` + Networks []NotificationNetwork `json:"networks"` + PairedDevices []NotificationPairedDevice `json:"paired_devices"` + Clients []NotificationSettingsClient `json:"clients"` } type InternalGetUserNotificationSettingsResponse ApiDataResponse[NotificationSettings] diff --git a/frontend/stores/notifications/useNotificationsManagementStore.ts b/frontend/stores/notifications/useNotificationsManagementStore.ts index ad08472d8..2b7c060b7 100644 --- a/frontend/stores/notifications/useNotificationsManagementStore.ts +++ b/frontend/stores/notifications/useNotificationsManagementStore.ts @@ -10,6 +10,7 @@ export const useNotificationsManagementStore = defineStore('notifications-manage const { fetch } = useCustomFetch() const settings = ref( { + clients: [], general_settings: { do_not_disturb_timestamp: 0, is_email_notifications_enabled: false, @@ -26,7 +27,6 @@ export const useNotificationsManagementStore = defineStore('notifications-manage machine_storage_usage_threshold: 0.0, rocket_pool_max_collateral_threshold: 0, rocket_pool_min_collateral_threshold: 0, - subscribed_clients: [], }, networks: [ { chain_id: 0, diff --git a/frontend/types/api/notifications.ts b/frontend/types/api/notifications.ts index 434f93970..0fe772280 100644 --- a/frontend/types/api/notifications.ts +++ b/frontend/types/api/notifications.ts @@ -157,6 +157,13 @@ export interface NotificationPairedDevice { is_notifications_enabled: boolean; } export type InternalPutUserNotificationSettingsPairedDevicesResponse = ApiDataResponse; +export interface NotificationSettingsClient { + id: number /* uint64 */; + name: string; + category: string; + is_subscribed: boolean; +} +export type InternalPutUserNotificationSettingsClientResponse = ApiDataResponse; export interface NotificationSettingsGeneral { do_not_disturb_timestamp: number /* int64 */; // notifications are disabled until this timestamp is_email_notifications_enabled: boolean; @@ -168,7 +175,6 @@ export interface NotificationSettingsGeneral { machine_cpu_usage_threshold: number /* float64 */; is_machine_memory_usage_subscribed: boolean; machine_memory_usage_threshold: number /* float64 */; - subscribed_clients: string[]; is_rocket_pool_new_reward_round_subscribed: boolean; is_rocket_pool_max_collateral_subscribed: boolean; rocket_pool_max_collateral_threshold: number /* float64 */; @@ -180,6 +186,7 @@ export interface NotificationSettings { general_settings: NotificationSettingsGeneral; networks: NotificationNetwork[]; paired_devices: NotificationPairedDevice[]; + clients: NotificationSettingsClient[]; } export type InternalGetUserNotificationSettingsResponse = ApiDataResponse; export interface NotificationSettingsValidatorDashboard {