From 1914c3b4a045e8b127ddf26d0febd7c26d4fb683 Mon Sep 17 00:00:00 2001 From: Vishal Sharma Date: Fri, 27 Jan 2023 12:53:23 +0530 Subject: [PATCH 1/6] chore: update install message in install.sh script (#2131) --- deploy/install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deploy/install.sh b/deploy/install.sh index 34ca5356bb..ba69553b50 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -511,13 +511,15 @@ else echo "" echo -e "🟢 Your frontend is running on http://localhost:3301" echo "" + echo "ā„¹ļø By default, retention period is set to 7 days for logs and traces, and 30 days for metrics." + echo -e "To change this, navigate to the General tab on the Settings page of SigNoz UI. For more details, refer to https://signoz.io/docs/userguide/retention-period \n" echo "ā„¹ļø To bring down SigNoz and clean volumes : $sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml down -v" echo "" echo "+++++++++++++++++++++++++++++++++++++++++++++++++" echo "" - echo "šŸ‘‰ Need help Getting Started?" + echo "šŸ‘‰ Need help in Getting Started?" echo -e "Join us on Slack https://signoz.io/slack" echo "" echo -e "\nšŸ“Ø Please share your email to receive support & updates about SigNoz!" From ed4a01dea69dab11692b75f5703e408f3f378d3c Mon Sep 17 00:00:00 2001 From: Amol Umbark Date: Fri, 27 Jan 2023 13:27:59 +0530 Subject: [PATCH 2/6] fix: log issue remove field in query panel (#2130) --- .../src/container/LogsSearchFilter/SearchFields/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/container/LogsSearchFilter/SearchFields/index.tsx b/frontend/src/container/LogsSearchFilter/SearchFields/index.tsx index a7228c6c45..50e2947ed2 100644 --- a/frontend/src/container/LogsSearchFilter/SearchFields/index.tsx +++ b/frontend/src/container/LogsSearchFilter/SearchFields/index.tsx @@ -47,6 +47,11 @@ function SearchFields({ } }, [parsedQuery]); + const updateFieldsQuery = (updated: QueryFields[][]): void => { + setFieldsQuery(updated); + keyPrefixRef.current = hashCode(JSON.stringify(updated)); + }; + const addSuggestedField = useCallback( (name: string): void => { if (!name) { @@ -97,7 +102,7 @@ function SearchFields({ keyPrefix={keyPrefixRef.current} onDropDownToggleHandler={onDropDownToggleHandler} fieldsQuery={fieldsQuery} - setFieldsQuery={setFieldsQuery} + setFieldsQuery={updateFieldsQuery} /> Date: Mon, 30 Jan 2023 07:37:23 -0300 Subject: [PATCH 3/6] FIX: Exported dashboard include response of the queries #1981 (#2052) * clear the queryData * avoid creation of inline func and move logic to utils * remove console.log * fix --- .../DescriptionOfDashboard/ShareModal.tsx | 7 ++++--- .../NewDashboard/DescriptionOfDashboard/util.ts | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/frontend/src/container/NewDashboard/DescriptionOfDashboard/ShareModal.tsx b/frontend/src/container/NewDashboard/DescriptionOfDashboard/ShareModal.tsx index e3be718e86..b177f056d2 100644 --- a/frontend/src/container/NewDashboard/DescriptionOfDashboard/ShareModal.tsx +++ b/frontend/src/container/NewDashboard/DescriptionOfDashboard/ShareModal.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; import { useCopyToClipboard } from 'react-use'; import { DashboardData } from 'types/api/dashboard/getAll'; -import { downloadObjectAsJson } from './util'; +import { cleardQueryData, downloadObjectAsJson } from './util'; function ShareModal({ isJSONModalVisible, @@ -51,6 +51,7 @@ function ShareModal({ } }, [state.error, state.value, t]); + const selectedDataCleaned = cleardQueryData(selectedData); const GetFooterComponent = useMemo(() => { if (!isViewJSON) { return ( @@ -66,7 +67,7 @@ function ShareModal({ ); - }, [isViewJSON, jsonValue, selectedData, setCopy, t]); + }, [isViewJSON, jsonValue, selectedData, selectedDataCleaned, setCopy, t]); return ( ({ + ...widget, + queryData: { + ...widget.queryData, + data: { + queryData: [], + }, + }, + })), + }; +} From b336a6cb452e1adae92afd339690c0c2f07ea821 Mon Sep 17 00:00:00 2001 From: Palash Gupta Date: Mon, 30 Jan 2023 18:06:49 +0530 Subject: [PATCH 4/6] fix: widget options are now opening (#2141) --- .../GridGraphLayout/WidgetHeader/config.ts | 9 + .../GridGraphLayout/WidgetHeader/index.tsx | 165 +++++++++++------- .../GridGraphLayout/WidgetHeader/styles.ts | 6 - 3 files changed, 109 insertions(+), 71 deletions(-) diff --git a/frontend/src/container/GridGraphLayout/WidgetHeader/config.ts b/frontend/src/container/GridGraphLayout/WidgetHeader/config.ts index 55f00c9a86..2d9771d235 100644 --- a/frontend/src/container/GridGraphLayout/WidgetHeader/config.ts +++ b/frontend/src/container/GridGraphLayout/WidgetHeader/config.ts @@ -10,4 +10,13 @@ export const tooltipStyles = { right: '0.313rem', color: themeColors.errorColor, }; + export const errorTooltipPosition = 'top'; + +export const overlayStyles: React.CSSProperties = { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + position: 'absolute', +}; diff --git a/frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx b/frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx index 0626f4b3e8..6a3795e6a2 100644 --- a/frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx +++ b/frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx @@ -5,11 +5,12 @@ import { ExclamationCircleOutlined, FullscreenOutlined, } from '@ant-design/icons'; -import { Dropdown, Menu, Tooltip, Typography } from 'antd'; +import { Dropdown, MenuProps, Tooltip, Typography } from 'antd'; +import { MenuItemType } from 'antd/es/menu/hooks/useItems'; import Spinner from 'components/Spinner'; import useComponentPermission from 'hooks/useComponentPermission'; import history from 'lib/history'; -import React, { useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { UseQueryResult } from 'react-query'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; @@ -18,12 +19,16 @@ import { Widgets } from 'types/api/dashboard/getAll'; import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange'; import AppReducer from 'types/reducer/app'; -import { errorTooltipPosition, spinnerStyles, tooltipStyles } from './config'; +import { + errorTooltipPosition, + overlayStyles, + spinnerStyles, + tooltipStyles, +} from './config'; import { ArrowContainer, HeaderContainer, HeaderContentContainer, - MenuItemContainer, } from './styles'; type TWidgetOptions = 'view' | 'edit' | 'delete' | string; @@ -48,33 +53,45 @@ function WidgetHeader({ errorMessage, }: IWidgetHeaderProps): JSX.Element { const [localHover, setLocalHover] = useState(false); + const [isOpen, setIsOpen] = useState(false); - const onEditHandler = (): void => { + const onEditHandler = useCallback((): void => { const widgetId = widget.id; history.push( `${window.location.pathname}/new?widgetId=${widgetId}&graphType=${widget.panelTypes}`, ); - }; + }, [widget.id, widget.panelTypes]); const keyMethodMapping: { [K in TWidgetOptions]: { key: TWidgetOptions; method: VoidFunction }; - } = { - view: { - key: 'view', - method: onView, + } = useMemo( + () => ({ + view: { + key: 'view', + method: onView, + }, + edit: { + key: 'edit', + method: onEditHandler, + }, + delete: { + key: 'delete', + method: onDelete, + }, + }), + [onDelete, onEditHandler, onView], + ); + + const onMenuItemSelectHandler: MenuProps['onClick'] = useCallback( + ({ key }: { key: TWidgetOptions }): void => { + const functionToCall = keyMethodMapping[key]?.method; + if (functionToCall) { + functionToCall(); + setIsOpen(false); + } }, - edit: { - key: 'edit', - method: onEditHandler, - }, - delete: { - key: 'delete', - method: onDelete, - }, - }; - const onMenuItemSelectHandler = ({ key }: { key: TWidgetOptions }): void => { - keyMethodMapping[key]?.method(); - }; + [keyMethodMapping], + ); const { role } = useSelector((state) => state.app); const [deleteWidget, editWidget] = useComponentPermission( @@ -82,49 +99,67 @@ function WidgetHeader({ role, ); - const menu = ( - - - - View - - + const menuList: MenuItemType[] = useMemo( + () => [ + { + key: keyMethodMapping.view.key, + icon: , + disabled: queryResponse.isLoading, + label: 'View', + }, + { + key: keyMethodMapping.edit.key, + icon: , + disabled: !editWidget, + label: 'Edit', + }, + { + key: keyMethodMapping.delete.key, + icon: , + disabled: !deleteWidget, + danger: true, + label: 'Delete', + }, + ], + [ + deleteWidget, + editWidget, + keyMethodMapping.delete.key, + keyMethodMapping.edit.key, + keyMethodMapping.view.key, + queryResponse.isLoading, + ], + ); - {editWidget && ( - - - Edit - - - )} + const onClickHandler = useCallback(() => { + setIsOpen((open) => !open); + }, []); - {deleteWidget && ( - <> - - - - Delete - - - - )} - + const menu = useMemo( + () => ({ + items: menuList, + onClick: onMenuItemSelectHandler, + }), + [menuList, onMenuItemSelectHandler], ); return ( - - <> +
+ setLocalHover(true)} onMouseOut={(): void => setLocalHover(false)} hover={localHover} + onClick={onClickHandler} > - e.preventDefault()}> + {title} @@ -133,16 +168,16 @@ function WidgetHeader({ - {queryResponse.isFetching && !queryResponse.isError && ( - - )} - {queryResponse.isError && ( - - - - )} - - + + {queryResponse.isFetching && !queryResponse.isError && ( + + )} + {queryResponse.isError && ( + + + + )} +
); } diff --git a/frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts b/frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts index 9600a6bcb4..fab62ac9de 100644 --- a/frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts +++ b/frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts @@ -1,12 +1,6 @@ import { grey } from '@ant-design/colors'; import styled from 'styled-components'; -export const MenuItemContainer = styled.div` - display: flex; - justify-content: space-between; - align-items: center; -`; - export const HeaderContainer = styled.div<{ hover: boolean }>` width: 100%; text-align: center; From af272a368b37e5adc7772fb3df7c3b45892f2477 Mon Sep 17 00:00:00 2001 From: Chintan Sudani <46838508+csudani7@users.noreply.github.com> Date: Mon, 30 Jan 2023 18:32:05 +0530 Subject: [PATCH 5/6] fix: added lazy loading on dashboard (#2133) * fix: Removed Strict mode to stop render twice * fix: added lazy loading on dashboard * fix: suggested changes * fix: added react-intersection-observer changes * fix: resolved multiple time api call issue * chore: variable name is updated --------- Co-authored-by: Palash Gupta --- frontend/package.json | 1 + .../src/container/GridGraphLayout/Graph/index.tsx | 14 +++++++++++--- frontend/yarn.lock | 5 +++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 7d5784af7a..bd06d4893f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -76,6 +76,7 @@ "react-graph-vis": "^1.0.5", "react-grid-layout": "^1.3.4", "react-i18next": "^11.16.1", + "react-intersection-observer": "9.4.1", "react-query": "^3.34.19", "react-redux": "^7.2.2", "react-router-dom": "^5.2.0", diff --git a/frontend/src/container/GridGraphLayout/Graph/index.tsx b/frontend/src/container/GridGraphLayout/Graph/index.tsx index a47fc6b53d..011af4e46d 100644 --- a/frontend/src/container/GridGraphLayout/Graph/index.tsx +++ b/frontend/src/container/GridGraphLayout/Graph/index.tsx @@ -8,6 +8,7 @@ import getChartData from 'lib/getChartData'; import isEmpty from 'lodash-es/isEmpty'; import React, { memo, useCallback, useMemo, useState } from 'react'; import { Layout } from 'react-grid-layout'; +import { useInView } from 'react-intersection-observer'; import { useQuery } from 'react-query'; import { connect, useSelector } from 'react-redux'; import { bindActionCreators, Dispatch } from 'redux'; @@ -39,6 +40,11 @@ function GridCardGraph({ setLayout, onDragSelect, }: GridCardGraphProps): JSX.Element { + const { ref: graphRef, inView: isGraphVisible } = useInView({ + threshold: 0, + triggerOnce: true, + }); + const [errorMessage, setErrorMessage] = useState(''); const [hovered, setHovered] = useState(false); const [modal, setModal] = useState(false); @@ -79,6 +85,7 @@ function GridCardGraph({ }), { keepPreviousData: true, + enabled: isGraphVisible, refetchOnMount: false, onError: (error) => { if (error instanceof Error) { @@ -160,7 +167,7 @@ function GridCardGraph({ if (queryResponse.isError && !isEmptyLayout) { return ( - + {getModals()} {!isEmpty(widget) && prevChartDataSetRef && ( <> @@ -192,7 +199,7 @@ function GridCardGraph({ if (prevChartDataSetRef?.labels === undefined && queryResponse.isLoading) { return ( - + {!isEmpty(widget) && prevChartDataSetRef?.labels ? ( <>
@@ -225,6 +232,7 @@ function GridCardGraph({ return ( { setHovered(true); }} @@ -260,7 +268,7 @@ function GridCardGraph({ data={chartData} isStacked={widget.isStacked} opacity={widget.opacity} - title={' '} // empty title to accommodate absolutely positioned widget header + title={' '} // `empty title to accommodate absolutely positioned widget header name={name} yAxisUnit={yAxisUnit} onDragSelect={onDragSelect} diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 079f789676..7f06bd9c40 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -11104,6 +11104,11 @@ react-i18next@^11.16.1: "@babel/runtime" "^7.14.5" html-parse-stringify "^3.0.1" +react-intersection-observer@9.4.1: + version "9.4.1" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz#4ccb21e16acd0b9cf5b28d275af7055bef878f6b" + integrity sha512-IXpIsPe6BleFOEHKzKh5UjwRUaz/JYS0lT/HPsupWEQou2hDqjhLMStc5zyE3eQVT4Fk3FufM8Fw33qW1uyeiw== + react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" From 3115b32dcde2f4a3b3c4a7b54df00e3e8a793bf8 Mon Sep 17 00:00:00 2001 From: Palash Gupta Date: Mon, 30 Jan 2023 19:27:13 +0530 Subject: [PATCH 6/6] fix: interval is blocked for custom time selection (#2146) * fix: interval is blocked for custom time selection * fix: custom is updated * chore: selectedTime is updated in hidden logic --- frontend/src/container/TopNav/AutoRefresh/index.tsx | 12 ++++++++++-- .../src/container/TopNav/DateTimeSelection/index.tsx | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/frontend/src/container/TopNav/AutoRefresh/index.tsx b/frontend/src/container/TopNav/AutoRefresh/index.tsx index ba0d4bb3e6..ab02e27a3d 100644 --- a/frontend/src/container/TopNav/AutoRefresh/index.tsx +++ b/frontend/src/container/TopNav/AutoRefresh/index.tsx @@ -37,8 +37,11 @@ function AutoRefresh({ disabled = false }: AutoRefreshProps): JSX.Element { const { pathname } = useLocation(); const isDisabled = useMemo( - () => disabled || globalTime.isAutoRefreshDisabled, - [globalTime.isAutoRefreshDisabled, disabled], + () => + disabled || + globalTime.isAutoRefreshDisabled || + globalTime.selectedTime === 'custom', + [globalTime.isAutoRefreshDisabled, disabled, globalTime.selectedTime], ); const localStorageData = JSON.parse(get(DASHBOARD_TIME_IN_DURATION) || '{}'); @@ -132,6 +135,11 @@ function AutoRefresh({ disabled = false }: AutoRefreshProps): JSX.Element { [localStorageData, pathname], ); + if (globalTime.selectedTime === 'custom') { + // eslint-disable-next-line react/jsx-no-useless-fragment + return <>; + } + return ( { + if (selectedTime === 'custom') { + setRefreshButtonHidden(true); + } else { + setRefreshButtonHidden(false); + } + }, [selectedTime]); + const getDefaultTime = (pathName: string): Time => { const defaultSelectedOption = getDefaultOption(pathName);