-
+
{/* this loading spinner works by using an optical illusion;
the actual icon is static and the "spinning" part is just a semi-transparent darker circle overlayed on top.
This makes it look like there is a small bright colored spinner rotating.
@@ -118,22 +118,22 @@ export const RuleListIcon = memo(function RuleListIcon({
)}
@@ -159,8 +159,8 @@ const spin = keyframes({
const getStyles = (theme: GrafanaTheme2) => ({
iconsContainer: css({
position: 'relative',
- width: 18,
- height: 18,
+ width: ICON_SIZE,
+ height: ICON_SIZE,
'> *': {
position: 'absolute',
},
diff --git a/public/app/features/alerting/unified/rule-list/hooks/useLazyLoadPrometheusGroups.tsx b/public/app/features/alerting/unified/rule-list/hooks/useLazyLoadPrometheusGroups.tsx
new file mode 100644
index 00000000000..351e42427d0
--- /dev/null
+++ b/public/app/features/alerting/unified/rule-list/hooks/useLazyLoadPrometheusGroups.tsx
@@ -0,0 +1,58 @@
+import { useState } from 'react';
+import { useEffectOnce } from 'react-use';
+
+import { PromRuleGroupDTO } from 'app/types/unified-alerting-dto';
+
+import { isLoading as isLoadingState, useAsync } from '../../hooks/useAsync';
+
+/**
+ * Provides lazy loading for rule groups.
+ * Instead of loading all groups at once, it uses a generator to fetch them in batches as needed,
+ * which helps with performance when dealing with large numbers of rules.
+ *
+ * @param groupsGenerator - An async generator that yields rule groups in batches
+ * @param pageSize - Number of groups to display per page
+ * @returns Groups loaded so far and controls for navigating through rule groups
+ */
+export function useLazyLoadPrometheusGroups(
+ groupsGenerator: AsyncIterator,
+ pageSize: number
+) {
+ const [groups, setGroups] = useState([]);
+ const [hasMoreGroups, setHasMoreGroups] = useState(true);
+
+ const [{ execute: fetchMoreGroups }, groupsRequestState] = useAsync(async () => {
+ let done = false;
+ const currentGroups: TGroup[] = [];
+
+ while (currentGroups.length < pageSize) {
+ const generatorResult = await groupsGenerator.next();
+ if (generatorResult.done) {
+ done = true;
+ break;
+ }
+ const group = generatorResult.value;
+ currentGroups.push(group);
+ }
+
+ if (done) {
+ setHasMoreGroups(false);
+ }
+
+ setGroups((groups) => groups.concat(currentGroups));
+ });
+
+ // make sure we only load the initial group exactly once
+ useEffectOnce(() => {
+ fetchMoreGroups();
+ });
+
+ const isLoading = isLoadingState(groupsRequestState);
+
+ return {
+ isLoading,
+ groups,
+ hasMoreGroups: !isLoading && hasMoreGroups,
+ fetchMoreGroups,
+ };
+}
diff --git a/public/app/features/alerting/unified/rule-list/hooks/usePaginatedPrometheusGroups.tsx b/public/app/features/alerting/unified/rule-list/hooks/usePaginatedPrometheusGroups.tsx
deleted file mode 100644
index 18da7186fb5..00000000000
--- a/public/app/features/alerting/unified/rule-list/hooks/usePaginatedPrometheusGroups.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import { useCallback, useMemo, useState } from 'react';
-
-import { PromRuleGroupDTO } from 'app/types/unified-alerting-dto';
-
-import { isLoading, useAsync } from '../../hooks/useAsync';
-
-/**
- * Provides pagination functionality for rule groups with lazy loading.
- * Instead of loading all groups at once, it uses a generator to fetch them in batches as needed,
- * which helps with performance when dealing with large numbers of rules.
- *
- * @param groupsGenerator - An async generator that yields rule groups in batches
- * @param pageSize - Number of groups to display per page
- * @returns Pagination state and controls for navigating through rule groups
- */
-export function usePaginatedPrometheusGroups(
- groupsGenerator: AsyncIterator,
- pageSize: number
-) {
- const [currentPage, setCurrentPage] = useState(1);
- const [groups, setGroups] = useState([]);
- const [lastPage, setLastPage] = useState(undefined);
-
- const [{ execute: fetchMoreGroups }, groupsRequestState] = useAsync(async (groupsCount: number) => {
- let done = false;
- const currentGroups: TGroup[] = [];
-
- while (currentGroups.length < groupsCount) {
- const generatorResult = await groupsGenerator.next();
- if (generatorResult.done) {
- done = true;
- break;
- }
- const group = generatorResult.value;
- currentGroups.push(group);
- }
-
- if (done) {
- const groupsTotal = groups.length + currentGroups.length;
- setLastPage(Math.ceil(groupsTotal / pageSize));
- }
-
- setGroups((groups) => [...groups, ...currentGroups]);
- });
-
- // lastPage could be computed from groups.length and pageSize
- const fetchInProgress = isLoading(groupsRequestState);
- const canMoveForward = !fetchInProgress && (!lastPage || currentPage < lastPage);
- // When going backward we already have the groups loaded, so no need to check if fetchInProgress
- const canMoveBackward = currentPage > 1;
-
- const nextPage = useCallback(async () => {
- if (canMoveForward) {
- setCurrentPage((page) => page + 1);
- }
- }, [canMoveForward]);
-
- const previousPage = useCallback(async () => {
- if (canMoveBackward) {
- setCurrentPage((page) => page - 1);
- }
- }, [canMoveBackward]);
-
- // groups.length - pageSize to have one more page loaded to prevent flickering with loading state
- // lastPage === undefined because 0 is falsy but a value which should stop fetching (e.g for broken data sources)
- const shouldFetchNextPage = groups.length - pageSize < pageSize * currentPage && lastPage === undefined;
-
- if (shouldFetchNextPage && !fetchInProgress) {
- fetchMoreGroups(pageSize);
- }
-
- const groupsPage = useMemo(() => {
- return groups.slice((currentPage - 1) * pageSize, currentPage * pageSize);
- }, [groups, currentPage, pageSize]);
-
- return { isLoading: fetchInProgress, page: groupsPage, nextPage, previousPage, canMoveForward, canMoveBackward };
-}
diff --git a/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json b/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json
index ed332ba2226..2e8360999c5 100644
--- a/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json
+++ b/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json
@@ -72,9 +72,9 @@
},
"config-editor": {
"description-additional-settings": "Additional settings are optional settings that can be configured for more control over your data source. This includes Secure Socks Proxy.",
+ "description-request-timeout": "Set the request timeout in seconds. Default is 30 seconds.",
"title-additional-settings": "Additional settings",
- "title-request-timeout": "Request timeout",
- "description-request-timeout": "Set the request timeout in seconds. Default is 30 seconds."
+ "title-request-timeout": "Request Timeout"
},
"current-user-fallback-credentials": {
"alert-fallback-credentials-disabled": "Fallback credentials have been disabled. As user-based authentication only inherently supports requests with a user in scope, features such as alerting, recorded queries, or reporting will not function as expected. Please review the <2>documentation2> for more details.",
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index ed688e5c2d2..5b0f410a274 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -1050,7 +1050,7 @@
"folder-bulk-actions": {
"delete": {
"button": {
- "label": "Delete rules"
+ "label": "Delete all rules"
}
},
"delete-modal-confirmation-text": "Delete",
@@ -1060,18 +1060,21 @@
"delete-modal-title": "Delete",
"error": "Failed to execute action for folder: {{error}}",
"more-button": {
- "title": "Folder bulk Actions",
- "tooltip": "Folder bulk Actions"
+ "title": "Folder actions",
+ "tooltip": "Folder actions"
},
"pause": {
"button": {
- "label": "Pause all rule evaluation"
+ "label": "Pause all rules"
}
},
"unpause": {
"button": {
- "label": "Resume all rule evaluation"
+ "label": "Resume all rules"
}
+ },
+ "view": {
+ "folder": "View folder"
}
},
"folder-selector": {
@@ -1206,15 +1209,6 @@
"grafana-rules-export-preview": {
"text-loading": "Loading...."
},
- "group-actions": {
- "actions-trigger": "Rule group actions",
- "details": "Details",
- "edit": "Edit"
- },
- "group-actions-menu": {
- "group-load-failed": "Failed to load group details",
- "unknown-error": "Unknown error"
- },
"group-and-namespace-fields": {
"group-picker-label-group": "Group",
"namespace-picker-label-namespace": "Namespace"
@@ -2070,8 +2064,7 @@
"new-datasource-recording-rule": "New Data source recording rule",
"new-grafana-recording-rule": "New Grafana recording rule",
"pagination": {
- "next-page": "next page",
- "previous-page": "previous page"
+ "next-page": "Show more…"
},
"recording-rules": "Recording rules",
"return-button": {