mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-10-13 12:11:29 +08:00

* feat: dashboard list view * feat: update sort menu items * feat: wire up add / import dashboard functionss * feat: update import json styles * feat: new dashboard templates modal * feat: add template filter logic * feat: revamp the overview settings modal (#4894) * feat: revamp the overview settings modal * feat: dashboard settings variable landing page * feat: dashboard add variable button settings * feat: add variable modal changes * feat: handle the unsaved changes for general settings * feat: follow ups for side panel section for dashboards (#4906) * feat: changes for tags input * feat: side panel header styles * feat: changes for textbox variable * feat: handle changes for custom type variable * feat: overflow preview vales * feat: overflow preview vales * feat: setup for new dashboard landing page (#4921) * feat: setup for new dashboard landing page * feat: added empty state widgets * feat: added functionality to the configure and the add panel button * feat: tag variables changes * feat: dashboard revamp changes follow ups (#4929) * feat: changes for new panel type modal * fix: added missing / in the breadcrumbs * feat: added dashboard settings menu items * feat: added dashboard rename modal * feat: move full screen handle a few components up * feat: handle rename and copy export changes * feat: minor cleanup * feat: delete button changes * feat: dashboard widget edit page design revamp (#4946) * feat: dashboard edit page base setup * feat: right container design revamp * feat: alerts and thresholds changes right container * feat: right container * feat: fix graph styles * fix: some edits for dashboard edit page * feat: threshold preview changes (#4990) * feat: threshold preview changes * feat: threshold preview changes * feat: threshold discard handler * fix: remove the horizontal scroll from the dashboards landing page * fix: added margin to dashboard widgets (#4991) * fix: rebase conflicts * feat: dashboard panel grouping change for new designs (#4992) * feat: dashboard panel groping base cleanups * feat: move add panel code from inner component to parent component * feat: new dashboard section panel naming modal * feat: dashboard panel groping base cleanups * feat: grip changes * feat: dashboard list page revamp and functionality additions (#4994) * feat: fix types and code structure for list page * feat: dashboard actions * feat: design changes for tags * feat: design changes for tags * feat: update import json styles * feat: added all dashboards row * feat: added configure metadata linking * feat: added local storage changes for dynamic columns * feat: added user metadata display for metadata modal * feat: configure metadata final changes * feat: handle dashboard list loading state * feat: sort and pagination changes for dashboard list view designs (#4996) * feat: minor list view css changes * feat: added sort functionality to the dashboards list * feat: added sort functionality to the dashboards list * feat: added name dropdown in the settings drawer and image as base64 format (#5000) * feat: added name input in settings drawer * feat: discard handler * feat: implemented the name dropdown * feat: added dashboard list page header * fix: margin of dashboard list container * feat: dashboard empty state (#5005) * feat: light mode changes for new dashboard revamp (#5006) * feat: light mode changes for dahsboards list page * feat: dashboard description landing page changes * feat: variable panels landing page light theme changes * feat: dashboard edit panel light mode * feat: added dashboard list error state (#5011) * feat: added missing light mode designs * fix: usability / customer issues (#5014) * fix: [GH-4986]: preview values not getting updated when the query result is empty * fix: [GH-4985]: fix the usability of dahsboards variables drawer * fix: light mode design for component slider * fix: code cleanup * fix: 0 being added in case of no tags * fix: minor styling fixes * fix: handle silent error for dashboard edit mutation (#5022) * fix: handle silent error for dashboard edit mutation * fix: handle silent error for dashboard edit mutation * fix: rbac changes * fix: grip icon color * fix: new dashboards feedback from testing (#5030) * fix: hide create new dashboards from viewer roles * fix: move the elipsis button right of date time picker and make it a button * fix: remove duplicate button from actions for now * fix: last updated by and created by difference * fix: hide intercom for modals * fix: actions popover not closing * fix: temp remove templates modal from normal flow * fix: delete button event propagation * fix: minor UI fixes (#5032) * fix: update dashboards landing page icons * fix: added lock icon for locked dashboards * fix: updated dashboards list page styles * fix: comment out filters code for phase 2 (#5034) * fix: dashboard revamp ui fixes (#5037) * fix: increase the width of the graph section * fix: remove select and next from component slider * Dashboard vqa 1 (#5090) * fix: dashboard VQA pt 1 * fix: dashboard VQA pt 2 * fix: dashboard VQA pt 3 * fix: dashboard VQA pt 4 * fix: dashboard VQA pt 5 * fix: dashboard VQA pt 6 * fix: dashboard VQA pt 7 * fix: added dashboard locked footer and base64 icons (#5091) * fix: added dashboard locked footer * fix: update base64 images * fix: dashboard delete hover and row actions refactor * fix: dashboard vqa pt 2 (#5098) * fix: review comments * fix: alerts plot tag spacing * fix: css variables update --------- Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
251 lines
6.5 KiB
TypeScript
251 lines
6.5 KiB
TypeScript
import './importJSON.styles.scss';
|
|
|
|
import { red } from '@ant-design/colors';
|
|
import { ExclamationCircleTwoTone } from '@ant-design/icons';
|
|
import MEditor, { Monaco } from '@monaco-editor/react';
|
|
import { Color } from '@signozhq/design-tokens';
|
|
import { Button, Modal, Space, Typography, Upload, UploadProps } from 'antd';
|
|
import createDashboard from 'api/dashboard/create';
|
|
import ROUTES from 'constants/routes';
|
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
|
import { MESSAGE } from 'hooks/useFeatureFlag';
|
|
import { useNotifications } from 'hooks/useNotifications';
|
|
import { getUpdatedLayout } from 'lib/dashboard/getUpdatedLayout';
|
|
import history from 'lib/history';
|
|
import { MonitorDot, MoveRight, X } from 'lucide-react';
|
|
import { useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { generatePath } from 'react-router-dom';
|
|
import { DashboardData } from 'types/api/dashboard/getAll';
|
|
|
|
function ImportJSON({
|
|
isImportJSONModalVisible,
|
|
uploadedGrafana,
|
|
onModalHandler,
|
|
}: ImportJSONProps): JSX.Element {
|
|
const [jsonData, setJsonData] = useState<Record<string, unknown>>();
|
|
const { t } = useTranslation(['dashboard', 'common']);
|
|
const [isUploadJSONError, setIsUploadJSONError] = useState<boolean>(false);
|
|
const [isCreateDashboardError, setIsCreateDashboardError] = useState<boolean>(
|
|
false,
|
|
);
|
|
const [isFeatureAlert, setIsFeatureAlert] = useState<boolean>(false);
|
|
|
|
const [dashboardCreating, setDashboardCreating] = useState<boolean>(false);
|
|
|
|
const [editorValue, setEditorValue] = useState<string>('');
|
|
|
|
const { notifications } = useNotifications();
|
|
|
|
const onChangeHandler: UploadProps['onChange'] = (info) => {
|
|
const { fileList } = info;
|
|
const reader = new FileReader();
|
|
|
|
const lastFile = fileList[fileList.length - 1];
|
|
|
|
if (lastFile.originFileObj) {
|
|
reader.onload = async (event): Promise<void> => {
|
|
if (event.target) {
|
|
const target = event.target.result;
|
|
try {
|
|
if (target) {
|
|
const targetFile = target.toString();
|
|
const parsedValue = JSON.parse(targetFile);
|
|
setJsonData(parsedValue);
|
|
setEditorValue(JSON.stringify(parsedValue, null, 2));
|
|
setIsUploadJSONError(false);
|
|
}
|
|
} catch (error) {
|
|
setIsUploadJSONError(true);
|
|
}
|
|
}
|
|
};
|
|
reader.readAsText(lastFile.originFileObj);
|
|
}
|
|
};
|
|
|
|
const onClickLoadJsonHandler = async (): Promise<void> => {
|
|
try {
|
|
setDashboardCreating(true);
|
|
const dashboardData = JSON.parse(editorValue) as DashboardData;
|
|
|
|
if (dashboardData?.layout) {
|
|
dashboardData.layout = getUpdatedLayout(dashboardData.layout);
|
|
} else {
|
|
dashboardData.layout = [];
|
|
}
|
|
|
|
const response = await createDashboard({
|
|
...dashboardData,
|
|
uploadedGrafana,
|
|
});
|
|
|
|
if (response.statusCode === 200) {
|
|
history.push(
|
|
generatePath(ROUTES.DASHBOARD, {
|
|
dashboardId: response.payload.uuid,
|
|
}),
|
|
);
|
|
} else if (response.error === 'feature usage exceeded') {
|
|
setIsFeatureAlert(true);
|
|
notifications.error({
|
|
message:
|
|
response.error ||
|
|
t('something_went_wrong', {
|
|
ns: 'common',
|
|
}),
|
|
});
|
|
} else {
|
|
setIsCreateDashboardError(true);
|
|
notifications.error({
|
|
message:
|
|
response.error ||
|
|
t('something_went_wrong', {
|
|
ns: 'common',
|
|
}),
|
|
});
|
|
}
|
|
setDashboardCreating(false);
|
|
} catch {
|
|
setDashboardCreating(false);
|
|
setIsFeatureAlert(false);
|
|
|
|
setIsCreateDashboardError(true);
|
|
}
|
|
};
|
|
|
|
const getErrorNode = (error: string): JSX.Element => (
|
|
<Space>
|
|
<ExclamationCircleTwoTone twoToneColor={[red[7], '#1f1f1f']} />
|
|
<Typography style={{ color: '#D89614' }}>{error}</Typography>
|
|
</Space>
|
|
);
|
|
|
|
const onCancelHandler = (): void => {
|
|
setIsUploadJSONError(false);
|
|
setIsCreateDashboardError(false);
|
|
setIsFeatureAlert(false);
|
|
onModalHandler();
|
|
};
|
|
|
|
const isDarkMode = useIsDarkMode();
|
|
|
|
function setEditorTheme(monaco: Monaco): void {
|
|
monaco.editor.defineTheme('my-theme', {
|
|
base: 'vs-dark',
|
|
inherit: true,
|
|
rules: [
|
|
{ token: 'string.key.json', foreground: Color.BG_VANILLA_400 },
|
|
{ token: 'string.value.json', foreground: Color.BG_ROBIN_400 },
|
|
],
|
|
colors: {
|
|
'editor.background': Color.BG_INK_300,
|
|
},
|
|
fontFamily: 'Space Mono',
|
|
fontSize: 20,
|
|
fontWeight: 'normal',
|
|
lineHeight: 18,
|
|
letterSpacing: -0.06,
|
|
});
|
|
}
|
|
|
|
return (
|
|
<Modal
|
|
wrapClassName="import-json-modal"
|
|
open={isImportJSONModalVisible}
|
|
centered
|
|
closable={false}
|
|
destroyOnClose
|
|
width="60vw"
|
|
footer={
|
|
<div className="import-json-modal-footer">
|
|
{isCreateDashboardError && (
|
|
<div className="create-dashboard-json-error">
|
|
{getErrorNode(t('error_loading_json'))}
|
|
</div>
|
|
)}
|
|
|
|
{isUploadJSONError && (
|
|
<div className="create-dashboard-json-error">
|
|
{getErrorNode(t('error_upload_json'))}
|
|
</div>
|
|
)}
|
|
|
|
<div className="action-btns-container">
|
|
<Upload
|
|
accept=".json"
|
|
showUploadList={false}
|
|
multiple={false}
|
|
onChange={onChangeHandler}
|
|
beforeUpload={(): boolean => false}
|
|
action="none"
|
|
data={jsonData}
|
|
>
|
|
<Button
|
|
type="default"
|
|
className="periscope-btn"
|
|
icon={<MonitorDot size={14} />}
|
|
>
|
|
{' '}
|
|
{t('upload_json_file')}
|
|
</Button>
|
|
</Upload>
|
|
|
|
<Button
|
|
// disabled={editorValue.length === 0}
|
|
onClick={onClickLoadJsonHandler}
|
|
loading={dashboardCreating}
|
|
className="periscope-btn primary"
|
|
type="primary"
|
|
>
|
|
{t('import_and_next')} <MoveRight size={14} />
|
|
</Button>
|
|
|
|
{isFeatureAlert && (
|
|
<Typography.Text type="danger">
|
|
{MESSAGE.CREATE_DASHBOARD}
|
|
</Typography.Text>
|
|
)}
|
|
</div>
|
|
</div>
|
|
}
|
|
>
|
|
<div className="import-json-content-container">
|
|
<div className="import-json-content-header">
|
|
<Typography.Text>{t('import_json')}</Typography.Text>
|
|
|
|
<X size={14} className="periscope-btn ghost" onClick={onCancelHandler} />
|
|
</div>
|
|
|
|
<MEditor
|
|
language="json"
|
|
height="40vh"
|
|
onChange={(newValue): void => setEditorValue(newValue || '')}
|
|
value={editorValue}
|
|
options={{
|
|
scrollbar: {
|
|
alwaysConsumeMouseWheel: false,
|
|
},
|
|
minimap: {
|
|
enabled: false,
|
|
},
|
|
fontSize: 14,
|
|
fontFamily: 'Space Mono',
|
|
}}
|
|
theme={isDarkMode ? 'my-theme' : 'light'}
|
|
// eslint-disable-next-line react/jsx-no-bind
|
|
beforeMount={setEditorTheme}
|
|
/>
|
|
</div>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
interface ImportJSONProps {
|
|
isImportJSONModalVisible: boolean;
|
|
onModalHandler: VoidFunction;
|
|
uploadedGrafana: boolean;
|
|
}
|
|
|
|
export default ImportJSON;
|