Merge branches 'ignite-843' and 'ignite-sprint-7' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-843
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/92c06985 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/92c06985 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/92c06985 Branch: refs/heads/ignite-843 Commit: 92c06985426981eb1637a6af16d945ddcbb115e6 Parents: 4a0fd03 872fc38 Author: AKuznetsov <akuznet...@gridgain.com> Authored: Thu Jul 2 15:17:58 2015 +0700 Committer: AKuznetsov <akuznet...@gridgain.com> Committed: Thu Jul 2 15:17:58 2015 +0700 ---------------------------------------------------------------------- assembly/dependencies-fabric.xml | 1 + examples/pom.xml | 2 +- modules/aop/pom.xml | 2 +- modules/aws/pom.xml | 2 +- modules/clients/pom.xml | 2 +- .../ClientAbstractConnectivitySelfTest.java | 4 +- modules/cloud/pom.xml | 2 +- modules/codegen/pom.xml | 2 +- modules/core/pom.xml | 2 +- .../apache/ignite/IgniteSystemProperties.java | 3 + .../org/apache/ignite/cluster/ClusterGroup.java | 18 +- .../org/apache/ignite/cluster/ClusterNode.java | 2 + .../configuration/CacheConfiguration.java | 105 +-- .../configuration/IgniteReflectionFactory.java | 81 +- .../configuration/NearCacheConfiguration.java | 10 +- .../ignite/internal/GridKernalContextImpl.java | 5 +- .../ignite/internal/MarshallerContextImpl.java | 12 +- .../internal/cluster/ClusterGroupAdapter.java | 50 +- .../cluster/IgniteClusterAsyncImpl.java | 12 +- .../internal/managers/GridManagerAdapter.java | 8 +- .../managers/communication/GridIoManager.java | 49 +- .../discovery/GridDiscoveryManager.java | 62 +- .../processors/cache/GridCacheContext.java | 2 +- .../cache/GridCacheDeploymentManager.java | 10 +- .../GridCachePartitionExchangeManager.java | 7 +- .../processors/cache/GridCacheProcessor.java | 62 +- .../processors/cache/GridCacheSwapManager.java | 12 +- .../processors/cache/IgniteCacheFutureImpl.java | 42 + .../processors/cache/IgniteCacheProxy.java | 2 +- .../distributed/dht/GridDhtLocalPartition.java | 3 +- .../distributed/dht/GridDhtLockFuture.java | 2 +- .../dht/atomic/GridDhtAtomicCache.java | 9 +- .../GridDhtPartitionsExchangeFuture.java | 95 ++- .../continuous/CacheContinuousQueryHandler.java | 8 + .../processors/clock/GridClockServer.java | 21 +- .../datastructures/DataStructuresProcessor.java | 64 +- .../processors/hadoop/HadoopJobInfo.java | 4 +- .../hadoop/counter/HadoopCounterWriter.java | 5 +- .../offheap/GridOffHeapProcessor.java | 19 +- .../processors/plugin/CachePluginManager.java | 10 +- .../processors/rest/GridRestProcessor.java | 4 +- .../handlers/task/GridTaskCommandHandler.java | 12 +- .../processors/task/GridTaskWorker.java | 4 +- .../internal/util/GridConfigurationFinder.java | 55 +- .../apache/ignite/internal/util/GridDebug.java | 37 +- .../ignite/internal/util/IgniteUtils.java | 6 +- .../internal/util/future/IgniteFutureImpl.java | 18 +- .../shmem/IpcSharedMemoryServerEndpoint.java | 10 +- .../util/nio/GridNioMessageTracker.java | 23 +- .../ignite/internal/util/nio/GridNioServer.java | 64 +- .../apache/ignite/internal/visor/VisorJob.java | 2 + .../internal/visor/log/VisorLogSearchTask.java | 2 +- .../visor/node/VisorNodeDataCollectorJob.java | 4 + .../visor/query/VisorQueryCleanupTask.java | 14 + .../util/VisorClusterGroupEmptyException.java | 37 + .../org/apache/ignite/spi/IgniteSpiAdapter.java | 7 +- .../org/apache/ignite/spi/IgniteSpiContext.java | 9 +- .../communication/tcp/TcpCommunicationSpi.java | 104 ++- .../tcp/TcpCommunicationSpiMBean.java | 19 + .../ignite/spi/discovery/DiscoverySpi.java | 3 +- .../ignite/spi/discovery/tcp/ClientImpl.java | 234 ++++-- .../ignite/spi/discovery/tcp/ServerImpl.java | 127 ++- .../spi/discovery/tcp/TcpDiscoveryImpl.java | 3 +- .../spi/discovery/tcp/TcpDiscoverySpi.java | 9 +- .../TcpDiscoveryMulticastIpFinder.java | 74 +- .../messages/TcpDiscoveryNodeFailedMessage.java | 18 + .../core/src/main/resources/ignite.properties | 2 +- .../core/src/test/config/spark/spark-config.xml | 46 ++ modules/core/src/test/config/tests.properties | 6 +- .../internal/ClusterGroupAbstractTest.java | 777 ++++++++++++++++++ .../internal/ClusterGroupHostsSelfTest.java | 141 ++++ .../ignite/internal/ClusterGroupSelfTest.java | 251 ++++++ .../internal/GridDiscoveryEventSelfTest.java | 12 +- ...ridFailFastNodeFailureDetectionSelfTest.java | 17 +- .../internal/GridProjectionAbstractTest.java | 784 ------------------- .../ignite/internal/GridProjectionSelfTest.java | 251 ------ .../apache/ignite/internal/GridSelfTest.java | 2 +- .../IgniteSlowClientDetectionSelfTest.java | 187 +++++ .../IgniteTopologyPrintFormatSelfTest.java | 289 +++++++ .../CacheReadThroughAtomicRestartSelfTest.java | 32 + ...heReadThroughLocalAtomicRestartSelfTest.java | 32 + .../CacheReadThroughLocalRestartSelfTest.java | 32 + ...dThroughReplicatedAtomicRestartSelfTest.java | 32 + ...cheReadThroughReplicatedRestartSelfTest.java | 32 + .../cache/CacheReadThroughRestartSelfTest.java | 133 ++++ .../cache/GridCacheAbstractSelfTest.java | 2 +- .../IgniteDaemonNodeMarshallerCacheTest.java | 192 +++++ ...eDynamicCacheStartNoExchangeTimeoutTest.java | 466 +++++++++++ .../cache/IgniteDynamicCacheStartSelfTest.java | 37 + ...GridCacheQueueMultiNodeAbstractSelfTest.java | 4 +- .../GridCacheSetAbstractSelfTest.java | 22 +- .../IgniteDataStructureWithJobTest.java | 111 +++ .../distributed/IgniteCache150ClientsTest.java | 189 +++++ ...teCacheClientNodePartitionsExchangeTest.java | 1 + .../distributed/IgniteCacheManyClientsTest.java | 1 + ...idCacheNearOnlyMultiNodeFullApiSelfTest.java | 5 - ...achePartitionedMultiNodeFullApiSelfTest.java | 53 +- .../GridCacheReplicatedFailoverSelfTest.java | 5 + .../IgniteCacheTxStoreSessionTest.java | 4 + .../internal/util/IgniteUtilsSelfTest.java | 22 + .../GridP2PContinuousDeploymentSelfTest.java | 2 - .../GridTcpCommunicationSpiConfigSelfTest.java | 1 - .../tcp/TcpClientDiscoverySpiSelfTest.java | 265 ++++++- .../testframework/GridSpiTestContext.java | 7 +- .../testframework/junits/GridAbstractTest.java | 2 +- .../ignite/testsuites/IgniteBasicTestSuite.java | 8 +- .../IgniteCacheDataStructuresSelfTestSuite.java | 1 + .../testsuites/IgniteCacheTestSuite4.java | 8 + .../testsuites/IgniteClientTestSuite.java | 38 + .../testsuites/IgniteKernalSelfTestSuite.java | 1 + modules/core/src/test/resources/helloworld.gar | Bin 6092 -> 0 bytes modules/core/src/test/resources/helloworld1.gar | Bin 6092 -> 0 bytes modules/core/src/test/resources/readme.txt | 6 - modules/docker/Dockerfile | 55 ++ modules/docker/README.txt | 11 + modules/docker/build_users_libs.sh | 39 + modules/docker/download_ignite.sh | 49 ++ modules/docker/execute.sh | 62 ++ modules/docker/run.sh | 34 + modules/extdata/p2p/pom.xml | 4 +- .../p2p/GridP2PContinuousDeploymentTask1.java | 2 +- modules/extdata/uri/META-INF/ignite.xml | 38 + .../extdata/uri/modules/uri-dependency/pom.xml | 42 + .../deployment/uri/tasks/GarHelloWorldBean.java | 60 ++ .../src/main/resources/gar-example.properties | 18 + modules/extdata/uri/pom.xml | 62 +- .../deployment/uri/tasks/GarHelloWorldTask.java | 81 ++ .../deployment/uri/tasks/gar-spring-bean.xml | 29 + modules/gce/pom.xml | 2 +- modules/geospatial/pom.xml | 2 +- modules/hadoop/pom.xml | 80 +- .../fs/IgniteHadoopFileSystemCounterWriter.java | 9 +- .../processors/hadoop/HadoopClassLoader.java | 29 + .../processors/hadoop/HadoopDefaultJobInfo.java | 27 +- .../internal/processors/hadoop/HadoopUtils.java | 237 ------ .../hadoop/SecondaryFileSystemProvider.java | 3 +- .../hadoop/fs/HadoopFileSystemCacheUtils.java | 241 ++++++ .../hadoop/fs/HadoopFileSystemsUtils.java | 11 + .../hadoop/fs/HadoopLazyConcurrentMap.java | 5 + .../hadoop/jobtracker/HadoopJobTracker.java | 25 +- .../child/HadoopChildProcessRunner.java | 3 +- .../processors/hadoop/v2/HadoopV2Job.java | 84 +- .../hadoop/v2/HadoopV2JobResourceManager.java | 22 +- .../hadoop/v2/HadoopV2TaskContext.java | 37 +- .../apache/ignite/igfs/IgfsEventsTestSuite.java | 5 +- .../processors/hadoop/HadoopMapReduceTest.java | 2 +- .../processors/hadoop/HadoopTasksV1Test.java | 7 +- .../processors/hadoop/HadoopTasksV2Test.java | 7 +- .../processors/hadoop/HadoopV2JobSelfTest.java | 6 +- .../collections/HadoopAbstractMapTest.java | 3 +- .../testsuites/IgniteHadoopTestSuite.java | 2 +- .../IgniteIgfsLinuxAndMacOSTestSuite.java | 3 +- modules/hibernate/pom.xml | 2 +- modules/indexing/pom.xml | 2 +- .../processors/query/h2/IgniteH2Indexing.java | 2 + .../query/h2/twostep/GridMapQueryExecutor.java | 23 +- .../cache/IgniteCacheOffheapEvictQueryTest.java | 196 +++++ .../IgniteCacheQuerySelfTestSuite.java | 1 + modules/jcl/pom.xml | 2 +- modules/jta/pom.xml | 2 +- .../cache/jta/GridCacheXAResource.java | 18 +- .../processors/cache/GridCacheJtaSelfTest.java | 2 +- modules/log4j/pom.xml | 2 +- modules/mesos/pom.xml | 2 +- modules/rest-http/pom.xml | 2 +- modules/scalar-2.10/pom.xml | 2 +- modules/scalar/pom.xml | 2 +- modules/schedule/pom.xml | 2 +- modules/schema-import/pom.xml | 2 +- .../ignite/schema/model/PojoDescriptor.java | 2 + .../apache/ignite/schema/model/PojoField.java | 1 + .../parser/dialect/OracleMetadataDialect.java | 2 +- modules/slf4j/pom.xml | 2 +- modules/spark-2.10/pom.xml | 2 +- modules/spark/pom.xml | 2 +- .../org/apache/ignite/spark/IgniteContext.scala | 50 +- .../org/apache/ignite/spark/IgniteRddSpec.scala | 18 + modules/spring/pom.xml | 2 +- modules/ssh/pom.xml | 2 +- modules/tools/pom.xml | 2 +- modules/urideploy/pom.xml | 2 +- .../GridTaskUriDeploymentDeadlockSelfTest.java | 13 +- .../ignite/p2p/GridP2PDisabledSelfTest.java | 2 +- modules/visor-console-2.10/pom.xml | 2 +- modules/visor-console/pom.xml | 2 +- .../commands/cache/VisorCacheCommand.scala | 7 +- modules/visor-plugins/pom.xml | 2 +- modules/web/pom.xml | 2 +- modules/webconfig/nodejs/views/error.jade | 22 - .../ignite/webconfig/server/HelloServlet.java | 12 + .../main/webapp/WEB-INF/applicationContext.xml | 53 -- .../src/main/webapp/WEB-INF/main-servlet.xml | 10 - modules/webconfig/src/main/webapp/caches.html | 491 ++++++++++++ modules/webconfig/src/main/webapp/clients.html | 86 ++ modules/webconfig/src/main/webapp/clusters.html | 493 ++++++++++++ modules/webconfig/src/main/webapp/css/home.css | 34 - modules/webconfig/src/main/webapp/css/login.css | 217 ----- modules/webconfig/src/main/webapp/home.html | 26 - .../webconfig/src/main/webapp/images/docker.png | Bin 0 -> 994 bytes .../webconfig/src/main/webapp/images/java.png | Bin 0 -> 170 bytes .../webconfig/src/main/webapp/images/logo.png | Bin 0 -> 8148 bytes .../webconfig/src/main/webapp/images/xml.png | Bin 0 -> 232 bytes modules/webconfig/src/main/webapp/index.html | 76 ++ modules/webconfig/src/main/webapp/js/home.js | 20 - modules/webconfig/src/main/webapp/js/login.js | 170 ---- .../src/main/webapp/layout-sidebar.html | 80 ++ modules/webconfig/src/main/webapp/layout.html | 61 ++ modules/webconfig/src/main/webapp/login.html | 74 +- .../webconfig/src/main/webapp/persistence.html | 377 +++++++++ modules/webconfig/src/main/webapp/sql.html | 66 ++ .../src/main/webapp/stylesheets/style.css | 1 + modules/webconfig/src/main/webapp/summary.html | 142 ++++ modules/yardstick/pom.xml | 2 +- pom.xml | 14 +- scripts/git-patch-prop.sh | 2 +- 215 files changed, 8013 insertions(+), 2558 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/92c06985/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/HelloServlet.java ---------------------------------------------------------------------- diff --cc modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/HelloServlet.java index 0000000,0000000..efc7ef5 new file mode 100644 --- /dev/null +++ b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/HelloServlet.java @@@ -1,0 -1,0 +1,12 @@@ ++package org.apache.ignite.webconfig.server; ++ ++public class HelloServlet extends HttpServlet ++{ ++ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException ++ { ++ response.setContentType("text/html"); ++ response.setStatus(HttpServletResponse.SC_OK); ++ response.getWriter().println("<h1>Hello Servlet</h1>"); ++ response.getWriter().println("session=" + request.getSession(true).getId()); ++ } ++} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/92c06985/modules/webconfig/src/main/webapp/caches.html ---------------------------------------------------------------------- diff --cc modules/webconfig/src/main/webapp/caches.html index 0000000,0000000..150e5a6 new file mode 100644 --- /dev/null +++ b/modules/webconfig/src/main/webapp/caches.html @@@ -1,0 -1,0 +1,491 @@@ ++<!DOCTYPE html> ++<html ng-app="ignite-web-configurator"> ++ <head> ++ <title></title> ++ <!-- Bootstrap--> ++ <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css"> ++ <!-- Font Awesome Icons--> ++ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css"> ++ <!-- Font--> ++ <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif"> ++ <link rel="stylesheet" href="/stylesheets/style.css"> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script> ++ <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-sanitize.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.tpl.min.js"></script> ++ <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js"></script> ++ <script src="/javascripts/controllers/common.js"></script> ++ <script src="/javascripts/dataStructures.js"></script> ++ <script src="/javascripts/bundle.js"></script> ++ <script src="/javascripts/controllers/caches.js"></script> ++ </head> ++ <body class="theme-line body-overlap"> ++ <div class="wrapper"> ++ <header id="header" class="header"> ++ <div class="container"> ++ <h1 class="navbar-brand"><a href="/">Apache Ignite Web Configurator</a></h1> ++ <div ng-controller="auth" class="navbar-collapse collapse"> ++ <ul ng-controller="activeLink" class="nav navbar-nav"> ++ <li><a ng-class="{active: isActive('/clusters')}" href="/clusters">Configuration</a></li> ++ <li><a ng-class="{active: isActive('/sql')}" href="/sql">SQL</a></li> ++ </ul> ++ <ul ng-init="user = undefined" class="nav navbar-nav pull-right"> ++ <li ng-show="user"><a data-toggle="dropdown" aria-expanded="true" bs-dropdown data-template="user-dropdown" data-placement="bottom-right" class="dropdown-toggle">{{user.username}}<span class="caret"></span></a> ++ <script id="user-dropdown" type="text/ng-template"> ++ <ul class="dropdown-menu"> ++ <li><a href="/rest/auth/logout">Log Out</a></li> ++ </ul> ++ </script> ++ </li> ++ <li ng-show="!user" class="nav-login"><a ng-click="login()" href="#">Log In</a></li> ++ </ul> ++ </div> ++ </div> ++ </header> ++ <div class="container body-container"> ++ <div class="main-content"> ++ <div class="main-head"> ++ <div class="row"> ++ <div class="col-sm-2 border-right section-left greedy"> ++ <div class="sidebar-nav"> ++ <ul ng-controller="activeLink" class="menu"> ++ <li><a ng-class="{active: isActive('/clusters')}" href="/clusters">Clusters</a></li> ++ <li><a ng-class="{active: isActive('/caches')}" href="/caches">Caches</a></li> ++ <li><a ng-class="{active: isActive('/persistence')}" href="/persistence">Persistence</a></li> ++ <li><a ng-class="{active: isActive('/clients')}" href="/clients">Clients</a></li> ++ <li> ++ <p></p><a ng-class="{active: isActive('/summary')}" href="/summary">Summary</a> ++ </li> ++ </ul> ++ </div> ++ </div> ++ <div class="col-sm-10 border-left section-right"> ++ <div class="docs-content"> ++ <div class="docs-header"> ++ <h1>Caches</h1> ++ <p>Create and configure Ignite caches.</p> ++ <hr> ++ </div> ++ <div ng-controller="cachesController" class="docs-body"> ++ <div ng-hide="caches.length == 0" class="links"> ++ <table st-table="caches" class="col-sm-12"> ++ <tbody> ++ <tr ng-repeat="row in caches track by row._id"> ++ <td ng-class="{active: row._id == selectedItem._id}" class="col-sm-6"><a ng-click="selectItem(row)">{{$index + 1}}. {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}, {{row.atomicityMode | displayValue:atomicities:'Cache atomicity not set'}}</a></td> ++ </tr> ++ </tbody> ++ </table> ++ </div> ++ <button ng-click="createItem()" class="btn btn-primary">Add cache</button> ++ <hr> ++ <form name="inputForm" ng-if="backupItem" novalidate class="form-horizontal"> ++ <div bs-collapse data-start-collapsed="false"> ++ <div class="panel panel-default"> ++ <div class="panel-heading"> ++ <h3><a bs-collapse-toggle>General</a></h3> ++ </div> ++ <div bs-collapse-target class="panel-collapse"> ++ <div class="panel-body"> ++ <div ng-repeat="field in general" class="settings-row"> ++ <div ng-switch="field.type"> ++ <div ng-switch-when="check" class="checkbox col-sm-6"> ++ <label> ++ <input type="checkbox" ng-model="getModel(backupItem, field.path)[field.model]"/>{{field.label}}<i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!field.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </label> ++ </div> ++ <div ng-switch-when="text"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" placeholder="{{field.placeholder}}" ng-required="field.required" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="password"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="password" placeholder="{{field.placeholder}}" ng-required="field.required" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="number"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input name="{{field.model}}" type="number" placeholder="{{field.placeholder}}" min="{{field.min ? field.min : 0}}" max="{{field.max ? field.max : Number.MAX_VALUE}}" ng-required="field.required" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"/><i ng-show="inputForm["{{field.model}}"].$error.min" bs-tooltip="bs-tooltip" data-title="Value is less than allowable minimum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{field.model}}"].$error.max" bs-tooltip="bs-tooltip" data-title="Value is more than allowable maximum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{field.model}}"].$error.number" bs-tooltip="bs-tooltip" data-title="Invalid value. Only numbers allowed." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" ng-required="field.required" data-placeholder="{{field.placeholder}}" bs-options="item.value as item.label for item in {{field.items}}" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"></button> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown-multiple"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" ng-disabled="{{field.items}}.length == 0" data-multiple="1" data-placeholder="{{field.placeholder}}" bs-options="item.value as item.label for item in {{field.items}}" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"></button> ++ </div> ++ </div><a ng-show="field.addLink" ng-href="{{field.addLink.ref}}" class="customize">{{field.addLink.label}}</a> ++ </div> ++ <div ng-switch-when="dropdown-details"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" ng-required="field.required" data-placeholder="{{field.placeholder}}" bs-options="item.value as item.label for item in {{field.items}}" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"></button> ++ </div> ++ </div><a ng-show="getModel(backupItem, field.path)[field.model] && field.details[getModel(backupItem, field.path)[field.model]].fields" ng-click="field.details[getModel(backupItem, field.path)[field.model]].expanded = !field.details[getModel(backupItem, field.path)[field.model]].expanded" class="customize">{{field.details[getModel(backupItem, field.path)[field.model]].expanded ? "Hide settings" : "Show settings"}}</a> ++ <div ng-show="field.details[getModel(backupItem, field.path)[field.model]].expanded && getModel(backupItem, field.path)[field.model]" class="col-sm-6 panel-details"> ++ <div ng-repeat="detail in field.details[getModel(backupItem, field.path)[field.model]].fields" class="details-row"> ++ <div ng-switch="detail.type"> ++ <div ng-switch-when="check" class="checkbox"> ++ <label> ++ <input type="checkbox" ng-model="getModel(backupItem, detail.path)[detail.model]"/>{{detail.label}}<i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </label> ++ </div> ++ <div ng-switch-when="text"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" placeholder="{{detail.placeholder}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="number"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input name="{{detail.model}}" type="number" placeholder="{{detail.placeholder}}" min="{{detail.min ? detail.min : 0}}" max="{{detail.max ? detail.max : Number.MAX_VALUE}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"/><i ng-show="inputForm["{{detail.model}}"].$error.min" bs-tooltip="bs-tooltip" data-title="Value is less than allowable minimum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{detail.model}}"].$error.max" bs-tooltip="bs-tooltip" data-title="Value is more than allowable maximum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{detail.model}}"].$error.number" bs-tooltip="bs-tooltip" data-title="Invalid value. Only numbers allowed." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" data-placeholder="{{detail.placeholder}}" bs-options="item.value as item.label for item in {{detail.items}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"></button> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown-multiple"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"> ++ <button bs-select="bs-select" data-multiple="1" data-placeholder="{{detail.placeholder}}" bs-options="item.value as item.label for item in {{detail.items}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"></button> ++ </div><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ </div> ++ <div ng-switch-when="table-simple" style="margin-right: 5px; margin-top: -0.65em" ng-model="getModel(backupItem, detail.path)[detail.model]"> ++ <table st-table="getModel(backupItem, detail.path)[detail.model]" ng-show="getModel(backupItem, detail.path)[detail.model].length > 0" class="col-sm-12 links-edit"> ++ <tbody> ++ <tr ng-repeat="item in getModel(backupItem, detail.path)[detail.model] track by $index"> ++ <td class="col-sm-11"> ++ <div ng-show="detail.editIdx != {{$index}}"><a ng-click="detail.editIdx = $index; curValue = getModel(backupItem, detail.path)[detail.model][$index]">{{$index + 1}}) {{item}}</a><i ng-click="detail.editIdx = -1; getModel(backupItem, detail.path)[detail.model].splice($index, 1)" class="tipField fa fa-remove"></i></div> ++ <div ng-show="detail.editIdx == {{$index}}"> ++ <label class="labelField">{{$index + 1}})</label><i ng-click="detail.editIdx = -1; getModel(backupItem, detail.path)[detail.model][$index]=curValue" class="tipField fa fa-floppy-o"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="curValue" placeholder="{{detail.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </td> ++ <td ng-if="detail.reordering" class="col-sm-1"><i ng-show="$index > 0" ng-click="swapSimpleItems(detailMdl, $index, $index - 1); detail.editIdx = -1;" class="fa fa-arrow-up"></i><i ng-show="$index < getModel(backupItem, detail.path)[detail.model].length - 1" ng-click="swapSimpleItems(getModel(backupItem, detail.path)[detail.model], $index, $index + 1); detail.editIdx = -1;" class="fa fa-arrow-down"></i></td> ++ </tr> ++ </tbody> ++ </table> ++ <button ng-disabled="!newValue || getModel(backupItem, detail.path)[detail.model].indexOf(newValue) >= 0" ng-click="detail.editIdx = -1; getModel(backupItem, detail.path)[detail.model] ? getModel(backupItem, detail.path)[detail.model].push(newValue) : getModel(backupItem, detail.path)[detail.model] = [newValue];" class="btn btn-primary fieldButton">Add</button><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="newValue" ng-focus="detail.editIdx = -1" placeholder="{{detail.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="table-simple" ng-model="getModel(backupItem, field.path)[field.model]"> ++ <div> ++ <label>{{field.tableLabel}}: {{getModel(backupItem, field.path)[field.model].length}}</label><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!field.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </div> ++ <table st-table="getModel(backupItem, field.path)[field.model]" ng-show="getModel(backupItem, field.path)[field.model].length > 0" class="links-edit col-sm-12"> ++ <tbody> ++ <tr ng-repeat="item in getModel(backupItem, field.path)[field.model] track by $index" class="col-sm-12"> ++ <td class="col-sm-6"> ++ <div ng-show="field.editIdx != {{$index}}"><a ng-click="field.editIdx = $index; curValue = getModel(backupItem, field.path)[field.model][$index]">{{$index + 1}}) {{item | compact}}</a><i ng-click="field.editIdx = -1; getModel(backupItem, field.path)[field.model].splice($index, 1)" class="tipField fa fa-remove"></i></div> ++ <div ng-show="field.editIdx == {{$index}}"> ++ <label class="labelField">{{$index + 1}})</label><i ng-click="field.editIdx = -1; getModel(backupItem, field.path)[field.model][$index]=curValue" class="tipField fa fa-floppy-o"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="curValue" placeholder="{{field.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </td> ++ <td ng-if="field.reordering" class="col-sm-1"><i ng-show="$index > 0" ng-click="swapSimpleItems(fieldMdl, $index, $index - 1); field.editIdx = -1;" class="fa fa-arrow-up"></i><i ng-show="$index < getModel(backupItem, field.path)[field.model].length - 1" ng-click="swapSimpleItems(getModel(backupItem, field.path)[field.model], $index, $index + 1); field.editIdx = -1;" class="fa fa-arrow-down"></i></td> ++ </tr> ++ </tbody> ++ </table> ++ <div class="col-sm-6"> ++ <button ng-disabled="!newValue || getModel(backupItem, field.path)[field.model].indexOf(newValue) >= 0" ng-click="field.editIdx = -1; getModel(backupItem, field.path)[field.model] ? getModel(backupItem, field.path)[field.model].push(newValue) : getModel(backupItem, field.path)[field.model] = [newValue];" class="btn btn-primary fieldButton">Add</button><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="newValue" ng-focus="field.editIdx = -1" placeholder="{{field.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="indexedTypes"> ++ <div> ++ <label>Indexed types: {{backupItem.indexedTypes.length}}</label><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!field.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </div> ++ <table st-table="backupItem.indexedTypes" ng-show="backupItem.indexedTypes.length > 0" class="links-edit col-sm-12"> ++ <tbody> ++ <tr ng-repeat="item in backupItem.indexedTypes" class="col-sm-12"> ++ <td class="col-sm-6"> ++ <div ng-show="field.editIdx != {{$index}}"><a ng-click="field.editIdx = $index; curKeyClass = backupItem.indexedTypes[$index].keyClass; curValueClass = backupItem.indexedTypes[$index].valueClass">{{$index + 1}}) {{item.keyClass}} / {{item.valueClass}}</a><i ng-click="field.editIdx = -1; backupItem.indexedTypes.splice($index, 1)" class="tipField fa fa-remove"></i></div> ++ <div ng-show="field.editIdx == {{$index}}"> ++ <label class="labelField">{{$index + 1}})</label><i ng-click="field.editIdx = -1; backupItem.indexedTypes[$index]={keyClass: curKeyClass, valueClass: curValueClass}" class="tipField fa fa-floppy-o"></i> ++ <div class="input-tip"> ++ <div class="col-sm-12"> ++ <input type="text" ng-model="curKeyClass" placeholder="Key class full name" class="form-control table-form-control"/> ++ <label> / </label> ++ <input type="text" ng-model="curValueClass" placeholder="Value class full name" class="form-control table-form-control"/> ++ </div> ++ </div> ++ </div> ++ </td> ++ </tr> ++ </tbody> ++ </table> ++ <div class="col-sm-6"> ++ <input type="text" ng-model="newKeyClass" ng-focus="field.editIdx = -1" placeholder="Key class full name" class="form-control"/> ++ <div class="settings-row"> ++ <input type="text" ng-model="newValueClass" ng-focus="field.editIdx = -1" placeholder="Value class full name" class="form-control"/> ++ </div> ++ <button ng-click="field.editIdx = -1; addIndexedTypes(newKeyClass, newValueClass)" class="btn btn-primary fieldButton">Add</button> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ <div bs-collapse data-start-collapsed="true"> ++ <div ng-show="expanded" class="panel-title"> ++ <h3><a bs-collapse-toggle="0" ng-click="expanded = !expanded;">{{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}</a></h3> ++ </div> ++ <div bs-collapse-target class="panel-collapse"> ++ <div bs-collapse data-start-collapsed="true" data-allow-multiple="true" class="span"> ++ <div ng-repeat="group in advanced" class="panel panel-default"> ++ <div class="panel-heading"> ++ <h3><a bs-collapse-toggle>{{group.label}}</a><i ng-if="group.tip" bs-tooltip="joinTip(group.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!group.tip" class="tipLabel fa fa-question-circle blank"></i></h3> ++ </div> ++ <div bs-collapse-target class="panel-collapse"> ++ <div class="panel-body"> ++ <div ng-repeat="field in group.fields" class="settings-row"> ++ <div ng-switch="field.type"> ++ <div ng-switch-when="check" class="checkbox col-sm-6"> ++ <label> ++ <input type="checkbox" ng-model="getModel(backupItem, field.path)[field.model]"/>{{field.label}}<i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!field.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </label> ++ </div> ++ <div ng-switch-when="text"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" placeholder="{{field.placeholder}}" ng-required="field.required" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="password"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="password" placeholder="{{field.placeholder}}" ng-required="field.required" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="number"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input name="{{field.model}}" type="number" placeholder="{{field.placeholder}}" min="{{field.min ? field.min : 0}}" max="{{field.max ? field.max : Number.MAX_VALUE}}" ng-required="field.required" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"/><i ng-show="inputForm["{{field.model}}"].$error.min" bs-tooltip="bs-tooltip" data-title="Value is less than allowable minimum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{field.model}}"].$error.max" bs-tooltip="bs-tooltip" data-title="Value is more than allowable maximum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{field.model}}"].$error.number" bs-tooltip="bs-tooltip" data-title="Invalid value. Only numbers allowed." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" ng-required="field.required" data-placeholder="{{field.placeholder}}" bs-options="item.value as item.label for item in {{field.items}}" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"></button> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown-multiple"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" ng-disabled="{{field.items}}.length == 0" data-multiple="1" data-placeholder="{{field.placeholder}}" bs-options="item.value as item.label for item in {{field.items}}" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"></button> ++ </div> ++ </div><a ng-show="field.addLink" ng-href="{{field.addLink.ref}}" class="customize">{{field.addLink.label}}</a> ++ </div> ++ <div ng-switch-when="dropdown-details"> ++ <label ng-class="{required: field.required}" class="col-sm-2">{{field.label}}:</label> ++ <div class="col-sm-4"><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" ng-required="field.required" data-placeholder="{{field.placeholder}}" bs-options="item.value as item.label for item in {{field.items}}" class="form-control" ng-model="getModel(backupItem, field.path)[field.model]"></button> ++ </div> ++ </div><a ng-show="getModel(backupItem, field.path)[field.model] && field.details[getModel(backupItem, field.path)[field.model]].fields" ng-click="field.details[getModel(backupItem, field.path)[field.model]].expanded = !field.details[getModel(backupItem, field.path)[field.model]].expanded" class="customize">{{field.details[getModel(backupItem, field.path)[field.model]].expanded ? "Hide settings" : "Show settings"}}</a> ++ <div ng-show="field.details[getModel(backupItem, field.path)[field.model]].expanded && getModel(backupItem, field.path)[field.model]" class="col-sm-6 panel-details"> ++ <div ng-repeat="detail in field.details[getModel(backupItem, field.path)[field.model]].fields" class="details-row"> ++ <div ng-switch="detail.type"> ++ <div ng-switch-when="check" class="checkbox"> ++ <label> ++ <input type="checkbox" ng-model="getModel(backupItem, detail.path)[detail.model]"/>{{detail.label}}<i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </label> ++ </div> ++ <div ng-switch-when="text"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" placeholder="{{detail.placeholder}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="number"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input name="{{detail.model}}" type="number" placeholder="{{detail.placeholder}}" min="{{detail.min ? detail.min : 0}}" max="{{detail.max ? detail.max : Number.MAX_VALUE}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"/><i ng-show="inputForm["{{detail.model}}"].$error.min" bs-tooltip="bs-tooltip" data-title="Value is less than allowable minimum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{detail.model}}"].$error.max" bs-tooltip="bs-tooltip" data-title="Value is more than allowable maximum." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i><i ng-show="inputForm["{{detail.model}}"].$error.number" bs-tooltip="bs-tooltip" data-title="Invalid value. Only numbers allowed." type="button" class="fa fa-exclamation-triangle form-control-feedback"></i> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <button bs-select="bs-select" data-placeholder="{{detail.placeholder}}" bs-options="item.value as item.label for item in {{detail.items}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"></button> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="dropdown-multiple"> ++ <label class="col-sm-4 details-label">{{detail.label}}:</label> ++ <div class="col-sm-8"> ++ <button bs-select="bs-select" data-multiple="1" data-placeholder="{{detail.placeholder}}" bs-options="item.value as item.label for item in {{detail.items}}" class="form-control" ng-model="getModel(backupItem, detail.path)[detail.model]"></button> ++ </div><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ </div> ++ <div ng-switch-when="table-simple" style="margin-right: 5px; margin-top: -0.65em" ng-model="getModel(backupItem, detail.path)[detail.model]"> ++ <table st-table="getModel(backupItem, detail.path)[detail.model]" ng-show="getModel(backupItem, detail.path)[detail.model].length > 0" class="col-sm-12 links-edit"> ++ <tbody> ++ <tr ng-repeat="item in getModel(backupItem, detail.path)[detail.model] track by $index"> ++ <td class="col-sm-11"> ++ <div ng-show="detail.editIdx != {{$index}}"><a ng-click="detail.editIdx = $index; curValue = getModel(backupItem, detail.path)[detail.model][$index]">{{$index + 1}}) {{item}}</a><i ng-click="detail.editIdx = -1; getModel(backupItem, detail.path)[detail.model].splice($index, 1)" class="tipField fa fa-remove"></i></div> ++ <div ng-show="detail.editIdx == {{$index}}"> ++ <label class="labelField">{{$index + 1}})</label><i ng-click="detail.editIdx = -1; getModel(backupItem, detail.path)[detail.model][$index]=curValue" class="tipField fa fa-floppy-o"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="curValue" placeholder="{{detail.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </td> ++ <td ng-if="detail.reordering" class="col-sm-1"><i ng-show="$index > 0" ng-click="swapSimpleItems(detailMdl, $index, $index - 1); detail.editIdx = -1;" class="fa fa-arrow-up"></i><i ng-show="$index < getModel(backupItem, detail.path)[detail.model].length - 1" ng-click="swapSimpleItems(getModel(backupItem, detail.path)[detail.model], $index, $index + 1); detail.editIdx = -1;" class="fa fa-arrow-down"></i></td> ++ </tr> ++ </tbody> ++ </table> ++ <button ng-disabled="!newValue || getModel(backupItem, detail.path)[detail.model].indexOf(newValue) >= 0" ng-click="detail.editIdx = -1; getModel(backupItem, detail.path)[detail.model] ? getModel(backupItem, detail.path)[detail.model].push(newValue) : getModel(backupItem, detail.path)[detail.model] = [newValue];" class="btn btn-primary fieldButton">Add</button><i ng-if="detail.tip" bs-tooltip="joinTip(detail.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!detail.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="newValue" ng-focus="detail.editIdx = -1" placeholder="{{detail.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="table-simple" ng-model="getModel(backupItem, field.path)[field.model]"> ++ <div> ++ <label>{{field.tableLabel}}: {{getModel(backupItem, field.path)[field.model].length}}</label><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!field.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </div> ++ <table st-table="getModel(backupItem, field.path)[field.model]" ng-show="getModel(backupItem, field.path)[field.model].length > 0" class="links-edit col-sm-12"> ++ <tbody> ++ <tr ng-repeat="item in getModel(backupItem, field.path)[field.model] track by $index" class="col-sm-12"> ++ <td class="col-sm-6"> ++ <div ng-show="field.editIdx != {{$index}}"><a ng-click="field.editIdx = $index; curValue = getModel(backupItem, field.path)[field.model][$index]">{{$index + 1}}) {{item | compact}}</a><i ng-click="field.editIdx = -1; getModel(backupItem, field.path)[field.model].splice($index, 1)" class="tipField fa fa-remove"></i></div> ++ <div ng-show="field.editIdx == {{$index}}"> ++ <label class="labelField">{{$index + 1}})</label><i ng-click="field.editIdx = -1; getModel(backupItem, field.path)[field.model][$index]=curValue" class="tipField fa fa-floppy-o"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="curValue" placeholder="{{field.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </td> ++ <td ng-if="field.reordering" class="col-sm-1"><i ng-show="$index > 0" ng-click="swapSimpleItems(fieldMdl, $index, $index - 1); field.editIdx = -1;" class="fa fa-arrow-up"></i><i ng-show="$index < getModel(backupItem, field.path)[field.model].length - 1" ng-click="swapSimpleItems(getModel(backupItem, field.path)[field.model], $index, $index + 1); field.editIdx = -1;" class="fa fa-arrow-down"></i></td> ++ </tr> ++ </tbody> ++ </table> ++ <div class="col-sm-6"> ++ <button ng-disabled="!newValue || getModel(backupItem, field.path)[field.model].indexOf(newValue) >= 0" ng-click="field.editIdx = -1; getModel(backupItem, field.path)[field.model] ? getModel(backupItem, field.path)[field.model].push(newValue) : getModel(backupItem, field.path)[field.model] = [newValue];" class="btn btn-primary fieldButton">Add</button><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipField fa fa-question-circle"></i><i ng-if="!field.tip" class="tipField fa fa-question-circle blank"></i> ++ <div class="input-tip"> ++ <input type="text" ng-model="newValue" ng-focus="field.editIdx = -1" placeholder="{{field.placeholder}}" class="form-control"/> ++ </div> ++ </div> ++ </div> ++ <div ng-switch-when="indexedTypes"> ++ <div> ++ <label>Indexed types: {{backupItem.indexedTypes.length}}</label><i ng-if="field.tip" bs-tooltip="joinTip(field.tip)" type="button" class="tipLabel fa fa-question-circle"></i><i ng-if="!field.tip" class="tipLabel fa fa-question-circle blank"></i> ++ </div> ++ <table st-table="backupItem.indexedTypes" ng-show="backupItem.indexedTypes.length > 0" class="links-edit col-sm-12"> ++ <tbody> ++ <tr ng-repeat="item in backupItem.indexedTypes" class="col-sm-12"> ++ <td class="col-sm-6"> ++ <div ng-show="field.editIdx != {{$index}}"><a ng-click="field.editIdx = $index; curKeyClass = backupItem.indexedTypes[$index].keyClass; curValueClass = backupItem.indexedTypes[$index].valueClass">{{$index + 1}}) {{item.keyClass}} / {{item.valueClass}}</a><i ng-click="field.editIdx = -1; backupItem.indexedTypes.splice($index, 1)" class="tipField fa fa-remove"></i></div> ++ <div ng-show="field.editIdx == {{$index}}"> ++ <label class="labelField">{{$index + 1}})</label><i ng-click="field.editIdx = -1; backupItem.indexedTypes[$index]={keyClass: curKeyClass, valueClass: curValueClass}" class="tipField fa fa-floppy-o"></i> ++ <div class="input-tip"> ++ <div class="col-sm-12"> ++ <input type="text" ng-model="curKeyClass" placeholder="Key class full name" class="form-control table-form-control"/> ++ <label> / </label> ++ <input type="text" ng-model="curValueClass" placeholder="Value class full name" class="form-control table-form-control"/> ++ </div> ++ </div> ++ </div> ++ </td> ++ </tr> ++ </tbody> ++ </table> ++ <div class="col-sm-6"> ++ <input type="text" ng-model="newKeyClass" ng-focus="field.editIdx = -1" placeholder="Key class full name" class="form-control"/> ++ <div class="settings-row"> ++ <input type="text" ng-model="newValueClass" ng-focus="field.editIdx = -1" placeholder="Value class full name" class="form-control"/> ++ </div> ++ <button ng-click="field.editIdx = -1; addIndexedTypes(newKeyClass, newValueClass)" class="btn btn-primary fieldButton">Add</button> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ <div class="panel-title"> ++ <h3><a bs-collapse-toggle="0" ng-click="expanded = !expanded;">{{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}</a></h3> ++ </div> ++ </div> ++ <button id="save-btn" ng-disabled="inputForm.$invalid" ng-click="saveItem()" class="btn btn-primary">Save</button> ++ <button ng-show="backupItem._id" ng-click="removeItem()" class="btn btn-primary btn-second">Remove</button> ++ </form> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ <div class="container container-footer"> ++ <footer> ++ <center> ++ <p>Powered by<a href="http://ignite.incubator.apache.org"> Apache Ignite</a>, version 1.1.0</p> ++ </center> ++ </footer> ++ </div> ++ </div> ++ </body> ++</html> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/92c06985/modules/webconfig/src/main/webapp/clients.html ---------------------------------------------------------------------- diff --cc modules/webconfig/src/main/webapp/clients.html index 0000000,0000000..05daf87 new file mode 100644 --- /dev/null +++ b/modules/webconfig/src/main/webapp/clients.html @@@ -1,0 -1,0 +1,86 @@@ ++<!DOCTYPE html> ++<html ng-app="ignite-web-configurator"> ++ <head> ++ <title></title> ++ <!-- Bootstrap--> ++ <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css"> ++ <!-- Font Awesome Icons--> ++ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css"> ++ <!-- Font--> ++ <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif"> ++ <link rel="stylesheet" href="/stylesheets/style.css"> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script> ++ <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-sanitize.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.js"></script> ++ <script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.tpl.min.js"></script> ++ <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js"></script> ++ <script src="/javascripts/controllers/common.js"></script> ++ <script src="/javascripts/dataStructures.js"></script> ++ <script src="/javascripts/bundle.js"></script> ++ </head> ++ <body class="theme-line body-overlap"> ++ <div class="wrapper"> ++ <header id="header" class="header"> ++ <div class="container"> ++ <h1 class="navbar-brand"><a href="/">Apache Ignite Web Configurator</a></h1> ++ <div ng-controller="auth" class="navbar-collapse collapse"> ++ <ul ng-controller="activeLink" class="nav navbar-nav"> ++ <li><a ng-class="{active: isActive('/clusters')}" href="/clusters">Configuration</a></li> ++ <li><a ng-class="{active: isActive('/sql')}" href="/sql">SQL</a></li> ++ </ul> ++ <ul ng-init="user = undefined" class="nav navbar-nav pull-right"> ++ <li ng-show="user"><a data-toggle="dropdown" aria-expanded="true" bs-dropdown data-template="user-dropdown" data-placement="bottom-right" class="dropdown-toggle">{{user.username}}<span class="caret"></span></a> ++ <script id="user-dropdown" type="text/ng-template"> ++ <ul class="dropdown-menu"> ++ <li><a href="/rest/auth/logout">Log Out</a></li> ++ </ul> ++ </script> ++ </li> ++ <li ng-show="!user" class="nav-login"><a ng-click="login()" href="#">Log In</a></li> ++ </ul> ++ </div> ++ </div> ++ </header> ++ <div class="container body-container"> ++ <div class="main-content"> ++ <div class="main-head"> ++ <div class="row"> ++ <div class="col-sm-2 border-right section-left greedy"> ++ <div class="sidebar-nav"> ++ <ul ng-controller="activeLink" class="menu"> ++ <li><a ng-class="{active: isActive('/clusters')}" href="/clusters">Clusters</a></li> ++ <li><a ng-class="{active: isActive('/caches')}" href="/caches">Caches</a></li> ++ <li><a ng-class="{active: isActive('/persistence')}" href="/persistence">Persistence</a></li> ++ <li><a ng-class="{active: isActive('/clients')}" href="/clients">Clients</a></li> ++ <li> ++ <p></p><a ng-class="{active: isActive('/summary')}" href="/summary">Summary</a> ++ </li> ++ </ul> ++ </div> ++ </div> ++ <div class="col-sm-10 border-left section-right"> ++ <div class="docs-content"> ++ <div class="docs-header"> ++ <h1>Clients</h1> ++ <p>Create and configure Ignite clients.</p> ++ <hr> ++ </div> ++ <div ng-controller="clientsRouter" class="docs-body"></div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ </div> ++ <div class="container container-footer"> ++ <footer> ++ <center> ++ <p>Powered by<a href="http://ignite.incubator.apache.org"> Apache Ignite</a>, version 1.1.0</p> ++ </center> ++ </footer> ++ </div> ++ </div> ++ </body> ++</html>