mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 15:13:21 +00:00
Handle add attribute for all data
This commit is contained in:
parent
c3d6b206e6
commit
24a304e194
@ -14,22 +14,19 @@
|
||||
"comment": ""
|
||||
},
|
||||
"attributes": {
|
||||
"full_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"postal_coder": {
|
||||
"type": "string"
|
||||
},
|
||||
"city": {
|
||||
"type": "string"
|
||||
"addresses": {
|
||||
"collection": "address",
|
||||
"via": "address"
|
||||
},
|
||||
"geolocation": {
|
||||
"type": "json",
|
||||
"required": true
|
||||
},
|
||||
"addresses": {
|
||||
"collection": "address",
|
||||
"via": "address"
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"postal_coder": {
|
||||
"type": "string"
|
||||
},
|
||||
"address": {
|
||||
"model": "address",
|
||||
@ -47,10 +44,8 @@
|
||||
"plugin": "upload",
|
||||
"required": false
|
||||
},
|
||||
"teter": {
|
||||
"type": "component",
|
||||
"repeatable": false,
|
||||
"component": "default.teter"
|
||||
"full_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,10 +13,6 @@
|
||||
"attributes": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"toto": {
|
||||
"via": "category",
|
||||
"model": "toto"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,10 +24,6 @@
|
||||
"maxLength": 3,
|
||||
"unique": true,
|
||||
"minLength": 2
|
||||
},
|
||||
"toto": {
|
||||
"via": "countries",
|
||||
"model": "toto"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,10 +26,6 @@
|
||||
"like_right": {
|
||||
"model": "like",
|
||||
"via": "like_left"
|
||||
},
|
||||
"totos": {
|
||||
"via": "like",
|
||||
"collection": "toto"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,10 +21,6 @@
|
||||
"restaurant": {
|
||||
"model": "restaurant",
|
||||
"via": "menu"
|
||||
},
|
||||
"totos": {
|
||||
"via": "menus",
|
||||
"collection": "toto"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/totos",
|
||||
"handler": "toto.find",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/totos/count",
|
||||
"handler": "toto.count",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/totos/:id",
|
||||
"handler": "toto.findOne",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/totos",
|
||||
"handler": "toto.create",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/totos/:id",
|
||||
"handler": "toto.update",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"path": "/totos/:id",
|
||||
"handler": "toto.delete",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/controllers.html#core-controllers)
|
||||
* to customize this controller
|
||||
*/
|
||||
|
||||
module.exports = {};
|
||||
@ -1,44 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `toto` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
@ -1,92 +0,0 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "totos",
|
||||
"info": {
|
||||
"name": "toto"
|
||||
},
|
||||
"attributes": {
|
||||
"totosmanytomanyright": {
|
||||
"collection": "toto",
|
||||
"via": "totosmanytomany"
|
||||
},
|
||||
"totoonewayLeft": {
|
||||
"model": "toto",
|
||||
"via": "totoonewayRight"
|
||||
},
|
||||
"totosonetomanyLeft": {
|
||||
"collection": "toto",
|
||||
"via": "totoonetomanyRight"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"default": "something"
|
||||
},
|
||||
"menusections": {
|
||||
"collection": "menusection"
|
||||
},
|
||||
"totosmanytooneright": {
|
||||
"collection": "toto",
|
||||
"via": "totomanytooneleft"
|
||||
},
|
||||
"totoonetomanyRight": {
|
||||
"model": "toto",
|
||||
"via": "totosonetomanyLeft"
|
||||
},
|
||||
"mainCompoField": {
|
||||
"type": "component",
|
||||
"repeatable": true,
|
||||
"component": "nested.compo-with-nested",
|
||||
"max": 2
|
||||
},
|
||||
"totosmanyway": {
|
||||
"collection": "toto"
|
||||
},
|
||||
"countries": {
|
||||
"collection": "country",
|
||||
"via": "toto"
|
||||
},
|
||||
"menus": {
|
||||
"collection": "menu",
|
||||
"via": "totos",
|
||||
"dominant": true
|
||||
},
|
||||
"address": {
|
||||
"model": "address"
|
||||
},
|
||||
"toto": {
|
||||
"model": "toto"
|
||||
},
|
||||
"totosmanytomany": {
|
||||
"collection": "toto",
|
||||
"via": "totosmanytomanyright",
|
||||
"dominant": true
|
||||
},
|
||||
"like": {
|
||||
"model": "like",
|
||||
"via": "totos"
|
||||
},
|
||||
"compoField": {
|
||||
"type": "component",
|
||||
"repeatable": false,
|
||||
"component": "compo.newcompo"
|
||||
},
|
||||
"totoonewayRight": {
|
||||
"model": "toto",
|
||||
"via": "totoonewayLeft"
|
||||
},
|
||||
"totomanytooneleft": {
|
||||
"model": "toto",
|
||||
"via": "totosmanytooneright"
|
||||
},
|
||||
"category": {
|
||||
"model": "category",
|
||||
"via": "toto"
|
||||
},
|
||||
"dz": {
|
||||
"type": "dynamiczone",
|
||||
"components": [
|
||||
"babab.baba"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/services.html#core-services)
|
||||
* to customize this service
|
||||
*/
|
||||
|
||||
module.exports = {};
|
||||
@ -1,16 +0,0 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "components_babab_babas",
|
||||
"info": {
|
||||
"name": "baba",
|
||||
"icon": "balance-scale-right"
|
||||
},
|
||||
"attributes": {
|
||||
"babaname": {
|
||||
"type": "string",
|
||||
"default": "babababa",
|
||||
"unique": true,
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "components_compo_newcompos",
|
||||
"info": {
|
||||
"name": "newcompo",
|
||||
"icon": "address-book"
|
||||
},
|
||||
"attributes": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"default": "something"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "components_main_main_compos",
|
||||
"info": {
|
||||
"name": "main compo",
|
||||
"icon": "air-freshener"
|
||||
},
|
||||
"attributes": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"subCompoField": {
|
||||
"type": "component",
|
||||
"repeatable": false,
|
||||
"component": "main.sub-compo"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "components_main_sub_compos",
|
||||
"info": {
|
||||
"name": "subCompo",
|
||||
"icon": "align-center"
|
||||
},
|
||||
"attributes": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import PropTypes from 'prop-types';
|
||||
import { useGlobalContext } from 'strapi-helper-plugin';
|
||||
|
||||
import pluginId from '../../pluginId';
|
||||
import useListView from '../../hooks/useListView';
|
||||
|
||||
import DynamicZoneList from '../DynamicZoneList';
|
||||
import ComponentList from '../ComponentList';
|
||||
@ -19,10 +20,8 @@ function List({
|
||||
className,
|
||||
customRowComponent,
|
||||
items,
|
||||
addField,
|
||||
addComponentToDZ,
|
||||
targetUid,
|
||||
|
||||
mainTypeName,
|
||||
editTarget,
|
||||
firstLoopComponentName,
|
||||
@ -31,11 +30,31 @@ function List({
|
||||
secondLoopComponentUid,
|
||||
}) {
|
||||
const { formatMessage } = useGlobalContext();
|
||||
const { openModalAddField } = useListView();
|
||||
const addButtonProps = {
|
||||
icon: true,
|
||||
color: 'primary',
|
||||
label: formatMessage({ id: `${pluginId}.button.attributes.add.another` }),
|
||||
onClick: () => addField(),
|
||||
onClick: () => {
|
||||
let headerDisplayName = mainTypeName;
|
||||
|
||||
if (firstLoopComponentName) {
|
||||
headerDisplayName = firstLoopComponentName;
|
||||
}
|
||||
|
||||
if (secondLoopComponentUid) {
|
||||
headerDisplayName = secondLoopComponentName;
|
||||
}
|
||||
|
||||
openModalAddField(
|
||||
editTarget,
|
||||
targetUid,
|
||||
headerDisplayName,
|
||||
firstLoopComponentUid ? mainTypeName : null,
|
||||
secondLoopComponentName ? firstLoopComponentName : null,
|
||||
secondLoopComponentUid ? firstLoopComponentUid : null
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
@ -108,12 +127,9 @@ List.defaultProps = {
|
||||
};
|
||||
|
||||
List.propTypes = {
|
||||
addField: PropTypes.func,
|
||||
addComponentToDZ: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
customRowComponent: PropTypes.func,
|
||||
// dataType: PropTypes.string.isRequired,
|
||||
// dataTypeName: PropTypes.string.isRequired,
|
||||
editTarget: PropTypes.string.isRequired,
|
||||
firstLoopComponentName: PropTypes.string,
|
||||
firstLoopComponentUid: PropTypes.string,
|
||||
|
||||
@ -427,8 +427,6 @@ const DataManagerProvider = ({ allIcons, children }) => {
|
||||
});
|
||||
};
|
||||
|
||||
console.log({ modifiedData });
|
||||
|
||||
return (
|
||||
<DataManagerContext.Provider
|
||||
value={{
|
||||
|
||||
@ -59,6 +59,7 @@ const FormModal = () => {
|
||||
editCategory,
|
||||
modifiedData: allDataSchema,
|
||||
nestedComponents,
|
||||
setModifiedData,
|
||||
sortedContentTypesList,
|
||||
updateSchema,
|
||||
} = useDataManager();
|
||||
@ -110,6 +111,11 @@ const FormModal = () => {
|
||||
targetUid,
|
||||
});
|
||||
|
||||
// Reset all the modification when opening the edit category modal
|
||||
if (modalType === 'editCategory') {
|
||||
setModifiedData();
|
||||
}
|
||||
|
||||
// Case:
|
||||
// the user opens the modal chooseAttributes
|
||||
// selects dynamic zone => set the field name
|
||||
|
||||
@ -28,7 +28,6 @@ function LeftMenu({ wait }) {
|
||||
componentsGroupedByCategory,
|
||||
contentTypes,
|
||||
isInDevelopmentMode,
|
||||
setModifiedData,
|
||||
sortedContentTypesList,
|
||||
} = useDataManager();
|
||||
const { formatMessage } = useGlobalContext();
|
||||
@ -42,8 +41,6 @@ function LeftMenu({ wait }) {
|
||||
onClickEdit: (e, data) => {
|
||||
e.stopPropagation();
|
||||
|
||||
// Reset previous modifications
|
||||
setModifiedData();
|
||||
const search = makeSearch({
|
||||
actionType: 'edit',
|
||||
modalType: 'editCategory',
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
ViewContainer,
|
||||
} from 'strapi-helper-plugin';
|
||||
import { Header } from '@buffetjs/custom';
|
||||
import ListViewContext from '../../contexts/ListViewContext';
|
||||
import convertAttrObjToArray from '../../utils/convertAttrObjToArray';
|
||||
import getTrad from '../../utils/getTrad';
|
||||
import makeSearch from '../../utils/makeSearch';
|
||||
@ -68,12 +69,22 @@ const ListPage = () => {
|
||||
const hasModelBeenModified = !isEqual(modifiedData, initialData);
|
||||
const forTarget = isInContentTypeView ? 'contentType' : 'component';
|
||||
|
||||
const handleClickAddAttributeMainData = async () => {
|
||||
const handleClickOpenModalAddField = async (
|
||||
forTarget,
|
||||
targetUid,
|
||||
headerDisplayName,
|
||||
headerDisplayCategory = null,
|
||||
headerDisplaySubCategory = null,
|
||||
subTargetUid = null
|
||||
) => {
|
||||
const searchObj = {
|
||||
modalType: 'chooseAttribute',
|
||||
forTarget,
|
||||
targetUid,
|
||||
headerDisplayName: currentDataName,
|
||||
headerDisplayName,
|
||||
headerDisplayCategory,
|
||||
headerDisplaySubCategory,
|
||||
subTargetUid,
|
||||
};
|
||||
|
||||
// Disable the prompt
|
||||
@ -237,7 +248,9 @@ const ListPage = () => {
|
||||
icon: true,
|
||||
color: 'primary',
|
||||
label: formatMessage({ id: `${pluginId}.button.attributes.add.another` }),
|
||||
onClick: handleClickAddAttributeMainData,
|
||||
onClick: () => {
|
||||
handleClickOpenModalAddField(forTarget, targetUid, currentDataName);
|
||||
},
|
||||
};
|
||||
|
||||
const listActions = isInDevelopmentMode ? [{ ...addButtonProps }] : [];
|
||||
@ -267,41 +280,42 @@ const ListPage = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<ViewContainer>
|
||||
<BackHeader />
|
||||
<Prompt
|
||||
message={formatMessage({ id: getTrad('prompt.unsaved') })}
|
||||
when={hasModelBeenModified && enablePrompt}
|
||||
/>
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<LeftMenu wait={wait} />
|
||||
<div
|
||||
className="col-md-9 content"
|
||||
style={{ paddingLeft: '30px', paddingRight: '30px' }}
|
||||
>
|
||||
<Header {...headerProps} />
|
||||
<ListViewContext.Provider
|
||||
value={{ openModalAddField: handleClickOpenModalAddField }}
|
||||
>
|
||||
<ViewContainer>
|
||||
<BackHeader />
|
||||
<Prompt
|
||||
message={formatMessage({ id: getTrad('prompt.unsaved') })}
|
||||
when={hasModelBeenModified && enablePrompt}
|
||||
/>
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<LeftMenu wait={wait} />
|
||||
<div
|
||||
className="col-md-9 content"
|
||||
style={{ paddingLeft: '30px', paddingRight: '30px' }}
|
||||
>
|
||||
<Header {...headerProps} />
|
||||
|
||||
<ListWrapper>
|
||||
<ListHeader actions={listActions} title={listTitle} />
|
||||
<List
|
||||
items={convertAttrObjToArray(attributes)}
|
||||
customRowComponent={props => <CustomRow {...props} />}
|
||||
addField={handleClickAddAttributeMainData}
|
||||
addComponentToDZ={handleClickAddComponentToDZ}
|
||||
targetUid={targetUid}
|
||||
dataType={forTarget}
|
||||
dataTypeName={currentDataName}
|
||||
//
|
||||
mainTypeName={currentDataName}
|
||||
editTarget={forTarget}
|
||||
// parentTarget={forTarget}
|
||||
></List>
|
||||
</ListWrapper>
|
||||
<ListWrapper>
|
||||
<ListHeader actions={listActions} title={listTitle} />
|
||||
<List
|
||||
items={convertAttrObjToArray(attributes)}
|
||||
customRowComponent={props => <CustomRow {...props} />}
|
||||
addComponentToDZ={handleClickAddComponentToDZ}
|
||||
targetUid={targetUid}
|
||||
dataType={forTarget}
|
||||
dataTypeName={currentDataName}
|
||||
mainTypeName={currentDataName}
|
||||
editTarget={forTarget}
|
||||
></List>
|
||||
</ListWrapper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ViewContainer>
|
||||
</ViewContainer>
|
||||
</ListViewContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
const ListViewContext = createContext();
|
||||
|
||||
export default ListViewContext;
|
||||
@ -0,0 +1,6 @@
|
||||
import { useContext } from 'react';
|
||||
import ListViewContext from '../contexts/ListViewContext';
|
||||
|
||||
const useListView = () => useContext(ListViewContext);
|
||||
|
||||
export default useListView;
|
||||
Loading…
x
Reference in New Issue
Block a user