corvée(dépendances) ajoute Carbon Fields

This commit is contained in:
gcch 2024-08-09 18:45:01 +02:00
commit 62368587e5
459 changed files with 72750 additions and 26 deletions

View file

@ -0,0 +1,169 @@
/**
* Returns an action object used to setup the state when first opening an editor.
*
* @param {Object[]} containers
* @param {Object} fields
* @return {Object}
*/
export function setupState( containers, fields ) {
return {
type: 'SETUP_STATE',
payload: {
containers,
fields
}
};
}
/**
* Returns an action object used to update the state.
*
* @param {Object[]} containers
* @param {Object} fields
* @return {Object}
*/
export function updateState( containers, fields ) {
return {
type: 'UPDATE_STATE',
payload: {
containers,
fields
}
};
}
/**
* Returns an action object used to update the field's value.
*
* @param {string} fieldId
* @param {mixed} value
* @param {string[]} fieldsToRemove It's used by the complex fields to remove the nested
* fields within a single action.
* @return {Object}
*/
export function updateFieldValue( fieldId, value, fieldsToRemove = [] ) {
return {
type: 'UPDATE_FIELD_VALUE',
payload: {
fieldId,
value,
fieldsToRemove
}
};
}
/**
* Returns an action object used to add the fields.
*
* @param {Object[]} fields
* @return {Object}
*/
export function addFields( fields ) {
return {
type: 'ADD_FIELDS',
payload: {
fields
}
};
}
/**
* Returns an action object used to clone the fields.
*
* @param {string[]} originFieldIds
* @param {string[]} cloneFieldIds
* @return {Object}
*/
export function cloneFields( originFieldIds, cloneFieldIds ) {
return {
type: 'CLONE_FIELDS',
payload: {
originFieldIds,
cloneFieldIds
}
};
}
/**
* Returns an action object used to remove the fields.
*
* @param {string[]} fieldIds
* @return {Object}
*/
export function removeFields( fieldIds ) {
return {
type: 'REMOVE_FIELDS',
payload: {
fieldIds
}
};
}
/**
* Returns an action object used to add a container to all containers.
*
* @param {Object} container
* @return {Object}
*/
export function addContainer( container ) {
return {
type: 'ADD_CONTAINER',
payload: container
};
}
/**
* Returns an action object used to remove a container from all containers.
*
* @param {Object} container
* @return {Object}
*/
export function removeContainer( container ) {
return {
type: 'REMOVE_CONTAINER',
payload: container
};
}
/**
* Returns an action object used to add the created sidebar to all fields.
*
* @param {Object} sidebar
* @return {Object}
*/
export function receiveSidebar( sidebar ) {
return {
type: 'RECEIVE_SIDEBAR',
payload: sidebar
};
}
/**
* Returns an action object used to signal that saving is locked.
*
* @param {string} lockName
* @return {Object}
*/
export function lockSaving( lockName ) {
return {
type: 'LOCK_SAVING',
payload: {
lockName
}
};
}
/**
* Returns an action object used to signal that saving is unlocked.
*
* @param {string} lockName
* @return {Object}
*/
export function unlockSaving( lockName ) {
return {
type: 'UNLOCK_SAVING',
payload: {
lockName
}
};
}

View file

@ -0,0 +1,28 @@
/**
* External dependencies.
*/
import { assign, endsWith } from 'lodash';
/**
* Internal dependencies.
*/
import flattenField from '../utils/flatten-field';
/**
* Transform the shape of the given state to be more Redux friendly.
*
* @param {Object} state
* @return {Object}
*/
export function normalizePreloadedState( state ) {
const fields = [];
const containers = state
.filter( ( { id } ) => ! endsWith( id, '__i__' ) )
.map( ( container ) => {
return assign( {}, container, {
fields: container.fields.map( ( field ) => flattenField( field, container.id, fields ) )
} );
} );
return { containers, fields };
}

View file

