+ {truncatedText || fullText || 'View'}
+
+ }
footer={[]}
centered
open={isFullViewOpen}
diff --git a/frontend/src/container/GridCardLayout/WidgetHeader/index.tsx b/frontend/src/container/GridCardLayout/WidgetHeader/index.tsx
index 9956ebc160..2d69a737f7 100644
--- a/frontend/src/container/GridCardLayout/WidgetHeader/index.tsx
+++ b/frontend/src/container/GridCardLayout/WidgetHeader/index.tsx
@@ -16,6 +16,7 @@ import { Dropdown, Input, MenuProps, Tooltip, Typography } from 'antd';
import Spinner from 'components/Spinner';
import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder';
+import useGetResolvedText from 'hooks/dashboard/useGetResolvedText';
import useCreateAlerts from 'hooks/queryBuilder/useCreateAlerts';
import useComponentPermission from 'hooks/useComponentPermission';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
@@ -205,6 +206,11 @@ function WidgetHeader({
[updatedMenuList, onMenuItemSelectHandler],
);
+ const { truncatedText, fullText } = useGetResolvedText({
+ text: widget.title as string,
+ maxLength: 100,
+ });
+
if (widget.id === PANEL_TYPES.EMPTY_WIDGET) {
return null;
}
@@ -237,13 +243,15 @@ function WidgetHeader({
) : (
<>
-
- {title}
-
+
+
+ {truncatedText}
+
+
{widget.description && (
(null);
+
const onChangeHandler = useCallback(
(setFunc: Dispatch>, value: string) => {
setFunc(value);
@@ -112,6 +136,66 @@ function RightContainer({
const [graphTypes, setGraphTypes] = useState(GraphTypes);
+ // Get dashboard variables
+ const dashboardVariables = useMemo(() => {
+ if (!selectedDashboard?.data?.variables) return [];
+ return Object.entries(selectedDashboard.data.variables).map(([, value]) => ({
+ value: value.name || '',
+ label: value.name || '',
+ }));
+ }, [selectedDashboard?.data?.variables]);
+
+ const updateCursorAndDropdown = (value: string, pos: number): void => {
+ setCursorPos(pos);
+ const lastDollar = value.lastIndexOf('$', pos - 1);
+ setAutoCompleteOpen(lastDollar !== -1 && pos >= lastDollar + 1);
+ };
+
+ const onInputChange = (value: string): void => {
+ setInputValue(value);
+ onChangeHandler(setTitle, value);
+ setTimeout(() => {
+ const pos = inputRef.current?.input?.selectionStart ?? 0;
+ updateCursorAndDropdown(value, pos);
+ }, 0);
+ };
+
+ const handleInputCursor = (): void => {
+ const pos = inputRef.current?.input?.selectionStart ?? 0;
+ updateCursorAndDropdown(inputValue, pos);
+ };
+
+ const onSelect = (selectedValue: string): void => {
+ const pos = cursorPos;
+ const value = inputValue;
+ const lastDollar = value.lastIndexOf('$', pos - 1);
+ const textBeforeDollar = value.substring(0, lastDollar);
+ const textAfterDollar = value.substring(lastDollar + 1);
+ const match = textAfterDollar.match(/^([a-zA-Z0-9_.]*)/);
+ const rest = textAfterDollar.substring(match ? match[1].length : 0);
+ const newValue = `${textBeforeDollar}$${selectedValue}${rest}`;
+ setInputValue(newValue);
+ onChangeHandler(setTitle, newValue);
+ setAutoCompleteOpen(false);
+ setTimeout(() => {
+ const newCursor = `${textBeforeDollar}$${selectedValue}`.length;
+ inputRef.current?.input?.setSelectionRange(newCursor, newCursor);
+ setCursorPos(newCursor);
+ }, 0);
+ };
+
+ const filterOption = (
+ inputValue: string,
+ option?: VariableOption,
+ ): boolean => {
+ const pos = cursorPos;
+ const value = inputValue;
+ const lastDollar = value.lastIndexOf('$', pos - 1);
+ if (lastDollar === -1) return false;
+ const afterDollar = value.substring(lastDollar + 1, pos).toLowerCase();
+ return option?.value.toLowerCase().startsWith(afterDollar) || false;
+ };
+
useEffect(() => {
const queryContainsMetricsDataSource = currentQuery.builder.queryData.some(
(query) => query.dataSource === DataSource.METRICS,
@@ -148,12 +232,25 @@ function RightContainer({