diff --git a/default-profile.json b/default-profile.json
index efe814f..0263a45 100644
--- a/default-profile.json
+++ b/default-profile.json
@@ -1,5 +1,8 @@
{
"items": [
+ {
+ "import": "./partial-profile.json"
+ },
{
"label": "Level 1",
"icon": "chromium-browser",
@@ -12,15 +15,13 @@
{
"label": "Chromium Browser 1",
"icon": "chromium-browser",
- "exec": "/usr/bin/chromium-browser",
- "_key": "item_1444480285022_3"
+ "exec": "/usr/bin/chromium-browser"
},
{
"label": "Pitaya Edit",
"exec": "PITAYA_MODE=edit PITAYA_AS_DESKTOP=0 npm start"
}
- ],
- "_key": "item_1444480285022_2"
+ ]
},
{
"label": "Level 2-3",
@@ -33,32 +34,24 @@
{
"label": "Chromium Browser 2",
"icon": "chromium-browser",
- "exec": "/usr/bin/chromium-browser",
- "_key": "item_1444480285022_6"
+ "exec": "/usr/bin/chromium-browser"
},
{
"label": "Atom",
"icon": "atom",
"exec": "/usr/share/atom/atom %U",
- "_key": "item_1444480288996_7",
"items": []
},
{
"label": "Firefox Developer Edition Web Browser",
"icon": "firefox",
- "exec": "firefox %u",
- "_key": "item_1444761351301_2",
- "selected": true
+ "exec": "firefox %u"
}
- ],
- "_key": "item_1444480285022_5"
+ ]
}
- ],
- "_key": "item_1444480285022_4"
+ ]
}
- ],
- "_key": "item_1444480285022_1"
+ ]
}
- ],
- "_key": "item_1444480285021_0"
+ ]
}
diff --git a/partial-profile.json b/partial-profile.json
new file mode 100644
index 0000000..ee92b8b
--- /dev/null
+++ b/partial-profile.json
@@ -0,0 +1,5 @@
+{
+ "label": "Partial Level 1",
+ "icon": "chromium-browser",
+ "background": "./img/background2.jpg"
+}
diff --git a/src/components/edit/item-form.js b/src/components/edit/item-form.js
index 6888680..6ef5d4e 100644
--- a/src/components/edit/item-form.js
+++ b/src/components/edit/item-form.js
@@ -7,7 +7,9 @@ var ItemForm = React.createClass({
return {
label: '',
icon: '',
- exec: ''
+ exec: '',
+ import: '',
+ background: ''
};
},
@@ -19,7 +21,8 @@ var ItemForm = React.createClass({
label: props.item.label,
icon: props.item.icon,
exec: props.item.exec,
- background: props.item.background
+ background: props.item.background,
+ import: props.item.import
});
}
@@ -54,6 +57,11 @@ var ItemForm = React.createClass({
placeholder="Fond d'écran" value={state.background}
onChange={this.handleChange.bind(this, 'background')} />
+
+
+
);
diff --git a/src/components/edit/profile-menu.js b/src/components/edit/profile-menu.js
index 00e3de7..1073e7e 100644
--- a/src/components/edit/profile-menu.js
+++ b/src/components/edit/profile-menu.js
@@ -21,7 +21,7 @@ var ProfileMenu = React.createClass({
var dispatch = this.props.dispatch;
this.showOpenProfileDialog()
.then(function(profilePath) {
- if(profilePath) dispatch(actions.common.loadProfile(profilePath));
+ if(profilePath) dispatch(actions.common.loadProfile(profilePath, false));
})
;
},
diff --git a/src/store/actions/common.js b/src/store/actions/common.js
index 2f02acb..f7db2ad 100644
--- a/src/store/actions/common.js
+++ b/src/store/actions/common.js
@@ -4,7 +4,7 @@ var LOAD_PROFILE = exports.LOAD_PROFILE = 'LOAD_PROFILE';
var LOAD_PROFILE_SUCCESS = exports.LOAD_PROFILE_SUCCESS = 'LOAD_PROFILE_SUCCESS';
var LOAD_PROFILE_FAILED = exports.LOAD_PROFILE_FAILED = 'LOAD_PROFILE_FAILED';
-exports.loadProfile = function(profilePath) {
+exports.loadProfile = function(profilePath, withImports) {
return function(dispatch, getState) {
@@ -12,7 +12,7 @@ exports.loadProfile = function(profilePath) {
Util.Logger.info('Loading profile "%s"', profilePath);
- return Util.System.loadJSON(profilePath)
+ return Util.Profile.load(profilePath, withImports)
.then(function(profile) {
Util.Logger.info('Profile loaded.');
dispatch({ type: LOAD_PROFILE_SUCCESS, profile: profile });
diff --git a/src/util/index.js b/src/util/index.js
index 97f1641..3b4d58e 100644
--- a/src/util/index.js
+++ b/src/util/index.js
@@ -6,3 +6,4 @@ exports.Tree = require('./tree');
exports.Const = require('./const');
exports.Promises = require('./promises');
exports.App = require('./app');
+exports.Profile = require('./profile');
diff --git a/src/util/profile.js b/src/util/profile.js
new file mode 100644
index 0000000..e7d16fd
--- /dev/null
+++ b/src/util/profile.js
@@ -0,0 +1,52 @@
+var RecursiveIterator = require('recursive-iterator');
+var System = require('./system');
+var Logger = require('./logger');
+var _ = require('lodash');
+var path = require('path');
+
+// Load a profile file with imports
+exports.load = function(profileUrl, withImports) {
+
+ withImports = withImports || true;
+
+ // Load root profile
+ return System.loadJSON(profileUrl)
+ .then(function(profile) {
+
+ if(!withImports) {
+ return profile;
+ }
+
+ var promises = [];
+
+ // Search for imports
+ var iterator = new RecursiveIterator(profile);
+
+ for(var node, item = iterator.next(); !item.done; item = iterator.next()) {
+ node = item.value.node;
+ // For each import found, load the partial and "mount" it on the current item
+ if(node.import) {
+ Logger.info('Loading import "%s"', path.resolve(node.import));
+ p = exports.load(node.import)
+ .then(_mountImport.bind(node))
+ ;
+ promises.push(p);
+ }
+ }
+
+ // When all imports are loaded, return the complete profile
+ return Promise.all(promises)
+ .then(function() {
+ return profile;
+ })
+ ;
+
+ })
+ ;
+
+ // Internal method, extend "this" (the mount point) with the partial profile
+ function _mountImport(importProfile) {
+ _.extend(this, importProfile);
+ }
+
+};
diff --git a/test/profile.js b/test/profile.js
new file mode 100644
index 0000000..c175c81
--- /dev/null
+++ b/test/profile.js
@@ -0,0 +1,19 @@
+var Profile = require('../src/util/profile');
+
+var ProfileSuite = module.exports = {};
+
+ProfileSuite.loadProfileWithImport = function(test) {
+
+ Profile.load(__dirname+'/../default-profile.json')
+ .then(function(profile) {
+ console.log('%j', profile);
+ test.ok(profile.items[0].label === "Partial Level 1", "It should have loaded the partial import !");
+ test.done();
+ })
+ .catch(function(err) {
+ test.ifError(err);
+ test.done();
+ })
+ ;
+
+};