@ -0,0 +1,35 @@
/**
* External dependencies.
*/
import { registerStore, dispatch } from '@wordpress/data';
import {
get,
keyBy
} from 'lodash';
/**
* Internal dependencies.
*/
import reducer from './reducer';
import * as actions from './actions';
import * as selectors from './selectors';
import { normalizePreloadedState } from './helpers';
/**
* Register the store.
*/
registerStore( 'carbon-fields/metaboxes', {
reducer,
actions,
selectors
} );
/**
* Hydrate the store's state.
*/
const { containers, fields } = normalizePreloadedState( get( window.cf, 'preloaded.containers', [] ) );
dispatch( 'carbon-fields/metaboxes' ).setupState(
keyBy( containers, 'id' ),
keyBy( fields, 'id' )
);

View file

@ -0,0 +1,247 @@
/**
* External dependencies.
*/
import produce from 'immer';
import { combineReducers } from '@wordpress/data';
import {
omit,
keyBy,
assign,
forEach,
cloneDeep,
values,
unset
} from 'lodash';
/**
* Carbon Fields dependencies.
*/
import { uniqueId } from '@carbon-fields/core';
/**
* The reducer that keeps track of the containers.
*
* @param {Object} state
* @param {Object} action
* @return {Object}
*/
export function containers( state = {}, action ) {
switch ( action.type ) {
case 'SETUP_STATE':
return action.payload.containers;
case 'UPDATE_STATE':
return produce( state, ( draft ) => {
values( action.payload.containers ).forEach( ( container ) => {
draft[ container.id ] = container;
} );
} );
case 'ADD_CONTAINER':
return produce( state, ( draft ) => {
draft[ action.payload.id ] = action.payload;
} );
case 'REMOVE_CONTAINER':
return omit( state, action.payload );
default:
return state;
}
}
/**
* Clones a field.
*
* @param {string} originId
* @param {string} cloneId
* @param {Object} fields
* @param {Object[]} accumulator
* @return {Object[]}
*/
function cloneField( originId, cloneId, fields, accumulator ) {
const field = cloneDeep( fields[ originId ] );
field.id = cloneId;
if ( field.type === 'complex' ) {
field.value.forEach( ( group ) => {
group.id = uniqueId();
accumulator = group.fields.reduce( ( groupAccumulator, groupField ) => {
const originGroupFieldId = groupField.id;
const cloneGroupFieldId = uniqueId();
groupField.id = cloneGroupFieldId;
return cloneField( originGroupFieldId, cloneGroupFieldId, fields, groupAccumulator );
}, accumulator );
} );
}
return accumulator.concat( field );
}
/**
* Returns a list of field ids by a given root id.
*
* @param {string} fieldId
* @param {Object} fields
* @param {string[]} accumulator
* @return {string[]}
*/
function getFieldIdsByRootId( fieldId, fields, accumulator ) {
const field = fields[ fieldId ];
if ( field.type === 'complex' ) {
field.value.forEach( ( group ) => {
accumulator = group.fields.reduce( ( groupAccumulator, groupField ) => {
return getFieldIdsByRootId( groupField.id, fields, groupAccumulator );
}, accumulator );
} );
}
return accumulator.concat( fieldId );
}
/**
* The reducer that keeps track of the fields.
*
* @param {Object} state
* @param {Object} action
* @return {Object}
*/
export function fields( state = {}, action ) {
switch ( action.type ) {
case 'SETUP_STATE':
return action.payload.fields;
case 'UPDATE_STATE':
return produce( state, ( draft ) => {
values( action.payload.fields ).forEach( ( field ) => {
draft[ field.id ] = field;
} );
} );
case 'UPDATE_FIELD_VALUE':
return produce( state, ( draft ) => {
const {
fieldId,
value,
fieldsToRemove
} = action.payload;
draft[ fieldId ].value = value;
const fieldIdsToRemove = fieldsToRemove.reduce( ( accumulator, fieldIdToRemove ) => {
return getFieldIdsByRootId( fieldIdToRemove, state, accumulator );
}, [] );
fieldIdsToRemove.forEach( ( fieldIdToRemove ) => {
unset( draft, fieldIdToRemove );
} );
} );
case 'ADD_FIELDS':
return produce( state, ( draft ) => {
action.payload.fields.forEach( ( field ) => {
draft[ field.id ] = field;
} );
} );
case 'CLONE_FIELDS':
return produce( state, ( draft ) => {
const { originFieldIds, cloneFieldIds } = action.payload;
const clonedFields = originFieldIds.reduce( ( accumulator, originFieldId, index ) => {
return cloneField( originFieldId, cloneFieldIds[ index ], draft, accumulator );
}, [] );
assign( draft, keyBy( clonedFields, 'id' ) );
} );
case 'REMOVE_FIELDS':
const fieldIds = action.payload.fieldIds.reduce( ( accumulator, fieldId ) => {
return getFieldIdsByRootId( fieldId, state, accumulator );
}, [] );
return omit( state, fieldIds );
case 'RECEIVE_SIDEBAR':
return produce( state, ( draft ) => {
forEach( draft, ( field ) => {
if ( field.type === 'sidebar' ) {
field.options.unshift( action.payload );
}
} );
} );
default:
return state;
}
}
/**
* The reducer that keeps track of the save locks.
*
* @param {Object} state
* @param {Object} action
* @return {Object}
*/
export function savingLock( state = {}, action ) {
switch ( action.type ) {
case 'LOCK_SAVING':
return {
...state,
[ action.payload.lockName ]: true
};
case 'UNLOCK_SAVING':
return omit( state, [ action.payload.lockName ] );
default:
return state;
}
}
/**
* The reducer that keeps track if there is dirty fields.
*
* @param {boolean} state
* @param {Object} action
* @return {Object}
*/
export function isDirty( state = false, action ) {
switch ( action.type ) {
case 'UPDATE_FIELD_VALUE':
return true;
default:
return state;
}
}
/**
* The reducer that keeps track if an update is being made.
*
* @param {boolean} state
* @param {Object} action
* @return {Object}
*/
export function isFieldUpdated( state, action ) {
switch ( action.type ) {
case 'UPDATE_FIELD_VALUE':
return { action };
default:
return false;
}
}
export default combineReducers( {
containers,
fields,
savingLock,
isDirty,
isFieldUpdated
} );

