@@ -0,0 +1,126 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useTranslation, Trans } from 'react-i18next';
|
||||
import { Loader } from 'semantic-ui-react';
|
||||
|
||||
import selectors from '../../../selectors';
|
||||
import version from '../../../version';
|
||||
import ModalTypes from '../../../constants/ModalTypes';
|
||||
import Message from './Message';
|
||||
import Toaster from '../Toaster';
|
||||
import Fixed from '../Fixed';
|
||||
import Static from '../Static';
|
||||
import AdministrationModal from '../AdministrationModal';
|
||||
import UserSettingsModal from '../../users/UserSettingsModal';
|
||||
import ProjectBackground from '../../projects/ProjectBackground';
|
||||
import AddProjectModal from '../../projects/AddProjectModal';
|
||||
|
||||
const Core = React.memo(() => {
|
||||
const isInitializing = useSelector(selectors.selectIsInitializing);
|
||||
const isSocketDisconnected = useSelector(selectors.selectIsSocketDisconnected);
|
||||
const modal = useSelector(selectors.selectCurrentModal);
|
||||
const project = useSelector(selectors.selectCurrentProject);
|
||||
const board = useSelector(selectors.selectCurrentBoard);
|
||||
|
||||
// TODO: move to selector?
|
||||
const isNewVersionAvailable = useSelector((state) => {
|
||||
const config = selectors.selectConfig(state);
|
||||
return !!config && config.version !== version;
|
||||
});
|
||||
|
||||
const [t] = useTranslation();
|
||||
|
||||
const defaultTitleRef = useRef(document.title);
|
||||
|
||||
const handleRefreshPageClick = useCallback(() => {
|
||||
window.location.reload(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const titleParts = [];
|
||||
if (project) {
|
||||
if (board) {
|
||||
titleParts.push(board.name);
|
||||
}
|
||||
|
||||
titleParts.push(project.name);
|
||||
}
|
||||
|
||||
document.title = titleParts.length === 0 ? defaultTitleRef.current : titleParts.join(' | ');
|
||||
}, [project, board]);
|
||||
|
||||
let modalNode = null;
|
||||
if (modal) {
|
||||
switch (modal.type) {
|
||||
case ModalTypes.ADMINISTRATION:
|
||||
modalNode = <AdministrationModal />;
|
||||
|
||||
break;
|
||||
case ModalTypes.USER_SETTINGS:
|
||||
modalNode = <UserSettingsModal />;
|
||||
|
||||
break;
|
||||
case ModalTypes.ADD_PROJECT:
|
||||
modalNode = <AddProjectModal />;
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
let messageNode = null;
|
||||
if (isSocketDisconnected) {
|
||||
messageNode = (
|
||||
<Message
|
||||
type="error"
|
||||
header={t('common.noConnectionToServer')}
|
||||
content={
|
||||
<Trans i18nKey="common.allChangesWillBeAutomaticallySavedAfterConnectionRestored">
|
||||
All changes will be automatically saved
|
||||
<br />
|
||||
after connection restored
|
||||
</Trans>
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else if (isNewVersionAvailable) {
|
||||
messageNode = (
|
||||
<Message
|
||||
type="info"
|
||||
header={t('common.newVersionAvailable')}
|
||||
content={
|
||||
<Trans i18nKey="common.clickHereOrRefreshPageToUpdate">
|
||||
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid,
|
||||
jsx-a11y/click-events-have-key-events,
|
||||
jsx-a11y/no-static-element-interactions */}
|
||||
<a onClick={handleRefreshPageClick}>Click here</a> or refresh the page to update
|
||||
</Trans>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isInitializing ? (
|
||||
<Loader active size="massive" />
|
||||
) : (
|
||||
<>
|
||||
<Toaster />
|
||||
{project && project.backgroundType && <ProjectBackground />}
|
||||
<Fixed />
|
||||
<Static />
|
||||
{modalNode}
|
||||
</>
|
||||
)}
|
||||
{messageNode}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export default Core;
|
||||
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import styles from './Message.module.scss';
|
||||
|
||||
const Types = {
|
||||
INFO: 'info',
|
||||
ERROR: 'error',
|
||||
};
|
||||
|
||||
const Message = React.memo(({ type, header, content }) => (
|
||||
<div className={classNames(styles.wrapper, styles[`wrapper${upperFirst(type)}`])}>
|
||||
<div className={styles.header}>{header}</div>
|
||||
<div className={styles.content}>{content}</div>
|
||||
</div>
|
||||
));
|
||||
|
||||
Message.propTypes = {
|
||||
type: PropTypes.oneOf(Object.values(Types)).isRequired,
|
||||
header: PropTypes.node.isRequired,
|
||||
content: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default Message;
|
||||
@@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) {
|
||||
.content {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
line-height: 1.4;
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
border-radius: 4px;
|
||||
bottom: 20px;
|
||||
max-width: calc(100% - 40px);
|
||||
padding: 12px 18px;
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
width: 390px;
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
.wrapperError {
|
||||
background: #cf513d;
|
||||
box-shadow: #6e2f1a 0 1px 0;
|
||||
}
|
||||
|
||||
.wrapperInfo {
|
||||
background: #2185d0;
|
||||
box-shadow: rgba(34, 36, 38, 0.15) 0 1px 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import Core from './Core';
|
||||
|
||||
export default Core;
|
||||
Reference in New Issue
Block a user