mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-26 04:14:27 +08:00
feat: show retention info for cloud users and show count next to team… (#4536)
* feat: show retention info for cloud users and show count next to team members and pending invites * feat: add safety check for saved views response
This commit is contained in:
parent
0dffd86287
commit
d6b7587bbe
@ -107,7 +107,7 @@ function ExplorerOptions({
|
|||||||
const viewName = useGetSearchQueryParam(QueryParams.viewName) || '';
|
const viewName = useGetSearchQueryParam(QueryParams.viewName) || '';
|
||||||
const viewKey = useGetSearchQueryParam(QueryParams.viewKey) || '';
|
const viewKey = useGetSearchQueryParam(QueryParams.viewKey) || '';
|
||||||
|
|
||||||
const extraData = viewsData?.data.data.find((view) => view.uuid === viewKey)
|
const extraData = viewsData?.data?.data?.find((view) => view.uuid === viewKey)
|
||||||
?.extraData;
|
?.extraData;
|
||||||
|
|
||||||
const extraDataColor = extraData ? JSON.parse(extraData).color : '';
|
const extraDataColor = extraData ? JSON.parse(extraData).color : '';
|
||||||
@ -134,7 +134,7 @@ function ExplorerOptions({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onUpdateQueryHandler = (): void => {
|
const onUpdateQueryHandler = (): void => {
|
||||||
const extraData = viewsData?.data.data.find((view) => view.uuid === viewKey)
|
const extraData = viewsData?.data?.data?.find((view) => view.uuid === viewKey)
|
||||||
?.extraData;
|
?.extraData;
|
||||||
updateViewAsync(
|
updateViewAsync(
|
||||||
{
|
{
|
||||||
@ -166,7 +166,7 @@ function ExplorerOptions({
|
|||||||
({ key }: { key: string }): void => {
|
({ key }: { key: string }): void => {
|
||||||
const currentViewDetails = getViewDetailsUsingViewKey(
|
const currentViewDetails = getViewDetailsUsingViewKey(
|
||||||
key,
|
key,
|
||||||
viewsData?.data.data,
|
viewsData?.data?.data,
|
||||||
);
|
);
|
||||||
if (!currentViewDetails) return;
|
if (!currentViewDetails) return;
|
||||||
const {
|
const {
|
||||||
@ -296,7 +296,7 @@ function ExplorerOptions({
|
|||||||
onClear={handleClearSelect}
|
onClear={handleClearSelect}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
>
|
>
|
||||||
{viewsData?.data.data.map((view) => {
|
{viewsData?.data?.data?.map((view) => {
|
||||||
const extraData =
|
const extraData =
|
||||||
view.extraData !== '' ? JSON.parse(view.extraData) : '';
|
view.extraData !== '' ? JSON.parse(view.extraData) : '';
|
||||||
let bgColor = getRandomColor();
|
let bgColor = getRandomColor();
|
||||||
|
@ -3,6 +3,7 @@ import { LoadingOutlined } from '@ant-design/icons';
|
|||||||
import { Button, Card, Col, Divider, Modal, Row, Spin, Typography } from 'antd';
|
import { Button, Card, Col, Divider, Modal, Row, Spin, Typography } from 'antd';
|
||||||
import setRetentionApi from 'api/settings/setRetention';
|
import setRetentionApi from 'api/settings/setRetention';
|
||||||
import TextToolTip from 'components/TextToolTip';
|
import TextToolTip from 'components/TextToolTip';
|
||||||
|
import GeneralSettingsCloud from 'container/GeneralSettingsCloud';
|
||||||
import useComponentPermission from 'hooks/useComponentPermission';
|
import useComponentPermission from 'hooks/useComponentPermission';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import find from 'lodash-es/find';
|
import find from 'lodash-es/find';
|
||||||
@ -24,6 +25,7 @@ import {
|
|||||||
PayloadPropsTraces as GetRetentionPeriodTracesPayload,
|
PayloadPropsTraces as GetRetentionPeriodTracesPayload,
|
||||||
} from 'types/api/settings/getRetention';
|
} from 'types/api/settings/getRetention';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
import { isCloudUser } from 'utils/app';
|
||||||
|
|
||||||
import Retention from './Retention';
|
import Retention from './Retention';
|
||||||
import StatusMessage from './StatusMessage';
|
import StatusMessage from './StatusMessage';
|
||||||
@ -394,6 +396,8 @@ function GeneralSettings({
|
|||||||
onModalToggleHandler(type);
|
onModalToggleHandler(type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isCloudUserVal = isCloudUser();
|
||||||
|
|
||||||
const renderConfig = [
|
const renderConfig = [
|
||||||
{
|
{
|
||||||
name: 'Metrics',
|
name: 'Metrics',
|
||||||
@ -521,7 +525,7 @@ function GeneralSettings({
|
|||||||
return (
|
return (
|
||||||
<Fragment key={category.name}>
|
<Fragment key={category.name}>
|
||||||
<Col xs={22} xl={11} key={category.name} style={{ margin: '0.5rem' }}>
|
<Col xs={22} xl={11} key={category.name} style={{ margin: '0.5rem' }}>
|
||||||
<Card style={{ height: '100%', minHeight: 300 }}>
|
<Card style={{ height: '100%' }}>
|
||||||
<Typography.Title style={{ margin: 0 }} level={3}>
|
<Typography.Title style={{ margin: 0 }} level={3}>
|
||||||
{category.name}
|
{category.name}
|
||||||
</Typography.Title>
|
</Typography.Title>
|
||||||
@ -542,38 +546,43 @@ function GeneralSettings({
|
|||||||
hide={!!retentionField.hide}
|
hide={!!retentionField.hide}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<ActionItemsContainer>
|
|
||||||
<Button
|
{!isCloudUserVal && (
|
||||||
type="primary"
|
<>
|
||||||
onClick={category.save.modalOpen}
|
<ActionItemsContainer>
|
||||||
disabled={category.save.isDisabled}
|
<Button
|
||||||
>
|
type="primary"
|
||||||
{category.save.saveButtonText}
|
onClick={category.save.modalOpen}
|
||||||
</Button>
|
disabled={category.save.isDisabled}
|
||||||
{category.statusComponent}
|
>
|
||||||
</ActionItemsContainer>
|
{category.save.saveButtonText}
|
||||||
<Modal
|
</Button>
|
||||||
title={t('retention_confirmation')}
|
{category.statusComponent}
|
||||||
focusTriggerAfterClose
|
</ActionItemsContainer>
|
||||||
forceRender
|
<Modal
|
||||||
destroyOnClose
|
title={t('retention_confirmation')}
|
||||||
closable
|
focusTriggerAfterClose
|
||||||
onCancel={(): void =>
|
forceRender
|
||||||
onModalToggleHandler(category.name.toLowerCase() as TTTLType)
|
destroyOnClose
|
||||||
}
|
closable
|
||||||
onOk={(): Promise<void> =>
|
onCancel={(): void =>
|
||||||
onOkHandler(category.name.toLowerCase() as TTTLType)
|
onModalToggleHandler(category.name.toLowerCase() as TTTLType)
|
||||||
}
|
}
|
||||||
centered
|
onOk={(): Promise<void> =>
|
||||||
open={category.save.modal}
|
onOkHandler(category.name.toLowerCase() as TTTLType)
|
||||||
confirmLoading={category.save.apiLoading}
|
}
|
||||||
>
|
centered
|
||||||
<Typography>
|
open={category.save.modal}
|
||||||
{t('retention_confirmation_description', {
|
confirmLoading={category.save.apiLoading}
|
||||||
name: category.name.toLowerCase(),
|
>
|
||||||
})}
|
<Typography>
|
||||||
</Typography>
|
{t('retention_confirmation_description', {
|
||||||
</Modal>
|
name: category.name.toLowerCase(),
|
||||||
|
})}
|
||||||
|
</Typography>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
@ -587,16 +596,20 @@ function GeneralSettings({
|
|||||||
{Element}
|
{Element}
|
||||||
<Col xs={24} md={22} xl={20} xxl={18} style={{ margin: 'auto' }}>
|
<Col xs={24} md={22} xl={20} xxl={18} style={{ margin: 'auto' }}>
|
||||||
<ErrorTextContainer>
|
<ErrorTextContainer>
|
||||||
<TextToolTip
|
{!isCloudUserVal && (
|
||||||
{...{
|
<TextToolTip
|
||||||
text: `More details on how to set retention period`,
|
{...{
|
||||||
url: 'https://signoz.io/docs/userguide/retention-period/',
|
text: `More details on how to set retention period`,
|
||||||
}}
|
url: 'https://signoz.io/docs/userguide/retention-period/',
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{errorText && <ErrorText>{errorText}</ErrorText>}
|
{errorText && <ErrorText>{errorText}</ErrorText>}
|
||||||
</ErrorTextContainer>
|
</ErrorTextContainer>
|
||||||
|
|
||||||
<Row justify="start">{renderConfig}</Row>
|
<Row justify="start">{renderConfig}</Row>
|
||||||
|
|
||||||
|
{isCloudUserVal && <GeneralSettingsCloud />}
|
||||||
</Col>
|
</Col>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
import { isCloudUser } from 'utils/app';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Input,
|
Input,
|
||||||
@ -85,9 +86,13 @@ function Retention({
|
|||||||
func(null);
|
func(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hide) {
|
if (hide) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isCloudUserVal = isCloudUser();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RetentionContainer>
|
<RetentionContainer>
|
||||||
<Row justify="space-between">
|
<Row justify="space-between">
|
||||||
@ -98,12 +103,14 @@ function Retention({
|
|||||||
<RetentionFieldInputContainer>
|
<RetentionFieldInputContainer>
|
||||||
<Input
|
<Input
|
||||||
value={selectedValue && selectedValue >= 0 ? selectedValue : ''}
|
value={selectedValue && selectedValue >= 0 ? selectedValue : ''}
|
||||||
|
disabled={isCloudUserVal}
|
||||||
onChange={(e): void => onChangeHandler(e, setSelectedValue)}
|
onChange={(e): void => onChangeHandler(e, setSelectedValue)}
|
||||||
style={{ width: 75 }}
|
style={{ width: 75 }}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
value={selectedTimeUnit}
|
value={selectedTimeUnit}
|
||||||
onChange={currentSelectedOption}
|
onChange={currentSelectedOption}
|
||||||
|
disabled={isCloudUserVal}
|
||||||
style={{ width: 100 }}
|
style={{ width: 100 }}
|
||||||
>
|
>
|
||||||
{menuItems}
|
{menuItems}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { green, orange, volcano } from '@ant-design/colors';
|
import { green, orange, volcano } from '@ant-design/colors';
|
||||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||||
import { Card, Col, Row } from 'antd';
|
import { Card, Col } from 'antd';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { TStatus } from 'types/api/settings/getRetention';
|
import { TStatus } from 'types/api/settings/getRetention';
|
||||||
@ -43,9 +43,16 @@ function StatusMessage({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Row style={{ gap: '1rem', alignItems: 'center', justifyContent: 'center' }}>
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
gap: '1rem',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Col xs={1}>
|
<Col xs={1}>
|
||||||
<InfoCircleOutlined style={{ fontSize: '1.5rem' }} />
|
<InfoCircleOutlined style={{ fontSize: '1rem' }} />
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<Col
|
<Col
|
||||||
@ -56,7 +63,7 @@ function StatusMessage({
|
|||||||
>
|
>
|
||||||
{statusMessage}
|
{statusMessage}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
.general-settings-container {
|
.general-settings-container {
|
||||||
|
margin: 16px 8px;
|
||||||
|
|
||||||
.ant-card-body {
|
.ant-card-body {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
padding: 8px;
|
||||||
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ function UserFunction({
|
|||||||
|
|
||||||
function Members(): JSX.Element {
|
function Members(): JSX.Element {
|
||||||
const { org } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { org } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
const { status, data } = useQuery({
|
const { status, data, isLoading } = useQuery({
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
getOrgUser({
|
getOrgUser({
|
||||||
orgId: (org || [])[0].id,
|
orgId: (org || [])[0].id,
|
||||||
@ -308,7 +308,12 @@ function Members(): JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Space direction="vertical" size="middle">
|
<Space direction="vertical" size="middle">
|
||||||
<Typography.Title level={3}>Members</Typography.Title>
|
<Typography.Title level={3}>
|
||||||
|
Members{' '}
|
||||||
|
{!isLoading && dataSource && (
|
||||||
|
<div className="members-count"> ({dataSource.length}) </div>
|
||||||
|
)}
|
||||||
|
</Typography.Title>
|
||||||
<ResizeTable
|
<ResizeTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
tableLayout="fixed"
|
tableLayout="fixed"
|
||||||
|
@ -271,7 +271,12 @@ function PendingInvitesContainer(): JSX.Element {
|
|||||||
|
|
||||||
<Space direction="vertical" size="middle">
|
<Space direction="vertical" size="middle">
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Typography.Title level={3}>{t('pending_invites')}</Typography.Title>
|
<Typography.Title level={3}>
|
||||||
|
{t('pending_invites')}
|
||||||
|
{getPendingInvitesResponse.status !== 'loading' && dataSource && (
|
||||||
|
<div className="members-count"> ({dataSource.length})</div>
|
||||||
|
)}
|
||||||
|
</Typography.Title>
|
||||||
|
|
||||||
<Space>
|
<Space>
|
||||||
<Typography.Text type="warning">
|
<Typography.Text type="warning">
|
||||||
|
@ -5,7 +5,6 @@ import { isCloudUser } from 'utils/app';
|
|||||||
import {
|
import {
|
||||||
alertChannels,
|
alertChannels,
|
||||||
generalSettings,
|
generalSettings,
|
||||||
generalSettingsCloud,
|
|
||||||
ingestionSettings,
|
ingestionSettings,
|
||||||
organizationSettings,
|
organizationSettings,
|
||||||
} from './config';
|
} from './config';
|
||||||
@ -23,11 +22,12 @@ export const getRoutes = (
|
|||||||
if (isCloudUser()) {
|
if (isCloudUser()) {
|
||||||
settings.push(...ingestionSettings(t));
|
settings.push(...ingestionSettings(t));
|
||||||
settings.push(...alertChannels(t));
|
settings.push(...alertChannels(t));
|
||||||
settings.push(...generalSettingsCloud(t));
|
|
||||||
} else {
|
} else {
|
||||||
settings.push(...alertChannels(t));
|
settings.push(...alertChannels(t));
|
||||||
settings.push(...generalSettings(t));
|
settings.push(...generalSettings(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settings.push(...generalSettings(t));
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
};
|
};
|
||||||
|
@ -218,3 +218,9 @@ body {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.members-count {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user