View file

@ -0,0 +1,108 @@
/**
* External dependencies.
*/
import {
filter,
pick,
mapValues,
mapKeys
} from 'lodash';
/**
* Returns the containers.
*
* @param {Object} state
* @return {Object[]}
*/
export function getContainers( state ) {
return state.containers;
}
/**
* Returns a container by an id.
*
* @param {Object} state
* @param {string} containerId
* @return {?Object}
*/
export function getContainerById( state, containerId ) {
return state.containers[ containerId ];
}
/**
* Returns the fields.
*
* @param {Object} state
* @return {Object}
*/
export function getFields( state ) {
return state.fields;
}
/**
* Returns the fields that belong to the specified container.
*
* @param {Object} state
* @param {string} containerId
* @return {Object[]}
*/
export function getFieldsByContainerId( state, containerId ) {
return filter( state.fields, [ 'container_id', containerId ] );
}
/**
* Returns a field by an id.
*
* @param {Object} state
* @param {string} fieldId
* @return {?Object}
*/
export function getFieldById( state, fieldId ) {
return state.fields[ fieldId ];
}
/**
* Returns whether saving is locked.
*
* @param {Object} state
* @return {boolean}
*/
export function isSavingLocked( state ) {
return Object.keys( state.savingLock ).length > 0;
}
/**
* Returns whether the metaboxes fields contain unsaved changed.
*
* @param {Object} state
* @return {boolean}
*/
export function isDirty( state ) {
return state.isDirty;
}
/**
* Returns whether the metaboxes fields contain unsaved changed.
*
* @param {Object} state
* @return {boolean}
*/
export function isFieldUpdated( state ) {
return state.isFieldUpdated;
}
/**
* Returns a map of field values for a given group.
*
* @param {Object} state
* @param {string[]} fieldIds
* @return {Object}
*/
export function getComplexGroupValues( state, fieldIds ) {
let fields = pick( getFields( state ), fieldIds );
fields = mapKeys( fields, ( field ) => field.base_name.replace( /\-/g, '_' ) );
fields = mapValues( fields, ( field ) => field.value );
return fields;
}