2 var DefaultShadow =
"";
7 var CurrentNamedConfig =
"";
11 var EditedValues = {};
12 var ExportTarFileName =
"export";
14 var ConfigVersionData = {};
21 function GenerateUuid() {
23 if (window.performance && typeof window.performance.now ===
"function") {
24 d += performance.now();
26 var uuid =
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,
function (c) {
27 var r = (d + Math.random() * 16) % 16 | 0;
28 d = Math.floor(d / 16);
29 return (c ===
"x" ? r : (r & 0x3 | 0x8)).toString(16);
34 function UpdateHeader(error, change, text) {
36 $(
"#header").css(
"background-color",
"#D59595").css(
"text-shadow",
"#D99 0 1px 0");
37 $(
"#info").text(text);
38 text =
"ERROR: " + text;
40 $(
"#header").css(
"background-color",
"#E7F29B").css(
"text-shadow",
"#EF9 0 1px 0");
41 $(
"#info").text(text);
42 text =
"CHANGE: " + text;
44 $(
"#header").css(
"background-color", DefaultColor).css(
"text-shadow", DefaultShadow);
45 $(
"#info").text(text);
47 if (text.length > 0) {
52 function ResizeTextAreas() {
53 $(
"textarea").each(
function (i, el) {
54 $(el).height(el.scrollHeight);
58 function GetRadix(value) {
64 if (value.search(
"0x") === 0) {
65 output.value = value.slice(2);
67 if ((
"" + output.value).search(/[^0-9a-fA-F]/) >= 0) { output.radix = -1; }
68 }
else if (value.search(
"0") === 0) {
69 output.value = value.slice(1);
71 if (isNaN(output.value)) { output.radix = -1; }
72 }
else if (value.search(
"b") === value.length - 1) {
73 output.value = value.slice(0, -1);
75 if (isNaN(output.value)) { output.radix = -1; }
76 }
else if (isNaN(value)) {
83 if (output.value ===
" " || (
"" + output.value).length === 0 || (
"" + output.value).indexOf(
".") >= 0) {
90 function CreateRowEditor(row, cellvalue, editor, cellText, width, height) {
91 editor.after(
"<div></div><div></div>");
92 var radixObj = GetRadix(cellText);
93 if (radixObj.radix > 0) {
94 editor.parent().jqxFormattedInput({ radix: radixObj.radix, value: radixObj.value, width: width, height: height, upperCase:
true, dropDown:
true, spinButtons:
true });
98 function InitRowEditor(row, cellvalue, editor) {
99 editor.parent().val(cellvalue);
102 function GetRowEditorValue(row, cellvalue, editor) {
103 if (editor.parent()) {
104 if (editor.val().length === 0) {
105 editor.parent().parent().empty();
108 var radix = editor.parent().jqxFormattedInput(
"radix");
109 if (radix === 2 || radix ===
"binary") {
110 return editor.val() +
"b";
112 if (radix === 16 || radix ===
"hexadecimal") {
113 return "0x" + editor.val().toUpperCase();
115 if (radix === 8 || radix ===
"octal") {
116 if (editor.val()[0] ===
"0") {
119 return "0" + editor.val();
125 function RowEditDialogSave(dataFields, newRowId, grid) {
128 for (var i in dataFields) {
129 if (dataFields.hasOwnProperty(i)) {
130 var name = dataFields[i].name +
"_Editor";
131 var value =
"" + $(
"#" + name).val();
132 if (value ===
"undefined") {
135 row[dataFields[i].name] = value;
140 var currentName = path;
141 var parent = row.parent;
143 if ((parent === null || parent === undefined) && currentName.indexOf(
"___") >= 0) {
144 var parentSelector = grid.selector.split(
" ").slice(0, -1).join(
" ");
145 var parentRow = $(parentSelector +
" #treeGrid").jqxTreeGrid(
"getRow", currentName.slice(0, -4));
146 parent = parentRow[0];
148 if (parent !== null && parent !== undefined) {
149 currentName = parent.name;
150 path = parent.name +
"/" + path;
151 parent = parent.parent;
153 }
while (parent !== null && parent !== undefined);
155 path = CurrentCollection +
"/" + CurrentEntity +
"/" + path;
159 AjaxPost(
"/db/AddOrUpdate", {
160 configName: CurrentNamedConfig,
165 },
function (retval) {
166 if (retval.Success) {
168 $(
"#changes", $(
".file-tab.active a").attr(
"href")).val(now.toISOString() +
": Edit - Path: " + path +
", Name: " + row.name +
" Dialog Edit - multiple columns may have been changed!");
169 $(
"#masterChanges").val(now.toISOString() +
": Edit - Path: " + path +
", Name: " + row.name +
" Dialog Edit - multiple columns may have been changed!");
171 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
173 UpdateHeader(
true,
false,
"Sending Update to server failed");
177 grid.jqxTreeGrid(
"updateRow", newRowId, row);
178 EditedValues[CurrentCollection +
"/" + CurrentEntity +
"/" + row.uid] =
true;
179 $(
"li.active :visible").parent().addClass(
"editedValue");
183 function MakeTreeGrid(tag, dataFields, data, columnGroups) {
184 tag.html(TreeGridHtml);
185 var grid = tag.find(
"#treeGrid");
186 var contextMenu = tag.find(
"#Menu");
187 var dialog = tag.find(
"#dialog");
189 var displayColumns = TranslateColumns(dataFields);
192 console.log(
"DisplayColumns is " + JSON.stringify(displayColumns));
193 console.log(
"DataFields is " + JSON.stringify(dataFields));
197 dataFields: dataFields,
203 addRow:
function (rowId) {
208 var dataAdapter =
new $.jqx.dataAdapter(source, {
209 beforeLoadComplete:
function (records) {
210 var numberFields = [];
211 for (var c in source.dataFields) {
212 if (source.dataFields.hasOwnProperty(c)) {
213 if (source.dataFields[c].dataType ===
"number") {
214 numberFields.push({ name: source.dataFields[c].name, radix: source.dataFields[c].radix });
218 for (var i in records) {
219 if (records.hasOwnProperty(i)) {
220 for (var f in numberFields) {
221 if (numberFields.hasOwnProperty(f)) {
222 var radix = numberFields[f].radix;
226 var value = records[i][numberFields[f].name];
228 if (typeof value ===
"number" || !(value.search(
"0x") === 0 || value.search(
"0") === 0 || value.search(
"b") === value.length - 1)) {
230 value = parseInt(value).toString(radix).toUpperCase();
231 records[i][numberFields[f].name] = value;
233 records[i][numberFields[f].name] +=
"b";
236 records[i][numberFields[f].name] =
"0x" + value;
239 records[i][numberFields[f].name] =
"0" + value;
251 var sequenceTables = [];
253 grid.addClass(
"jqxTreeGrid").jqxTreeGrid(
258 editSettings: { saveOnPageChange:
true, saveOnBlur:
true, saveOnSelectionChange:
true, cancelOnEsc:
true, saveOnEnter:
true, editSingleCell:
true, editOnDoubleClick:
true, editOnF2:
true },
261 columns: displayColumns,
262 columnGroups: columnGroups,
264 rowDetailsRenderer:
function (rowKey, row) {
265 if (row.isSequence) {
266 var indent = (1 + row.level) * 20;
267 var details =
"<div id=\"" + rowKey +
"___Table\" style=\"margin-left: " + indent +
"px;padding-right: 5px\"></div>";
268 sequenceTables.push({ key: rowKey, data: row.table });
274 rendered:
function () {
275 $(
".jqx-tooltip").
remove();
276 var setupRow =
function (rowObject) {
277 if (rowObject[source.comment] && rowObject[source.comment].length > 0 && rowObject[source.comment] !==
" ") {
278 var selector = $(
"tr[data-key=\'" + rowObject.uid +
"\']");
279 if (selector.length) {
280 selector.jqxTooltip({ content: rowObject[source.comment], position:
"mouse" });
283 for (var trow in rowObject.records) {
284 if (rowObject.records.hasOwnProperty(trow)) {
285 setupRow(rowObject.records[trow]);
289 var rows = grid.jqxTreeGrid(
"getRows");
290 for (var ttrow = 0; ttrow < rows.length; ttrow++) {
291 setupRow(rows[ttrow]);
293 for (var seq in sequenceTables) {
294 if (sequenceTables.hasOwnProperty(seq)) {
295 var elem = tag.find(
"#" + sequenceTables[seq].key +
"___Table");
296 var data = sequenceTables[seq].data;
297 MakeTreeGrid(elem, data.columns, data.rows, data.columnGroups);
302 dialog.on(
"close",
function () {
304 grid.jqxTreeGrid({ disabled:
false });
309 position: { left: grid.offset().left + 75, top: grid.offset().top + 35 },
312 dialog.css(
"visibility",
"visible");
317 grid.jqxTreeGrid(
"expandAll");
319 contextMenu.jqxMenu({ width: 200, height: 120, autoOpenPopup:
false, mode:
"popup" });
320 grid.on(
"contextmenu",
function () {
323 grid.on(
"rowClick",
function (event) {
324 var args =
event.args;
325 if (args.originalEvent.button === 2) {
326 var scrollTop = $(window).scrollTop();
327 var scrollLeft = $(window).scrollLeft();
328 contextMenu.jqxMenu(
"open", parseInt(event.args.originalEvent.clientX) + 5 + scrollLeft, parseInt(event.args.originalEvent.clientY) + 5 + scrollTop);
333 var edit =
function (row, key, newRow, x, y) {
336 dialog.jqxWindow(
"setTitle",
"Edit Row: " + row.name);
337 dialog.jqxWindow(
"setContent", DialogContentHtml);
338 dialog.jqxWindow(
"move", x, y);
340 for (var i in dataFields) {
341 if (dataFields.hasOwnProperty(i)) {
342 var name = dataFields[i].name;
343 var value =
"" + row[name];
344 if (value ===
"undefined") {
347 if (dataFields[i].editable || newRow) {
348 var start =
"<tr><td align=\"right\">" + name +
":</td><td align=\"left\">";
349 var editor =
"<input id=\"" + name +
"_Editor\" type=\"text\" value=\"" + value +
"\" />";
351 var radixObj = GetRadix(value);
353 if (radixObj.radix > 0) {
354 editor =
"<div id=\"" + name +
"_Editor\"><input type=\"text\" /><div></div><div></div></div>";
356 name: name +
"_Editor",
357 value: radixObj.value,
358 radix: radixObj.radix
361 var end =
"</td></tr>";
362 dialog.find(
"tr:last").before(start + editor + end);
364 dialog.find(
"tr:last").before(
"<tr><td align=\"right\">" + name +
":</td><td align=\"left\"><input id=\"" + name +
"_Editor\" type=\"text\" value=\"" + value +
"\" readonly=\"true\" disabled=\"disabled\" /></td></tr>");
368 var content = dialog.find(
"table").parent().html();
369 dialog.jqxWindow(
"setContent", content);
370 for (var ed in jqEditors) {
371 if (jqEditors.hasOwnProperty(ed)) {
372 dialog.find(
"#" + jqEditors[ed].name).jqxFormattedInput({ radix: jqEditors[ed].radix, value: jqEditors[ed].value, width:
"100%", height: 25, upperCase:
true, dropDown:
true, spinButtons:
true });
375 dialog.find(
"#save").jqxButton({ height: 30, width: 80 });
376 dialog.find(
"#cancel").jqxButton({ height: 30, width: 80 });
377 dialog.find(
"#save").mousedown(
function () {
378 dialog.jqxWindow(
"close");
379 RowEditDialogSave(dataFields, newRowId, grid);
381 dialog.find(
"#cancel").mousedown(
function () {
382 dialog.jqxWindow(
"close");
384 dialog.jqxWindow(
"open");
385 var newHeight = $(
"#bottomOfDialog").position().top + 100;
386 dialog.jqxWindow({ height: newHeight });
387 dialog.attr(
"data-row", key);
390 grid.jqxTreeGrid({ disabled:
true });
392 var bitedit =
function (row, key, x, y) {
395 dialog.jqxWindow(
"setTitle",
"Bit Editor for Row: " + row.name);
396 dialog.jqxWindow(
"setContent", DialogContentHtml);
397 dialog.jqxWindow(
"move", x, y);
399 for (var i in dataFields) {
400 if (dataFields.hasOwnProperty(i)) {
401 var name = dataFields[i].name;
402 var value =
"" + row[name];
403 if (value ===
"undefined") {
406 dialog.find(
"tr:last").before(
"<input id=\"" + name +
"_Editor\" type=\"hidden\" value=\"" + value +
"\" />");
407 if (dataFields[i].editable) {
408 var radixObj = GetRadix(value);
409 if (radixObj.radix === 2 || radixObj.radix === 8 || radixObj.radix === 16)
415 var selectHtml =
"<select id=bitFieldSelect>";
416 for (var f in fields) {
417 if (fields.hasOwnProperty(f)) {
418 selectHtml +=
"<option id=" + fields[f] +
" value=\"" + fields[f] +
"\">" + fields[f] +
"</option>";
421 selectHtml +=
"</select>";
422 dialog.find(
"tr:last").before(
"<tr><td colspan=\"2\" align=\"right\">" + selectHtml +
"</td></tr>");
423 dialog.find(
"tr:last").before(
'<tr><td colspan="2" align="right"><div id=bitCheckboxes></div></td></tr>');
425 var content = dialog.find(
"table").parent().html();
426 dialog.jqxWindow(
"setContent", content);
427 dialog.find(
"#bitFieldSelect").change(
function () {
428 var currentValue = dialog.find(
"#" + this.value +
"_Editor").val();
429 var radixObj = GetRadix(currentValue);
430 var length = String(radixObj.value).length;
432 switch (radixObj.radix) {
444 var bitFieldCheckboxHtml =
"<table><tr>";
445 for (var i = 0; i < bits; ++i) {
446 if (i > 0 && i % 4 === 0) {
447 bitFieldCheckboxHtml +=
"</tr><tr>";
449 var checkedStr = (currentValue & (1 << i)) !== 0 ?
"checked" :
"";
450 bitFieldCheckboxHtml +=
"<td><input type=\"checkbox\" name=\"" + i +
"\" class=\"bitFieldCheckBox\"" + checkedStr +
">" + i +
"</input></td>";
452 bitFieldCheckboxHtml +=
"</tr></table>";
453 dialog.find(
"#bitCheckboxes").html(bitFieldCheckboxHtml);
454 var newHeight = $(
"#bottomOfDialog").position().top;
455 dialog.jqxWindow({ height: newHeight });
456 $(
".bitFieldCheckBox").change(
function () {
457 var currentValue = String(dialog.find(
"#" + $(
"#bitFieldSelect").val() +
"_Editor").val());
458 var radixObj = GetRadix(currentValue);
459 var bitId = this.name;
460 var digit, rem, curDigit, mask;
461 switch (radixObj.radix) {
463 currentValue = currentValue.substr(0, currentValue.length - bitId - 1) + (this.checked ?
"1" :
"0") + currentValue.substr(currentValue.length - bitId);
466 digit = Math.floor(bitId / 3);
467 rem = bitId - (digit * 3);
468 curDigit = parseInt(currentValue.charAt(currentValue.length - digit - 1), 8);
470 curDigit = curDigit | (1 << rem);
472 mask = 7 - (1 << rem);
473 curDigit = curDigit & mask;
475 currentValue = currentValue.substr(0, currentValue.length - digit - 1) + curDigit.toString(8) + currentValue.substr(currentValue.length - digit);
478 digit = Math.floor(bitId / 4);
479 rem = bitId - (digit * 4);
480 curDigit = parseInt(currentValue.charAt(currentValue.length - digit - 1), 16);
482 curDigit = curDigit | (1 << rem);
484 mask = 15 - (1 << rem);
485 curDigit = curDigit & mask;
487 currentValue = currentValue.substr(0, currentValue.length - digit - 1) + curDigit.toString(16) + currentValue.substr(currentValue.length - digit);
490 dialog.find(
"#" + $(
"#bitFieldSelect").val() +
"_Editor").val(currentValue);
492 }).trigger(
"change");
493 dialog.find(
"#save").jqxButton({ height: 30, width: 80 });
494 dialog.find(
"#cancel").jqxButton({ height: 30, width: 80 });
495 dialog.find(
"#save").mousedown(
function () {
496 dialog.jqxWindow(
"close");
497 RowEditDialogSave(dataFields, newRowId, grid);
499 dialog.find(
"#cancel").mousedown(
function () {
500 dialog.jqxWindow(
"close");
502 dialog.jqxWindow(
"open");
503 var newHeight = $(
"#bottomOfDialog").position().top;
504 dialog.jqxWindow({ height: newHeight });
505 dialog.attr(
"data-row", key);
508 grid.jqxTreeGrid({ disabled:
true });
510 contextMenu.on(
"itemclick",
function (event) {
511 var args =
event.args;
512 var selection = grid.jqxTreeGrid(
"getSelection");
513 var rowid = selection[0].uid;
514 var text = $.trim($(args).text());
515 if (text ===
"Edit Selected Row") {
516 edit(selection[0], rowid,
false, event.pageX, event.pageY);
517 }
else if (text ===
"Delete Selected Row") {
518 grid.jqxTreeGrid(
"deleteRow", rowid);
519 }
else if (text ===
"Bit Editor") {
520 bitedit(selection[0], rowid, event.pageX, event.pageY);
522 var arrayName =
false;
523 if (rowid.search(/___/) > 0) {
526 grid.jqxTreeGrid(
"addRow", null, {},
"last", rowid);
528 var idx = newRowId.search(/___/);
529 var num = newRowId.slice(idx + 3, -1);
530 num = parseInt(num) + 1;
531 newRowId = newRowId.slice(0, idx + 3) + num;
534 for (var i in dataFields) {
535 if (dataFields.hasOwnProperty(i)) {
536 obj[dataFields[i].name] =
"";
540 edit(obj, newRowId,
true, event.pageX, event.pageY);
545 grid.on(
"cellEndEdit",
function (event) {
546 var args =
event.args;
548 var rowKey = args.key;
550 var rowData = args.row;
551 var path = rowData.name;
552 var currentName = rowKey;
553 var parent = rowData.parent;
556 if ((parent === null || parent === undefined) && currentName.indexOf(
"___") >= 0) {
557 var parentSelector = tag.selector.split(
" ").slice(0, -1).join(
" ");
558 var parentRow = $(parentSelector +
" #treeGrid").jqxTreeGrid(
"getRow", currentName.slice(0, -4));
559 parent = parentRow[0];
560 while ((parent !== null && parent !== undefined) && parent.constructor === Array) {
564 else if ((parent === null || parent === undefined) && rowData.name.indexOf(
"___") >= 0 && first) {
566 var parentSelector = tag.selector.split(
" ").slice(0, -1).join(
" ");
567 var parentName = tag.selector.split(
" ").slice(-1).join(
" ").slice(1);
568 parentName = parentName.slice(0, parentName.indexOf(
"___"));
569 var parentRow = $(parentSelector +
" #treeGrid").jqxTreeGrid(
"getRow", parentName);
570 parent = parentRow[0];
571 while ((parent !== null && parent !== undefined) && parent.constructor === Array) {
576 if (parent !== null && parent !== undefined) {
577 currentName = parent.name;
578 path = parent.name +
"/" + path;
579 parent = parent.parent;
581 }
while (parent !== null && parent !== undefined);
583 if (CurrentCollection && CurrentEntity) {
584 path = CurrentCollection +
"/" + CurrentEntity +
"/" + path;
586 var pathTmp = path.split(
'/');
587 CurrentCollection = pathTmp.shift();
588 CurrentEntity = pathTmp.shift();
590 console.log(
"Path is " + path);
592 var columnDataField = args.dataField;
594 var columnName = args.dataField;
595 for (var i in args.owner._columns) {
596 if (args.owner._columns.hasOwnProperty(i)) {
597 if (args.owner._columns[i].dataField === columnName) {
598 columnName = args.owner._columns[i].text;
603 EditedValues[CurrentCollection +
"/" + CurrentEntity +
"/" + rowKey] =
true;
604 $(
"li.active :visible").parent().addClass(
"editedValue");
606 var value = args.value;
608 AjaxPost(
"/db/Update", {
609 configName: CurrentNamedConfig,
611 column: columnDataField,
616 },
function (retval) {
617 if (retval.Success) {
619 var selector = $(
"#changes", $(
".file-tab.active a").attr(
"href"));
620 selector.val(now.toISOString() +
": Edit - File: " + CurrentCollection +
"/" + CurrentEntity +
", Name: " + rowData.name +
", Column: " + columnName +
", Value: " + value +
"\n" + selector.val());
621 $(
"#masterChanges").val(now.toISOString() +
": Edit - File: " + CurrentCollection +
"/" + CurrentEntity +
", Name: " + rowData.name +
", Column: " + columnName +
", Value: " + value +
"\n" + $(
"#masterChanges").val());
622 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
624 UpdateHeader(
true,
false,
"Sending Update to server failed");
630 function CellClass(row, dataField, cellText, rowData) {
632 for (var val in EditedValues) {
633 if (EditedValues.hasOwnProperty(val)) {
634 if (val === CurrentCollection +
"/" + CurrentEntity +
"/" + rowData.uid) {
635 edited = EditedValues[val];
641 return "editedValue";
646 function TranslateColumns(columns) {
647 var displayColumns = [];
649 for (var c in columns) {
650 if (columns.hasOwnProperty(c)) {
651 var title = columns[c].title;
652 if (title === undefined || title === null || title.length === 0) {
653 title = columns[c].name.charAt(0).toUpperCase() + columns[c].name.slice(1);
655 if (columns[c].type ===
"string" && columns[c].display) {
656 displayColumns.push({
658 dataField: columns[c].name,
659 editable: columns[c].editable,
660 columnGroup: columns[c].columnGroup,
661 createEditor: CreateRowEditor,
662 initEditor: InitRowEditor,
663 getEditorValue: GetRowEditorValue,
664 cellClassName: CellClass
666 }
else if (columns[c].type ===
"number" && columns[c].display) {
667 columns[c].type =
"string";
668 columns[c].dataType =
"number";
669 displayColumns.push({
671 dataField: columns[c].name,
672 editable: columns[c].editable,
673 columnGroup: columns[c].columnGroup,
674 createEditor: CreateRowEditor,
675 initEditor: InitRowEditor,
676 getEditorValue: GetRowEditorValue,
677 cellClassName: CellClass
682 return displayColumns;
685 function LoadTable(tag) {
687 AjaxPost(
"/db/GetData", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId },
function (data) {
689 UpdateHeader(
true,
false,
"Fetch of data from database failed");
692 var columns = data.data.columns;
694 MakeTreeGrid(tag, columns, data.data.children);
699 function SetupConfigVersionPicker(element, target) {
701 element.on(
"change",
function () {
702 var thisConfig = element.find(
":selected").text();
703 var configVersionHtml =
"";
704 for (var version in ConfigVersionData[thisConfig]) {
705 if (ConfigVersionData[thisConfig].hasOwnProperty(version)) {
706 configVersionHtml +=
"<option name=\"" + ConfigVersionData[thisConfig][version].name
707 +
"\" value=" + ConfigVersionData[thisConfig][version].data +
">" + ConfigVersionData[thisConfig][version].version +
"</option>";
710 $(
"#" + target).html(configVersionHtml).trigger(
"create").selectmenu(
"refresh");
711 $(
"#" + target).html($(
"#" + target +
" option").sort(
function (a, b) {
712 return parseInt(a.text) === parseInt(b.text) ? 0 : parseInt(a.text) > parseInt(b.text) ? -1 : 1;
714 var option = $(
"#" + target).find(
'option:eq(0)');
715 option.prop(
'selected',
true);
716 $(
"#"+target).trigger(
"create").selectmenu(
"refresh");
720 function GetConfigList() {
721 UpdateHeader(
false,
false,
"");
722 $(
"#masterChanges").val(
"");
724 for (var i = 2; i <= LastTabId; i++) {
725 $(
"#tab" + i).
remove();
726 $(
"#tablink" + i).
remove();
729 $(
"#reloadConfigsButton").text(
"Reload Configurations");
732 AjaxPost(
"/db/NamedConfigs", { configFilter: $(
"#configurationFilter").val(), user: UserId },
function (data) {
734 UpdateHeader(
true,
false,
"Error retrieving Configuration list. Please contact an expert!");
737 var configsHtml =
"";
738 for (var name in data.data) {
739 if (data.data.hasOwnProperty(name)) {
740 configsHtml +=
"<option>" + name +
"</option>";
741 ConfigVersionData[name] = data.data[name];
744 $(
"#configs").html(configsHtml).trigger(
"create").selectmenu(
"refresh");
745 $(
"#oldConfigName").html(configsHtml).trigger(
"create").selectmenu(
"refresh");
746 $(
"#exportConfigName").html(configsHtml).trigger(
"create").selectmenu(
"refresh");
748 SetupConfigVersionPicker($(
"#configs"),
"configversions");
749 $(
"#configs").trigger(
"change");
750 SetupConfigVersionPicker($(
"#oldConfigName"),
"oldConfigVersion");
751 $(
"#oldConfigName").trigger(
"change");
752 SetupConfigVersionPicker($(
"#exportConfigName"),
"exportConfigVersion");
753 $(
"#exportConfigName").trigger(
"change");
755 var config = GetUrlParameter(
"configs");
756 if (config !== undefined) {
757 $(
"#configs").val(config);
760 $(
"#configLoad").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
761 $(
"#configSave").collapsible(
"option",
"disabled",
true).collapsible(
"option",
"collapsed",
true);
762 $(
"#configMetadata").collapsible(
"option",
"disabled",
true).collapsible(
"option",
"collapsed",
true);
763 $(
"#searchConfig").collapsible(
"option",
"disabled",
false);
764 $(
"#exportFile").collapsible(
"option",
"collapsed",
true);
765 $(
"#newConfig").collapsible(
"option",
"collapsed",
true);
768 function RegisterTabFunctions() {
769 $(
".file-tab a").off();
770 $(
".collection-tab a").off();
771 $(
".tabs .tab-links a").off().on(
"click",
function (e) {
772 var currentAttrValue = $(
this).attr(
"href");
773 var tab = $(
this).parent();
774 var div = tab.parent();
776 var left = Math.floor(tab.position().left - 20);
777 div.scrollLeft(left);
779 $(
".tabs " + currentAttrValue).show().siblings().hide();
782 $(
this).parent(
"li").addClass(
"active").siblings().removeClass(
"active");
786 $(
".collection-tab a").on(
"click",
function () {
787 CurrentCollection = $(
this).text();
789 $(
".file-tab a").on(
"click",
function () {
790 var fileName = $(
this).text();
791 CurrentEntity = fileName;
792 LoadFile($(
this).attr(
"href"));
797 function GetUrlParameter(sParam) {
798 var sUrlVariables = window.location.search.substring(1).split(
"&");
800 for (var i = 0; i < sUrlVariables.length; i++) {
801 var sParameterName = sUrlVariables[i].split(
"=");
803 if (sParameterName[0].search(sParam) >= 0) {
805 return sParameterName[1];
811 function LoadConfigMetadata() {
812 console.log(
"Loading configuration metadata");
814 AjaxPost(
"/db/LoadConfigMetadata", { configName: CurrentNamedConfig, user: UserId },
function (metadata) {
815 if (!metadata.Success) {
816 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
819 var metadataObj = metadata.data;
822 var displayColumns = [
829 text:
"Collection Name",
830 dataField:
"collection",
835 dataField:
"version",
839 text:
"Edit", cellsAlign:
"center", align:
"center", columnType:
"none", editable:
false, sortable:
false, dataField: null, cellsRenderer:
function (row) {
841 return "<button data-row='" + row +
"' class='editButtons' onclick=''>Edit</button>";
846 { name:
"name", type:
"string", editable:
false, display:
true },
847 { name:
"collection", type:
"string", editable:
false, display:
true },
848 { name:
"file", type:
"string", editable:
false, display:
false },
849 { name:
"version", type:
"string", editable:
false, display:
true }
853 dataFields: dataFields,
858 localData: metadataObj.entities
861 var dataAdapter =
new $.jqx.dataAdapter(source);
863 var grid = $(
"#configurationEntities");
864 grid.addClass(
"jqxTreeGrid").jqxTreeGrid(
871 columns: displayColumns,
872 rendering:
function () {
874 if ($(
".editButtons").length > 0) {
875 $(
".editButtons").jqxButton(
"destroy");
878 rendered:
function () {
879 if ($(
".editButtons").length > 0) {
880 $(
".editButtons").jqxButton();
882 var editClick =
function (event) {
884 var rowKey =
event.target.getAttribute(
"data-row");
885 var row = grid.jqxTreeGrid(
"getRow", rowKey);
886 var collection = row[
"collection"];
887 var collectionTab = $(
".collection-tab[collection-name=\"" + collection +
"\"] a");
888 collectionTab.trigger(
"click");
889 var file = row[
"name"];
890 var fileNameTab = $(collectionTab[0].hash).find(
".file-tab[file-name=\"" + file +
"\"] a");
891 fileNameTab.trigger(
"click");
893 $(
".editButtons").on(
"click",
function (event) {
904 function AddEntityToFile(
id) {
905 var newEntityName = $(
id +
" #newEntityName").val();
906 $(
id +
" #newEntityName").val(
"");
907 if (newEntityName !==
"") {
908 AjaxPost(
"/db/AddEntityToFile", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId, name: newEntityName },
function (res) {
913 UpdateHeader(
true,
false,
"Error adding Entity to configuration file");
919 function LoadFile(
id) {
921 AjaxPost(
"/db/LoadFileMetadata", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId },
function (metadata) {
922 if (!metadata.Success) {
923 UpdateHeader(
true,
false,
"Error loading file metadata from database");
926 console.log(
"Loading file metadata");
927 var metadataObj = metadata.data;
928 console.log(metadata);
929 $(
id +
" #metadataCollection").val(metadataObj.collection);
930 $(
id +
" #metadataVersion").val(metadataObj.version);
931 $(
id +
" #changeLog").val(metadataObj.changelog);
933 var displayColumns = [
940 text:
"Date Assigned",
941 dataField:
"assigned",
946 { name:
"name", type:
"string", editable:
false, display:
true },
947 { name:
"assigned", type:
"date", editable:
false, display:
true }
949 var entitiesSource = {
951 dataFields: dataFields,
956 localData: metadataObj.entities
959 var entitiesDataAdapter =
new $.jqx.dataAdapter(entitiesSource);
961 $(
id +
" #metadataEntities").addClass(
"jqxTreeGrid").jqxTreeGrid(
964 source: entitiesDataAdapter,
968 columns: displayColumns
970 var configsSource = {
972 dataFields: dataFields,
977 localData: metadataObj.configurations
980 var configsDataAdapter =
new $.jqx.dataAdapter(configsSource);
982 $(
id +
" #metadataConfigurations").addClass(
"jqxTreeGrid").jqxTreeGrid(
985 source: configsDataAdapter,
989 columns: displayColumns
991 LoadTable($(
id +
" #fileTable"));
995 function SearchCurrentConfig() {
996 console.log(
"Searching Configuration");
998 var searchKey = $(
"#searchKey").val();
999 console.log(
"SearchKey is " + searchKey);
1001 AjaxPost(
"/db/SearchLoadedConfig", { configName: CurrentNamedConfig, user: UserId, searchKey: searchKey },
function (results) {
1002 if (!results.Success) {
1003 UpdateHeader(
true,
false,
"Error searching configuration");
1007 MakeTreeGrid($(
"#searchResults"), results.columns, results.collections);
1011 function LoadConfig() {
1012 console.log(
"Loading Configuration");
1013 $(
"#masterChanges").val(
"");
1014 UpdateHeader(
false,
false,
"");
1015 var selected = $(
"#configversions").find(
":selected");
1016 if (selected.text() ===
"No Configurations Found" || selected.text() ===
"Click \"Load Configurations\" To Load Configuration Names") {
return; }
1017 CurrentNamedConfig = selected.attr(
"name");
1018 $(
"#configName").val(CurrentNamedConfig);
1019 for (var i = 2; i <= LastTabId; i++) {
1020 $(
"#tab" + i).
remove();
1021 $(
"#tablink" + i).
remove();
1025 AjaxPost(
"/db/LoadNamedConfig", { configName: CurrentNamedConfig, query: selected.val(), user: UserId },
function (config) {
1026 if (!config.Success) {
1027 UpdateHeader(
true,
false,
"Error loading configuration files from database");
1031 for (var collection in config.collections) {
1032 if (config.collections.hasOwnProperty(collection)) {
1034 var parentTab = LastTabId;
1035 $(
"#tabLinks").append(
"<li id=\"tablink" + LastTabId +
"\"collection-name=\"" + config.collections[collection].name +
"\" tabNum=\"" + LastTabId +
"\" class=\"collection-tab\"><a href=\"#tab" + LastTabId +
"\">" + config
1036 .collections[collection].name +
"</a></li>");
1037 $(
"#tabContents").append(
"<div id=tab" + LastTabId +
" class=\"tab\"></div>");
1038 $(
"#tab" + LastTabId).html(TableHtml);
1040 for (var file in config.collections[collection].files) {
1041 if (config.collections[collection].files.hasOwnProperty(file)) {
1042 var name = config.collections[collection].files[file];
1045 $(
"#tab" + parentTab +
" #tabLinks").append(
"<li id=\"tablink" + LastTabId +
"\" file-name=\"" + name +
"\" tabNum=\"" + LastTabId +
"\" class=\"file-tab\"><a href=\"#tab" + LastTabId +
"\">" + name +
"</a></li>");
1046 $(
"#tab" + parentTab +
" #tabContents").append(
"<div id=tab" + LastTabId +
" class=\"tab\"></div>");
1047 $(
"#tab" + LastTabId).html(InfoHtml).trigger(
"create");;
1052 $(
"#configLoad").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
true);
1053 $(
"#configSave").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
1054 LoadConfigMetadata();
1055 $(
"#configMetadata").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
1056 $(
"#searchConfig").collapsible(
"option",
"disabled",
false);
1057 RegisterTabFunctions();
1061 function BaseConfig() {
1063 AjaxPost(
"/db/LoadConfigMetadata", { configName: $(
"#oldConfigName :selected").text(), user: UserId },
function (metadata) {
1064 if (!metadata.Success) {
1065 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
1068 var metadataObj = metadata.data;
1071 $(
"#newConfigName").val($(
"#oldConfigName :selected").text());
1072 var tag = $(
"#configurationPicker");
1073 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1074 for (var r in rows) {
1075 if (rows.hasOwnProperty(r)) {
1076 var thisRow = rows[r];
1077 var isChecked =
false;
1078 for (var e in metadataObj.entities) {
1079 if (isChecked)
break;
1080 if (metadataObj.entities.hasOwnProperty(e)) {
1081 var entity = metadataObj.entities[e];
1082 if (thisRow.name === entity.collection) {
1083 for (var r in thisRow.records) {
1084 if (thisRow.records.hasOwnProperty(r)) {
1085 var record = thisRow.records[r];
1086 if (record.id === entity.collection + entity.name) {
1087 tag.find(
"#grid").jqxTreeGrid(
"updateRow", record.uid, { name: entity.name, version: entity.version });
1088 tag.find(
"#grid").jqxTreeGrid(
"checkRow", record.uid);
1097 if (!isChecked && thisRow.checked) {
1098 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", thisRow.uid);
1105 function BaseExportConfig() {
1107 AjaxPost(
"/db/LoadConfigMetadata", { configName: $(
"#exportConfigName :selected").text(), user: UserId },
function (metadata) {
1108 if (!metadata.Success) {
1109 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
1112 ExportTarFileName = $(
"#exportConfigName :selected").text();
1113 var metadataObj = metadata.data;
1116 var tag = $(
"#filePicker");
1117 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1118 for (var r in rows) {
1119 if (rows.hasOwnProperty(r)) {
1120 var thisRow = rows[r];
1121 var isChecked =
false;
1122 for (var e in metadataObj.entities) {
1123 if (isChecked)
break;
1124 if (metadataObj.entities.hasOwnProperty(e)) {
1125 var entity = metadataObj.entities[e];
1126 if (thisRow.name === entity.collection) {
1127 for (var r in thisRow.records) {
1128 if (thisRow.records.hasOwnProperty(r)) {
1129 var record = thisRow.records[r];
1130 if (record.id === entity.collection + entity.name) {
1131 tag.find(
"#grid").jqxTreeGrid(
"updateRow", record.uid, { name: entity.name, version: entity.version });
1132 tag.find(
"#grid").jqxTreeGrid(
"checkRow", record.uid);
1141 if (!isChecked && thisRow.checked) {
1142 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", thisRow.uid);
1150 function SaveNewConfig() {
1151 console.log(
"Saving New Configuration");
1152 var tag = $(
"#configurationPicker");
1153 var rows = tag.find(
"#grid").jqxTreeGrid(
"getCheckedRows");
1158 for (var r in rows) {
1159 if (rows.hasOwnProperty(r) &&
1160 (typeof rows[r].collection !==
"undefined" && rows[r].collection.length > 0) &&
1161 (typeof rows[r].version !==
"undefined" && rows[r].version.length > 0)) {
1162 configObj.entities.push({ name: rows[r].name, version: rows[r].version, collection: rows[r].collection });
1167 AjaxPost(
"/db/MakeNewConfig", { user: UserId, config: JSON.stringify(configObj), name: $(
"#newConfigName").val() },
function (retval) {
1168 if (retval.Success) {
1169 $(
"#newConfig").collapsible(
"option",
"collapsed",
true);
1172 UpdateHeader(
true,
false,
"MakeNewConfig operation failed.");
1177 function ExportFiles() {
1178 console.log(
"Exporting Files");
1179 var tag = $(
"#filePicker");
1180 var rows = tag.find(
"#grid").jqxTreeGrid(
"getCheckedRows");
1185 for (var r in rows) {
1186 if (rows.hasOwnProperty(r) &&
1187 (typeof rows[r].collection !==
"undefined" && rows[r].collection.length > 0) &&
1188 (typeof rows[r].version !==
"undefined" && rows[r].version.length > 0)) {
1189 configObj.entities.push({ name: rows[r].name, version: rows[r].version, collection: rows[r].collection });
1194 var xhr =
new XMLHttpRequest();
1195 xhr.open(
"POST",
"/db/DownloadConfigurationFile",
true);
1196 xhr.responseType =
"arraybuffer";
1197 xhr.onload =
function () {
1198 if (this.status === 200) {
1200 var disposition = xhr.getResponseHeader(
"Content-Disposition");
1201 if (disposition && disposition.indexOf(
"attachment") !== -1) {
1202 var filenameRegex = /filename[^;=\n]*=(([
'"]).*?\2|[^;\n]*)/;
1203 var matches = filenameRegex.exec(disposition);
1204 if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, "");
1206 var type = xhr.getResponseHeader("Content-Type
");
1208 var blob = new Blob([this.response], { type: type });
1209 if (typeof window.navigator.msSaveBlob !== "undefined
") {
1210 // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob
for which they were created. These URLs will no longer resolve as the data backing the URL has been freed.
"
1211 window.navigator.msSaveBlob(blob, filename);
1213 var url = window.URL || window.webkitURL;
1214 var downloadUrl = url.createObjectURL(blob);
1217 // use HTML5 a[download] attribute to specify filename
1218 var a = document.createElement("a
");
1219 // safari doesn't support this yet
1220 if (typeof a.download === "undefined
") {
1221 window.location = downloadUrl;
1223 a.href = downloadUrl;
1224 a.download = filename;
1225 document.body.appendChild(a);
1229 window.location = downloadUrl;
1232 setTimeout(function () { url.revokeObjectURL(downloadUrl); }, 100); // cleanup
1234 } else if (this.status === 500) {
1235 UpdateHeader(true, false, "An error occurred on the server. Contact an expert
if the situation persists
");
1238 xhr.setRequestHeader("Content-type
", "application/x-www-form-urlencoded
");
1239 xhr.send($.param({ user: UserId, config: JSON.stringify(configObj), tarFileName: ExportTarFileName, type: $("#exportFileFormat :selected
").val() }));
1240 ExportTarFileName = "export
";
1243 function AddRowToFileUploader() {
1244 $("#fileUploader
").find("#grid
").jqxTreeGrid("addRow
", null, {});
1247 function SetupFileUploadTable(tag) {
1248 var displayColumns = [
1251 dataField: "fileName
",
1253 cellClassName: CellClass,
1254 columntype: "template",
1255 initEditor: function (row, cellvalue, editor) {
1256 if (cellvalue === "" || cellvalue === "undefined
" || !cellvalue) {
1257 editor.html("<input type=\
"file\" id=\"fileName\"/>");
1259 editor.text(cellvalue);
1262 getEditorValue:
function (row, cellvalue, editor) {
1264 if (cellvalue ===
"" || cellvalue ===
"undefined" || !cellvalue) {
1265 var fileName = editor.find(
"#fileName")[0];
1266 UploadFiles[row] = fileName.files[0];
1267 return fileName.files[0].name;
1274 dataField:
"fileType",
1276 cellClassName: CellClass,
1277 columntype:
"template",
1278 initEditor:
function (row, cellvalue, editor) {
1280 var versionsAdapter =
new $.jqx.dataAdapter({ datatype:
"array", datafields: [{ name:
"name", type:
"string" }, { name:
"value", type:
"string" }], localdata: [{ name:
"FHiCL", value:
"fhicl" }, { name:
"JSON", value:
"json" }] }, { autoBind:
true });
1281 editor.jqxDropDownList({ source: versionsAdapter, displayMember:
"name", valueMember:
"value", selectedIndex: 0 }).jqxDropDownList(
"refresh");
1283 editor.jqxDropDownList(
"selectItem", cellvalue);
1285 getEditorValue:
function (row, cellvalue, editor) {
1287 return editor.val();
1292 dataField:
"collection",
1294 cellClassName: CellClass
1297 text:
"Entity Name",
1298 dataField:
"entity",
1300 cellClassName: CellClass
1304 dataField:
"version",
1306 cellClassName: CellClass
1309 text:
"Remove", cellsAlign:
"center", align:
"center", columnType:
"none", editable:
false, sortable:
false, dataField: null, cellsRenderer:
function (row) {
1311 return "<button data-row='" + row +
"' class='removeButtons' onclick=''>Remove</button>";
1316 tag.html(
"<div id=\"grid\" class=\"jqxTreeGrid\"></div><br>");
1319 { name:
"id", type:
"string", editable:
false, display:
false },
1320 { name:
"fileName", type:
"string", editable:
true, display:
true },
1321 { name:
"fileType", type:
"string", editable:
true, display:
true },
1322 { name:
"collection", type:
"string", editable:
true, display:
true },
1323 { name:
"entity", type:
"string", editable:
true, display:
true },
1324 { name:
"version", type:
"string", editable:
true, display:
true }
1328 dataFields: dataFields,
1336 var dataAdapter =
new $.jqx.dataAdapter(source);
1338 tag.find(
"#grid").jqxTreeGrid({
1340 source: dataAdapter,
1343 columnsResize:
true,
1344 columns: displayColumns,
1345 rendering:
function () {
1347 if ($(
".removeButtons").length > 0) {
1348 $(
".removeButtons").jqxButton(
"destroy");
1351 rendered:
function () {
1352 if ($(
".removeButtons").length > 0) {
1353 $(
".removeButtons").jqxButton();
1355 var removeClick =
function (event) {
1357 var rowKey =
event.target.getAttribute(
"data-row");
1358 delete UploadFiles[rowKey];
1359 tag.find(
"#grid").jqxTreeGrid(
"deleteRow", rowKey);
1361 $(
".removeButtons").on(
"click",
function (event) {
1371 function SetupReader(file) {
1372 var f = UploadFiles[file];
1373 var r =
new FileReader();
1375 r.onload =
function (e) {
1376 var contents = e.target.result;
1377 var thisfile = e.target.fileid;
1378 var row = $(
"#fileUploader").find(
"#grid").jqxTreeGrid(
"getRow", thisfile);
1379 console.log(
"Calling AjaxPost with parameters: Collection: " +
1386 row.fileType +
", fileName: " + row.fileName +
", file.name: " + f.name);
1389 AjaxPost(
"/db/UploadConfigurationFile",
1392 collection: row.collection,
1393 version: row.version,
1400 UpdateHeader(
true,
false,
"File upload failed");
1402 console.log(
"Upload: " + row.fileName +
" returned: " + JSON.stringify(res));
1404 delete UploadFiles[thisfile];
1410 function UploadFhiclFile() {
1411 $(
"#uploadFhiclFileButton").text(
"Uploading... Please Wait.");
1413 var didAnything =
false;
1414 for (var file in UploadFiles) {
1415 if (UploadFiles.hasOwnProperty(file)) {
1417 var f = UploadFiles[file];
1419 var row = $(
"#fileUploader").find(
"#grid").jqxTreeGrid(
"getRow", file);
1421 alert(
"Failed to load file");
1425 if (row.fileType ===
"fhicl" && f.name.search(
".fcl") === -1) {
1426 alert(f.name +
" is not a valid fhicl file.");
1430 if (row.fileType ===
"json" && f.name.search(
".json") === -1) {
1431 alert(f.name +
" is not a valid json file.");
1435 if ((row.fileType !==
"fhicl" &&
1436 row.fileType !==
"json") ||
1437 row.collection ===
"" ||
1438 row.version ===
"" ||
1439 row.entity ===
"") {
1440 alert(f.name +
" missing needed metadata");
1450 $(
"#uploadFile").collapsible(
"option",
"collapsed",
true);
1451 $(
"#uploadFhiclFileButton").text(
"Store File(s) In Database");
1453 setTimeout(
function () { UploadFhiclFile(); }, 1000);
1457 function SetupEntityVersionPicker(tag) {
1459 AjaxGet(
"/db/EntitiesAndVersions",
function (data) {
1460 console.log(JSON.stringify(data));
1461 if (!data.Success) {
1462 UpdateHeader(
true,
false,
"Error retrieving entities and versions lists. Please contact an expert!");
1465 var collectionsObj = data.collections;
1467 var collectionNames = [];
1468 for (var c in collectionsObj) {
1469 if (collectionsObj.hasOwnProperty(c)) {
1470 var collection = [];
1471 var entitiesObj = collectionsObj[c];
1472 for (var e in entitiesObj.entities) {
1473 if (entitiesObj.entities.hasOwnProperty(e)) {
1474 var entity = entitiesObj.entities[e];
1476 var search = entity.versions.search;
1477 for (var v in search) {
1478 if (search.hasOwnProperty(v)) {
1479 versions.push({ name: search[v].name });
1482 collection.push({
id: entitiesObj.name + entity.name, name: entity.name, collection: entity.collection, edited:
false, version: versions[0].name, versions: versions });
1485 dataObj.push({
id: entitiesObj.name, name: entitiesObj.name, entities: collection });
1486 collectionNames.push(entitiesObj.name);
1490 var displayColumns = [
1492 text:
"Entity Name",
1495 cellClassName: CellClass
1499 dataField:
"version",
1501 columntype:
"template",
1502 initEditor:
function (rowKey, cellvalue, editor) {
1503 var row = tag.find(
"#grid").jqxTreeGrid(
"getRow", rowKey);
1506 for (var r in dataObj) {
1507 if (dataObj.hasOwnProperty(r)) {
1508 if (row.id.indexOf(dataObj[r].name) === 0) {
1514 var localData = dataObj[index1];
1515 for (var rr in localData.entities) {
1516 if (localData.entities.hasOwnProperty(rr)) {
1517 if (row.id === localData.entities[rr].id) {
1523 var versionsSource = { datatype:
"array", datafields: [{ name:
"name", type:
"string" }], localdata: dataObj[index1].entities[index2].versions };
1525 var versionsAdapter =
new $.jqx.dataAdapter(versionsSource, { autoBind:
true });
1526 editor.jqxDropDownList({ source: versionsAdapter, displayMember:
"name", valueMember:
"name", selectedIndex: 0 }).jqxDropDownList(
"refresh");
1530 editor.jqxDropDownList(
"selectItem", cellvalue);
1532 getEditorValue:
function (row, cellvalue, editor) {
1534 return editor.val();
1536 cellClassName: CellClass
1540 tag.html(
"<br><button type=\"button\" class=\"miniButton\" id=\"all1\"> Select All </button><button type=\"button\" class=\"miniButton\" id=\"none1\"> Select None </button><br>" +
1541 "<div id=\"grid\" class=\"jqxTreeGrid\"></div><br>" +
1542 "<button type=\"button\" class=\"miniButton\" id=\"all2\"> Select All </button><button type=\"button\" class=\"miniButton\" id=\"none2\"> Select None </button>");
1544 tag.find(
"#none1").jqxButton({ height: 30 });
1545 tag.find(
"#all1").jqxButton({ height: 30 });
1546 tag.find(
"#none2").jqxButton({ height: 30 });
1547 tag.find(
"#all2").jqxButton({ height: 30 });
1550 { name:
"id", type:
"string", editable:
false, display:
false },
1551 { name:
"name", type:
"string", editable:
false, display:
true },
1552 { name:
"version", type:
"string", editable:
true, display:
true },
1553 { name:
"versions", type:
"array", editable:
false, display:
false },
1554 { name:
"edited", type:
"boolean", editable:
false, display:
false },
1555 { name:
"entities", type:
"array", editable:
false, display:
false }
1559 dataFields: dataFields,
1567 var dataAdapter =
new $.jqx.dataAdapter(source);
1569 tag.find(
"#grid").jqxTreeGrid({
1571 source: dataAdapter,
1574 columnsResize:
true,
1576 hierarchicalCheckboxes:
true,
1577 columns: displayColumns
1579 for (var n in collectionNames) {
1580 if (collectionNames.hasOwnProperty(n)) {
1581 tag.find(
"#grid").jqxTreeGrid(
"lockRow", collectionNames[n]);
1587 tag.find(
"#none1").mousedown(
function () {
1588 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1589 for (var r in rows) {
1590 if (rows.hasOwnProperty(r)) {
1591 if (rows[r].checked) {
1592 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", rows[r].uid);
1597 tag.find(
"#all1").mousedown(
function () {
1598 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1599 for (var r in rows) {
1600 if (rows.hasOwnProperty(r)) {
1601 if (!rows[r].checked) {
1602 tag.find(
"#grid").jqxTreeGrid(
"checkRow", rows[r].uid);
1607 tag.find(
"#none2").mousedown(
function () {
1608 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1609 for (var r in rows) {
1610 if (rows.hasOwnProperty(r)) {
1611 if (rows[r].checked) {
1612 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", rows[r].uid);
1618 tag.find(
"#all2").mousedown(
function () {
1619 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1620 for (var r in rows) {
1621 if (rows.hasOwnProperty(r)) {
1622 if (!rows[r].checked) {
1623 tag.find(
"#grid").jqxTreeGrid(
"checkRow", rows[r].uid);
1631 function SaveConfig() {
1632 console.log(
"Saving Configuration Changes");
1634 $(
".file-tab.editedValue a")
1636 var log = $(
"#changes", $(
this).attr(
"href")).val();
1637 var collection = $(
"#metadataCollection", $(
this).attr(
"href")).val();
1639 var rows = $(
"#metadataEntities", $(
this).attr(
"href")).jqxTreeGrid(
'getRows');
1640 for (var i = 0; i < rows.length; i++) {
1642 entities.push(rows[i].name);
1644 var version = $(
"#metadataVersion", $(
this).attr(
"href")).val();
1645 files.push({ entities: entities, changelog: log, collection: collection, version: version });
1648 AjaxPost(
"/db/saveConfig",
1650 oldConfigName: CurrentNamedConfig,
1651 newConfigName: $(
"#configName").val(),
1656 if (res !== null && res !== undefined && res.Success) {
1657 UpdateHeader(
false,
false,
"Configuration Saved.");
1660 UpdateHeader(
true,
false,
"Failed to save configuration!");
1666 function DiscardConfig() {
1667 console.log(
"Discarding Configuration Changes");
1669 $(
".file-tab.editedValue").each(
function () {
1670 files.push({ name: $(
this).text() });
1673 AjaxPost(
"/db/discardConfig", { configName: CurrentNamedConfig, files: files, user: UserId },
function (res) {
1677 UpdateHeader(
true,
false,
"Failed to discard configuration. Make sure you have a valid configuration selected.\nIf this problem persists, call an expert.");
1683 function GetDbConfig() {
1685 AjaxGet(
"/db/getDbConfig",
1688 $(
"#dbType").val(data.dbprovider).trigger(
"change");
1689 $(
"#baseDir").val(data.baseDir);
1690 $(
"#databases").html(data.data.join(
"")).trigger(
"create").selectmenu(
"refresh");
1691 var database = GetUrlParameter(
"database");
1692 if (database !== undefined && database !==
"") {
1693 $(
"#databases").val(database).trigger(
"change");
1695 $(
"#databases").val(data.instanceName).trigger(
"change");
1702 function UpdateDbConfig() {
1704 dbprovider: $(
"#dbType").val(),
1705 baseDir: $(
"#baseDir").val(),
1706 instanceName: $(
"#databases").val()
1709 AjaxPost(
"/db/updateDbConfig",
1717 "Failed to update Database Module Configuration. Please See server logs for more details.");
1723 function MakeNewDatabase() {
1724 var newDBName = { name: $(
"#newDatabaseName").val() };
1725 AjaxPost(
"/db/makeNewDBInstance",
1726 newDBName,
function (res) {
1730 UpdateHeader(
true,
false,
"Failed to create new Database Instance. Please see server logs for more details.");
1736 function RegisterButtonFunctions() {
1737 $(
"#loadConfigButton").on(
"click",
function () { LoadConfig(); });
1738 $(
"#getConfigListButton").on(
"click",
function () { GetConfigList(); });
1739 $(
"#saveConfigButton").on(
"click",
function () { SaveConfig(); });
1740 $(
"#discardConfigButton").on(
"click",
function () { DiscardConfig(); });
1741 $(
"#searchCurrentConfigButton").on(
"click",
function () { SearchCurrentConfig(); });
1742 $(
"#baseConfigButton").on(
"click",
function () { BaseConfig(); });
1743 $(
"#saveNewConfigButton").on(
"click",
function () { SaveNewConfig(); });
1744 $(
"#baseExportConfigButton").on(
"click",
function () { BaseExportConfig(); });
1745 $(
"#exportFilesButton").on(
"click",
function () { ExportFiles(); });
1746 $(
"#addRowToFileUploaderButton").on(
"click",
function () { AddRowToFileUploader(); });
1747 $(
"#uploadFhiclFileButton").on(
"click",
function () { UploadFhiclFile(); });
1748 $(
"#updateDBConfigButton").on(
"click",
function () { UpdateDbConfig(); });
1749 $(
"#createNewDatabaseButton").on(
"click",
function () { MakeNewDatabase(); });
1756 var debounce =
function (func, threshold, execAsap) {
1759 return function debounced() {
1760 var obj =
this, args = arguments;
1761 function delayed() {
1763 func.apply(obj, args);
1768 clearTimeout(timeout);
1770 func.apply(obj, args);
1772 timeout = setTimeout(delayed, threshold || 100);
1777 jQuery.fn[sr] =
function (fn) {
return fn ? this.bind(
"resize", debounce(fn)) : this.trigger(sr); };
1779 })(jQuery,
"smartresize");
1781 $(document).ready(
function () {
1782 DefaultColor = $(
"#header").css(
"background-color");
1783 DefaultShadow = $(
"#header").css(
"text-shadow");
1785 $.get(
"/db/Tables.html",
function (data) {
1789 $.get(
"/db/FileInfo.html",
function (data) {
1793 $.get(
"/db/TreeGrid.html",
function (data) {
1794 TreeGridHtml = data;
1797 $.get(
"/db/Dialog.html",
function (data) { DialogContentHtml = data; });
1799 $(
".configInfo-tab").on(
"click",
function () {
1803 RegisterTabFunctions();
1804 $(
".tabs #tab1").show().siblings().hide();
1806 $(
".triggersModified").change(
function () {
1807 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
1810 $(window).smartresize(
function () {
1811 $(
".jqxTreeGrid").jqxTreeGrid({ width:
"100%" }).jqxTreeGrid(
"refresh");
1814 $(
"#newConfig").on(
"collapsibleexpand",
function () {
1815 SetupEntityVersionPicker($(
"#configurationPicker"));
1818 $(
"#exportFile").on(
"collapsibleexpand",
function () {
1819 SetupEntityVersionPicker($(
"#filePicker"));
1823 .on(
"collapsibleexpand",
1825 SetupFileUploadTable($(
"#fileUploader"));
1828 $(
"#dbType").on(
"change",
function () {
1829 var dbtype = $(
"#dbType").val();
1830 if (dbtype ===
"filesystem") {
1831 $(
"#filesystemdbConfig").show();
1832 $(
"#mongodbConfig").hide();
1833 }
else if (dbtype ===
"mongo") {
1834 $(
"#filesystemdbConfig").hide();
1835 $(
"#mongodbConfig").show();
1837 }).trigger(
"change");
1839 $(
"#databases").on(
"change",
function () {
1840 var instanceName = $(
"#databases").val();
1841 if (instanceName ===
"NONE") {
1842 $(
"#newDatabaseFS").show();
1844 $(
"#newDatabaseFS").hide();
1847 }).trigger(
"change");
1851 RegisterButtonFunctions();