mirror of
https://github.com/strapi/strapi.git
synced 2025-08-18 13:45:25 +00:00
Groups data formatting utils
This commit is contained in:
commit
b595f64d3a
@ -9,8 +9,12 @@ describe('<Block />', () => {
|
||||
});
|
||||
|
||||
it('should render his children', () => {
|
||||
const Child = () => <div>I'm a child</div>;
|
||||
const wrapper = shallow(<Block><Child /></Block>);
|
||||
const Child = () => <div>I am a child</div>;
|
||||
const wrapper = shallow(
|
||||
<Block>
|
||||
<Child />
|
||||
</Block>
|
||||
);
|
||||
|
||||
expect(wrapper.find(Child).exists()).toBe(true);
|
||||
});
|
||||
|
@ -19,11 +19,13 @@ function ButtonModalSuccess({ message, onClick, type }) {
|
||||
}
|
||||
|
||||
ButtonModalSuccess.defaultProps = {
|
||||
onClick: () => {},
|
||||
type: 'button',
|
||||
};
|
||||
|
||||
ButtonModalSuccess.propTypes = {
|
||||
message: PropTypes.string.isRequired,
|
||||
onClick: PropTypes.func,
|
||||
type: PropTypes.string,
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,7 @@ const DocumentationSection = () => (
|
||||
<a
|
||||
href="http://strapi.io/documentation/3.0.0-beta.x/guides/models.html"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{message}
|
||||
</a>
|
||||
|
@ -9,8 +9,12 @@ describe('<Flex />', () => {
|
||||
});
|
||||
|
||||
it('should render his children', () => {
|
||||
const Child = () => <div>I'm a child</div>;
|
||||
const wrapper = shallow(<Flex><Child /></Flex>);
|
||||
const Child = () => <div>I am a child</div>;
|
||||
const wrapper = shallow(
|
||||
<Flex>
|
||||
<Child />
|
||||
</Flex>
|
||||
);
|
||||
|
||||
expect(wrapper.find(Child).exists()).toBe(true);
|
||||
});
|
||||
|
@ -9,8 +9,12 @@ describe('<ListTitle />', () => {
|
||||
});
|
||||
|
||||
it('should render his children', () => {
|
||||
const Child = () => <div>I'm a child</div>;
|
||||
const wrapper = shallow(<ListTitle><Child /></ListTitle>);
|
||||
const Child = () => <div>I am a child</div>;
|
||||
const wrapper = shallow(
|
||||
<ListTitle>
|
||||
<Child />
|
||||
</ListTitle>
|
||||
);
|
||||
|
||||
expect(wrapper.find(Child).exists()).toBe(true);
|
||||
});
|
||||
|
@ -9,8 +9,12 @@ describe('<Ul />', () => {
|
||||
});
|
||||
|
||||
it('should render its children', () => {
|
||||
const Child = () => <div>I'm a child</div>;
|
||||
const wrapper = shallow(<Ul><Child /></Ul>);
|
||||
const Child = () => <div>I am a child</div>;
|
||||
const wrapper = shallow(
|
||||
<Ul>
|
||||
<Child />
|
||||
</Ul>
|
||||
);
|
||||
|
||||
expect(wrapper.find(Child).exists()).toBe(true);
|
||||
});
|
||||
|
@ -170,6 +170,7 @@ export function getDataSucceeded({ allModels, models }, connections, { data }) {
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
<<<<<<< HEAD
|
||||
|
||||
const initialDataGroup = data.reduce((acc, current, i) => {
|
||||
const {
|
||||
@ -187,6 +188,9 @@ export function getDataSucceeded({ allModels, models }, connections, { data }) {
|
||||
}, {});
|
||||
|
||||
const groups = data.reduce((acc, current, i) => {
|
||||
=======
|
||||
const groups = data.reduce((acc, current) => {
|
||||
>>>>>>> 28c9339ace187ee1b88de0002851d3598f8e9def
|
||||
const {
|
||||
name,
|
||||
schema: { attributes, description },
|
||||
|
@ -9,7 +9,7 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators, compose } from 'redux';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import { get, isEmpty } from 'lodash';
|
||||
import { get } from 'lodash';
|
||||
|
||||
import { NotFound, getQueryParameters } from 'strapi-helper-plugin';
|
||||
|
||||
@ -184,7 +184,6 @@ export class App extends React.Component {
|
||||
location: { pathname, search },
|
||||
isLoading,
|
||||
models,
|
||||
newContentType,
|
||||
newGroup,
|
||||
onChangeExistingContentTypeMainInfos,
|
||||
onChangeNewContentTypeMainInfos,
|
||||
@ -271,12 +270,19 @@ App.defaultProps = {
|
||||
App.propTypes = {
|
||||
addAttributeRelation: PropTypes.func.isRequired,
|
||||
cancelNewContentType: PropTypes.func.isRequired,
|
||||
connections: PropTypes.array.isRequired,
|
||||
createTempContentType: PropTypes.func.isRequired,
|
||||
createTempGroup: PropTypes.func.isRequired,
|
||||
deleteModel: PropTypes.func.isRequired,
|
||||
getData: PropTypes.func.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
groups: PropTypes.array.isRequired,
|
||||
history: PropTypes.object.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
models: PropTypes.array.isRequired,
|
||||
modifiedData: PropTypes.object.isRequired,
|
||||
newContentType: PropTypes.object.isRequired,
|
||||
newGroup: PropTypes.object.isRequired,
|
||||
onChangeExistingContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
onChangeNewContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
onChangeNewGroupMainInfos: PropTypes.func.isRequired,
|
||||
@ -285,7 +291,10 @@ App.propTypes = {
|
||||
saveEditedAttributeRelation: PropTypes.func.isRequired,
|
||||
setTemporaryAttribute: PropTypes.func.isRequired,
|
||||
setTemporaryAttributeRelation: PropTypes.func.isRequired,
|
||||
resetExistingContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
resetNewContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
shouldRefetchData: PropTypes.bool,
|
||||
updateTempContentType: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = makeSelectApp();
|
||||
|
@ -13,6 +13,9 @@ describe('<App />', () => {
|
||||
props = {
|
||||
addAttributeRelation: jest.fn(),
|
||||
cancelNewContentType: jest.fn(),
|
||||
connections: [],
|
||||
createTempContentType: jest.fn(),
|
||||
createTempGroup: jest.fn(),
|
||||
deleteModel: jest.fn(),
|
||||
history: {
|
||||
push: jest.fn(),
|
||||
@ -76,6 +79,8 @@ describe('<App />', () => {
|
||||
},
|
||||
],
|
||||
modifiedData: {},
|
||||
newContentType: {},
|
||||
newGroup: {},
|
||||
onChangeExistingContentTypeMainInfos: jest.fn(),
|
||||
onChangeNewContentTypeMainInfos: jest.fn(),
|
||||
onChangeNewGroupMainInfos: jest.fn(),
|
||||
@ -84,6 +89,9 @@ describe('<App />', () => {
|
||||
setTemporaryAttribute: jest.fn(),
|
||||
setTemporaryAttributeRelation: jest.fn(),
|
||||
resetProps: jest.fn(),
|
||||
resetExistingContentTypeMainInfos: jest.fn(),
|
||||
resetNewContentTypeMainInfos: jest.fn(),
|
||||
updateTempContentType: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -294,6 +294,7 @@ AttributeForm.defaultProps = {
|
||||
modifiedData: {},
|
||||
onCancel: () => {},
|
||||
onChange: () => {},
|
||||
onSubmit: () => {},
|
||||
push: () => {},
|
||||
};
|
||||
|
||||
@ -307,7 +308,7 @@ AttributeForm.propTypes = {
|
||||
modifiedData: PropTypes.object, // TODO: Clearly define this object (It's working without it though)
|
||||
onCancel: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
onSubmit: PropTypes.func,
|
||||
onSubmitEdit: PropTypes.func.isRequired,
|
||||
push: PropTypes.func,
|
||||
};
|
||||
|
@ -6,21 +6,17 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
import {
|
||||
HeaderNav,
|
||||
ListWrapper,
|
||||
ListHeader,
|
||||
List,
|
||||
PluginHeader,
|
||||
getQueryParameters,
|
||||
routerPropTypes,
|
||||
} from 'strapi-helper-plugin';
|
||||
|
||||
import EmptyContentTypeView from '../../components/EmptyContentTypeView';
|
||||
import pluginId from '../../pluginId';
|
||||
import ModelForm from '../ModelForm';
|
||||
import Row from './Row';
|
||||
import styles from './styles.scss';
|
||||
|
||||
@ -77,7 +73,6 @@ class HomePage extends React.Component {
|
||||
|
||||
handleGoTo = (to, source, shouldEdit = false) => {
|
||||
const {
|
||||
canOpenModal,
|
||||
history: { push },
|
||||
match: {
|
||||
params: { type },
|
||||
@ -97,25 +92,16 @@ class HomePage extends React.Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
allGroupsAndModelsName,
|
||||
cancelNewContentType,
|
||||
canOpenModal,
|
||||
connections,
|
||||
createTempContentType,
|
||||
deleteGroup,
|
||||
deleteModel,
|
||||
deleteTemporaryGroup,
|
||||
deleteTemporaryModel,
|
||||
groups,
|
||||
history: { push },
|
||||
location: { pathname, search },
|
||||
match: {
|
||||
params: { type },
|
||||
},
|
||||
models,
|
||||
modifiedData,
|
||||
newContentType,
|
||||
onChangeNewContentTypeMainInfos,
|
||||
} = this.props;
|
||||
const displayedData = type === 'groups' ? groups : models;
|
||||
const availableNumber = type === 'groups' ? groups.length : models.length;
|
||||
@ -175,22 +161,6 @@ class HomePage extends React.Component {
|
||||
</List>
|
||||
</ListWrapper>
|
||||
)}
|
||||
|
||||
{/* <ModelForm
|
||||
actionType="create"
|
||||
activeTab={getQueryParameters(search, 'settingType')}
|
||||
allTakenNames={allGroupsAndModelsName}
|
||||
cancelNewContentType={cancelNewContentType}
|
||||
connections={connections}
|
||||
createTempContentType={createTempContentType}
|
||||
currentData={modifiedData}
|
||||
featureType={type}
|
||||
modifiedData={newContentType}
|
||||
onChangeNewContentTypeMainInfos={onChangeNewContentTypeMainInfos}
|
||||
isOpen={!isEmpty(search)}
|
||||
pathname={pathname}
|
||||
push={push}
|
||||
/> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -2,10 +2,8 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import pluginId from '../../../pluginId';
|
||||
|
||||
import { ListHeader } from 'strapi-helper-plugin';
|
||||
import EmptyContentTypeView from '../../../components/EmptyContentTypeView';
|
||||
import TableList from '../../../components/TableList';
|
||||
import ModelForm from '../../ModelForm';
|
||||
|
||||
import HomePage from '../index';
|
||||
|
||||
@ -71,7 +69,7 @@ describe('CTB <HomePage />', () => {
|
||||
},
|
||||
location: {
|
||||
search: '',
|
||||
pathname: `/plugins/${pluginId}`,
|
||||
pathname: `/plugins/${pluginId}/models`,
|
||||
},
|
||||
};
|
||||
});
|
||||
@ -82,93 +80,171 @@ describe('CTB <HomePage />', () => {
|
||||
shallow(<HomePage {...props} />, { context });
|
||||
});
|
||||
|
||||
// describe('render', () => {
|
||||
// it('should display the EmptyContentTypeView if there is no model in the application', () => {
|
||||
// props.models = [];
|
||||
describe('render', () => {
|
||||
it('should display the EmptyContentTypeView if there is no model in the application', () => {
|
||||
props.models = [];
|
||||
|
||||
// const context = { emitEvent: jest.fn() };
|
||||
// const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
// const emptyView = wrapper.find(EmptyContentTypeView);
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const emptyView = wrapper.find(EmptyContentTypeView);
|
||||
|
||||
// expect(emptyView).toHaveLength(1);
|
||||
// });
|
||||
|
||||
// it('the tableList should have a plural title if there is more than 1 model', () => {
|
||||
// const context = { emitEvent: jest.fn() };
|
||||
// const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
// const table = wrapper.find(TableList);
|
||||
|
||||
// expect(table).toHaveLength(1);
|
||||
// expect(table.prop('title')).toEqual(
|
||||
// `${pluginId}.table.contentType.title.plural`,
|
||||
// );
|
||||
// });
|
||||
|
||||
// it('the tableList should have a singular title if there is more less 2 model', () => {
|
||||
// props.models = [
|
||||
// {
|
||||
// icon: 'fa-cube',
|
||||
// name: 'permission',
|
||||
// description: '',
|
||||
// fields: 6,
|
||||
// source: 'users-permissions',
|
||||
// isTemporary: false,
|
||||
// },
|
||||
// ];
|
||||
|
||||
// const context = { emitEvent: jest.fn() };
|
||||
// const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
// const table = wrapper.find(TableList);
|
||||
|
||||
// expect(table).toHaveLength(1);
|
||||
// expect(table.prop('title')).toEqual(
|
||||
// `${pluginId}.table.contentType.title.singular`,
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('workflow', () => {
|
||||
// it('should open the modelForm if there is no saved content type', () => {
|
||||
// props.canOpenModal = true;
|
||||
// props.history.push = jest.fn(({ search }) => {
|
||||
// props.location.search = `?${search}`;
|
||||
// });
|
||||
// const context = { emitEvent: jest.fn() };
|
||||
// const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
// const spyOnClick = jest.spyOn(wrapper.instance(), 'handleClick');
|
||||
|
||||
// wrapper.instance().forceUpdate();
|
||||
// // Simulate the click on button
|
||||
// wrapper.find(TableList).prop('onButtonClick')();
|
||||
// wrapper.instance().forceUpdate();
|
||||
|
||||
// const form = wrapper.find(ModelForm).first();
|
||||
|
||||
// expect(spyOnClick).toHaveBeenCalled();
|
||||
// expect(context.emitEvent).toHaveBeenCalledWith('willCreateContentType');
|
||||
// expect(props.history.push).toHaveBeenCalledWith({
|
||||
// search: 'modalType=model&settingType=base&actionType=create',
|
||||
// });
|
||||
// expect(form.prop('isOpen')).toBe(true);
|
||||
// });
|
||||
|
||||
// it('should not open the modal if the is one or more not saved content type and display a notification', () => {
|
||||
// props.canOpenModal = false;
|
||||
// const context = { emitEvent: jest.fn() };
|
||||
// const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
|
||||
// wrapper.find(TableList).prop('onButtonClick')();
|
||||
// wrapper.instance().forceUpdate();
|
||||
|
||||
// const form = wrapper.find(ModelForm).first();
|
||||
|
||||
// expect(context.emitEvent).not.toHaveBeenCalled();
|
||||
// expect(props.history.push).not.toHaveBeenCalled();
|
||||
// expect(strapi.notification.info).toHaveBeenCalled();
|
||||
// expect(strapi.notification.info).toHaveBeenCalledWith(
|
||||
// `${pluginId}.notification.info.contentType.creating.notSaved`,
|
||||
// );
|
||||
// expect(form.prop('isOpen')).toBe(false);
|
||||
// });
|
||||
// });
|
||||
expect(emptyView).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should display the EmptyContentTypeView if there is no model in the application', () => {
|
||||
props.match.params.type = 'groups';
|
||||
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const emptyView = wrapper.find(EmptyContentTypeView);
|
||||
|
||||
expect(emptyView).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('Should handle the listheader title correctly if there is more than 1 model', () => {
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const list = wrapper.find(ListHeader);
|
||||
|
||||
expect(list).toHaveLength(1);
|
||||
expect(list.prop('title')).toBe(
|
||||
`${pluginId}.table.contentType.title.plural`
|
||||
);
|
||||
});
|
||||
|
||||
it('Should handle the listheader title correctly if there is more than 1 group', () => {
|
||||
props.groups = props.models;
|
||||
props.match.params.type = 'groups';
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const list = wrapper.find(ListHeader);
|
||||
|
||||
expect(list).toHaveLength(1);
|
||||
expect(list.prop('title')).toBe(`${pluginId}.table.groups.title.plural`);
|
||||
});
|
||||
|
||||
it('Should handle the listheader title correctly if there is less than 2 groups', () => {
|
||||
props.groups = [
|
||||
{
|
||||
icon: 'fa-cube',
|
||||
name: 'user',
|
||||
description: '',
|
||||
fields: 6,
|
||||
source: 'users-permissions',
|
||||
isTemporary: false,
|
||||
},
|
||||
];
|
||||
props.match.params.type = 'groups';
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const list = wrapper.find(ListHeader);
|
||||
|
||||
expect(list).toHaveLength(1);
|
||||
expect(list.prop('title')).toBe(
|
||||
`${pluginId}.table.groups.title.singular`
|
||||
);
|
||||
});
|
||||
|
||||
it('Should handle the listheader title correctly if there is less than 2 models', () => {
|
||||
props.models = [
|
||||
{
|
||||
icon: 'fa-cube',
|
||||
name: 'user',
|
||||
description: '',
|
||||
fields: 6,
|
||||
source: 'users-permissions',
|
||||
isTemporary: false,
|
||||
},
|
||||
];
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const list = wrapper.find(ListHeader);
|
||||
|
||||
expect(list).toHaveLength(1);
|
||||
expect(list.prop('title')).toBe(
|
||||
`${pluginId}.table.contentType.title.singular`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('workflow', () => {
|
||||
it('should open the modelForm for the model if there is no saved content type', () => {
|
||||
props.canOpenModal = true;
|
||||
props.history.push = jest.fn(({ search }) => {
|
||||
props.location.search = `?${search}`;
|
||||
});
|
||||
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const spyOnClick = jest.spyOn(wrapper.instance(), 'handleClick');
|
||||
|
||||
wrapper.instance().forceUpdate();
|
||||
// Simulate the click on button
|
||||
wrapper
|
||||
.find(ListHeader)
|
||||
.prop('button')
|
||||
.onClick();
|
||||
wrapper.instance().forceUpdate();
|
||||
|
||||
expect(spyOnClick).toHaveBeenCalled();
|
||||
expect(context.emitEvent).toHaveBeenCalledWith('willCreateContentType');
|
||||
expect(props.history.push).toHaveBeenCalledWith({
|
||||
search: 'modalType=model&settingType=base&actionType=create',
|
||||
});
|
||||
});
|
||||
|
||||
it('should open the modelForm for groups if there is no is no saved content type', () => {
|
||||
props.canOpenModal = true;
|
||||
props.groups = [
|
||||
{
|
||||
icon: 'fa-cube',
|
||||
name: 'user',
|
||||
description: '',
|
||||
fields: 6,
|
||||
source: 'users-permissions',
|
||||
isTemporary: false,
|
||||
},
|
||||
];
|
||||
props.location.pathname = `/plugins/${pluginId}/groups`;
|
||||
props.history.push = jest.fn(({ search }) => {
|
||||
props.location.search = `?${search}`;
|
||||
});
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
const spyOnClick = jest.spyOn(wrapper.instance(), 'handleClick');
|
||||
|
||||
wrapper.instance().forceUpdate();
|
||||
// Simulate the click on button
|
||||
wrapper
|
||||
.find(ListHeader)
|
||||
.prop('button')
|
||||
.onClick();
|
||||
wrapper.instance().forceUpdate();
|
||||
|
||||
expect(spyOnClick).toHaveBeenCalled();
|
||||
expect(context.emitEvent).toHaveBeenCalledWith('willCreateContentType');
|
||||
expect(props.history.push).toHaveBeenCalledWith({
|
||||
search: 'modalType=model&settingType=base&actionType=create',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not open the modal if there is one not saved content type and display a notification', () => {
|
||||
props.canOpenModal = false;
|
||||
const context = { emitEvent: jest.fn() };
|
||||
const wrapper = shallow(<HomePage {...props} />, { context });
|
||||
|
||||
wrapper
|
||||
.find(ListHeader)
|
||||
.prop('button')
|
||||
.onClick();
|
||||
wrapper.instance().forceUpdate();
|
||||
|
||||
expect(context.emitEvent).not.toHaveBeenCalled();
|
||||
expect(props.history.push).not.toHaveBeenCalled();
|
||||
expect(strapi.notification.info).toHaveBeenCalled();
|
||||
expect(strapi.notification.info).toHaveBeenCalledWith(
|
||||
`${pluginId}.notification.info.work.notSaved`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -159,7 +159,11 @@ class ModelForm extends React.Component {
|
||||
link: (
|
||||
<FormattedMessage id={input.inputDescriptionParams.id}>
|
||||
{msg => (
|
||||
<a href={input.inputDescriptionParams.href} target="_blank">
|
||||
<a
|
||||
href={input.inputDescriptionParams.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{msg}
|
||||
</a>
|
||||
)}
|
||||
|
@ -32,7 +32,6 @@ import Ul from '../../components/Ul';
|
||||
|
||||
import AttributeForm from '../AttributeForm';
|
||||
import AttributesModalPicker from '../AttributesPickerModal';
|
||||
import ModelForm from '../ModelForm';
|
||||
import RelationForm from '../RelationForm';
|
||||
import LeftMenu from '../LeftMenu';
|
||||
|
||||
@ -101,18 +100,18 @@ export class ModelPage extends React.Component {
|
||||
getAttributeType = () =>
|
||||
getQueryParameters(this.getSearch(), 'attributeType');
|
||||
|
||||
getFormData = () => {
|
||||
const { modifiedData, newContentType } = this.props;
|
||||
// getFormData = () => {
|
||||
// const { modifiedData, newContentType } = this.props;
|
||||
|
||||
if (
|
||||
this.getActionType() === 'create' ||
|
||||
this.isUpdatingTemporaryContentType()
|
||||
) {
|
||||
return newContentType;
|
||||
}
|
||||
// if (
|
||||
// this.getActionType() === 'create' ||
|
||||
// this.isUpdatingTemporaryContentType()
|
||||
// ) {
|
||||
// return newContentType;
|
||||
// }
|
||||
|
||||
return get(modifiedData, this.getModelName());
|
||||
};
|
||||
// return get(modifiedData, this.getModelName());
|
||||
// };
|
||||
|
||||
getModalType = () => getQueryParameters(this.getSearch(), 'modalType');
|
||||
|
||||
@ -503,27 +502,18 @@ export class ModelPage extends React.Component {
|
||||
render() {
|
||||
const listTitleMessageIdBasePrefix = `${pluginId}.modelPage.contentType.list.title`;
|
||||
const {
|
||||
cancelNewContentType,
|
||||
connections,
|
||||
clearTemporaryAttribute,
|
||||
clearTemporaryAttributeRelation,
|
||||
createTempContentType,
|
||||
history: { push },
|
||||
location: { pathname, search },
|
||||
location: { search },
|
||||
models,
|
||||
modifiedData,
|
||||
onChangeAttribute,
|
||||
onChangeExistingContentTypeMainInfos,
|
||||
onChangeNewContentTypeMainInfos,
|
||||
onChangeRelation,
|
||||
onChangeRelationNature,
|
||||
onChangeRelationTarget,
|
||||
resetExistingContentTypeMainInfos,
|
||||
resetNewContentTypeMainInfos,
|
||||
setTemporaryAttributeRelation,
|
||||
temporaryAttribute,
|
||||
temporaryAttributeRelation,
|
||||
updateTempContentType,
|
||||
} = this.props;
|
||||
const { showWarning, removePrompt } = this.state;
|
||||
|
||||
@ -641,28 +631,6 @@ export class ModelPage extends React.Component {
|
||||
onSubmitEdit={this.handleSubmitEdit}
|
||||
push={push}
|
||||
/>
|
||||
{/* <ModelForm
|
||||
actionType={actionType}
|
||||
activeTab={settingType}
|
||||
allTakenNames={allGroupsAndModelsName}
|
||||
cancelNewContentType={cancelNewContentType}
|
||||
connections={connections}
|
||||
createTempContentType={createTempContentType}
|
||||
currentData={modifiedData}
|
||||
modifiedData={this.getFormData()}
|
||||
modelToEditName={getQueryParameters(search, 'modelName')}
|
||||
onChangeExistingContentTypeMainInfos={
|
||||
onChangeExistingContentTypeMainInfos
|
||||
}
|
||||
onChangeNewContentTypeMainInfos={onChangeNewContentTypeMainInfos}
|
||||
isOpen={modalType === 'model'}
|
||||
isUpdatingTemporaryContentType={this.isUpdatingTemporaryContentType()}
|
||||
pathname={pathname}
|
||||
push={push}
|
||||
resetExistingContentTypeMainInfos={resetExistingContentTypeMainInfos}
|
||||
resetNewContentTypeMainInfos={resetNewContentTypeMainInfos}
|
||||
updateTempContentType={updateTempContentType}
|
||||
/> */}
|
||||
<PopUpWarning
|
||||
isOpen={showWarning}
|
||||
toggleModal={this.toggleModalWarning}
|
||||
@ -725,15 +693,11 @@ ModelPage.propTypes = {
|
||||
modifiedData: PropTypes.object.isRequired,
|
||||
newContentType: PropTypes.object.isRequired,
|
||||
onChangeAttribute: PropTypes.func.isRequired,
|
||||
onChangeExistingContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
onChangeNewContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
onChangeRelation: PropTypes.func.isRequired,
|
||||
onChangeRelationNature: PropTypes.func.isRequired,
|
||||
onChangeRelationTarget: PropTypes.func.isRequired,
|
||||
resetEditExistingContentType: PropTypes.func.isRequired,
|
||||
resetEditTempContentType: PropTypes.func.isRequired,
|
||||
resetExistingContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
resetNewContentTypeMainInfos: PropTypes.func.isRequired,
|
||||
saveEditedAttribute: PropTypes.func.isRequired,
|
||||
saveEditedAttributeRelation: PropTypes.func.isRequired,
|
||||
setTemporaryAttribute: PropTypes.func.isRequired,
|
||||
@ -742,7 +706,6 @@ ModelPage.propTypes = {
|
||||
submitTempContentType: PropTypes.func.isRequired,
|
||||
temporaryAttribute: PropTypes.object.isRequired,
|
||||
temporaryAttributeRelation: PropTypes.object.isRequired,
|
||||
updateTempContentType: PropTypes.func.isRequired,
|
||||
...routerPropTypes({ params: PropTypes.string }).isRequired,
|
||||
};
|
||||
|
||||
|
@ -126,16 +126,13 @@ describe('<ModelPage />', () => {
|
||||
name: '',
|
||||
attributes: {},
|
||||
},
|
||||
onChangeExistingContentTypeMainInfos: jest.fn(),
|
||||
onChangeNewContentTypeMainInfos: jest.fn(),
|
||||
onChangeAttribute: jest.fn(),
|
||||
onChangeRelation: jest.fn(),
|
||||
onChangeRelationNature: jest.fn(),
|
||||
onChangeRelationTarget: jest.fn(),
|
||||
resetEditExistingContentType: jest.fn(),
|
||||
resetEditTempContentType: jest.fn(),
|
||||
resetExistingContentTypeMainInfos: jest.fn(),
|
||||
resetNewContentTypeMainInfos: jest.fn(),
|
||||
|
||||
saveEditedAttribute: jest.fn(),
|
||||
saveEditedAttributeRelation: jest.fn(),
|
||||
setTemporaryAttribute: jest.fn(),
|
||||
@ -154,7 +151,6 @@ describe('<ModelPage />', () => {
|
||||
target: '',
|
||||
unique: false,
|
||||
},
|
||||
updateTempContentType: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
@ -427,16 +423,12 @@ describe('<ModelPage /> lifecycle', () => {
|
||||
name: '',
|
||||
attributes: {},
|
||||
},
|
||||
onChangeExistingContentTypeMainInfos: jest.fn(),
|
||||
onChangeNewContentTypeMainInfos: jest.fn(),
|
||||
onChangeAttribute: jest.fn(),
|
||||
onChangeRelation: jest.fn(),
|
||||
onChangeRelationNature: jest.fn(),
|
||||
onChangeRelationTarget: jest.fn(),
|
||||
resetEditExistingContentType: jest.fn(),
|
||||
resetEditTempContentType: jest.fn(),
|
||||
resetExistingContentTypeMainInfos: jest.fn(),
|
||||
resetNewContentTypeMainInfos: jest.fn(),
|
||||
saveEditedAttribute: jest.fn(),
|
||||
saveEditedAttributeRelation: jest.fn(),
|
||||
setTemporaryAttribute: jest.fn(),
|
||||
@ -455,7 +447,6 @@ describe('<ModelPage /> lifecycle', () => {
|
||||
target: '',
|
||||
unique: false,
|
||||
},
|
||||
updateTempContentType: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { camelCase, truncate } from 'lodash';
|
||||
import { truncate } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import pluralize from 'pluralize';
|
||||
|
||||
@ -57,14 +57,14 @@ const NaturePicker = ({ modelName, onClick, nature, target }) => {
|
||||
leftName: pluralize(modelName, nature === 'manyToMany' ? 2 : 1),
|
||||
rightName: pluralize(
|
||||
target,
|
||||
['manyToMany', 'oneToMany', 'manyToOne'].includes(nature) ? 2 : 1,
|
||||
['manyToMany', 'oneToMany', 'manyToOne'].includes(nature) ? 2 : 1
|
||||
),
|
||||
}
|
||||
: {
|
||||
leftName: target,
|
||||
rightName: pluralize(
|
||||
modelName,
|
||||
['manyToMany', 'oneToMany', 'manyToOne'].includes(nature) ? 2 : 1,
|
||||
['manyToMany', 'oneToMany', 'manyToOne'].includes(nature) ? 2 : 1
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -9,11 +9,11 @@ describe('<InlineBlock />', () => {
|
||||
});
|
||||
|
||||
it('should render his children', () => {
|
||||
const Child = () => <div>I'm a child</div>;
|
||||
const Child = () => <div>I am a child</div>;
|
||||
const wrapper = shallow(
|
||||
<InlineBlock>
|
||||
<Child />
|
||||
</InlineBlock>,
|
||||
</InlineBlock>
|
||||
);
|
||||
|
||||
expect(wrapper.find(Child).exists()).toBe(true);
|
||||
|
@ -62,7 +62,7 @@ function* submit() {
|
||||
return yield put(
|
||||
setFormErrors({
|
||||
password: [{ id: 'components.Input.error.validation.required' }],
|
||||
}),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@ -95,12 +95,16 @@ function* updateDoc(action) {
|
||||
|
||||
// Individual exports for testing
|
||||
export function* defaultSaga() {
|
||||
try {
|
||||
yield all([
|
||||
fork(takeLatest, GET_DOC_INFOS, getData),
|
||||
fork(takeLatest, ON_CONFIRM_DELETE_DOC, deleteDoc),
|
||||
fork(takeLatest, ON_SUBMIT, submit),
|
||||
fork(takeLatest, ON_UPDATE_DOC, updateDoc),
|
||||
]);
|
||||
} catch (err) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// All sagas to be loaded
|
||||
|
@ -6,7 +6,17 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { findIndex, forEach, has, isObject , join, pullAt, split, includes} from 'lodash';
|
||||
import {
|
||||
findIndex,
|
||||
forEach,
|
||||
has,
|
||||
isObject,
|
||||
join,
|
||||
pullAt,
|
||||
split,
|
||||
includes,
|
||||
} from 'lodash';
|
||||
/* eslint-disable */
|
||||
|
||||
import InputNumber from '../InputNumber';
|
||||
import InputText from '../InputText';
|
||||
@ -18,18 +28,16 @@ import config from './config.json';
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable react/require-default-props */
|
||||
const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
const WithFormSection = InnerComponent =>
|
||||
class extends React.Component {
|
||||
static propTypes = {
|
||||
addRequiredInputDesign: PropTypes.bool,
|
||||
cancelAction: PropTypes.bool,
|
||||
formErrors: PropTypes.array,
|
||||
onChange: PropTypes.func,
|
||||
section: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.array,
|
||||
]),
|
||||
section: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
values: PropTypes.object,
|
||||
}
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -57,8 +65,15 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.section !== this.props.section || nextProps.cancelAction !== this.props.cancelAction) {
|
||||
this.setState({ showNestedForm: false, hasNestedInput: false, inputWithNestedForm: '' });
|
||||
if (
|
||||
nextProps.section !== this.props.section ||
|
||||
nextProps.cancelAction !== this.props.cancelAction
|
||||
) {
|
||||
this.setState({
|
||||
showNestedForm: false,
|
||||
hasNestedInput: false,
|
||||
inputWithNestedForm: '',
|
||||
});
|
||||
if (isObject(nextProps.section)) {
|
||||
this.checkForNestedForm(nextProps);
|
||||
}
|
||||
@ -66,9 +81,12 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
}
|
||||
|
||||
checkForNestedForm(props) {
|
||||
forEach(props.section.items, (input) => {
|
||||
forEach(props.section.items, input => {
|
||||
if (has(input, 'items')) {
|
||||
this.setState({ hasNestedInput: true, inputWithNestedForm: input.target });
|
||||
this.setState({
|
||||
hasNestedInput: true,
|
||||
inputWithNestedForm: input.target,
|
||||
});
|
||||
|
||||
if (props.values[input.target]) {
|
||||
this.setState({ showNestedForm: true });
|
||||
@ -84,32 +102,42 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
}
|
||||
|
||||
this.props.onChange({ target });
|
||||
}
|
||||
};
|
||||
|
||||
renderInput = (props, key) => {
|
||||
const Input = this.inputs[props.type];
|
||||
const inputValue = this.props.values[props.target];
|
||||
// retrieve options for the select input
|
||||
const selectOptions = props.type === 'enum' || props.type === 'select' ? props.items : [];
|
||||
const selectOptions =
|
||||
props.type === 'enum' || props.type === 'select' ? props.items : [];
|
||||
|
||||
// custom check for dynamic keys used for databases
|
||||
const dynamicTarget = join(pullAt(split(props.target, '.'),['0', '1', '3', '4']), '.');
|
||||
const dynamicTarget = join(
|
||||
pullAt(split(props.target, '.'), ['0', '1', '3', '4']),
|
||||
'.'
|
||||
);
|
||||
|
||||
// check if the input has a nested form so it is displayed on the entire line
|
||||
const customBootstrapClass = this.state.hasNestedInput ?
|
||||
// bootstrap class to make the input displayed on the entire line
|
||||
'col-md-6 offset-md-6 mr-md-5' :
|
||||
// if the input hasn't a nested form but the config requires him to be displayed differently
|
||||
const customBootstrapClass = this.state.hasNestedInput
|
||||
? // bootstrap class to make the input displayed on the entire line
|
||||
'col-md-6 offset-md-6 mr-md-5'
|
||||
: // if the input hasn't a nested form but the config requires him to be displayed differently
|
||||
config[props.target] || config[dynamicTarget] || '';
|
||||
|
||||
// custom handleChange props for nested input form
|
||||
const handleChange = this.state.hasNestedInput ? this.handleChange : this.props.onChange;
|
||||
const handleChange = this.state.hasNestedInput
|
||||
? this.handleChange
|
||||
: this.props.onChange;
|
||||
let hiddenLabel = includes(props.name, 'enabled');
|
||||
|
||||
if (includes(config.showInputLabel, props.name)) hiddenLabel = false;
|
||||
|
||||
const errorIndex = findIndex(this.props.formErrors, ['target', props.target]);
|
||||
const errors = errorIndex !== -1 ? this.props.formErrors[errorIndex].errors : [];
|
||||
const errorIndex = findIndex(this.props.formErrors, [
|
||||
'target',
|
||||
props.target,
|
||||
]);
|
||||
const errors =
|
||||
errorIndex !== -1 ? this.props.formErrors[errorIndex].errors : [];
|
||||
|
||||
return (
|
||||
<Input
|
||||
@ -128,7 +156,7 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
errors={errors}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
@ -7,16 +7,14 @@
|
||||
import React from 'react';
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
/* eslint-disable react/require-default-props */
|
||||
const WithInput = (InnerInput) => class extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
const WithInput = InnerInput =>
|
||||
class extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
render() {
|
||||
return (
|
||||
<InnerInput
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
styles={styles}
|
||||
/>
|
||||
);
|
||||
return <InnerInput {...this.props} {...this.state} styles={styles} />;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user