You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/09/13 09:53:30 UTC
[38/69] [abbrv] ignite git commit: Web Console beta-3.
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/generator/Pom.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Pom.service.js b/modules/web-console/frontend/app/modules/configuration/generator/Pom.service.js
new file mode 100644
index 0000000..627a1e3
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/generator/Pom.service.js
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Java built-in class names.
+import POM_DEPENDENCIES from 'app/data/pom-dependencies.json';
+
+/**
+ * Pom file generation entry point.
+ */
+class GeneratorPom {
+ escapeId(s) {
+ if (typeof (s) !== 'string')
+ return s;
+
+ return s.replace(/[^A-Za-z0-9_\-.]+/g, '_');
+ }
+
+ addProperty(res, tag, val) {
+ res.line('<' + tag + '>' + val + '</' + tag + '>');
+ }
+
+ addDependency(deps, groupId, artifactId, version, jar) {
+ if (!_.find(deps, (dep) => dep.groupId === groupId && dep.artifactId === artifactId))
+ deps.push({groupId, artifactId, version, jar});
+ }
+
+ addResource(res, dir, exclude) {
+ res.startBlock('<resource>');
+ if (dir)
+ this.addProperty(res, 'directory', dir);
+
+ if (exclude) {
+ res.startBlock('<excludes>');
+ this.addProperty(res, 'exclude', exclude);
+ res.endBlock('</excludes>');
+ }
+
+ res.endBlock('</resource>');
+ }
+
+ artifact(res, cluster, igniteVersion) {
+ this.addProperty(res, 'groupId', 'org.apache.ignite');
+ this.addProperty(res, 'artifactId', this.escapeId(cluster.name) + '-project');
+ this.addProperty(res, 'version', igniteVersion);
+
+ res.needEmptyLine = true;
+ }
+
+ dependencies(res, cluster, deps) {
+ if (!res)
+ res = $generatorCommon.builder();
+
+ res.startBlock('<dependencies>');
+
+ _.forEach(deps, (dep) => {
+ res.startBlock('<dependency>');
+
+ this.addProperty(res, 'groupId', dep.groupId);
+ this.addProperty(res, 'artifactId', dep.artifactId);
+ this.addProperty(res, 'version', dep.version);
+
+ if (dep.jar) {
+ this.addProperty(res, 'scope', 'system');
+ this.addProperty(res, 'systemPath', '${project.basedir}/jdbc-drivers/' + dep.jar);
+ }
+
+ res.endBlock('</dependency>');
+ });
+
+ res.endBlock('</dependencies>');
+
+ return res;
+ }
+
+ build(res, cluster, excludeGroupIds) {
+ res.startBlock('<build>');
+ res.startBlock('<resources>');
+ this.addResource(res, 'src/main/java', '**/*.java');
+ this.addResource(res, 'src/main/resources');
+ res.endBlock('</resources>');
+
+ res.startBlock('<plugins>');
+ res.startBlock('<plugin>');
+ this.addProperty(res, 'artifactId', 'maven-dependency-plugin');
+ res.startBlock('<executions>');
+ res.startBlock('<execution>');
+ this.addProperty(res, 'id', 'copy-libs');
+ this.addProperty(res, 'phase', 'test-compile');
+ res.startBlock('<goals>');
+ this.addProperty(res, 'goal', 'copy-dependencies');
+ res.endBlock('</goals>');
+ res.startBlock('<configuration>');
+ this.addProperty(res, 'excludeGroupIds', excludeGroupIds.join(','));
+ this.addProperty(res, 'outputDirectory', 'target/libs');
+ this.addProperty(res, 'includeScope', 'compile');
+ this.addProperty(res, 'excludeTransitive', 'true');
+ res.endBlock('</configuration>');
+ res.endBlock('</execution>');
+ res.endBlock('</executions>');
+ res.endBlock('</plugin>');
+ res.startBlock('<plugin>');
+ this.addProperty(res, 'artifactId', 'maven-compiler-plugin');
+ this.addProperty(res, 'version', '3.1');
+ res.startBlock('<configuration>');
+ this.addProperty(res, 'source', '1.7');
+ this.addProperty(res, 'target', '1.7');
+ res.endBlock('</configuration>');
+ res.endBlock('</plugin>');
+ res.endBlock('</plugins>');
+ res.endBlock('</build>');
+
+ res.endBlock('</project>');
+ }
+
+ /**
+ * Add dependency for specified store factory if not exist.
+ * @param storeDeps Already added dependencies.
+ * @param storeFactory Store factory to add dependency.
+ */
+ storeFactoryDependency(storeDeps, storeFactory) {
+ if (storeFactory.dialect && (!storeFactory.connectVia || storeFactory.connectVia === 'DataSource')) {
+ const dep = POM_DEPENDENCIES[storeFactory.dialect];
+
+ this.addDependency(storeDeps, dep.groupId, dep.artifactId, dep.version, dep.jar);
+ }
+ }
+
+ /**
+ * Generate pom.xml.
+ *
+ * @param cluster Cluster to take info about dependencies.
+ * @param igniteVersion Ignite version for Ignite dependencies.
+ * @param res Resulting output with generated pom.
+ * @returns {string} Generated content.
+ */
+ generate(cluster, igniteVersion, res) {
+ const caches = cluster.caches;
+ const deps = [];
+ const storeDeps = [];
+ const excludeGroupIds = ['org.apache.ignite'];
+
+ const blobStoreFactory = {cacheStoreFactory: {kind: 'CacheHibernateBlobStoreFactory'}};
+
+ if (!res)
+ res = $generatorCommon.builder();
+
+ _.forEach(caches, (cache) => {
+ if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind)
+ this.storeFactoryDependency(storeDeps, cache.cacheStoreFactory[cache.cacheStoreFactory.kind]);
+
+ if (_.get(cache, 'nodeFilter.kind') === 'Exclude')
+ this.addDependency(deps, 'org.apache.ignite', 'ignite-extdata-p2p', igniteVersion);
+ });
+
+ res.line('<?xml version="1.0" encoding="UTF-8"?>');
+
+ res.needEmptyLine = true;
+
+ res.line('<!-- ' + $generatorCommon.mainComment() + ' -->');
+
+ res.needEmptyLine = true;
+
+ res.startBlock('<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">');
+
+ res.line('<modelVersion>4.0.0</modelVersion>');
+
+ res.needEmptyLine = true;
+
+ this.artifact(res, cluster, igniteVersion);
+
+ this.addDependency(deps, 'org.apache.ignite', 'ignite-core', igniteVersion);
+
+ this.addDependency(deps, 'org.apache.ignite', 'ignite-spring', igniteVersion);
+ this.addDependency(deps, 'org.apache.ignite', 'ignite-indexing', igniteVersion);
+ this.addDependency(deps, 'org.apache.ignite', 'ignite-rest-http', igniteVersion);
+
+ let dep = POM_DEPENDENCIES[cluster.discovery.kind];
+
+ if (dep)
+ this.addDependency(deps, 'org.apache.ignite', dep.artifactId, igniteVersion);
+
+ if (cluster.discovery.kind === 'Jdbc') {
+ const store = cluster.discovery.Jdbc;
+
+ if (store.dataSourceBean && store.dialect)
+ this.storeFactoryDependency(storeDeps, cluster.discovery.Jdbc);
+ }
+
+ if (_.find(cluster.igfss, (igfs) => igfs.secondaryFileSystemEnabled))
+ this.addDependency(deps, 'org.apache.ignite', 'ignite-hadoop', igniteVersion);
+
+ if (_.find(caches, blobStoreFactory))
+ this.addDependency(deps, 'org.apache.ignite', 'ignite-hibernate', igniteVersion);
+
+ if (cluster.logger && cluster.logger.kind) {
+ dep = POM_DEPENDENCIES[cluster.logger.kind];
+
+ if (dep)
+ this.addDependency(deps, 'org.apache.ignite', dep.artifactId, igniteVersion);
+ }
+
+ this.dependencies(res, cluster, deps.concat(storeDeps));
+
+ res.needEmptyLine = true;
+
+ this.build(res, cluster, excludeGroupIds);
+
+ return res;
+ }
+}
+
+export default ['GeneratorPom', GeneratorPom];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/generator/Xml.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Xml.service.js b/modules/web-console/frontend/app/modules/configuration/generator/Xml.service.js
new file mode 100644
index 0000000..58d1ce0
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/generator/Xml.service.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// TODO IGNITE-2052: need move $generatorXml to services.
+export default ['GeneratorXml', () => {
+ return $generatorXml;
+}];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/sidebar.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/sidebar.directive.js b/modules/web-console/frontend/app/modules/configuration/sidebar.directive.js
new file mode 100644
index 0000000..e51553b
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/sidebar.directive.js
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteSidebar', ['igniteSidebar', (igniteSidebar) => {
+ function controller() {
+ const ctrl = this;
+
+ ctrl.items = igniteSidebar;
+ }
+
+ return {
+ restrict: 'A',
+ controller,
+ controllerAs: 'sidebar'
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/dialog/dialog-content.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/dialog/dialog-content.directive.js b/modules/web-console/frontend/app/modules/dialog/dialog-content.directive.js
new file mode 100644
index 0000000..98e9903
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/dialog/dialog-content.directive.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteDialogContent', [() => {
+ const link = ($scope, $element, $attrs, igniteDialog) => {
+ igniteDialog.content = $element.html();
+
+ $element.hide();
+ };
+
+ return {
+ scope: {},
+ restrict: 'E',
+ link,
+ require: '^igniteDialog'
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/dialog/dialog-title.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/dialog/dialog-title.directive.js b/modules/web-console/frontend/app/modules/dialog/dialog-title.directive.js
new file mode 100644
index 0000000..ed4adb8
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/dialog/dialog-title.directive.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteDialogTitle', [() => {
+ const link = ($scope, $element, $attrs, igniteDialog) => {
+ igniteDialog.title = $element.text();
+
+ $element.hide();
+ };
+
+ return {
+ scope: {},
+ restrict: 'E',
+ link,
+ require: '^igniteDialog'
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/dialog/dialog.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/dialog/dialog.controller.js b/modules/web-console/frontend/app/modules/dialog/dialog.controller.js
new file mode 100644
index 0000000..05518d3
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/dialog/dialog.controller.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['$rootScope', '$scope', 'IgniteDialog', function($root, $scope, IgniteDialog) {
+ const ctrl = this;
+
+ const dialog = new IgniteDialog({
+ scope: $scope
+ });
+
+ ctrl.show = () => {
+ dialog.$promise.then(dialog.show);
+ };
+
+ $scope.$watch(() => ctrl.title, () => {
+ $scope.title = ctrl.title;
+ });
+
+ $scope.$watch(() => ctrl.content, () => {
+ $scope.content = ctrl.content;
+ });
+
+ $root.$on('$stateChangeStart', () => {
+ dialog.hide();
+ });
+}];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/dialog/dialog.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/dialog/dialog.directive.js b/modules/web-console/frontend/app/modules/dialog/dialog.directive.js
new file mode 100644
index 0000000..7aab10f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/dialog/dialog.directive.js
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import controller from './dialog.controller';
+
+const template = '<a ng-click="ctrl.show()"><span ng-transclude=""></span></a>';
+
+export default ['igniteDialog', [() => {
+ return {
+ restrict: 'E',
+ template,
+ controller,
+ controllerAs: 'ctrl',
+ replace: true,
+ transclude: true,
+ require: '^igniteDialog'
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/dialog/dialog.factory.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/dialog/dialog.factory.js b/modules/web-console/frontend/app/modules/dialog/dialog.factory.js
new file mode 100644
index 0000000..e15891f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/dialog/dialog.factory.js
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import templateUrl from './dialog.jade';
+
+export default ['IgniteDialog', ['$modal', ($modal) => {
+ const defaults = {
+ templateUrl,
+ placement: 'center',
+ show: false
+ };
+
+ return function(options) {
+ options = _.extend({}, defaults, options);
+
+ return $modal(options);
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/dialog/dialog.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/dialog/dialog.jade b/modules/web-console/frontend/app/modules/dialog/dialog.jade
new file mode 100644
index 0000000..0043709
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/dialog/dialog.jade
@@ -0,0 +1,26 @@
+//-
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+.modal(tabindex='-1' role='dialog')
+ .modal-dialog
+ .modal-content
+ .modal-header
+ button.close(ng-click='$hide()' aria-hidden='true') ×
+ h4.modal-title {{title}}
+ .modal-body(ng-show='content')
+ p(ng-bind-html='content' style='text-align: left;')
+ .modal-footer
+ button.btn.btn-primary(id='confirm-btn-confirm' ng-click='$hide()') Ok
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/dialog/dialog.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/dialog/dialog.module.js b/modules/web-console/frontend/app/modules/dialog/dialog.module.js
new file mode 100644
index 0000000..c9ba9f9
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/dialog/dialog.module.js
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import angular from 'angular';
+
+import igniteDialog from './dialog.directive';
+import igniteDialogTitle from './dialog-title.directive';
+import igniteDialogContent from './dialog-content.directive';
+import IgniteDialog from './dialog.factory';
+
+angular
+.module('ignite-console.dialog', [
+
+])
+.factory(...IgniteDialog)
+.directive(...igniteDialog)
+.directive(...igniteDialogTitle)
+.directive(...igniteDialogContent);
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/bs-select-placeholder.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/bs-select-placeholder.directive.js b/modules/web-console/frontend/app/modules/form/field/bs-select-placeholder.directive.js
new file mode 100644
index 0000000..83f438d
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/bs-select-placeholder.directive.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Override AngularStrap "bsSelect" in order to dynamically change placeholder and class.
+export default ['bsSelect', [() => {
+ const link = (scope, $element, attrs, [ngModel]) => {
+ if (!ngModel)
+ return;
+
+ const $render = ngModel.$render;
+
+ ngModel.$render = () => {
+ $render();
+
+ const value = ngModel.$viewValue;
+
+ if (_.isNil(value) || (attrs.multiple && !value.length)) {
+ $element.html(attrs.placeholder);
+
+ $element.addClass('placeholder');
+ }
+ else
+ $element.removeClass('placeholder');
+ };
+ };
+
+ return {
+ priority: 1,
+ restrict: 'A',
+ link,
+ require: ['?ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/down.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/down.directive.js b/modules/web-console/frontend/app/modules/form/field/down.directive.js
new file mode 100644
index 0000000..659933e
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/down.directive.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteFormFieldDown', ['$tooltip', ($tooltip) => {
+ const controller = ['$element', function($element) {
+ $tooltip($element, { title: 'Move item down' });
+
+ this.down = () => {
+ const i = this.models.indexOf(this.model);
+
+ this.models.splice(i, 1);
+ this.models.splice(i + 1, 0, this.model);
+ };
+ }];
+
+ return {
+ restrict: 'A',
+ bindToController: {
+ model: '=ngModel',
+ models: '=models'
+ },
+ controller,
+ controllerAs: '$ctrl'
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/feedback.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/feedback.scss b/modules/web-console/frontend/app/modules/form/field/feedback.scss
new file mode 100644
index 0000000..08d0aef
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/feedback.scss
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "../../../../public/stylesheets/variables";
+
+.form-field-feedback {
+ position: relative;
+ width: 0;
+ height: 28px;
+ float: right;
+ z-index: 2;
+
+ color: $brand-primary;
+ line-height: $input-height;
+ pointer-events: initial;
+ text-align: center;
+
+ &:before {
+ position: absolute;
+ right: 0;
+ width: 38px;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/field.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/field.scss b/modules/web-console/frontend/app/modules/form/field/field.scss
new file mode 100644
index 0000000..5717766
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/field.scss
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "../../../../public/stylesheets/variables";
+
+.indexField {
+ float: left;
+ line-height: 28px;
+ margin-right: 5px;
+ color: $brand-primary;
+}
+
+.form-field-save {
+ position: relative;
+ width: 0;
+ height: 28px;
+ float: right;
+ z-index: 2;
+
+ line-height: $input-height;
+ pointer-events: initial;
+ text-align: center;
+
+ &:before {
+ position: absolute;
+ right: 0;
+ width: 38px;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/form-control-feedback.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/form-control-feedback.directive.js b/modules/web-console/frontend/app/modules/form/field/form-control-feedback.directive.js
new file mode 100644
index 0000000..797ba69
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/form-control-feedback.directive.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['formFieldFeedback', [() => {
+ const link = ($scope, $element, $attrs, [form]) => {
+ let name = $scope.name;
+
+ if (_.isNil(name))
+ name = $attrs.name;
+
+ const err = $attrs.igniteError;
+ const msg = $attrs.igniteErrorMessage;
+
+ if (name && err && msg) {
+ form.$errorMessages = form.$errorMessages || {};
+ form.$errorMessages[name] = form.$errorMessages[name] || {};
+ form.$errorMessages[name][err] = msg;
+ }
+ };
+
+ return {
+ restrict: 'C',
+ link,
+ require: ['^form']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/input/autofocus.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/input/autofocus.directive.js b/modules/web-console/frontend/app/modules/form/field/input/autofocus.directive.js
new file mode 100644
index 0000000..8ffc9a0
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/input/autofocus.directive.js
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteFormFieldInputAutofocus', ['$timeout', ($timeout) => {
+ const link = (scope, el, attrs) => {
+ if (_.isUndefined(attrs.igniteFormFieldInputAutofocus) || attrs.igniteFormFieldInputAutofocus !== 'true')
+ return;
+
+ $timeout(() => el.focus(), 100);
+ };
+
+ return {
+ restrict: 'A',
+ link
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/input/select.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/input/select.scss b/modules/web-console/frontend/app/modules/form/field/input/select.scss
new file mode 100644
index 0000000..55bbd58
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/input/select.scss
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.select.dropdown-menu.ng-leave {
+ transition: none !important; /* disable transitions */
+ animation: none 0s !important; /* disable keyframe animations */
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/input/text.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/input/text.scss b/modules/web-console/frontend/app/modules/form/field/input/text.scss
new file mode 100644
index 0000000..c76bebd
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/input/text.scss
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.checkbox label .input-tip {
+ position: initial;
+}
+
+.input-tip .fa-floppy-o {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+
+ width: 34px;
+ height: 34px;
+
+ text-align: center;
+
+ display: inline-block;
+ line-height: 28px;
+ pointer-events: initial;
+}
+
+.input-tip .form-control-feedback {
+ height: auto;
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/label.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/label.directive.js b/modules/web-console/frontend/app/modules/form/field/label.directive.js
new file mode 100644
index 0000000..97ba598
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/label.directive.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteFormFieldLabel', [() => {
+ return {
+ restrict: 'E',
+ compile() {
+ return {
+ post($scope, $element, $attrs, [form, field], $transclude) {
+ $transclude($scope, function(clone) {
+ const text = clone.text();
+
+ if (/(.*):$/.test(text))
+ field.name = /(.*):$/.exec(text)[1];
+
+ const $label = $element.parent().parent().find('.group-legend > label, .ignite-field > label');
+
+ if ($label[0] && $element[0].id) {
+ const id = $element[0].id;
+
+ $label[0].id = id.indexOf('+') >= 0 ? $scope.$eval(id) : id;
+ }
+
+ $label.append(clone);
+ });
+ }
+ };
+ },
+ replace: true,
+ transclude: true,
+ require: ['^form', '?^igniteFormField']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js b/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js
new file mode 100644
index 0000000..5005280
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const template = '<i class="tipField fa fa-question-circle"></i>';
+
+export default ['igniteFormFieldTooltip', ['$tooltip', ($tooltip) => {
+ const link = ($scope, $element, $attrs, [form, field], $transclude) => {
+ const content = Array.prototype.slice
+ .apply($transclude($scope))
+ .reduce((html, el) => html += el.outerHTML || el.textContent || el, '');
+
+ $tooltip($element, { title: content });
+
+ if (field)
+ $element.attr('id', field.for + 'Tooltip');
+
+ // TODO cleanup css styles.
+ if ($element.hasClass('tipLabel'))
+ $element.removeClass('tipField');
+
+ if ($element.parent('label').length)
+ $element.addClass('tipLabel').removeClass('tipField');
+ };
+
+ return {
+ priority: 1,
+ restrict: 'E',
+ scope: {},
+ template,
+ link,
+ replace: true,
+ transclude: true,
+ require: ['^form', '?^igniteFormField']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/field/up.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/up.directive.js b/modules/web-console/frontend/app/modules/form/field/up.directive.js
new file mode 100644
index 0000000..aba1cbe
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/field/up.directive.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteFormFieldUp', ['$tooltip', ($tooltip) => {
+ const controller = ['$element', function($element) {
+ $tooltip($element, { title: 'Move item up' });
+
+ this.up = () => {
+ const idx = this.models.indexOf(this.model);
+
+ this.models.splice(idx, 1);
+ this.models.splice(idx - 1, 0, this.model);
+ };
+ }];
+
+ return {
+ restrict: 'A',
+ bindToController: {
+ model: '=ngModel',
+ models: '=models'
+ },
+ controller,
+ controllerAs: '$ctrl'
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/form.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/form.module.js b/modules/web-console/frontend/app/modules/form/form.module.js
new file mode 100644
index 0000000..23eafcd
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/form.module.js
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import angular from 'angular';
+
+// Fields styles.
+import './field/field.scss';
+import './field/feedback.scss';
+import './field/input/text.scss';
+import './field/input/select.scss';
+
+// Panel.
+import igniteFormPanel from './panel/panel.directive';
+import igniteFormPanelField from './panel/field.directive';
+import igniteFormPanelChevron from './panel/chevron.directive';
+import igniteFormRevert from './panel/revert.directive';
+
+// Field.
+import igniteFormFieldLabel from './field/label.directive';
+import igniteFormFieldTooltip from './field/tooltip.directive';
+import placeholder from './field/bs-select-placeholder.directive';
+
+// Group.
+import igniteFormGroupAdd from './group/add.directive';
+import igniteFormGroupTooltip from './group/tooltip.directive';
+
+// Validators.
+import ipaddress from './validator/ipaddress.directive';
+import javaKeywords from './validator/java-keywords.directive';
+import javaPackageSpecified from './validator/java-package-specified.directive';
+import javaBuiltInClass from './validator/java-built-in-class.directive';
+import javaIdentifier from './validator/java-identifier.directive';
+import javaPackageName from './validator/java-package-name.directive';
+import propertyValueSpecified from './validator/property-value-specified.directive';
+import propertyUnique from './validator/property-unique.directive';
+import unique from './validator/unique.directive';
+import uuid from './validator/uuid.directive';
+
+// Helpers.
+import igniteFormFieldInputAutofocus from './field/input/autofocus.directive';
+import igniteFormControlFeedback from './field/form-control-feedback.directive';
+import igniteFormFieldUp from './field/up.directive';
+import igniteFormFieldDown from './field/down.directive';
+
+angular
+.module('ignite-console.Form', [
+
+])
+// Panel.
+.directive(...igniteFormPanel)
+.directive(...igniteFormPanelField)
+.directive(...igniteFormPanelChevron)
+.directive(...igniteFormRevert)
+// Field.
+.directive(...igniteFormFieldLabel)
+.directive(...igniteFormFieldTooltip)
+.directive(...placeholder)
+// Group.
+.directive(...igniteFormGroupAdd)
+.directive(...igniteFormGroupTooltip)
+// Validators.
+.directive(...ipaddress)
+.directive(...javaKeywords)
+.directive(...javaPackageSpecified)
+.directive(...javaBuiltInClass)
+.directive(...javaIdentifier)
+.directive(...javaPackageName)
+.directive(...propertyValueSpecified)
+.directive(...propertyUnique)
+.directive(...unique)
+.directive(...uuid)
+// Helpers.
+.directive(...igniteFormFieldInputAutofocus)
+.directive(...igniteFormControlFeedback)
+.directive(...igniteFormFieldUp)
+.directive(...igniteFormFieldDown)
+// Generator of globally unique identifier.
+.factory('IgniteFormGUID', [() => {
+ let guid = 0;
+
+ return () => `form-field-${guid++}`;
+}]);
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/group/add.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/group/add.directive.js b/modules/web-console/frontend/app/modules/form/group/add.directive.js
new file mode 100644
index 0000000..7e9a50c
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/group/add.directive.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const template = '<i class="group-legend-btn fa fa-plus"></i>';
+
+export default ['igniteFormGroupAdd', ['$tooltip', ($tooltip) => {
+ const link = ($scope, $element, $attrs, $ctrls, $transclude) => {
+ const content = Array.prototype.slice
+ .apply($transclude($scope))
+ .reduce((html, el) => html += el.outerHTML || el.textContent || el, '');
+
+ $tooltip($element, { title: content });
+
+ $element.closest('.group').find('.group-legend').append($element);
+ };
+
+ return {
+ restrict: 'E',
+ scope: {},
+ template,
+ link,
+ replace: true,
+ transclude: true,
+ require: ['^form']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js b/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js
new file mode 100644
index 0000000..3e470e1
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const template = '<i class="group-legend-btn fa fa-question-circle"></i>';
+
+export default ['igniteFormGroupTooltip', ['$tooltip', ($tooltip) => {
+ const link = ($scope, $element, $attrs, $ctrls, $transclude) => {
+ const content = Array.prototype.slice
+ .apply($transclude($scope))
+ .reduce((html, el) => html += el.outerHTML || el.textContent || el, '');
+
+ $tooltip($element, { title: content });
+
+ $element.closest('.group').find('.group-legend').append($element);
+ };
+
+ return {
+ restrict: 'E',
+ scope: {},
+ template,
+ link,
+ replace: true,
+ transclude: true,
+ require: ['^form']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/panel/chevron.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/panel/chevron.directive.js b/modules/web-console/frontend/app/modules/form/panel/chevron.directive.js
new file mode 100644
index 0000000..6af560b
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/panel/chevron.directive.js
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const template = `<i class='fa' ng-class='isOpen ? "fa-chevron-circle-down" : "fa-chevron-circle-right"'></i>`; // eslint-disable-line quotes
+
+export default ['igniteFormPanelChevron', [() => {
+ const controller = [() => {}];
+
+ const link = ($scope, $element, $attrs, [bsCollapseCtrl]) => {
+ const $target = $element.parent().parent().find('.panel-collapse');
+
+ bsCollapseCtrl.$viewChangeListeners.push(function() {
+ const index = bsCollapseCtrl.$targets.reduce((acc, el, i) => {
+ if (el[0] === $target[0])
+ acc.push(i);
+
+ return acc;
+ }, [])[0];
+
+ $scope.isOpen = false;
+
+ const active = bsCollapseCtrl.$activeIndexes();
+
+ if ((active instanceof Array) && active.indexOf(index) !== -1 || active === index)
+ $scope.isOpen = true;
+ });
+ };
+
+ return {
+ restrict: 'E',
+ scope: {},
+ link,
+ template,
+ controller,
+ replace: true,
+ transclude: true,
+ require: ['^bsCollapse']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/panel/field.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/panel/field.directive.js b/modules/web-console/frontend/app/modules/form/panel/field.directive.js
new file mode 100644
index 0000000..5dc7b07
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/panel/field.directive.js
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteFormPanelField', ['$parse', 'IgniteLegacyTable', ($parse, LegacyTable) => {
+ const link = (scope, element, attrs, [ngModelCtrl, formCtrl]) => {
+ formCtrl.$defaults = formCtrl.$defaults || {};
+
+ const { name, ngModel } = attrs;
+ const getter = () => $parse(ngModel)(scope);
+
+ const saveDefault = () => {
+ formCtrl.$defaults[name] = _.cloneDeep(getter());
+ };
+
+ const resetDefault = () => {
+ ngModelCtrl.$viewValue = formCtrl.$defaults[name];
+
+ ngModelCtrl.$valid = true;
+ ngModelCtrl.$invalid = false;
+ ngModelCtrl.$error = {};
+ ngModelCtrl.$render();
+ };
+
+ if (!(_.isNull(formCtrl.$defaults[name]) || _.isUndefined(formCtrl.$defaults[name])))
+ resetDefault();
+ else
+ saveDefault();
+
+ scope.tableReset = () => {
+ if (!LegacyTable.tableSaveAndReset())
+ LegacyTable.tableReset();
+ };
+
+ scope.$watch(() => formCtrl.$pristine, () => {
+ if (!formCtrl.$pristine)
+ return;
+
+ saveDefault();
+ resetDefault();
+ });
+
+ scope.$watch(() => ngModelCtrl.$modelValue, () => {
+ if (!formCtrl.$pristine)
+ return;
+
+ saveDefault();
+ });
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel', '^form']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/panel/panel.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/panel/panel.directive.js b/modules/web-console/frontend/app/modules/form/panel/panel.directive.js
new file mode 100644
index 0000000..b8e7c25
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/panel/panel.directive.js
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['form', [() => {
+ const link = (scope, $element, $attrs, [form]) => {
+ const $form = $element.parent().closest('form');
+
+ scope.$watch(() => {
+ return $form.hasClass('ng-pristine');
+ }, (value) => {
+ if (!value)
+ return;
+
+ form.$setPristine();
+ });
+ };
+
+ return {
+ restrict: 'E',
+ link,
+ require: ['^form']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/panel/revert.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/panel/revert.directive.js b/modules/web-console/frontend/app/modules/form/panel/revert.directive.js
new file mode 100644
index 0000000..2076b0d
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/panel/revert.directive.js
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const template = '<i ng-show="form.$dirty" class="fa fa-undo pull-right" ng-click="revert($event)"></i>';
+
+export default ['igniteFormRevert', ['$tooltip', 'IgniteLegacyTable', ($tooltip, LegacyTable) => {
+ const link = (scope, $element, $attrs, [form]) => {
+ $tooltip($element, { title: 'Undo unsaved changes' });
+
+ scope.form = form;
+
+ scope.revert = (e) => {
+ e.stopPropagation();
+
+ LegacyTable.tableReset();
+
+ _.forOwn(form.$defaults, (value, name) => {
+ const field = form[name];
+
+ if (field) {
+ field.$viewValue = value;
+ field.$setViewValue(value);
+ field.$setPristine();
+ field.$render();
+ }
+ });
+
+ form.$setPristine();
+ };
+ };
+
+ return {
+ restrict: 'E',
+ scope: { },
+ template,
+ link,
+ replace: true,
+ require: ['^form']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/ipaddress.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/ipaddress.directive.js b/modules/web-console/frontend/app/modules/form/validator/ipaddress.directive.js
new file mode 100644
index 0000000..77e63f6
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/ipaddress.directive.js
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['ipaddress', ['IgniteInetAddress', (InetAddress) => {
+ const onlyDigits = (str) => (/^\d+$/.test(str));
+
+ const strictParseInt = (str) => onlyDigits(str) ? parseInt(str, 10) : Number.NaN;
+
+ const parse = (commonIpAddress) => {
+ const [ipOrHost, portRange] = commonIpAddress.split(':');
+ const ports = _.isUndefined(portRange) ? [] : portRange.split('..').map(strictParseInt);
+
+ return {ipOrHost, ports};
+ };
+
+ const link = (scope, el, attrs, [ngModel]) => {
+ const isEmpty = (modelValue) => {
+ return ngModel.$isEmpty(modelValue) || _.isUndefined(attrs.ipaddress) || attrs.ipaddress !== 'true';
+ };
+
+ const portRange = !_.isNil(attrs.ipaddressWithPortRange);
+
+ if (attrs.ipaddressWithPort) {
+ ngModel.$validators.ipaddressPort = (modelValue) => {
+ if (isEmpty(modelValue) || modelValue.indexOf(':') === -1)
+ return true;
+
+ if ((modelValue.match(/:/g) || []).length > 1)
+ return false;
+
+ const {ports} = parse(modelValue);
+
+ if (ports.length !== 1)
+ return portRange;
+
+ return InetAddress.validPort(ports[0]);
+ };
+ }
+
+ if (portRange) {
+ ngModel.$validators.ipaddressPortRange = (modelValue) => {
+ if (isEmpty(modelValue) || modelValue.indexOf('..') === -1)
+ return true;
+
+ const {ports} = parse(modelValue);
+
+ if (ports.length !== 2)
+ return false;
+
+ return InetAddress.validPort(ports[0]) && InetAddress.validPort(ports[1]) && ports[0] < ports[1];
+ };
+ }
+
+ ngModel.$validators.ipaddress = (modelValue) => {
+ if (isEmpty(modelValue))
+ return true;
+
+ const {ipOrHost, ports} = parse(modelValue);
+
+ if (attrs.ipaddressWithPort || attrs.ipaddressWithPortRange || ports.length === 0)
+ return InetAddress.validHost(ipOrHost);
+
+ return false;
+ };
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/java-built-in-class.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/java-built-in-class.directive.js b/modules/web-console/frontend/app/modules/form/validator/java-built-in-class.directive.js
new file mode 100644
index 0000000..1a4b504
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/java-built-in-class.directive.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['javaBuiltInClass', ['JavaTypes', (JavaTypes) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.javaBuiltInClass) || !attrs.javaBuiltInClass)
+ return;
+
+ ngModel.$validators.javaBuiltInClass = (value) => JavaTypes.nonBuiltInClass(value);
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/java-identifier.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/java-identifier.directive.js b/modules/web-console/frontend/app/modules/form/validator/java-identifier.directive.js
new file mode 100644
index 0000000..5cbf7fb
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/java-identifier.directive.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['javaIdentifier', ['JavaTypes', (JavaTypes) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.javaIdentifier) || !attrs.javaIdentifier)
+ return;
+
+ ngModel.$validators.javaIdentifier = (value) => JavaTypes.validIdentifier(value);
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/java-keywords.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/java-keywords.directive.js b/modules/web-console/frontend/app/modules/form/validator/java-keywords.directive.js
new file mode 100644
index 0000000..d97e59a
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/java-keywords.directive.js
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['javaKeywords', ['JavaTypes', (JavaTypes) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.javaKeywords) || !attrs.javaKeywords)
+ return;
+
+ const packageOnly = attrs.javaPackageName === 'package-only';
+
+ ngModel.$validators.javaKeywords = (value) => {
+ if (value) {
+ if (!JavaTypes.validIdentifier(value) || (!packageOnly && !JavaTypes.packageSpecified(value)))
+ return true;
+
+ return _.findIndex(value.split('.'), JavaTypes.isKeywords) < 0;
+ }
+
+ return true;
+ };
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/java-package-name.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/java-package-name.directive.js b/modules/web-console/frontend/app/modules/form/validator/java-package-name.directive.js
new file mode 100644
index 0000000..ac38179
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/java-package-name.directive.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['javaPackageName', ['JavaTypes', (JavaTypes) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.javaPackageName) || !attrs.javaPackageName)
+ return;
+
+ ngModel.$validators.javaPackageName = (value) => JavaTypes.validPackage(value);
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/java-package-specified.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/java-package-specified.directive.js b/modules/web-console/frontend/app/modules/form/validator/java-package-specified.directive.js
new file mode 100644
index 0000000..451d7ec
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/java-package-specified.directive.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['javaPackageSpecified', ['JavaTypes', (JavaTypes) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.javaPackageSpecified))
+ return;
+
+ const allowBuiltIn = attrs.javaPackageSpecified === 'allow-built-in';
+
+ ngModel.$validators.javaPackageSpecified = (value) => !value || !JavaTypes.validIdentifier(value) || JavaTypes.packageSpecified(value) ||
+ (allowBuiltIn && !JavaTypes.nonBuiltInClass(value));
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/property-unique.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/property-unique.directive.js b/modules/web-console/frontend/app/modules/form/validator/property-unique.directive.js
new file mode 100644
index 0000000..8cfae89
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/property-unique.directive.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['ignitePropertyUnique', ['$parse', ($parse) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.ignitePropertyUnique) || !attrs.ignitePropertyUnique)
+ return;
+
+ ngModel.$validators.ignitePropertyUnique = (value) => {
+ const arr = $parse(attrs.ignitePropertyUnique)(scope);
+
+ // Return true in case if array not exist, array empty.
+ if (!value || !arr || !arr.length)
+ return true;
+
+ const key = value.split('=')[0];
+ const idx = _.findIndex(arr, (item) => item.split('=')[0] === key);
+
+ // In case of new element check all items.
+ if (attrs.name === 'new')
+ return idx < 0;
+
+ // Check for $index in case of editing in-place.
+ return (_.isNumber(scope.$index) && (idx < 0 || scope.$index === idx));
+ };
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/property-value-specified.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/property-value-specified.directive.js b/modules/web-console/frontend/app/modules/form/validator/property-value-specified.directive.js
new file mode 100644
index 0000000..d113a4f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/property-value-specified.directive.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['ignitePropertyValueSpecified', [() => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.ignitePropertyValueSpecified) || !attrs.ignitePropertyValueSpecified)
+ return;
+
+ ngModel.$validators.ignitePropertyValueSpecified = (value) => value ? value.indexOf('=') > 0 : true;
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/unique.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/unique.directive.js b/modules/web-console/frontend/app/modules/form/validator/unique.directive.js
new file mode 100644
index 0000000..0e6af18
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/unique.directive.js
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['igniteUnique', ['$parse', ($parse) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ if (_.isUndefined(attrs.igniteUnique) || !attrs.igniteUnique)
+ return;
+
+ const isNew = _.startsWith(attrs.name, 'new');
+ const property = attrs.igniteUniqueProperty;
+
+ ngModel.$validators.igniteUnique = (value) => {
+ const arr = $parse(attrs.igniteUnique)(scope);
+
+ // Return true in case if array not exist, array empty.
+ if (!arr || !arr.length)
+ return true;
+
+ const idx = _.findIndex(arr, (item) => (property ? item[property] : item) === value);
+
+ // In case of new element check all items.
+ if (isNew)
+ return idx < 0;
+
+ // Check for $index in case of editing in-place.
+ return (_.isNumber(scope.$index) && (idx < 0 || scope.$index === idx));
+ };
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/form/validator/uuid.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/validator/uuid.directive.js b/modules/web-console/frontend/app/modules/form/validator/uuid.directive.js
new file mode 100644
index 0000000..0704175
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/form/validator/uuid.directive.js
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default ['uuid', ['JavaTypes', (JavaTypes) => {
+ const link = (scope, el, attrs, [ngModel]) => {
+ const isEmpty = (modelValue) => {
+ return ngModel.$isEmpty(modelValue) || _.isUndefined(attrs.uuid) || attrs.uuid !== 'true';
+ };
+
+ ngModel.$validators.uuid = (modelValue) => {
+ if (isEmpty(modelValue))
+ return true;
+
+ return JavaTypes.validUUID(modelValue);
+ };
+ };
+
+ return {
+ restrict: 'A',
+ link,
+ require: ['ngModel']
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js b/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js
new file mode 100644
index 0000000..cf9f561
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import angular from 'angular';
+
+// Getting started pages.
+import PAGES from 'app/data/getting-started.json';
+
+angular
+ .module('ignite-console.getting-started', [])
+ .provider('igniteGettingStarted', function() {
+ const items = PAGES;
+
+ this.push = (before, data) => {
+ const idx = _.findIndex(items, {title: before});
+
+ if (idx < 0)
+ items.push(data);
+ else
+ items.splice(idx, 0, data);
+ };
+
+ this.update = (before, data) => {
+ const idx = _.findIndex(items, {title: before});
+
+ if (idx >= 0)
+ items[idx] = data;
+ };
+
+ this.$get = [function() {
+ return items;
+ }];
+ })
+ .service('gettingStarted', ['$rootScope', '$modal', 'igniteGettingStarted', function($root, $modal, igniteGettingStarted) {
+ const _model = igniteGettingStarted;
+
+ let _page = 0;
+
+ const scope = $root.$new();
+
+ scope.ui = {
+ showGettingStarted: false
+ };
+
+ function _fillPage() {
+ scope.title = _model[_page].title;
+ scope.message = _model[_page].message.join(' ');
+ }
+
+ scope.isFirst = () => _page === 0;
+
+ scope.isLast = () => _page === _model.length - 1;
+
+ scope.next = () => {
+ _page += 1;
+
+ _fillPage();
+ };
+
+ scope.prev = () => {
+ _page -= 1;
+
+ _fillPage();
+ };
+
+ const dialog = $modal({templateUrl: '/templates/getting-started.html', scope, placement: 'center', show: false, backdrop: 'static'});
+
+ scope.close = () => {
+ try {
+ localStorage.showGettingStarted = scope.ui.showGettingStarted;
+ }
+ catch (ignore) {
+ // No-op.
+ }
+
+ dialog.hide();
+ };
+
+ return {
+ tryShow: (force) => {
+ try {
+ scope.ui.showGettingStarted = _.isNil(localStorage.showGettingStarted)
+ || localStorage.showGettingStarted === 'true';
+ }
+ catch (ignore) {
+ // No-op.
+ }
+
+ if (force || scope.ui.showGettingStarted) {
+ _page = 0;
+
+ _fillPage();
+
+ dialog.$promise.then(dialog.show);
+ }
+ }
+ };
+ }]);