2 var DefaultShadow =
"";
7 var CurrentNamedConfig =
"";
11 var EditedValues = {};
12 var ExportTarFileName =
"export";
19 function GenerateUuid() {
21 if (window.performance && typeof window.performance.now ===
"function") {
22 d += performance.now();
24 var uuid =
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,
function (c) {
25 var r = (d + Math.random() * 16) % 16 | 0;
26 d = Math.floor(d / 16);
27 return (c ===
"x" ? r : (r & 0x3 | 0x8)).toString(16);
32 function UpdateHeader(error, change, text) {
34 $(
"#header").css(
"background-color",
"#D59595").css(
"text-shadow",
"#D99 0 1px 0");
35 $(
"#info").text(text);
36 text =
"ERROR: " + text;
38 $(
"#header").css(
"background-color",
"#E7F29B").css(
"text-shadow",
"#EF9 0 1px 0");
39 $(
"#info").text(text);
40 text =
"CHANGE: " + text;
42 $(
"#header").css(
"background-color", DefaultColor).css(
"text-shadow", DefaultShadow);
43 $(
"#info").text(text);
45 if (text.length > 0) {
50 function ResizeTextAreas() {
51 $(
"textarea").each(
function (i, el) {
52 $(el).height(el.scrollHeight);
56 function GetRadix(value) {
62 if (value.search(
"0x") === 0) {
63 output.value = value.slice(2);
65 if ((
"" + output.value).search(/[^0-9a-fA-F]/) >= 0) { output.radix = -1; }
66 }
else if (value.search(
"0") === 0) {
67 output.value = value.slice(1);
69 if (isNaN(output.value)) { output.radix = -1; }
70 }
else if (value.search(
"b") === value.length - 1) {
71 output.value = value.slice(0, -1);
73 if (isNaN(output.value)) { output.radix = -1; }
74 }
else if (isNaN(value)) {
81 if (output.value ===
" " || (
"" + output.value).length === 0 || (
"" + output.value).indexOf(
".") >= 0) {
88 function CreateRowEditor(row, cellvalue, editor, cellText, width, height) {
89 editor.after(
"<div></div><div></div>");
90 var radixObj = GetRadix(cellText);
91 if (radixObj.radix > 0) {
92 editor.parent().jqxFormattedInput({ radix: radixObj.radix, value: radixObj.value, width: width, height: height, upperCase:
true, dropDown:
true, spinButtons:
true });
96 function InitRowEditor(row, cellvalue, editor) {
97 editor.parent().val(cellvalue);
100 function GetRowEditorValue(row, cellvalue, editor) {
101 if (editor.parent()) {
102 if (editor.val().length === 0) {
103 editor.parent().parent().empty();
106 var radix = editor.parent().jqxFormattedInput(
"radix");
107 if (radix === 2 || radix ===
"binary") {
108 return editor.val() +
"b";
110 if (radix === 16 || radix ===
"hexadecimal") {
111 return "0x" + editor.val().toUpperCase();
113 if (radix === 8 || radix ===
"octal") {
114 if (editor.val()[0] ===
"0") {
117 return "0" + editor.val();
123 function RowEditDialogSave(dataFields, newRowId, grid) {
126 for (var i in dataFields) {
127 if (dataFields.hasOwnProperty(i)) {
128 var name = dataFields[i].name +
"_Editor";
129 var value =
"" + $(
"#" + name).val();
130 if (value ===
"undefined") {
133 row[dataFields[i].name] = value;
138 var currentName = path;
139 var parent = row.parent;
141 if ((parent === null || parent === undefined) && currentName.indexOf(
"___") >= 0) {
142 var parentSelector = grid.selector.split(
" ").slice(0, -1).join(
" ");
143 var parentRow = $(parentSelector +
" #treeGrid").jqxTreeGrid(
"getRow", currentName.slice(0, -4));
144 parent = parentRow[0];
146 if (parent !== null && parent !== undefined) {
147 currentName = parent.name;
148 path = parent.name +
"/" + path;
149 parent = parent.parent;
151 }
while (parent !== null && parent !== undefined);
153 path = CurrentCollection +
"/" + CurrentEntity +
"/" + path;
157 AjaxPost(
"/db/AddOrUpdate", {
158 configName: CurrentNamedConfig,
163 },
function (retval) {
164 if (retval.Success) {
166 $(
"#changes", $(
".file-tab.active a").attr(
"href")).val(now.toISOString() +
": Edit - Path: " + path +
", Name: " + row.name +
" Dialog Edit - multiple columns may have been changed!");
167 $(
"#masterChanges").val(now.toISOString() +
": Edit - Path: " + path +
", Name: " + row.name +
" Dialog Edit - multiple columns may have been changed!");
169 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
171 UpdateHeader(
true,
false,
"Sending Update to server failed");
175 grid.jqxTreeGrid(
"updateRow", newRowId, row);
176 EditedValues[CurrentCollection +
"/" + CurrentEntity +
"/" + row.uid] =
true;
177 $(
"li.active :visible").parent().addClass(
"editedValue");
181 function MakeTreeGrid(tag, dataFields, data, columnGroups) {
182 tag.html(TreeGridHtml);
183 var grid = tag.find(
"#treeGrid");
184 var contextMenu = tag.find(
"#Menu");
185 var dialog = tag.find(
"#dialog");
187 var displayColumns = TranslateColumns(dataFields);
190 console.log(
"DisplayColumns is " + JSON.stringify(displayColumns));
191 console.log(
"DataFields is " + JSON.stringify(dataFields));
195 dataFields: dataFields,
201 addRow:
function (rowId) {
206 var dataAdapter =
new $.jqx.dataAdapter(source, {
207 beforeLoadComplete:
function (records) {
208 var numberFields = [];
209 for (var c in source.dataFields) {
210 if (source.dataFields.hasOwnProperty(c)) {
211 if (source.dataFields[c].dataType ===
"number") {
212 numberFields.push({ name: source.dataFields[c].name, radix: source.dataFields[c].radix });
216 for (var i in records) {
217 if (records.hasOwnProperty(i)) {
218 for (var f in numberFields) {
219 if (numberFields.hasOwnProperty(f)) {
220 var radix = numberFields[f].radix;
224 var value = records[i][numberFields[f].name];
226 if (typeof value ===
"number" || !(value.search(
"0x") === 0 || value.search(
"0") === 0 || value.search(
"b") === value.length - 1)) {
228 value = parseInt(value).toString(radix).toUpperCase();
229 records[i][numberFields[f].name] = value;
231 records[i][numberFields[f].name] +=
"b";
234 records[i][numberFields[f].name] =
"0x" + value;
237 records[i][numberFields[f].name] =
"0" + value;
249 var sequenceTables = [];
251 grid.addClass(
"jqxTreeGrid").jqxTreeGrid(
256 editSettings: { saveOnPageChange:
true, saveOnBlur:
true, saveOnSelectionChange:
true, cancelOnEsc:
true, saveOnEnter:
true, editSingleCell:
true, editOnDoubleClick:
true, editOnF2:
true },
259 columns: displayColumns,
260 columnGroups: columnGroups,
262 rowDetailsRenderer:
function (rowKey, row) {
263 if (row.isSequence) {
264 var indent = (1 + row.level) * 20;
265 var details =
"<div id=\"" + rowKey +
"___Table\" style=\"margin-left: " + indent +
"px;padding-right: 5px\"></div>";
266 sequenceTables.push({ key: rowKey, data: row.table });
272 rendered:
function () {
273 $(
".jqx-tooltip").
remove();
274 var setupRow =
function (rowObject) {
275 if (rowObject[source.comment] && rowObject[source.comment].length > 0 && rowObject[source.comment] !==
" ") {
276 var selector = $(
"tr[data-key=\'" + rowObject.uid +
"\']");
277 if (selector.length) {
278 selector.jqxTooltip({ content: rowObject[source.comment], position:
"mouse" });
281 for (var trow in rowObject.records) {
282 if (rowObject.records.hasOwnProperty(trow)) {
283 setupRow(rowObject.records[trow]);
287 var rows = grid.jqxTreeGrid(
"getRows");
288 for (var ttrow = 0; ttrow < rows.length; ttrow++) {
289 setupRow(rows[ttrow]);
291 for (var seq in sequenceTables) {
292 if (sequenceTables.hasOwnProperty(seq)) {
293 var elem = tag.find(
"#" + sequenceTables[seq].key +
"___Table");
294 var data = sequenceTables[seq].data;
295 MakeTreeGrid(elem, data.columns, data.rows, data.columnGroups);
300 dialog.on(
"close",
function () {
302 grid.jqxTreeGrid({ disabled:
false });
307 position: { left: grid.offset().left + 75, top: grid.offset().top + 35 },
310 dialog.css(
"visibility",
"visible");
315 grid.jqxTreeGrid(
"expandAll");
317 contextMenu.jqxMenu({ width: 200, height: 120, autoOpenPopup:
false, mode:
"popup" });
318 grid.on(
"contextmenu",
function () {
321 grid.on(
"rowClick",
function (event) {
322 var args =
event.args;
323 if (args.originalEvent.button === 2) {
324 var scrollTop = $(window).scrollTop();
325 var scrollLeft = $(window).scrollLeft();
326 contextMenu.jqxMenu(
"open", parseInt(event.args.originalEvent.clientX) + 5 + scrollLeft, parseInt(event.args.originalEvent.clientY) + 5 + scrollTop);
331 var edit =
function (row, key, newRow, x, y) {
334 dialog.jqxWindow(
"setTitle",
"Edit Row: " + row.name);
335 dialog.jqxWindow(
"setContent", DialogContentHtml);
336 dialog.jqxWindow(
"move", x, y);
338 for (var i in dataFields) {
339 if (dataFields.hasOwnProperty(i)) {
340 var name = dataFields[i].name;
341 var value =
"" + row[name];
342 if (value ===
"undefined") {
345 if (dataFields[i].editable || newRow) {
346 var start =
"<tr><td align=\"right\">" + name +
":</td><td align=\"left\">";
347 var editor =
"<input id=\"" + name +
"_Editor\" type=\"text\" value=\"" + value +
"\" />";
349 var radixObj = GetRadix(value);
351 if (radixObj.radix > 0) {
352 editor =
"<div id=\"" + name +
"_Editor\"><input type=\"text\" /><div></div><div></div></div>";
354 name: name +
"_Editor",
355 value: radixObj.value,
356 radix: radixObj.radix
359 var end =
"</td></tr>";
360 dialog.find(
"tr:last").before(start + editor + end);
362 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>");
366 var content = dialog.find(
"table").parent().html();
367 dialog.jqxWindow(
"setContent", content);
368 for (var ed in jqEditors) {
369 if (jqEditors.hasOwnProperty(ed)) {
370 dialog.find(
"#" + jqEditors[ed].name).jqxFormattedInput({ radix: jqEditors[ed].radix, value: jqEditors[ed].value, width:
"100%", height: 25, upperCase:
true, dropDown:
true, spinButtons:
true });
373 dialog.find(
"#save").jqxButton({ height: 30, width: 80 });
374 dialog.find(
"#cancel").jqxButton({ height: 30, width: 80 });
375 dialog.find(
"#save").mousedown(
function () {
376 dialog.jqxWindow(
"close");
377 RowEditDialogSave(dataFields, newRowId, grid);
379 dialog.find(
"#cancel").mousedown(
function () {
380 dialog.jqxWindow(
"close");
382 dialog.jqxWindow(
"open");
383 var newHeight = $(
"#bottomOfDialog").position().top + 100;
384 dialog.jqxWindow({ height: newHeight });
385 dialog.attr(
"data-row", key);
388 grid.jqxTreeGrid({ disabled:
true });
390 var bitedit =
function (row, key, x, y) {
393 dialog.jqxWindow(
"setTitle",
"Bit Editor for Row: " + row.name);
394 dialog.jqxWindow(
"setContent", DialogContentHtml);
395 dialog.jqxWindow(
"move", x, y);
397 for (var i in dataFields) {
398 if (dataFields.hasOwnProperty(i)) {
399 var name = dataFields[i].name;
400 var value =
"" + row[name];
401 if (value ===
"undefined") {
404 dialog.find(
"tr:last").before(
"<input id=\"" + name +
"_Editor\" type=\"hidden\" value=\"" + value +
"\" />");
405 if (dataFields[i].editable) {
406 var radixObj = GetRadix(value);
407 if (radixObj.radix === 2 || radixObj.radix === 8 || radixObj.radix === 16)
413 var selectHtml =
"<select id=bitFieldSelect>";
414 for (var f in fields) {
415 if (fields.hasOwnProperty(f)) {
416 selectHtml +=
"<option id=" + fields[f] +
" value=\"" + fields[f] +
"\">" + fields[f] +
"</option>";
419 selectHtml +=
"</select>";
420 dialog.find(
"tr:last").before(
"<tr><td colspan=\"2\" align=\"right\">" + selectHtml +
"</td></tr>");
421 dialog.find(
"tr:last").before(
'<tr><td colspan="2" align="right"><div id=bitCheckboxes></div></td></tr>');
423 var content = dialog.find(
"table").parent().html();
424 dialog.jqxWindow(
"setContent", content);
425 dialog.find(
"#bitFieldSelect").change(
function () {
426 var currentValue = dialog.find(
"#" + this.value +
"_Editor").val();
427 var radixObj = GetRadix(currentValue);
428 var length = String(radixObj.value).length;
430 switch (radixObj.radix) {
442 var bitFieldCheckboxHtml =
"<table><tr>";
443 for (var i = 0; i < bits; ++i) {
444 if (i > 0 && i % 4 === 0) {
445 bitFieldCheckboxHtml +=
"</tr><tr>";
447 var checkedStr = (currentValue & (1 << i)) !== 0 ?
"checked" :
"";
448 bitFieldCheckboxHtml +=
"<td><input type=\"checkbox\" name=\"" + i +
"\" class=\"bitFieldCheckBox\"" + checkedStr +
">" + i +
"</input></td>";
450 bitFieldCheckboxHtml +=
"</tr></table>";
451 dialog.find(
"#bitCheckboxes").html(bitFieldCheckboxHtml);
452 var newHeight = $(
"#bottomOfDialog").position().top;
453 dialog.jqxWindow({ height: newHeight });
454 $(
".bitFieldCheckBox").change(
function () {
455 var currentValue = String(dialog.find(
"#" + $(
"#bitFieldSelect").val() +
"_Editor").val());
456 var radixObj = GetRadix(currentValue);
457 var bitId = this.name;
458 var digit, rem, curDigit, mask;
459 switch (radixObj.radix) {
461 currentValue = currentValue.substr(0, currentValue.length - bitId - 1) + (this.checked ?
"1" :
"0") + currentValue.substr(currentValue.length - bitId);
464 digit = Math.floor(bitId / 3);
465 rem = bitId - (digit * 3);
466 curDigit = parseInt(currentValue.charAt(currentValue.length - digit - 1), 8);
468 curDigit = curDigit | (1 << rem);
470 mask = 7 - (1 << rem);
471 curDigit = curDigit & mask;
473 currentValue = currentValue.substr(0, currentValue.length - digit - 1) + curDigit.toString(8) + currentValue.substr(currentValue.length - digit);
476 digit = Math.floor(bitId / 4);
477 rem = bitId - (digit * 4);
478 curDigit = parseInt(currentValue.charAt(currentValue.length - digit - 1), 16);
480 curDigit = curDigit | (1 << rem);
482 mask = 15 - (1 << rem);
483 curDigit = curDigit & mask;
485 currentValue = currentValue.substr(0, currentValue.length - digit - 1) + curDigit.toString(16) + currentValue.substr(currentValue.length - digit);
488 dialog.find(
"#" + $(
"#bitFieldSelect").val() +
"_Editor").val(currentValue);
490 }).trigger(
"change");
491 dialog.find(
"#save").jqxButton({ height: 30, width: 80 });
492 dialog.find(
"#cancel").jqxButton({ height: 30, width: 80 });
493 dialog.find(
"#save").mousedown(
function () {
494 dialog.jqxWindow(
"close");
495 RowEditDialogSave(dataFields, newRowId, grid);
497 dialog.find(
"#cancel").mousedown(
function () {
498 dialog.jqxWindow(
"close");
500 dialog.jqxWindow(
"open");
501 var newHeight = $(
"#bottomOfDialog").position().top;
502 dialog.jqxWindow({ height: newHeight });
503 dialog.attr(
"data-row", key);
506 grid.jqxTreeGrid({ disabled:
true });
508 contextMenu.on(
"itemclick",
function (event) {
509 var args =
event.args;
510 var selection = grid.jqxTreeGrid(
"getSelection");
511 var rowid = selection[0].uid;
512 var text = $.trim($(args).text());
513 if (text ===
"Edit Selected Row") {
514 edit(selection[0], rowid,
false, event.pageX, event.pageY);
515 }
else if (text ===
"Delete Selected Row") {
516 grid.jqxTreeGrid(
"deleteRow", rowid);
517 }
else if (text ===
"Bit Editor") {
518 bitedit(selection[0], rowid, event.pageX, event.pageY);
520 var arrayName =
false;
521 if (rowid.search(/___/) > 0) {
524 grid.jqxTreeGrid(
"addRow", null, {},
"last", rowid);
526 var idx = newRowId.search(/___/);
527 var num = newRowId.slice(idx + 3, -1);
528 num = parseInt(num) + 1;
529 newRowId = newRowId.slice(0, idx + 3) + num;
532 for (var i in dataFields) {
533 if (dataFields.hasOwnProperty(i)) {
534 obj[dataFields[i].name] =
"";
538 edit(obj, newRowId,
true, event.pageX, event.pageY);
543 grid.on(
"cellEndEdit",
function (event) {
544 var args =
event.args;
546 var rowKey = args.key;
548 var rowData = args.row;
549 var path = rowData.name;
550 var currentName = rowKey;
551 var parent = rowData.parent;
553 if ((parent === null || parent === undefined) && currentName.indexOf(
"___") >= 0) {
554 var parentSelector = tag.selector.split(
" ").slice(0, -1).join(
" ");
555 var parentRow = $(parentSelector +
" #treeGrid").jqxTreeGrid(
"getRow", currentName.slice(0, -4));
556 parent = parentRow[0];
558 if (parent !== null && parent !== undefined) {
559 currentName = parent.name;
560 path = parent.name +
"/" + path;
561 parent = parent.parent;
563 }
while (parent !== null && parent !== undefined);
565 if (CurrentCollection && CurrentEntity) {
566 path = CurrentCollection +
"/" + CurrentEntity +
"/" + path;
568 var pathTmp = path.split(
'/');
569 CurrentCollection = pathTmp.shift();
570 CurrentEntity = pathTmp.shift();
572 console.log(
"Path is " + path);
574 var columnDataField = args.dataField;
576 var columnName = args.dataField;
577 for (var i in args.owner._columns) {
578 if (args.owner._columns.hasOwnProperty(i)) {
579 if (args.owner._columns[i].dataField === columnName) {
580 columnName = args.owner._columns[i].text;
585 EditedValues[CurrentCollection +
"/" + CurrentEntity +
"/" + rowKey] =
true;
586 $(
"li.active :visible").parent().addClass(
"editedValue");
588 var value = args.value;
590 AjaxPost(
"/db/Update", {
591 configName: CurrentNamedConfig,
593 column: columnDataField,
598 },
function (retval) {
599 if (retval.Success) {
601 var selector = $(
"#changes", $(
".file-tab.active a").attr(
"href"));
602 selector.val(now.toISOString() +
": Edit - File: " + CurrentCollection +
"/" + CurrentEntity +
", Name: " + rowData.name +
", Column: " + columnName +
", Value: " + value +
"\n" + selector.val());
603 $(
"#masterChanges").val(now.toISOString() +
": Edit - File: " + CurrentCollection +
"/" + CurrentEntity +
", Name: " + rowData.name +
", Column: " + columnName +
", Value: " + value +
"\n" + $(
"#masterChanges").val());
604 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
606 UpdateHeader(
true,
false,
"Sending Update to server failed");
612 function CellClass(row, dataField, cellText, rowData) {
614 for (var val in EditedValues) {
615 if (EditedValues.hasOwnProperty(val)) {
616 if (val === CurrentCollection +
"/" + CurrentEntity +
"/" + rowData.uid) {
617 edited = EditedValues[val];
623 return "editedValue";
628 function TranslateColumns(columns) {
629 var displayColumns = [];
631 for (var c in columns) {
632 if (columns.hasOwnProperty(c)) {
633 var title = columns[c].title;
634 if (title === undefined || title === null || title.length === 0) {
635 title = columns[c].name.charAt(0).toUpperCase() + columns[c].name.slice(1);
637 if (columns[c].type ===
"string" && columns[c].display) {
638 displayColumns.push({
640 dataField: columns[c].name,
641 editable: columns[c].editable,
642 columnGroup: columns[c].columnGroup,
643 createEditor: CreateRowEditor,
644 initEditor: InitRowEditor,
645 getEditorValue: GetRowEditorValue,
646 cellClassName: CellClass
648 }
else if (columns[c].type ===
"number" && columns[c].display) {
649 columns[c].type =
"string";
650 columns[c].dataType =
"number";
651 displayColumns.push({
653 dataField: columns[c].name,
654 editable: columns[c].editable,
655 columnGroup: columns[c].columnGroup,
656 createEditor: CreateRowEditor,
657 initEditor: InitRowEditor,
658 getEditorValue: GetRowEditorValue,
659 cellClassName: CellClass
664 return displayColumns;
667 function LoadTable(tag) {
669 AjaxPost(
"/db/GetData", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId },
function (data) {
671 UpdateHeader(
true,
false,
"Fetch of data from database failed");
674 var columns = data.data.columns;
676 MakeTreeGrid(tag, columns, data.data.children);
681 function GetConfigList() {
682 UpdateHeader(
false,
false,
"");
683 $(
"#masterChanges").val(
"");
685 for (var i = 2; i <= LastTabId; i++) {
686 $(
"#tab" + i).
remove();
687 $(
"#tablink" + i).
remove();
690 $(
"#reloadConfigsButton").text(
"Reload Configurations");
693 AjaxPost(
"/db/NamedConfigs", { configFilter: $(
"#configurationFilter").val(), user: UserId },
function (data) {
695 UpdateHeader(
true,
false,
"Error retrieving Configuration list. Please contact an expert!");
698 $(
"#configs").html(data.data.join(
"")).trigger(
"create").selectmenu(
"refresh");
699 var config = GetUrlParameter(
"configs");
700 if (config !== undefined) {
701 $(
"#configs").val(config);
703 $(
"#oldConfigName").html(data.data.join(
"")).trigger(
"create").selectmenu(
"refresh");
704 $(
"#exportConfigName").html(data.data.join(
"")).trigger(
"create").selectmenu(
"refresh");
706 $(
"#configLoad").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
707 $(
"#configSave").collapsible(
"option",
"disabled",
true).collapsible(
"option",
"collapsed",
true);
708 $(
"#configMetadata").collapsible(
"option",
"disabled",
true).collapsible(
"option",
"collapsed",
true);
709 $(
"#searchConfig").collapsible(
"option",
"disabled",
false);
710 $(
"#exportFile").collapsible(
"option",
"collapsed",
true);
711 $(
"#newConfig").collapsible(
"option",
"collapsed",
true);
714 function RegisterTabFunctions() {
715 $(
".file-tab a").off();
716 $(
".collection-tab a").off();
717 $(
".tabs .tab-links a").off().on(
"click",
function (e) {
718 var currentAttrValue = $(
this).attr(
"href");
719 var tab = $(
this).parent();
720 var div = tab.parent();
722 var left = Math.floor(tab.position().left - 20);
723 div.scrollLeft(left);
725 $(
".tabs " + currentAttrValue).show().siblings().hide();
728 $(
this).parent(
"li").addClass(
"active").siblings().removeClass(
"active");
732 $(
".collection-tab a").on(
"click",
function () {
733 CurrentCollection = $(
this).text();
735 $(
".file-tab a").on(
"click",
function () {
736 var fileName = $(
this).text();
737 CurrentEntity = fileName;
738 LoadFile($(
this).attr(
"href"));
743 function GetUrlParameter(sParam) {
744 var sUrlVariables = window.location.search.substring(1).split(
"&");
746 for (var i = 0; i < sUrlVariables.length; i++) {
747 var sParameterName = sUrlVariables[i].split(
"=");
749 if (sParameterName[0].search(sParam) >= 0) {
751 return sParameterName[1];
757 function LoadConfigMetadata() {
758 console.log(
"Loading configuration metadata");
760 AjaxPost(
"/db/LoadConfigMetadata", { configName: CurrentNamedConfig, user: UserId },
function (metadata) {
761 if (!metadata.Success) {
762 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
765 var metadataObj = metadata.data;
768 var displayColumns = [
775 text:
"Collection Name",
776 dataField:
"collection",
781 dataField:
"version",
785 text:
"Edit", cellsAlign:
"center", align:
"center", columnType:
"none", editable:
false, sortable:
false, dataField: null, cellsRenderer:
function (row) {
787 return "<button data-row='" + row +
"' class='editButtons' onclick=''>Edit</button>";
792 { name:
"name", type:
"string", editable:
false, display:
true },
793 { name:
"collection", type:
"string", editable:
false, display:
true },
794 { name:
"file", type:
"string", editable:
false, display:
false },
795 { name:
"version", type:
"string", editable:
false, display:
true }
799 dataFields: dataFields,
804 localData: metadataObj.entities
807 var dataAdapter =
new $.jqx.dataAdapter(source);
809 var grid = $(
"#configurationEntities");
810 grid.addClass(
"jqxTreeGrid").jqxTreeGrid(
817 columns: displayColumns,
818 rendering:
function () {
820 if ($(
".editButtons").length > 0) {
821 $(
".editButtons").jqxButton(
"destroy");
824 rendered:
function () {
825 if ($(
".editButtons").length > 0) {
826 $(
".editButtons").jqxButton();
828 var editClick =
function (event) {
830 var rowKey =
event.target.getAttribute(
"data-row");
831 var row = grid.jqxTreeGrid(
"getRow", rowKey);
832 var collection = row[
"collection"];
833 var collectionTab = $(
".collection-tab[collection-name=\"" + collection +
"\"] a");
834 collectionTab.trigger(
"click");
835 var file = row[
"name"];
836 var fileNameTab = $(collectionTab[0].hash).find(
".file-tab[file-name=\"" + file +
"\"] a");
837 fileNameTab.trigger(
"click");
839 $(
".editButtons").on(
"click",
function (event) {
850 function AddEntityToFile(
id) {
851 var newEntityName = $(
id +
" #newEntityName").val();
852 $(
id +
" #newEntityName").val(
"");
853 if (newEntityName !==
"") {
854 AjaxPost(
"/db/AddEntityToFile", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId, name: newEntityName },
function (res) {
859 UpdateHeader(
true,
false,
"Error adding Entity to configuration file");
865 function LoadFile(
id) {
867 AjaxPost(
"/db/LoadFileMetadata", { configName: CurrentNamedConfig, entity: CurrentEntity, collection: CurrentCollection, user: UserId },
function (metadata) {
868 if (!metadata.Success) {
869 UpdateHeader(
true,
false,
"Error loading file metadata from database");
872 console.log(
"Loading file metadata");
873 var metadataObj = metadata.data;
874 console.log(metadata);
875 $(
id +
" #metadataCollection").val(metadataObj.collection);
876 $(
id +
" #metadataVersion").val(metadataObj.version);
877 $(
id +
" #changeLog").val(metadataObj.changelog);
879 var displayColumns = [
886 text:
"Date Assigned",
887 dataField:
"assigned",
892 { name:
"name", type:
"string", editable:
false, display:
true },
893 { name:
"assigned", type:
"date", editable:
false, display:
true }
895 var entitiesSource = {
897 dataFields: dataFields,
902 localData: metadataObj.entities
905 var entitiesDataAdapter =
new $.jqx.dataAdapter(entitiesSource);
907 $(
id +
" #metadataEntities").addClass(
"jqxTreeGrid").jqxTreeGrid(
910 source: entitiesDataAdapter,
914 columns: displayColumns
916 var configsSource = {
918 dataFields: dataFields,
923 localData: metadataObj.configurations
926 var configsDataAdapter =
new $.jqx.dataAdapter(configsSource);
928 $(
id +
" #metadataConfigurations").addClass(
"jqxTreeGrid").jqxTreeGrid(
931 source: configsDataAdapter,
935 columns: displayColumns
937 LoadTable($(
id +
" #fileTable"));
941 function SearchCurrentConfig() {
942 console.log(
"Searching Configuration");
944 var searchKey = $(
"#searchKey").val();
945 console.log(
"SearchKey is " + searchKey);
947 AjaxPost(
"/db/SearchLoadedConfig", { configName: CurrentNamedConfig, user: UserId, searchKey: searchKey },
function (results) {
948 if (!results.Success) {
949 UpdateHeader(
true,
false,
"Error searching configuration");
953 MakeTreeGrid($(
"#searchResults"), results.columns, results.collections);
957 function LoadConfig() {
958 console.log(
"Loading Configuration");
959 $(
"#masterChanges").val(
"");
960 UpdateHeader(
false,
false,
"");
961 var selected = $(
"#configs").find(
":selected");
962 if (selected.text() ===
"No Configurations Found" || selected.text() ===
"Click \"Load Configurations\" To Load Configuration Names") {
return; }
963 CurrentNamedConfig = selected.text();
964 $(
"#configName").val(CurrentNamedConfig);
965 for (var i = 2; i <= LastTabId; i++) {
966 $(
"#tab" + i).
remove();
967 $(
"#tablink" + i).
remove();
971 AjaxPost(
"/db/LoadNamedConfig", { configName: CurrentNamedConfig, query: selected.val(), user: UserId },
function (config) {
972 if (!config.Success) {
973 UpdateHeader(
true,
false,
"Error loading configuration files from database");
977 for (var collection in config.collections) {
978 if (config.collections.hasOwnProperty(collection)) {
980 var parentTab = LastTabId;
981 $(
"#tabLinks").append(
"<li id=\"tablink" + LastTabId +
"\"collection-name=\"" + config.collections[collection].name +
"\" tabNum=\"" + LastTabId +
"\" class=\"collection-tab\"><a href=\"#tab" + LastTabId +
"\">" + config
982 .collections[collection].name +
"</a></li>");
983 $(
"#tabContents").append(
"<div id=tab" + LastTabId +
" class=\"tab\"></div>");
984 $(
"#tab" + LastTabId).html(TableHtml);
986 for (var file in config.collections[collection].files) {
987 if (config.collections[collection].files.hasOwnProperty(file)) {
988 var name = config.collections[collection].files[file];
991 $(
"#tab" + parentTab +
" #tabLinks").append(
"<li id=\"tablink" + LastTabId +
"\" file-name=\"" + name +
"\" tabNum=\"" + LastTabId +
"\" class=\"file-tab\"><a href=\"#tab" + LastTabId +
"\">" + name +
"</a></li>");
992 $(
"#tab" + parentTab +
" #tabContents").append(
"<div id=tab" + LastTabId +
" class=\"tab\"></div>");
993 $(
"#tab" + LastTabId).html(InfoHtml).trigger(
"create");;
998 $(
"#configLoad").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
true);
999 $(
"#configSave").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
1000 LoadConfigMetadata();
1001 $(
"#configMetadata").collapsible(
"option",
"disabled",
false).collapsible(
"option",
"collapsed",
false);
1002 $(
"#searchConfig").collapsible(
"option",
"disabled",
false);
1003 RegisterTabFunctions();
1007 function BaseConfig() {
1009 AjaxPost(
"/db/LoadConfigMetadata", { configName: $(
"#oldConfigName :selected").text(), user: UserId },
function (metadata) {
1010 if (!metadata.Success) {
1011 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
1014 var metadataObj = metadata.data;
1017 $(
"#newConfigName").val($(
"#oldConfigName :selected").text());
1018 var tag = $(
"#configurationPicker");
1019 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1020 for (var r in rows) {
1021 if (rows.hasOwnProperty(r)) {
1022 var thisRow = rows[r];
1023 var isChecked =
false;
1024 for (var e in metadataObj.entities) {
1025 if (isChecked)
break;
1026 if (metadataObj.entities.hasOwnProperty(e)) {
1027 var entity = metadataObj.entities[e];
1028 if (thisRow.name === entity.collection) {
1029 for (var r in thisRow.records) {
1030 if (thisRow.records.hasOwnProperty(r)) {
1031 var record = thisRow.records[r];
1032 if (record.id === entity.collection + entity.name) {
1033 tag.find(
"#grid").jqxTreeGrid(
"updateRow", record.uid, { name: entity.name, version: entity.version });
1034 tag.find(
"#grid").jqxTreeGrid(
"checkRow", record.uid);
1043 if (!isChecked && thisRow.checked) {
1044 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", thisRow.uid);
1051 function BaseExportConfig() {
1053 AjaxPost(
"/db/LoadConfigMetadata", { configName: $(
"#exportConfigName :selected").text(), user: UserId },
function (metadata) {
1054 if (!metadata.Success) {
1055 UpdateHeader(
true,
false,
"Error loading configuration metadata from database");
1058 ExportTarFileName = $(
"#exportConfigName :selected").text();
1059 var metadataObj = metadata.data;
1062 var tag = $(
"#filePicker");
1063 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1064 for (var r in rows) {
1065 if (rows.hasOwnProperty(r)) {
1066 var thisRow = rows[r];
1067 var isChecked =
false;
1068 for (var e in metadataObj.entities) {
1069 if (isChecked)
break;
1070 if (metadataObj.entities.hasOwnProperty(e)) {
1071 var entity = metadataObj.entities[e];
1072 if (thisRow.name === entity.collection) {
1073 for (var r in thisRow.records) {
1074 if (thisRow.records.hasOwnProperty(r)) {
1075 var record = thisRow.records[r];
1076 if (record.id === entity.collection + entity.name) {
1077 tag.find(
"#grid").jqxTreeGrid(
"updateRow", record.uid, { name: entity.name, version: entity.version });
1078 tag.find(
"#grid").jqxTreeGrid(
"checkRow", record.uid);
1087 if (!isChecked && thisRow.checked) {
1088 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", thisRow.uid);
1096 function SaveNewConfig() {
1097 console.log(
"Saving New Configuration");
1098 var tag = $(
"#configurationPicker");
1099 var rows = tag.find(
"#grid").jqxTreeGrid(
"getCheckedRows");
1104 for (var r in rows) {
1105 if (rows.hasOwnProperty(r) &&
1106 (typeof rows[r].collection !==
"undefined" && rows[r].collection.length > 0) &&
1107 (typeof rows[r].version !==
"undefined" && rows[r].version.length > 0)) {
1108 configObj.entities.push({ name: rows[r].name, version: rows[r].version, collection: rows[r].collection });
1113 AjaxPost(
"/db/MakeNewConfig", { user: UserId, config: JSON.stringify(configObj), name: $(
"#newConfigName").val() },
function (retval) {
1114 if (retval.Success) {
1115 $(
"#newConfig").collapsible(
"option",
"collapsed",
true);
1118 UpdateHeader(
true,
false,
"MakeNewConfig operation failed.");
1123 function ExportFiles() {
1124 console.log(
"Exporting Files");
1125 var tag = $(
"#filePicker");
1126 var rows = tag.find(
"#grid").jqxTreeGrid(
"getCheckedRows");
1131 for (var r in rows) {
1132 if (rows.hasOwnProperty(r) &&
1133 (typeof rows[r].collection !==
"undefined" && rows[r].collection.length > 0) &&
1134 (typeof rows[r].version !==
"undefined" && rows[r].version.length > 0)) {
1135 configObj.entities.push({ name: rows[r].name, version: rows[r].version, collection: rows[r].collection });
1140 var xhr =
new XMLHttpRequest();
1141 xhr.open(
"POST",
"/db/DownloadConfigurationFile",
true);
1142 xhr.responseType =
"arraybuffer";
1143 xhr.onload =
function () {
1144 if (this.status === 200) {
1146 var disposition = xhr.getResponseHeader(
"Content-Disposition");
1147 if (disposition && disposition.indexOf(
"attachment") !== -1) {
1148 var filenameRegex = /filename[^;=\n]*=(([
'"]).*?\2|[^;\n]*)/;
1149 var matches = filenameRegex.exec(disposition);
1150 if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, "");
1152 var type = xhr.getResponseHeader("Content-Type
");
1154 var blob = new Blob([this.response], { type: type });
1155 if (typeof window.navigator.msSaveBlob !== "undefined
") {
1156 // 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.
"
1157 window.navigator.msSaveBlob(blob, filename);
1159 var url = window.URL || window.webkitURL;
1160 var downloadUrl = url.createObjectURL(blob);
1163 // use HTML5 a[download] attribute to specify filename
1164 var a = document.createElement("a
");
1165 // safari doesn't support this yet
1166 if (typeof a.download === "undefined
") {
1167 window.location = downloadUrl;
1169 a.href = downloadUrl;
1170 a.download = filename;
1171 document.body.appendChild(a);
1175 window.location = downloadUrl;
1178 setTimeout(function () { url.revokeObjectURL(downloadUrl); }, 100); // cleanup
1180 } else if (this.status === 500) {
1181 UpdateHeader(true, false, "An error occurred on the server. Contact an expert
if the situation persists
");
1184 xhr.setRequestHeader("Content-type
", "application/x-www-form-urlencoded
");
1185 xhr.send($.param({ user: UserId, config: JSON.stringify(configObj), tarFileName: ExportTarFileName, type: $("#exportFileFormat :selected
").val() }));
1186 ExportTarFileName = "export
";
1189 function AddRowToFileUploader() {
1190 $("#fileUploader
").find("#grid
").jqxTreeGrid("addRow
", null, {});
1193 function SetupFileUploadTable(tag) {
1194 var displayColumns = [
1197 dataField: "fileName
",
1199 cellClassName: CellClass,
1200 columntype: "template",
1201 initEditor: function (row, cellvalue, editor) {
1202 if (cellvalue === "" || cellvalue === "undefined
" || !cellvalue) {
1203 editor.html("<input type=\
"file\" id=\"fileName\"/>");
1205 editor.text(cellvalue);
1208 getEditorValue:
function (row, cellvalue, editor) {
1210 if (cellvalue ===
"" || cellvalue ===
"undefined" || !cellvalue) {
1211 var fileName = editor.find(
"#fileName")[0];
1212 UploadFiles[row] = fileName.files[0];
1213 return fileName.files[0].name;
1220 dataField:
"fileType",
1222 cellClassName: CellClass,
1223 columntype:
"template",
1224 initEditor:
function (row, cellvalue, editor) {
1226 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 });
1227 editor.jqxDropDownList({ source: versionsAdapter, displayMember:
"name", valueMember:
"value", selectedIndex: 0 }).jqxDropDownList(
"refresh");
1229 editor.jqxDropDownList(
"selectItem", cellvalue);
1231 getEditorValue:
function (row, cellvalue, editor) {
1233 return editor.val();
1238 dataField:
"collection",
1240 cellClassName: CellClass
1243 text:
"Entity Name",
1244 dataField:
"entity",
1246 cellClassName: CellClass
1250 dataField:
"version",
1252 cellClassName: CellClass
1255 text:
"Remove", cellsAlign:
"center", align:
"center", columnType:
"none", editable:
false, sortable:
false, dataField: null, cellsRenderer:
function (row) {
1257 return "<button data-row='" + row +
"' class='removeButtons' onclick=''>Remove</button>";
1262 tag.html(
"<div id=\"grid\" class=\"jqxTreeGrid\"></div><br>");
1265 { name:
"id", type:
"string", editable:
false, display:
false },
1266 { name:
"fileName", type:
"string", editable:
true, display:
true },
1267 { name:
"fileType", type:
"string", editable:
true, display:
true },
1268 { name:
"collection", type:
"string", editable:
true, display:
true },
1269 { name:
"entity", type:
"string", editable:
true, display:
true },
1270 { name:
"version", type:
"string", editable:
true, display:
true }
1274 dataFields: dataFields,
1282 var dataAdapter =
new $.jqx.dataAdapter(source);
1284 tag.find(
"#grid").jqxTreeGrid({
1286 source: dataAdapter,
1289 columnsResize:
true,
1290 columns: displayColumns,
1291 rendering:
function () {
1293 if ($(
".removeButtons").length > 0) {
1294 $(
".removeButtons").jqxButton(
"destroy");
1297 rendered:
function () {
1298 if ($(
".removeButtons").length > 0) {
1299 $(
".removeButtons").jqxButton();
1301 var removeClick =
function (event) {
1303 var rowKey =
event.target.getAttribute(
"data-row");
1304 delete UploadFiles[rowKey];
1305 tag.find(
"#grid").jqxTreeGrid(
"deleteRow", rowKey);
1307 $(
".removeButtons").on(
"click",
function (event) {
1317 function SetupReader(file) {
1318 var f = UploadFiles[file];
1319 var r =
new FileReader();
1321 r.onload =
function (e) {
1322 var contents = e.target.result;
1323 var thisfile = e.target.fileid;
1324 var row = $(
"#fileUploader").find(
"#grid").jqxTreeGrid(
"getRow", thisfile);
1325 console.log(
"Calling AjaxPost with parameters: Collection: " +
1332 row.fileType +
", fileName: " + row.fileName +
", file.name: " + f.name);
1335 AjaxPost(
"/db/UploadConfigurationFile",
1338 collection: row.collection,
1339 version: row.version,
1346 UpdateHeader(
true,
false,
"File upload failed");
1348 console.log(
"Upload: " + row.fileName +
" returned: " + JSON.stringify(res));
1350 delete UploadFiles[thisfile];
1356 function UploadFhiclFile() {
1357 $(
"#uploadFhiclFileButton").text(
"Uploading... Please Wait.");
1359 var didAnything =
false;
1360 for (var file in UploadFiles) {
1361 if (UploadFiles.hasOwnProperty(file)) {
1363 var f = UploadFiles[file];
1365 var row = $(
"#fileUploader").find(
"#grid").jqxTreeGrid(
"getRow", file);
1367 alert(
"Failed to load file");
1371 if (row.fileType ===
"fhicl" && f.name.search(
".fcl") === -1) {
1372 alert(f.name +
" is not a valid fhicl file.");
1376 if (row.fileType ===
"json" && f.name.search(
".json") === -1) {
1377 alert(f.name +
" is not a valid json file.");
1381 if ((row.fileType !==
"fhicl" &&
1382 row.fileType !==
"json") ||
1383 row.collection ===
"" ||
1384 row.version ===
"" ||
1385 row.entity ===
"") {
1386 alert(f.name +
" missing needed metadata");
1396 $(
"#uploadFile").collapsible(
"option",
"collapsed",
true);
1397 $(
"#uploadFhiclFileButton").text(
"Store File(s) In Database");
1399 setTimeout(
function () { UploadFhiclFile(); }, 1000);
1403 function SetupEntityVersionPicker(tag) {
1405 AjaxGet(
"/db/EntitiesAndVersions",
function (data) {
1406 console.log(JSON.stringify(data));
1407 if (!data.Success) {
1408 UpdateHeader(
true,
false,
"Error retrieving entities and versions lists. Please contact an expert!");
1411 var collectionsObj = data.collections;
1413 var collectionNames = [];
1414 for (var c in collectionsObj) {
1415 if (collectionsObj.hasOwnProperty(c)) {
1416 var collection = [];
1417 var entitiesObj = collectionsObj[c];
1418 for (var e in entitiesObj.entities) {
1419 if (entitiesObj.entities.hasOwnProperty(e)) {
1420 var entity = entitiesObj.entities[e];
1422 var search = entity.versions.search;
1423 for (var v in search) {
1424 if (search.hasOwnProperty(v)) {
1425 versions.push({ name: search[v].name });
1428 collection.push({
id: entitiesObj.name + entity.name, name: entity.name, collection: entity.collection, edited:
false, version: versions[0].name, versions: versions });
1431 dataObj.push({
id: entitiesObj.name, name: entitiesObj.name, entities: collection });
1432 collectionNames.push(entitiesObj.name);
1436 var displayColumns = [
1438 text:
"Entity Name",
1441 cellClassName: CellClass
1445 dataField:
"version",
1447 columntype:
"template",
1448 initEditor:
function (rowKey, cellvalue, editor) {
1449 var row = tag.find(
"#grid").jqxTreeGrid(
"getRow", rowKey);
1452 for (var r in dataObj) {
1453 if (dataObj.hasOwnProperty(r)) {
1454 if (row.id.indexOf(dataObj[r].name) === 0) {
1460 var localData = dataObj[index1];
1461 for (var rr in localData.entities) {
1462 if (localData.entities.hasOwnProperty(rr)) {
1463 if (row.id === localData.entities[rr].id) {
1469 var versionsSource = { datatype:
"array", datafields: [{ name:
"name", type:
"string" }], localdata: dataObj[index1].entities[index2].versions };
1471 var versionsAdapter =
new $.jqx.dataAdapter(versionsSource, { autoBind:
true });
1472 editor.jqxDropDownList({ source: versionsAdapter, displayMember:
"name", valueMember:
"name", selectedIndex: 0 }).jqxDropDownList(
"refresh");
1476 editor.jqxDropDownList(
"selectItem", cellvalue);
1478 getEditorValue:
function (row, cellvalue, editor) {
1480 return editor.val();
1482 cellClassName: CellClass
1486 tag.html(
"<br><button type=\"button\" class=\"miniButton\" id=\"all1\"> Select All </button><button type=\"button\" class=\"miniButton\" id=\"none1\"> Select None </button><br>" +
1487 "<div id=\"grid\" class=\"jqxTreeGrid\"></div><br>" +
1488 "<button type=\"button\" class=\"miniButton\" id=\"all2\"> Select All </button><button type=\"button\" class=\"miniButton\" id=\"none2\"> Select None </button>");
1490 tag.find(
"#none1").jqxButton({ height: 30 });
1491 tag.find(
"#all1").jqxButton({ height: 30 });
1492 tag.find(
"#none2").jqxButton({ height: 30 });
1493 tag.find(
"#all2").jqxButton({ height: 30 });
1496 { name:
"id", type:
"string", editable:
false, display:
false },
1497 { name:
"name", type:
"string", editable:
false, display:
true },
1498 { name:
"version", type:
"string", editable:
true, display:
true },
1499 { name:
"versions", type:
"array", editable:
false, display:
false },
1500 { name:
"edited", type:
"boolean", editable:
false, display:
false },
1501 { name:
"entities", type:
"array", editable:
false, display:
false }
1505 dataFields: dataFields,
1513 var dataAdapter =
new $.jqx.dataAdapter(source);
1515 tag.find(
"#grid").jqxTreeGrid({
1517 source: dataAdapter,
1520 columnsResize:
true,
1522 hierarchicalCheckboxes:
true,
1523 columns: displayColumns
1525 for (var n in collectionNames) {
1526 if (collectionNames.hasOwnProperty(n)) {
1527 tag.find(
"#grid").jqxTreeGrid(
"lockRow", collectionNames[n]);
1533 tag.find(
"#none1").mousedown(
function () {
1534 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1535 for (var r in rows) {
1536 if (rows.hasOwnProperty(r)) {
1537 if (rows[r].checked) {
1538 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", rows[r].uid);
1543 tag.find(
"#all1").mousedown(
function () {
1544 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1545 for (var r in rows) {
1546 if (rows.hasOwnProperty(r)) {
1547 if (!rows[r].checked) {
1548 tag.find(
"#grid").jqxTreeGrid(
"checkRow", rows[r].uid);
1553 tag.find(
"#none2").mousedown(
function () {
1554 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1555 for (var r in rows) {
1556 if (rows.hasOwnProperty(r)) {
1557 if (rows[r].checked) {
1558 tag.find(
"#grid").jqxTreeGrid(
"uncheckRow", rows[r].uid);
1564 tag.find(
"#all2").mousedown(
function () {
1565 var rows = tag.find(
"#grid").jqxTreeGrid(
"getRows");
1566 for (var r in rows) {
1567 if (rows.hasOwnProperty(r)) {
1568 if (!rows[r].checked) {
1569 tag.find(
"#grid").jqxTreeGrid(
"checkRow", rows[r].uid);
1577 function SaveConfig() {
1578 console.log(
"Saving Configuration Changes");
1580 $(
".file-tab.editedValue a")
1582 var log = $(
"#changes", $(
this).attr(
"href")).val();
1583 var collection = $(
"#metadataCollection", $(
this).attr(
"href")).val();
1585 var rows = $(
"#metadataEntities", $(
this).attr(
"href")).jqxTreeGrid(
'getRows');
1586 for (var i = 0; i < rows.length; i++) {
1588 entities.push(rows[i].name);
1590 var version = $(
"#metadataVersion", $(
this).attr(
"href")).val();
1591 files.push({ entities: entities, changelog: log, collection: collection, version: version });
1594 AjaxPost(
"/db/saveConfig",
1596 oldConfigName: CurrentNamedConfig,
1597 newConfigName: $(
"#configName").val(),
1602 if (res !== null && res !== undefined && res.Success) {
1603 UpdateHeader(
false,
false,
"Configuration Saved.");
1606 UpdateHeader(
true,
false,
"Failed to save configuration!");
1612 function DiscardConfig() {
1613 console.log(
"Discarding Configuration Changes");
1615 $(
".file-tab.editedValue").each(
function () {
1616 files.push({ name: $(
this).text() });
1619 AjaxPost(
"/db/discardConfig", { configName: CurrentNamedConfig, files: files, user: UserId },
function (res) {
1623 UpdateHeader(
true,
false,
"Failed to discard configuration. Make sure you have a valid configuration selected.\nIf this problem persists, call an expert.");
1629 function GetDbConfig() {
1631 AjaxGet(
"/db/getDbConfig",
1634 $(
"#dbType").val(data.dbprovider).trigger(
"change");
1635 $(
"#baseDir").val(data.baseDir);
1636 $(
"#databases").html(data.data.join(
"")).trigger(
"create").selectmenu(
"refresh");
1637 var database = GetUrlParameter(
"database");
1638 if (database !== undefined && database !==
"") {
1639 $(
"#databases").val(database).trigger(
"change");
1641 $(
"#databases").val(data.instanceName).trigger(
"change");
1648 function UpdateDbConfig() {
1650 dbprovider: $(
"#dbType").val(),
1651 baseDir: $(
"#baseDir").val(),
1652 instanceName: $(
"#databases").val()
1655 AjaxPost(
"/db/updateDbConfig",
1663 "Failed to update Database Module Configuration. Please See server logs for more details.");
1669 function MakeNewDatabase() {
1670 var newDBName = { name: $(
"#newDatabaseName").val() };
1671 AjaxPost(
"/db/makeNewDBInstance",
1672 newDBName,
function (res) {
1676 UpdateHeader(
true,
false,
"Failed to create new Database Instance. Please see server logs for more details.");
1682 function RegisterButtonFunctions() {
1683 $(
"#loadConfigButton").on(
"click",
function () { LoadConfig(); });
1684 $(
"#getConfigListButton").on(
"click",
function () { GetConfigList(); });
1685 $(
"#saveConfigButton").on(
"click",
function () { SaveConfig(); });
1686 $(
"#discardConfigButton").on(
"click",
function () { DiscardConfig(); });
1687 $(
"#searchCurrentConfigButton").on(
"click",
function () { SearchCurrentConfig(); });
1688 $(
"#baseConfigButton").on(
"click",
function () { BaseConfig(); });
1689 $(
"#saveNewConfigButton").on(
"click",
function () { SaveNewConfig(); });
1690 $(
"#baseExportConfigButton").on(
"click",
function () { BaseExportConfig(); });
1691 $(
"#exportFilesButton").on(
"click",
function () { ExportFiles(); });
1692 $(
"#addRowToFileUploaderButton").on(
"click",
function () { AddRowToFileUploader(); });
1693 $(
"#uploadFhiclFileButton").on(
"click",
function () { UploadFhiclFile(); });
1694 $(
"#updateDBConfigButton").on(
"click",
function () { UpdateDbConfig(); });
1695 $(
"#createNewDatabaseButton").on(
"click",
function () { MakeNewDatabase(); });
1702 var debounce =
function (func, threshold, execAsap) {
1705 return function debounced() {
1706 var obj =
this, args = arguments;
1707 function delayed() {
1709 func.apply(obj, args);
1714 clearTimeout(timeout);
1716 func.apply(obj, args);
1718 timeout = setTimeout(delayed, threshold || 100);
1723 jQuery.fn[sr] =
function (fn) {
return fn ? this.bind(
"resize", debounce(fn)) : this.trigger(sr); };
1725 })(jQuery,
"smartresize");
1727 $(document).ready(
function () {
1728 DefaultColor = $(
"#header").css(
"background-color");
1729 DefaultShadow = $(
"#header").css(
"text-shadow");
1731 $.get(
"/db/Tables.html",
function (data) {
1735 $.get(
"/db/FileInfo.html",
function (data) {
1739 $.get(
"/db/TreeGrid.html",
function (data) {
1740 TreeGridHtml = data;
1743 $.get(
"/db/Dialog.html",
function (data) { DialogContentHtml = data; });
1745 $(
".configInfo-tab").on(
"click",
function () {
1749 RegisterTabFunctions();
1750 $(
".tabs #tab1").show().siblings().hide();
1752 $(
".triggersModified").change(
function () {
1753 UpdateHeader(
false,
true,
"There are pending unsaved changes. Please save or discard before closing the editor!");
1756 $(window).smartresize(
function () {
1757 $(
".jqxTreeGrid").jqxTreeGrid({ width:
"100%" }).jqxTreeGrid(
"refresh");
1760 $(
"#newConfig").on(
"collapsibleexpand",
function () {
1761 SetupEntityVersionPicker($(
"#configurationPicker"));
1764 $(
"#exportFile").on(
"collapsibleexpand",
function () {
1765 SetupEntityVersionPicker($(
"#filePicker"));
1769 .on(
"collapsibleexpand",
1771 SetupFileUploadTable($(
"#fileUploader"));
1774 $(
"#dbType").on(
"change",
function () {
1775 var dbtype = $(
"#dbType").val();
1776 if (dbtype ===
"filesystem") {
1777 $(
"#filesystemdbConfig").show();
1778 $(
"#mongodbConfig").hide();
1779 }
else if (dbtype ===
"mongo") {
1780 $(
"#filesystemdbConfig").hide();
1781 $(
"#mongodbConfig").show();
1783 }).trigger(
"change");
1785 $(
"#databases").on(
"change",
function () {
1786 var instanceName = $(
"#databases").val();
1787 if (instanceName ===
"NONE") {
1788 $(
"#newDatabaseFS").show();
1790 $(
"#newDatabaseFS").hide();
1793 }).trigger(
"change");
1797 RegisterButtonFunctions();