mirror of
https://github.com/wassname/talk.git
synced 2026-08-13 12:40:11 +08:00
Refractor plugins helper
This commit is contained in:
@@ -6,7 +6,7 @@ import isEqual from 'lodash/isEqual';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from 'coral-framework/translations';
|
||||
const lang = new I18n(translations);
|
||||
import {graphImporter} from 'coral-framework/helpers/plugins';
|
||||
import {queriesAndMutators as pluginQueriesAndMutators} from 'coral-framework/helpers/plugins';
|
||||
|
||||
import {TabBar, Tab, TabContent, Spinner} from 'coral-ui';
|
||||
|
||||
@@ -306,5 +306,5 @@ export default compose(
|
||||
removeCommentTag,
|
||||
deleteAction,
|
||||
queryStream,
|
||||
...graphImporter
|
||||
...pluginQueriesAndMutators,
|
||||
)(Embed);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as authActions from './auth';
|
||||
import * as assetActions from './asset';
|
||||
import * as notificationActions from './notification';
|
||||
import {actionsImporter} from '../helpers/plugins';
|
||||
import {actions as pluginActions} from '../helpers/plugins';
|
||||
|
||||
export default {
|
||||
authActions,
|
||||
assetActions,
|
||||
notificationActions,
|
||||
pluginActions: actionsImporter
|
||||
pluginActions,
|
||||
};
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import React, {Component} from 'react';
|
||||
import {injectPlugins} from 'coral-framework/helpers/plugins';
|
||||
import {getSlotComponents} from 'coral-framework/helpers/plugins';
|
||||
|
||||
class Slot extends Component {
|
||||
render() {
|
||||
const {fill, ...rest} = this.props;
|
||||
return (
|
||||
<div>
|
||||
{injectPlugins(this.props)}
|
||||
{getSlotComponents(fill, rest)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,157 +1,62 @@
|
||||
import {client as clientPlugins} from 'pluginsConfig';
|
||||
import React from 'react';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import values from 'lodash/values';
|
||||
import flatten from 'lodash/flatten';
|
||||
import merge from 'lodash/merge';
|
||||
|
||||
function injectPlugins ({fill, ...props}) {
|
||||
let context,
|
||||
importedFiles;
|
||||
|
||||
function buildContext() {
|
||||
|
||||
/**
|
||||
* buildContext creates the context for the plugins
|
||||
* require.context(<path>, true, <regexp>
|
||||
* path: The path where the importer builds the context. 'plugins' is allowed as path because it's an alias
|
||||
* regxp: A Regular Expression to match the files that the importer needs. i.e (index.js, config.json)
|
||||
* data such as path and regexp cannot be passed as arguments or variables
|
||||
*/
|
||||
context = require.context('plugins', true, /\.\/(.*)\/client\/(index|config).(js|json)$/);
|
||||
return importedFiles = context
|
||||
.keys()
|
||||
.map(key => shapeData(key));
|
||||
}
|
||||
|
||||
function getConfig (name) {
|
||||
|
||||
/**
|
||||
* getConfig finds a the config file for each plugin
|
||||
* returns the config.json as an object to be passed as props to the plugin
|
||||
*/
|
||||
return importedFiles
|
||||
.filter(key => key.format === 'json' && key.name === name)
|
||||
.reduce((acc, plugin) => {
|
||||
return context(plugin.key);
|
||||
}, {});
|
||||
}
|
||||
|
||||
function addProps (plugin) {
|
||||
|
||||
/**
|
||||
* addProps add properties to the injected plugins
|
||||
*/
|
||||
plugin.props = {
|
||||
...getConfig(plugin.name),
|
||||
...props
|
||||
};
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
function filterBySlot (plugin) {
|
||||
|
||||
/**
|
||||
* filterBySlot
|
||||
*/
|
||||
return plugin.props.slot === fill;
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
/**
|
||||
* init will build the context and
|
||||
* returns a map with each plugin and its instance
|
||||
*/
|
||||
buildContext();
|
||||
|
||||
return importedFiles
|
||||
.filter(filterByUserConfig)
|
||||
.filter(key => key.format === 'js')
|
||||
.map(addProps)
|
||||
.filter(filterBySlot)
|
||||
.reduce((entry, plugin, i) => {
|
||||
const component = context(plugin.key);
|
||||
const element = React.createElement(component, {
|
||||
key: i,
|
||||
...plugin.props
|
||||
}, null);
|
||||
|
||||
entry = [...entry, element];
|
||||
return entry;
|
||||
}, []);
|
||||
}
|
||||
|
||||
return init();
|
||||
}
|
||||
|
||||
function shapeData(test) {
|
||||
|
||||
/**
|
||||
* shapeData shapes each item in the plugins array with useful data
|
||||
* returns an Object with the name of the plugin, the format, and it's key(filename)
|
||||
*/
|
||||
const match = test.match(/\.\/(.*)\/client\/.*.(json|js)$/);
|
||||
return {
|
||||
name: match[1],
|
||||
format: match[2],
|
||||
key: match[0]
|
||||
};
|
||||
}
|
||||
|
||||
function filterByUserConfig (plugin) {
|
||||
|
||||
/**
|
||||
* filterByUserConfig will filter the imported files and will only keep the allowed plugins
|
||||
*/
|
||||
return clientPlugins.indexOf(plugin.name) > -1;
|
||||
}
|
||||
|
||||
function importAll(context) {
|
||||
|
||||
/**
|
||||
* importAll builds the map to import
|
||||
*/
|
||||
return context
|
||||
.keys()
|
||||
.map(key => shapeData(key))
|
||||
.filter(filterByUserConfig)
|
||||
.reduce((entry, actionsPlugin) => {
|
||||
const input = context(actionsPlugin.key);
|
||||
return {...entry, ...input};
|
||||
}, {});
|
||||
}
|
||||
|
||||
function importAllAsArr(context) {
|
||||
|
||||
/**
|
||||
* importAllAsArr builds the array to import
|
||||
*/
|
||||
return context
|
||||
.keys()
|
||||
.map(key => shapeData(key))
|
||||
.filter(filterByUserConfig)
|
||||
.reduce((entry, graphPlugin) => {
|
||||
const input = context(graphPlugin.key);
|
||||
const res = Object.keys(input)
|
||||
.map(key => input[key]);
|
||||
return [...entry, ...res];
|
||||
}, []);
|
||||
}
|
||||
|
||||
function actionsImporter () {
|
||||
return importAll(require.context('plugins', true, /\.\/(.*)\/client\/actions.js$/));
|
||||
}
|
||||
|
||||
function reducersImporter () {
|
||||
return importAll(require.context('plugins', true, /\.\/(.*)\/client\/reducer.js$/));
|
||||
}
|
||||
|
||||
function graphImporter () {
|
||||
return importAllAsArr(require.context('plugins', true, /\.\/(.*)\/client\/(queries|mutations)\/index.js$/));
|
||||
}
|
||||
|
||||
export default {
|
||||
injectPlugins,
|
||||
actionsImporter: actionsImporter(),
|
||||
reducersImporter: reducersImporter(),
|
||||
graphImporter: graphImporter()
|
||||
// Gather require context information of different parts of the plugins.
|
||||
const contextMap = {
|
||||
actions: require.context('plugins', true, /\.\/(.*)\/client\/actions.js$/),
|
||||
reducers: require.context('plugins', true, /\.\/(.*)\/client\/reducer.js$/),
|
||||
graph: require.context('plugins', true, /\.\/(.*)\/client\/(mutations|queries)\/index.js$/),
|
||||
configs: require.context('plugins', true, /\.\/(.*)\/client\/config.json$/),
|
||||
components: require.context('plugins', true, /\.\/(.*)\/client\/index.js$/),
|
||||
};
|
||||
|
||||
const getPluginName = (key) => key.match(/\.\/(.*)\/client\/.*$/)[1];
|
||||
const isActivePlugin = (plugin) => clientPlugins.indexOf(plugin) > -1;
|
||||
|
||||
/**
|
||||
* Loads all enabled modules of the context and returns an
|
||||
* Array with {plugin, module} entries.
|
||||
*/
|
||||
function loadActiveModules(context) {
|
||||
return context
|
||||
.keys()
|
||||
.map(key => ({key, plugin: getPluginName(key)}))
|
||||
.filter(info => isActivePlugin(info.plugin))
|
||||
.map(info => ({plugin: info.plugin, module: context(info.key)}));
|
||||
}
|
||||
|
||||
const loaded = mapValues(contextMap, loadActiveModules);
|
||||
|
||||
/**
|
||||
* getConfig returns the config object of given plugin.
|
||||
*/
|
||||
function getConfig(plugin) {
|
||||
return loaded.configs.filter(o => o.plugin === plugin)[0].module;
|
||||
}
|
||||
|
||||
/**
|
||||
* getSlotComponents returns React Elements for given slot.
|
||||
*/
|
||||
export function getSlotComponents(slot, props = {}) {
|
||||
return loaded.components
|
||||
.map((o, i) => ({
|
||||
component: o.module,
|
||||
props: {...getConfig(o.plugin), ...props, key: i},
|
||||
}))
|
||||
.filter(o => o.props.slot === slot)
|
||||
.map(o => React.createElement(o.component, o.props));
|
||||
}
|
||||
|
||||
// actions is a map of redux actions .
|
||||
export const actions = merge(...loaded.actions.map(o => ({...o.module})));
|
||||
|
||||
// reducers is a map of redux reducers.
|
||||
export const reducers = merge(...loaded.reducers.map(o => ({...o.module})));
|
||||
|
||||
// queriesAndMutators is an array of graphQL queries and mutators.
|
||||
export const queriesAndMutators = flatten(loaded.graph.map(o => values(o.module)));
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import auth from './auth';
|
||||
import user from './user';
|
||||
import asset from './asset';
|
||||
import {reducersImporter} from '../helpers/plugins';
|
||||
import {reducers as pluginReducers} from '../helpers/plugins';
|
||||
|
||||
export default {
|
||||
auth,
|
||||
user,
|
||||
asset,
|
||||
...reducersImporter
|
||||
...pluginReducers
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user