-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUtils.js
176 lines (154 loc) · 6.12 KB
/
Utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import {execPythonMessage, evalPythonMessage} from '../../js/communication/geppettoJupyter/GeppettoJupyterUtils';
import React from 'react';
const Utils = {
getAvailableKey: function (model, prefix) {
if (model == undefined) {
return prefix;
}
// Get New Available ID
var id = prefix;
var i = 2;
while (model[id] != undefined) {
id = prefix + i++;
}
return id;
},
getMetadataField: function (key, field) {
if (key == undefined) {
return;
}
var currentObject;
var nextObject = window.metadata;
key.split('.').forEach((item) => {
if (item in nextObject) {
currentObject = nextObject[item];
if ("children" in currentObject) {
nextObject = currentObject["children"];
}
}
else {
currentObject = undefined;
return;
}
});
return (currentObject == undefined) ? currentObject : currentObject[field];
},
getHTMLType: function (key) {
var type = this.getMetadataField(key, "type")
switch (type) {
case "int":
var htmlType = "number"
break;
default:
var htmlType = "text"
break;
}
return htmlType;
},
isObject: function (item) {
return (item && typeof item === 'object' && !Array.isArray(item));
},
mergeDeep: function (target, source) {
let output = Object.assign({}, target);
if (this.isObject(target) && this.isObject(source)) {
Object.keys(source).forEach(key => {
if (this.isObject(source[key])) {
if (!(key in target))
Object.assign(output, { [key]: source[key] });
else
output[key] = this.mergeDeep(target[key], source[key]);
} else {
Object.assign(output, { [key]: source[key] });
}
});
}
return output;
},
getFieldsFromMetadataTree: function (tree, callback) {
function iterate(object, path) {
if (Array.isArray(object)) {
object.forEach(function (a, i) {
iterate(a, path.concat(i));
});
return;
}
if (object !== null && typeof object === 'object') {
Object.keys(object).forEach(function (k) {
// Don't add the leaf to path
iterate(object[k], (typeof object[k] === 'object') ? path.concat(k) : path);
});
return;
}
// Push to array of field id. Remove children and create id string
modelFieldsIds.push(path.filter(path => path != 'children').join('.'));
}
// Iterate the array extracting the fields Ids
var modelFieldsIds = [];
iterate(tree, []);
// Generate model fields based on ids
var modelFields = [];
modelFieldsIds.filter((v, i, a) => a.indexOf(v) === i).map((id) => modelFields.push(callback(id, 0)))
return modelFields;
},
renameKey(path, oldValue, newValue, callback) {
this.execPythonMessage('netpyne_geppetto.rename("' + path + '","' + oldValue + '","' + newValue + '")')
.then((response) => {
callback(response, newValue);
})
},
nameValidation(name) {
// Remove spaces
if((/\s/.test(name))) {
name = name.replace(/\s+/g, "").replace(/^\d+/g, "");
}
// Remove number at the beginning
else if((/^[0-9]/.test(name))) {
name = name.replace(/\s+/g, "").replace(/^\d+/g, "");
}
return name;
},
//FIXME: Hack to remove scaped chars (\\ -> \ and \' -> ') manually
convertToJSON(data){
if (typeof data === 'string' || data instanceof String){
return JSON.parse(data.replace(/\\\\/g, '\\').replace(/\\'/g, '\''))
}
return data
},
getErrorResponse(data){
var parsedData = this.convertToJSON(data)
if (parsedData.hasOwnProperty("type") && parsedData['type'] == 'ERROR'){
return {'message': parsedData['message'], 'details' : parsedData['details']}
}
return null;
},
parsePythonException(exception){
return <pre dangerouslySetInnerHTML={{__html: IPython.utils.fixConsole(exception)}}></pre>
},
handleUpdate(updateCondition, newValue, originalValue, context, componentName) {
if((updateCondition) && (newValue != originalValue)) {
// if the new value has been changed by the function Utils.nameValidation means that the name convention
// has not been respected, so we need to open the dialog and inform the user.
context.setState({ currentName: newValue,
errorMessage: "Error",
errorDetails: "Leading digits or whitespaces are not allowed in "+componentName+" names."});
return true;
} else if ((updateCondition) && (newValue == originalValue)){
context.setState({ currentName: newValue });
return true;
} else if (!(updateCondition) && (newValue == originalValue)) {
context.setState({ currentName: newValue,
errorMessage: "Error",
errorDetails: "Name collision detected, the name "+newValue+
" is already used in this model, please pick another name."});
return false;
} else if (!(updateCondition) && (newValue != originalValue)) {
context.setState({ currentName: newValue,
errorMessage: "Error",
errorDetails: "Leading digits or whitespaces are not allowed in "+componentName+" names."});
return false;
}
},
execPythonMessage: execPythonMessage,
evalPythonMessage: evalPythonMessage
}
export default Utils