From 539095c89e11ff79213f2f537c34ce812b06ce3f Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Thu, 28 Mar 2019 14:59:35 +0400 Subject: [PATCH] partially restored commits page --- .../ulstu/configuration/MvcConfiguration.java | 2 +- src/main/resources/public/css/odin.css | 226 +++ src/main/resources/public/js/config.js | 10 + src/main/resources/public/js/core.js | 6 +- src/main/resources/public/js/odin.js | 1512 +++++++++++++++++ src/main/resources/public/templates/odin.html | 165 ++ src/main/resources/templates/default.html | 5 + 7 files changed, 1922 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/public/css/odin.css create mode 100644 src/main/resources/public/js/config.js create mode 100644 src/main/resources/public/js/odin.js create mode 100644 src/main/resources/public/templates/odin.html diff --git a/src/main/java/ru/ulstu/configuration/MvcConfiguration.java b/src/main/java/ru/ulstu/configuration/MvcConfiguration.java index 3e8d66f..c704596 100644 --- a/src/main/java/ru/ulstu/configuration/MvcConfiguration.java +++ b/src/main/java/ru/ulstu/configuration/MvcConfiguration.java @@ -10,7 +10,7 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/{articlename:\\w+}"); - //registry.addViewController("/admin/{articlename:\\w+}"); + registry.addViewController("/admin/{articlename:\\w+}"); registry.addViewController("/papers/{articlename:\\w+}"); registry.addViewController("/grants/{articlename:\\w+}"); registry.addViewController("/conferences/{articlename:\\w+}"); diff --git a/src/main/resources/public/css/odin.css b/src/main/resources/public/css/odin.css new file mode 100644 index 0000000..2bfeb75 --- /dev/null +++ b/src/main/resources/public/css/odin.css @@ -0,0 +1,226 @@ +.odin-unselectable { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.odin-kill-padding { + padding: 0; +} + +.odin-input-group { + padding-left: 15px !important; + padding-right: 15px !important; +} + +.odin-closable .fa { + font-size: 1.5em; + margin-top: -1px; +} + +.odin-closable .fa:hover:before { + content: "\f057"; +} + +/* + Odin Toolbar +*/ +.odin-toolbar { + padding-left: 1px; + padding-bottom: 4px; +} + +.odin-toolbar .odin-btn { + float: none !important; +} + +.odin-btn { + min-width: 112px; + margin-right: 3px; +} + +@media (min-width: 768px) { + .odin-btn { + min-width: 150px; + } +} + +/* + Odin Paginator +*/ +.odin-paginator { + margin: 0; + margin-top: 5px; + text-align: center; +} + +.odin-paginator-content { + display: inline-block; +} + +.odin-paginator-content a { + cursor: pointer; + color: black; + float: left; + padding: 6px 16px; + text-decoration: none; + transition: background-color .3s; + border-radius: 4px; +} + +.odin-paginator-content i { + color: black; + float: left; + padding: 6px 16px; +} + +.odin-paginator-content a.active { + background-color: #4CAF50; + color: white; +} + +.odin-paginator-content a:hover:not(.active) { + background-color: #ddd; +} + +/* + Odin Formatters +*/ +.odin-negative { + color: red; + font-weight: bold; +} + +/* + Odin Table +*/ +.odin-table { + min-height: 324px; + border: 1px solid #ddd; + padding: 0; + margin: 0 0 0 1px; + background-color: #f8f8f8; +} + +.odin-table > table { + margin-bottom: 0; +} + +.odin-table > table > tbody > tr { + background-color: #fff; +} + +.odin-table-pointed-line { + cursor: pointer; +} + +.odin-table-selected-line { + background-color: #5bc0de !important; +} + +.odin-table-selected-line:hover { + background-color: #6bd0ee !important; +} + +/* + Odin Form + */ +.odin-form { + display: none; + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: 1500; + background: rgba(0, 0, 0, 0.5); +} + +.odin-form .panel { + position: relative; + max-height: 95%; + max-width: 95%; + overflow: auto; +} + +@media (min-width: 768px) { + .odin-form .panel { + max-width: 55%; + } +} + +.odin-form .panel-footer { + padding: 5px 7px; +} + +.odin-form .odin-btn { + float: right; +} + +.odin-checkbox { + width: 20px; + height: 20px; +} + +.odin-form .tab-pane { + padding-top: 5px; +} + +/* + Odin Confirm Box + */ +.odin-confirm-box { + display: none; + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: 2000; + background: rgba(0, 0, 0, 0.5); +} + +.odin-confirm-box .panel { + position: relative; + max-width: 95%; +} + +.odin-confirm-box .panel-footer { + text-align: center; +} + +@media (min-width: 768px) { + .odin-confirm-box .panel { + max-width: 25%; + } +} + +.odin-confirm-box .panel-body { + text-align: center; +} + +/* + Odin Table Box + */ +.odin-table-box { + z-index: 2500; +} + +/* + Odin Simple Box + */ + +@media (min-width: 768px) { + .odin-simple-form .panel { + max-width: 35%; + } +} \ No newline at end of file diff --git a/src/main/resources/public/js/config.js b/src/main/resources/public/js/config.js new file mode 100644 index 0000000..353180b --- /dev/null +++ b/src/main/resources/public/js/config.js @@ -0,0 +1,10 @@ +/* exported contextPath */ +var contextPath = ""; +var apiVersion = "/api/1.0"; + +var basePath = contextPath + apiVersion; + +/* exported urlVersions */ +var urlVersions = basePath + "/versions"; +/* exported urlCommits */ +var urlCommits = basePath + "/commits"; \ No newline at end of file diff --git a/src/main/resources/public/js/core.js b/src/main/resources/public/js/core.js index 216f411..2d6ff62 100644 --- a/src/main/resources/public/js/core.js +++ b/src/main/resources/public/js/core.js @@ -88,12 +88,12 @@ function getFromRest(url, callBack, errorCallBack) { } /* exported getFromRestWithVersion */ -function getFromRestWithVersion(url, callBack, errorCallBack) { - getFromRestWithVersionAndParams(url, "", callBack, errorCallBack); +function getFromRest(url, callBack, errorCallBack) { + getFromRestWithParams(url, "", callBack, errorCallBack); } /* exported getFromRestWithVersionAndParams */ -function getFromRestWithVersionAndParams(url, params, callBack, errorCallBack) { +function getFromRestWithParams(url, params, callBack, errorCallBack) { getCurrentVersion(function (version) { $.ajax({ url: url + "?versionId=" + version + params, diff --git a/src/main/resources/public/js/odin.js b/src/main/resources/public/js/odin.js new file mode 100644 index 0000000..384c496 --- /dev/null +++ b/src/main/resources/public/js/odin.js @@ -0,0 +1,1512 @@ +// form config.js +/* global uiLocale, urlVersions */ +// from core.js +/* global isEmpty, deleteFromRest, fillSelect, MessageTypesEnum, showFeedbackMessage, getCurrentVersionData */ +/* global getFromRestWithVersionAndParams, getFromRestWithVersion, getFromRest */ +/* global postToRestWithVersionAndParams, putToRestWithVersionAndParams */ + +// TODO: settings for table selection mode (single, multiple) + +var odinMetaList = "/meta/list"; +var odinMetaElement = "/meta/element"; +var odinCopy = "/copy-from-version"; + +/* exported OdinTableWithMeta */ +function OdinTableWithMeta(divId, dataUrl, disableCopy) { + return OdinTableWithMetaAndParams(divId, dataUrl, "", disableCopy, ""); +} + +/* exported OdinTableWithMetaAndGlobalCallback */ +function OdinTableWithMetaAndGlobalCallback(divId, dataUrl, disableCopy, globalSaveCallback, globalSelectCallback) { + return OdinTableWithMetaAndParams(divId, dataUrl, "", disableCopy, globalSaveCallback, globalSelectCallback); +} + +/* exported OdinTableWithMetaAndParams */ +function OdinTableWithMetaAndParams(divId, dataUrl, params, disableCopy, globalSaveCallback, globalSelectCallback) { + return new OdinTable(divId, dataUrl + odinMetaList, dataUrl + odinMetaElement, dataUrl, + params, disableCopy, globalSaveCallback, globalSelectCallback); +} + +function OdinTable(divId, listMetaDataUrl, elementMetaDataUrl, dataUrl, params, disableCopy, globalSaveCallback, globalSelectCallback) { + var CLICK_DELAY = 250; + var DATA_ATTR = "odin-data"; + var DATA_VIEW_ATTR = "odin-data-view"; + var TYPE_ATTR = "type"; + var ID_ATTR = "id"; + var DISABLED_ATTR = "disabled"; + var REQUIRED_ATTR = "required"; + var LABELS_SELECTOR = "label"; + var INPUTS_SELECTOR = ":input"; + var BUTTONS_SELECTOR = ":button"; + var CHECKED_ATTR = "checked"; + var NOT_CHECKED_ATTR = ""; + var PAGINATOR_ITEMS_PER_PAGE = 10; + var PAGINATOR_VISIBLE_BUTTONS_COUNT = 3; + var odinTable; + + var L10nEnum = { + VIEW: "Наименование", + COLLECTION: "Коллеция объектов", + GO_TO: "Перейти", + + BUTTON_ADD: "Добавить", + BUTTON_CREATE: "Создать", + BUTTON_EDIT: "Изменить", + BUTTON_DELETE: "Удалить", + + BUTTON_COPY: "Копировать", + + BUTTON_OK: "Продолжить", + BUTTON_CANCEL: "Отмена", + + BUTTON_SAVE: "Записать", + BUTTON_CLOSE: "Закрыть", + + CAPTION_CREATE_FORM: "Новый элемент", + CAPTION_EDIT_FORM: "(редактирование)", + CAPTION_CHOOSE_FORM: "Выбор объекта", + CAPTION_COPY_FORM: "Копирование данных", + CAPTION_DEFAULT_TAB: "Реквизиты", + CPATION_FORM_DEFAULT: "...", + + QUESTION_LOST_CHANGES: "Закрыть без сохранения?", + QUESTION_DELETE_ITEM: "Выполнить удаление?", + QUESTION_DEFAULT_CAPTION: "Продолжит?", + + ERROR_VERSIONS_MATCH: "Версии совпадают" + }; + Object.freeze(L10nEnum); + + var FieldTypesEnum = { + BOOLEAN: "boolean", + DATE: "date", + NUMERIC: "numeric", + STRING: "string", + COLLECTION: "collection", + OBJECT: "object" + }; + Object.freeze(FieldTypesEnum); + + var DateTypesEnum = { + DATETIME: "datetime", + DATE: "date", + TIME: "time" + }; + Object.freeze(DateTypesEnum); + + var StringTypesEnum = { + STRING: "string", + PASSWORD: "password", + TEXT: "text", + EMAIL: "email", + HREF: "href" + }; + Object.freeze(StringTypesEnum); + + var VisibleTypesEnum = { + ALL: "all", + ON_CREATE: "on_create", + ON_UPDATE: "on_update", + NONE: "none" + }; + Object.freeze(VisibleTypesEnum); + + var InputTypesEnum = { + CHECKBOX: "checkbox", + PASSWORD: "password", + TEXT: "text", + EMAIL: "email", + DATE: "date", + DATETIME: "datetime-local", + TIME: "time", + NUMBER: "number", + HIDDEN: "hidden", + SUBMIT: "submit" + }; + Object.freeze(InputTypesEnum); + + var FormTypesEnum = { + FORM: "form", + CONFIRM: "confirm", + SIMPLE: "simple" + }; + Object.freeze(FormTypesEnum); + + var NumberAttrEnum = { + MIN: "min", + MAX: "max", + STEP: "step" + }; + Object.freeze(NumberAttrEnum); + + var StringAttrEnum = { + MIN: "minlength", + MAX: "maxlength" + }; + Object.freeze(StringAttrEnum); + + $(document.body).append("
"); + $("#odinTemplates").load("/templates/odin.html", function () { + $("#" + divId).append("
" + + " " + + "
"); + odinTable = new OdinTableMain(divId, listMetaDataUrl, elementMetaDataUrl, dataUrl, params, disableCopy, globalSaveCallback, globalSelectCallback); + }); + + this.getSelectedItems = function () { + return odinTable.getSelectedItems(); + } + + function format(str, args) { + if (isEmpty(str) || isEmpty(args)) { + return str; + } + if (!Array.isArray(args)) { + throw "Odin: Format args is not array"; + } + return str.replace(/\{(\d+)\}/g, + function (match, number) { + return typeof args[number] !== "undefined" ? + args[number] : match; + }); + } + + function centerDiv(component) { + if (isEmpty(component)) { + return; + } + component.offset({ + top: ($(window).height() - component.height()) / 2, + left: ($(window).width() - component.width()) / 2 + }); + } + + function tmpl(id) { + var html = $("#odinTemplates").find("#" + id).html(); + if (isEmpty(html)) { + throw "Odin: Template load error"; + } + var template = format(html.trim(), Array.prototype.slice.call(arguments, 1)); + return $(template); + } + + function find(object, selector) { + var result = object.find(selector); + if (isEmpty(result)) { + throw "Can't find elements by selector " + selector; + } + return result; + } + + function findFiltered(object, selector, notSelector) { + var result = object.find(selector).not(notSelector); + if (isEmpty(result)) { + throw "Can't find elements by selector " + selector; + } + return result; + } + + function OdinFormCommon(type) { + var BUTTON_CLOSE_SELECTOR = "i.fa"; + var CAPTION_SELECTOR = "#caption"; + var PANEL_SELECTOR = ".panel"; + var FORM_INPUTS_SELECTOR = ":input"; + var DATA_CHANGED_ATTR = "changed"; + + var form; + var header; + var content; + var footer; + + var createForm = function () { + switch (type) { + case FormTypesEnum.FORM: + form = tmpl("form"); + break; + case FormTypesEnum.CONFIRM: + form = tmpl("formConfirm"); + break; + default: + form = tmpl("formSimple"); + } + if (isEmpty(form)) { + throw "Odin: Unknown form type"; + } + header = createFormHeader(); + content = createFormContent(); + footer = createFormFooter(); + var formPanel = tmpl("formPanel"); + formPanel.append(header); + formPanel.append(content); + formPanel.append(footer); + form.append(formPanel); + setCaption(L10nEnum.CPATION_FORM_DEFAULT); + $(document.body).append(form); + }; + + var createFormHeader = function () { + var fHeader = tmpl("formHeader"); + fHeader.find(BUTTON_CLOSE_SELECTOR).click(function () { + hideForm(); + }); + return fHeader; + }; + + var createFormContent = function () { + return tmpl("formContent"); + }; + + var createFormFooter = function () { + return tmpl("formFooter"); + }; + + var setCaption = function (caption) { + if (isEmpty(caption)) { + throw "Odin: Caption is not set"; + } + find(header, CAPTION_SELECTOR).text(caption); + }; + + var addFormClass = function (clazz) { + if (isEmpty(clazz)) { + throw "Odin: Additional class is not set"; + } + form.addClass(clazz); + }; + + var isModified = function () { + return form.data(DATA_CHANGED_ATTR); + }; + + var setFormSubmit = function (callBack) { + if (isEmpty(callBack)) { + throw "Odin: Callback is not set"; + } + form.submit(function () { + callBack(); + return false; + }); + }; + + var showForm = function () { + form.show(0, function () { + centerDiv(find(form, PANEL_SELECTOR)); + }); + if (type === FormTypesEnum.FORM) { + find(form, FORM_INPUTS_SELECTOR).change(function () { + form.data(DATA_CHANGED_ATTR, true); + }); + } + }; + + var hideForm = function () { + var callBack = function () { + form.hide(); + form.remove(); + }; + callBack(); + }; + + this._getHeader = function () { + return header; + }; + + this._getContent = function () { + return content; + }; + + this._getFooter = function () { + return footer; + }; + + this._setCaption = function (caption) { + setCaption(caption); + }; + + this._setFormSubmit = function (callBack) { + setFormSubmit(callBack); + }; + + this._addFormClass = function (clazz) { + addFormClass(clazz); + }; + + this._isModified = function () { + return isModified(); + }; + + this._show = function () { + showForm(); + }; + + this._hide = function () { + hideForm(); + }; + + createForm(); + } + + function OdinToolbar(tableDiv, createCallBack, editCallBack, deleteCallBack) { + var SELECTOR_ODIN_TABLE = ".odin-table"; + + var toolbar; + + var createButton; + var editButton; + var deleteButton; + + var initialize = function () { + if (isEmpty(tableDiv)) { + throw "Odin-Toolbar: Target div is not set"; + } + var table = find(tableDiv, SELECTOR_ODIN_TABLE); + toolbar = tmpl("toolbar"); + toolbar.insertBefore(table, null); + if (!isEmpty(createCallBack)) { + createButton = tmpl("createButton", L10nEnum.BUTTON_CREATE); + createButton.click(function () { + createCallBack(); + }); + toolbar.append(createButton); + } + if (!isEmpty(editCallBack)) { + editButton = tmpl("editButton", L10nEnum.BUTTON_EDIT); + editButton.click(function () { + editCallBack(); + }); + setEditButtonState(false); + toolbar.append(editButton); + } + if (!isEmpty(deleteCallBack)) { + deleteButton = tmpl("deleteButton", L10nEnum.BUTTON_DELETE); + deleteButton.click(function () { + deleteCallBack(); + }); + setDeleteButtonState(false); + toolbar.append(deleteButton); + } + }; + + var setEditButtonState = function (state) { + if (isEmpty(editButton)) { + return; + } + editButton.attr("disabled", !state); + }; + + var setDeleteButtonState = function (state) { + if (isEmpty(deleteButton)) { + return; + } + deleteButton.attr("disabled", !state); + }; + + this.addButton = function (caption, callBack) { + if (isEmpty(caption) || isEmpty(callBack)) { + throw "Odin-Toolbar: Caption or callback is not set"; + } + var button = tmpl("basicButton", caption); + button.click(function () { + callBack(); + }); + toolbar.append(button); + }; + + this.setEditButtonState = function (state) { + setEditButtonState(state); + }; + + this.setDeleteButtonState = function (state) { + setDeleteButtonState(state); + }; + + initialize(); + } + + function OdinPaginator(tableDiv, callBack) { + var SELECTOR_PAGINATOR_CONTENT = ".odin-paginator-content"; + var SELECTOR_PAGINATOR_BUTTON = "a"; + var PAGINATOR_BUTTON_PREFIX = "odin-paginator-"; + var PAGINATOR_SELECTED_BUTTON_CLASS = "active"; + + var initialize = function () { + if (isEmpty(tableDiv)) { + throw "Odin-Paginator: Target div is not set"; + } + if (isEmpty(callBack)) { + throw "Odin-Paginator: Callback is not set"; + } + tableDiv.append(tmpl("paginator")); + }; + + var drawPaginator = function (data, offset) { + var paginatorContentDiv = find(tableDiv, SELECTOR_PAGINATOR_CONTENT); + paginatorContentDiv.empty(); + if (isEmpty(data)) { + return; + } + $.each(data, function (index, value) { + if (value.name) { + paginatorContentDiv.append(tmpl("paginatorButton", value.offset, value.name)); + } else { + paginatorContentDiv.append(tmpl("paginatorSeparator")); + } + }); + var buttons = find(paginatorContentDiv, SELECTOR_PAGINATOR_BUTTON); + buttons.removeClass("active"); + buttons.click(function () { + $('#preloader').show(); + var offset = $(this).attr(ID_ATTR).replace(PAGINATOR_BUTTON_PREFIX, ""); + callBack(offset); + }); + find(paginatorContentDiv, "#" + PAGINATOR_BUTTON_PREFIX + offset) + .addClass(PAGINATOR_SELECTED_BUTTON_CLASS); + }; + + this.drawPaginator = function (offset, count) { + var currentOffset = parseInt(offset ? offset : "0"); + var buttonCount = Math.floor( + count <= PAGINATOR_ITEMS_PER_PAGE ? 0 : count / PAGINATOR_ITEMS_PER_PAGE) + + (count < PAGINATOR_ITEMS_PER_PAGE || + count % PAGINATOR_ITEMS_PER_PAGE === 0 ? 0 : 1); + var data = []; + Array.apply(0, Array(buttonCount)).forEach(function (element, index) { + if (index > 0 && index < buttonCount - 1 && + buttonCount > PAGINATOR_VISIBLE_BUTTONS_COUNT * 2) { + if (index === currentOffset - PAGINATOR_VISIBLE_BUTTONS_COUNT || + index === currentOffset + PAGINATOR_VISIBLE_BUTTONS_COUNT + 1) { + data.push({ + "offset": null, + "name": null + }); + } + if (index <= currentOffset - PAGINATOR_VISIBLE_BUTTONS_COUNT || + index > currentOffset + PAGINATOR_VISIBLE_BUTTONS_COUNT) { + return true; + } + } + data.push({ + "offset": index, + "name": index + 1 + }); + }); + drawPaginator(data, currentOffset); + }; + + initialize(); + } + + function OdinTableFormatter() { + var BOOLEAN_TRUE_CLASS = "fa-check"; + var BOOLEAN_FALSE_CLASS = "fa-times"; + + var formatBooleanValue = function (value) { + return tmpl("tableBoolean", (value ? BOOLEAN_TRUE_CLASS : BOOLEAN_FALSE_CLASS)); + }; + + var formatDateValue = function (value, dateType) { + var date = new Date(value); + var formatterSettings = {}; + switch (dateType) { + case DateTypesEnum.DATETIME: + formatterSettings = { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric" + }; + break; + case DateTypesEnum.TIME: + formatterSettings = { + hour: "numeric", + minute: "numeric", + second: "numeric" + }; + break; + } + var dateFormatter = new Intl.DateTimeFormat(uiLocale, formatterSettings); + return dateFormatter.format(date); + }; + + var formatNumericValue = function (value, positiveOnly, scale) { + var numberFormatter = new Intl.NumberFormat(uiLocale, { + useGrouping: false, + minimumFractionDigits: scale + }); + var formattedValue = numberFormatter.format(value); + if (positiveOnly && value < 0) { + return tmpl("tableNumericNegative", formattedValue); + } + return formattedValue; + }; + + var formatStringValue = function (value, maxLength, stringType) { + switch (stringType) { + case StringTypesEnum.HREF: + return tmpl("anchor", value, L10nEnum.GO_TO); + default: + if (isEmpty(maxLength) || maxLength === 0) { + return value; + } + return value.substring(0, Math.min(value.length, maxLength)); + } + }; + + this.formatValue = function (value, fieldParams) { + if (isEmpty(value) || isEmpty(fieldParams)) { + return ""; + } + if (fieldParams.hidden) { + return value; + } + switch (fieldParams.fieldType) { + case FieldTypesEnum.BOOLEAN: + return formatBooleanValue(value); + case FieldTypesEnum.DATE: + return formatDateValue(value, fieldParams.type); + case FieldTypesEnum.NUMERIC: + return formatNumericValue(value, fieldParams.positiveOnly, fieldParams.scale); + case FieldTypesEnum.STRING: + return formatStringValue(value, fieldParams.maxLength, fieldParams.type); + case FieldTypesEnum.COLLECTION: + return L10nEnum.COLLECTION; + case FieldTypesEnum.OBJECT: + return value.view; + default: + return value; + } + }; + } + + function OdinTableView(odinDiv, editCallback, globalSelectCallback) { + var TABLEVIEW_SELECTED_LINE_CLASS = "odin-table-selected-line"; + var TABLEVIEW_LINE_SELECTOR = "tr"; + var TABLEVIEW_SELECTED_LINE_SELECTOR = TABLEVIEW_LINE_SELECTOR + + "." + TABLEVIEW_SELECTED_LINE_CLASS; + var TABLEVIEW_LINE_DATA_SELECTOR = TABLEVIEW_LINE_SELECTOR + + "[" + DATA_ATTR + "=\"{0}\"]"; + var TABLEVIEW_CHOOSABLE_CLASS = "table-hover odin-unselectable"; + var TABLEVIEW_LINE_POINTED_CLASS = "odin-table-pointed-line"; + var TABLEVIEW_HEAD_COLUMN_SELECTOR = "th:nth-child({0})"; + var TABLEVIEW_BODY_COLUMN_SELECTOR = "td:nth-child({0})"; + + var tTable; + var tHead; + var tBody; + var choosable; + var formatter; + var toolbar; + + var createLine = function (idValue) { + var prevent = false; + var timer = 0; + var newLine = tmpl("tableLine"); + if (!isEmpty(idValue) && choosable) { + newLine.attr(DATA_ATTR, idValue); + newLine.click(function () { + var btn = $(this); + timer = setTimeout(function () { + if (!prevent) { + btn.toggleClass(TABLEVIEW_SELECTED_LINE_CLASS); + } + prevent = false; + if (!isEmpty(globalSelectCallback)) { + globalSelectCallback(getLines()); + } + if (!isEmpty(toolbar)) { + toolbar.setEditButtonState(!isEmpty(getLines())); + toolbar.setDeleteButtonState(!isEmpty(getLines())); + } + }, CLICK_DELAY); + }); + if (!isEmpty(editCallback)) { + newLine.dblclick(function () { + clearTimeout(timer); + prevent = true; + editCallback(idValue); + }); + } + newLine.addClass(TABLEVIEW_LINE_POINTED_CLASS); + } + return newLine; + }; + + var addLineToHead = function (line) { + tHead.append(line); + }; + + var addLineToBody = function (line) { + tBody.append(line); + }; + + var clearBody = function () { + tBody.empty(); + }; + + var initialize = function () { + if (isEmpty(odinDiv)) { + throw "Odin: Odin div is not set"; + } + odinDiv.append(tmpl("table")); + tTable = find(odinDiv, "table"); + tHead = find(odinDiv, "thead"); + tBody = find(odinDiv, "tbody"); + formatter = new OdinTableFormatter(); + }; + + var getLines = function (isAll) { + var selector = isAll ? TABLEVIEW_LINE_SELECTOR : TABLEVIEW_SELECTED_LINE_SELECTOR; + var selectedItems = []; + try { + find(tBody, selector).each(function () { + selectedItems.push({ + id: $(this).attr(DATA_ATTR), + view: $(this).attr(DATA_VIEW_ATTR) + }); + }); + } catch (e) { + // Ignore + } + return selectedItems; + }; + + var disableToolbar = function () { + if (isEmpty(toolbar)) { + return; + } + toolbar.setEditButtonState(false); + toolbar.setDeleteButtonState(false); + }; + + this.createHead = function (metaData, isOdinDto) { + if (isEmpty(metaData)) { + throw "Odin: Metadata is not set"; + } + choosable = isOdinDto; + if (choosable) { + tTable.addClass(TABLEVIEW_CHOOSABLE_CLASS); + } + var tHeadLine = createLine(); + $.each(metaData, function (index, value) { + tHeadLine.append(tmpl("tableHeadColumn", value.caption)); + }); + addLineToHead(tHeadLine); + $.each(metaData, function (columnIndex, columnParams) { + if (columnParams.visible === VisibleTypesEnum.NONE) { + var index = columnIndex + 1; + find(tHead, format(TABLEVIEW_HEAD_COLUMN_SELECTOR, [index])).hide(); + } + }); + }; + + this.fillBody = function (metaData, data) { + clearBody(); + $.each(data, function (index, value) { + var idValue = choosable ? value.id : null; + var line = createLine(idValue); + line.attr(DATA_VIEW_ATTR, value.view); + $.each(metaData, function (columnIndex, columnParams) { + var column = tmpl("tableBodyColumn"); + column.append( + formatter.formatValue(value[columnParams.fieldName], + columnParams)); + line.append(column); + }); + addLineToBody(line); + }); + if (!isEmpty(data)) { + $.each(metaData, function (columnIndex, columnParams) { + if (columnParams.visible === VisibleTypesEnum.NONE) { + var index = columnIndex + 1; + find(tBody, format(TABLEVIEW_BODY_COLUMN_SELECTOR, [index])).hide(); + } + }); + } + }; + + this.getSelectedItems = function () { + return getLines(false); + }; + + this.getItems = function () { + return getLines(true); + }; + + // Delete form view only! + this.deleteById = function (id) { + if (isEmpty(id)) { + return; + } + try { + find(tBody, format(TABLEVIEW_LINE_DATA_SELECTOR, [id])).remove(); + disableToolbar(); + } catch (e) { + // Ignore + } + }; + + this.setToolbar = function (toolbarVar) { + toolbar = toolbarVar; + }; + + this.disableToolbar = function () { + disableToolbar(); + }; + + initialize(); + } + + function OdinTableMain(divId, listMetaDataUrl, elementMetaDataUrl, dataUrl, args, disableCopy, globalSaveCallback, globalSelectCallback) { + if (isEmpty(divId) || isEmpty(listMetaDataUrl) || isEmpty(dataUrl)) { + throw "Odin: Not enough parameters"; + } + + var OFFSET_ARG = "&offset="; + var COUNT_ARG = "&count="; + + var odinDiv; + var tableView; + var paginator; + + var currentOffset; + + var listMetaData; + var elementMetaData; + + var params = isEmpty(args) ? "" : args; + + var drawBody = function (offset) { + if (isEmpty(listMetaData)) { + throw "Odin: Meta data is not defined"; + } + currentOffset = isEmpty(offset) ? 0 : parseInt(offset); + getFromRestWithVersionAndParams(dataUrl, + OFFSET_ARG + (currentOffset * PAGINATOR_ITEMS_PER_PAGE) + + COUNT_ARG + PAGINATOR_ITEMS_PER_PAGE + params, function (data) { + if (isEmpty(data)) { + throw "Odin: Response data is null"; + } + tableView.fillBody(listMetaData, data.items); + if (data.count > 0) { + paginator.drawPaginator(offset, data.count); + } + tableView.disableToolbar(); + $('#preloader').hide(); + }); + }; + + var initialize = function () { + odinDiv = find($(document.body), "#" + divId); + tableView = new OdinTableView(odinDiv, editItem, globalSelectCallback); + paginator = new OdinPaginator(odinDiv, drawBody); + getFromRest(listMetaDataUrl, function (data) { + if (isEmpty(data) || isEmpty(data.fields)) { + throw "Odin: Can't load list meta data"; + } + var isOdinDto = data.odinDto; + listMetaData = data.fields; + if (isOdinDto && !isEmpty(elementMetaDataUrl)) { + getFromRest(elementMetaDataUrl, function (data) { + if (isEmpty(data) || isEmpty(data.fields)) { + throw "Odin: Can't load element meta data"; + } + elementMetaData = data.fields; + var toolbar = new OdinToolbar(odinDiv, createItem, editItem, deleteItem, globalSaveCallback); + tableView.setToolbar(toolbar); + if (!disableCopy) { + toolbar.addButton(L10nEnum.BUTTON_COPY, function () { + new OdinCopyBox(dataUrl, drawBody); + }); + } + }); + } + tableView.createHead(listMetaData, isOdinDto); + drawBody(); + }); + }; + + var updateTable = function () { + // TODO: recalculate offset before redraw table + drawBody(currentOffset); + }; + + var createItem = function () { + new OdinForm(elementMetaData, dataUrl, updateTable, null, params); + }; + + var editItem = function (value) { + if (isEmpty(elementMetaDataUrl)) { + return; + } + var curValue = value; + if (isEmpty(value)) { + var selectedItems = tableView.getSelectedItems(); + if (!isEmpty(selectedItems)) { + curValue = selectedItems[0].id; + } + } + if (isEmpty(curValue)) { + return; + } + new OdinForm(elementMetaData, dataUrl, updateTable, curValue, params); + }; + + var deleteItem = function () { + var selectedItems = tableView.getSelectedItems(); + if (isEmpty(selectedItems)) { + return; + } + var callBack = function () { + $.each(selectedItems, function (index, value) { + deleteFromRest(dataUrl + "/" + value.id, null, function () { + if (index === selectedItems.length - 1) { + updateTable(); + } + }); + }); + }; + new OdinConfirmBox(callBack, L10nEnum.QUESTION_DELETE_ITEM); + }; + + this.getSelectedItems = function () { + return tableView.getSelectedItems(); + }; + + initialize(); + } + + function OdinFormControlGenerator() { + this.createInputGroup = function () { + return tmpl("formInputGroup"); + }; + + this.createLabel = function (id, caption) { + return tmpl("formLabel", id, caption); + }; + + var createInput = function (id, value, type) { + if (isEmpty(id)) { + throw "Odin: Input id is not set"; + } + if (isEmpty(type)) { + throw "Odin: Input type is not set"; + } + var curValue = isEmpty(value) ? "" : value; + var wrapper = tmpl("formInputWrapper"); + if (type === InputTypesEnum.CHECKBOX) { + wrapper.append(tmpl("formInputCheckbox", + id, (curValue ? CHECKED_ATTR : NOT_CHECKED_ATTR))); + } else { + wrapper.append(tmpl("formInput", + id, curValue, type)); + } + return wrapper; + }; + + this.createBooleanInput = function (id, value) { + return createInput(id, value, InputTypesEnum.CHECKBOX); + }; + + var fixDateUnit = function (dateUnitValue) { + return dateUnitValue < 10 ? "0" + dateUnitValue : dateUnitValue; + }; + + var dateToStr = function (value, type) { + if (isEmpty(value)) { + return ""; + } + var date = new Date(value); + var year = fixDateUnit(date.getFullYear()); + var month = fixDateUnit(date.getMonth() + 1); + var day = fixDateUnit(date.getDate()); + var hour = fixDateUnit(date.getHours()); + var minute = fixDateUnit(date.getMinutes()); + var formattedDate; + switch (type) { + case DateTypesEnum.DATETIME: + formattedDate = year + "-" + month + "-" + day + "T" + hour + ":" + minute; + break; + case DateTypesEnum.TIME: + formattedDate = hour + ":" + minute; + break; + default: + formattedDate = year + "-" + month + "-" + day; + } + return formattedDate; + }; + + this.createDateInput = function (id, value, type) { + var dateType; + switch (type) { + case DateTypesEnum.DATETIME: + dateType = InputTypesEnum.DATETIME; + break; + case DateTypesEnum.TIME: + dateType = InputTypesEnum.TIME; + break; + default: + dateType = InputTypesEnum.DATE; + } + return createInput(id, dateToStr(value, type), dateType); + }; + + this.createNumericInput = function (id, value) { + return createInput(id, value, InputTypesEnum.NUMBER); + }; + + this.createStringInput = function (id, value, type) { + var stringType; + switch (type) { + case StringTypesEnum.PASSWORD: + stringType = InputTypesEnum.PASSWORD; + break; + case StringTypesEnum.EMAIL: + stringType = InputTypesEnum.EMAIL; + break; + default: + stringType = InputTypesEnum.TEXT; + } + return createInput(id, value, stringType); + }; + + this.dateToStr = function (value, type) { + return dateToStr(value, type); + }; + } + + function OdinFormContentGenerator(createNavTabCallBack, isCreateOperation) { + var PRECISION_CHAR = "9"; + var SCALE_PREFIX = "0."; + var SCALE_CHAR = "0"; + var SCALE_POSTFIX = "1"; + var OBJECT_INPUT_CLASS = "input-group odin-input-group"; + var CREATE_BUTTON_TEXT_SELECTOR = ".btn-success > span"; + var CHOOSE_BTN_SELECTOR = ".odin-choose-btn"; + var CLEAR_BTN_SELECTOR = ".odin-clear-btn"; + var CLEARABLE_INPUT_SELECTOR = ".form-control"; + + var controlGenerator = new OdinFormControlGenerator(); + + var createBooleanControl = function (id, caption, value) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + group.append(controlGenerator.createBooleanInput(id, value)); + return group; + }; + + var createDateControl = function (id, caption, value, type) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + group.append(controlGenerator.createDateInput(id, value, type)); + return group; + }; + + var createNumericControl = function (id, caption, value, positiveOnly, precision, scale) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + var control = controlGenerator.createNumericInput(id, value); + find(control, INPUTS_SELECTOR).each(function () { + var currentControl = $(this); + if (positiveOnly) { + currentControl.attr(NumberAttrEnum.MIN, 0); + } + if (precision) { + currentControl + .attr(NumberAttrEnum.MAX, Array(precision + 1).join(PRECISION_CHAR)); + } + if (scale) { + var step = SCALE_PREFIX + Array(scale).join(SCALE_CHAR) + SCALE_POSTFIX; + currentControl.attr(NumberAttrEnum.STEP, step); + } + }); + group.append(control); + return group; + }; + + var createStringControl = function (id, caption, value, minLength, maxLength, type) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + var control = controlGenerator.createStringInput(id, value, type); + find(control, INPUTS_SELECTOR).each(function () { + var currentControl = $(this); + currentControl.attr(StringAttrEnum.MIN, minLength); + currentControl.attr(StringAttrEnum.MAX, maxLength); + }); + group.append(control); + return group; + }; + + var createCollectionControl = function (id, caption, values, path) { + // TODO: add required check if needed + var content = $(tmpl("emptyDiv")); + var tabView = new OdinTableView(content, null, null); + var createAction = function () { + new OdinChooseBox(path, function (selectedItems) { + if (isEmpty(selectedItems)) { + return; + } + var currentValues = tabView.getItems(); + $.merge(currentValues, selectedItems); + var existingIDs = []; + currentValues = $.grep(currentValues, function (v) { + if ($.inArray(v.id, existingIDs) !== -1) { + return false; + } else { + existingIDs.push(v.id); + return true; + } + }); + tabView.fillBody(metaData, currentValues); + }); + }; + var deleteAction = function () { + var callBack = function () { + $.each(tabView.getSelectedItems(), function (index, value) { + tabView.deleteById(value.id); + }); + }; + new OdinConfirmBox(callBack, L10nEnum.QUESTION_DELETE_ITEM); + }; + content.append(tabView); + var metaData = [ + { + "fieldType": "string", + "fieldName": "id", + "caption": "id", + "visible": "none" + }, + { + "fieldType": "string", + "fieldName": "view", + "caption": L10nEnum.VIEW, + "visible": "all" + } + ]; + tabView.createHead(metaData, true); + tabView.fillBody(metaData, values); + createNavTabCallBack(id, caption, content); + var toolbar = new OdinToolbar(content, createAction, null, deleteAction); + tabView.setToolbar(toolbar); + find(content, CREATE_BUTTON_TEXT_SELECTOR).text(L10nEnum.BUTTON_ADD); + return null; + }; + + var createObjectControl = function (id, caption, value, path) { + // TODO: add required check if needed + var chooseInput = controlGenerator.createStringInput( + id, isEmpty(value) ? "" : value.view, StringTypesEnum.TEXT); + chooseInput.addClass(OBJECT_INPUT_CLASS); + var buttonGroup = tmpl("buttonGroup"); + chooseInput.append(buttonGroup); + var chooseButton = tmpl("chooseButton"); + buttonGroup.append(chooseButton); + find(buttonGroup, CHOOSE_BTN_SELECTOR).click(function () { + new OdinChooseBox(path, function (selectedItems) { + if (isEmpty(selectedItems)) { + return; + } + find(chooseInput, CLEARABLE_INPUT_SELECTOR).each(function () { + $(this) + .val(selectedItems[0].view) + .attr(DATA_ATTR, selectedItems[0].id); + }); + }); + }); + var clearButton = tmpl("clearButton"); + buttonGroup.append(clearButton); + find(buttonGroup, CLEAR_BTN_SELECTOR).click(function () { + find(chooseInput, CLEARABLE_INPUT_SELECTOR).val(""); + }); + find(chooseInput, CLEARABLE_INPUT_SELECTOR).each(function () { + $(this) + .attr(DISABLED_ATTR, true) + .attr(DATA_ATTR, isEmpty(value) ? "" : value.id); + }); + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + group.append(chooseInput); + return group; + }; + + var configureControl = function (control, hidden, readonly, notempty) { + if (isEmpty(control)) { + return; + } + find(control, LABELS_SELECTOR).each(function () { + var currentControl = $(this); + if (hidden) { + currentControl.hide(); + } + }); + find(control, INPUTS_SELECTOR).each(function () { + var currentControl = $(this); + if (hidden) { + currentControl.hide(); + currentControl.attr(TYPE_ATTR, InputTypesEnum.HIDDEN); + } + if (readonly) { + currentControl.attr(DISABLED_ATTR, true); + } + if (notempty) { + currentControl.attr(REQUIRED_ATTR, true); + } + }); + return control; + }; + + this.createFormControl = function (value, fieldParams) { + if (isEmpty(fieldParams)) { + return null; + } + var control; + switch (fieldParams.fieldType) { + case FieldTypesEnum.BOOLEAN: + control = createBooleanControl(fieldParams.fieldName, + fieldParams.caption, value); + break; + case FieldTypesEnum.DATE: + control = createDateControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.type); + break; + case FieldTypesEnum.NUMERIC: + control = createNumericControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.positiveOnly, + fieldParams.precision, fieldParams.scale); + break; + case FieldTypesEnum.STRING: + control = createStringControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.minLength, + fieldParams.maxLength, fieldParams.type); + break; + case FieldTypesEnum.COLLECTION: + control = createCollectionControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.path); + break; + case FieldTypesEnum.OBJECT: + control = createObjectControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.path); + break; + default: + return null; + } + var hidden; + switch (fieldParams.visible) { + case VisibleTypesEnum.NONE: + hidden = true; + break; + case VisibleTypesEnum.ON_CREATE: + case VisibleTypesEnum.ON_UPDATE: + hidden = isCreateOperation; + break; + default: + hidden = false; + } + return configureControl(control, hidden, fieldParams.readOnly, fieldParams.notEmpty); + }; + + this.getCurrentDateStr = function () { + return controlGenerator.dateToStr(new Date(), DateTypesEnum.DATE); + }; + } + + function OdinForm(metaData, dataUrl, tableCallBack, id, args) { + if (isEmpty(metaData) || isEmpty(dataUrl) || isEmpty(tableCallBack)) { + throw "Odin: Not enough parameters"; + } + + var DEFAULT_TAB_SELECTOR = "odin-values"; + var TABS_HEADER_SELECTOR = ".nav-tabs"; + var TABS_CONTENT_SELECTOR = ".tab-content"; + var TAB_SELECTOR = ".tab-pane"; + var COLLECTION_ITEM_SELECTOR = "tbody > tr"; + + OdinFormCommon.call(this, FormTypesEnum.FORM); + + var self = this; + + var generator; + + var params = isEmpty(args) ? "" : args; + + var isCreateForm = function () { + return isEmpty(id); + }; + + var formToJson = function () { + var formData = {}; + try { + findFiltered(self._getContent(), TAB_SELECTOR, "#" + DEFAULT_TAB_SELECTOR) + .each(function () { + var tabData = []; + try { + find($(this), COLLECTION_ITEM_SELECTOR) + .each(function () { + if ($(this).attr(DATA_ATTR)) { + tabData.push({ + id: $(this).attr(DATA_ATTR), + view: $(this).attr(DATA_VIEW_ATTR) + }); + return true; + } + }); + } catch (e) { + // Ignore + } + formData[$(this).attr(ID_ATTR)] = tabData; + }); + } catch (e) { + // Ignore + } + findFiltered(self._getContent(), INPUTS_SELECTOR, BUTTONS_SELECTOR) + .each(function () { + if (isEmpty($(this).val())) { + return true; + } + if ($(this).attr(DATA_ATTR)) { + formData[$(this).attr(ID_ATTR)] = { + id: $(this).attr(DATA_ATTR), + view: $(this).val() + }; + return true; + } + switch ($(this).attr(TYPE_ATTR)) { + case InputTypesEnum.CHECKBOX: + formData[$(this).attr(ID_ATTR)] = $(this).is(":" + CHECKED_ATTR); + break; + case InputTypesEnum.DATE: + case InputTypesEnum.DATETIME: + formData[$(this).attr(ID_ATTR)] = isEmpty($(this).val) ? + "" : Date.parse($(this).val()); + break; + case InputTypesEnum.TIME: + formData[$(this).attr(ID_ATTR)] = isEmpty($(this).val) ? + "" : Date.parse(generator.getCurrentDateStr() + + "T" + $(this).val()); + break; + case InputTypesEnum.NUMBER: + formData[$(this).attr(ID_ATTR)] = parseFloat($(this).val()); + break; + default: + formData[$(this).attr(ID_ATTR)] = $(this).val(); + } + }); + return JSON.stringify(formData); + }; + + var initialize = function () { + generator = new OdinFormContentGenerator(createNavTab, isCreateForm()); + self._getContent() + .append(tmpl("formTabs", DEFAULT_TAB_SELECTOR, L10nEnum.CAPTION_DEFAULT_TAB)); + var okBtn = tmpl("okButton", L10nEnum.BUTTON_SAVE); + okBtn.attr(TYPE_ATTR, InputTypesEnum.SUBMIT); + var closeBtn = tmpl("cancelButton", L10nEnum.BUTTON_CLOSE); + self._getFooter().append(closeBtn); + self._getFooter().append(okBtn); + if (isCreateForm()) { + configureAndShowForm(); + } else { + getFromRestWithVersion(dataUrl + "/" + id, function (data) { + if (isEmpty(data)) { + throw format("Odin: Can't load data by id {0} and url {1}", [id, dataUrl]); + } + configureAndShowForm(data); + }); + } + closeBtn.click(function () { + closeForm(); + }); + }; + + var configureAndShowForm = function (data) { + var saveCallBack = function () { + saveData(formToJson()); + }; + self._setCaption(isEmpty(data) ? + L10nEnum.CAPTION_CREATE_FORM : + data.view + " " + L10nEnum.CAPTION_EDIT_FORM); + self._setFormSubmit(saveCallBack); + $.each(metaData, function (fieldIndex, fieldParams) { + var value = isEmpty(data) ? + null : data[fieldParams.fieldName]; + find(self._getContent(), "#" + DEFAULT_TAB_SELECTOR) + .append(generator.createFormControl(value, fieldParams)); + }); + self._show(); + }; + + var createNavTab = function (id, caption, content) { + find(self._getContent(), TABS_HEADER_SELECTOR).append(tmpl("formTab", id, caption)); + var tab = tmpl("formTabContent", id); + tab.append(content); + find(self._getContent(), TABS_CONTENT_SELECTOR).append(tab); + }; + + var saveData = function (data) { + var saveCallback = function (responseData) { + if (isEmpty(responseData)) { + throw "Odin: Error on data save"; + } + self._hide(); + tableCallBack(); + if (!isEmpty(globalSaveCallback)) { + globalSaveCallback(); + } + }; + if (isCreateForm()) { + postToRestWithVersionAndParams(dataUrl, data, params, saveCallback); + } else { + putToRestWithVersionAndParams(dataUrl, data, params, saveCallback); + } + }; + + var closeForm = function () { + if (self._isModified()) { + new OdinConfirmBox(self._hide, L10nEnum.QUESTION_LOST_CHANGES); + return; + } + self._hide(); + }; + + initialize(); + } + + function OdinConfirmBox(callBack, questionText) { + if (isEmpty(callBack) || isEmpty(questionText)) { + throw "Odin: Not enough parameters"; + } + + OdinFormCommon.call(this, FormTypesEnum.CONFIRM); + + var self = this; + + var initialize = function () { + var yesBtn = tmpl("okButton", L10nEnum.BUTTON_OK); + var cancelBtn = tmpl("cancelButton", L10nEnum.BUTTON_CANCEL); + self._setCaption(L10nEnum.QUESTION_DEFAULT_CAPTION); + self._getContent().text(questionText); + self._getFooter().append(yesBtn); + self._getFooter().append(cancelBtn); + self._show(); + + yesBtn.click(function () { + self._hide(); + callBack(); + if (!isEmpty(globalSaveCallback)) { + globalSaveCallback(); + } + }); + cancelBtn.click(function () { + self._hide(); + }); + }; + + initialize(); + } + + function OdinChooseBox(path, callBack) { + if (isEmpty(path) || isEmpty(callBack)) { + throw "Odin: Not enough parameters"; + } + + var ADDITIONAL_FORM_CLASS = "odin-table-box"; + var ADDITIONAL_CONTENT_CLASS = "odin-kill-padding"; + var CONTENT_ID_VALUE = "table-block"; + + OdinFormCommon.call(this); + + var self = this; + + var initialize = function () { + self._addFormClass(ADDITIONAL_FORM_CLASS); + self._getContent().addClass(ADDITIONAL_CONTENT_CLASS); + self._getContent().attr(ID_ATTR, CONTENT_ID_VALUE); + var yesBtn = tmpl("okButton", L10nEnum.BUTTON_OK); + var cancelBtn = tmpl("cancelButton", L10nEnum.BUTTON_CANCEL); + self._getFooter().append(cancelBtn); + self._getFooter().append(yesBtn); + var table = new OdinTableMain("table-block", path + odinMetaList, null, path); + self._show(); + + yesBtn.click(function () { + self._hide(); + callBack(table.getSelectedItems()); + }); + cancelBtn.click(function () { + self._hide(); + }); + }; + + initialize(); + } + + function OdinCopyBox(dataUrl, tableRedrawCallback) { + if (isEmpty(dataUrl) || isEmpty(tableRedrawCallback)) { + throw "Odin: Not enough parameters"; + } + + var ADDITIONAL_FORM_CLASS = "odin-simple-form"; + var FROM_VERSION_SELECTOR = "#fromVersion"; + var VERSION_SELECTOR = "#version"; + + OdinFormCommon.call(this); + + var self = this; + + var initialize = function () { + self._setCaption(L10nEnum.CAPTION_COPY_FORM); + self._addFormClass(ADDITIONAL_FORM_CLASS); + self._getContent().append(tmpl("copyForm")); + var from = find(self._getContent(), FROM_VERSION_SELECTOR); + var to = find(self._getContent(), VERSION_SELECTOR); + var yesBtn = tmpl("okButton", L10nEnum.BUTTON_OK); + var cancelBtn = tmpl("cancelButton", L10nEnum.BUTTON_CANCEL); + self._getFooter().append(cancelBtn); + self._getFooter().append(yesBtn); + + getFromRest(urlVersions, function (versions) { + if (isEmpty(versions) || versions.count === 0) { + return; + } + var versionsData = []; + versions.items.forEach(function (version) { + versionsData.push({ + id: version.id, + name: version.name + " от " + + new Date(version.date).toLocaleDateString(uiLocale) + }); + }); + fillSelect(from, versionsData.sort(function (a, b) { + return a.id - b.id; + })); + var currentVersion = getCurrentVersionData(); + if (!isEmpty(currentVersion)) { + to.attr(DATA_ATTR, currentVersion.id); + to.val(currentVersion.name); + } + self._show(); + }); + + yesBtn.click(function () { + if (isEmpty(from.val()) || isEmpty(to.val())) { + return; + } + if (from.val() === to.attr(DATA_ATTR)) { + showFeedbackMessage(L10nEnum.ERROR_VERSIONS_MATCH, MessageTypesEnum.DANGER); + return; + } + postToRestWithVersionAndParams(dataUrl + odinCopy, null, + "&fromVersionId=" + from.val(), function () { + self._hide(); + tableRedrawCallback(); + }); + }); + cancelBtn.click(function () { + self._hide(); + }); + }; + + initialize(); + } +} diff --git a/src/main/resources/public/templates/odin.html b/src/main/resources/public/templates/odin.html new file mode 100644 index 0000000..1f9f9d9 --- /dev/null +++ b/src/main/resources/public/templates/odin.html @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/default.html b/src/main/resources/templates/default.html index 9aae873..00e2c0f 100644 --- a/src/main/resources/templates/default.html +++ b/src/main/resources/templates/default.html @@ -23,6 +23,7 @@ + @@ -94,6 +95,10 @@ + + + +