mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-02-02 13:12:13 +08:00
Merge pull request #937 from ZmagoD/feat/external-components-loader
Enable loading of external React components
This commit is contained in:
commit
7b28bfa6d4
10 changed files with 1815 additions and 905 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -60,3 +60,5 @@ coverage
|
|||
# Added during webpacker install
|
||||
/public/packs
|
||||
/node_modules
|
||||
.DS_Store
|
||||
app/javascript/src/componentLoader/components/*
|
||||
|
|
2
app/javascript/src/componentLoader/availableAddons.js
Normal file
2
app/javascript/src/componentLoader/availableAddons.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
// intentionally exports empty object
|
||||
export default {};
|
0
app/javascript/src/componentLoader/components/.gitkeep
Normal file
0
app/javascript/src/componentLoader/components/.gitkeep
Normal file
1
app/javascript/src/componentLoader/config.js
Normal file
1
app/javascript/src/componentLoader/config.js
Normal file
|
@ -0,0 +1 @@
|
|||
export { default } from './availableAddons';
|
5
app/javascript/src/componentLoader/index.js
Normal file
5
app/javascript/src/componentLoader/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { createLoader } from 'react-hijack';
|
||||
|
||||
const componentLoader = createLoader((module) => import('./components/' + module));
|
||||
|
||||
export default componentLoader;
|
26
app/javascript/src/componentLoader/massageConfiguration.js
Normal file
26
app/javascript/src/componentLoader/massageConfiguration.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
const massageConfiguration = (config, identifier) => {
|
||||
let result = {};
|
||||
|
||||
const addons = Object.keys(config);
|
||||
if (addons) {
|
||||
|
||||
result = {
|
||||
[identifier]: {}
|
||||
};
|
||||
|
||||
addons.forEach(
|
||||
addon => Object.keys(config[addon])
|
||||
.forEach(
|
||||
component => {
|
||||
if (config[addon][component].areas.indexOf(identifier) !== -1) {
|
||||
result[identifier][component] = config[addon][component];
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export default massageConfiguration;
|
|
@ -16,6 +16,10 @@ import SearchDropdown from "./components/SearchDropdown";
|
|||
import NotificationsDropdown from "./components/NotificationsDropdown";
|
||||
import InfoDropdown from "./components/InfoDropdown";
|
||||
import UserAccountDropdown from "./components/UserAccountDropdown";
|
||||
import withExtras from 'react-hijack';
|
||||
import addonsConfig from '../../componentLoader/config';
|
||||
import massageConfiguration from '../../componentLoader/massageConfiguration';
|
||||
import componentLoader from '../../componentLoader';
|
||||
|
||||
const StyledNavbar = styled(Navbar)`
|
||||
background-color: ${WHITE_COLOR};
|
||||
|
@ -75,7 +79,7 @@ class Navigation extends Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div id="mountPoint">
|
||||
<StyledNavbar onSelect={this.selectItemCallback}>
|
||||
<Navbar.Header>
|
||||
<Navbar.Brand>
|
||||
|
@ -147,5 +151,9 @@ Navigation.propTypes = {
|
|||
|
||||
// Map the states from store to component props
|
||||
const mapStateToProps = ({ current_team }) => ({ current_team });
|
||||
const NavigationWithExtras = withExtras({
|
||||
identifier: 'navigation',
|
||||
config: massageConfiguration(addonsConfig, 'navigation'),
|
||||
}, componentLoader)(Navigation);
|
||||
|
||||
export default connect(mapStateToProps)(Navigation);
|
||||
export default connect(mapStateToProps)(NavigationWithExtras);
|
||||
|
|
31
config/initializers/addon_loader.rb
Normal file
31
config/initializers/addon_loader.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
TARGET_ROOT = "#{Dir.pwd}/app/javascript/src/componentLoader".freeze
|
||||
COMPONENTS_ROOT = "#{TARGET_ROOT}/components".freeze
|
||||
UBER_CONFIG_PATH = "#{TARGET_ROOT}/availableAddons.js".freeze
|
||||
|
||||
begin
|
||||
# clear previous build
|
||||
FileUtils.rm_f Dir.glob("#{COMPONENTS_ROOT}/*")
|
||||
FileUtils.rm_f Dir.glob(UBER_CONFIG_PATH)
|
||||
File.new(UBER_CONFIG_PATH, 'w+')
|
||||
enabled_addons = []
|
||||
|
||||
Dir.foreach('addons/') do |path|
|
||||
addons_client_root = "addons/#{path}/client"
|
||||
next unless Dir.exist? addons_client_root
|
||||
File.open(UBER_CONFIG_PATH, 'w') do |file|
|
||||
file.puts("import #{path} from \'./components/#{path}/config.js\';")
|
||||
end
|
||||
enabled_addons << "#{path}"
|
||||
File.symlink("#{Dir.pwd}/#{addons_client_root}", "#{COMPONENTS_ROOT}/#{path}")
|
||||
end
|
||||
|
||||
File.open(UBER_CONFIG_PATH, 'a') do |file|
|
||||
file.puts("export default { #{enabled_addons.join(", ").gsub(/\"/, '')} };")
|
||||
end
|
||||
|
||||
# handles error on the platforms that does not support symlink
|
||||
# http://ruby-doc.org/core-2.2.0/File.html#symlink-method
|
||||
rescue
|
||||
puts '[sciNote] Unable to load React components from addons!'
|
||||
puts '[sciNote] Your system does not support symlink!'
|
||||
end
|
|
@ -79,6 +79,7 @@
|
|||
"react-data-grid": "^2.0.2",
|
||||
"react-document-title": "^2.0.3",
|
||||
"react-dom": "15.6.1",
|
||||
"react-hijack": "biosistemika/react-hijack#2.0.1",
|
||||
"react-intl": "^2.3.0",
|
||||
"react-intl-redux": "^0.6.0",
|
||||
"react-moment": "^0.6.4",
|
||||
|
|
Loading…
Reference in a new issue