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;
555 if ((parent === null || parent === undefined) && currentName.indexOf(
"___") >= 0) {
556 var parentSelector = tag.selector.split(
" ").slice(0, -1).join(
" ");
557 var parentRow = $(parentSelector +
" #treeGrid").jqxTreeGrid(
"getRow", currentName.slice(0, -4));
558 parent = parentRow[0];
560 if (parent !== null && parent !== undefined) {
561 currentName = parent.name;
562 path = parent.name +
"/" + path;
563 parent = parent.parent;
565 }
while (parent !== null && parent !== undefined);
567 if (CurrentCollection && CurrentEntity) {
568 path = CurrentCollection +
"/" + CurrentEntity +
"/" + path;
570 var pathTmp = path.split(
'/');
571 CurrentCollection = pathTmp.shift();
572 CurrentEntity = pathTmp.shift();
574 console.log(
"Path is " + path);
576 var columnDataField = args.dataField;
578 var columnName = args.dataField;
579 for (var i in args.owner._columns) {
580 if (args.owner._columns.hasOwnProperty(i)) {
581 if (args.owner._columns[i].dataField === columnName) {
582 columnName = args.owner._columns[i].text;
587 EditedValues[CurrentCollection +
"/" + CurrentEntity +
"/" + rowKey] =
true;
588 $(
"li.active :visible").parent().addClass(
"editedValue");
590 var value = args.value;
592 AjaxPost(
"/db/Update", {
593 configName: CurrentNamedConfig,
595 column: columnDataField,
600 },
function (retval) {
601 if (retval.Success) {
603 var selector = $(
"#changes", $(
".file-tab.active a").attr(
"href"));
604 selector.val(now.toISOString() +
": Edit - File: " + CurrentCollection +
"/" + CurrentEntity +
", Name: " + rowData.name +
", Column: " + columnName +
", Value: " + value +
"\n" + selector.val());
605 $(
"#masterChanges").val(now.toISOString() +
": Edit - File: " + CurrentCollection +
"/" + CurrentEntity +
", Name: " + rowData.name +
", Column: " + columnName +
", Value: " + value +
"\n" + $(
"#masterChanges").val());
606 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
608 UpdateHeader(
true,
false,
"Sending Update to server failed");
614 function CellClass(row, dataField, cellText, rowData) {
616 for (var val in EditedValues) {
617 if (EditedValues.hasOwnProperty(val)) {
618 if (val === CurrentCollection +
"/" + CurrentEntity +
"/" + rowData.uid) {
619 edited = EditedValues[val];
625 return "editedValue";
630 function TranslateColumns(columns) {
631 var displayColumns = [];
633 for (var c in columns) {
634 if (columns.hasOwnProperty(c)) {
635 var title = columns[c].title;
636 if (title === undefined || title === null || title.length === 0) {
637 title = columns[c].name.charAt(0).toUpperCase() + columns[c].name.slice(1);
639 if (columns[c].type ===
"string" && columns[c].display) {
640 displayColumns.push({
642 dataField: columns[c].name,
643 editable: columns[c].editable,
644 columnGroup: columns[c].columnGroup,
645 createEditor: CreateRowEditor,
646 initEditor: InitRowEditor,
647 getEditorValue: GetRowEditorValue,
648 cellClassName: CellClass
650 }
else if (columns[c].type ===
"number" && columns[c].display) {
651 columns[c].type =
"string";
652 columns[c].dataType =
"number";
653 displayColumns.push({
655 dataField: columns[c].name,
656 editable: columns[c].editable,
657 columnGroup: columns[c].columnGroup,
658 createEditor: CreateRowEditor,
659 initEditor: InitRowEditor,
660 getEditorValue: GetRowEditorValue,
661 cellClassName: CellClass
666 return displayColumns;
669 function LoadTable(tag) {
671 AjaxPost(
"/db/GetData", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId },
function (data) {
673 UpdateHeader(
true,
false,
"Fetch of data from database failed");
676 var columns = data.data.columns;
678 MakeTreeGrid(tag, columns, data.data.children);
683 function SetupConfigVersionPicker(element, target) {
685 element.on(
"change",
function () {
686 var thisConfig = element.find(
":selected").text();
687 var configVersionHtml =
"";
688 for (var version in ConfigVersionData[thisConfig]) {
689 if (ConfigVersionData[thisConfig].hasOwnProperty(version)) {
690 configVersionHtml +=
"<option name=\"" + ConfigVersionData[thisConfig][version].name
691 +
"\" value=" + ConfigVersionData[thisConfig][version].data +
">" + ConfigVersionData[thisConfig][version].version +
"</option>";
694 $(
"#" + target).html(configVersionHtml).trigger(
"create").selectmenu(
"refresh");
695 $(
"#" + target).html($(
"#" + target +
" option").sort(
function (a, b) {
696 return parseInt(a.text) === parseInt(b.text) ? 0 : parseInt(a.text) > parseInt(b.text) ? -1 : 1;
698 var option = $(
"#" + target).find(
'option:eq(0)');
699 option.prop(
'selected',
true);
700 $(
"#"+target).trigger(
"create").selectmenu(
"refresh");
704 function GetConfigList() {
705 UpdateHeader(
false,
false,
"");
706 $(
"#masterChanges").val(
"");
708 for (var i = 2; i <= LastTabId; i++) {
709 $(
"#tab" + i).
remove();
710 $(
"#tablink" + i).
remove();
713 $(
"#reloadConfigsButton").text(
"Reload Configurations");
716 AjaxPost(
"/db/NamedConfigs", { configFilter: $(
"#configurationFilter").val(), user: UserId },
function (data) {
718 UpdateHeader(
true,
false,
"Error retrieving Configuration list. Please contact an expert!");
721 var configsHtml =
"";
722 for (var name in data.data) {
723 if (data.data.hasOwnProperty(name)) {
724 configsHtml +=
"<option>" + name +
"</option>";
725 ConfigVersionData[name] = data.data[name];
728 $(
"#configs").html(configsHtml).trigger(
"create").selectmenu(
"refresh");
729 $(
"#oldConfigName").html(configsHtml).trigger(
"create").selectmenu(
"refresh");
730 $(
"#exportConfigName").html(configsHtml).trigger(
"create").selectmenu(
"refresh");
732 SetupConfigVersionPicker($(
"#configs"),
"configversions");
733 $(
"#configs").trigger(
"change");
734 SetupConfigVersionPicker($(
"#oldConfigName"),
"oldConfigVersion");
735 $(
"#oldConfigName").trigger(
"change");
736 SetupConfigVersionPicker($(
"#exportConfigName"),
"exportConfigVersion");
737 $(
"#exportConfigName").trigger(
"change");
739 var config = GetUrlParameter(
"configs");
740 if (config !== undefined) {
741 $(
"#configs").val(config);
744 $(
"#configLoad").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
745 $(
"#configSave").collapsible(
"option",
"disabled",
true).collapsible(
"option",
"collapsed",
true);
746 $(
"#configMetadata").collapsible(
"option",
"disabled",
true).collapsible(
"option",
"collapsed",
true);
747 $(
"#searchConfig").collapsible(
"option",
"disabled",
false);
748 $(
"#exportFile").collapsible(
"option",
"collapsed",
true);
749 $(
"#newConfig").collapsible(
"option",
"collapsed",
true);
752 function RegisterTabFunctions() {
753 $(
".file-tab a").off();
754 $(
".collection-tab a").off();
755 $(
".tabs .tab-links a").off().on(
"click",
function (e) {
756 var currentAttrValue = $(
this).attr(
"href");
757 var tab = $(
this).parent();
758 var div = tab.parent();
760 var left = Math.floor(tab.position().left - 20);
761 div.scrollLeft(left);
763 $(
".tabs " + currentAttrValue).show().siblings().hide();
766 $(
this).parent(
"li").addClass(
"active").siblings().removeClass(
"active");
770 $(
".collection-tab a").on(
"click",
function () {
771 CurrentCollection = $(
this).text();
773 $(
".file-tab a").on(
"click",
function () {
774 var fileName = $(
this).text();
775 CurrentEntity = fileName;
776 LoadFile($(
this).attr(
"href"));
781 function GetUrlParameter(sParam) {
782 var sUrlVariables = window.location.search.substring(1).split(
"&");
784 for (var i = 0; i < sUrlVariables.length; i++) {
785 var sParameterName = sUrlVariables[i].split(
"=");
787 if (sParameterName[0].search(sParam) >= 0) {
789 return sParameterName[1];
795 function LoadConfigMetadata() {
796 console.log(
"Loading configuration metadata");
798 AjaxPost(
"/db/LoadConfigMetadata", { configName: CurrentNamedConfig, user: UserId },
function (metadata) {
799 if (!metadata.Success) {
800 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
803 var metadataObj = metadata.data;
806 var displayColumns = [
813 text:
"Collection Name",
814 dataField:
"collection",
819 dataField:
"version",
823 text:
"Edit", cellsAlign:
"center", align:
"center", columnType:
"none", editable:
false, sortable:
false, dataField: null, cellsRenderer:
function (row) {
825 return "<button data-row='" + row +
"' class='editButtons' onclick=''>Edit</button>";
830 { name:
"name", type:
"string", editable:
false, display:
true },
831 { name:
"collection", type:
"string", editable:
false, display:
true },
832 { name:
"file", type:
"string", editable:
false, display:
false },
833 { name:
"version", type:
"string", editable:
false, display:
true }
837 dataFields: dataFields,
842 localData: metadataObj.entities
845 var dataAdapter =
new $.jqx.dataAdapter(source);
847 var grid = $(
"#configurationEntities");
848 grid.addClass(
"jqxTreeGrid").jqxTreeGrid(
855 columns: displayColumns,
856 rendering:
function () {
858 if ($(
".editButtons").length > 0) {
859 $(
".editButtons").jqxButton(
"destroy");
862 rendered:
function () {
863 if ($(
".editButtons").length > 0) {
864 $(
".editButtons").jqxButton();
866 var editClick =
function (event) {
868 var rowKey =
event.target.getAttribute(
"data-row");
869 var row = grid.jqxTreeGrid(
"getRow", rowKey);
870 var collection = row[
"collection"];
871 var collectionTab = $(
".collection-tab[collection-name=\"" + collection +
"\"] a");
872 collectionTab.trigger(
"click");
873 var file = row[
"name"];
874 var fileNameTab = $(collectionTab[0].hash).find(
".file-tab[file-name=\"" + file +
"\"] a");
875 fileNameTab.trigger(
"click");
877 $(
".editButtons").on(
"click",
function (event) {
888 function AddEntityToFile(
id) {
889 var newEntityName = $(
id +
" #newEntityName").val();
890 $(
id +
" #newEntityName").val(
"");
891 if (newEntityName !==
"") {
892 AjaxPost(
"/db/AddEntityToFile", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId, name: newEntityName },
function (res) {
897 UpdateHeader(
true,
false,
"Error adding Entity to configuration file");
903 function LoadFile(
id) {
905 AjaxPost(
"/db/LoadFileMetadata", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId },
function (metadata) {
906 if (!metadata.Success) {
907 UpdateHeader(
true,
false,
"Error loading file metadata from database");
910 console.log(
"Loading file metadata");
911 var metadataObj = metadata.data;
912 console.log(metadata);
913 $(
id +
" #metadataCollection").val(metadataObj.collection);
914 $(
id +
" #metadataVersion").val(metadataObj.version);
915 $(
id +
" #changeLog").val(metadataObj.changelog);
917 var displayColumns = [
924 text:
"Date Assigned",
925 dataField:
"assigned",
930 { name:
"name", type:
"string", editable:
false, display:
true },
931 { name:
"assigned", type:
"date", editable:
false, display:
true }
933 var entitiesSource = {
935 dataFields: dataFields,
940 localData: metadataObj.entities
943 var entitiesDataAdapter =
new $.jqx.dataAdapter(entitiesSource);
945 $(
id +
" #metadataEntities").addClass(
"jqxTreeGrid").jqxTreeGrid(
948 source: entitiesDataAdapter,
952 columns: displayColumns
954 var configsSource = {
956 dataFields: dataFields,
961 localData: metadataObj.configurations
964 var configsDataAdapter =
new $.jqx.dataAdapter(configsSource);
966 $(
id +
" #metadataConfigurations").addClass(
"jqxTreeGrid").jqxTreeGrid(
969 source: configsDataAdapter,
973 columns: displayColumns
975 LoadTable($(
id +
" #fileTable"));
979 function SearchCurrentConfig() {
980 console.log(
"Searching Configuration");
982 var searchKey = $(
"#searchKey").val();
983 console.log(
"SearchKey is " + searchKey);
985 AjaxPost(
"/db/SearchLoadedConfig", { configName: CurrentNamedConfig, user: UserId, searchKey: searchKey },
function (results) {
986 if (!results.Success) {
987 UpdateHeader(
true,
false,
"Error searching configuration");
991 MakeTreeGrid($(
"#searchResults"), results.columns, results.collections);
995 function LoadConfig() {
996 console.log(
"Loading Configuration");
997 $(
"#masterChanges").val(
"");
998 UpdateHeader(
false,
false,
"");
999 var selected = $(
"#configversions").find(
":selected");
1000 if (selected.text() ===
"No Configurations Found" || selected.text() ===
"Click \"Load Configurations\" To Load Configuration Names") {
return; }
1001 CurrentNamedConfig = selected.attr(
"name");
1002 $(
"#configName").val(CurrentNamedConfig);
1003 for (var i = 2; i <= LastTabId; i++) {
1004 $(
"#tab" + i).
remove();
1005 $(
"#tablink" + i).
remove();
1009 AjaxPost(
"/db/LoadNamedConfig", { configName: CurrentNamedConfig, query: selected.val(), user: UserId },
function (config) {
1010 if (!config.Success) {
1011 UpdateHeader(
true,
false,
"Error loading configuration files from database");
1015 for (var collection in config.collections) {
1016 if (config.collections.hasOwnProperty(collection)) {
1018 var parentTab = LastTabId;
1019 $(
"#tabLinks").append(
"<li id=\"tablink" + LastTabId +
"\"collection-name=\"" + config.collections[collection].name +
"\" tabNum=\"" + LastTabId +
"\" class=\"collection-tab\"><a href=\"#tab" + LastTabId +
"\">" + config
1020 .collections[collection].name +
"</a></li>");
1021 $(
"#tabContents").append(
"<div id=tab" + LastTabId +
" class=\"tab\"></div>");
1022 $(
"#tab" + LastTabId).html(TableHtml);
1024 for (var file in config.collections[collection].files) {
1025 if (config.collections[collection].files.hasOwnProperty(file)) {
1026 var name = config.collections[collection].files[file];
1029 $(
"#tab" + parentTab +
" #tabLinks").append(
"<li id=\"tablink" + LastTabId +
"\" file-name=\"" + name +
"\" tabNum=\"" + LastTabId +
"\" class=\"file-tab\"><a href=\"#tab" + LastTabId +
"\">" + name +
"</a></li>");
1030 $(
"#tab" + parentTab +
" #tabContents").append(
"<div id=tab" + LastTabId +
" class=\"tab\"></div>");
1031 $(
"#tab" + LastTabId).html(InfoHtml).trigger(
"create");;
1036 $(
"#configLoad").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
true);
1037 $(
"#configSave").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
1038 LoadConfigMetadata();
1039 $(
"#configMetadata").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
1040 $(
"#searchConfig").collapsible(
"option",
"disabled",
false);
1041 RegisterTabFunctions();
1045 function BaseConfig() {
1047 AjaxPost(
"/db/LoadConfigMetadata", { configName: $(
"#oldConfigName :selected").text(), user: UserId },
function (metadata) {
1048 if (!metadata.Success) {
1049 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
1052 var metadataObj = metadata.data;
1055 $(
"#newConfigName").val($(
"#oldConfigName :selected").text());
1056 var tag = $(
"#configurationPicker");
1057 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1058 for (var r in rows) {
1059 if (rows.hasOwnProperty(r)) {
1060 var thisRow = rows[r];
1061 var isChecked =
false;
1062 for (var e in metadataObj.entities) {
1063 if (isChecked)
break;
1064 if (metadataObj.entities.hasOwnProperty(e)) {
1065 var entity = metadataObj.entities[e];
1066 if (thisRow.name === entity.collection) {
1067 for (var r in thisRow.records) {
1068 if (thisRow.records.hasOwnProperty(r)) {
1069 var record = thisRow.records[r];
1070 if (record.id === entity.collection + entity.name) {
1071 tag.find(
"#grid").jqxTreeGrid(
"updateRow", record.uid, { name: entity.name, version: entity.version });
1072 tag.find(
"#grid").jqxTreeGrid(
"checkRow", record.uid);
1081 if (!isChecked && thisRow.checked) {
1082 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", thisRow.uid);
1089 function BaseExportConfig() {
1091 AjaxPost(
"/db/LoadConfigMetadata", { configName: $(
"#exportConfigName :selected").text(), user: UserId },
function (metadata) {
1092 if (!metadata.Success) {
1093 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
1096 ExportTarFileName = $(
"#exportConfigName :selected").text();
1097 var metadataObj = metadata.data;
1100 var tag = $(
"#filePicker");
1101 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1102 for (var r in rows) {
1103 if (rows.hasOwnProperty(r)) {
1104 var thisRow = rows[r];
1105 var isChecked =
false;
1106 for (var e in metadataObj.entities) {
1107 if (isChecked)
break;
1108 if (metadataObj.entities.hasOwnProperty(e)) {
1109 var entity = metadataObj.entities[e];
1110 if (thisRow.name === entity.collection) {
1111 for (var r in thisRow.records) {
1112 if (thisRow.records.hasOwnProperty(r)) {
1113 var record = thisRow.records[r];
1114 if (record.id === entity.collection + entity.name) {
1115 tag.find(
"#grid").jqxTreeGrid(
"updateRow", record.uid, { name: entity.name, version: entity.version });
1116 tag.find(
"#grid").jqxTreeGrid(
"checkRow", record.uid);
1125 if (!isChecked && thisRow.checked) {
1126 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", thisRow.uid);
1134 function SaveNewConfig() {
1135 console.log(
"Saving New Configuration");
1136 var tag = $(
"#configurationPicker");
1137 var rows = tag.find(
"#grid").jqxTreeGrid(
"getCheckedRows");
1142 for (var r in rows) {
1143 if (rows.hasOwnProperty(r) &&
1144 (typeof rows[r].collection !==
"undefined" && rows[r].collection.length > 0) &&
1145 (typeof rows[r].version !==
"undefined" && rows[r].version.length > 0)) {
1146 configObj.entities.push({ name: rows[r].name, version: rows[r].version, collection: rows[r].collection });
1151 AjaxPost(
"/db/MakeNewConfig", { user: UserId, config: JSON.stringify(configObj), name: $(
"#newConfigName").val() },
function (retval) {
1152 if (retval.Success) {
1153 $(
"#newConfig").collapsible(
"option",
"collapsed",
true);
1156 UpdateHeader(
true,
false,
"MakeNewConfig operation failed.");
1161 function ExportFiles() {
1162 console.log(
"Exporting Files");
1163 var tag = $(
"#filePicker");
1164 var rows = tag.find(
"#grid").jqxTreeGrid(
"getCheckedRows");
1169 for (var r in rows) {
1170 if (rows.hasOwnProperty(r) &&
1171 (typeof rows[r].collection !==
"undefined" && rows[r].collection.length > 0) &&
1172 (typeof rows[r].version !==
"undefined" && rows[r].version.length > 0)) {
1173 configObj.entities.push({ name: rows[r].name, version: rows[r].version, collection: rows[r].collection });
1178 var xhr =
new XMLHttpRequest();
1179 xhr.open(
"POST",
"/db/DownloadConfigurationFile",
true);
1180 xhr.responseType =
"arraybuffer";
1181 xhr.onload =
function () {
1182 if (this.status === 200) {
1184 var disposition = xhr.getResponseHeader(
"Content-Disposition");
1185 if (disposition && disposition.indexOf(
"attachment") !== -1) {
1186 var filenameRegex = /filename[^;=\n]*=(([
'"]).*?\2|[^;\n]*)/;
1187 var matches = filenameRegex.exec(disposition);
1188 if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, "");
1190 var type = xhr.getResponseHeader("Content-Type
");
1192 var blob = new Blob([this.response], { type: type });
1193 if (typeof window.navigator.msSaveBlob !== "undefined
") {
1194 // 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.
"
1195 window.navigator.msSaveBlob(blob, filename);
1197 var url = window.URL || window.webkitURL;
1198 var downloadUrl = url.createObjectURL(blob);
1201 // use HTML5 a[download] attribute to specify filename
1202 var a = document.createElement("a
");
1203 // safari doesn't support this yet
1204 if (typeof a.download === "undefined
") {
1205 window.location = downloadUrl;
1207 a.href = downloadUrl;
1208 a.download = filename;
1209 document.body.appendChild(a);
1213 window.location = downloadUrl;
1216 setTimeout(function () { url.revokeObjectURL(downloadUrl); }, 100); // cleanup
1218 } else if (this.status === 500) {
1219 UpdateHeader(true, false, "An error occurred on the server. Contact an expert
if the situation persists
");
1222 xhr.setRequestHeader("Content-type
", "application/x-www-form-urlencoded
");
1223 xhr.send($.param({ user: UserId, config: JSON.stringify(configObj), tarFileName: ExportTarFileName, type: $("#exportFileFormat :selected
").val() }));
1224 ExportTarFileName = "export
";
1227 function AddRowToFileUploader() {
1228 $("#fileUploader
").find("#grid
").jqxTreeGrid("addRow
", null, {});
1231 function SetupFileUploadTable(tag) {
1232 var displayColumns = [
1235 dataField: "fileName
",
1237 cellClassName: CellClass,
1238 columntype: "template",
1239 initEditor: function (row, cellvalue, editor) {
1240 if (cellvalue === "" || cellvalue === "undefined
" || !cellvalue) {
1241 editor.html("<input type=\
"file\" id=\"fileName\"/>");
1243 editor.text(cellvalue);
1246 getEditorValue:
function (row, cellvalue, editor) {
1248 if (cellvalue ===
"" || cellvalue ===
"undefined" || !cellvalue) {
1249 var fileName = editor.find(
"#fileName")[0];
1250 UploadFiles[row] = fileName.files[0];
1251 return fileName.files[0].name;
1258 dataField:
"fileType",
1260 cellClassName: CellClass,
1261 columntype:
"template",
1262 initEditor:
function (row, cellvalue, editor) {
1264 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 });
1265 editor.jqxDropDownList({ source: versionsAdapter, displayMember:
"name", valueMember:
"value", selectedIndex: 0 }).jqxDropDownList(
"refresh");
1267 editor.jqxDropDownList(
"selectItem", cellvalue);
1269 getEditorValue:
function (row, cellvalue, editor) {
1271 return editor.val();
1276 dataField:
"collection",
1278 cellClassName: CellClass
1281 text:
"Entity Name",
1282 dataField:
"entity",
1284 cellClassName: CellClass
1288 dataField:
"version",
1290 cellClassName: CellClass
1293 text:
"Remove", cellsAlign:
"center", align:
"center", columnType:
"none", editable:
false, sortable:
false, dataField: null, cellsRenderer:
function (row) {
1295 return "<button data-row='" + row +
"' class='removeButtons' onclick=''>Remove</button>";
1300 tag.html(
"<div id=\"grid\" class=\"jqxTreeGrid\"></div><br>");
1303 { name:
"id", type:
"string", editable:
false, display:
false },
1304 { name:
"fileName", type:
"string", editable:
true, display:
true },
1305 { name:
"fileType", type:
"string", editable:
true, display:
true },
1306 { name:
"collection", type:
"string", editable:
true, display:
true },
1307 { name:
"entity", type:
"string", editable:
true, display:
true },
1308 { name:
"version", type:
"string", editable:
true, display:
true }
1312 dataFields: dataFields,
1320 var dataAdapter =
new $.jqx.dataAdapter(source);
1322 tag.find(
"#grid").jqxTreeGrid({
1324 source: dataAdapter,
1327 columnsResize:
true,
1328 columns: displayColumns,
1329 rendering:
function () {
1331 if ($(
".removeButtons").length > 0) {
1332 $(
".removeButtons").jqxButton(
"destroy");
1335 rendered:
function () {
1336 if ($(
".removeButtons").length > 0) {
1337 $(
".removeButtons").jqxButton();
1339 var removeClick =
function (event) {
1341 var rowKey =
event.target.getAttribute(
"data-row");
1342 delete UploadFiles[rowKey];
1343 tag.find(
"#grid").jqxTreeGrid(
"deleteRow", rowKey);
1345 $(
".removeButtons").on(
"click",
function (event) {
1355 function SetupReader(file) {
1356 var f = UploadFiles[file];
1357 var r =
new FileReader();
1359 r.onload =
function (e) {
1360 var contents = e.target.result;
1361 var thisfile = e.target.fileid;
1362 var row = $(
"#fileUploader").find(
"#grid").jqxTreeGrid(
"getRow", thisfile);
1363 console.log(
"Calling AjaxPost with parameters: Collection: " +
1370 row.fileType +
", fileName: " + row.fileName +
", file.name: " + f.name);
1373 AjaxPost(
"/db/UploadConfigurationFile",
1376 collection: row.collection,
1377 version: row.version,
1384 UpdateHeader(
true,
false,
"File upload failed");
1386 console.log(
"Upload: " + row.fileName +
" returned: " + JSON.stringify(res));
1388 delete UploadFiles[thisfile];
1394 function UploadFhiclFile() {
1395 $(
"#uploadFhiclFileButton").text(
"Uploading... Please Wait.");
1397 var didAnything =
false;
1398 for (var file in UploadFiles) {
1399 if (UploadFiles.hasOwnProperty(file)) {
1401 var f = UploadFiles[file];
1403 var row = $(
"#fileUploader").find(
"#grid").jqxTreeGrid(
"getRow", file);
1405 alert(
"Failed to load file");
1409 if (row.fileType ===
"fhicl" && f.name.search(
".fcl") === -1) {
1410 alert(f.name +
" is not a valid fhicl file.");
1414 if (row.fileType ===
"json" && f.name.search(
".json") === -1) {
1415 alert(f.name +
" is not a valid json file.");
1419 if ((row.fileType !==
"fhicl" &&
1420 row.fileType !==
"json") ||
1421 row.collection ===
"" ||
1422 row.version ===
"" ||
1423 row.entity ===
"") {
1424 alert(f.name +
" missing needed metadata");
1434 $(
"#uploadFile").collapsible(
"option",
"collapsed",
true);
1435 $(
"#uploadFhiclFileButton").text(
"Store File(s) In Database");
1437 setTimeout(
function () { UploadFhiclFile(); }, 1000);
1441 function SetupEntityVersionPicker(tag) {
1443 AjaxGet(
"/db/EntitiesAndVersions",
function (data) {
1444 console.log(JSON.stringify(data));
1445 if (!data.Success) {
1446 UpdateHeader(
true,
false,
"Error retrieving entities and versions lists. Please contact an expert!");
1449 var collectionsObj = data.collections;
1451 var collectionNames = [];
1452 for (var c in collectionsObj) {
1453 if (collectionsObj.hasOwnProperty(c)) {
1454 var collection = [];
1455 var entitiesObj = collectionsObj[c];
1456 for (var e in entitiesObj.entities) {
1457 if (entitiesObj.entities.hasOwnProperty(e)) {
1458 var entity = entitiesObj.entities[e];
1460 var search = entity.versions.search;
1461 for (var v in search) {
1462 if (search.hasOwnProperty(v)) {
1463 versions.push({ name: search[v].name });
1466 collection.push({
id: entitiesObj.name + entity.name, name: entity.name, collection: entity.collection, edited:
false, version: versions[0].name, versions: versions });
1469 dataObj.push({
id: entitiesObj.name, name: entitiesObj.name, entities: collection });
1470 collectionNames.push(entitiesObj.name);
1474 var displayColumns = [
1476 text:
"Entity Name",
1479 cellClassName: CellClass
1483 dataField:
"version",
1485 columntype:
"template",
1486 initEditor:
function (rowKey, cellvalue, editor) {
1487 var row = tag.find(
"#grid").jqxTreeGrid(
"getRow", rowKey);
1490 for (var r in dataObj) {
1491 if (dataObj.hasOwnProperty(r)) {
1492 if (row.id.indexOf(dataObj[r].name) === 0) {
1498 var localData = dataObj[index1];
1499 for (var rr in localData.entities) {
1500 if (localData.entities.hasOwnProperty(rr)) {
1501 if (row.id === localData.entities[rr].id) {
1507 var versionsSource = { datatype:
"array", datafields: [{ name:
"name", type:
"string" }], localdata: dataObj[index1].entities[index2].versions };
1509 var versionsAdapter =
new $.jqx.dataAdapter(versionsSource, { autoBind:
true });
1510 editor.jqxDropDownList({ source: versionsAdapter, displayMember:
"name", valueMember:
"name", selectedIndex: 0 }).jqxDropDownList(
"refresh");
1514 editor.jqxDropDownList(
"selectItem", cellvalue);
1516 getEditorValue:
function (row, cellvalue, editor) {
1518 return editor.val();
1520 cellClassName: CellClass
1524 tag.html(
"<br><button type=\"button\" class=\"miniButton\" id=\"all1\"> Select All </button><button type=\"button\" class=\"miniButton\" id=\"none1\"> Select None </button><br>" +
1525 "<div id=\"grid\" class=\"jqxTreeGrid\"></div><br>" +
1526 "<button type=\"button\" class=\"miniButton\" id=\"all2\"> Select All </button><button type=\"button\" class=\"miniButton\" id=\"none2\"> Select None </button>");
1528 tag.find(
"#none1").jqxButton({ height: 30 });
1529 tag.find(
"#all1").jqxButton({ height: 30 });
1530 tag.find(
"#none2").jqxButton({ height: 30 });
1531 tag.find(
"#all2").jqxButton({ height: 30 });
1534 { name:
"id", type:
"string", editable:
false, display:
false },
1535 { name:
"name", type:
"string", editable:
false, display:
true },
1536 { name:
"version", type:
"string", editable:
true, display:
true },
1537 { name:
"versions", type:
"array", editable:
false, display:
false },
1538 { name:
"edited", type:
"boolean", editable:
false, display:
false },
1539 { name:
"entities", type:
"array", editable:
false, display:
false }
1543 dataFields: dataFields,
1551 var dataAdapter =
new $.jqx.dataAdapter(source);
1553 tag.find(
"#grid").jqxTreeGrid({
1555 source: dataAdapter,
1558 columnsResize:
true,
1560 hierarchicalCheckboxes:
true,
1561 columns: displayColumns
1563 for (var n in collectionNames) {
1564 if (collectionNames.hasOwnProperty(n)) {
1565 tag.find(
"#grid").jqxTreeGrid(
"lockRow", collectionNames[n]);
1571 tag.find(
"#none1").mousedown(
function () {
1572 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1573 for (var r in rows) {
1574 if (rows.hasOwnProperty(r)) {
1575 if (rows[r].checked) {
1576 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", rows[r].uid);
1581 tag.find(
"#all1").mousedown(
function () {
1582 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1583 for (var r in rows) {
1584 if (rows.hasOwnProperty(r)) {
1585 if (!rows[r].checked) {
1586 tag.find(
"#grid").jqxTreeGrid(
"checkRow", rows[r].uid);
1591 tag.find(
"#none2").mousedown(
function () {
1592 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1593 for (var r in rows) {
1594 if (rows.hasOwnProperty(r)) {
1595 if (rows[r].checked) {
1596 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", rows[r].uid);
1602 tag.find(
"#all2").mousedown(
function () {
1603 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1604 for (var r in rows) {
1605 if (rows.hasOwnProperty(r)) {
1606 if (!rows[r].checked) {
1607 tag.find(
"#grid").jqxTreeGrid(
"checkRow", rows[r].uid);
1615 function SaveConfig() {
1616 console.log(
"Saving Configuration Changes");
1618 $(
".file-tab.editedValue a")
1620 var log = $(
"#changes", $(
this).attr(
"href")).val();
1621 var collection = $(
"#metadataCollection", $(
this).attr(
"href")).val();
1623 var rows = $(
"#metadataEntities", $(
this).attr(
"href")).jqxTreeGrid(
'getRows');
1624 for (var i = 0; i < rows.length; i++) {
1626 entities.push(rows[i].name);
1628 var version = $(
"#metadataVersion", $(
this).attr(
"href")).val();
1629 files.push({ entities: entities, changelog: log, collection: collection, version: version });
1632 AjaxPost(
"/db/saveConfig",
1634 oldConfigName: CurrentNamedConfig,
1635 newConfigName: $(
"#configName").val(),
1640 if (res !== null && res !== undefined && res.Success) {
1641 UpdateHeader(
false,
false,
"Configuration Saved.");
1644 UpdateHeader(
true,
false,
"Failed to save configuration!");
1650 function DiscardConfig() {
1651 console.log(
"Discarding Configuration Changes");
1653 $(
".file-tab.editedValue").each(
function () {
1654 files.push({ name: $(
this).text() });
1657 AjaxPost(
"/db/discardConfig", { configName: CurrentNamedConfig, files: files, user: UserId },
function (res) {
1661 UpdateHeader(
true,
false,
"Failed to discard configuration. Make sure you have a valid configuration selected.\nIf this problem persists, call an expert.");
1667 function GetDbConfig() {
1669 AjaxGet(
"/db/getDbConfig",
1672 $(
"#dbType").val(data.dbprovider).trigger(
"change");
1673 $(
"#baseDir").val(data.baseDir);
1674 $(
"#databases").html(data.data.join(
"")).trigger(
"create").selectmenu(
"refresh");
1675 var database = GetUrlParameter(
"database");
1676 if (database !== undefined && database !==
"") {
1677 $(
"#databases").val(database).trigger(
"change");
1679 $(
"#databases").val(data.instanceName).trigger(
"change");
1686 function UpdateDbConfig() {
1688 dbprovider: $(
"#dbType").val(),
1689 baseDir: $(
"#baseDir").val(),
1690 instanceName: $(
"#databases").val()
1693 AjaxPost(
"/db/updateDbConfig",
1701 "Failed to update Database Module Configuration. Please See server logs for more details.");
1707 function MakeNewDatabase() {
1708 var newDBName = { name: $(
"#newDatabaseName").val() };
1709 AjaxPost(
"/db/makeNewDBInstance",
1710 newDBName,
function (res) {
1714 UpdateHeader(
true,
false,
"Failed to create new Database Instance. Please see server logs for more details.");
1720 function RegisterButtonFunctions() {
1721 $(
"#loadConfigButton").on(
"click",
function () { LoadConfig(); });
1722 $(
"#getConfigListButton").on(
"click",
function () { GetConfigList(); });
1723 $(
"#saveConfigButton").on(
"click",
function () { SaveConfig(); });
1724 $(
"#discardConfigButton").on(
"click",
function () { DiscardConfig(); });
1725 $(
"#searchCurrentConfigButton").on(
"click",
function () { SearchCurrentConfig(); });
1726 $(
"#baseConfigButton").on(
"click",
function () { BaseConfig(); });
1727 $(
"#saveNewConfigButton").on(
"click",
function () { SaveNewConfig(); });
1728 $(
"#baseExportConfigButton").on(
"click",
function () { BaseExportConfig(); });
1729 $(
"#exportFilesButton").on(
"click",
function () { ExportFiles(); });
1730 $(
"#addRowToFileUploaderButton").on(
"click",
function () { AddRowToFileUploader(); });
1731 $(
"#uploadFhiclFileButton").on(
"click",
function () { UploadFhiclFile(); });
1732 $(
"#updateDBConfigButton").on(
"click",
function () { UpdateDbConfig(); });
1733 $(
"#createNewDatabaseButton").on(
"click",
function () { MakeNewDatabase(); });
1740 var debounce =
function (func, threshold, execAsap) {
1743 return function debounced() {
1744 var obj =
this, args = arguments;
1745 function delayed() {
1747 func.apply(obj, args);
1752 clearTimeout(timeout);
1754 func.apply(obj, args);
1756 timeout = setTimeout(delayed, threshold || 100);
1761 jQuery.fn[sr] =
function (fn) {
return fn ? this.bind(
"resize", debounce(fn)) : this.trigger(sr); };
1763 })(jQuery,
"smartresize");
1765 $(document).ready(
function () {
1766 DefaultColor = $(
"#header").css(
"background-color");
1767 DefaultShadow = $(
"#header").css(
"text-shadow");
1769 $.get(
"/db/Tables.html",
function (data) {
1773 $.get(
"/db/FileInfo.html",
function (data) {
1777 $.get(
"/db/TreeGrid.html",
function (data) {
1778 TreeGridHtml = data;
1781 $.get(
"/db/Dialog.html",
function (data) { DialogContentHtml = data; });
1783 $(
".configInfo-tab").on(
"click",
function () {
1787 RegisterTabFunctions();
1788 $(
".tabs #tab1").show().siblings().hide();
1790 $(
".triggersModified").change(
function () {
1791 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
1794 $(window).smartresize(
function () {
1795 $(
".jqxTreeGrid").jqxTreeGrid({ width:
"100%" }).jqxTreeGrid(
"refresh");
1798 $(
"#newConfig").on(
"collapsibleexpand",
function () {
1799 SetupEntityVersionPicker($(
"#configurationPicker"));
1802 $(
"#exportFile").on(
"collapsibleexpand",
function () {
1803 SetupEntityVersionPicker($(
"#filePicker"));
1807 .on(
"collapsibleexpand",
1809 SetupFileUploadTable($(
"#fileUploader"));
1812 $(
"#dbType").on(
"change",
function () {
1813 var dbtype = $(
"#dbType").val();
1814 if (dbtype ===
"filesystem") {
1815 $(
"#filesystemdbConfig").show();
1816 $(
"#mongodbConfig").hide();
1817 }
else if (dbtype ===
"mongo") {
1818 $(
"#filesystemdbConfig").hide();
1819 $(
"#mongodbConfig").show();
1821 }).trigger(
"change");
1823 $(
"#databases").on(
"change",
function () {
1824 var instanceName = $(
"#databases").val();
1825 if (instanceName ===
"NONE") {
1826 $(
"#newDatabaseFS").show();
1828 $(
"#newDatabaseFS").hide();
1831 }).trigger(
"change");
1835 RegisterButtonFunctions();