mirror of
https://github.com/strapi/strapi.git
synced 2025-10-03 12:26:19 +00:00
commit
106260da45
@ -1,5 +1,5 @@
|
|||||||
// Import
|
// Import
|
||||||
@import "../../styles/variables/variables";
|
@import '../../styles/variables/variables';
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -12,13 +12,14 @@
|
|||||||
.plugin {
|
.plugin {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px; left: calc(100% - 4px);
|
top: 10px;
|
||||||
|
left: calc(100% - 4px);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
transition: right 1s ease-in-out;
|
transition: right 1s ease-in-out;
|
||||||
|
|
||||||
span{
|
span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: auto;
|
width: auto;
|
||||||
@ -29,10 +30,10 @@
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
background: #0097f7;
|
background: #0097f7;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
transition: transform .3s ease-in-out;
|
transition: transform 0.3s ease-in-out;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
|
|
||||||
&:hover{
|
&:hover {
|
||||||
transform: translateX(calc(-100% + 9px));
|
transform: translateX(calc(-100% + 9px));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +41,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
padding-top: .9rem;
|
position: relative;
|
||||||
|
padding-top: 0.8rem;
|
||||||
padding-bottom: 0.2rem;
|
padding-bottom: 0.2rem;
|
||||||
padding-left: 1.6rem;
|
padding-left: 1.6rem;
|
||||||
min-height: 3.6rem;
|
min-height: 3.6rem;
|
||||||
@ -66,6 +68,15 @@
|
|||||||
&:visited {
|
&:visited {
|
||||||
color: $left-menu-link-color;
|
color: $left-menu-link-color;
|
||||||
}
|
}
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
padding-right: 1rem;
|
||||||
|
padding-left: 2.6rem;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.linkActive {
|
.linkActive {
|
||||||
@ -74,7 +85,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.linkIcon {
|
.linkIcon {
|
||||||
position: relative;
|
position: absolute;
|
||||||
|
top: calc(50% - 0.9rem + 0.6rem);
|
||||||
|
left: 1.6rem;
|
||||||
margin-right: 1.2rem;
|
margin-right: 1.2rem;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
width: 1.4rem;
|
width: 1.4rem;
|
||||||
@ -85,5 +98,7 @@
|
|||||||
|
|
||||||
.linkLabel {
|
.linkLabel {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
|
padding-left: 2.6rem;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* StyledPluginHeader
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledPluginHeader = styled.div`
|
||||||
|
margin-bottom: 30px;
|
||||||
|
.justify-content-end {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default StyledPluginHeader;
|
@ -6,12 +6,11 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import cn from 'classnames';
|
|
||||||
|
|
||||||
import PluginHeaderTitle from '../PluginHeaderTitle';
|
import PluginHeaderTitle from '../PluginHeaderTitle';
|
||||||
import PluginHeaderActions from '../PluginHeaderActions';
|
import PluginHeaderActions from '../PluginHeaderActions';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import StyledPluginHeader from './StyledPluginHeader';
|
||||||
|
|
||||||
function PluginHeader({
|
function PluginHeader({
|
||||||
actions,
|
actions,
|
||||||
@ -25,27 +24,27 @@ function PluginHeader({
|
|||||||
withDescriptionAnim,
|
withDescriptionAnim,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className={cn(styles.pluginHeader, 'row')}>
|
<StyledPluginHeader>
|
||||||
<div className="col-lg-7">
|
<div className="row">
|
||||||
<PluginHeaderTitle
|
<div className="col-lg-6">
|
||||||
icon={icon}
|
<PluginHeaderTitle
|
||||||
onClickIcon={onClickIcon}
|
icon={icon}
|
||||||
title={title}
|
onClickIcon={onClickIcon}
|
||||||
titleId={titleId}
|
title={title}
|
||||||
description={description}
|
titleId={titleId}
|
||||||
withDescriptionAnim={withDescriptionAnim}
|
description={description}
|
||||||
/>
|
withDescriptionAnim={withDescriptionAnim}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-6 justify-content-end">
|
||||||
|
<PluginHeaderActions actions={subActions} />
|
||||||
|
<PluginHeaderActions
|
||||||
|
actions={actions}
|
||||||
|
overrideRendering={overrideRendering}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-2 justify-content-end">
|
</StyledPluginHeader>
|
||||||
<PluginHeaderActions actions={subActions} />
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-3 justify-content">
|
|
||||||
<PluginHeaderActions
|
|
||||||
actions={actions}
|
|
||||||
overrideRendering={overrideRendering}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
.pluginHeader {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* StyledPluginHeaderActions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledPluginHeaderActions = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 100%;
|
||||||
|
padding-top: 0.9rem;
|
||||||
|
button {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 1.8rem;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default StyledPluginHeaderActions;
|
@ -10,26 +10,20 @@ import { isArray, isFunction } from 'lodash';
|
|||||||
|
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import StyledPluginHeaderActions from './StyledPluginHeaderActions';
|
||||||
|
|
||||||
function PluginHeaderActions({ actions, overrideRendering }) {
|
function PluginHeaderActions({ actions, overrideRendering }) {
|
||||||
let content = '';
|
let content = '';
|
||||||
|
|
||||||
if (isArray(actions)) {
|
if (isArray(actions)) {
|
||||||
content = actions.map(action => (
|
content = actions.map(action => <Button {...action} key={action.label} />);
|
||||||
<Button {...action} key={action.label} />
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFunction(overrideRendering)) {
|
if (isFunction(overrideRendering)) {
|
||||||
content = overrideRendering();
|
content = overrideRendering();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return <StyledPluginHeaderActions>{content}</StyledPluginHeaderActions>;
|
||||||
<div className={styles.pluginHeaderActions}>
|
|
||||||
{content}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginHeaderActions.defaultProps = {
|
PluginHeaderActions.defaultProps = {
|
||||||
@ -38,14 +32,8 @@ PluginHeaderActions.defaultProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PluginHeaderActions.propTypes = {
|
PluginHeaderActions.propTypes = {
|
||||||
actions: PropTypes.oneOfType([
|
actions: PropTypes.oneOfType([PropTypes.array, PropTypes.bool]),
|
||||||
PropTypes.array,
|
overrideRendering: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
||||||
PropTypes.bool,
|
|
||||||
]),
|
|
||||||
overrideRendering: PropTypes.oneOfType([
|
|
||||||
PropTypes.bool,
|
|
||||||
PropTypes.func,
|
|
||||||
]),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PluginHeaderActions;
|
export default PluginHeaderActions;
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
.pluginHeaderActions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-top: 9px;
|
|
||||||
margin-right: -18px;
|
|
||||||
}
|
|
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* StyledPluginHeaderTitle
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledPluginHeaderTitle = styled.div`
|
||||||
|
.header-title {
|
||||||
|
position: relative;
|
||||||
|
h1 {
|
||||||
|
position: relative;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 2.4rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 0.7rem;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
padding-right: 18px;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
margin-top: 9px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(16, 22, 34, 0.35);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header-subtitle {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #787e8f;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default StyledPluginHeaderTitle;
|
@ -11,7 +11,7 @@ import { isEmpty, isFunction, isObject } from 'lodash';
|
|||||||
|
|
||||||
import LoadingBar from '../LoadingBar';
|
import LoadingBar from '../LoadingBar';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import StyledPluginHeaderTitle from './StyledPluginHeaderTitle';
|
||||||
|
|
||||||
function PluginHeaderTitle({
|
function PluginHeaderTitle({
|
||||||
description,
|
description,
|
||||||
@ -25,28 +25,26 @@ function PluginHeaderTitle({
|
|||||||
const contentDescription = formatData(description);
|
const contentDescription = formatData(description);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<StyledPluginHeaderTitle>
|
||||||
<div style={{ display: 'flex' }}>
|
<div className="header-title">
|
||||||
<h1 className={styles.pluginHeaderTitleName} id={titleId}>
|
<h1 id={titleId}>
|
||||||
{contentTitle}
|
{contentTitle}
|
||||||
|
{icon && (
|
||||||
|
<i
|
||||||
|
className={`${icon}`}
|
||||||
|
id="editCTName"
|
||||||
|
onClick={onClickIcon}
|
||||||
|
role="button"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</h1>
|
</h1>
|
||||||
{icon && (
|
|
||||||
<i
|
|
||||||
className={`${icon} ${styles.icon}`}
|
|
||||||
id="editCTName"
|
|
||||||
onClick={onClickIcon}
|
|
||||||
role="button"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{withDescriptionAnim ? (
|
{withDescriptionAnim ? (
|
||||||
<LoadingBar style={{ marginTop: '13px' }} />
|
<LoadingBar style={{ marginTop: '13px' }} />
|
||||||
) : (
|
) : (
|
||||||
<p className={styles.pluginHeaderTitleDescription}>
|
<p className="header-subtitle">{contentDescription} </p>
|
||||||
{contentDescription}
|
|
||||||
</p>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</StyledPluginHeaderTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
.pluginHeaderTitleName {
|
|
||||||
font-size: 2.4rem;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-top: 0.7rem;
|
|
||||||
margin-bottom: 1px;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pluginHeaderTitleDescription {
|
|
||||||
font-size: 1.3rem;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #787E8F;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
margin-top: 16px;
|
|
||||||
margin-left: 3px;
|
|
||||||
color: rgba(16,22,34,.35);
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
@ -43,4 +43,5 @@ const TrashButton = styled.div`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default TrashButton;
|
export default TrashButton;
|
||||||
|
@ -106,11 +106,7 @@ const Icon = styled.i`
|
|||||||
}}
|
}}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Truncate = styled.div`
|
const Truncate = styled.div``;
|
||||||
// display: table;
|
|
||||||
// table-layout: fixed;
|
|
||||||
// width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Truncated = styled.p`
|
const Truncated = styled.p`
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
@ -73,36 +73,48 @@ const Wrapper = styled(Flex)`
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
background-color: ${({ hasErrors, isOpen }) => {
|
background-color: ${({ hasErrors, isOpen }) => {
|
||||||
if (hasErrors && isOpen) {
|
if (hasErrors && isOpen) {
|
||||||
return '#FFE9E0';
|
return '#FFE9E0';
|
||||||
} else if (isOpen) {
|
} else if (isOpen) {
|
||||||
return '#E6F0FB';
|
return '#E6F0FB';
|
||||||
} else {
|
} else {
|
||||||
return '#ffffff';
|
return '#ffffff';
|
||||||
}
|
|
||||||
}}
|
|
||||||
${({ hasErrors, isOpen }) => {
|
|
||||||
if (hasErrors) {
|
|
||||||
return css`
|
|
||||||
color: #f64d0a;
|
|
||||||
font-weight: 600;
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isOpen) {
|
|
||||||
return css`
|
|
||||||
color: #007eff;
|
|
||||||
font-weight: 600;
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
button,
|
|
||||||
i, img {
|
|
||||||
&:active,
|
|
||||||
&:focus {
|
|
||||||
outline: 0;
|
|
||||||
}
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
${({ hasErrors, isOpen }) => {
|
||||||
|
if (hasErrors) {
|
||||||
|
return css`
|
||||||
|
color: #f64d0a;
|
||||||
|
font-weight: 600;
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
if (isOpen) {
|
||||||
|
return css`
|
||||||
|
color: #007eff;
|
||||||
|
font-weight: 600;
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
button,
|
||||||
|
i, img {
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${({ isOpen }) => {
|
||||||
|
if (isOpen) {
|
||||||
|
return css`
|
||||||
|
&.trash-icon i {
|
||||||
|
color: #007eff;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
webkit-font-smoothing: antialiased;
|
webkit-font-smoothing: antialiased;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ const ListWrapper = styled.div`
|
|||||||
max-height: 116px;
|
max-height: 116px;
|
||||||
|
|
||||||
> ul {
|
> ul {
|
||||||
margin: 4px -20px 0;
|
margin: 0 -20px 0;
|
||||||
padding: 0 20px !important;
|
padding: 0 20px !important;
|
||||||
list-style: none !important;
|
list-style: none !important;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -37,14 +37,13 @@ const Li = styled.li`
|
|||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
height: 27px;
|
height: 18px;
|
||||||
background-color: transparent !important;
|
margin-top: 9px;
|
||||||
margin-bottom: 9px;
|
&:last-of-type {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
&:active {
|
&:active {
|
||||||
.dragHandle {
|
.dragHandle {
|
||||||
// cursor: pointer;
|
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
background: #aed4fb;
|
background: #aed4fb;
|
||||||
}
|
}
|
||||||
@ -132,7 +131,7 @@ const Li = styled.li`
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
line-height: 27px;
|
line-height: 18px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -5,6 +5,10 @@ const Wrapper = styled.div`
|
|||||||
margin-bottom: 27px;
|
margin-bottom: 27px;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
@ -94,11 +98,6 @@ const Wrapper = styled.div`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
& + div {
|
|
||||||
ul {
|
|
||||||
margin-bottom: -4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -380,9 +380,7 @@ function EditView({
|
|||||||
label: `${pluginId}.containers.Edit.submit`,
|
label: `${pluginId}.containers.Edit.submit`,
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
loader: isSubmitting,
|
loader: isSubmitting,
|
||||||
style: isSubmitting
|
style: isSubmitting ? { marginRight: '18px' } : {},
|
||||||
? { marginRight: '18px', flexGrow: 2 }
|
|
||||||
: { flexGrow: 2 },
|
|
||||||
disabled: isSubmitting, // TODO STATE WHEN SUBMITING
|
disabled: isSubmitting, // TODO STATE WHEN SUBMITING
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* StyledBackButton
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledBackButton = styled.div`
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
height: 6rem;
|
||||||
|
width: 6.5rem;
|
||||||
|
line-height: 6rem;
|
||||||
|
z-index: 1050;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #81848a;
|
||||||
|
border-top: 1px solid #f3f4f4;
|
||||||
|
border-right: 1px solid #f3f4f4;
|
||||||
|
border-left: 1px solid #f3f4f4;
|
||||||
|
cursor: pointer;
|
||||||
|
i {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: #f3f4f4;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default StyledBackButton;
|
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* BackButton
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import StyledBackButton from './StyledBackButton';
|
||||||
|
|
||||||
|
function BackButton({ onClick }) {
|
||||||
|
return (
|
||||||
|
<StyledBackButton onClick={onClick}>
|
||||||
|
<i className="fa fa-chevron-left"></i>
|
||||||
|
</StyledBackButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BackButton.propTypes = {
|
||||||
|
onClick: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BackButton;
|
@ -23,6 +23,8 @@ import GroupPage from '../GroupPage';
|
|||||||
|
|
||||||
import Loader from './Loader';
|
import Loader from './Loader';
|
||||||
|
|
||||||
|
import BackButton from '../../components/BackButton';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
addAttributeRelation,
|
addAttributeRelation,
|
||||||
cancelNewContentType,
|
cancelNewContentType,
|
||||||
@ -77,6 +79,11 @@ const ROUTES = [
|
|||||||
|
|
||||||
export class App extends React.Component {
|
export class App extends React.Component {
|
||||||
// eslint-disable-line react/prefer-stateless-function
|
// eslint-disable-line react/prefer-stateless-function
|
||||||
|
state = {
|
||||||
|
routerHistory: [],
|
||||||
|
historyCount: 1,
|
||||||
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.getData();
|
this.props.getData();
|
||||||
}
|
}
|
||||||
@ -86,6 +93,13 @@ export class App extends React.Component {
|
|||||||
if (prevProps.shouldRefetchData !== this.props.shouldRefetchData) {
|
if (prevProps.shouldRefetchData !== this.props.shouldRefetchData) {
|
||||||
this.props.getData();
|
this.props.getData();
|
||||||
}
|
}
|
||||||
|
if (prevProps.location !== this.props.location) {
|
||||||
|
if (prevProps.location.pathname !== this.getPathname()) {
|
||||||
|
this.addRouterHistory(prevProps.location.pathname);
|
||||||
|
} else {
|
||||||
|
this.increaseHistoryCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@ -101,8 +115,51 @@ export class App extends React.Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
addRouterHistory = pathname => {
|
||||||
|
if (this.getLastPathname() !== this.getPathname()) {
|
||||||
|
this.setState(prevState => {
|
||||||
|
return {
|
||||||
|
routerHistory: [...prevState.routerHistory, pathname],
|
||||||
|
historyCount: prevState.historyCount + 1,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
increaseHistoryCount = () => {
|
||||||
|
this.setState(prevState => {
|
||||||
|
return {
|
||||||
|
routerHistory: [...prevState.routerHistory],
|
||||||
|
historyCount: prevState.historyCount + 1,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
removeRouterHistory = () => {
|
||||||
|
const array = [...this.state.routerHistory];
|
||||||
|
const index = array.length - 1;
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
array.splice(index, 1);
|
||||||
|
this.setState(prevState => {
|
||||||
|
return {
|
||||||
|
routerHistory: array,
|
||||||
|
historyCount: prevState.historyCount + 1,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
getSearch = () => this.props.location.search;
|
getSearch = () => this.props.location.search;
|
||||||
|
|
||||||
|
getPathname = () => this.props.location.pathname;
|
||||||
|
|
||||||
|
getLastPathname = () => {
|
||||||
|
const { routerHistory } = this.state;
|
||||||
|
|
||||||
|
return routerHistory[routerHistory.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
getActionType = () => {
|
getActionType = () => {
|
||||||
return getQueryParameters(this.getSearch(), 'actionType');
|
return getQueryParameters(this.getSearch(), 'actionType');
|
||||||
};
|
};
|
||||||
@ -140,6 +197,24 @@ export class App extends React.Component {
|
|||||||
getFeatureNameFromSearch = () =>
|
getFeatureNameFromSearch = () =>
|
||||||
getQueryParameters(this.getSearch(), `${this.getFeatureType()}Name`);
|
getQueryParameters(this.getSearch(), `${this.getFeatureType()}Name`);
|
||||||
|
|
||||||
|
handleGoBack = async () => {
|
||||||
|
const { history } = this.props;
|
||||||
|
const { routerHistory, historyCount } = this.state;
|
||||||
|
|
||||||
|
await this.wait();
|
||||||
|
|
||||||
|
if (routerHistory.length > 0) {
|
||||||
|
history.push(this.getLastPathname());
|
||||||
|
this.removeRouterHistory();
|
||||||
|
} else {
|
||||||
|
history.go(-historyCount);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
wait = async () => {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, 200));
|
||||||
|
};
|
||||||
|
|
||||||
isUpdatingTemporaryModel = (modelName = this.getFeatureNameFromSearch()) => {
|
isUpdatingTemporaryModel = (modelName = this.getFeatureNameFromSearch()) => {
|
||||||
const { models } = this.props;
|
const { models } = this.props;
|
||||||
|
|
||||||
@ -194,7 +269,7 @@ export class App extends React.Component {
|
|||||||
createTempGroup,
|
createTempGroup,
|
||||||
groups,
|
groups,
|
||||||
history: { push },
|
history: { push },
|
||||||
location: { pathname, search },
|
location: { search },
|
||||||
isLoading,
|
isLoading,
|
||||||
models,
|
models,
|
||||||
onChangeExistingContentTypeMainInfos,
|
onChangeExistingContentTypeMainInfos,
|
||||||
@ -227,7 +302,7 @@ export class App extends React.Component {
|
|||||||
modifiedData: this.getFormDataForModel(),
|
modifiedData: this.getFormDataForModel(),
|
||||||
onChangeExistingFeatureMainInfos: onChangeExistingContentTypeMainInfos,
|
onChangeExistingFeatureMainInfos: onChangeExistingContentTypeMainInfos,
|
||||||
onChangeNewFeatureMainInfos: onChangeNewContentTypeMainInfos,
|
onChangeNewFeatureMainInfos: onChangeNewContentTypeMainInfos,
|
||||||
pathname,
|
pathname: this.getPathname(),
|
||||||
push,
|
push,
|
||||||
resetExistingFeatureMainInfos: resetExistingContentTypeMainInfos,
|
resetExistingFeatureMainInfos: resetExistingContentTypeMainInfos,
|
||||||
resetNewFeatureMainInfos: resetNewContentTypeMainInfos,
|
resetNewFeatureMainInfos: resetNewContentTypeMainInfos,
|
||||||
@ -246,7 +321,7 @@ export class App extends React.Component {
|
|||||||
modifiedData: this.getFormDataForGroup(),
|
modifiedData: this.getFormDataForGroup(),
|
||||||
onChangeExistingFeatureMainInfos: onChangeExistingGroupMainInfos,
|
onChangeExistingFeatureMainInfos: onChangeExistingGroupMainInfos,
|
||||||
onChangeNewFeatureMainInfos: onChangeNewGroupMainInfos,
|
onChangeNewFeatureMainInfos: onChangeNewGroupMainInfos,
|
||||||
pathname,
|
pathname: this.getPathname(),
|
||||||
push,
|
push,
|
||||||
resetExistingFeatureMainInfos: resetExistingGroupMainInfos,
|
resetExistingFeatureMainInfos: resetExistingGroupMainInfos,
|
||||||
resetNewFeatureMainInfos: () => {},
|
resetNewFeatureMainInfos: () => {},
|
||||||
@ -264,6 +339,7 @@ export class App extends React.Component {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={styles.app}>
|
<div className={styles.app}>
|
||||||
|
<BackButton onClick={this.handleGoBack}></BackButton>
|
||||||
<Switch>
|
<Switch>
|
||||||
{ROUTES.map(this.renderRoute)}
|
{ROUTES.map(this.renderRoute)}
|
||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
|
@ -17,7 +17,6 @@ import ViewContainer from '../ViewContainer';
|
|||||||
import RelationFormGroup from '../RelationFormGroup';
|
import RelationFormGroup from '../RelationFormGroup';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BackHeader,
|
|
||||||
Button,
|
Button,
|
||||||
EmptyAttributesBlock,
|
EmptyAttributesBlock,
|
||||||
getQueryParameters,
|
getQueryParameters,
|
||||||
@ -316,10 +315,6 @@ export class GroupPage extends React.Component {
|
|||||||
this.setState({ attrToDelete: null, showDeleteAttrWarning: false });
|
this.setState({ attrToDelete: null, showDeleteAttrWarning: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleGoBack = () => {
|
|
||||||
this.props.history.goBack();
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSubmit = (shouldContinue = false) => {
|
handleSubmit = (shouldContinue = false) => {
|
||||||
const {
|
const {
|
||||||
addAttributeRelationGroup,
|
addAttributeRelationGroup,
|
||||||
@ -523,7 +518,6 @@ export class GroupPage extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BackHeader onClick={this.handleGoBack} />
|
|
||||||
<FormattedMessage id={`${pluginId}.prompt.content.unsaved`}>
|
<FormattedMessage id={`${pluginId}.prompt.content.unsaved`}>
|
||||||
{msg => (
|
{msg => (
|
||||||
<Prompt
|
<Prompt
|
||||||
@ -715,7 +709,6 @@ GroupPage.propTypes = {
|
|||||||
groups: PropTypes.array.isRequired,
|
groups: PropTypes.array.isRequired,
|
||||||
history: PropTypes.shape({
|
history: PropTypes.shape({
|
||||||
push: PropTypes.func.isRequired,
|
push: PropTypes.func.isRequired,
|
||||||
goBack: PropTypes.func.isRequired,
|
|
||||||
}),
|
}),
|
||||||
initialDataGroup: PropTypes.object.isRequired,
|
initialDataGroup: PropTypes.object.isRequired,
|
||||||
location: PropTypes.shape({
|
location: PropTypes.shape({
|
||||||
|
@ -69,7 +69,6 @@ const props = {
|
|||||||
],
|
],
|
||||||
history: {
|
history: {
|
||||||
push: jest.fn(),
|
push: jest.fn(),
|
||||||
goBack: jest.fn(),
|
|
||||||
},
|
},
|
||||||
initialDataGroup: {
|
initialDataGroup: {
|
||||||
tests: {
|
tests: {
|
||||||
@ -232,15 +231,6 @@ describe('CTB <GroupPage />', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('HandleGoBack', () => {
|
|
||||||
it('should go to previous page', () => {
|
|
||||||
const { handleGoBack } = shallow(<GroupPage {...props} />).instance();
|
|
||||||
handleGoBack();
|
|
||||||
|
|
||||||
expect(props.history.goBack).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('toggleDeleteAttrModalWarning', () => {
|
describe('toggleDeleteAttrModalWarning', () => {
|
||||||
const wrapper = shallow(<GroupPage {...props} />);
|
const wrapper = shallow(<GroupPage {...props} />);
|
||||||
expect(wrapper.state()).toEqual({
|
expect(wrapper.state()).toEqual({
|
||||||
|
@ -14,7 +14,6 @@ import { get, isEqual, pickBy } from 'lodash';
|
|||||||
import { Prompt } from 'react-router';
|
import { Prompt } from 'react-router';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BackHeader,
|
|
||||||
Button,
|
Button,
|
||||||
EmptyAttributesBlock,
|
EmptyAttributesBlock,
|
||||||
List,
|
List,
|
||||||
@ -381,17 +380,16 @@ export class ModelPage extends React.Component {
|
|||||||
this.setState({ attrToDelete: null, showDeleteAttrWarning: false });
|
this.setState({ attrToDelete: null, showDeleteAttrWarning: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleGoBack = () => {
|
|
||||||
this.props.history.goBack();
|
|
||||||
};
|
|
||||||
|
|
||||||
handleRedirectToGroup = group => {
|
handleRedirectToGroup = group => {
|
||||||
|
const {
|
||||||
|
history: { push },
|
||||||
|
} = this.props;
|
||||||
const { source, uid } = group;
|
const { source, uid } = group;
|
||||||
|
|
||||||
const base = `/plugins/${pluginId}/groups/${uid}`;
|
const base = `/plugins/${pluginId}/groups/${uid}`;
|
||||||
const to = source ? `${base}&source=${source}` : base;
|
const to = source ? `${base}&source=${source}` : base;
|
||||||
|
|
||||||
this.props.history.push(to);
|
push(to);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSubmit = (shouldContinue = false) => {
|
handleSubmit = (shouldContinue = false) => {
|
||||||
@ -599,7 +597,6 @@ export class ModelPage extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.modelpage}>
|
<div className={styles.modelpage}>
|
||||||
<BackHeader onClick={this.handleGoBack} />
|
|
||||||
<FormattedMessage id={`${pluginId}.prompt.content.unsaved`}>
|
<FormattedMessage id={`${pluginId}.prompt.content.unsaved`}>
|
||||||
{msg => (
|
{msg => (
|
||||||
<Prompt
|
<Prompt
|
||||||
|
@ -12,11 +12,6 @@ const StyledViewContainer = styled.div`
|
|||||||
min-height: calc(100vh - ${sizes.header.height});
|
min-height: calc(100vh - ${sizes.header.height});
|
||||||
.components-container {
|
.components-container {
|
||||||
padding: 1.8rem 1.5rem;
|
padding: 1.8rem 1.5rem;
|
||||||
div div:not(.list-button) {
|
|
||||||
button {
|
|
||||||
top: 1.8rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
> div:not(:first-of-type):not(:last-of-type) {
|
> div:not(:first-of-type):not(:last-of-type) {
|
||||||
> div:first-of-type {
|
> div:first-of-type {
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
@ -35,9 +30,16 @@ const StyledViewContainer = styled.div`
|
|||||||
.trash-btn-wrapper {
|
.trash-btn-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: 3.4rem;
|
padding-top: 3.1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
> div {
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
> div {
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user