Web: Added product version badge

This commit is contained in:
Ilya Oleshko 2021-02-18 15:55:26 +03:00
parent 07077ee655
commit cb72f2241b
12 changed files with 119 additions and 18 deletions

View File

@ -38,6 +38,7 @@ const {
getIsEncryptionSupport,
getEncryptionKeys,
getIsAuthenticated,
setProductVersion,
} = commonStore.auth.actions;
const {
getCurrentUser,
@ -68,9 +69,11 @@ class App extends React.Component {
getEncryptionKeys,
isDesktop,
getIsAuthenticated,
setProductVersion,
} = this.props;
setModuleInfo();
setProductVersion();
if (this.isEditor) {
setIsLoaded();
@ -229,6 +232,7 @@ const mapDispatchToProps = (dispatch) => {
getIsEncryptionSupport: () => getIsEncryptionSupport(dispatch),
getEncryptionKeys: () => getEncryptionKeys(dispatch),
setEncryptionKeys: (keys) => dispatch(setEncryptionKeys(keys)),
setProductVersion: () => dispatch(setProductVersion(config.version)),
};
};

View File

@ -37,6 +37,7 @@ const {
getPortalPasswordSettings,
getPortalCultures,
getIsAuthenticated,
setProductVersion,
} = commonStore.auth.actions;
/*const Profile = lazy(() => import("./components/pages/Profile"));
@ -56,9 +57,12 @@ class App extends React.Component {
fetchPeople,
setIsLoaded,
getIsAuthenticated,
setProductVersion,
} = this.props;
setModuleInfo();
setProductVersion();
getIsAuthenticated().then((isAuthenticated) => {
if (!isAuthenticated) {
utils.updateTempContent();
@ -191,6 +195,7 @@ const mapDispatchToProps = (dispatch) => {
return Promise.resolve();
},
setIsLoaded: () => dispatch(setIsLoaded(true)),
setProductVersion: () => dispatch(setProductVersion(config.version)),
};
};

View File

@ -16,6 +16,7 @@ import {
Layout,
} from "asc-web-common";
import Home from "./components/pages/Home";
import config from "../package.json";
const About = lazy(() => import("./components/pages/About"));
const Confirm = lazy(() => import("./components/pages/Confirm"));
@ -30,6 +31,7 @@ const {
getPortalSettings,
getModules,
getIsAuthenticated,
setProductVersion,
} = CommonStore.auth.actions;
class App extends React.Component {
@ -46,8 +48,11 @@ class App extends React.Component {
getModules,
setIsLoaded,
getIsAuthenticated,
setProductVersion,
} = this.props;
setProductVersion();
getIsAuthenticated()
.then((isAuthenticated) => {
if (isAuthenticated) utils.updateTempContent(isAuthenticated);
@ -156,6 +161,7 @@ const mapDispatchToProps = (dispatch) => {
getUser: () => getUser(dispatch),
getModules: () => getModules(dispatch),
setIsLoaded: () => dispatch(setIsLoaded(true)),
setProductVersion: () => dispatch(setProductVersion(config.version)),
};
};

View File

@ -7,6 +7,7 @@ import { Text, Link, Icons, Badge, Box } from "asc-web-components";
import { toastr, PageLayout, utils, store, Loaders } from "asc-web-common";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
import { isMobile, isIOS, isAndroid } from "react-device-detect";
import { createI18N } from "../../../helpers/i18n";
import { setDocumentTitle } from "../../../helpers/utils";
@ -22,7 +23,8 @@ const i18n = createI18N({
const { changeLanguage } = utils;
const ComingSoonPage = styled.div`
width: 375px;
padding: ${isMobile ? "62px 0 0 0" : "0"};
width: 336px;
margin: 0 auto;
.module-logo-icon {
@ -48,14 +50,25 @@ const ComingSoonPage = styled.div`
margin: 8px 0;
.view-web-link {
margin: 8px;
:focus {
outline: 0;
}
}
}
`;
const ExternalLink = ({ label }) => (
const ExternalLink = ({ label, href }) => (
<Box className="link-box">
<Icons.ExternalLinkIcon color="#333333" size="small" />
<Link as="span" className="view-web-link" color="#555F65" isBold isHovered>
<Link
as="a"
href={href}
target="_blank"
className="view-web-link"
color="#555F65"
isBold
isHovered
>
{label}
</Link>
</Box>
@ -66,7 +79,17 @@ const Body = ({ modules, match, isLoaded, setCurrentProductId }) => {
const { error } = match.params;
const pageLink = window.location.pathname;
const currentModule = modules.find((m) => m.link === pageLink);
const { id, title, description, imageUrl } = currentModule;
const { id, title, description, imageUrl, link } = currentModule;
const appLink =
id === "2A923037-8B2D-487b-9A22-5AC0918ACF3F"
? "mailto:"
: id === "32D24CB5-7ECE-4606-9C94-19216BA42086"
? isIOS
? "webcal:"
: isAndroid
? "content://com.android.calendar/time/"
: false
: false;
setDocumentTitle();
@ -98,7 +121,7 @@ const Body = ({ modules, match, isLoaded, setCurrentProductId }) => {
)}
src={imageUrl}
/>
<Box displayProp="flex" flexDirection="column" widthProp="200px">
<Box displayProp="flex" flexDirection="column" widthProp="220px">
<Text fontWeight="600" fontSize="19px" className="module-title">
{title}
</Text>
@ -109,12 +132,15 @@ const Body = ({ modules, match, isLoaded, setCurrentProductId }) => {
borderRadius="2px"
className="coming-soon-badge"
/>
<ExternalLink label={t("ViewWeb")} />
<ExternalLink
label={t("OpenApp", {
title: "App",
})}
/>
<ExternalLink label={t("ViewWeb")} href={link} />
{appLink && (
<ExternalLink
label={t("OpenApp", {
title: title,
})}
href={appLink}
/>
)}
</Box>
</ComingSoonPage>
);

View File

@ -1,5 +1,5 @@
{
"ComingSoon": "Скоро появится",
"ViewWeb": "Просмотреть веб-версию",
"OpenApp": "Откройте приложение {{title}}"
"OpenApp": "Откройте {{title}}"
}

View File

@ -17,6 +17,7 @@ export const SET_LOGO_SIZES = "SET_LOGO_SIZES";
export const SET_LOGO_URLS = "SET_LOGO_URLS";
export const SET_CONSUMERS = "SET_CONSUMERS";
export const SET_SELECTED_CONSUMER = "SET_SELECTED_CONSUMER";
export const SET_PRODUCT_VERSION = "SET_PRODUCT_VERSION";
export function setOptions(options) {
return {

View File

@ -10,5 +10,7 @@
"Profile": "Profile",
"AboutCompanyTitle": "About this program",
"LogoutButton": "Sign Out",
"Settings": "Settings"
"Settings": "Settings",
"Version": "Version",
"AboutShort": "About"
}

View File

@ -10,5 +10,7 @@
"Profile": "Профиль",
"AboutCompanyTitle": "О программе",
"LogoutButton": "Выйти",
"Settings": "Настройки"
"Settings": "Настройки",
"Version": "Версия",
"AboutShort": "О программе"
}

View File

@ -8,8 +8,9 @@ import NavLogoItem from "./nav-logo-item";
import Loaders from "../../Loaders/index";
import { ReactSVG } from "react-svg";
import { useTranslation } from "react-i18next";
import { utils } from "asc-web-components";
import { utils, Box, Link, Text } from "asc-web-components";
import { connect } from "react-redux";
import {
getCurrentProductId,
@ -72,6 +73,12 @@ const Header = styled.header`
}
`;
const versionBadgeProps = {
color: "#7A95B0",
fontWeight: "600",
fontSize: "13px",
};
const HeaderComponent = ({
currentProductName,
totalNotifications,
@ -84,9 +91,12 @@ const HeaderComponent = ({
currentProductId,
toggleAside,
isLoaded,
version,
isAuthenticated,
...props
}) => {
const { t } = useTranslation();
const isNavAvailable = mainModules.length > 0;
const onLogoClick = () => {
window.open(defaultPage, "_self");
@ -152,7 +162,7 @@ const HeaderComponent = ({
iconUrl,
notifications,
onClick,
url,
link,
title,
}) => (
<NavItem
@ -166,12 +176,29 @@ const HeaderComponent = ({
badgeNumber={notifications}
onClick={onClick}
onBadgeClick={onBadgeClick}
url={url}
link={link}
>
{title}
</NavItem>
)
)}
<Box className="version-box">
<Link
as="a"
href={`https://github.com/ONLYOFFICE/AppServer/releases`}
target="_blank"
{...versionBadgeProps}
>
{t("Version")} {version}
</Link>
<Text as="span" {...versionBadgeProps}>
{" "}
-{" "}
</Text>
<Link as="a" href="/about" target="_blank" {...versionBadgeProps}>
{t("AboutShort")}
</Link>
</Box>
</Nav>
)}
</>
@ -193,12 +220,13 @@ HeaderComponent.propTypes = {
toggleAside: PropTypes.func,
logoUrl: PropTypes.string,
isLoaded: PropTypes.bool,
version: PropTypes.string,
isAuthenticated: PropTypes.bool,
};
const mapStateToProps = (state) => {
const { logoUrl } = state.auth.settings;
const { isAuthenticated } = state.auth;
const { isAuthenticated, version } = state.auth;
return {
defaultPage: getDefaultPage(state),
@ -208,6 +236,7 @@ const mapStateToProps = (state) => {
currentProductId: getCurrentProductId(state),
isLoaded: getIsLoaded(state),
logoUrl,
version,
isAuthenticated,
};
};

View File

@ -17,6 +17,16 @@ const StyledNav = styled.nav`
width: ${(props) => (props.opened ? "240px" : "0")};
z-index: 200;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
.version-box {
position: inherit;
left: 16px;
bottom: 16px;
white-space: nowrap;
a:focus {
outline: 0;
}
}
`;
const StyledScrollbar = styled(Scrollbar)`

View File

@ -28,6 +28,7 @@ export const SET_IS_ENCRYPTION_SUPPORT = "SET_IS_ENCRYPTION_SUPPORT";
export const SET_IS_AUTHENTICATED = "SET_IS_AUTHENTICATED";
export const SET_IS_TABLET_VIEW = "SET_IS_TABLET_VIEW";
export const SET_ARTICLE_PINNED = "SET_ARTICLE_PINNED";
export const SET_PRODUCT_VERSION = "SET_PRODUCT_VERSION";
export function setCurrentUser(user) {
return {
@ -167,6 +168,13 @@ export function setIsTabletView(isTabletView) {
};
}
export function setProductVersion(version) {
return {
type: SET_PRODUCT_VERSION,
version,
};
}
export function getUser(dispatch) {
return api.people
.getUser()

View File

@ -21,6 +21,7 @@ import {
SET_IS_AUTHENTICATED,
SET_IS_TABLET_VIEW,
SET_ARTICLE_PINNED,
SET_PRODUCT_VERSION,
} from "./actions";
import {
LANGUAGE,
@ -94,6 +95,7 @@ const initialState = {
isTabletView: false,
isArticlePinned: localStorage.getItem(ARTICLE_PINNED_KEY) || false,
},
version: null,
};
const authReducer = (state = initialState, action) => {
@ -226,6 +228,12 @@ const authReducer = (state = initialState, action) => {
return Object.assign({}, state, {
settings: { ...state.settings, isArticlePinned: action.isPinned },
});
case SET_PRODUCT_VERSION:
return Object.assign({}, state, {
version: action.version,
});
default:
return state;
}