Init SettigViewModel

This commit is contained in:
soupette 2019-07-05 09:41:14 +02:00
parent cb9599d405
commit de9ee49878
14 changed files with 517 additions and 63 deletions

View File

@ -108,22 +108,22 @@ class SettingPage extends React.PureComponent {
const prevDisplayedFields = get(
schema,
['models', ...this.getPath().split('.'), 'editDisplay', 'fields'],
[],
[]
);
const prevDisplayedRelations = get(
schema,
['models', ...this.getPath().split('.'), 'editDisplay', 'relations'],
[],
[]
);
const currentDisplayedFields = get(
this.props.schema,
['models', ...this.getPath().split('.'), 'editDisplay', 'fields'],
[],
[]
);
const currentDisplayedRelations = get(
this.props.schema,
['models', ...this.getPath().split('.'), 'editDisplay', 'relations'],
[],
[]
);
if (prevProps.submitSuccess !== this.props.submitSuccess) {
@ -170,7 +170,7 @@ class SettingPage extends React.PureComponent {
const name = get(
this.props.schema,
`models.${this.getPath()}.primaryKey`,
'id',
'id'
);
// The id attribute is not present on the schema so we need to add it manually
const defaultAttr = {
@ -184,7 +184,7 @@ class SettingPage extends React.PureComponent {
};
const attributes = Object.assign(
get(this.props.schema, `models.${this.getPath()}.attributes`, {}),
defaultAttr,
defaultAttr
);
return Object.keys(attributes)
@ -233,7 +233,7 @@ class SettingPage extends React.PureComponent {
{
fields: [],
relations: [],
},
}
);
};
@ -252,7 +252,7 @@ class SettingPage extends React.PureComponent {
'editDisplay',
'availableFields',
],
{},
{}
);
getEditPagePossibleEntryTitleFields = () => {
@ -307,7 +307,7 @@ class SettingPage extends React.PureComponent {
const attrLabel = get(
this.props.schema,
['models', ...this.getPath().split('.'), 'relations', attrName, 'label'],
'iii',
'iii'
);
return attrLabel;
@ -317,7 +317,7 @@ class SettingPage extends React.PureComponent {
const relations = get(
this.props.schema,
'models.'.concat(this.getPath()).concat('.relations'),
{},
{}
);
return Object.keys(relations).filter(relation => {
@ -373,7 +373,7 @@ class SettingPage extends React.PureComponent {
get(
this.props.schema,
['models', this.getModelName()].concat(['primaryKey']),
'id',
'id'
);
getValue = (keys, type) => {
@ -433,7 +433,7 @@ class SettingPage extends React.PureComponent {
if (enableAttrsSort.length === 0) {
strapi.notification.info(
'content-manager.notification.info.SettingPage.disableSort',
'content-manager.notification.info.SettingPage.disableSort'
);
} else {
const newDefaultSort =
@ -458,7 +458,7 @@ class SettingPage extends React.PureComponent {
['models']
.concat(this.getPath().split('.'))
.concat(['listDisplay', index]),
{},
{}
);
this.props.onClickEditListItem(attrToEdit);
};
@ -467,7 +467,7 @@ class SettingPage extends React.PureComponent {
const fieldToEditName = get(
this.props.schema,
['models', ...this.getPath().split('.'), 'editDisplay', 'fields', index],
'',
''
);
const fieldToEdit = get(
this.props.schema,
@ -478,7 +478,7 @@ class SettingPage extends React.PureComponent {
'availableFields',
fieldToEditName,
],
{},
{}
);
return this.props.onClickEditField(fieldToEdit);
@ -488,7 +488,7 @@ class SettingPage extends React.PureComponent {
const relationToEditName = get(
this.getEditPageDisplayedRelations(),
index,
'',
''
);
const relationToEdit = get(this.props.schema, [
'models',
@ -535,7 +535,7 @@ class SettingPage extends React.PureComponent {
const fieldToEditName = get(
this.props.schema,
['models', ...keys.split('.'), 'fields', index],
'',
''
);
this.manageRemove(index, keys, fieldToEditName, fieldToEdit, false);
};
@ -568,8 +568,8 @@ class SettingPage extends React.PureComponent {
'editDisplay',
'availableFields',
],
{},
),
{}
)
);
if (
@ -578,7 +578,7 @@ class SettingPage extends React.PureComponent {
allFields.length === 0
) {
return strapi.notification.info(
'content-manager.notification.error.displayedFields',
'content-manager.notification.error.displayedFields'
);
}
@ -588,7 +588,7 @@ class SettingPage extends React.PureComponent {
allRelations.length === 0
) {
return strapi.notification.info(
'content-manager.notification.error.displayedFields',
'content-manager.notification.error.displayedFields'
);
}
@ -633,7 +633,7 @@ class SettingPage extends React.PureComponent {
if (isRelation) {
this.props.onClickAddAttrField(
toAdd,
`${this.getPath()}.editDisplay.fields`,
`${this.getPath()}.editDisplay.fields`
);
this.setState(prevState => ({
shouldSelectField: !prevState.shouldSelectField,
@ -641,7 +641,7 @@ class SettingPage extends React.PureComponent {
} else {
this.props.onClickAddAttr(
toAdd,
`${this.getPath()}.editDisplay.relations`,
`${this.getPath()}.editDisplay.relations`
);
this.setState(prevState => ({
shouldSelectRelation: !prevState.shouldSelectRelation,
@ -694,7 +694,7 @@ class SettingPage extends React.PureComponent {
}
const index = this.getEditPageDisplayedRelations().indexOf(
relationToEdit.alias,
relationToEdit.alias
);
return index;
@ -831,7 +831,7 @@ class SettingPage extends React.PureComponent {
onClick={() =>
this.props.onClickAddAttrField(
item,
`${this.getPath()}.editDisplay.fields`,
`${this.getPath()}.editDisplay.fields`
)
}
>
@ -847,7 +847,7 @@ class SettingPage extends React.PureComponent {
onClick={() =>
this.props.onClickAddAttr(
item,
`${this.getPath()}.editDisplay.relations`,
`${this.getPath()}.editDisplay.relations`
)
}
>
@ -878,7 +878,7 @@ class SettingPage extends React.PureComponent {
if (isEmpty(fieldToEdit)) {
return forms.editView.relationForm.map(
this.renderFormEditSettingsRelation,
this.renderFormEditSettingsRelation
);
}
@ -993,7 +993,7 @@ class SettingPage extends React.PureComponent {
const value = get(
this.props.schema,
['models', ...displayedFieldPath],
null,
null
);
return (
@ -1032,7 +1032,7 @@ class SettingPage extends React.PureComponent {
className={cn(
'col-md-8',
styles.draggedDescription,
styles.edit_settings,
styles.edit_settings
)}
>
<FormTitle
@ -1045,7 +1045,7 @@ class SettingPage extends React.PureComponent {
<CustomDragLayer />
<div className={cn('row', styles.noPadding)}>
{this.getEditPageDisplayedFields().map(
this.renderDraggableAttrEditSettingsField,
this.renderDraggableAttrEditSettingsField
)}
<div className={cn('col-md-6')}>
<div
@ -1054,7 +1054,7 @@ class SettingPage extends React.PureComponent {
styles.dropdownWrapper,
isOpenField && styles.dropdownWrapperOpen,
this.shouldDisplayCursorNotAllowed('fields') &&
styles.dropDownNotAllowed,
styles.dropDownNotAllowed
)}
>
<ButtonDropdown
@ -1068,7 +1068,7 @@ class SettingPage extends React.PureComponent {
</DropdownToggle>
<DropdownMenu>
{this.getDropDownFieldItems().map(
this.renderDropDownItemSettingField,
this.renderDropDownItemSettingField
)}
</DropdownMenu>
</ButtonDropdown>
@ -1084,7 +1084,7 @@ class SettingPage extends React.PureComponent {
className={cn(
'col-md-4',
styles.draggedDescription,
styles.edit_settings,
styles.edit_settings
)}
>
<FormTitle
@ -1095,7 +1095,7 @@ class SettingPage extends React.PureComponent {
<div className="row">
{/* DRAGGABLE BLOCK */}
{this.getEditPageDisplayedRelations().map(
this.renderDraggableAttrEditSettingsRelation,
this.renderDraggableAttrEditSettingsRelation
)}
{/* DRAGGABLE BLOCK */}
<div
@ -1104,7 +1104,7 @@ class SettingPage extends React.PureComponent {
styles.dropdownWrapper,
isOpenRelation && styles.dropdownWrapperOpen,
this.shouldDisplayCursorNotAllowed('relations') &&
styles.dropDownNotAllowed,
styles.dropDownNotAllowed
)}
>
<ButtonDropdown
@ -1118,7 +1118,7 @@ class SettingPage extends React.PureComponent {
</DropdownToggle>
<DropdownMenu>
{this.getDropDownRelationsItems().map(
this.renderDropDownItemEditSettingsRelation,
this.renderDropDownItemEditSettingsRelation
)}
</DropdownMenu>
</ButtonDropdown>
@ -1188,7 +1188,7 @@ class SettingPage extends React.PureComponent {
styles.dropdownWrapper,
isOpen && styles.dropdownWrapperOpen,
this.shouldDisplayCursorNotAllowed('list') &&
styles.dropDownNotAllowed,
styles.dropDownNotAllowed
)}
>
<ButtonDropdown isOpen={isOpen} toggle={this.toggleDropdown}>
@ -1199,7 +1199,7 @@ class SettingPage extends React.PureComponent {
</DropdownToggle>
<DropdownMenu>
{this.getDropDownItems().map(
this.renderDropDownItemListSettings,
this.renderDropDownItemListSettings
)}
</DropdownMenu>
</ButtonDropdown>
@ -1367,7 +1367,7 @@ const mapDispatchToProps = dispatch =>
onSubmit,
setLayout,
},
dispatch,
dispatch
);
const mapStateToProps = createStructuredSelector({
addedField: makeSelectAddedField(),
@ -1382,7 +1382,7 @@ const mapStateToProps = createStructuredSelector({
});
const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
mapDispatchToProps
);
const withReducer = strapi.injectReducer({
key: 'settingPage',
@ -1394,5 +1394,5 @@ const withSaga = strapi.injectSaga({ key: 'settingPage', saga, pluginId });
export default compose(
withReducer,
withSaga,
withConnect,
withConnect
)(DragDropContext(HTML5Backend)(SettingPage));

View File

@ -1,7 +0,0 @@
import React from 'react';
function SettingView() {
return <div>Coming soon</div>;
}
export default SettingView;

View File

@ -0,0 +1,15 @@
import { GET_DATA, GET_DATA_SUCCEEDED } from './constants';
export function getData(uid) {
return {
type: GET_DATA,
uid,
};
}
export function getDataSucceeded(layout) {
return {
type: GET_DATA_SUCCEEDED,
layout,
};
}

View File

@ -0,0 +1,3 @@
export const GET_DATA = 'ContentManager/SettingViewModel/GET_DATA';
export const GET_DATA_SUCCEEDED =
'ContentManager/SettingViewModel/GET_DATA_SUCCEEDED';

View File

@ -1,7 +1,97 @@
import React from 'react';
import React, { memo, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { upperFirst } from 'lodash';
function SettingViewModel() {
return <div>Coming soon</div>;
import { BackHeader, HeaderNav, PluginHeader } from 'strapi-helper-plugin';
import pluginId from '../../pluginId';
import Container from '../../components/Container';
import { getData } from './actions';
import reducer from './reducer';
import saga from './saga';
import makeSelectSettingViewModel from './selectors';
const getUrl = (name, to) =>
`/plugins/${pluginId}/ctm-configurations/models/${name}/${to}`;
function SettingViewModel({
getData,
history: { goBack },
match: {
params: { name },
},
}) {
strapi.useInjectReducer({ key: 'settingViewModel', reducer, pluginId });
strapi.useInjectSaga({ key: 'settingViewModel', saga, pluginId });
useEffect(() => {
getData(name);
}, []);
return (
<>
<BackHeader onClick={() => goBack()} />
<Container className="container-fluid">
<PluginHeader
actions={[]}
title={{
id: `${pluginId}.containers.SettingViewModel.pluginHeader.title`,
values: { name: upperFirst(name) },
}}
description={{
id:
'content-manager.containers.SettingPage.pluginHeaderDescription',
}}
/>
<HeaderNav
links={[
{
name: 'content-manager.containers.SettingPage.listSettings.title',
to: getUrl(name, 'list-settings'),
},
{
name: 'content-manager.containers.SettingPage.editSettings.title',
to: getUrl(name, 'edit-settings'),
},
]}
/>
</Container>
</>
);
}
export default SettingViewModel;
SettingViewModel.defaultProps = {};
SettingViewModel.propTypes = {
getData: PropTypes.func.isRequired,
history: PropTypes.shape({
goBack: PropTypes.func,
}).isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
name: PropTypes.string,
}),
}).isRequired,
};
const mapStateToProps = makeSelectSettingViewModel();
export function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
getData,
},
dispatch
);
}
const withConnect = connect(
mapStateToProps,
mapDispatchToProps
);
export default compose(
withConnect,
memo
)(SettingViewModel);

View File

@ -0,0 +1,25 @@
/**
*
* settingViewModel reducer
*/
import { fromJS, Map } from 'immutable';
import { GET_DATA_SUCCEEDED } from './constants';
export const initialState = fromJS({
initialData: Map({}),
modifiedData: Map({}),
});
function settingViewModelReducer(state = initialState, action) {
switch (action.type) {
case GET_DATA_SUCCEEDED:
return state
.update('initialData', () => Map(action.layout))
.update('modifiedData', () => Map(action.layout));
default:
return state;
}
}
export default settingViewModelReducer;

View File

@ -0,0 +1,30 @@
import { all, fork, put, call, takeLatest } from 'redux-saga/effects';
import { request } from 'strapi-helper-plugin';
import pluginId from '../../pluginId';
import { getDataSucceeded } from './actions';
import { GET_DATA } from './constants';
const getRequestUrl = path => `/${pluginId}/fixtures/${path}`;
export function* getData({ uid }) {
try {
const { layout } = yield call(request, getRequestUrl(`layouts/${uid}`), {
method: 'GET',
});
yield put(getDataSucceeded(layout));
} catch (err) {
strapi.notification.error('notification.error');
}
}
function* defaultSaga() {
try {
yield all([fork(takeLatest, GET_DATA, getData)]);
} catch (err) {
// Do nothing
}
}
export default defaultSaga;

View File

@ -0,0 +1,28 @@
import { createSelector } from 'reselect';
import pluginId from '../../pluginId';
import { initialState } from './reducer';
/**
* Direct selector to the settingViewModel state domain
*/
const settingViewModelDomain = () => state =>
state.get(`${pluginId}_settingViewModel`) || initialState;
/**
* Other specific selectors
*/
/**
* Default selector used by SettingViewModel
*/
const makeSelectSettingViewModel = () =>
createSelector(
settingViewModelDomain(),
substate => {
return substate.toJS();
}
);
export default makeSelectSettingViewModel;
export { settingViewModelDomain };

View File

@ -22,7 +22,7 @@
"customBootstrapClass": "col-md-4",
"didCheckErrors": false,
"errors": [],
"name": "bulkActions",
"name": "bulkable",
"type": "toggle",
"validations": {}
},

View File

@ -25,7 +25,7 @@ import ListRow from './ListRow';
import { getData, onChange, onReset, onSubmit } from './actions';
import reducer from './reducer';
import saga from './saga';
import makeSelectSettingView from './selectors';
import makeSelectSettingsView from './selectors';
import form from './forms.json';
@ -211,7 +211,7 @@ SettingsView.propTypes = {
shouldToggleModalSubmit: PropTypes.bool.isRequired,
};
const mapStateToProps = makeSelectSettingView();
const mapStateToProps = makeSelectSettingsView();
export function mapDispatchToProps(dispatch) {
return bindActionCreators(

View File

@ -5,7 +5,7 @@ import { initialState } from './reducer';
/**
* Direct selector to the settingView state domain
*/
const settingViewDomain = () => state =>
const settingsViewDomain = () => state =>
state.get(`${pluginId}_settingsView`) || initialState;
/**
@ -13,12 +13,12 @@ const settingViewDomain = () => state =>
*/
/**
* Default selector used by Main
* Default selector used by SettingsView
*/
const makeSelectSettingView = () =>
const makeSelectSettingsView = () =>
createSelector(
settingViewDomain(),
settingsViewDomain(),
substate => {
return substate.toJS();
}
@ -26,10 +26,10 @@ const makeSelectSettingView = () =>
const makeSelectModifiedData = () =>
createSelector(
settingViewDomain(),
settingsViewDomain(),
substate => {
return substate.get('modifiedData').toJS();
}
);
export default makeSelectSettingView;
export { settingViewDomain, makeSelectModifiedData };
export default makeSelectSettingsView;
export { settingsViewDomain, makeSelectModifiedData };

View File

@ -64,6 +64,9 @@
"containers.SettingPage.relations": "Relational fields",
"containers.SettingPage.settings": "Settings",
"containers.SettingPage.layout": "Layout",
"containers.SettingViewModel.pluginHeader.title": "Content Manager - {name}",
"containers.SettingsPage.Block.contentType.description": "Configure the specific settings",
"containers.SettingsPage.Block.contentType.title": "Content Types",
"containers.SettingsPage.Block.generalSettings.description": "Configure the default options for your Content Types",

View File

@ -40,6 +40,14 @@
"policies": []
}
},
{
"method": "GET",
"path": "/fixtures/layouts/:uid",
"handler": "ContentManagerFixtures.getLayout",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/explorer/:model",

View File

@ -1,7 +1,7 @@
module.exports = {
getGeneralSettings: ctx => {
const generalSettings = {
bulkActions: true,
bulkable: true,
filters: true,
pageEntries: 10,
search: true,
@ -22,6 +22,265 @@ module.exports = {
ctx.body = { groups };
},
getLayout: ctx => {
console.log('ooo');
const layouts = {
article: {
uid: 'article',
schema: {
// good old schema
connection: 'default',
collectionName: 'articles',
options: {},
infos: {
name: 'article',
description: '',
},
attributes: {
title: {
type: 'string',
},
content: {
type: 'text',
},
},
},
settings: {
mainField: 'id',
defaultSortBy: 'id',
searchable: true,
filterable: true,
bulkable: false,
pageSize: 10,
},
metadata: {
title: {
edit: {
label: 'title',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'title',
searchable: true,
sortable: true,
},
},
content: {
edit: {
label: 'content',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'content',
searchable: true,
sortable: true,
},
},
},
layouts: {
list: ['id', 'title', 'content'],
editRelations: [],
edit: [
[
{
name: 'title',
size: 6,
},
{
name: 'content',
size: 6,
},
],
],
},
},
user: {
uid: 'user',
schema: {
// good old schema
connection: 'default',
collectionName: 'users-permissions_user',
info: {
name: 'user',
description: '',
},
attributes: {
username: {
type: 'string',
minLength: 3,
unique: true,
configurable: false,
required: true,
},
email: {
type: 'email',
minLength: 6,
configurable: false,
required: true,
},
provider: {
type: 'string',
configurable: false,
},
password: {
type: 'password',
minLength: 6,
configurable: false,
private: true,
},
resetPasswordToken: {
type: 'string',
configurable: false,
private: true,
},
confirmed: {
type: 'boolean',
default: false,
configurable: false,
},
blocked: {
type: 'boolean',
default: false,
configurable: false,
},
role: {
model: 'role',
via: 'users',
plugin: 'users-permissions',
configurable: false,
},
},
},
settings: {
mainField: 'id',
defaultSortBy: 'id',
searchable: true,
filterable: true,
bulkable: false,
pageSize: 10,
},
metadata: {
username: {
edit: {
label: 'username',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'username',
searchable: true,
sortable: true,
},
},
email: {
edit: {
label: 'email',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'email',
searchable: true,
sortable: true,
},
},
provider: {
edit: {
label: 'provider',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'provider',
searchable: true,
sortable: true,
},
confirmed: {
edit: {
label: 'confirmed',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'confirmed',
searchable: true,
sortable: true,
},
},
blocked: {
edit: {
label: 'blocked',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'blocked',
searchable: true,
sortable: true,
},
},
role: {
edit: {
label: 'role',
description: '....',
editable: true,
visible: true,
},
list: {
label: 'role',
searchable: true,
sortable: true,
},
},
},
layouts: {
list: ['id', 'title', 'content'],
editRelations: ['role'],
edit: [
[
{
name: 'username',
size: 6,
},
{
name: 'email',
size: 6,
},
{
name: 'provider',
size: 6,
},
{
name: 'password',
size: 6,
},
{
name: 'confirmed',
size: 4,
},
{
name: 'blocked',
size: 4,
},
],
],
},
},
},
};
ctx.body = { layout: layouts[ctx.params.uid] };
},
getModels: ctx => {
const models = [
{