Repository: incubator-ignite Updated Branches: refs/heads/ignite-843 5c2784eb0 -> 9672838ea
IGNITE-843: Meta validation and fix meta + cache selection. Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/9672838e Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/9672838e Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/9672838e Branch: refs/heads/ignite-843 Commit: 9672838ea773f94f7b3beda6305d89f43ee044f0 Parents: 5c2784e Author: AKuznetsov <akuznet...@gridgain.com> Authored: Tue Aug 18 16:53:37 2015 +0700 Committer: AKuznetsov <akuznet...@gridgain.com> Committed: Tue Aug 18 16:53:37 2015 +0700 ---------------------------------------------------------------------- .../main/js/controllers/metadata-controller.js | 106 ++++++++++++------- .../main/js/controllers/models/metadata.json | 21 +++- modules/control-center-web/src/main/js/db.js | 1 + .../main/js/views/configuration/metadata.jade | 8 +- .../src/main/js/views/includes/controls.jade | 22 ++-- .../src/main/js/views/login.jade | 4 +- 6 files changed, 100 insertions(+), 62 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9672838e/modules/control-center-web/src/main/js/controllers/metadata-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/metadata-controller.js b/modules/control-center-web/src/main/js/controllers/metadata-controller.js index cf69262..17ed895 100644 --- a/modules/control-center-web/src/main/js/controllers/metadata-controller.js +++ b/modules/control-center-web/src/main/js/controllers/metadata-controller.js @@ -44,6 +44,8 @@ controlCenterModule.controller('metadataController', [ $scope.compactJavaName = $common.compactJavaName; + $scope.hidePopover = $common.hidePopover; + var presets = [ { db: 'oracle', @@ -329,66 +331,90 @@ controlCenterModule.controller('metadataController', [ $scope.backupItem = {space: $scope.spaces[0]._id}; }; + function queryConfigured(item) { + return !($common.isEmptyArray(item.queryFields) + && $common.isEmptyArray(item.ascendingFields) + && $common.isEmptyArray(item.descendingFields) + && $common.isEmptyArray(item.textFields) + && $common.isEmptyArray(item.groups)) + } + + function storeConfigured(item) { + return !($common.isEmptyString(item.databaseSchema) + && $common.isEmptyString(item.databaseTable) + && $common.isEmptyArray(item.keyFields) + && $common.isEmptyArray(item.valueFields)) + } + // Check metadata logical consistency. function validate(item) { - /* - if (!$common.isValidJavaClass('Key type', item.keyType, true)) { - $focus('keyType'); - - return false; - } + if ($common.isEmptyString(item.name)) + return $common.showPopoverMessage($scope.panels, 'metadata-data', 'metadataName', 'Name should not be empty'); - if (!$common.isValidJavaClass('Value type', item.valueType, false)) { - $focus('valueType'); + if ($common.isEmptyString(item.keyType)) + return $common.showPopoverMessage($scope.panels, 'metadata-data', 'keyType', 'Key type should not be empty'); + else if (!$common.isValidJavaClass('Key type', item.keyType, true)) + return $common.showPopoverMessage($scope.panels, 'metadata-data', 'keyType', 'Key type should be valid Java class'); - return false; - } + if ($common.isEmptyString(item.valueType)) + return $common.showPopoverMessage($scope.panels, 'metadata-data', 'valueType', 'Value type should not be empty'); + else if (!$common.isValidJavaClass('Value type', item.valueType, false)) + return $common.showPopoverMessage($scope.panels, 'metadata-data', 'valueType', 'Value type should valid Java class'); - if ($common.isEmptyArray(item.queryFields) && $common.isEmptyArray(item.ascendingFields) && - $common.isEmptyArray(item.descendingFields) && $common.isEmptyArray(item.textFields) && - $common.isEmptyArray(item.groups)) { - $common.showError('SQL fields are not specified!'); + var qry = queryConfigured(item); - return false; - } + if (qry) { + var groups = item.groups; - var groups = item.groups; - if (groups && groups.length > 0) { - for (var i = 0; i < groups.length; i++) { - var group = groups[i]; - var fields = group.fields; + if (groups && groups.length > 0) { + for (var i = 0; i < groups.length; i++) { + var group = groups[i]; + var fields = group.fields; - if ($common.isEmptyArray(fields)) { - $common.showError('Group "' + group.name + '" has no fields.'); + if ($common.isEmptyArray(fields)) + return $common.showPopoverMessage($scope.panels, 'metadataQuery-data', 'groups' + i, 'Group fields are not specified'); - return false; - } + if (fields.length == 1) { + return $common.showPopoverMessage($scope.panels, 'metadataQuery-data', 'groups' + i, 'Group has only one field. Consider to use ascending or descending fields.'); + } + } + } + } - if (fields.length == 1) { - $common.showError('Group "' + group.name + '" has only one field.<br/> Consider to use ascending or descending fields.'); + var str = storeConfigured(item); - return false; - } - } - } + if (str) { + if ($common.isEmptyString(item.databaseSchema)) + return $common.showPopoverMessage($scope.panels, 'metadataCache-data', 'databaseSchema', 'Database schema should not be empty'); - if ($common.isEmptyArray(item.keyFields) && !$common.isJavaBuildInClass(item.keyType)) { - $common.showError('Key fields are not specified!'); + if ($common.isEmptyString(item.databaseTable)) + return $common.showPopoverMessage($scope.panels, 'metadataCache-data', 'databaseTable', 'Database table should not be empty'); - return false; - } - if ($common.isEmptyArray(item.valueFields)) { - $common.showError('Value fields are not specified!'); + if ($common.isEmptyArray(item.keyFields) && !$common.isJavaBuildInClass(item.keyType)) + return $common.showPopoverMessage($scope.panels, 'metadataCache-data', 'keyFields-add', 'Key fields are not specified'); - return false; - } - */ + if ($common.isEmptyArray(item.valueFields)) + return $common.showPopoverMessage($scope.panels, 'metadataCache-data', 'valueFields-add', 'Value fields are not specified'); + } + else if (!qry) { + return $common.showPopoverMessage($scope.panels, 'metadataQuery-data', 'metadataQuery-data-title', 'SQL query metadata should be configured'); + } return true; } // Save cache type metadata into database. function save(item) { + var qry = queryConfigured(item); + var str = storeConfigured(item); + + item.kind = 'query'; + + if (qry && str) + item.kind = 'both'; + else if (str) + item.kind = 'store'; + $http.post('metadata/save', item) .success(function (_id) { $common.showInfo('Metadata "' + item.name + '" saved.'); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9672838e/modules/control-center-web/src/main/js/controllers/models/metadata.json ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/models/metadata.json b/modules/control-center-web/src/main/js/controllers/models/metadata.json index 682181b..58a40fa 100644 --- a/modules/control-center-web/src/main/js/controllers/models/metadata.json +++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json @@ -34,17 +34,17 @@ "fields": [ { "label": "Name", + "id": "metadataName", "type": "text", "model": "name", "required": true, - "placeholder": "Input name", - "id": "defaultFocusId" + "placeholder": "Input name" }, { "label": "Key type", + "id": "keyType", "type": "withJavaBuildInTypes", "model": "keyType", - "id": "keyType", "required": true, "placeholder": "Full class name for Key", "tip": [ @@ -53,9 +53,9 @@ }, { "label": "Value type", + "id": "valueType", "type": "text", "model": "valueType", - "id": "valueType", "required": true, "placeholder": "Full class name for Value", "tip": [ @@ -66,10 +66,12 @@ }, { "label": "Metadata for SQL query", + "id": "metadataQuery-data", "tip": [], "fields": [ { "label": "Not indexed fields", + "id": "queryFields", "ui": "table-pair", "type": "queryFieldsFirst", "model": "queryFields", @@ -84,6 +86,7 @@ }, { "label": "Ascending indexed fields", + "id": "ascendingFields", "ui": "table-pair", "type": "queryFields", "model": "ascendingFields", @@ -98,6 +101,7 @@ }, { "label": "Descending indexed fields", + "id": "descendingFields", "ui": "table-pair", "type": "queryFields", "model": "descendingFields", @@ -112,6 +116,7 @@ }, { "label": "Text indexed fields", + "id": "textFields", "type": "table-simple", "model": "textFields", "placeholder": "Field name", @@ -127,6 +132,7 @@ }, { "label": "Group indexes", + "id": "groups", "type": "table-query-groups", "model": "groups", "addTip": "Add new group.", @@ -141,10 +147,12 @@ }, { "label": "Metadata for cache store", + "id": "metadataCache-data", "tip": [], "fields": [ { "label": "Database schema", + "id": "databaseSchema", "type": "text", "model": "databaseSchema", "placeholder": "Input DB schema name", @@ -154,6 +162,7 @@ }, { "label": "Database table", + "id": "databaseTable", "type": "text", "model": "databaseTable", "placeholder": "Input DB table name", @@ -163,6 +172,7 @@ }, { "label": "Key fields", + "id": "keyFields", "type": "table-db-fields", "model": "keyFields", "keyName": "name", @@ -177,6 +187,7 @@ }, { "label": "Value fields", + "id": "valueFields", "type": "table-db-fields", "model": "valueFields", "keyName": "name", @@ -212,9 +223,9 @@ }, { "label": "JDBC URL", + "id": "jdbcUrl", "type": "text", "model": "jdbcUrl", - "id": "jdbcUrl", "placeholder": "JDBC URL", "tip": [ "JDBC URL for connecting to database.", http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9672838e/modules/control-center-web/src/main/js/db.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js index bcd7331..b183bdb 100644 --- a/modules/control-center-web/src/main/js/db.js +++ b/modules/control-center-web/src/main/js/db.js @@ -68,6 +68,7 @@ exports.Space = mongoose.model('Space', new Schema({ var CacheTypeMetadataSchema = new Schema({ space: {type: ObjectId, ref: 'Space'}, name: String, + kind: {type: String, enum: ['query', 'store', 'both']}, databaseSchema: String, databaseTable: String, keyType: String, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9672838e/modules/control-center-web/src/main/js/views/configuration/metadata.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/configuration/metadata.jade b/modules/control-center-web/src/main/js/views/configuration/metadata.jade index 1cef373..f320a12 100644 --- a/modules/control-center-web/src/main/js/views/configuration/metadata.jade +++ b/modules/control-center-web/src/main/js/views/configuration/metadata.jade @@ -27,15 +27,15 @@ block content hr .docs-body(ng-controller='metadataController') +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)') - +main-table('Types metadata:', 'metadatas', 'defaultFocusId', 'selectItem(row)', '{{$index + 1}}) {{row.name}}') + +main-table('Types metadata:', 'metadatas', 'metadataName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}') .padding-top-dflt - button.btn.btn-primary(ng-click='createItem()' on-click-focus='defaultFocusId') Add metadata + button.btn.btn-primary(ng-click='createItem()' on-click-focus='metadataName') Add metadata button.btn.btn-primary(ng-click='showLoadMetadataModal()') Load from database hr form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate) .panel-group(bs-collapse ng-model='panels.activePanels' data-allow-multiple='true') +groups('metadata', 'backupItem') .section - button.btn.btn-primary(ng-disabled='inputForm.$invalid' ng-click='saveItem()') Save - button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy + button.btn.btn-primary(ng-click='saveItem()') Save + button.btn.btn-primary(ng-show='backupItem._id' ng-click='saveItemAs()') Copy button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9672838e/modules/control-center-web/src/main/js/views/includes/controls.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade index b9c753f..0dd319d1 100644 --- a/modules/control-center-web/src/main/js/views/includes/controls.jade +++ b/modules/control-center-web/src/main/js/views/includes/controls.jade @@ -43,9 +43,9 @@ mixin btn-save(show, click) mixin group-tip(lines) i.group-legend-tip.fa.fa-question-circle(ng-if=lines bs-tooltip='joinTip(#{lines})' type='button') -mixin group-add(field) +mixin group-add(field, id) div(ng-show='!tableNewItemActive(#{field})') - a(ng-click='tableNewItem(#{field})') Add + a(ng-click='tableNewItem(#{field})' id='#{id}') Add mixin btn-add(click, tip) i.tipField.fa.fa-plus(ng-click=click bs-tooltip=tip) @@ -104,7 +104,7 @@ mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, tfoot tr td.col-sm-12 - +group-add('field') + +group-add('field', '{{::field.id + "-add"}}') div(ng-show='tableNewItemActive(field)') +table-pair-edit('new', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, '{{::field.focusId}}', '-1') @@ -146,7 +146,7 @@ mixin details-row +tipField('detail.tip') .input-tip button.form-control(id='{{::detail.id}}' bs-select data-placeholder='{{::detail.placeholder}}' bs-options='item.value as item.label for item in {{detail.items}}' tabindex='0')&attributes(detailCommon) - div(ng-switch-when='dropdown-multiple') + div(ng-switch-when='dropdown-multiple') label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}: .col-sm-8 +tipField('detail.tip') @@ -176,7 +176,7 @@ mixin details-row tfoot tr td.col-sm-12 - +group-add('detail') + +group-add('detail', '{{::detail.id + "-add"}}') div(ng-show='tableNewItemActive(detail)') +btn-save('tableSimpleSaveVisible(detail, -1)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, -1)') .input-tip.form-group.has-feedback @@ -312,7 +312,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) +tipField('field.tip') .input-tip button.form-control(bs-select ng-disabled=fieldDisabled data-placeholder='{{::field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}' tabindex='0')&attributes(fieldCommon) - a.customize(ng-show='#{fieldMdl} && field.settings' ng-click='#{expanded} = !#{expanded}') {{#{expanded} ? "Hide settings" : "Show settings"}} + a.customize(ng-show='#{fieldMdl} && field.settings' ng-click='#{expanded} = !#{expanded}') {{#{expanded} ? 'Hide settings' : 'Show settings'}} .col-sm-7.panel-details(ng-show='(#{expanded} || !field.settings) && #{fieldMdl}') .details-row(ng-repeat='detail in field.details[#{fieldMdl}].fields') +details-row @@ -347,7 +347,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) tfoot tr td.col-sm-12 - +group-add('field') + +group-add('field', '{{::field.id + "-add"}}') div(ng-show='tableNewItemActive(field)') +btn-save('tableSimpleSaveVisible(field, -1)', 'tableSimpleSave(tableSimpleValid, backupItem, field, -1)') .input-tip @@ -376,7 +376,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) tfoot tr td.col-sm-12 - +group-add('field') + +group-add('field', '{{::field.id + "-add"}}') div(ng-show='tableNewItemActive(field)') +table-db-field-edit('new', '{{::field.focusId}}', '-1') .group-section(ng-switch-when='table-query-groups' ng-hide=fieldHide) @@ -390,7 +390,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) tr(ng-repeat='group in #{fieldMdl}') td.col-sm-12 .col-sm-12(ng-show='!tableEditing(field, $index)') - a.labelFormField(ng-click='tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{group.name}} + a.labelFormField(id='{{field.id + $index}}' ng-click='tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{group.name}} +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip') +btn-add('tableGroupNewItem(field, $index)', 'field.addItemTip') div(ng-if='tableEditing(field, $index)') @@ -415,7 +415,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) tfoot tr td.col-sm-12 - +group-add('field') + +group-add('field', '{{::field.id + "-add"}}') div(ng-show='tableNewItemActive(field)') +btn-save('tableGroupSaveVisible(field, -1)', 'tableGroupSave(field, -1)') .input-tip @@ -434,7 +434,7 @@ mixin groups(groups, dataSource) .panel.panel-default(ng-repeat='group in #{groups}' ng-click='triggerDigest=true') .panel-heading h3 - a(bs-collapse-toggle ng-click='hidePopover()') {{::group.label}} + a(id='{{::group.id + "-title"}}' bs-collapse-toggle ng-click='hidePopover()') {{::group.label}} i.tipLabel.fa.fa-question-circle(ng-if='group.tip' bs-tooltip='joinTip(group.tip)' type='button') i.tipLabel.fa.fa-question-circle.blank(ng-if='!group.tip') .panel-collapse(role='tabpanel' bs-collapse-target id='{{::group.id}}' number='{{::group.number}}') http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9672838e/modules/control-center-web/src/main/js/views/login.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/login.jade b/modules/control-center-web/src/main/js/views/login.jade index 90af007..ddc5c05 100644 --- a/modules/control-center-web/src/main/js/views/login.jade +++ b/modules/control-center-web/src/main/js/views/login.jade @@ -49,7 +49,7 @@ mixin lbl(txt) input#user_confirm.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' ng-required='action == "register"' on-enter='loginForm.$valid && auth(action, user_info)') .modal-footer(ng-show='action == "register"') a.labelField(ng-click='action = "forgot_password"' on-click-focus='user_email') Forgot password? - a.labelLogin(ng-click='action = "login";' on-click-focus='user_email') Log In + a.labelLogin(ng-click='action = "login"' on-click-focus='user_email') Log In button.btn.btn-primary(ng-click='auth(action, user_info)' ng-disabled='loginForm.$invalid') Sign Up .modal-footer(ng-show='action == "forgot_password"') @@ -59,4 +59,4 @@ mixin lbl(txt) .modal-footer(ng-show='action == "login"') a.labelField(ng-click='action = "forgot_password"' on-click-focus='user_email') Forgot password? a.labelLogin(ng-click='action = "register"' on-click-focus='user_name') Sign Up - button.btn.btn-primary(ng-click='auth(action, user_info)' ng-disabled='loginForm.$invalid') Log In \ No newline at end of file + button.btn.btn-primary(ng-click='auth(action, user_info)' ng-disabled='loginForm.$invalid') Log In