mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-16 14:35:58 +08:00
feat: version page is added (#924)
* feat👔 : getLatestVersion api is added * chore: VERSION page is added * feat: ✨ version page is added * chore: all string is grabbed from locale * chore: warning is removed * chore: translation json is added * chore: feedback about version is added * chore: made two different functions * unused import is removed * feat: version changes are updated * chore: if current version is present then it is displayed
This commit is contained in:
parent
5744193f50
commit
2a348e916c
@ -1,5 +1,14 @@
|
||||
{
|
||||
"monitor_signup": "Monitor your applications. Find what is causing issues.",
|
||||
"version": "Version",
|
||||
"latest_version": "Latest version",
|
||||
"current_version": "Current version",
|
||||
"release_notes": "Release Notes",
|
||||
"read_how_to_upgrade": "Read instructions on how to upgrade",
|
||||
"latest_version_signoz": "You are running the latest version of SigNoz.",
|
||||
"stale_version": "You are on an older version and may be loosing on the latest features we have shipped. We recommend to upgrade to the latest version",
|
||||
"oops_something_went_wrong_version": "Oops.. facing issues with fetching updated version information",
|
||||
"n_a": "N/A",
|
||||
"routes": {
|
||||
"general": "General",
|
||||
"alert_channels": "Alert Channels"
|
||||
|
@ -85,3 +85,7 @@ export const EditAlertChannelsAlerts = Loadable(
|
||||
export const AllAlertChannels = Loadable(
|
||||
() => import(/* webpackChunkName: "All Channels" */ 'pages/AllAlertChannels'),
|
||||
);
|
||||
|
||||
export const StatusPage = Loadable(
|
||||
() => import(/* webpackChunkName: "All Status" */ 'pages/Status'),
|
||||
);
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
ServicesTablePage,
|
||||
SettingsPage,
|
||||
SignupPage,
|
||||
StatusPage,
|
||||
TraceDetail,
|
||||
TraceFilter,
|
||||
UsageExplorerPage,
|
||||
@ -113,6 +114,11 @@ const routes: AppRoutes[] = [
|
||||
exact: true,
|
||||
component: AllAlertChannels,
|
||||
},
|
||||
{
|
||||
path: ROUTES.VERSION,
|
||||
exact: true,
|
||||
component: StatusPage,
|
||||
},
|
||||
];
|
||||
|
||||
interface AppRoutes {
|
||||
|
25
frontend/src/api/user/getLatestVersion.ts
Normal file
25
frontend/src/api/user/getLatestVersion.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import axios, { AxiosError } from 'axios';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import { PayloadProps } from 'types/api/user/getLatestVersion';
|
||||
|
||||
const getLatestVersion = async (): Promise<
|
||||
SuccessResponse<PayloadProps> | ErrorResponse
|
||||
> => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://api.github.com/repos/signoz/signoz/releases/latest`,
|
||||
);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
}
|
||||
};
|
||||
|
||||
export default getLatestVersion;
|
@ -17,6 +17,7 @@ const ROUTES = {
|
||||
ALL_CHANNELS: '/settings/channels',
|
||||
CHANNELS_NEW: '/setting/channels/new',
|
||||
CHANNELS_EDIT: '/setting/channels/edit/:id',
|
||||
VERSION: '/status',
|
||||
};
|
||||
|
||||
export default ROUTES;
|
||||
|
@ -1,11 +1,24 @@
|
||||
import { notification } from 'antd';
|
||||
import getLatestVersion from 'api/user/getLatestVersion';
|
||||
import getVersion from 'api/user/getVersion';
|
||||
import ROUTES from 'constants/routes';
|
||||
import TopNav from 'container/Header';
|
||||
import SideNav from 'container/SideNav';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import history from 'lib/history';
|
||||
import React, { ReactNode, useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import React, { ReactNode, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Dispatch } from 'redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import AppActions from 'types/actions';
|
||||
import {
|
||||
UPDATE_CURRENT_ERROR,
|
||||
UPDATE_CURRENT_VERSION,
|
||||
UPDATE_LATEST_VERSION,
|
||||
UPDATE_LATEST_VERSION_ERROR,
|
||||
} from 'types/actions/app';
|
||||
import AppReducer from 'types/reducer/app';
|
||||
|
||||
import { Content, Layout } from './styles';
|
||||
@ -13,11 +26,24 @@ import { Content, Layout } from './styles';
|
||||
function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
const { isLoggedIn } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||
const { pathname } = useLocation();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isSignUpPage, setIsSignUpPage] = useState(ROUTES.SIGN_UP === pathname);
|
||||
|
||||
const { payload: versionPayload, loading, error: getVersionError } = useFetch(
|
||||
getVersion,
|
||||
);
|
||||
|
||||
const {
|
||||
payload: latestVersionPayload,
|
||||
loading: latestLoading,
|
||||
error: latestError,
|
||||
} = useFetch(getLatestVersion);
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const dispatch = useDispatch<Dispatch<AppActions>>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoggedIn) {
|
||||
setIsSignUpPage(true);
|
||||
@ -27,11 +53,71 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
}
|
||||
}, [isLoggedIn, isSignUpPage]);
|
||||
|
||||
const latestCurrentCounter = useRef(0);
|
||||
const latestVersionCounter = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoggedIn && pathname === ROUTES.SIGN_UP) {
|
||||
history.push(ROUTES.APPLICATION);
|
||||
}
|
||||
}, [isLoggedIn, pathname]);
|
||||
|
||||
if (!latestLoading && latestError && latestCurrentCounter.current === 0) {
|
||||
latestCurrentCounter.current = 1;
|
||||
|
||||
dispatch({
|
||||
type: UPDATE_LATEST_VERSION_ERROR,
|
||||
payload: {
|
||||
isError: true,
|
||||
},
|
||||
});
|
||||
notification.error({
|
||||
message: t('oops_something_went_wrong_version'),
|
||||
});
|
||||
}
|
||||
|
||||
if (!loading && getVersionError && latestVersionCounter.current === 0) {
|
||||
latestVersionCounter.current = 1;
|
||||
|
||||
dispatch({
|
||||
type: UPDATE_CURRENT_ERROR,
|
||||
payload: {
|
||||
isError: true,
|
||||
},
|
||||
});
|
||||
notification.error({
|
||||
message: t('oops_something_went_wrong_version'),
|
||||
});
|
||||
}
|
||||
|
||||
if (!latestLoading && versionPayload) {
|
||||
dispatch({
|
||||
type: UPDATE_CURRENT_VERSION,
|
||||
payload: {
|
||||
currentVersion: versionPayload.version,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!loading && latestVersionPayload) {
|
||||
dispatch({
|
||||
type: UPDATE_LATEST_VERSION,
|
||||
payload: {
|
||||
latestVersion: latestVersionPayload.name,
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [
|
||||
dispatch,
|
||||
loading,
|
||||
latestLoading,
|
||||
versionPayload,
|
||||
latestVersionPayload,
|
||||
isLoggedIn,
|
||||
pathname,
|
||||
getVersionError,
|
||||
latestError,
|
||||
t,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
|
@ -11,6 +11,7 @@ const breadcrumbNameMap = {
|
||||
[ROUTES.INSTRUMENTATION]: 'Add instrumentation',
|
||||
[ROUTES.SETTINGS]: 'Settings',
|
||||
[ROUTES.DASHBOARD]: 'Dashboard',
|
||||
[ROUTES.VERSION]: 'Status',
|
||||
};
|
||||
|
||||
function ShowBreadcrumbs(props: RouteComponentProps): JSX.Element {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { CheckCircleTwoTone, WarningOutlined } from '@ant-design/icons';
|
||||
import { Menu, Typography } from 'antd';
|
||||
import getLocalStorageKey from 'api/browser/localstorage/get';
|
||||
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
||||
@ -5,6 +6,7 @@ import ROUTES from 'constants/routes';
|
||||
import history from 'lib/history';
|
||||
import setTheme, { AppMode } from 'lib/theme/setTheme';
|
||||
import React, { useCallback, useLayoutEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { connect, useDispatch, useSelector } from 'react-redux';
|
||||
import { NavLink, useLocation } from 'react-router-dom';
|
||||
import { bindActionCreators } from 'redux';
|
||||
@ -19,11 +21,13 @@ import menus from './menuItems';
|
||||
import Slack from './Slack';
|
||||
import {
|
||||
Logo,
|
||||
RedDot,
|
||||
Sider,
|
||||
SlackButton,
|
||||
SlackMenuItemContainer,
|
||||
ThemeSwitcherWrapper,
|
||||
ToggleButton,
|
||||
VersionContainer,
|
||||
} from './styles';
|
||||
|
||||
function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
||||
@ -31,9 +35,15 @@ function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
||||
const [collapsed, setCollapsed] = useState<boolean>(
|
||||
getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true',
|
||||
);
|
||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||
const {
|
||||
isDarkMode,
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
isCurrentVersionError,
|
||||
} = useSelector<AppState, AppReducer>((state) => state.app);
|
||||
|
||||
const { pathname } = useLocation();
|
||||
const { t } = useTranslation('');
|
||||
|
||||
const toggleTheme = useCallback(() => {
|
||||
const preMode: AppMode = isDarkMode ? 'lightMode' : 'darkMode';
|
||||
@ -77,6 +87,38 @@ function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
||||
window.open('https://signoz.io/slack', '_blank');
|
||||
};
|
||||
|
||||
const onClickVersionHandler = (): void => {
|
||||
history.push(ROUTES.VERSION);
|
||||
};
|
||||
|
||||
const isNotCurrentVersion = currentVersion !== latestVersion;
|
||||
|
||||
const sidebar = [
|
||||
{
|
||||
onClick: onClickSlackHandler,
|
||||
icon: <Slack />,
|
||||
text: <SlackButton>Support</SlackButton>,
|
||||
},
|
||||
{
|
||||
onClick: onClickVersionHandler,
|
||||
icon: isNotCurrentVersion ? (
|
||||
<WarningOutlined style={{ color: '#E87040' }} />
|
||||
) : (
|
||||
<CheckCircleTwoTone twoToneColor={['#D5F2BB', '#1f1f1f']} />
|
||||
),
|
||||
text: (
|
||||
<VersionContainer>
|
||||
{!isCurrentVersionError ? (
|
||||
<SlackButton>{currentVersion}</SlackButton>
|
||||
) : (
|
||||
<SlackButton>{t('n_a')}</SlackButton>
|
||||
)}
|
||||
{isNotCurrentVersion && <RedDot />}
|
||||
</VersionContainer>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse} width={200}>
|
||||
<ThemeSwitcherWrapper>
|
||||
@ -87,7 +129,7 @@ function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
||||
/>
|
||||
</ThemeSwitcherWrapper>
|
||||
<NavLink to={ROUTES.APPLICATION}>
|
||||
<Logo src="/signoz.svg" alt="SigNoz" collapsed={collapsed} />
|
||||
<Logo index={0} src="/signoz.svg" alt="SigNoz" collapsed={collapsed} />
|
||||
</NavLink>
|
||||
|
||||
<Menu
|
||||
@ -105,11 +147,21 @@ function SideNav({ toggleDarkMode }: Props): JSX.Element {
|
||||
<Typography>{name}</Typography>
|
||||
</Menu.Item>
|
||||
))}
|
||||
<SlackMenuItemContainer collapsed={collapsed}>
|
||||
<Menu.Item onClick={onClickSlackHandler} icon={<Slack />}>
|
||||
<SlackButton>Support</SlackButton>
|
||||
</Menu.Item>
|
||||
</SlackMenuItemContainer>
|
||||
{sidebar.map((props, index) => (
|
||||
<SlackMenuItemContainer
|
||||
index={index + 1}
|
||||
key={`${index + 1}`}
|
||||
collapsed={collapsed}
|
||||
>
|
||||
<Menu.Item
|
||||
eventKey={index.toString()}
|
||||
onClick={props.onClick}
|
||||
icon={props.icon}
|
||||
>
|
||||
{props.text}
|
||||
</Menu.Item>
|
||||
</SlackMenuItemContainer>
|
||||
))}
|
||||
</Menu>
|
||||
</Sider>
|
||||
);
|
||||
|
@ -19,6 +19,7 @@ export const Logo = styled.img<LogoProps>`
|
||||
|
||||
interface LogoProps {
|
||||
collapsed: boolean;
|
||||
index: number;
|
||||
}
|
||||
|
||||
export const Sider = styled(SiderComponent)`
|
||||
@ -50,9 +51,10 @@ export const SlackButton = styled(Typography)`
|
||||
|
||||
export const SlackMenuItemContainer = styled.div<LogoProps>`
|
||||
position: fixed;
|
||||
bottom: 48px;
|
||||
bottom: ${({ index }): string => `${index * 48 + (index + 16)}px`};
|
||||
background: #262626;
|
||||
width: ${({ collapsed }): string => (!collapsed ? '200px' : '80px')};
|
||||
transition: inherit;
|
||||
|
||||
&&& {
|
||||
li {
|
||||
@ -60,11 +62,14 @@ export const SlackMenuItemContainer = styled.div<LogoProps>`
|
||||
collapsed &&
|
||||
css`
|
||||
padding-left: 24px;
|
||||
padding-top: 6px;
|
||||
`}
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-left: ${({ collapsed }): string => (collapsed ? '0' : '24px')};
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
|
||||
${({ collapsed }): StyledCSS =>
|
||||
collapsed &&
|
||||
@ -73,5 +78,24 @@ export const SlackMenuItemContainer = styled.div<LogoProps>`
|
||||
margin: 0 auto;
|
||||
`}
|
||||
}
|
||||
.ant-menu-title-content {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const RedDot = styled.div`
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: #d32029;
|
||||
border-radius: 50%;
|
||||
|
||||
margin-left: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
`;
|
||||
|
||||
export const VersionContainer = styled.div`
|
||||
&&& {
|
||||
display: flex;
|
||||
}
|
||||
`;
|
||||
|
110
frontend/src/container/Version/index.tsx
Normal file
110
frontend/src/container/Version/index.tsx
Normal file
@ -0,0 +1,110 @@
|
||||
import { WarningFilled } from '@ant-design/icons';
|
||||
import { Button, Card, Form, Space, Typography } from 'antd';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import AppReducer from 'types/reducer/app';
|
||||
|
||||
import { InputComponent } from './styles';
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
function Version(): JSX.Element {
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onClickUpgradeHandler = useCallback((link: string) => {
|
||||
window.open(link, '_blank');
|
||||
}, []);
|
||||
|
||||
const {
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
isCurrentVersionError,
|
||||
isLatestVersionError,
|
||||
} = useSelector<AppState, AppReducer>((state) => state.app);
|
||||
|
||||
const isLatestVersion = currentVersion === latestVersion;
|
||||
const isError = isCurrentVersionError || isLatestVersionError;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<Title ellipsis level={4}>
|
||||
{t('version')}
|
||||
</Title>
|
||||
|
||||
<Form
|
||||
wrapperCol={{
|
||||
span: 14,
|
||||
}}
|
||||
labelCol={{
|
||||
span: 3,
|
||||
}}
|
||||
layout="horizontal"
|
||||
form={form}
|
||||
labelAlign="left"
|
||||
>
|
||||
<Form.Item label={t('current_version')}>
|
||||
<InputComponent
|
||||
readOnly
|
||||
value={isCurrentVersionError ? t('n_a').toString() : currentVersion}
|
||||
placeholder={t('current_version')}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label={t('latest_version')}>
|
||||
<InputComponent
|
||||
readOnly
|
||||
value={isLatestVersionError ? t('n_a').toString() : latestVersion}
|
||||
placeholder={t('latest_version')}
|
||||
/>
|
||||
<Button
|
||||
onClick={(): void =>
|
||||
onClickUpgradeHandler('https://github.com/SigNoz/signoz/releases')
|
||||
}
|
||||
type="link"
|
||||
>
|
||||
{t('release_notes')}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
{!isError && isLatestVersion && (
|
||||
<div>
|
||||
<Space align="start">
|
||||
<span>✅</span>
|
||||
<Typography.Paragraph italic>
|
||||
{t('latest_version_signoz')}
|
||||
</Typography.Paragraph>
|
||||
</Space>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isError && !isLatestVersion && (
|
||||
<div>
|
||||
<Space align="start">
|
||||
<span>
|
||||
<WarningFilled style={{ color: '#E87040' }} />
|
||||
</span>
|
||||
<Typography.Paragraph italic>{t('stale_version')}</Typography.Paragraph>
|
||||
</Space>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isError && !isLatestVersion && (
|
||||
<Button
|
||||
onClick={(): void =>
|
||||
onClickUpgradeHandler(
|
||||
'https://signoz.io/docs/operate/docker-standalone/#upgrade',
|
||||
)
|
||||
}
|
||||
>
|
||||
{t('read_how_to_upgrade')}
|
||||
</Button>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default Version;
|
8
frontend/src/container/Version/styles.ts
Normal file
8
frontend/src/container/Version/styles.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Input } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const InputComponent = styled(Input)`
|
||||
&&& {
|
||||
max-width: 183px;
|
||||
}
|
||||
`;
|
8
frontend/src/pages/Status/index.tsx
Normal file
8
frontend/src/pages/Status/index.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
import Version from 'container/Version';
|
||||
import React from 'react';
|
||||
|
||||
function Status(): JSX.Element {
|
||||
return <Version />;
|
||||
}
|
||||
|
||||
export default Status;
|
@ -7,6 +7,10 @@ import {
|
||||
LOGGED_IN,
|
||||
SIDEBAR_COLLAPSE,
|
||||
SWITCH_DARK_MODE,
|
||||
UPDATE_CURRENT_ERROR,
|
||||
UPDATE_CURRENT_VERSION,
|
||||
UPDATE_LATEST_VERSION,
|
||||
UPDATE_LATEST_VERSION_ERROR,
|
||||
} from 'types/actions/app';
|
||||
import InitialValueTypes from 'types/reducer/app';
|
||||
|
||||
@ -14,6 +18,10 @@ const InitialValue: InitialValueTypes = {
|
||||
isDarkMode: getTheme() === 'darkMode',
|
||||
isLoggedIn: getLocalStorageKey(IS_LOGGED_IN) === 'yes',
|
||||
isSideBarCollapsed: getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true',
|
||||
currentVersion: '',
|
||||
latestVersion: '',
|
||||
isCurrentVersionError: false,
|
||||
isLatestVersionError: false,
|
||||
};
|
||||
|
||||
const appReducer = (
|
||||
@ -42,6 +50,28 @@ const appReducer = (
|
||||
};
|
||||
}
|
||||
|
||||
case UPDATE_CURRENT_VERSION: {
|
||||
return {
|
||||
...state,
|
||||
currentVersion: action.payload.currentVersion,
|
||||
};
|
||||
}
|
||||
|
||||
case UPDATE_LATEST_VERSION: {
|
||||
return { ...state, latestVersion: action.payload.latestVersion };
|
||||
}
|
||||
|
||||
case UPDATE_CURRENT_ERROR: {
|
||||
return { ...state, isCurrentVersionError: true };
|
||||
}
|
||||
|
||||
case UPDATE_LATEST_VERSION_ERROR: {
|
||||
return {
|
||||
...state,
|
||||
isLatestVersionError: true,
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -1,7 +1,15 @@
|
||||
import AppReducer from 'types/reducer/app';
|
||||
|
||||
export const SWITCH_DARK_MODE = 'SWITCH_DARK_MODE';
|
||||
export const LOGGED_IN = 'LOGGED_IN';
|
||||
export const SIDEBAR_COLLAPSE = 'SIDEBAR_COLLAPSE';
|
||||
|
||||
export const UPDATE_CURRENT_VERSION = 'UPDATE_CURRENT_VERSION';
|
||||
export const UPDATE_LATEST_VERSION = 'UPDATE_LATEST_VERSION';
|
||||
|
||||
export const UPDATE_CURRENT_ERROR = 'UPDATE_CURRENT_ERROR';
|
||||
export const UPDATE_LATEST_VERSION_ERROR = 'UPDATE_LATEST_VERSION_ERROR';
|
||||
|
||||
export interface SwitchDarkMode {
|
||||
type: typeof SWITCH_DARK_MODE;
|
||||
}
|
||||
@ -15,4 +23,31 @@ export interface SideBarCollapse {
|
||||
payload: boolean;
|
||||
}
|
||||
|
||||
export type AppAction = SwitchDarkMode | LoggedInUser | SideBarCollapse;
|
||||
export interface UpdateAppVersion {
|
||||
type: typeof UPDATE_CURRENT_VERSION;
|
||||
payload: {
|
||||
currentVersion: AppReducer['currentVersion'];
|
||||
};
|
||||
}
|
||||
|
||||
export interface UpdateLatestVersion {
|
||||
type: typeof UPDATE_LATEST_VERSION;
|
||||
payload: {
|
||||
latestVersion: AppReducer['latestVersion'];
|
||||
};
|
||||
}
|
||||
|
||||
export interface UpdateVersionError {
|
||||
type: typeof UPDATE_CURRENT_ERROR | typeof UPDATE_LATEST_VERSION_ERROR;
|
||||
payload: {
|
||||
isError: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export type AppAction =
|
||||
| SwitchDarkMode
|
||||
| LoggedInUser
|
||||
| SideBarCollapse
|
||||
| UpdateAppVersion
|
||||
| UpdateLatestVersion
|
||||
| UpdateVersionError;
|
||||
|
18
frontend/src/types/api/user/getLatestVersion.ts
Normal file
18
frontend/src/types/api/user/getLatestVersion.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export interface PayloadProps {
|
||||
body: string;
|
||||
created_at: string;
|
||||
draft: boolean;
|
||||
html_url: string;
|
||||
id: number;
|
||||
mentions_count: number;
|
||||
name: string;
|
||||
node_id: number;
|
||||
prerelease: boolean;
|
||||
published_at: string;
|
||||
tag_name: number;
|
||||
tarball_url: string;
|
||||
target_commitish: string;
|
||||
upload_url: string;
|
||||
url: string;
|
||||
zipball_url: string;
|
||||
}
|
@ -2,4 +2,8 @@ export default interface AppReducer {
|
||||
isDarkMode: boolean;
|
||||
isLoggedIn: boolean;
|
||||
isSideBarCollapsed: boolean;
|
||||
currentVersion: string;
|
||||
latestVersion: string;
|
||||
isCurrentVersionError: boolean;
|
||||
isLatestVersionError: boolean;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user