From ebaaf0a11523fa1edfea8521f531f25a7746980e Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:11:32 +0100 Subject: [PATCH 01/35] refactor(DashboardValidatorSubsetList): rename `component` It is easier to work with components if their name reflect the file path in nuxt. --- frontend/.vscode/settings.json | 1 + ...{ValidatorSubsetList.vue => DashboardValidatorSubsetList.vue} | 0 2 files changed, 1 insertion(+) rename frontend/components/dashboard/validator/subset/{ValidatorSubsetList.vue => DashboardValidatorSubsetList.vue} (100%) diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json index 8be5c62f7..40904a878 100644 --- a/frontend/.vscode/settings.json +++ b/frontend/.vscode/settings.json @@ -16,6 +16,7 @@ "DashboardTableSummaryValue", "DashboardTableValidators", "DashboardValidatorManagmentModal", + "DashboardValidatorSubsetList", "NotificationMachinesTable", "NotificationsClientsTable", "NotificationsDashboardDialogEntity", diff --git a/frontend/components/dashboard/validator/subset/ValidatorSubsetList.vue b/frontend/components/dashboard/validator/subset/DashboardValidatorSubsetList.vue similarity index 100% rename from frontend/components/dashboard/validator/subset/ValidatorSubsetList.vue rename to frontend/components/dashboard/validator/subset/DashboardValidatorSubsetList.vue From c8694b35d076d38359c8b512ac70c5292581469d Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:12:29 +0100 Subject: [PATCH 02/35] fix(DashboardValidatorSubsetList): change `block` to `slot` See: BEDS-1003 --- .../validator/subset/DashboardValidatorSubsetList.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/components/dashboard/validator/subset/DashboardValidatorSubsetList.vue b/frontend/components/dashboard/validator/subset/DashboardValidatorSubsetList.vue index 500938985..0bdec8f71 100644 --- a/frontend/components/dashboard/validator/subset/DashboardValidatorSubsetList.vue +++ b/frontend/components/dashboard/validator/subset/DashboardValidatorSubsetList.vue @@ -78,7 +78,7 @@ function mapDutyLabel(dutyObjects?: number[]) { case 'proposal_missed': return $t('common.slot', dutyObjects.length) + ':' case 'proposal_proposed': - return $t('common.block', dutyObjects.length) + ':' + return $t('common.slot', dutyObjects.length) + ':' } } function mapDutyLinks( @@ -102,7 +102,7 @@ function mapDutyLinks( path = '/slot/' break case 'proposal_proposed': - path = '/block/' + path = '/slot/' break } if (path) { From 7314bdf0c5c0ceb77fc1db4d3404c1932a370fed Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:59:11 +0100 Subject: [PATCH 03/35] fix(DashboardTableSummaryValue): only show `tooltip` for `sync` See: BEDS-1028 --- .../dashboard/table/DashboardTableSummaryValue.vue | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/components/dashboard/table/DashboardTableSummaryValue.vue b/frontend/components/dashboard/table/DashboardTableSummaryValue.vue index 91a13b398..e14cc8d41 100644 --- a/frontend/components/dashboard/table/DashboardTableSummaryValue.vue +++ b/frontend/components/dashboard/table/DashboardTableSummaryValue.vue @@ -57,10 +57,12 @@ const data = computed(() => { props.property as SummaryDetailsEfficiencyProp, ) ) { - const tooltip: undefined | { text: string, - title: string, } = { - text: $t('dashboard.validator.tooltip.sync.text'), - title: $t('dashboard.validator.tooltip.sync.title'), + let tooltip: undefined | { text: string, title: string } + if (props.property === 'sync') { + tooltip = { + text: $t('dashboard.validator.tooltip.sync.text'), + title: $t('dashboard.validator.tooltip.sync.title'), + } } const prop = col[props.property as SummaryDetailsEfficiencyProp] From 5f3ddecbf5c33680953c42059a48daaac44e5489 Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:50:26 +0100 Subject: [PATCH 04/35] fix(NotificationsManagementGeneralTab): reset `mute state` after `mute timestamp` had passed See: BEDS-952 --- frontend/.vscode/settings.json | 1 + .../NotificationsManagementGeneralTab.vue | 47 +++++++++++-------- frontend/utils/time.ts | 2 + 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json index 40904a878..30b53f04f 100644 --- a/frontend/.vscode/settings.json +++ b/frontend/.vscode/settings.json @@ -22,6 +22,7 @@ "NotificationsDashboardDialogEntity", "NotificationsDashboardTable", "NotificationsManagementDashboards", + "NotificationsManagementGeneralTab", "NotificationsManagementModalDashboardsDelete", "NotificationsManagementModalWebhook", "NotificationsManagementNetwork", diff --git a/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue b/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue index b501f814f..46409a393 100644 --- a/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue +++ b/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue @@ -11,13 +11,13 @@ const { t: $t } = useTranslation() const { fetch } = useCustomFetch() const toast = useBcToast() -const notificationsManagementStore = useNotificationsManagementStore() +const store = useNotificationsManagementStore() const { status, } = useAsyncData( - () => notificationsManagementStore + () => store .getSettings() - .then(({ data }) => notificationsManagementStore.settings = data), + .then(({ data }) => store.settings = data), ) const isVisible = ref(false) @@ -50,12 +50,12 @@ const muteDropdownList = [ const muteNotifications = (seconds: number) => { if (seconds === Number.MAX_SAFE_INTEGER) { - return notificationsManagementStore + return store .settings .general_settings .do_not_disturb_timestamp = seconds } - notificationsManagementStore + store .settings .general_settings .do_not_disturb_timestamp = getFutureTimestampInSeconds({ seconds }) @@ -78,30 +78,39 @@ const sendTestNotification = async (type: 'email' | 'push') => { } } -const pairedDevicesCount = computed(() => notificationsManagementStore.settings.paired_devices?.length || 0) +const pairedDevicesCount = computed(() => store.settings.paired_devices?.length || 0) const hasPushNotificationTest = computed(() => - notificationsManagementStore + store .settings .general_settings .is_push_notifications_enabled - && notificationsManagementStore.settings.paired_devices?.length, + && store.settings.paired_devices?.length, ) const hasEmailNotificationTest = computed(() => - notificationsManagementStore.settings.general_settings.is_email_notifications_enabled, + store.settings.general_settings.is_email_notifications_enabled, ) const openPairdeDevicesModal = () => { isVisible.value = true } - +const isMuted = computed(() => { + const timeStampIsInTheFuture = store.settings.general_settings.do_not_disturb_timestamp > currentTimestampInSeconds() + if ( + store.settings.general_settings.do_not_disturb_timestamp > 0 + && timeStampIsInTheFuture + ) { + return true + } + return false +}) const textMutedUntil = computed(() => { - if (notificationsManagementStore.settings.general_settings.do_not_disturb_timestamp === Number.MAX_SAFE_INTEGER) { + if (store.settings.general_settings.do_not_disturb_timestamp === Number.MAX_SAFE_INTEGER) { return $t('notifications.general.mute.until_turned_on') } return $t('notifications.general.mute.until', { date: formatTsToAbsolute( - notificationsManagementStore.settings.general_settings.do_not_disturb_timestamp, + store.settings.general_settings.do_not_disturb_timestamp, $t('locales.date'), true, ), @@ -110,8 +119,8 @@ const textMutedUntil = computed(() => { const { refreshOverview, } = useNotificationsDashboardOverviewStore() -watchDebounced(() => notificationsManagementStore.settings.general_settings, async () => { - await notificationsManagementStore.saveSettings() +watchDebounced(() => store.settings.general_settings, async () => { + await store.saveSettings() // this is a quickfix and should not be needed, // reactive data should be updated automatically and `user actions` should be atomic -> error handling await refreshOverview() @@ -146,12 +155,12 @@ watchDebounced(() => notificationsManagementStore.settings.general_settings, asy }}
diff --git a/frontend/utils/time.ts b/frontend/utils/time.ts index 464e0ef37..5fd7e6bf4 100644 --- a/frontend/utils/time.ts +++ b/frontend/utils/time.ts @@ -1,3 +1,5 @@ +export const currentTimestampInSeconds = () => Math.round(Date.now() / 1000) + export const getFutureTimestampInSeconds = ( { seconds = 0, From fc27dc05e224e462382514d2d40dd7b24a7e2969 Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Fri, 6 Dec 2024 08:51:28 +0100 Subject: [PATCH 05/35] chore(git-blame-ignore): add `styling` commit See: f67f385625eff411b47e4d82bd8d21f88b5486b6 --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 23196270b..1b8b49208 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -4,6 +4,8 @@ # in order to work execute once: # git config blame.ignoreRevsFile .git-blame-ignore-revs +# chore(deps): update `eslint rule set` and apply changes +f67f385625eff411b47e4d82bd8d21f88b5486b6 #chore(eslint): add `natural sorting` for `json` files f3da99c5c685eae1914aad8513d3b4b2f1cdcaa2 # style(eslint): add `typescript delimiter` rule From f875e7dbf3aa682a35cf47dd8a6295e9ecd04cc0 Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:32:43 +0100 Subject: [PATCH 06/35] fix: `relative hours` for `email reset` in `notifications overview` `Tooltip` of `Email Notifications` showed timestamp instead of `relative time` BEDS-941 --- .../notifications/NotificationsOverview.vue | 7 +++++-- frontend/i18n/locales/en.json | 2 +- frontend/utils/time.ts | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/frontend/components/notifications/NotificationsOverview.vue b/frontend/components/notifications/NotificationsOverview.vue index 6c208da86..1624e399d 100644 --- a/frontend/components/notifications/NotificationsOverview.vue +++ b/frontend/components/notifications/NotificationsOverview.vue @@ -30,10 +30,13 @@ const notificationsTotal = computed(() => { const { user } = useUserStore() const mailLimit = computed(() => user.value?.premium_perks.email_notifications_per_day ?? 0) -const resetHours = computed(() => overview.value?.next_email_count_reset_timestamp ?? 0) +const resetHours = computed( + () => getRelativeTime(overview.value?.next_email_count_reset_timestamp ?? 0), +) + const tooltipEmail = computed(() => { return $t('notifications.overview.email_tooltip', { - hours: resetHours.value, + in_x_hours: resetHours.value, limit: mailLimit.value, }) }) diff --git a/frontend/i18n/locales/en.json b/frontend/i18n/locales/en.json index 6861998b0..ae3830642 100644 --- a/frontend/i18n/locales/en.json +++ b/frontend/i18n/locales/en.json @@ -798,7 +798,7 @@ }, "overview": { "email_activate": "Click here to activate Email notifications", - "email_tooltip": "Your current limit is { limit } emails per day. Your email limit resets in { hours } hours. Upgrade to premium for more.", + "email_tooltip": "Your current limit is { limit } emails per day. Your email limit resets { in_x_hours }. Upgrade to premium for more.", "headers": { "account_groups": "Most notified account groups", "email_notifications": "Email Notifications", diff --git a/frontend/utils/time.ts b/frontend/utils/time.ts index 5fd7e6bf4..275124f83 100644 --- a/frontend/utils/time.ts +++ b/frontend/utils/time.ts @@ -49,3 +49,21 @@ export const formatSecondsTo = (seconds: number, minutes, } } + +export const getRelativeTime = (timestampInSeconds: number, { + locale = 'en-US', +}: { + locale?: string, +} = {}) => { + const seconds = timestampInSeconds - (Date.now() / 1000) + const minutes = (seconds / 60) + const hours = (minutes / 60) + + if (hours >= 1 || hours <= -1) { + return new Intl.RelativeTimeFormat(locale).format(Math.round(hours), 'hours') + } + if (minutes >= 1 || minutes <= -1) { + return new Intl.RelativeTimeFormat(locale).format(Math.round(minutes), 'minutes') + } + return new Intl.RelativeTimeFormat(locale).format(Math.round(seconds), 'seconds') +} From 2950978b58be1cc704dac09cffa2c6fc62c3277c Mon Sep 17 00:00:00 2001 From: peter <1674920+peterbitfly@users.noreply.github.com> Date: Sun, 8 Dec 2024 19:08:25 +0000 Subject: [PATCH 07/35] fix(notifications): ignore global webhook flag for dashboard notifications remove unusued parameter --- backend/pkg/notification/queuing.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/pkg/notification/queuing.go b/backend/pkg/notification/queuing.go index 09f9687a1..a3623225a 100644 --- a/backend/pkg/notification/queuing.go +++ b/backend/pkg/notification/queuing.go @@ -678,9 +678,8 @@ func QueueWebhookNotifications(notificationsByUserID types.NotificationsPerUserI LEFT JOIN users_val_dashboards ON users_val_dashboards_groups.dashboard_id = users_val_dashboards.id WHERE users_val_dashboards.user_id = ANY($1) AND webhook_target IS NOT NULL - AND webhook_format IS NOT NULL - AND user_id NOT IN (SELECT user_id from users_notification_channels WHERE active = false and channel = $2); - `, pq.Array(userIds), types.WebhookNotificationChannel) + AND webhook_format IS NOT NULL; + `, pq.Array(userIds)) if err != nil { return fmt.Errorf("error quering users_val_dashboards_groups, err: %w", err) } From bfc6a231e49bb278a1c9a98fa2ac3f45ed77a5e8 Mon Sep 17 00:00:00 2001 From: benji-bitfly Date: Thu, 7 Nov 2024 15:03:17 +0100 Subject: [PATCH 08/35] feat(NotificationsManagementGeneralTab): add `webhook notifications` toggle to `general settings` See: BEDS-857 --- .../management/NotificationsManagementGeneralTab.vue | 12 +++++++++++- frontend/i18n/locales/en.json | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue b/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue index 46409a393..471593623 100644 --- a/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue +++ b/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue @@ -104,6 +104,7 @@ const isMuted = computed(() => { } return false }) + const textMutedUntil = computed(() => { if (store.settings.general_settings.do_not_disturb_timestamp === Number.MAX_SAFE_INTEGER) { return $t('notifications.general.mute.until_turned_on') @@ -190,7 +191,6 @@ watchDebounced(() => store.settings.general_settings, async () => {
{{ $t("notifications.general.push_notifications") }} @@ -219,6 +219,16 @@ watchDebounced(() => store.settings.general_settings, async () => { {{ tOf($t, "notifications.general.download_app", 2) }}
+
+
+ {{ $t("notifications.general.webhook_notifications") }} +
+ +
Date: Mon, 9 Dec 2024 10:24:28 +0100 Subject: [PATCH 09/35] fix(NotificationsManagementGeneralTab): show `webhook toggle button` independently from `email toggle button` --- .../management/NotificationsManagementGeneralTab.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue b/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue index 471593623..ebb620c38 100644 --- a/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue +++ b/frontend/components/notifications/management/NotificationsManagementGeneralTab.vue @@ -220,7 +220,6 @@ watchDebounced(() => store.settings.general_settings, async () => {
From 0c7c0646cbc452017a0a3304a76692c441eced43 Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:19:10 +0100 Subject: [PATCH 10/35] fix(dashboard): `guest dashboards` not available Due to an update it was not possible anymore to have a `watch` function be dependend on `variables` that are not yet `initialized`. --- frontend/.vscode/settings.json | 1 + frontend/pages/dashboard/[[id]]/index.vue | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json index 30b53f04f..8b5a7725b 100644 --- a/frontend/.vscode/settings.json +++ b/frontend/.vscode/settings.json @@ -37,6 +37,7 @@ "color-mode", "csrf", "customFetch", + "dashboard", "deps", "dialog", "eslint", diff --git a/frontend/pages/dashboard/[[id]]/index.vue b/frontend/pages/dashboard/[[id]]/index.vue index 547844211..52e6a31ec 100644 --- a/frontend/pages/dashboard/[[id]]/index.vue +++ b/frontend/pages/dashboard/[[id]]/index.vue @@ -95,6 +95,13 @@ const { error: validatorOverviewError } = await useAsyncData( () => refreshOverview(dashboardKey.value), { watch: [ dashboardKey ] }, ) +// when we run into an error loading a dashboard keep it here to prevent an infinity loop +const errorDashboardKeys: string[] = [] +const setDashboardKeyIfNoError = (key: string) => { + if (!errorDashboardKeys.includes(key)) { + setDashboardKey(key) + } +} watch( validatorOverviewError, (error) => { @@ -126,13 +133,6 @@ function showDashboardCreationDialog() { dashboardCreationControllerModal.value?.show() } -// when we run into an error loading a dashboard keep it here to prevent an infinity loop -const errorDashboardKeys: string[] = [] -const setDashboardKeyIfNoError = (key: string) => { - if (!errorDashboardKeys.includes(key)) { - setDashboardKey(key) - } -} watch( [ dashboardKey, From 9f560b87250161f57e89021c31a4fd57e45322e7 Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Fri, 29 Nov 2024 15:00:18 +0100 Subject: [PATCH 11/35] fix: fontsize of `dropdown` --- frontend/assets/css/prime.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/assets/css/prime.scss b/frontend/assets/css/prime.scss index d59792610..695061617 100644 --- a/frontend/assets/css/prime.scss +++ b/frontend/assets/css/prime.scss @@ -380,7 +380,6 @@ div.p-checkbox { // Multiselect drop-down div.p-multiselect { - @include fonts.button_text; color: var(--input-active-text-color); background: var(--input-background); border: 1px solid var(--input-border-color); @@ -402,7 +401,6 @@ div.p-multiselect { margin-left: var(--padding-small); .p-multiselect-label { - font-size: var(--tiny_text_font_size); font-weight: var(--standard_text_font_weight); } } From e9f9ba9f10d50a5b948654f8c76cf5564b068bf0 Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Mon, 9 Dec 2024 11:17:46 +0100 Subject: [PATCH 12/35] fix: `summary chart tooltip` not enterable Toggle `trigger` of tooltip between `mousemove` and `click`. Make `tooltip` enterable. Change `series pagination` text color. See: BEDS-577 --- .../chart/DashboardChartSummaryChart.vue | 46 +++++++++++-------- .../DashboardChartSummaryChartFilter.vue | 2 +- .../dashboard/chart/SummaryChartTooltip.vue | 1 + .../dashboard/chart/TooltipHeader.vue | 3 +- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/frontend/components/dashboard/chart/DashboardChartSummaryChart.vue b/frontend/components/dashboard/chart/DashboardChartSummaryChart.vue index db56e783f..766827a1d 100644 --- a/frontend/components/dashboard/chart/DashboardChartSummaryChart.vue +++ b/frontend/components/dashboard/chart/DashboardChartSummaryChart.vue @@ -1,11 +1,16 @@ diff --git a/frontend/components/dashboard/table/DashboardTableSummary.vue b/frontend/components/dashboard/table/DashboardTableSummary.vue index c2a2c6085..29fcfc11c 100644 --- a/frontend/components/dashboard/table/DashboardTableSummary.vue +++ b/frontend/components/dashboard/table/DashboardTableSummary.vue @@ -174,7 +174,7 @@ const searchPlaceholder = computed(() => class="small" :placeholder="$t('dashboard.group.selection.placeholder')" /> - @@ -335,7 +335,7 @@ const searchPlaceholder = computed(() => From a2c00c2373b1b3576d2bf2398088c79a0ed12ff6 Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:09:53 +0100 Subject: [PATCH 14/35] fix(DashboardChartSummary): `tooltip closed` after `pointer up` on `mobile` See: e9f9ba9f10d50a5b948654f8c76cf5564b068bf0 --- frontend/.vscode/settings.json | 1 + .../dashboard/chart/DashboardChartSummary.vue | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json index 65b0d05f7..76b6630b7 100644 --- a/frontend/.vscode/settings.json +++ b/frontend/.vscode/settings.json @@ -10,6 +10,7 @@ "BcPremiumModal", "BcTablePager", "BcToggle", + "DashboardChartSummary", "DashboardChartSummaryFilter", "DashboardGroupManagementModal", "DashboardTableSummaryDetails", diff --git a/frontend/components/dashboard/chart/DashboardChartSummary.vue b/frontend/components/dashboard/chart/DashboardChartSummary.vue index 3f0e63b6d..7b572d755 100644 --- a/frontend/components/dashboard/chart/DashboardChartSummary.vue +++ b/frontend/components/dashboard/chart/DashboardChartSummary.vue @@ -283,7 +283,7 @@ const formatTimestamp = (value: string) => { return date } } -const toogleTrigger = ref(false) +const isTriggeringOnMouseMove = ref(true) const option = computed(() => { return { color: colors.value.groups, @@ -371,7 +371,7 @@ const option = computed(() => { order: 'seriesAsc', padding: 0, trigger: 'axis', - triggerOn: toogleTrigger.value ? 'click' : 'mousemove|click', + triggerOn: isTriggeringOnMouseMove.value ? 'mousemove|click' : 'click', }, xAxis: [ { @@ -607,9 +607,8 @@ const onDatazoom = () => { const onMouseMove = (e: MouseEvent) => { lastMouseYPos = e.offsetY } -const onMouseUp = () => { - // using mouseup event here, as `click` or `mousedown` would close `tooltip` - toogleTrigger.value = !toogleTrigger.value +const toggleTriggeringOnMouseMove = () => { + isTriggeringOnMouseMove.value = !isTriggeringOnMouseMove.value } @@ -624,7 +623,7 @@ const onMouseUp = () => { class="chart" :option autoresize - @zr:mouseup="onMouseUp" + @zr:mousedown="toggleTriggeringOnMouseMove" @datazoom="onDatazoom" /> Date: Mon, 9 Dec 2024 14:57:06 +0100 Subject: [PATCH 15/35] feat(NotificationsOverview): change `email limit` color to `red` when `limit reached` See: BEDS-482 --- .../components/notifications/NotificationsOverview.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/components/notifications/NotificationsOverview.vue b/frontend/components/notifications/NotificationsOverview.vue index 1624e399d..6d907f8a5 100644 --- a/frontend/components/notifications/NotificationsOverview.vue +++ b/frontend/components/notifications/NotificationsOverview.vue @@ -58,7 +58,10 @@ const emit = defineEmits<{ {{ hasEmail ? $t('common.active') : $t('common.inactive') }}
- {{ last24hEmailsCount }}/{{ mailLimit }} {{ $t('common.units.per_day') }} + {{ last24hEmailsCount }}/{{ mailLimit }} {{ $t('common.units.per_day') }} Date: Mon, 9 Dec 2024 14:57:25 +0100 Subject: [PATCH 16/35] chore(migrations): add migration for validatorindex_slot_index_withdrawals_table --- ...dd_validatorindex_slot_index_withdrawals_table.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql diff --git a/backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql b/backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql new file mode 100644 index 000000000..5bafa95f2 --- /dev/null +++ b/backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql @@ -0,0 +1,11 @@ +-- +goose Up +-- +goose StatementBegin +SELECT 'creating idx_blocks_withdrawals_validatorindex_slot'; +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_blocks_withdrawals_validatorindex_slot ON blocks_withdrawals (validatorindex, block_slot DESC); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +SELECT 'dropping idx_blocks_withdrawals_validatorindex_slot'; +DROP INDEX CONCURRENTLY IF EXISTS idx_blocks_withdrawals_validatorindex_slot; +-- +goose StatementEnd From a8deb0546d0661c7d28fb29d9d506d6b948e0cfc Mon Sep 17 00:00:00 2001 From: Patrick Pfeiffer <306324+guybrush@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:22:46 +0100 Subject: [PATCH 17/35] fix(migrations): add no tx statement for concurrent migration --- ...104132640_add_columns_to_users_val_dashboards_groups.sql | 4 ++-- ...2635_add_validatorindex_slot_index_withdrawals_table.sql | 6 ++++-- .../postgres/20241121094954_rocketpool_onchain_configs.sql | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/backend/pkg/commons/db/migrations/postgres/20241104132640_add_columns_to_users_val_dashboards_groups.sql b/backend/pkg/commons/db/migrations/postgres/20241104132640_add_columns_to_users_val_dashboards_groups.sql index 4e05100cf..b6b1af5b9 100644 --- a/backend/pkg/commons/db/migrations/postgres/20241104132640_add_columns_to_users_val_dashboards_groups.sql +++ b/backend/pkg/commons/db/migrations/postgres/20241104132640_add_columns_to_users_val_dashboards_groups.sql @@ -8,6 +8,6 @@ ALTER TABLE users_val_dashboards_groups ADD COLUMN IF NOT EXISTS webhook_retries -- +goose Down -- +goose StatementBegin SELECT 'remove columns from table users_val_dashboards_groups'; -ALTER TABLE users_val_dashboards_groups DROP COLUMN IF NOT EXISTS webhook_last_sent; -ALTER TABLE users_val_dashboards_groups DROP COLUMN IF NOT EXISTS webhook_retries; +ALTER TABLE users_val_dashboards_groups DROP COLUMN IF EXISTS webhook_last_sent; +ALTER TABLE users_val_dashboards_groups DROP COLUMN IF EXISTS webhook_retries; -- +goose StatementEnd diff --git a/backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql b/backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql index 5bafa95f2..5bc3eb099 100644 --- a/backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql +++ b/backend/pkg/commons/db/migrations/postgres/20241120092635_add_validatorindex_slot_index_withdrawals_table.sql @@ -1,11 +1,13 @@ +-- +goose NO TRANSACTION + -- +goose Up --- +goose StatementBegin SELECT 'creating idx_blocks_withdrawals_validatorindex_slot'; +-- +goose StatementBegin CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_blocks_withdrawals_validatorindex_slot ON blocks_withdrawals (validatorindex, block_slot DESC); -- +goose StatementEnd -- +goose Down --- +goose StatementBegin SELECT 'dropping idx_blocks_withdrawals_validatorindex_slot'; +-- +goose StatementBegin DROP INDEX CONCURRENTLY IF EXISTS idx_blocks_withdrawals_validatorindex_slot; -- +goose StatementEnd diff --git a/backend/pkg/commons/db/migrations/postgres/20241121094954_rocketpool_onchain_configs.sql b/backend/pkg/commons/db/migrations/postgres/20241121094954_rocketpool_onchain_configs.sql index f42c495a2..334540e3d 100644 --- a/backend/pkg/commons/db/migrations/postgres/20241121094954_rocketpool_onchain_configs.sql +++ b/backend/pkg/commons/db/migrations/postgres/20241121094954_rocketpool_onchain_configs.sql @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS rocketpool_onchain_configs ( PRIMARY KEY (rocketpool_storage_address) ); -ALTER TABLE rocketpool_minipools ADD COLUMN validator_index INTEGER; +ALTER TABLE rocketpool_minipools ADD COLUMN IF NOT EXISTS validator_index INTEGER; CREATE INDEX IF NOT EXISTS rocketpool_minipools_validator_index_idx ON rocketpool_minipools (validator_index); -- +goose StatementEnd @@ -18,6 +18,6 @@ CREATE INDEX IF NOT EXISTS rocketpool_minipools_validator_index_idx ON rocketpoo DROP TABLE IF EXISTS rocketpool_onchain_configs; DROP INDEX IF EXISTS rocketpool_minipools_validator_index_idx; -ALTER TABLE rocketpool_minipools DROP COLUMN validator_index; +ALTER TABLE rocketpool_minipools DROP COLUMN IF EXISTS validator_index; -- +goose StatementEnd From 4417d4dcfde4c04eb1aadd81365e7025bb0f7241 Mon Sep 17 00:00:00 2001 From: peter <1674920+peterbitfly@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:04:36 +0000 Subject: [PATCH 18/35] fix(notifications): do not save machine metrics related fields --- backend/pkg/api/data_access/notifications.go | 54 +------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/backend/pkg/api/data_access/notifications.go b/backend/pkg/api/data_access/notifications.go index a5397577f..2734ce39a 100644 --- a/backend/pkg/api/data_access/notifications.go +++ b/backend/pkg/api/data_access/notifications.go @@ -1301,11 +1301,6 @@ func (d *DataAccessService) GetNotificationSettingsDefaultValues(ctx context.Con } func (d *DataAccessService) UpdateNotificationSettingsGeneral(ctx context.Context, userId uint64, settings t.NotificationSettingsGeneral) error { - epoch := utils.TimeToEpoch(time.Now()) - - var eventsToInsert []goqu.Record - var eventsToDelete []goqu.Expression - tx, err := d.userWriter.BeginTxx(ctx, nil) if err != nil { return fmt.Errorf("error starting db transactions to update general notification settings: %w", err) @@ -1341,60 +1336,13 @@ func (d *DataAccessService) UpdateNotificationSettingsGeneral(ctx context.Contex return err } - // ------------------------------------- - // Collect the machine and rocketpool events to set and delete - - //Machine events - d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsMachineOfflineSubscribed, userId, types.MonitoringMachineOfflineEventName, "", "", epoch, 0) - d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsMachineStorageUsageSubscribed, userId, types.MonitoringMachineDiskAlmostFullEventName, "", "", epoch, settings.MachineStorageUsageThreshold) - d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsMachineCpuUsageSubscribed, userId, types.MonitoringMachineCpuLoadEventName, "", "", epoch, settings.MachineCpuUsageThreshold) - d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsMachineMemoryUsageSubscribed, userId, types.MonitoringMachineMemoryUsageEventName, "", "", epoch, settings.MachineMemoryUsageThreshold) - - // Insert all the events or update the threshold if they already exist - if len(eventsToInsert) > 0 { - insertDs := goqu.Dialect("postgres"). - Insert("users_subscriptions"). - Cols("user_id", "event_name", "event_filter", "created_ts", "created_epoch", "event_threshold"). - Rows(eventsToInsert). - OnConflict(goqu.DoUpdate( - "user_id, event_name, event_filter", - goqu.Record{"event_threshold": goqu.L("EXCLUDED.event_threshold")}, - )) - - query, args, err := insertDs.Prepared(true).ToSQL() - if err != nil { - return fmt.Errorf("error preparing query: %w", err) - } - - _, err = tx.ExecContext(ctx, query, args...) - if err != nil { - return err - } - } - - // Delete all the events - if len(eventsToDelete) > 0 { - deleteDs := goqu.Dialect("postgres"). - Delete("users_subscriptions"). - Where(goqu.Or(eventsToDelete...)) - - query, args, err := deleteDs.Prepared(true).ToSQL() - if err != nil { - return fmt.Errorf("error preparing query: %w", err) - } - - _, err = tx.ExecContext(ctx, query, args...) - if err != nil { - return err - } - } - err = tx.Commit() if err != nil { return fmt.Errorf("error committing tx to update general notification settings: %w", err) } return nil } + func (d *DataAccessService) UpdateNotificationSettingsNetworks(ctx context.Context, userId uint64, chainId uint64, settings t.NotificationSettingsNetwork) error { epoch := utils.TimeToEpoch(time.Now()) From d0a025464d45712a68d9f2cf8b41e904f149079b Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:39:19 +0100 Subject: [PATCH 19/35] refactor(notifications): remove `machine settings` See: BEDS-1051 --- .../NotificationsManagementMachines.vue | 249 ------------------ .../NotificationsManagementModal.vue | 9 - frontend/i18n/locales/en.json | 14 +- 3 files changed, 1 insertion(+), 271 deletions(-) delete mode 100644 frontend/components/notifications/management/NotificationsManagementMachines.vue diff --git a/frontend/components/notifications/management/NotificationsManagementMachines.vue b/frontend/components/notifications/management/NotificationsManagementMachines.vue deleted file mode 100644 index b966c91bc..000000000 --- a/frontend/components/notifications/management/NotificationsManagementMachines.vue +++ /dev/null @@ -1,249 +0,0 @@ - - - - - diff --git a/frontend/components/notifications/management/NotificationsManagementModal.vue b/frontend/components/notifications/management/NotificationsManagementModal.vue index c6cf728d3..2a08b848f 100644 --- a/frontend/components/notifications/management/NotificationsManagementModal.vue +++ b/frontend/components/notifications/management/NotificationsManagementModal.vue @@ -3,7 +3,6 @@ import { faBolt, faCog, faGaugeSimpleMax, - faMonitorWaveform, faNetworkWired, } from '@fortawesome/pro-solid-svg-icons' import type { HashTabs } from '~/types/hashTabs' @@ -23,11 +22,6 @@ const tabs: HashTabs = [ key: 'dashboards', title: $t('notifications.tabs.dashboards'), }, - { - icon: faMonitorWaveform, - key: 'machines', - title: $t('notifications.tabs.machines'), - }, { icon: faBolt, key: 'clients', @@ -60,9 +54,6 @@ const tabs: HashTabs = [ - diff --git a/frontend/i18n/locales/en.json b/frontend/i18n/locales/en.json index 07c0565ca..07fb024c5 100644 --- a/frontend/i18n/locales/en.json +++ b/frontend/i18n/locales/en.json @@ -758,21 +758,9 @@ "no_storage": "No storage left" }, "footer": { - "subscriptions": "Machines (1 Subscription) |Machines ({count} Subscriptions)" + "subscriptions": "Machines (1 Subscription) | Machines ({count} Subscriptions)" }, "search_placeholder": "Machine", - "settings": { - "check_out_knowlege_base": "Check out our Knowledge Base for a step by step tutorial:", - "cpu_usage": "CPU usage", - "info": "Currently there are no machines configured.", - "machine_offline": "Machine offline", - "memory_usage": "Memory usage", - "mobile_app_node_monitoring": "Mobile App Node Monitoring", - "storage_usage": "Storage usage", - "subscribe_to_premium_cpu": "Subscribe to premium to set a custom CPU threshold.", - "subscribe_to_premium_memory": "Subscribe to premium to set a custom memory threshold.", - "subscribe_to_premium_storage": "Subscribe to premium to set a custom storage threshold." - }, "title": "Machines" }, "manage": "Manage Notifications", From b8eb2078b86b12e90afee1a99776b462bbcc0aea Mon Sep 17 00:00:00 2001 From: marcel-bitfly <174338434+marcel-bitfly@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:53:09 +0100 Subject: [PATCH 20/35] chore(eslint): reenabled rule to have only `one attribute` per line in `vue files` --- frontend/components/bc/BcAccordion.vue | 8 +++- frontend/components/bc/BcInputSearch.vue | 5 ++- frontend/components/bc/BcScreenreaderOnly.vue | 5 ++- frontend/components/bc/BcTranslation.vue | 15 ++++++-- frontend/components/bc/header/MainHeader.vue | 5 ++- frontend/components/bc/tab/BcTabList.vue | 18 +++++++-- .../components/bc/toggle/MultiBarButton.vue | 29 +++++++++++--- .../components/bc/toggle/SingleBarButton.vue | 38 +++++++++++++++---- .../dashboard/chart/DashboardChartRewards.vue | 20 ++++++++-- .../chart/DashboardChartSummaryFilter.vue | 34 ++++++++++++++--- .../NotificationsDashboardDialogEntity.vue | 15 ++++++-- .../notifications/NotificationsOverview.vue | 15 ++++++-- .../NotificationsManagementNetwork.vue | 5 ++- ...ificationsManagementPairedDevicesModal.vue | 8 +++- ...cationsManagementModalDashboardsDelete.vue | 5 ++- .../playground/PlaygroundComponents.vue | 5 ++- .../playground/PlaygroundComposable.vue | 3 +- .../playground/PlaygroundStyling.vue | 3 +- frontend/eslint.config.mjs | 1 - frontend/pages/dashboard/[[id]]/index.vue | 17 +++++++-- frontend/pages/playground.vue | 16 ++++++-- frontend/pages/pricing.vue | 5 ++- 22 files changed, 220 insertions(+), 55 deletions(-) diff --git a/frontend/components/bc/BcAccordion.vue b/frontend/components/bc/BcAccordion.vue index a6c8dfb4b..16245fac0 100644 --- a/frontend/components/bc/BcAccordion.vue +++ b/frontend/components/bc/BcAccordion.vue @@ -66,12 +66,16 @@ const copyText = async () => { :key="`${index}-${element}`" class="bc-accordion-list__element" > - +