# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
dlux-web/node
+dlux-web/src/LICENSE
<parent>
<groupId>org.opendaylight.controller.archetypes</groupId>
<artifactId>archetypes-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath/>
</parent>
<properties>
<osgi.core.version>5.0.0</osgi.core.version>
<apache.felix.compendium>1.4.0</apache.felix.compendium>
- <dlux.loader.version>0.4.0-SNAPSHOT</dlux.loader.version>
+ <dlux.loader.version>0.5.0-SNAPSHOT</dlux.loader.version>
</properties>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<module>node</module>
<module>topology</module>
<module>yangui</module>
+ <module>yangman</module>
<module>yangutils</module>
<module>yangvisualizer</module>
<module>sigmatopology</module>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>bundles</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>dlux.yangman</artifactId>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.osgi.compendium.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>dlux.yangman.resources</artifactId>
+ <version>${yangman.resources.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <!--loader Resources-->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>org.opendaylight.dlux</groupId>
+ <includeArtifactIds>dlux.yangman.resources</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader,
+ org.slf4j
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_dlux:Main</url>
+ </scm>
+</project>
--- /dev/null
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="yangman"/>
+ <property name="url" value="/src/app/yangman"/>
+ <property name="directory" value="/yangman"/>
+ <property name="requireJs" value="app/yangman/main"/>
+ <property name="angularJs" value="app.yangman"/>
+ </bean>
+</blueprint>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>bundles</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
<executions>
<!--loader Resources-->
<execution>
"version": "0.2.0",
"dependencies": {
"angular": "~1.4.0",
+ "angular-resource": "~1.4.0",
+ "angular-cookies": "~1.4.0",
+ "angular-sanitize": "~1.4.0",
+ "angular-messages": "~1.4.0",
+ "angular-animate": "~1.4.0",
+ "angular-aria": "~1.4.0",
"json3": "~3.2.4",
"jquery": "~1.9.1",
"jquery-ui": "1.11.1",
"es5-shim": "~2.0.8",
- "angular-resource": "~1.4.0",
- "angular-cookies": "~1.4.0",
- "angular-sanitize": "~1.4.0",
"angular-ui-date": "~0.0.11",
"requirejs": "~2.1.14",
"font-awesome": "~4.0.3",
"angular-ui-router": "~0.2.10",
"angular-ui-utils": "~0.0.3",
"d3": "~3.3.2",
- "restangular": "1.2.1",
+ "restangular": "1.4.0",
"angular-ui-select2": "~0.0.5",
"underscore": "~1.8.3",
"underscore.string": "~3.2.1",
"select2": "^3.3.2",
"select2-bootstrap-css": "~1.2.5",
"footable": "2.0.1",
- "angular-translate": "2.2.0",
- "angular-translate-loader-static-files": "2.2.0",
"vis": "2.0.0",
"sigma": "https://github.com/jacomyal/sigma.js/releases/download/v1.0.3/release-v1.0.3.zip",
"ng-slider": "2.2.2",
- "ng-tiny-scrollbar": "~0.9.0",
"zeroclipboard": "~2.2.0",
"ng-clip": "~0.2.6",
- "angular-translate-loader-partial": "~2.7.2"
+ "angular-translate": "~2.7.2",
+ "angular-translate-loader-static-files": "~2.7.2",
+ "angular-translate-loader-partial": "~2.7.2",
+ "angular-material": "~1.0.8",
+ "material-design-icons": "~2.2.3"
},
"devDependencies": {
"angular": "~1.4.0",
"resolutions": {
"angular": "~1.4.0",
"angular-translate": "~2.7.2",
+ "angular-animate": "~1.4.0",
"select2": "^3.3.2"
}
}
*/\r
build_dir: 'build',\r
compile_dir: 'target/generated-resources/pages',\r
- \r
+\r
/**\r
* This is a collection of file patterns that refer to our app code (the\r
* stuff in `src/`). These file paths are used in the configuration of\r
jsunit: [ 'src/**/*.spec.js' ],\r
js_common: [ 'src/common/**/*.js', '!src/common/**/*.spec.js', '!src/common/assets/**/*.js' ],\r
js_app: [ 'src/app/**/*.js', '!src/app/**/*.spec.js', '!src/app/assets/**/*.js' ],\r
- app_assets: [ '! src/app/yangui/assets/js/**/*.js' ],\r
+ app_assets: [ '! src/app/yangui/assets/js/**/*.js', '! src/app/yangman/assets/js/**/*.js' ],\r
\r
atpl: [ 'src/app/**/*.tpl.html' ],\r
ctpl: [ 'src/common/**/*.tpl.html' ],\r
'vendor/ng-clip/src/ngClip.js',\r
'vendor/zeroclipboard/dist/ZeroClipboard.js',\r
'vendor/angular-translate-loader-partial/angular-translate-loader-partial.js',\r
+ 'vendor/angular-animate/angular-animate.min.js',\r
+ 'vendor/angular-aria/angular-aria.min.js',\r
+ 'vendor/angular-material/angular-material.min.js',\r
+ 'vendor/angular-messages/angular-messages.min.js',\r
],\r
css: [\r
'vendor/ng-grid/ng-grid.min.css',\r
'vendor/footable/css/footable.core.min.css',\r
'vendor/footable/css/footable.standalone.min.css',\r
'vendor/vis/dist/vis.min.css',\r
- 'vendor/ng-slider/dist/css/ng-slider.min.css'\r
-\r
+ 'vendor/ng-slider/dist/css/ng-slider.min.css',\r
+ 'vendor/angular-material/angular-material.css',\r
+ 'vendor/material-design-icons/iconfont/*',\r
],\r
images: [\r
'vendor/select2/select2.png',\r
'vendor/select2/select2x2.png'\r
],\r
assets: [\r
- 'vendor/zeroclipboard/dist/ZeroClipboard.swf'\r
+ 'vendor/zeroclipboard/dist/ZeroClipboard.swf',\r
],\r
font: [\r
'vendor/font-awesome/font/*',\r
- 'vendor/footable/css/fonts/*'\r
+ 'vendor/footable/css/fonts/*',\r
+\r
]\r
}\r
};\r
<parent>\r
<groupId>org.opendaylight.dlux</groupId>\r
<artifactId>dlux-parent</artifactId>\r
- <version>0.4.0-SNAPSHOT</version>\r
+ <version>0.5.0-SNAPSHOT</version>\r
<relativePath>..</relativePath>\r
</parent>\r
\r
<artifactId>dlux.yangui.resources</artifactId>\r
<version>${yangui.resources.version}</version>\r
</dependency>\r
+ <dependency>\r
+ <groupId>org.opendaylight.dlux</groupId>\r
+ <artifactId>dlux.yangman.resources</artifactId>\r
+ <version>${yangman.resources.version}</version>\r
+ </dependency>\r
<dependency>\r
<groupId>org.opendaylight.dlux</groupId>\r
<artifactId>dlux.yangvisualizer.resources</artifactId>\r
<include>app/routingConfig.js</include>\r
<include>app/node/</include>\r
<include>app/yangui/</include>\r
+ <include>app/yangman/</include>\r
<include>app/yangvisualizer/</include>\r
<include>app/topology/</include>\r
<include>app/core/</include>\r
<plugin>\r
<groupId>org.apache.maven.plugins</groupId>\r
<artifactId>maven-dependency-plugin</artifactId>\r
- <version>2.6</version>\r
<executions>\r
<!--src/app/ Resources-->\r
<execution>\r
<includeArtifactIds>\r
dlux.node.resources,\r
dlux.yangui.resources,\r
+ dlux.yangman.resources,\r
dlux.yangvisualizer.resources,\r
dlux.topology.resources,\r
dlux.core.resources,\r
color: white;
}
-.main input[type="text"] {
- background-color: #58595B;
- color: white;
-}
-
-
.select2-choice, .select2-choices {
background-color: #58595B !important;
}
.btn-orange {
background-color: orange;
}
-h1, h2, h3, h4, h5, h6, span {
+h1, h2, h3, h4, h5, h6 {
color: white;
}
}
.select2-choice {
- border: 1px solid #939598 !important;
+ border: 1px solid #939598 !important;
}
#red {
.navbar {
border-bottom: none !important;
background-color: black !important;
-}
+}
@media all and (max-width: 462px) {
-
+
.navbar {
border-bottom: none !important;
background-color: #F3F3F4 !important;
-}
+}
#page_logo {
display: none;
}
color: #666;\r
}\r
\r
+.main {\r
+ position: relative;\r
+}\r
\r
/**\r
* Navigation\r
\r
/**\r
* Now that all app-wide styles have been applied, we can load the styles for\r
- * all the submodules and components we are using. \r
+ * all the submodules and components we are using.\r
*\r
* TODO: In a later version of this boilerplate, I'd like to automate this.\r
*/\r
@import '../common/login/login.less';\r
@import '../common/topbar/topbar.less';\r
@import '../app/topology/topology.less';\r
+@import '../app/yangman/yangman.less';\r
+@import '../assets/js/codemirror/lib/codemirror.less';\r
+@import '../assets/js/codemirror/theme/eclipse.less';\r
+@import '../assets/js/codemirror/theme/eclipse-disabled.less';\r
+@import '../assets/js/codemirror/addon/hint/show-hint.less';\r
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>features-parent</artifactId>
- <version>1.7.0-SNAPSHOT</version>
+ <version>1.8.0-SNAPSHOT</version>
<relativePath/>
</parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>features-dlux</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<name>DLUX - Features </name>
<packaging>jar</packaging>
<properties>
<features.file>features.xml</features.file>
- <restconf.version>1.4.0-SNAPSHOT</restconf.version>
+ <restconf.version>1.5.0-SNAPSHOT</restconf.version>
</properties>
<dependencies>
<dependency>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>features-test</artifactId>
- <version>1.7.0-SNAPSHOT</version>
+ <version>1.8.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>opendaylight-karaf-empty</artifactId>
- <version>1.7.0-SNAPSHOT</version>
+ <version>1.8.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<artifactId>dlux.yangui</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>dlux.yangman</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux.common.yangutils</artifactId>
<bundle>mvn:org.opendaylight.dlux/dlux.common.sigmatopology/{{VERSION}}</bundle>
</feature>
+ <feature name="odl-dlux-yangman" version='${project.version}' description="Enable Yangman in Opendaylight dlux">
+ <feature>odl-dlux-core</feature>
+ <feature version="${restconf.version}">odl-mdsal-apidocs</feature>
+ <bundle>mvn:org.opendaylight.dlux/dlux.yangman/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.dlux/dlux.common.yangutils/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.dlux/dlux.common.sigmatopology/{{VERSION}}</bundle>
+ </feature>
+
<feature name="odl-dlux-yangvisualizer" version='${project.version}' description="Enable Yang visualizer in Opendaylight dlux">
<feature>odl-dlux-core</feature>
<bundle>mvn:org.opendaylight.dlux/dlux.yangvisualizer/{{VERSION}}</bundle>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>loader</artifactId>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>loader.implementation</artifactId>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
</div>
</div><!-- /.page-content -->
</div>
-</div><!-- /.main-content -->
+<!-- /.main-content -->
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
#page-wrapper {
- min-height: 0px !important;
+ min-height: 0px !important;
}
.btn-orange {
- background-color: orange;
+ background-color: orange;
}
.error {
- color: Red;
+ color: Red;
}
-html, body, #wrapper, #page-wrapper {
- height: 100%;
+html, body, #page-wrapper, #main-content-container{
+ height: 100%;
}
.footable {
- margin-top: 25px;
+ margin-top: 25px;
}
\ No newline at end of file
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
ALLOWED_LEAF_TYPES_FOR_FILTER: ['string', 'uint32', 'uint8', 'decimal64', 'int16', 'int32', 'int64', 'int8',
'uint16', 'uint64', 'union', 'bits', 'leafref', 'identityref'],
ALLOWED_NODE_TYPES_FOR_FILTER: ['case', 'choice', 'container', 'input', 'leaf', 'output', 'rpc'],
+ DISPLAY_TYPE_REQ_DATA: 'req-data',
+ DISPLAY_TYPE_FORM: 'form',
+ DATA_STORE_CONFIG: 'config',
+ DATA_STORE_OPERATIONAL: 'operational',
+ DATA_STORE_OPERATIONS: 'operations',
+ NODE_RPC: 'rpc',
+ OPERATION_GET: 'GET',
+ OPERATION_PUT: 'PUT',
+ OPERATION_DELETE: 'DELETE',
+ OPERATION_POST: 'POST',
+ REQUEST_DATA_TYPE_RECEIVED: 'RECEIVED',
+ ICON_EXPAND_ADD: 'add',
+ ICON_COLLAPSE_REMOVE: 'remove',
+ ICON_KEYBOARD_ARROW_RIGHT: 'keyboard_arrow_right',
+ EXPAND_LEVEL_THREE: '3',
+ COLLECTION_CHECK_ARRAY: ['sentData', 'receivedData', 'path', 'collection', 'method', 'status', 'name'],
+ EV_REFRESH_LIST_INDEX: 'EV_REFRESH_LIST_INDEX',
+ YANGMAN_DISABLE_ADDING_LIST_ELEMENT: 'YANGMAN_DISABLE_ADDING_LIST_ELEMENT',
+ YANGMAN_MODULE_D_INIT: 'YANGMAN_MODULE_D_INIT',
+ YANGMAN_GET_API_TREE_DATA: 'YANGMAN_GET_API_TREE_DATA',
+ YANGMAN_SET_API_TREE_DATA: 'YANGMAN_SET_API_TREE_DATA',
+ YANGMAN_SET_LOADING_BOX: 'YANGMAN_SET_LOADING_BOX',
+ YANGMAN_SHOW_TOAST: 'YANGMAN_SHOW_TOAST',
+ YANGMAN_SET_MODULE_LIST_TITLE: 'YANGMAN_SET_MODULE_LIST_TITLE',
+ YANGMAN_SET_CODEMIRROR_DATA: 'YANGMAN_SET_CODEMIRROR_DATA_',
+ YANGMAN_GET_CODEMIRROR_DATA: 'YANGMAN_GET_CODEMIRROR_DATA_',
+ SET_SEL_OPERATIONS: 'SET_SEL_OPERATIONS',
+ YANGMAN_HEADER_INIT: 'YANGMAN_HEADER_INIT',
+ YANGMAN_FILL_NODE_FROM_REQ: 'YANGMAN_FILL_NODE_FROM_REQ',
+ YANGMAN_EXECUTE_WITH_DATA: 'YANGMAN_EXECUTE_WITH_DATA',
+ YANGMAN_DESELECT_REQUESTS: 'YANGMAN_DESELECT_REQUESTS',
+ YANGMAN_REFRESH_COLLECTIONS: 'YANGMAN_REFRESH_COLLECTIONS',
+ YANGMAN_REFRESH_HISTORY: 'YANGMAN_REFRESH_HISTORY',
+ YANGMAN_SAVE_EXECUTED_REQUEST: 'YANGMAN_SAVE_EXECUTED_REQUEST',
+ YANGMAN_SELECT_THE_NEWEST_REQUEST: 'YANGMAN_SELECT_THE_NEWEST_REQUEST',
+ YANGMAN_SAVE_REQUEST_TO_COLLECTION: 'YANGMAN_SAVE_REQUEST_TO_COLLECTION',
+ YANGMAN_REFRESH_AND_EXPAND_COLLECTIONS: 'YANGMAN_REFRESH_AND_EXPAND_COLLECTIONS',
+ YANGMAN_SET_ERROR_DATA: 'YANGMAN_SET_ERROR_DATA',
+ YANGMAN_SET_ERROR_MESSAGE: 'YANGMAN_SET_ERROR_MESSAGE',
+ YANGMAN_EXECUTING_REQUEST_PROGRESS_START: 'YANGMAN_EXECUTING_REQUEST_PROGRESS_START',
+ YANGMAN_EXECUTING_REQUEST_PROGRESS_STOP: 'YANGMAN_EXECUTING_REQUEST_PROGRESS_STOP',
+ YANGMAN_GET_CODEMIRROR_DATA_RECEIVED: 'YANGMAN_GET_CODEMIRROR_DATA_RECEIVED',
+ YANGMAN_GET_CODEMIRROR_DATA_SENT: 'YANGMAN_GET_CODEMIRROR_DATA_SENT',
+ YANGMAN_SET_CODEMIRROR_DATA_RECEIVED: 'YANGMAN_SET_CODEMIRROR_DATA_RECEIVED',
+ YANGMAN_SET_CODEMIRROR_DATA_SENT: 'YANGMAN_SET_CODEMIRROR_DATA_SENT',
+ YANGMAN_ERROR_EMPTY_IDENTIFIERS: 'YANGMAN_ERROR_EMPTY_IDENTIFIERS',
+ YANGMAN_NO_MOUNT_POINT: 'YANGMAN_NO_MOUNT_POINT',
+ YANGMAN_CUST_MOUNT_POINTS: 'YANGMAN_CUST_MOUNT_POINTS',
+ YANGMAN_CANCEL_MP: 'YANGMAN_CANCEL_MP',
+ YANGMAN_MOUNT_POINT: 'YANGMAN_MOUNT_POINT',
+ SET_SCOPE_TREE_ROWS: 'SET_SCOPE_TREE_ROWS',
+ TREE_ROWS: 'tree_rows',
};
});
processSingleRootNode: processSingleRootNode,
},
storageOperations = {
- config: ['GET', 'PUT', 'DELETE'],
+ config: ['GET', 'PUT', 'POST', 'DELETE'],
operational: ['GET'],
operations: ['POST'],
},
});
});
- // console.info(co);
}
// TODO: add service's description
this.callback = callback;
};
- this.runCallback = function (args) {
- if (this.callback) {
- this.callback(args);
- } else {
- console.warn('no callback set for custom functionality', this.label);
- }
+ this.runCallback = function (args){
+ (this.callback || angular.noop)(args);
};
}
return key || 'DEFAULT';
}
- // TODO: add service's description
+ /**
+ * Method for storing values from scope
+ * @param variables
+ * @param scope
+ * @param key
+ */
function storeFromScope(variables, scope, key) {
var data = {};
key = getKey(key);
variables.forEach(function (k) {
- if (scope.hasOwnProperty(k)) {
- data[k] = scope[k];
- } else {
- console.warn('scope doesn\'t have variable', k);
- }
+ data[k] = scope[k];
});
service.storedData[key] = data;
}
- // TODO: add service's description
+ /**
+ * Method for putting stored values to scope
+ * @param variables
+ * @param scope
+ * @param key
+ */
function getToScope(variables, scope, key) {
var data = {};
key = getKey(key);
+
if (service.storedData.hasOwnProperty(key)) {
data = service.storedData[key];
if (data.hasOwnProperty(k)) {
scope[k] = data[k];
} else {
- console.warn('storet data doesn\'t have variable', k);
}
});
}
try {
valueStr = string.toString();
} catch (e) {
- console.warn('cannot convert value', node.value);
}
return valueStr;
};
});
getActElementFilter(node);
- // console.info('applyFilter node', node, 'node.referenceNode.filterNodes',
// node.referenceNode.filterNodes, 'node.referenceNode.filters', node.referenceNode.filters);
}
}
// TODO: add function's description
- function uses(usesNode, currentModule) {
+ function uses(usesNode, currentModule, parentNode) {
var targetType = 'grouping';
return function (modules) {
var data = findLinkedStatement(usesNode, targetType, currentModule, modules),
changed = false;
if (node && module) {
- usesNode.parent.children.splice(usesNode.parent.children.indexOf(usesNode), 1); // delete uses node
+ if (usesNode.parent.children) { // if parent is node
+ usesNode.parent.children.splice(usesNode.parent.children.indexOf(usesNode), 1); // delete uses node
+ }
+ else if (usesNode.parent._roots) { // if parent is module
+ usesNode.parent._roots.splice(usesNode.parent._roots.indexOf(usesNode), 1);
+ }
for (var i = 0; i < node.children.length; i++) {
applyLinks(node.children[i], module, modules);
}
}
// TODO: add function's description
- function type(typeNode, currentModule) {
+ function type(typeNode, currentModule, parentNode) {
var targetType = 'typedef';
if (isBuildInType(typeNode.label) === false) {
if (node) {
// delete referencing type node
- typeNode.parent.children.splice(typeNode.parent.children.indexOf(typeNode), 1);
- typeNode.parent.addChild(node);
+
+ parentNode.children.splice(typeNode.parent.children.indexOf(typeNode), 1);
+ parentNode.addChild(node);
changed = true;
}
}
// TODO: add function's description
- function applyLinks(node, module, modules) {
+ function applyLinks(node, module, modules, parentNode) {
var changed = false;
if (linkFunctions.hasOwnProperty(node.type)) { // applying link function to uses.node
- changed = linkFunctions[node.type](node, module)(modules);
+ changed = linkFunctions[node.type](node, module, parentNode)(modules);
}
for (var i = 0; i < node.children.length; i++) {
- if (applyLinks(node.children[i], module, modules)) {
+ if (applyLinks(node.children[i], module, modules, node)) {
i--;
// need to repeat current index because we are deleting uses nodes,
// so in case there are more uses in row, it would skip second one
// TODO: add service's description
function isRootNode(type) {
- return type === 'container' || type === 'list' || type === 'rpc';
+ return type === 'container' || type === 'list' || type === 'uses' || type === 'rpc';
}
// TODO: add service's description
node.buildActElemData = function () {
var list = [],
result;
+
if (node.actElemStructure) {
node.actElemStructure.listElemBuildRequest(RequestBuilderService, list, node.module);
result = list[0] ? list[0] : {};
}
node.actElemStructure.clear();
- for (var prop in actData) {
+ Object.keys(actData).forEach(function(prop) {
node.actElemStructure.fillListElement(prop, actData[prop]);
- }
+ });
EventDispatcherService.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);
};
var actData = node.listData[node.actElemIndex];
node.actElemStructure.clear();
- for (var prop in actData) {
+ Object.keys(actData).forEach(function(prop) {
node.actElemStructure.fillListElement(prop, actData[prop]);
- }
+ });
}
EventDispatcherService.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);
var buildedDataCopy = node.listData.slice().map(function (item) {
var newItem = {};
- for (var prop in item){
+ Object.keys(item).forEach(function(prop) {
if (prop !== '$$hashKey'){
newItem[prop] = item[prop];
}
- }
+ });
return newItem;
}).filter(function (item){
return Object.keys(item).length !== 0;
node.createStructure();
node.listData = array.slice();
node.actElemIndex = node.listData.length - 1;
- for (var prop in node.listData[node.actElemIndex]) {
+
+ Object.keys(node.listData[node.actElemIndex]).forEach(function(prop) {
node.actElemStructure.fillListElement(prop, node.listData[node.actElemIndex][prop]);
- }
+ });
}
return (match && array.length > 0);
if (match && nodesToFill.length) {
nodesToFill.forEach(function (child) {
- for (var prop in data) {
+ Object.keys(data).forEach(function(prop) {
child.fill(prop, data[prop]);
- }
+ });
});
node.expanded = match;
}
if (match && nodesToFill.length) {
nodesToFill.forEach(function (child) {
- for (var prop in data) {
+ Object.keys(data).forEach(function(prop) {
child.fill(prop, data[prop]);
- }
+ });
});
node.expanded = match;
}
};
node.fill = function (name, data) {
- var filled = false,
+ var match = comparePropToElemByName(name, node.label),
nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
- nodesToFill.forEach(function (child) {
- var childFilled = child.fill(name, data);
- filled = filled || childFilled;
- });
+ if (match && nodesToFill.length) {
+ nodesToFill.forEach(function (child) {
+ Object.keys(data).forEach(function(prop) {
+ child.fill(prop, data[prop]);
+ });
+ });
+ }
- node.expanded = filled;
+ node.expanded = match;
- return filled;
+ return match;
};
node.clear = function () {
if (match && nodesToFill.length) {
nodesToFill.forEach(function (child) {
- for (var prop in data) {
+ Object.keys(data).forEach(function(prop) {
child.fill(prop, data[prop]);
- }
+ });
});
node.expanded = match;
};
node.getChildren('type').forEach(function (child) {
- // console.info('child', child);
getTypesRecursive(child, types);
});
function PathUtilsService(ArrayUtilsService){
var service = {
+ clearPath: clearPath,
+ checkEmptyIdentifiers: checkEmptyIdentifiers,
createPathElement: createPathElement,
getModuleNameFromPath: getModuleNameFromPath,
getStorageAndNormalizedPath: getStorageAndNormalizedPath,
return selNode;
}
} else {
- console.warn('search: cannot find element ', pathElem.name);
return null;
}
}
- // TODO: add service's description
- function translate(path, prefixConverter, importNodes, getDefaultModuleCallback) {
+ /**
+ * Translate path url into path elements array
+ * @param path
+ * @param prefixConverter
+ * @param importNodes
+ * @param getDefaultModuleCallback
+ * @param notIdentifiers
+ * @returns {Array}
+ */
+ function translate(path, prefixConverter, importNodes, getDefaultModuleCallback, notIdentifiers) {
var pathStrElements = path.split('/').filter(function (e) {
return e !== '';
}),
for (index = 0; index < maxIndex; index += 1) {
var actElem = pathStrElements[index],
- lastElem = getLastElement(pathArrayElements);
+ lastElem = getLastElement(pathArrayElements),
+ checkIdentifier = notIdentifiers ? false : isIdentifier(actElem);
- if (isIdentifier(actElem) && lastElem) {
+ if (checkIdentifier && lastElem) {
lastElem.addIdentifier(actElem.slice(1, -1));
} else {
function translatePathArray(pathArray) {
var getIdentifiersValues = function (identifiers) {
return identifiers.map(function (i) {
- return i.value.replace(/\//g, '%2F');
+ return i.value.length ? i.value.replace(/\//g, '%2F') : '{' + i.label + '}';
}).join('/');
},
getLastElem = function (i) {
});
}
- // TODO: add service's description
+ /**
+ * Check if in path elements array is empty identifier
+ * @param pathArray
+ * @returns {*}
+ */
+ function checkEmptyIdentifiers(pathArray){
+ return pathArray.some(function (item) {
+ return item.hasEmptyIdentifier();
+ });
+ }
+
+ /**
+ * Service for filling API url object from url string data
+ * @param pathArrayIn
+ * @param pathString
+ */
function fillPath(pathArrayIn, pathString) {
var pathArray = trimPath(pathString).split('/'),
pathPosition = 0;
if ( pathItem.hasIdentifier() ){
pathItem.identifiers.forEach(function (identifier){
pathPosition++;
- identifier.value = pathArray[pathPosition];
+ identifier.value = isIdentifier(pathArray[pathPosition]) ? '' : pathArray[pathPosition];
});
}
pathPosition++;
}
+ /**
+ * Service for clearing api path object
+ * @param pathArrayIn
+ */
+ function clearPath(pathArrayIn){
+ pathArrayIn.forEach(function (pathItem){
+ if ( pathItem.hasIdentifier() ){
+ pathItem.identifiers.forEach(function (identifier){
+ identifier.value = '';
+ });
+ }
+ });
+ }
+
// TODO: add service's description
function getModuleNameFromPath(path){
var pathArray = translate(trimPath(path));
}
// TODO: add service's description
- function searchNodeByPath(pathString, treeApis, treeData, disabledExpand) {
- var pathArray = translate(trimPath(pathString)),
+ function searchNodeByPath(pathString, treeApis, treeData, disabledExpand, notIdentifiers) {
+ var pathArray = translate(trimPath(pathString), null, null, null, notIdentifiers),
module = pathArray.length > 1 ? pathArray[1].module : null,
selectedTreeApi = module ? treeApis.filter(function (treeApi) {
return treeApi.module === module;
return retObj;
}
- // TODO: add service's description
+ /**
+ * Fill path element's identifiers
+ * @param identifiers
+ * @param label
+ * @param value
+ */
function fillIdentifiers(identifiers, label, value) {
identifiers.some(function (i) {
var identifierMatch = i.label === label;
});
};
+ this.hasEmptyIdentifier = function () {
+ return this.identifiers.some(function (item) {
+ return item.value.length === 0;
+ });
+ };
+
this.toString = function () {
return (this.module ? this.module + ':' : '') + this.name + '/' + (this.hasIdentifier() ?
this.getIdentifierValues().join('/') + '/' : '');
this.spawnRequest = function (digest) {
var id = digest + (this.reqId++).toString();
this.runningRequests.push(id);
- // console.debug('adding request ',id,' total running requests = ',this.runningRequests);
return id;
};
if (index > -1) {
this.runningRequests.splice(index, 1);
- // console.debug('removing request ',id,' remaining requests = ',this.runningRequests);
} else {
- console.warn('cannot remove request', id, 'from', this.runningRequests, 'index is', index);
}
};
self = this;
if (processes > 0 && self.timeElapsed < timeout) {
- // console.debug('waitin on',processes,'processes',this.runningRequests);
$timeout(function () {
self.timeElapsed = self.timeElapsed + t;
self.waitFor(callback);
try {
valueStr = string.toString();
} catch (e) {
- console.warn('cannot convert value', node.value);
}
}
generateApiTreeData: generateApiTreeData,
generateNodesToApis: generateNodesToApis,
objectHandler: objectHandler,
+ postRequestData: postRequestData,
prepareHeaders: prepareHeaders,
prepareOperation: prepareOperation,
prepareRequestData: prepareRequestData,
// TODO: add service's description
function switchConfigOper(apiStr, swtichTo) {
- var c = 'config',
- o = 'operational',
+ var c = constants.DATA_STORE_CONFIG,
+ o = constants.DATA_STORE_OPERATIONAL,
str = apiStr;
if (apiStr.indexOf(c) === 0) {
}
// TODO: add service's description
+ // TODO: seems to be not used more
function prepareRequestData(requestData, operation, reqString, subApi){
var preparedData = requestData;
- if (operation === 'GET'){
+ if (operation === constants.OPERATION_GET || operation === constants.OPERATION_DELETE){
preparedData = null;
}
- else if (operation === 'POST'){
+ else if (operation === constants.OPERATION_POST){
return postRequestData(requestData, reqString, subApi);
}
// TODO: add service's description
function prepareOperation(operation){
- return operation === 'DELETE' ? 'REMOVE' : operation;
+ return operation === constants.OPERATION_DELETE ? 'REMOVE' : operation;
}
// TODO: add service's description
function loadStaticModule(name, callback, errorCbk) {
var yinPath = '/yang2xml/' + name + '.yang.xml';
$http.get(path + yinPath).success(function (data) {
- console.warn('cannot load ' + name + 'from controller, trying loading from static storage');
parseModule(data, callback);
}).error(function () {
- console.warn('cannot load file ' + yinPath + 'from static storage');
errorCbk();
return null;
});
});
if (duplicates && duplicates.length > 0) {
- console.warn('trying to add duplicate node', node, 'to module', this._statements);
} else {
this._statements[node.type].push(node);
}
if (searchResults && searchResults.length === 0) {
- // console.warn('no nodes with type', type, 'and name', name, 'found in', this);
} else if (searchResults && searchResults.length > 1) {
- // console.warn('multiple nodes with type', type, 'and name', name, 'found in', this);
} else if (searchResults && searchResults.length === 1) {
searchedNode = searchResults[0];
}
// });
});
} else {
- console.warn('can\'t find target node for augmentation ', this.getPathString());
}
};
};
this.config = function (xml, parent) {
- var type = 'config',
+ var type = constants.DATA_STORE_CONFIG,
name = $(xml).attr('value'),
nodeType = constants.NODE_ALTER;
this.rpc = function (xml, parent) {
- var type = 'rpc',
+ var type = constants.NODE_RPC,
name = $(xml).attr('name'),
nodeType = constants.NODE_UI_DISPLAY,
node = this.createNewNode(name, type, parent, nodeType);
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
'app/topology/topology.module',
'common/login/login.module',
'app/yangui/main',
+ 'app/yangman/main',
'app/yangvisualizer/yangvisualizer.module',
'common/sigmatopology/sigmatopology.module',
'common/navigation/navigation.module',
'app.topology',
'app.common.login',
'app.yangui',
+ 'app.yangman',
'app.yangvisualizer',
'app.common.sigmatopology',
'app.common.nav',
#wrapper {\r
width: 100%;\r
padding-left:250px;\r
-}\r
-\r
-#pageContent {\r
- margin-bottom:50px;\r
+ height: calc(100% - 62px);\r
+ overflow-y: auto;\r
+ overflow-x: hidden;\r
}\r
\r
#sideMenu {\r
position: absolute;\r
left: 250px;\r
width: 250px;\r
- height: 100%;\r
+ height: calc(100% - 62px);\r
margin-left: -250px;\r
overflow-y: auto;\r
background: #808285;\r
padding:0 15px;\r
position: relative;\r
width:100%;\r
+ height: 100%;\r
+}\r
+\r
+#page-wrapper-content > div.container-fluid,\r
+#page-wrapper-content > div.container-fluid > div.row,\r
+#pageContent{\r
+ height: 100%;\r
}\r
\r
.navbar-static-side ul li {\r
var WORD = /[<<\w$]+/, RANGE = 500;
CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
+
var acList = [],
word = options && options.word || WORD,
- cur = editor.getCursor(),
+ cur = editor.getCursor(),
curLine = editor.getLine(cur.line),
- end = cur.ch,
+ end = cur.ch,
start = end,
paramList = editor.data.parameterListObj.list;
-
+
function forEachParam(arr, f, fParam) {
- for (var i = 0, e = arr.length; i < e; ++i){
+ for (var i = 0, e = arr.length; i < e; ++i){
f(arr[i].name, fParam);
- };
+ }
}
-
-
+
+
function maybeAdd(possibleWord, word) {
var pw = '<<' + possibleWord + '>>';
- if (pw.lastIndexOf(word, 0) == 0 && !arrayContains(acList, pw))
+ if (pw.lastIndexOf(word, 0) == 0 && !arrayContains(acList, pw))
acList.push(pw);
}
-
+
function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
}
return arr.indexOf(item) != -1;
}
-
-
+
+
options.completeSingle = false;
-
- while (start && word.test(curLine.charAt(start - 1)))
+
+ while (start && word.test(curLine.charAt(start - 1)))
--start;
-
+
var curWord = curLine.slice(start, end);
-
+
if(curWord.length > 1){
forEachParam(paramList, maybeAdd, curWord);
}
-
-
-
+
+
+
return {list: acList, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
});
var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
if (pasted) {
e.preventDefault();
- runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); });
+ if (!isReadOnly(cm) && !cm.options.disableInput)
+ runInOp(cm, function () { applyTextInput(cm, pasted, 0, null, "paste"); });
return true;
}
}
<link rel="stylesheet" type="text/css" href="vendor/footable/css/footable.standalone.min.css" />
<link rel="stylesheet" type="text/css" href="vendor/vis/dist/vis.min.css" />
<link rel="stylesheet" type="text/css" href="vendor/ng-slider/dist/css/ng-slider.min.css" />
+ <link rel="stylesheet" type="text/css" href="vendor/angular-material/angular-material.css" />
+ <link rel="stylesheet" type="text/css" href="vendor/material-design-icons/iconfont/material-icons.css" />
<link rel="stylesheet" type="text/css" href="assets/opendaylight-dlux-0.2.0.css" />
<link rel="stylesheet" href="assets/css/sb-admin.css" />
</head>
<body class="skin-3">
- <div ui-view="mainContent"></div>
+ <div ui-view="mainContent" id="main-content-container"></div>
</body>
</html>
require.config({
baseUrl : 'src',
+ packages: [{
+ name: 'codemirror',
+ location: '../assets/js/codemirror',
+ main: 'lib/codemirror',
+ }],
paths : {
'angular' : '../vendor/angular/angular',
'ui-bootstrap' : '../vendor/angular-bootstrap/ui-bootstrap-tpls.min',
'ZeroClipboard' : '../vendor/zeroclipboard/dist/ZeroClipboard',
'ngClip' : '../vendor/ng-clip/src/ngClip',
'angular-translate-loader-partial' : '../vendor/angular-translate-loader-partial/angular-translate-loader-partial',
+ 'ngAnimate': '../vendor/angular-animate/angular-animate.min',
+ 'ngAria': '../vendor/angular-aria/angular-aria.min',
+ 'ngMaterial': '../vendor/angular-material/angular-material.min',
+ 'ngMessages': '../vendor/angular-messages/angular-messages.min',
+ 'codeMirror-showHint' : '../assets/js/codemirror/addon/hint/show-hint',
+ 'codeMirror-jsonParametersHint' : '../assets/js/codemirror/addon/hint/json-parameters-hint',
+ 'codeMirror-javascriptMode' : '../assets/js/codemirror/mode/javascript/javascript',
+ 'codeMirror-matchBrackets' : '../assets/js/codemirror/addon/edit/matchbrackets',
},
map: {
'*': {
'ngSlider' : ['angular'],
'ZeroClipboard': ['angular'],
'ngClip' : ['angular','ZeroClipboard'],
- 'angular-translate-loader-partial': ['angular-translate']
+ 'angular-translate-loader-partial': ['angular-translate'],
+ 'ngAnimate': ['angular'],
+ 'ngAria': ['angular'],
+ 'ngMaterial': {
+ deps: ['ngAnimate', 'ngAria']
+ },
+ 'codeMirros_showHint': ['codemirror'],
+ 'codeMirros_javascriptHint': ['codemirror'],
+ 'codeMirror_javascriptMode': ['codemirror'],
+ 'codeMirror_matchBrackets': ['codemirror'],
},
deps : ['app/app.module']
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
+.nodes-module{
+ padding-top: 20px;
+}
+
.indexGrid {
position: relative;
top: 20px;
background-image: radial-gradient(circle, #eee, #ccc);
}
-
-
-.main {
- position: relative;
- top: 20px;
-}
-
.footable {
a {
color: #428bca !important;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
-->
-<div class="main" ui-view></div>
+<div class="main nodes-module" ui-view></div>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<module>common-login-resources</module>
<module>common-general-resources</module>
<module>yangui-resources</module>
+ <module>yangman-resources</module>
<module>yangvisualizer-resources</module>
<module>network-resources</module>
<module>flow-resources</module>
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 Inocybe Technologies, and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>dlux-parent</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <relativePath>../../</relativePath>
+ </parent>
+
+ <artifactId>dlux.yangman.resources</artifactId>
+ <name>${project.artifactId}</name>
+ <description>Yangman Module Resources</description>
+ <version>${yangman.resources.version}</version>
+ <packaging>jar</packaging>
+
+</project>
--- /dev/null
+{
+ "YANGMAN_ADD_LIST_ITEM": "Add list item",
+ "YANGMAN_AUGMENTATIONS": "Augmentations",
+ "YANGMAN_CANCEL": "Cancel",
+ "YANGMAN_CLOSE": "Close",
+ "YANGMAN_CLEAR_SEARCH": "Clear filter",
+ "YANGMAN_COLLECTION_CHANGE_NAME": "Edit collection name",
+ "YANGMAN_COLLECTION_DELETE": "Delete collection",
+ "YANGMAN_COLLECTION_DOWNLOAD": "Download collection",
+ "YANGMAN_COLLECTION_DUPLICATE": "Duplicate collection",
+ "YANGMAN_COLLECTION_EDIT": "Edit collection name",
+ "YANGMAN_COLLECTION_NAME": "Collection name",
+ "YANGMAN_COLLECTION_NAME_REQUIRED": "Collection name is required",
+ "YANGMAN_COLLECTION_NEW_COL_": "New collection ",
+ "YANGMAN_COLLECTION_NEW_NAME": "New collection name",
+ "YANGMAN_COLLECTION_REQUEST": "request",
+ "YANGMAN_COLLECTION_REQUESTS": "requests",
+ "YANGMAN_COLLECTION_WILL_BE_CREATED": " will be created",
+ "YANGMAN_CREATING_COLLECTION": "Select collection or type a new name",
+ "YANGMAN_DELETE_COL_CONFIRM_TEXT": "Selected collection will be deleted forever.",
+ "YANGMAN_DELETE_COL_CONFIRM_TITLE": "Do you want to delete collection",
+ "YANGMAN_DELETE_REQ_CONFIRM_TEXT": "Selected requests will be deleted forever.",
+ "YANGMAN_DELETE_REQ_CONFIRM_TITLE": "Do you want to delete request?",
+ "YANGMAN_EXPLAIN": "Explain",
+ "YANGMAN_FORM": "FORM",
+ "YANGMAN_IMPORT_COLLECTION": "Import collection",
+ "YANGMAN_JSON": "JSON",
+ "YANGMAN_LOADED_MODULES": "Modules were loaded.",
+ "YANGMAN_LOADED_MODULES_ERROR": "Error in loading modules.",
+ "YANGMAN_MATCHING": "Matching",
+ "YANGMAN_MODULES": "Modules",
+ "YANGMAN_NO_COLLECTIONS": "Type new collection name.",
+ "YANGMAN_OK": "OK",
+ "YANGMAN_PARAM_DONT_REPLACE" : "undefined - won't be replaced",
+ "YANGMAN_REQ_DELETE": "Delete request",
+ "YANGMAN_REQ_DUPLICATE": "Duplicate request",
+ "YANGMAN_REQ_SHOW_FORM": "Show form",
+ "YANGMAN_REQ_RUN": "Run request",
+ "YANGMAN_REQ_SHOW_JSON_DATA": "Show json data",
+ "YANGMAN_REQ_URL": "Request URL",
+ "YANGMAN_REQS_DELETE": "Delete selected",
+ "YANGMAN_REQS_DUPLICATE": "Duplicating request",
+ "YANGMAN_REQS_SAVE_TO_COL": "Save to collection",
+ "YANGMAN_SAVE": "SAVE",
+ "YANGMAN_SEL_METHOD": "Select method",
+ "YANGMAN_SEND": "SEND",
+ "YANGMAN_SHOW_LIST_ITEM": "Show all list items",
+ "YANGMAN_SORT_ASC": "ascending",
+ "YANGMAN_SORT_DESC": "descending",
+ "YANGMAN_STATUS": "Status",
+ "YANGMAN_TIME": "Time",
+ "YANGMAN_HISTORY": "History",
+ "YANGMAN_COLLECTIONS": "Collections",
+ "YANGMAN_PARAMETERS_ADMINISTRATION": "Parameters administration",
+ "YANGMAN_PARAMETERS": "Parameters",
+ "YANGMAN_RECEIVED_DATA": "Received data",
+ "YANGMAN_SENT_DATA": "Sent data",
+ "YANGMAN_PARAM_KEY": "Key",
+ "YANGMAN_PARAM_VALUE": "Value",
+ "YANGMAN_REMOVE_PARAM": "Remove param",
+ "YANGMAN_SEARCH": "Search",
+ "YANGMAN_SORT_BY": "Sort by",
+ "YANGMAN_PARAMS_KEY": "key",
+ "YANGMAN_PARAMS_VALUE": "value",
+ "YANGMAN_PARAM_KEY_REQUIRED": "Required value",
+ "YANGMAN_PARAM_EXISTING_KEY": "Duplicate value",
+ "YANGMAN_SORTING": "Sorting",
+ "YANGMAN_CUST_MOUNT_POINTS": "Display mount points",
+ "YANGMAN_CANCEL_MP": "Back from mountpoint",
+ "YANGMAN_PLUGINS_MENU": "Plugins menu",
+ "YANGMAN_PARAMS_IMPORT_EXPORT": "Import and export parameters",
+ "YANGMAN_IMPORT_PARAMS": "Import all parameters",
+ "YANGMAN_EXPORT_PARAMETERS": "Export all parameters",
+ "YANGMAN_NO_MOUNT_POINT": "No mount points to display",
+ "YANGMAN_MOUNT_POINT": "Mount point",
+ "YANGMAN_YANG_MENU": "Yang menu",
+ "YANGMAN_DELETE_HISTORY_CONFIRM_TITLE": "Do you want to delete all history requests?",
+ "YANGMAN_DELETE_HISTORY_CONFIRM_TEXT": "All history requests will be Deleted.",
+ "YANGMAN_DELETE_HISTORY": "Delete all history requests",
+ "YANGMAN_DELETE_COLLECTIONS": "Delete all collections",
+ "YANGMAN_DELETE_COLLECTION_CONFIRM_TITLE": "Do you want to delete all collections?",
+ "YANGMAN_DELETE_COLLECTION_CONFIRM_TEXT": "All collections will be deleted.",
+ "YANGMAN_DELETE_OPTIONS": "Delete options",
+ "YANGMAN_SELECT_OPTIONS": "Select options",
+ "YANGMAN_SELECT_ALL": "Select All",
+ "YANGMAN_DESELECT_ALL": "Deselect All",
+ "YANGMAN_IS_AUGMENT": "Augments",
+ "YANGMAN_LOADING_MODULES": "Loading application modules...",
+ "YANGMAN_EXECUTING_REQUEST": "Request is beeing executed...",
+ "YANGMAN_CM_ENLARGE_FONT_SIZE": "Enlarge json font size (Alt +)",
+ "YANGMAN_CM_REDUCE_FONT_SIZE": "Reduce json font size (Alt -)",
+ "YANGMAN_INPUT_REQUIRED": "Required",
+ "YANGMAN_ERROR_EMPTY_IDENTIFIERS": "Identifiers in path are required. Please fill empty identifiers for successful request execution.",
+ "YANGMAN_SORT_COLLECTIONS_DESC": "Sort collections descending",
+ "YANGMAN_SORT_COLLECTIONS_ASC": "Sort collections ascending",
+ "YANGMAN_LIST_DELETE_ITEM": "Delete list item",
+ "YANGMAN_LIST_INDEX_DUPLICATE": "Duplicated index",
+ "YANGMAN_LIST_PREV_ITEM": "show previous item",
+ "YANGMAN_LIST_NEXT_ITEM": "show next item",
+ "YANGMAN_SHOW_HIDE_CON": "show / hide container"
+}
--- /dev/null
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="897.673px" height="897.673px" viewBox="0 0 897.673 897.673" style="enable-background:new 0 0 897.673 897.673;"
+ xml:space="preserve">
+<g>
+ <path d="M859.877,855.354L606.396,23.221C602.195,9.427,589.469,0,575.049,0H448.836H322.625c-14.42,0-27.146,9.426-31.347,23.221
+ L37.795,855.354c-6.413,21.055,9.338,42.318,31.347,42.318h181.071c15.246,0,28.479-10.515,31.922-25.367l38.312-165.216h128.39
+ h128.39l38.312,165.216c3.443,14.853,16.676,25.367,31.922,25.367h181.071C850.539,897.673,866.291,876.409,859.877,855.354z
+ M448.836,523.413h-85.578l15.191-62.147c22.096-85.624,44.192-194.726,66.29-284.493h4.097h4.097
+ c22.097,89.767,44.193,198.869,66.289,284.493l15.191,62.147H448.836z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('EditCollectionDialogCtrl', EditCollectionDialogCtrl);
+
+ EditCollectionDialogCtrl.$inject = ['$mdDialog', 'collection', 'allCollections', 'duplicate'];
+
+ function EditCollectionDialogCtrl($mdDialog, collection, allCollections, duplicate) {
+ var vm = this;
+
+ vm.collection = collection;
+ vm.existingNames = [];
+ vm.duplicate = duplicate;
+ vm.collectionName = duplicate ? '' : vm.collection.name;
+
+ vm.cancel = cancel;
+ vm.save = save;
+
+ init();
+
+ function init(){
+ vm.existingNames = allCollections.map(function (item){
+ return item.name;
+ });
+ }
+
+ function cancel() {
+ $mdDialog.cancel();
+ }
+
+ function save() {
+ $mdDialog.hide([vm.collection.name, vm.collectionName]);
+ }
+
+ }
+
+ return EditCollectionDialogCtrl;
+
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMAugmentationModalCtrl', YMAugmentationModalCtrl);
+
+ YMAugmentationModalCtrl.$inject = ['$scope'];
+
+ function YMAugmentationModalCtrl($scope){
+ $scope.init = init;
+
+ /**
+ * Initialization
+ * @param node
+ */
+ function init(node){
+ $scope.node = node;
+ }
+ }
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMCaseCtrl', YMCaseCtrl);
+
+ YMCaseCtrl.$inject = ['$scope'];
+
+ function YMCaseCtrl($scope){
+ var yangCase = this;
+
+ yangCase.empty = ($scope.case.children.length === 0 ||
+ ($scope.case.children.length === 1 && $scope.case.children[0].children.length === 0));
+
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMChoiceCtrl', YMChoiceCtrl);
+
+ YMChoiceCtrl.$inject = ['$scope', 'constants'];
+
+ function YMChoiceCtrl($scope, constants){
+ var yangChoice = this;
+
+ $scope.constants = constants;
+
+ // methods
+ yangChoice.isActionMenu = isActionMenu;
+ $scope.caseShowing = caseShowing;
+ yangChoice.toggleExpanded = toggleExpanded;
+
+ /**
+ * Show hide node
+ */
+ function toggleExpanded() {
+ $scope.node.expanded = !$scope.node.expanded;
+ }
+
+ // TODO :: do method description
+ function caseShowing(node) {
+ return !node.augmentationId ? true :
+ $scope.augmentations.getAugmentation(node.parent, node.augmentationId).expanded;
+ }
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return $scope.node.augmentionGroups && $scope.node.augmentionGroups.length;
+ }
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMContainerCtrl', YMContainerCtrl);
+
+ YMContainerCtrl.$inject = ['$scope'];
+
+ function YMContainerCtrl($scope){
+ var yangContainer = this;
+
+ // methods
+ yangContainer.isActionMenu = isActionMenu;
+ yangContainer.toggleExpanded = toggleExpanded;
+
+ /**
+ * Show hide node
+ */
+ function toggleExpanded() {
+ $scope.node.expanded = !$scope.node.expanded;
+ }
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return $scope.node.augmentionGroups && $scope.node.augmentionGroups.length;
+ }
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMInputCtrl', YMInputCtrl);
+
+ YMInputCtrl.$inject = ['$scope'];
+
+ function YMInputCtrl($scope){
+ var yangInput = this;
+
+ // methods
+ yangInput.isActionMenu = isActionMenu;
+ yangInput.toggleExpanded = toggleExpanded;
+
+ /**
+ * Show hide node
+ */
+ function toggleExpanded() {
+ $scope.node.expanded = !$scope.node.expanded;
+ }
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return $scope.node.augmentionGroups && $scope.node.augmentionGroups.length;
+ }
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMLeafListCtrl', YMLeafListCtrl);
+
+ YMLeafListCtrl.$inject = ['$scope'];
+
+ function YMLeafListCtrl($scope){
+ var yangLeafList = this;
+
+ // methods
+ yangLeafList.addListElem = addListElem;
+ yangLeafList.changed = changed;
+ yangLeafList.isActionMenu = isActionMenu;
+ yangLeafList.removeListElem = removeListElem;
+ yangLeafList.toggleExpanded = toggleExpanded;
+
+
+ // TODO :: do method description
+ function addListElem() {
+ $scope.node.addListElem();
+ }
+
+ // TODO :: do method description
+ function removeListElem(elem){
+ $scope.node.removeListElem(elem);
+ }
+
+ // TODO :: do method description
+ function changed() {
+ //$scope.preview();
+ $scope.buildRootRequest();
+ }
+
+ // TODO :: do method description
+ function toggleExpanded() {
+ $scope.node.expanded = !$scope.node.expanded;
+ }
+
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return true;
+ }
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMLeafCtrl', YMLeafCtrl);
+
+ YMLeafCtrl.$inject = ['$scope'];
+
+ function YMLeafCtrl($scope){
+ var types = [
+ 'binary',
+ 'bits',
+ 'boolean',
+ 'decimal64',
+ 'enumeration',
+ 'empty',
+ 'identityref',
+ 'instance-identifier',
+ 'int16',
+ 'int32',
+ 'int64',
+ 'int8',
+ 'leafref',
+ 'string',
+ 'uint16',
+ 'uint32',
+ 'uint64',
+ 'uint8',
+ 'union',
+ ],
+ yangLeaf = this;
+
+ yangLeaf.infoBox = false;
+ yangLeaf.infoBoxSection = '';
+
+ // methods
+ yangLeaf.displayValue = displayValue;
+ yangLeaf.getLeafCentering = getLeafCentering;
+ yangLeaf.getLeafType = getLeafType;
+ yangLeaf.isActionMenu = isActionMenu;
+
+
+ function getLeafCentering(){
+ return ['union', 'bits', 'empty'].indexOf(getLeafType()) > -1 ? 'start' : 'center';
+ }
+
+ /**
+ * Get leaf type
+ * @returns {*}
+ */
+ function getLeafType(){
+ var label = $scope.node.getChildren('type')[0].label;
+ return types.indexOf(label) !== -1 ? label : 'default';
+ }
+
+ function displayValue() {
+ return $scope.node.typeChild.label !== 'empty';
+ }
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return false;
+ }
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMListCtrl', YMListCtrl);
+
+ YMListCtrl.$inject = ['$scope', 'ListFilteringService', 'NodeWrapperService', 'constants'];
+
+ function YMListCtrl($scope, ListFilteringService, NodeWrapperService, constants){
+ var yangList = this;
+
+ $scope.actElement = null;
+ $scope.showListFilter = false;
+ $scope.filterListHover = 0;
+ yangList.constants = constants;
+ yangList.currentDisplayIndex = 1;
+ yangList.displayOffsets = [-1, 0, 1];
+
+ // methods
+ $scope.activeFilter = activeFilter;
+ $scope.applyFilter = applyFilter;
+ $scope.clearFilterData = clearFilterData;
+ $scope.createNewFilter = createNewFilter;
+ $scope.getFilterData = getFilterData;
+ $scope.showListFilterWin = showListFilterWin;
+ $scope.showModalWin = showModalWin;
+ $scope.switchFilter = switchFilter;
+
+ yangList.addListElem = addListElem;
+ yangList.getListName = getListName;
+ yangList.init = init;
+ yangList.isActionMenu = isActionMenu;
+ yangList.removeListElem = removeListElem;
+ yangList.shiftDisplayNext = shiftDisplayNext;
+ yangList.shiftDisplayPrev = shiftDisplayPrev;
+ yangList.showNextButton = showNextButton;
+ yangList.showPrevButton = showPrevButton;
+ yangList.toggleExpanded = toggleExpanded;
+
+ // WATCHERS
+ $scope.$on(constants.EV_REFRESH_LIST_INDEX, function () {
+ yangList.currentDisplayIndex = 1;
+ });
+
+ $scope.$on(constants.YANGMAN_DISABLE_ADDING_LIST_ELEMENT, function() {
+ yangList.init();
+ });
+
+ /**
+ * Disable adding more then one element
+ */
+ function init() {
+ yangList.disableAddingListElement = $scope.checkAddingListElement($scope.node);
+
+ if(yangList.disableAddingListElement &&
+ !$scope.node.listData.length &&
+ $scope.selectedDatastore.label === constants.DATA_STORE_CONFIG) {
+
+ yangList.addListElem();
+ }
+ }
+
+ /**
+ * Add element into list
+ */
+ function addListElem() {
+ $scope.showListFilter = false;
+ $scope.showModal = false;
+ ListFilteringService.removeEmptyFilters($scope.node);
+ $scope.node.addListElem();
+ }
+
+ // TODO :: do method description
+ function removeListElem(elemIndex, fromFilter) {
+ $scope.node.removeListElem(elemIndex, fromFilter);
+ // $scope.preview();
+ yangList.currentDisplayIndex =
+ Math.max(Math.min(yangList.currentDisplayIndex, $scope.node.listData.length - 2), 1);
+ if ($scope.node.listData.length === 0) {
+ $scope.$broadcast('hideInfoBox');
+ }
+ }
+
+ // TODO :: do method description
+ function toggleExpanded() {
+ $scope.node.expanded = !$scope.node.expanded;
+ }
+
+ // TODO :: do method description
+ function shiftDisplayNext(typeListData) {
+ yangList.currentDisplayIndex = Math.min(yangList.currentDisplayIndex + 3, $scope.node[typeListData].length - 2);
+ }
+
+ // TODO :: do method description
+ function shiftDisplayPrev() {
+ yangList.currentDisplayIndex = Math.max(yangList.currentDisplayIndex - 3, 1);
+ }
+
+ // TODO :: do method description
+ function showPrevButton() {
+ return yangList.currentDisplayIndex > 1;
+ }
+
+ // TODO :: do method description
+ function showNextButton(typeListData) {
+ // node is selected after view is loaded
+ return $scope.node[typeListData] && yangList.currentDisplayIndex < $scope.node[typeListData].length - 2;
+ }
+
+ // TODO :: do method description
+ function showModalWin() {
+ $scope.showModal = !$scope.showModal;
+ if ($scope.showListFilter){
+ $scope.showListFilter = !$scope.showListFilter;
+ }
+ }
+
+ // TODO :: do method description
+ function showListFilterWin() {
+ $scope.showListFilter = !$scope.showListFilter;
+ if ($scope.showModal){
+ $scope.showModal = !$scope.showModal;
+ }
+ ListFilteringService.showListFilterWin($scope.filterRootNode,$scope.node);
+ }
+
+ // TODO :: do method description
+ function getFilterData() {
+ ListFilteringService.getFilterData($scope.node);
+ }
+
+ // TODO :: do method description
+ function switchFilter(showedFilter) {
+ ListFilteringService.switchFilter($scope.node, showedFilter);
+ }
+
+ // TODO :: do method description
+ function createNewFilter() {
+ ListFilteringService.createNewFilter($scope.node);
+ }
+
+ // TODO :: do method description
+ function applyFilter() {
+ ListFilteringService.applyFilter($scope.node);
+ $scope.showListFilter = !$scope.showListFilter;
+ yangList.currentDisplayIndex = 1;
+ if ($scope.node.filteredListData.length){
+ $scope.node.doubleKeyIndexes =
+ NodeWrapperService.checkKeyDuplicity($scope.node.filteredListData, $scope.node.refKey);
+ } else {
+ $scope.node.doubleKeyIndexes =
+ NodeWrapperService.checkKeyDuplicity($scope.node.listData, $scope.node.refKey);
+ }
+ }
+
+ // TODO :: do method description
+ function clearFilterData(changeAct, filterForClear, removeFilters) {
+ ListFilteringService.clearFilterData($scope.node, changeAct, filterForClear, removeFilters);
+ if (changeAct){
+ $scope.showListFilter = !$scope.showListFilter;
+ }
+ $scope.node.doubleKeyIndexes =
+ NodeWrapperService.checkKeyDuplicity($scope.node.listData, $scope.node.refKey);
+ }
+
+ // TODO :: do method description
+ function activeFilter(filter) {
+ if (filter.active === 1){
+ filter.active = 2;
+ } else {
+ filter.active = 1;
+ }
+ }
+
+ // TODO :: do method description
+ function getListName(offset, config) {
+ var createdListItemName = $scope.node.createListName(yangList.currentDisplayIndex + offset);
+
+ if ( createdListItemName.length > 33 ) {
+ return {
+ name: createdListItemName.substring(0, 30) + '...',
+ tooltip: createdListItemName,
+ };
+ } else {
+ return {
+ name: config ? createdListItemName || '[' + (yangList.currentDisplayIndex + offset) + ']' : createdListItemName,
+ tooltip: '',
+ };
+ }
+ }
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return true;
+ }
+ }
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMOutputCtrl', YMOutputCtrl);
+
+ YMOutputCtrl.$inject = ['$scope'];
+
+ function YMOutputCtrl($scope){
+ var yangOutput = this;
+ yangOutput.notEditable = true;
+
+ // methods
+ yangOutput.isActionMenu = isActionMenu;
+ yangOutput.toggleExpanded = toggleExpanded;
+
+ /**
+ * Show hide node
+ */
+ function toggleExpanded() {
+ $scope.node.expanded = !$scope.node.expanded;
+ }
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return $scope.node.augmentionGroups && $scope.node.augmentionGroups.length;
+ }
+ }
+});
+
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMRpcCtrl', YMRpcCtrl);
+
+ YMRpcCtrl.$inject = ['$scope'];
+
+ function YMRpcCtrl($scope){
+ var yangRpc = this;
+
+ // methods
+ yangRpc.toggleExpanded = toggleExpanded;
+ yangRpc.isActionMenu = isActionMenu;
+
+ /**
+ * Show hide node
+ */
+ function toggleExpanded() {
+ $scope.node.expanded = !$scope.node.expanded;
+ }
+
+ /**
+ * Show hide action menu
+ * @returns {boolean|*}
+ */
+ function isActionMenu() {
+ return false;
+ }
+
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMTypeBitCtrl', YMTypeBitCtrl);
+
+ YMTypeBitCtrl.$inject = ['$scope'];
+
+ function YMTypeBitCtrl($scope){
+ var yangTypeBit = this;
+
+ // methods
+ yangTypeBit.valueChanged = valueChanged;
+
+ /**
+ * Methods for checking correct input
+ */
+ function valueChanged(){
+ $scope.type.setLeafValue($scope.type.bitsValues);
+ $scope.node.checkValueType();
+ $scope.node.fill($scope.node.label, $scope.node.value);
+ $scope.buildRootRequest();
+ }
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMTypeBooleanCtrl', YMTypeBooleanCtrl);
+
+ YMTypeBooleanCtrl.$inject = ['$scope'];
+
+ function YMTypeBooleanCtrl($scope){
+ var yangTypeBolean = this;
+
+ $scope.$watch('node.value', function(){
+ if ( typeof $scope.node.value !== 'boolean' && $scope.node.value.length) {
+ $scope.node.value = $scope.node.value === 'true';
+ }
+ });
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMTypeEmptyCtrl', YMTypeEmptyCtrl);
+
+ YMTypeEmptyCtrl.$inject = ['$scope'];
+
+ function YMTypeEmptyCtrl($scope){
+ var yangTypeEmpty = this;
+ // methods
+ yangTypeEmpty.valueChanged = valueChanged;
+
+ /**
+ * Methods for checking correct input
+ */
+ function valueChanged(){
+ $scope.buildRootRequest();
+ }
+ }
+});
+
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMTypeEnumCtrl', YMTypeEnumCtrl);
+
+ YMTypeEnumCtrl.$inject = ['$scope'];
+
+ function YMTypeEnumCtrl($scope){
+ var yangTypeEnum = this;
+
+ // methods
+ yangTypeEnum.valueChanged = valueChanged;
+
+ /**
+ * Methods for checking correct input
+ */
+ function valueChanged(){
+ var value = $scope.type.selEnum && $scope.type.selEnum.label ? $scope.type.selEnum.label : '';
+
+ $scope.type.setLeafValue(value);
+ $scope.node.checkValueType();
+ $scope.node.fill($scope.node.label, $scope.node.value);
+ $scope.buildRootRequest();
+ }
+ }
+});
+
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YMTypeCtrl', YMTypeCtrl);
+
+ YMTypeCtrl.$inject = ['$scope'];
+
+ function YMTypeCtrl($scope){
+ var yangType = this;
+
+ // methods
+ yangType.valueChanged = valueChanged;
+
+ /**
+ * Methods for checking correct input
+ */
+ function valueChanged(){
+ $scope.node.checkValueType();
+ $scope.node.fill($scope.node.label, $scope.node.value);
+ $scope.buildRootRequest();
+ }
+ }
+});
--- /dev/null
+define([
+ 'app/yangman/directives/abn-tree.directive',
+], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('ModuleDetailCtrl', ModuleDetailCtrl);
+
+ ModuleDetailCtrl.$inject = ['$scope', '$rootScope', '$timeout', 'YangmanService', 'constants'];
+
+ function ModuleDetailCtrl($scope, $rootScope, $timeout, YangmanService, constants) {
+ var moduleDetail = this;
+
+ moduleDetail.treeApis = [];
+ moduleDetail.selectedInnerDatastore = null;
+
+ // methods
+ moduleDetail.setApiNode = setApiNode;
+ moduleDetail.setDataDetailStore = setDataDetailStore;
+
+ // WATCHERS
+ $scope.$on(constants.YANGMAN_MODULE_D_INIT, function (){
+ init();
+ });
+
+ /**
+ * Initialization
+ */
+ function init(){
+ $timeout(function () {
+ moduleDetail.selectedDataStoreIndex =
+ YangmanService.getDataStoreIndex($scope.selectedModule.children, $scope.selectedDatastore.label);
+ moduleDetail.treeApis = $scope.selectedDatastore.children;
+ });
+ }
+
+ /**
+ * Set global selected yang node
+ * @param apiIndex
+ * @param subApiIndex
+ */
+ function setApiNode(apiIndex, subApiIndex){
+
+ if (apiIndex !== undefined && subApiIndex !== undefined ) {
+
+ $scope.setApi($scope.apis[apiIndex], $scope.apis[apiIndex].subApis[subApiIndex], true, true);
+ $scope.setNode($scope.selectedSubApi.node);
+ $scope.clearCM();
+ }
+ }
+
+ /**
+ * Set datastore to global param
+ * @param dataStore
+ */
+ function setDataDetailStore(dataStore){
+ $scope.setDataStore(dataStore);
+ $scope.setApi($scope.selectedApi, null);
+ $scope.setNode(null);
+ moduleDetail.treeApis = dataStore.children;
+ }
+ }
+
+});
--- /dev/null
+define([
+ 'app/yangman/services/plugins-handler.services',
+], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('ModulesListCtrl', ModulesListCtrl);
+
+ ModulesListCtrl.$inject = ['$scope', '$rootScope', '$mdToast', 'YangUtilsService', 'PluginsHandlerService',
+ '$filter', '$timeout', 'constants'];
+
+ function ModulesListCtrl($scope, $rootScope, $mdToast, YangUtilsService, PluginsHandlerService, $filter, $timeout, constants) {
+ var modulesList = this;
+
+ modulesList.treeApis = [];
+ modulesList.showLoadingBox = true;
+ modulesList.moduleListTitle = '';
+ modulesList.search = '';
+
+ // methods
+ modulesList.clearFilter = clearFilter;
+ modulesList.customSearch = customSearch;
+ modulesList.checkSelectedModule = checkSelectedModule;
+ modulesList.setDataStore = setDataStore;
+ modulesList.setModule = setModule;
+
+ // watchers
+ $scope.$on(constants.YANGMAN_GET_API_TREE_DATA, function (event, args) {
+ (args.cbk || angular.noop)(modulesList.treeApis);
+ });
+
+ // set tree apis data
+ $scope.$on(constants.YANGMAN_SET_API_TREE_DATA, function (event, args) {
+ modulesList.treeApis = args.params;
+ modulesList.showLoadingBox = false;
+ showToastInfoBox('YANGMAN_LOADED_MODULES');
+ });
+
+ // show hide loading box
+ $scope.$on(constants.YANGMAN_SET_LOADING_BOX, function (event, args){
+ modulesList.showLoadingBox = args.params;
+ (args.cbk || angular.noop)();
+ });
+
+ // show info box with custom title
+ $scope.$on(constants.YANGMAN_SHOW_TOAST, function (event, args) {
+ showToastInfoBox(args.params);
+ });
+
+ $scope.$on(constants.YANGMAN_SET_MODULE_LIST_TITLE, function (event, args) {
+ modulesList.moduleListTitle = args.params;
+ });
+
+ /**
+ * Initialization
+ */
+ function init(){
+ loadApis();
+ }
+
+ init();
+
+ /**
+ * Check if module and one of it datastore is selected
+ * @param module
+ * @returns {boolean|*|Function|o}
+ */
+ function checkSelectedModule(module){
+ var haveSelectedDS = [];
+
+ if ( $scope.selectedDatastore && (module === $scope.selectedModule)) {
+ haveSelectedDS = $scope.selectedModule.children.filter(function(item){
+ return item === $scope.selectedDatastore;
+ });
+ }
+
+ return haveSelectedDS.length;
+ }
+
+ /**
+ * Custom search function for searching by api label
+ * @param api
+ */
+ function customSearch(api){
+ return api.label.toLowerCase().indexOf(modulesList.search.toLowerCase()) > -1;
+ }
+
+ /**
+ * Clear current ctrl search value
+ */
+ function clearFilter(){
+ modulesList.search = '';
+ }
+
+ /**
+ * Load apis and modules
+ */
+ function loadApis() {
+ modulesList.allNodes = [];
+ modulesList.treeApis = [];
+
+ modulesList.showLoadingBox = true;
+
+ YangUtilsService.generateNodesToApis(function (apis, allNodes, augGroups) {
+ $scope.setGlobalParams(apis, augGroups);
+ modulesList.allNodes = allNodes;
+ modulesList.treeApis = YangUtilsService.generateApiTreeData(apis);
+ modulesList.showLoadingBox = false;
+ showToastInfoBox('YANGMAN_LOADED_MODULES');
+
+ PluginsHandlerService.plugAll(apis, modulesList);
+ }, function () {
+ showToastInfoBox('YANGMAN_LOADED_MODULES_ERROR');
+ modulesList.showLoadingBox = false;
+ });
+ }
+
+ /**
+ * Set and expand module in tree
+ */
+ function setModule(module, e){
+ if ( angular.element(e.target).hasClass('top-element') ) {
+ module.expanded = !module.expanded;
+ }
+ }
+
+ /**
+ * Set data store || rpc
+ * @param dataStore
+ * @param module
+ */
+ function setDataStore(dataStore, module){
+ $scope.setModule(module);
+ $scope.setDataStore(dataStore, true, 1);
+ }
+
+ /**
+ * Method for showing toast box
+ * @param text
+ */
+ function showToastInfoBox(text){
+ $timeout(function(){
+ $mdToast.show(
+ $mdToast.simple()
+ .textContent($filter('translate')(text))
+ .position('bottom left')
+ .parent(angular.element('.yangmanModule__left-panel'))
+ .hideDelay(3000)
+ );
+ }, 500);
+ }
+ }
+});
--- /dev/null
+define([
+ 'app/yangman/services/handle-file.services',
+], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('ParamsAdminCtrl', ParamsAdminCtrl);
+
+ ParamsAdminCtrl.$inject = ['$mdMenu', '$mdDialog', '$scope', '$timeout', 'YangmanService', 'YMHandleFileService', 'parametersList'];
+
+ function ParamsAdminCtrl($mdMenu, $mdDialog, $scope, $timeout, YangmanService, YMHandleFileService, parametersList) {
+ var openMenuListener,
+ vm = this;
+
+ vm.parametersList = parametersList;
+ vm.search = '';
+ vm.sortField1 = '_name';
+ vm.sortField2 = '_value';
+ vm.sortAsc = true;
+
+ vm.close = close;
+ vm.save = save;
+ vm.createEmptyParam = createEmptyParam;
+ vm.removeParam = removeParam;
+ vm.clearFilter = clearFilter;
+ vm.filterParam = filterParam;
+ vm.sortBy = sortBy;
+ vm.sortFunc = sortFunc;
+ vm.exportParameters = exportParameters;
+ vm.importParameters = importParameters;
+ vm.validateNamesUnique = validateNamesUnique;
+ vm.filterChange = filterChange;
+
+ init();
+
+
+ /**
+ * Force validation after some filter is applied
+ */
+ function filterChange() {
+ $timeout(vm.validateNamesUnique);
+ }
+
+ /**
+ * Loop over all name inputs in form and validate duplicities
+ */
+ function validateNamesUnique() {
+ var i = 0;
+ while (vm.paramsForm.hasOwnProperty('name_' + i)){
+ var modelValue = vm.paramsForm['name_' + i].$modelValue;
+ vm.paramsForm['name_' + i].$setValidity(
+ 'unique',
+ vm.parametersList.isNameUnique(modelValue)
+ );
+ i++;
+ }
+ }
+
+ /**
+ * Importing all parameters from json
+ * @param fileContent
+ */
+ function importParameters(fileContent) {
+ if (fileContent && YangmanService.validateFile(fileContent, ['name', 'value'])){
+ try {
+ vm.parametersList.createParamsFromJson(fileContent);
+ vm.parametersList.saveToStorage();
+ angular.element(document).find('#importParameters').val('');
+ createEmptyParam();
+ }
+ catch (e) {
+ angular.element(document).find('#importParameters').val('');
+ console.error('DataStorage error:', e);
+ }
+ }
+ else {
+ angular.element(document).find('#importParameters').val('');
+ }
+
+ }
+
+ /**
+ * Export all parameters to json file
+ */
+ function exportParameters() {
+
+ YMHandleFileService.downloadFile(
+ 'yangman_parameters.json',
+ vm.parametersList.toJSON(),
+ 'json',
+ 'charset=utf-8',
+ function (){},
+ function (e){
+ console.error('Export parameters error:', e);
+ }
+ );
+ }
+
+ /**
+ * Set attribute to use when sorting
+ * @param sortField1 , sortField2
+ */
+ function sortBy(sortField1, sortField2) {
+ vm.sortField1 = sortField1;
+ vm.sortField2 = sortField2;
+ vm.sortAsc = !vm.sortAsc;
+ vm.parametersList.applyValsForFilters();
+ $timeout(vm.validateNamesUnique);
+ }
+
+ /**
+ * Sort parameters with empty params at the end of list
+ * @param item
+ * @returns {*}
+ */
+ function sortFunc(item) {
+ return [item[vm.sortField1] ? item[vm.sortField1] : (vm.sortAsc ? String.fromCharCode(255) : ''),
+ item[vm.sortField2] ? item[vm.sortField2] : (vm.sortAsc ? String.fromCharCode(255) : '')];
+ }
+
+ /**
+ * Empty or matching params will be in list
+ * @param paramObj
+ * @returns {boolean}
+ */
+ function filterParam(paramObj) {
+ return !(paramObj._name || paramObj._value) ||
+ (paramObj._name && paramObj._name.indexOf(vm.search) !== -1) ||
+ (paramObj._value && paramObj._value.indexOf(vm.search) !== -1);
+ }
+
+
+ function clearFilter() {
+ vm.search = '';
+ }
+
+ /**
+ * Load params list and add one empty to the end of list
+ */
+ function init(){
+ vm.parametersList.loadListFromStorage();
+ createEmptyParam();
+ openMenuListener = $scope.$on('$mdMenuOpen', function () {
+ closeOpenedMenu();
+ $timeout(registerClickOutside);
+ });
+ }
+
+ /**
+ * Remove param from list
+ * @param paramObj
+ */
+ function removeParam(paramObj) {
+ vm.parametersList.deleteParameterItem(paramObj);
+ $timeout(vm.validateNamesUnique);
+ }
+
+ /**
+ * Create new empty param
+ */
+ function createEmptyParam() {
+ vm.parametersList.addEmptyItem();
+ }
+
+ /**
+ * Cancel dialog
+ */
+ function close() {
+ vm.parametersList.removeEmptyParams();
+ $mdDialog.hide();
+ }
+
+ /**
+ * Save list to storage and re-init dialog
+ */
+ function save() {
+ vm.parametersList.saveToStorage();
+ init();
+ }
+
+ function registerClickOutside() {
+ $(document).click(function () {
+ closeOpenedMenu();
+ });
+ }
+
+ function unregisterClickOutside() {
+ $(document).off('click');
+ }
+
+ function openMenuDestroyListener() {
+ $scope.$on('$destroy', function () {
+ openMenuListener();
+ });
+ }
+
+ function closeOpenedMenu() {
+ unregisterClickOutside();
+ openMenuDestroyListener();
+ $mdMenu.hide();
+ }
+
+
+
+ }
+
+ return ParamsAdminCtrl;
+
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('RequestDataCtrl', RequestDataCtrl);
+
+ RequestDataCtrl.$inject = ['$filter', '$mdToast', '$scope', 'RequestsService', 'constants'];
+
+ function RequestDataCtrl($filter, $mdToast, $scope, RequestsService, constants) {
+ var requestData = this,
+ cmData = {
+ cmInstance: null,
+ cmFontSize: 14,
+ };
+
+ requestData.paramsArray = [];
+ requestData.data = '';
+ requestData.type = null;
+
+
+ // todo: move all cm staff to directive
+ requestData.dataEditorOptions = {
+ mode: 'javascript',
+ lineNumbers: true,
+ lineWrapping: true,
+ matchBrackets: true,
+ extraKeys: {
+ 'Ctrl-Space': 'autocomplete',
+ },
+ onLoad: function (cmInstance) {
+
+ cmData.cmInstance = cmInstance;
+
+ cmInstance.data = {
+ parameterListObj: $scope.parametersList,
+ };
+
+ angular.element(cmInstance.display.wrapper).css('fontSize', cmData.cmFontSize + 'px');
+
+ cmInstance.on('changes', function () {
+ if (angular.isFunction(cmInstance.showHint)) {
+ cmInstance.showHint();
+ }
+ });
+
+ cmInstance.on('cursorActivity', function () {
+ var lineString = cmInstance.getLine(cmInstance.getCursor().line);
+ requestData.paramsArray = RequestsService.scanDataParams($scope.parametersList, lineString);
+
+ if (!$scope.$$phase) {
+ $scope.$apply();
+ }
+ });
+
+ cmInstance.on('keydown', function (codemirror, event) {
+ if (event.altKey) {
+ switch (event.key){
+ case '+':
+ incCMFontSize();
+ angular.element(cmInstance.display.wrapper).css(
+ 'fontSize',
+ cmData.cmFontSize + 'px'
+ );
+ break;
+ case '-':
+ decCMFontSize();
+ angular.element(cmInstance.display.wrapper).css(
+ 'fontSize',
+ cmData.cmFontSize + 'px'
+ );
+ break;
+ }
+
+ }
+ });
+
+
+ },
+ };
+
+ // methods
+ requestData.init = init;
+ requestData.enlargeCMFont = enlargeCMFont;
+ requestData.reduceCMFont = reduceCMFont;
+
+ function incCMFontSize() {
+ if (cmData.cmFontSize < 30) {
+ cmData.cmFontSize++;
+ }
+ }
+
+ function decCMFontSize() {
+ if (cmData.cmFontSize > 5) {
+ cmData.cmFontSize--;
+ }
+ }
+
+ function enlargeCMFont() {
+ incCMFontSize();
+ angular.element(cmData.cmInstance.display.wrapper).css(
+ 'fontSize',
+ cmData.cmFontSize + 'px'
+ );
+ }
+
+ function reduceCMFont() {
+ decCMFontSize();
+ angular.element(cmData.cmInstance.display.wrapper).css(
+ 'fontSize',
+ cmData.cmFontSize + 'px'
+ );
+ }
+
+ /**
+ * Set code mirror theme and readonly property considering requestData.type
+ */
+ function initEditorOptions() {
+ requestData.dataEditorOptions.theme = requestData.type === constants.REQUEST_DATA_TYPE_RECEIVED ? 'eclipse-disabled' : 'eclipse';
+ requestData.dataEditorOptions.readOnly = requestData.type === constants.REQUEST_DATA_TYPE_RECEIVED;
+ }
+
+
+ /**
+ * Initialization
+ * @param type
+ */
+ function init(type){
+ requestData.type = type;
+ initEditorOptions();
+
+ $scope.$on(constants.YANGMAN_SET_CODEMIRROR_DATA + type, function (event, args){
+ requestData.data = args.params.data;
+ });
+
+ $scope.$on(constants.YANGMAN_GET_CODEMIRROR_DATA + type, function (event, args){
+ args.params.reqData = requestData.data;
+ });
+ }
+ }
+
+});
--- /dev/null
+define([
+ 'app/yangman/controllers/params-admin.controller',
+ 'app/yangman/services/time-tracking.services',
+], function (ParamsAdminCtrl) {
+ 'use strict';
+
+ angular.module('app.yangman').controller('RequestHeaderCtrl', RequestHeaderCtrl);
+
+ RequestHeaderCtrl.$inject = [
+ '$mdDialog', '$mdToast', '$scope', '$rootScope', 'ENV', 'YangmanService', 'ParametersService',
+ 'PathUtilsService', 'RequestsService', '$filter', 'DataBackupService', 'constants', 'TimeTrackingService'
+ ];
+
+ function RequestHeaderCtrl($mdDialog, $mdToast, $scope, $rootScope, ENV, YangmanService, ParametersService,
+ PathUtilsService, RequestService, $filter, DataBackupService, constants,
+ TimeTrackingService) {
+ var requestHeader = this;
+
+ requestHeader.allOperations = [constants.OPERATION_GET, constants.OPERATION_POST, constants.OPERATION_PUT, constants.OPERATION_DELETE];
+ requestHeader.constants = constants;
+ requestHeader.urlChanged = false;
+ requestHeader.executedOperation = null;
+ requestHeader.selectedOperationsList = [];
+ requestHeader.selectedOperation = null;
+ requestHeader.requestUrl = '';
+ requestHeader.selectedPluginsButtons = [];
+ requestHeader.selectedPlugin = null;
+ requestHeader.statusObj = null;
+
+ // methods
+ requestHeader.executeOperation = executeOperation;
+ requestHeader.executePluginFunctionality = executePluginFunctionality;
+ requestHeader.fillNodeData = fillNodeData;
+ requestHeader.changeDataType = changeDataType;
+ requestHeader.prepareDataAndExecute = prepareDataAndExecute;
+ requestHeader.initMountPoint = initMountPoint;
+ requestHeader.setJsonView = setJsonView;
+ requestHeader.setRequestUrl = setRequestUrl;
+ requestHeader.showParamsAdmin = showParamsAdmin;
+ requestHeader.saveRequestToCollection = saveRequestToCollection;
+ requestHeader.unsetPluginFunctionality = unsetPluginFunctionality;
+
+ // watchers
+ /**
+ * Set selected operations based on data store
+ */
+ $scope.$on(constants.SET_SEL_OPERATIONS, function (event, operations, setUrl) {
+ setAllowedMethods(operations);
+
+ if ( setUrl ) {
+ setRequestUrl();
+ }
+ });
+
+ /**
+ * Watching for changes in shown detail data type (radio button)
+ */
+ $scope.$on(constants.YANGMAN_HEADER_INIT, function (event, args) {
+ init();
+ setRequestUrl(args.params.path);
+ setRequestMethod(args.params.method);
+ setRequestStatus(args.params.statusObj);
+ setJsonView();
+ (args.cbk || angular.noop)();
+ });
+
+ $scope.$on(constants.YANGMAN_FILL_NODE_FROM_REQ, function (event, args) {
+ setNodeDataFromRequestData(args.params.requestUrl, args.params.leftpanel);
+ (args.cbk || angular.noop)();
+ });
+
+ $scope.$on(constants.YANGMAN_EXECUTE_WITH_DATA, function (event, args) {
+ executeOperation(args.params.data ? angular.fromJson(args.params.data) : {}, args.cbk);
+ });
+
+ init();
+
+ /**
+ * Setter for selected operation
+ * @param method
+ */
+ function setRequestMethod(method){
+ requestHeader.selectedOperation = method;
+ }
+
+ /**
+ * Setter for request status
+ * @param statusObj
+ */
+ function setRequestStatus(statusObj){
+ requestHeader.statusObj = statusObj;
+ }
+
+ /**
+ * Show popup for parameters administration
+ * @param event
+ */
+ function showParamsAdmin(event) {
+ $mdDialog.show({
+ controller: ParamsAdminCtrl,
+ controllerAs: 'paramsAdmin',
+ templateUrl: $scope.globalViewPath + 'popup/parameters-admin.tpl.html',
+ parent: angular.element('#yangmanModule'),
+ targetEvent: event,
+ clickOutsideToClose: true,
+ locals: {
+ parametersList: $scope.parametersList,
+ },
+ }).then(
+ function (){
+ $scope.parametersList.loadListFromStorage();
+ },
+ function (){
+ $scope.parametersList.loadListFromStorage();
+ }
+ );
+ }
+
+ /**
+ * Method for selecting correct json view by selected operation
+ */
+ function setJsonView(){
+ var both = [constants.OPERATION_PUT, constants.OPERATION_POST];
+
+ if ( both.indexOf(requestHeader.selectedOperation) > -1 ){
+ $scope.setJsonView(true, true);
+ } else {
+ $scope.setJsonView(true, false);
+ }
+ }
+
+ /**
+ * Change displayed data type to json or form, after switching set current data to be displayed
+ */
+ function changeDataType(){
+ $scope.switchSection('rightPanelSection', requestHeader.selectedShownDataType);
+
+ if(!$scope.node || requestHeader.urlChanged) {
+ requestHeader.setRequestUrl();
+ requestHeader.urlChanged = false;
+ }
+
+ // if changing to json, fill codemirror data
+ if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA && $scope.node ){
+ setJsonView();
+ sendRequestData($scope.buildRootRequest(), 'SENT');
+ }
+
+ // if changing to form, try to fill node data
+ if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM) {
+ var reqData = {};
+
+ reqData = getDataForForm();
+ setNodeDataFromRequestData(requestHeader.requestUrl);
+
+ if ( $scope.node ) {
+
+ YangmanService.fillNodeFromResponse($scope.node, reqData);
+ $scope.node.expanded = true;
+ }
+ }
+ }
+
+ /**
+ * Helper method for building correct json data for form, rpc included
+ * @returns {*}
+ */
+ function getDataForForm(){
+ var params = {
+ reqData: null,
+ },
+ dataTypeFunc = {
+ rpc: function () {
+ var sentData = { reqData: null },
+ allData = { sent: null, received: null };
+
+ $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_RECEIVED, params);
+ $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, sentData);
+
+ allData.sent = sentData.reqData ? angular.fromJson(sentData.reqData) : {};
+ allData.received = params.reqData ? angular.fromJson(params.reqData) : {};
+
+ return YangmanService.prepareReceivedData(
+ $scope.node,
+ requestHeader.selectedOperation,
+ allData.received,
+ allData.sent,
+ requestHeader.selectedShownDataType
+ );
+ },
+ default: function (){
+ var dataType;
+ if(requestHeader.executedOperation) {
+ dataType = requestHeader.executedOperation === constants.OPERATION_GET ? constants.REQUEST_DATA_TYPE_RECEIVED : 'SENT';
+ }
+ else {
+ dataType = requestHeader.selectedOperation === constants.OPERATION_GET ? constants.REQUEST_DATA_TYPE_RECEIVED : 'SENT';
+ }
+
+ $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA + dataType, params);
+ return params.reqData ? angular.fromJson(params.reqData) : {};
+ },
+ };
+
+ return $scope.node ? (dataTypeFunc[$scope.node.type] || dataTypeFunc.default)() : {};
+ }
+
+ /**
+ * Send data to codemirror
+ * @param data
+ */
+ function sendRequestData(data, type){
+ $scope.rootBroadcast(
+ constants.YANGMAN_SET_CODEMIRROR_DATA + type,
+ { data: data instanceof Object ? JSON.stringify(data, null, 4) : data }
+ );
+ }
+
+ function sendErrorData(response) {
+ $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_DATA, response);
+ }
+
+ /**
+ * Create empty parameters list, load from local storage and set to $scope
+ */
+ function initParams(){
+ $scope.parametersList.loadListFromStorage();
+ }
+
+ /**
+ * Initialization
+ */
+ function init(){
+ setAllowedMethods(requestHeader.allOperations);
+ initParams();
+ requestHeader.selectedShownDataType = $scope.rightPanelSection;
+ }
+
+ /**
+ * Set allowed operations for request
+ * @param operations
+ */
+ function setAllowedMethods(operations){
+ requestHeader.selectedOperationsList = operations.length ? operations : requestHeader.allOperations;
+ if (operations.indexOf(requestHeader.selectedOperation) === -1){
+ requestHeader.selectedOperation = requestHeader.selectedOperationsList[0];
+ }
+ }
+
+ /**
+ * Set header request url if json selected
+ */
+ function setRequestUrl(path){
+ requestHeader.requestUrl = path || ($scope.selectedSubApi ?
+ ENV.getBaseURL('MD_SAL') + '/restconf/' + $scope.selectedSubApi.buildApiRequestString() : '');
+ }
+
+
+ /**
+ * Try to set api, module, dataStore and node, if api indexes for request url available
+ * and set (or unset) module detail panel to be displayed
+ * @param requestUrl url to try to find
+ * @param leftpanel index of main left tabs to be displayed (we dont want to display module detail in all cases)
+ */
+ function setNodeDataFromRequestData(requestUrl, leftpanel){
+
+ setApiByUrl(requestUrl, function (treeApis) {
+ // set module
+ $scope.setModule($filter('filter')(treeApis, { label: $scope.selectedApi.module })[0]);
+
+ // set datastore
+ $scope.setDataStore(
+ $filter('filter')(
+ $scope.selectedModule.children,
+ { label: $scope.selectedSubApi.storage })[0],
+ true,
+ leftpanel
+ );
+
+ // set node
+ $scope.setNode($scope.selectedSubApi.node);
+
+ // fill subapi path
+ PathUtilsService.fillPath($scope.selectedSubApi.pathArray, requestUrl);
+ setRequestUrl();
+ });
+ }
+
+ function setApiByUrl(url, cbk, fill){
+ $scope.rootBroadcast(constants.YANGMAN_GET_API_TREE_DATA, null, function (treeApis) {
+ var apisIndexes =
+ PathUtilsService.searchNodeByPath(url, treeApis, null, true, true);
+
+ if ( apisIndexes ) {
+
+ // set apis
+ $scope.setApi(
+ $scope.apis[apisIndexes.indexApi],
+ $scope.apis[apisIndexes.indexApi].subApis[apisIndexes.indexSubApi]
+ );
+
+ if ( $scope.selectedSubApi && fill ) {
+ var updatedUrl = YangmanService.cutUrl(url);
+ PathUtilsService.fillPath($scope.selectedSubApi.pathArray, updatedUrl);
+
+ }
+
+ (cbk || angular.noop)(treeApis);
+ }
+ });
+ }
+
+ function saveRequestToCollection(event) {
+ var historyReq = null,
+ sentData = { reqData: null },
+ receivedData = { reqData: null };
+
+ if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM) {
+ requestHeader.setRequestUrl();
+ }
+
+ historyReq = RequestService.createHistoryRequest(
+ null, null, requestHeader.requestUrl, requestHeader.selectedOperation, '', '', ''
+ );
+
+ $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, sentData);
+ $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_RECEIVED, receivedData);
+
+ RequestService.fillRequestByMethod(
+ historyReq, sentData, receivedData, requestHeader.selectedOperation, $scope.node,
+ requestHeader.selectedShownDataType
+ );
+
+ $scope.rootBroadcast(constants.YANGMAN_SAVE_REQUEST_TO_COLLECTION, { event: event, reqObj: historyReq });
+ }
+
+ function showRequestProgress(){
+ $scope.rootBroadcast(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_START);
+ }
+
+
+ function finishRequestProgress(message){
+ $scope.rootBroadcast(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_STOP);
+ }
+
+ /**
+ * Execute request operation
+ */
+ function executeOperation(requestData, executeCbk){
+ TimeTrackingService.startTimer();
+ var allowExecuteOperation =
+ requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM && $scope.selectedSubApi ?
+ !PathUtilsService.checkEmptyIdentifiers($scope.selectedSubApi.pathArray) : true;
+
+ if ( allowExecuteOperation ) {
+
+ showRequestProgress();
+ setRequestUrl(requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ? requestHeader.requestUrl : null);
+ $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_MESSAGE, '');
+
+ if ( requestHeader.selectedShownDataType !== constants.DISPLAY_TYPE_FORM ){
+ setApiByUrl(requestHeader.requestUrl, null, true);
+ }
+
+ var historyReq = RequestService.createHistoryRequest(null, null, requestHeader.requestUrl,
+ requestHeader.selectedOperation, '', '', '');
+
+ YangmanService.executeRequestOperation(
+ $scope.selectedApi,
+ $scope.selectedSubApi,
+ requestHeader.selectedOperation,
+ $scope.node,
+ requestHeader.selectedShownDataType,
+ requestHeader.requestUrl,
+ requestData,
+ $scope.parametersList,
+ executeReqSuccCbk,
+ executeReqErrCbk
+ );
+ requestHeader.executedOperation = requestHeader.selectedOperation;
+ } else {
+ $scope.rootBroadcast(
+ constants.YANGMAN_SET_ERROR_MESSAGE,
+ $filter('translate')(constants.YANGMAN_ERROR_EMPTY_IDENTIFIERS)
+ );
+ }
+
+ /**
+ * Success callback after executin operation
+ * @param reqInfo
+ * @param response
+ */
+ function executeReqSuccCbk(reqInfo, response) {
+ var preparedReceivedData = YangmanService.prepareReceivedData(
+ $scope.node,
+ requestHeader.selectedOperation,
+ response.data ? response.data.plain() : {},
+ reqInfo.requestSrcData,
+ requestHeader.selectedShownDataType
+ );
+
+ finishRequestProgress();
+
+ requestHeader.statusObj = reqInfo;
+
+ sendErrorData({});
+
+ if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA){
+
+ setNodeDataFromRequestData(requestHeader.requestUrl);
+ sendRequestData(preparedReceivedData, constants.REQUEST_DATA_TYPE_RECEIVED);
+ sendRequestData(reqInfo.requestSrcData || {}, 'SENT');
+ } else {
+
+ if ($scope.node){
+
+ YangmanService.fillNodeFromResponse($scope.node, preparedReceivedData);
+ YangmanService.handleNodeIdentifier(
+ $scope.parametersList, $scope.selectedSubApi, $scope.node
+ );
+ $scope.node.expanded = true;
+
+ $scope.rootBroadcast(constants.YANGMAN_DISABLE_ADDING_LIST_ELEMENT);
+ preparedReceivedData = YangmanService.checkRpcReceivedData(preparedReceivedData, $scope.node);
+ sendRequestData(preparedReceivedData, constants.REQUEST_DATA_TYPE_RECEIVED);
+ }
+ }
+
+ // create and set history request
+ requestHeader.statusObj.time = TimeTrackingService.returnTime();
+
+ historyReq.setExecutionData(
+ reqInfo.requestSrcData,
+ preparedReceivedData,
+ reqInfo.status,
+ reqInfo.status,
+ reqInfo.statusText,
+ requestHeader.statusObj.time
+ );
+
+ $scope.rootBroadcast(constants.YANGMAN_SAVE_EXECUTED_REQUEST, historyReq, function (){
+ $scope.rootBroadcast(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST);
+ });
+
+ (executeCbk || angular.noop)(historyReq);
+
+
+ }
+
+ /**
+ * Error callback after executin operation
+ * @param reqInfo
+ * @param response
+ */
+ function executeReqErrCbk(reqInfo, response) {
+ requestHeader.statusObj = reqInfo;
+
+ finishRequestProgress();
+
+ requestHeader.statusObj.time = TimeTrackingService.returnTime();
+
+ historyReq.setExecutionData(
+ reqInfo.requestSrcData,
+ response.data,
+ reqInfo.status,
+ reqInfo.status,
+ reqInfo.statusText,
+ requestHeader.statusObj.time
+ );
+ $scope.rootBroadcast(constants.YANGMAN_SAVE_EXECUTED_REQUEST, historyReq, function (){
+ $scope.rootBroadcast(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST);
+ });
+
+ if (response.data) {
+ // try to fill code mirror editor
+ sendRequestData(response.data, constants.REQUEST_DATA_TYPE_RECEIVED);
+ sendErrorData(response.data);
+ }
+
+ (executeCbk || angular.noop)(historyReq);
+
+
+ }
+
+ }
+
+ /**
+ * TODO :: description
+ * @param pathElem
+ * @param identifier
+ */
+ function fillNodeData(pathElem, identifier) {
+ if ($scope.selectedSubApi && $scope.selectedSubApi.storage === constants.DATA_STORE_CONFIG &&
+ $scope.selectedSubApi.pathArray.indexOf(pathElem) === ($scope.selectedSubApi.pathArray.length - 1)) {
+ PathUtilsService.fillListNode($scope.node, identifier.label, identifier.value);
+ }
+
+ requestHeader.urlChanged = true;
+ }
+
+ /**
+ * Check data before executin operations
+ */
+ function prepareDataAndExecute(cbk){
+ if (requestHeader.statusObj) {
+ requestHeader.statusObj.statusText = null;
+ requestHeader.statusObj.time = null;
+ }
+
+ if ( requestHeader.requestUrl.length ) {
+
+ if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ) {
+ // get json data
+ var params = { reqData: null };
+ $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, params);
+ executeOperation(params.reqData ? angular.fromJson(params.reqData) : {}, cbk);
+ } else {
+ executeOperation({}, cbk);
+ }
+ }
+ }
+
+ /**
+ * Mount point initialization
+ * @param mountPointStructure
+ * @param mountPointTreeApis
+ * @param mountPointApis
+ * @param augmentations
+ */
+ function initMountPoint(mountPointTreeApis, mountPointApis, augmentations, reqObj){
+ DataBackupService.storeFromScope(
+ [
+ 'selectedDatastore', 'node', 'apis',
+ 'selectedApi', 'selectedSubApi', 'augmentations', 'selectedModule',
+ ],
+ $scope,
+ 'MAIN_SCOPE'
+ );
+
+ $scope.rootBroadcast(constants.YANGMAN_GET_API_TREE_DATA, null, function (treeApis) {
+ DataBackupService.storeFromScope(
+ ['treeApis'],
+ { treeApis: treeApis },
+ 'MODULES_LIST'
+ );
+ });
+
+ $scope.setNode(null);
+ $scope.setModule(null);
+ $scope.setGlobalParams(mountPointApis, augmentations);
+ $scope.setDataStore(null);
+ requestHeader.statusObj = reqObj;
+ $scope.rootBroadcast(constants.YANGMAN_SET_API_TREE_DATA, mountPointTreeApis);
+ }
+
+ /**
+ * Executing custom plugin callback
+ * @param customPlugin
+ */
+ function executePluginFunctionality(customPlugin){
+ requestHeader.selectedPlugin = customPlugin;
+ customPlugin.runCallback({ scope: $scope, controller: requestHeader });
+ }
+
+ /**
+ * Unset custom plugin functionality - get back major params from scope
+ */
+ function unsetPluginFunctionality(){
+ if ( requestHeader.selectedPlugin ) {
+ $scope.unsetPlugin(requestHeader);
+ }
+
+ requestHeader.selectedPlugin = null;
+ requestHeader.selectedPluginsButtons = [];
+ }
+
+ }
+
+});
--- /dev/null
+define([
+ 'app/yangman/controllers/save-req-dialog.controller',
+ 'app/yangman/controllers/edit-collection-dialog.controller',
+ 'app/yangman/services/handle-file.services',
+], function (SaveReqDialogCtrl, EditCollectionDialogCtrl) {
+ 'use strict';
+
+ angular.module('app.yangman').controller('RequestsListCtrl', RequestsListCtrl);
+
+ RequestsListCtrl.$inject = [
+ '$filter', '$mdDialog', '$scope', 'YMHandleFileService', 'PathUtilsService', 'RequestsService', 'YangmanService',
+ 'YangmanDesignService', 'constants',
+ ];
+
+ /**
+ * Controller for requests lists, means History requests and Collections requests
+ * @param $filter
+ * @param $mdDialog
+ * @param $scope
+ * @param YMHandleFileService
+ * @param PathUtilsService
+ * @param RequestsService
+ * @param YangmanService
+ * @param YangmanDesignService
+ * @constructor
+ */
+ function RequestsListCtrl($filter, $mdDialog, $scope, YMHandleFileService, PathUtilsService, RequestsService,
+ YangmanService, YangmanDesignService, constants) {
+ var vm = this;
+
+ /**
+ * List of all collections containing requests, loads even for history controller to use collection names
+ * in saving requests dialog
+ * @type {*|CollectionList}
+ */
+ vm.collectionList = null;
+ vm.constants = constants;
+
+ /**
+ *
+ * @type {*|HistoryList}
+ */
+ vm.requestList = null;
+ vm.mainList = null;
+ vm.collectionsSortAsc = true;
+ vm.search = '';
+
+ // methods
+ vm.clearCollectionList = clearCollectionList;
+ vm.clearFilter = clearFilter;
+ vm.clearHistoryList = clearHistoryList;
+ vm.colMatchingReqsCount = colMatchingReqsCount;
+ vm.deselectAllFilteredRequests = deselectAllFilteredReqs;
+ vm.downloadCollection = downloadCollection;
+ vm.executeRequest = executeRequest;
+ vm.fakeFilter = fakeFilter;
+ vm.filterCol = filterCol;
+ vm.filterColName = filterColName;
+ vm.filterReq = filterReq;
+ vm.init = init;
+ vm.readCollectionFromFile = readCollectionFromFile;
+ vm.selectAllFilteredRequests = selectAllFilteredReqs;
+ vm.selectRequest = selectRequest;
+ vm.showData = showData;
+ vm.showDgDeleteCollection = showDgDeleteCollection;
+ vm.showDgDeleteRequests = showDgDeleteRequests;
+ vm.showDgEditCollection = showDgEditCollection;
+ vm.showDgSaveReq = showDgSaveReq;
+ vm.showForm = showForm;
+ vm.toggleCollectionsSort = toggleCollectionsSort;
+ vm.selectOnlyThisRequest = selectOnlyThisRequest;
+ vm.deselectAllRequests = deselectAllRequests;
+ vm.filterCollReq = filterCollReq;
+
+ /**
+ * Save request obje to collection from other controller
+ * @param reqObj
+ */
+ function saveRequestFromExt(event, args) {
+ vm.showDgSaveReq(args.params.event, args.params.reqObj, false);
+ }
+
+
+ /**
+ * Clear history requests list and save to storage
+ */
+ function clearHistoryList(event) {
+
+ YangmanDesignService.disableMdMenuItem(event);
+
+ var confirm = $mdDialog.confirm()
+ .title($filter('translate')('YANGMAN_DELETE_HISTORY_CONFIRM_TITLE'))
+ .textContent($filter('translate')('YANGMAN_DELETE_HISTORY_CONFIRM_TEXT'))
+ .ariaLabel($filter('translate')('YANGMAN_DELETE_HISTORY_CONFIRM_TITLE'))
+ .targetEvent(event)
+ .ok($filter('translate')('YANGMAN_OK'))
+ .cancel($filter('translate')('YANGMAN_CANCEL'));
+
+ $mdDialog.show(confirm).then(function (){
+ vm.requestList.clear();
+ vm.requestList.saveToStorage();
+ loadHistoryList();
+ YangmanDesignService.enableMdMenuItem(event);
+ }, function (){
+ YangmanDesignService.enableMdMenuItem(event);
+ });
+ }
+
+ /**
+ * Clear collections requests list and save to storage
+ */
+ function clearCollectionList(event) {
+ var confirm = $mdDialog.confirm()
+ .title($filter('translate')('YANGMAN_DELETE_COLLECTION_CONFIRM_TITLE'))
+ .textContent($filter('translate')('YANGMAN_DELETE_COLLECTION_CONFIRM_TEXT'))
+ .ariaLabel($filter('translate')('YANGMAN_DELETE_COLLECTION_CONFIRM_TITLE'))
+ .targetEvent(event)
+ .ok($filter('translate')('YANGMAN_OK'))
+ .cancel($filter('translate')('YANGMAN_CANCEL'));
+
+ YangmanDesignService.disableMdMenuItem(event);
+
+ $mdDialog.show(confirm).then(function (){
+ vm.collectionList.clear();
+ vm.collectionList.saveToStorage();
+ $scope.rootBroadcast(constants.YANGMAN_REFRESH_COLLECTIONS);
+ YangmanDesignService.enableMdMenuItem(event);
+ }, function () {
+ YangmanDesignService.enableMdMenuItem(event);
+ });
+ }
+
+ /**
+ * Create history request from other ctrl
+ * @param broadcastEvent
+ * @param params
+ */
+ function saveBcstedHistoryRequest(broadcastEvent, params) {
+ vm.requestList.addItemToList(params.params);
+ vm.requestList.saveToStorage();
+ (params.cbk || angular.noop)();
+ }
+
+ /**
+ * Clear value of input file used to import collection
+ * todo: move to design utils
+ */
+ function clearFileInputValue(){
+ angular.element(document).find('#importCollection').val('');
+ }
+
+ /**
+ * Importing collection from a file
+ * todo: error handling - msgs for user
+ * @param $fileContent
+ */
+ function readCollectionFromFile($fileContent) {
+ var data = $fileContent;
+
+ if (data && YangmanService.validateFile(data, constants.COLLECTION_CHECK_ARRAY)){
+ try {
+ vm.collectionList.loadListFromFile(data);
+ vm.collectionList.saveToStorage();
+ $scope.rootBroadcast(constants.YANGMAN_REFRESH_COLLECTIONS);
+ clearFileInputValue();
+ }
+ catch (e) {
+ clearFileInputValue();
+ console.error('DataStorage error:', e);
+ }
+ }
+ else {
+ clearFileInputValue();
+ }
+ removeButtonBackground();
+
+ function removeButtonBackground() {
+ $('#importCollection').next().css({ 'background': 'transparent' });
+ }
+ }
+
+ function toggleCollectionsSort() {
+ vm.collectionsSortAsc = !vm.collectionsSortAsc;
+ }
+
+ /**
+ * Export collection to json file
+ * @param {Collection} collection
+ */
+ function downloadCollection(collection) {
+
+ var cListJSON = vm.collectionList.getCollectionInRawJSON(collection.name);
+
+ YMHandleFileService.downloadFile(collection.name + '.json', cListJSON, 'json', 'charset=utf-8',
+ function (){},
+ function (e){
+ console.error('ExportCollection error:', e);
+ }
+ );
+ }
+
+ /**
+ * Fill request form in right panel with request data
+ * @param reqObj
+ */
+ function showForm(reqObj) {
+ var data = reqObj.sentData;
+
+ // exception for get meth
+ if ( reqObj.method === constants.OPERATION_GET ) {
+ data = reqObj.receivedData;
+ }
+
+ $scope.rootBroadcast(
+ constants.YANGMAN_SET_CODEMIRROR_DATA_RECEIVED, { data: reqObj.setDataForView(reqObj.receivedData) }
+ );
+ $scope.rootBroadcast(
+ constants.YANGMAN_SET_CODEMIRROR_DATA_SENT, { data: reqObj.setDataForView(reqObj.sentData) }
+ );
+
+ $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_DATA,
+ reqObj.receivedData && reqObj.receivedData.hasOwnProperty('errors') ? reqObj.receivedData : {});
+
+ $scope.rootBroadcast(constants.YANGMAN_FILL_NODE_FROM_REQ, { requestUrl: reqObj.path, requestData: data },
+ function (){
+ $scope.setRightPanelSection(constants.DISPLAY_TYPE_FORM);
+ $scope.rootBroadcast(constants.YANGMAN_HEADER_INIT, {
+ path: reqObj.path,
+ method: reqObj.method,
+ statusObj: {
+ status: reqObj.responseStatus,
+ statusText: reqObj.responseStatusText,
+ time: reqObj.responseTime,
+ },
+ });
+
+ if ( $scope.node ) {
+ // prepare data for filling form
+ data = $scope.node.type === constants.NODE_RPC ?
+ YangmanService.prepareReceivedData(
+ $scope.node,
+ reqObj.method,
+ reqObj.receivedData,
+ reqObj.sentData,
+ constants.DISPLAY_TYPE_FORM
+ ) : data;
+
+ // try to fill node
+ YangmanService.fillNodeFromResponse($scope.node, data);
+ $scope.node.expanded = true;
+ }
+
+ }
+ );
+
+ }
+
+ /**
+ * Force request header to execute request with data from reqObj
+ * @param reqObj
+ */
+ function executeRequest(reqObj) {
+ showData(reqObj);
+ $scope.rootBroadcast(constants.YANGMAN_EXECUTE_WITH_DATA,{ data: reqObj.sentData });
+ }
+
+ /**
+ * Method for setup data into CM, Header, find api, subapi, node
+ * @param reqObj
+ * @param status
+ */
+ function showData(reqObj, select){
+ var headerObj = {
+ path: reqObj.path,
+ method: reqObj.method,
+ };
+
+ // action select request
+ if ( select ) {
+ headerObj.statusObj = {
+ status: reqObj.responseStatus,
+ statusText: reqObj.responseStatusText,
+ time: reqObj.responseTime,
+ };
+
+ $scope.rootBroadcast(
+ constants.YANGMAN_SET_ERROR_DATA,
+ reqObj.receivedData && reqObj.receivedData.hasOwnProperty('errors') ? reqObj.receivedData : {}
+ );
+ }
+
+ $scope.setRightPanelSection(constants.DISPLAY_TYPE_REQ_DATA);
+ $scope.setJsonView(true, reqObj.method !== constants.OPERATION_GET);
+
+ $scope.rootBroadcast(constants.YANGMAN_HEADER_INIT, headerObj);
+ $scope.rootBroadcast(constants.YANGMAN_FILL_NODE_FROM_REQ, { requestUrl: reqObj.path });
+
+ $scope.rootBroadcast(
+ constants.YANGMAN_SET_CODEMIRROR_DATA_RECEIVED,
+ { data: reqObj.setDataForView(reqObj.receivedData) }
+ );
+
+ $scope.rootBroadcast(
+ constants.YANGMAN_SET_CODEMIRROR_DATA_SENT,
+ { data: reqObj.setDataForView(reqObj.sentData) }
+ );
+ }
+
+ /**
+ * Clear current ctrl search value
+ */
+ function clearFilter(){
+ vm.search = '';
+ }
+
+ /**
+ * Dialog for deleting either selected requests or reqObj
+ *
+ * @param event
+ * @param reqObj
+ */
+ function showDgDeleteRequests(event, reqObj){
+
+ var confirm = $mdDialog.confirm()
+ .title($filter('translate')('YANGMAN_DELETE_REQ_CONFIRM_TITLE'))
+ .textContent($filter('translate')('YANGMAN_DELETE_REQ_CONFIRM_TEXT'))
+ .ariaLabel($filter('translate')('YANGMAN_DELETE_REQ_CONFIRM_TITLE'))
+ .targetEvent(event)
+ .ok($filter('translate')('YANGMAN_OK'))
+ .cancel($filter('translate')('YANGMAN_CANCEL'));
+
+ YangmanDesignService.disableMdMenuItem(event);
+
+ $mdDialog.show(confirm).then(function (){
+ if (reqObj){
+ vm.mainList.deleteRequestItem(reqObj);
+ }
+ else {
+ vm.mainList.getSelectedItems(
+ vm.mainList === vm.collectionList ? filterCollReq : filterReq
+ ).forEach(function (elem){
+ vm.mainList.deleteRequestItem(elem);
+ });
+ }
+ vm.mainList.saveToStorage();
+
+ if (vm.mainList === vm.requestList) {
+ loadHistoryList();
+ }
+ else {
+ refreshCollectionsWithExpansion();
+ }
+ }, function (){
+ YangmanDesignService.enableMdMenuItem(event);
+ });
+ }
+
+
+ /**
+ * Dialog for deleting collection and refreshing collections
+ * @param ev
+ * @param collObj
+ */
+ function showDgDeleteCollection(ev, collObj){
+ var confirm = $mdDialog.confirm()
+ .title($filter('translate')('YANGMAN_DELETE_COL_CONFIRM_TITLE') + ' ' + collObj.name + '?')
+ .textContent($filter('translate')('YANGMAN_DELETE_COL_CONFIRM_TEXT'))
+ .ariaLabel($filter('translate')('YANGMAN_DELETE_COL_CONFIRM_TITLE'))
+ .targetEvent(ev)
+ .ok($filter('translate')('YANGMAN_OK'))
+ .cancel($filter('translate')('YANGMAN_CANCEL'));
+
+ YangmanDesignService.disableMdMenuItem(ev);
+
+ $mdDialog.show(confirm).then(function (){
+ vm.collectionList.deleteCollection(collObj);
+ vm.collectionList.saveToStorage();
+ refreshCollectionsWithExpansion();
+ }, function (){
+ YangmanDesignService.enableMdMenuItem(ev);
+ });
+ }
+
+ /**
+ * Check if reqObj matches current search value
+ * @param reqObj
+ * @returns {boolean}
+ */
+ function filterReq(reqObj){
+ var searchPhrase = vm.search.toLocaleLowerCase();
+ return reqObj.path.toLowerCase().indexOf(searchPhrase) > -1 ||
+ reqObj.collection.toLowerCase().indexOf(searchPhrase) > -1 ||
+ reqObj.method.toLowerCase() === searchPhrase;
+ }
+
+ /**
+ * Check if collection name matches current search value or any collection req matches
+ * @param colObj
+ */
+ function filterCol(colObj){
+ return filterColName(colObj) || colObj.data.some(filterReq);
+ }
+
+ /**
+ * Get count of requests matching filter in collection colObj
+ * @param colObj
+ * @returns {*}
+ */
+ function colMatchingReqsCount(colObj){
+ return colObj.data.filter(vm.filterReq).length;
+ }
+
+ /**
+ * Check if collection name matches current filter
+ * @param colObj
+ * @returns {boolean}
+ */
+ function filterColName(colObj){
+ return colObj.name.toLowerCase().indexOf(vm.search.toLowerCase()) > -1;
+ }
+
+ /**
+ * Returns true
+ * @returns {boolean}
+ */
+ function fakeFilter(){
+ return true;
+ }
+
+
+ /**
+ * Show dialog for saving reqObj to collection (used for duplicate req too)
+ * @param ev
+ * @param reqObj
+ * @param duplicate
+ */
+ function showDgSaveReq(ev, reqObj, duplicate){
+
+ $mdDialog.show({
+ controller: SaveReqDialogCtrl,
+ controllerAs: 'dialog',
+ templateUrl: $scope.globalViewPath + 'leftpanel/save-req-dialog.tpl.html',
+ parent: angular.element('#yangmanModule'),
+ targetEvent: ev,
+ clickOutsideToClose: true,
+ locals: {
+ requests: reqObj ? [reqObj] : vm.mainList.getSelectedItems(
+ vm.mainList === vm.collectionList ? filterCollReq : filterReq
+ ),
+ collectionNames: vm.collectionList.getCollectionNames(),
+ duplicate: duplicate || false,
+ },
+ }).then(saveRequests);
+ }
+
+ /**
+ * Add each request from requests array to collectionList and save
+ * @param requests
+ */
+ function saveRequests(requests){
+ requests.forEach(function (reqObj){
+ vm.collectionList.addItemToList(RequestsService.clearUnnecessaryProperties(reqObj.clone()));
+ vm.collectionList.saveToStorage();
+ refreshCollectionsWithExpansion();
+ });
+ }
+
+
+ /**
+ * Dialog for editing collection name (used for duplicating collection too)
+ * @param ev
+ * @param collection
+ * @param {boolean} duplicate
+ */
+ function showDgEditCollection(ev, collection, duplicate){
+ $mdDialog.show({
+ controller: EditCollectionDialogCtrl,
+ controllerAs: 'dialog',
+ templateUrl: $scope.globalViewPath + 'leftpanel/edit-collection-dialog.tpl.html',
+ parent: angular.element('#yangmanModule'),
+ targetEvent: ev,
+ clickOutsideToClose: true,
+ locals: {
+ collection: collection,
+ allCollections: vm.collectionList.collections,
+ duplicate: duplicate,
+ },
+ }).then(duplicate ? duplicateCollection : changeCollectionName);
+ }
+
+ /**
+ * Rename collection
+ * @param {array} names 0. element is old name, 1. element is new name
+ */
+ function changeCollectionName(names){
+ vm.collectionList.renameCollection(names[0], names[1]);
+ vm.collectionList.saveToStorage();
+ refreshCollectionsWithExpansion();
+ }
+
+ /**
+ * Create collection duplicate, save and refresh collections
+ * @param {array} names 0. element is old name, 1. element is new name
+ */
+ function duplicateCollection(names){
+ vm.collectionList.duplicateCollection(names[0], names[1]);
+ vm.collectionList.saveToStorage();
+ refreshCollectionsWithExpansion();
+ }
+
+
+ function selectNewestRequest() {
+ vm.mainList.toggleReqSelection(true, vm.mainList.getNewestRequest());
+ }
+
+ function loadCollectionsList() {
+ vm.collectionList.loadListFromStorage();
+ }
+
+ function loadHistoryList() {
+ vm.requestList.loadListFromStorage();
+ }
+
+ /**
+ *
+ * @param mainList collectionList or requestList object
+ */
+ function init(mainList){
+
+ vm.collectionList = RequestsService.createEmptyCollectionList('yangman_collectionsList');
+ // collections are loaded for both history and collections tab
+ loadCollectionsList();
+
+ vm.requestList = RequestsService.createEmptyHistoryList('yangman_requestsList');
+
+
+ // if request was selected, deselect requests in all other instances of RequestsListCtrl
+ $scope.$on(constants.YANGMAN_DESELECT_REQUESTS, function (event, params) {
+ if (params.params.broadcastingCtrl !== vm) {
+ deselectAllRequests();
+ }
+ });
+
+ $scope.$on(constants.YANGMAN_REFRESH_COLLECTIONS, function (event, params){
+ loadCollectionsList();
+ (params.cbk || angular.noop)();
+ });
+
+ // list type dependend operations
+ if (mainList === 'history') {
+
+ vm.mainList = vm.requestList;
+ loadHistoryList();
+
+ $scope.$on(constants.YANGMAN_REFRESH_HISTORY, loadHistoryList);
+ // saving from request header after execution
+ $scope.$on(constants.YANGMAN_SAVE_EXECUTED_REQUEST, saveBcstedHistoryRequest);
+ // select newest request
+ $scope.$on(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST, selectNewestRequest);
+ }
+ else {
+ vm.mainList = vm.collectionList;
+ // saving from request header
+ $scope.$on(constants.YANGMAN_SAVE_REQUEST_TO_COLLECTION, saveRequestFromExt);
+ // saving collections expanded status on refresh
+ $scope.$on(constants.YANGMAN_REFRESH_AND_EXPAND_COLLECTIONS, function(){
+ var expandedColNames = vm.collectionList.getExpandedCollectionNames();
+ $scope.rootBroadcast(constants.YANGMAN_REFRESH_COLLECTIONS, {}, function (){
+ vm.collectionList.expandCollectionByNames(expandedColNames);
+ });
+ });
+ }
+
+ }
+
+
+ /**
+ * Request in list selection
+ * For history reqs it is possible multiselect, thats why event.ctrlKey is used
+ * @param event
+ * @param requestObj
+ */
+ function selectRequest(event, requestObj){
+ $scope.rootBroadcast(constants.YANGMAN_DESELECT_REQUESTS, { broadcastingCtrl: vm });
+ vm.mainList.toggleReqSelection(!event.ctrlKey, requestObj);
+ if (!event.ctrlKey){
+ if ($scope.rightPanelSection === constants.DISPLAY_TYPE_FORM) {
+ vm.showForm(requestObj, true);
+ }
+ else {
+ vm.showData(requestObj, true);
+ }
+ }
+ }
+
+ /**
+ * Mark only requestObj in current list as selected
+ * Used for example when user clicks on request submenu
+ * @param requestObj
+ */
+ function selectOnlyThisRequest(requestObj){
+ vm.mainList.toggleReqSelection(true, requestObj);
+ }
+
+ /**
+ * Deselect history requests
+ */
+ function deselectAllFilteredReqs(){
+ vm.mainList.deselectAllFilteredItems(vm.mainList === vm.collectionList ? filterCollReq : vm.filterReq);
+ }
+
+ function deselectAllRequests() {
+ vm.mainList.deselectAllItems();
+ }
+
+ /**
+ * Select history requests
+ */
+ function selectAllFilteredReqs(){
+ vm.mainList.selectAllFilteredItems(vm.mainList === vm.collectionList ? filterCollReq : vm.filterReq);
+ }
+
+ /**
+ * Use when selecting filtered requests if they are saved to some collection
+ * Additional filter is if the collection of the request is expanded
+ * @param request
+ * @returns {*|boolean}
+ */
+ function filterCollReq(request) {
+ return vm.collectionList.getCollection(request.collection).expanded && vm.filterReq(request);
+ }
+
+ /**
+ * Refresh and expand collections
+ */
+ function refreshCollectionsWithExpansion(){
+ $scope.rootBroadcast(constants.YANGMAN_REFRESH_AND_EXPAND_COLLECTIONS);
+ }
+
+ }
+
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('SaveReqDialogCtrl', SaveReqDialogCtrl);
+
+ SaveReqDialogCtrl.$inject = ['$filter', '$mdDialog', 'collectionNames', 'requests', 'duplicate'];
+
+ function SaveReqDialogCtrl($filter, $mdDialog, collectionNames, requests, duplicate) {
+ var vm = this;
+
+ vm.collectionNames = collectionNames;
+ vm.collectionName = duplicate ? requests[0].collection : '';
+ vm.getColAutocomplete = getColAutocomplete;
+ vm.requests = requests;
+ vm.duplicate = duplicate;
+
+ vm.cancel = cancel;
+ vm.save = save;
+
+ cloneRequests();
+
+ function getColAutocomplete() {
+ return vm.collectionNames ? $filter('filter')(vm.collectionNames, vm.collectionName) : vm.collectionNames;
+ }
+
+ function cloneRequests(){
+ vm.requests = vm.requests.map(function (req){
+ return req.clone();
+ });
+ }
+
+ function cancel() {
+ $mdDialog.cancel();
+ }
+
+ function save() {
+ vm.requests.forEach(function (reqObj){
+ reqObj.collection = vm.collectionName;
+ });
+ $mdDialog.hide(vm.requests);
+ }
+
+ }
+
+ return SaveReqDialogCtrl;
+
+});
--- /dev/null
+define([
+ 'app/yangman/controllers/form/ym-augmentation-modal.controller',
+ 'app/yangman/controllers/form/ym-case.controller',
+ 'app/yangman/controllers/form/ym-container.controller',
+ 'app/yangman/controllers/form/ym-choice.controller',
+ 'app/yangman/controllers/form/ym-input.controller',
+ 'app/yangman/controllers/form/ym-leaf.controller',
+ 'app/yangman/controllers/form/ym-leaf-list.controller',
+ 'app/yangman/controllers/form/ym-list.controller',
+ 'app/yangman/controllers/form/ym-output.controller',
+ 'app/yangman/controllers/form/ym-rpc.controller',
+ 'app/yangman/controllers/form/ym-type.controller',
+ 'app/yangman/controllers/form/ym-type-bit.controller',
+ 'app/yangman/controllers/form/ym-type-boolean.controller',
+ 'app/yangman/controllers/form/ym-type-empty.controller',
+ 'app/yangman/controllers/form/ym-type-enum.controller',
+ 'app/yangman/directives/yang-form-menu.directive',
+ 'app/yangman/directives/ym-info-box.directive',
+], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YangFormCtrl', YangFormCtrl);
+
+ YangFormCtrl.$inject = ['$scope', '$rootScope', '$filter', 'constants', 'YangUtilsService'];
+
+ function YangFormCtrl($scope, $rootScope, $filter, constants) {
+ var yangForm = this;
+
+ yangForm.viewPath = $scope.globalViewPath + 'rightpanel/form';
+ yangForm.errorMsg = '';
+ $scope.constants = constants;
+
+ // methods
+ yangForm.getNodeName = getNodeName;
+
+ // watchers
+ $scope.$on(constants.YANGMAN_SET_ERROR_DATA, setRcvdErrorData);
+
+ $scope.$on(constants.YANGMAN_SET_ERROR_MESSAGE, setErrorMessage);
+
+ /**
+ * Method for set error message in form
+ * @param event
+ * @param message
+ */
+ function setErrorMessage(event, data){
+ yangForm.errorMsg = data.params;
+ }
+
+ /**
+ * Read and set error message received from header controller
+ * @param event
+ * @param data
+ */
+ function setRcvdErrorData(event, data) {
+
+ if (data.params.errors) {
+ yangForm.errorMsg = data.params.errors.error[0]['error-message'];
+ }
+ else {
+ yangForm.errorMsg = '';
+ }
+ }
+
+ /**
+ * Get node label name
+ * @param localeLabel
+ * @param label
+ * @returns {*}
+ */
+ function getNodeName(localeLabel, label) {
+ var localeResult = $filter('translate')(localeLabel);
+ return localeResult.indexOf(constants.LOCALE_PREFIX) === 0 ? label : localeResult;
+ }
+
+
+ }
+
+});
--- /dev/null
+define([
+ 'app/yangman/yangman.filters',
+ 'app/yangman/controllers/modules-list.controller',
+ 'app/yangman/controllers/module-detail.controller',
+ 'app/yangman/controllers/yang-form.controller',
+ 'app/yangman/controllers/requests-list.controller',
+ 'app/yangman/controllers/request-header.controller',
+ 'app/yangman/controllers/request-data.controller',
+ 'app/yangman/services/yangman.services',
+ 'app/yangman/services/handle-file.services',
+ 'app/yangman/services/yangman-design.services',
+ 'app/yangman/services/requests.services',
+ 'app/yangman/services/parameters.services',
+ 'app/yangman/services/plugins-unsetter.services',
+ 'app/yangman/directives/ui-codemirror.directive',
+ 'app/yangman/directives/read_file.directive',
+], function () {
+ 'use strict';
+
+ angular.module('app.yangman').controller('YangmanCtrl', YangmanCtrl);
+
+ YangmanCtrl.$inject = [
+ '$mdDialog', '$scope', '$rootScope', 'YangmanDesignService', 'RequestBuilderService',
+ 'EventDispatcherService', 'constants', 'ParametersService', 'PathUtilsService', 'PluginsUnsetterService', '$timeout',
+ ];
+
+ function YangmanCtrl(
+ $mdDialog, $scope, $rootScope, YangmanDesignService, RequestBuilderService,
+ EventDispatcherService, constants, ParametersService, PathUtilsService, PluginsUnsetterService, $timeout
+ ) {
+ var main = this;
+
+ $rootScope.section_logo = 'assets/images/logo_yangman.png';
+ $scope.globalViewPath = 'src/app/yangman/views/';
+
+ $scope.selectedModule = null;
+ $scope.selectedDatastore = null;
+ $scope.apis = [];
+ $scope.node = null;
+ $scope.rightPanelSection = constants.DISPLAY_TYPE_REQ_DATA;
+ $scope.augmentations = {};
+ $scope.selectedApi = null;
+ $scope.selectedSubApi = null;
+ $scope.historyReqsSelected = false;
+ $scope.requestToShow = null;
+ $scope.requestDataToShow = '';
+ $scope.parametersList = ParametersService.createEmptyParametersList('yangman_parameters');
+ $scope.shownCMHint = false;
+
+ main.selectedMainTab = 0;
+ main.leftPanelTab = 0;
+ main.jsonView = {
+ received: true,
+ sent: false,
+ };
+ main.executingRequestProgress = false;
+ main.constants = constants;
+
+ // methods
+ main.init = init;
+ main.initModuleDetailHeight = initModuleDetailHeight;
+ main.switchedTab = switchedTab;
+ main.toggleLeftPanel = toggleLeftPanel;
+ main.leftPanelShowModule = leftPanelShowModule;
+ main.modulesTreeDisplayed = modulesTreeDisplayed;
+
+ // scope global methods
+ $scope.buildRootRequest = buildRootRequest;
+ $scope.broadcastFromRoot = broadcastFromRoot;
+ $scope.checkAddingListElement = checkAddingListElement;
+ $scope.clearCM = clearCM;
+ $scope.rootBroadcast = rootBroadcast;
+ $scope.setApi = setApi;
+ $scope.setDataStore = setDataStore;
+ $scope.setGlobalParams = setGlobalParams;
+ $scope.setJsonView = setJsonView;
+ $scope.setLeftPanel = setLeftPanel;
+ $scope.setModule = setModule;
+ $scope.setNode = setNode;
+ $scope.setRequestToShow = setRequestToShow;
+ $scope.setRightPanelSection = setRightPanelSection;
+ $scope.switchSection = switchSection;
+ $scope.setParametersList = setParametersList;
+ $scope.unsetPlugin = unsetPlugin;
+ $scope.setCMHintShown = setCMHintShown;
+
+ init();
+
+ function setCMHintShown(shown) {
+ $scope.shownCMHint = shown;
+ }
+
+ function startExecutingRequestProgress() {
+ main.executingRequestProgress = true;
+ }
+
+ function stopExecutingRequestProgress() {
+ main.executingRequestProgress = false;
+ }
+
+ /**
+ * Set parametersList
+ * @param parametersList
+ */
+ function setParametersList(parametersList) {
+ $scope.parametersList = parametersList;
+ }
+
+
+ /**
+ * Broadcast from this main controller to all children ctrls
+ * @param eventName
+ * @param val
+ */
+ function broadcastFromRoot(eventName, val) {
+ $scope.$broadcast(eventName, val);
+ }
+ /**
+ * Initialization
+ */
+ function init(){
+ $scope.$on(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_START, startExecutingRequestProgress);
+ $scope.$on(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_STOP, stopExecutingRequestProgress);
+
+ YangmanDesignService.hideMainMenu();
+ YangmanDesignService.setDraggableLeftPanel();
+ YangmanDesignService.setJsonSplitter(forceCMsRefresh);
+
+ EventDispatcherService.registerHandler(constants.EV_FILL_PATH, fillPathIdentifiersByKey);
+ EventDispatcherService.registerHandler(constants.EV_LIST_CHANGED, fillPathIdentifiersByListData);
+ }
+
+ /**
+ * Initialize module detail height, with timeout
+ */
+ function initModuleDetailHeight(){
+ $timeout(function () {
+ YangmanDesignService.setModuleDetailHeight();
+ }, 1500);
+ }
+
+ /**
+ * Method for fill key into request path
+ * @param inputs
+ */
+ function fillPathIdentifiersByKey(inputs) {
+ var node = inputs[0],
+ value = inputs[1] || '';
+
+ if ($scope.selectedSubApi && node.parent && $scope.selectedSubApi.node.id === node.parent.id) {
+ var identifiers =
+ $scope.selectedSubApi.pathArray[$scope.selectedSubApi.pathArray.length - 1].identifiers;
+
+ PathUtilsService.fillIdentifiers(identifiers, node.label, value);
+ }
+ }
+
+ // TODO :: description
+ function fillPathIdentifiersByListData(inputs) {
+ var node = inputs[0];
+
+ if ($scope.selectedSubApi && node && $scope.selectedSubApi.node.id === node.id) {
+ var identifiers =
+ $scope.selectedSubApi.pathArray[$scope.selectedSubApi.pathArray.length - 1].identifiers,
+ keys = node.refKey;
+
+ keys.forEach(function (key) {
+ PathUtilsService.fillIdentifiers(identifiers, key.label, key.value);
+ });
+ }
+ }
+
+ // TODO :: description
+ function modulesTreeDisplayed() {
+ return main.selectedMainTab === 0;
+ }
+
+ /**
+ * Set switched tab index
+ */
+ function switchedTab(index){
+ main.selectedMainTab = index;
+ }
+
+ /**
+ * Switcher between modules list and module detail
+ */
+ function toggleLeftPanel(){
+ main.leftPanelTab = (main.leftPanelTab + 1) % 2;
+ }
+
+ /**
+ * Method for opening model detail tab
+ */
+ function leftPanelShowModule() {
+ if ($scope.node) {
+ main.leftPanelTab = 1;
+ }
+ }
+
+ /**
+ * General method for switching different section in application
+ * @param param
+ * @param section
+ */
+ function switchSection(param, section){
+ $scope[param] = section;
+ }
+
+ /**
+ * Genereal method for clearing code mirror - sent and received data too
+ */
+ function clearCM(){
+ $scope.rootBroadcast(constants.YANGMAN_SET_CODEMIRROR_DATA_RECEIVED, { data: JSON.stringify({}) });
+ $scope.rootBroadcast(constants.YANGMAN_SET_CODEMIRROR_DATA_SENT, { data: JSON.stringify({}) });
+ }
+
+
+ // SETTERS
+
+ /**
+ * Switcher for module detail and module list
+ * @param value
+ */
+ function setLeftPanel(value) {
+ if ( !angular.isUndefined(value) ) {
+ main.leftPanelTab = value;
+ }
+ }
+
+ /**
+ * Set global necessary params
+ * @param apis
+ */
+ function setGlobalParams(apis, augmentations){
+ $scope.apis = apis;
+ $scope.augmentations = augmentations;
+ }
+
+ /**
+ * Set node to global param
+ * @param node
+ */
+ function setNode(node){
+ $scope.node = node;
+
+ if ( $scope.node ) {
+ $scope.node.clear();
+ $scope.$broadcast(constants.YANGMAN_DISABLE_ADDING_LIST_ELEMENT);
+ }
+ }
+
+ /**
+ * Set module to global param
+ * @param module
+ */
+ function setModule(module){
+ $scope.selectedModule = module;
+ }
+
+ /**
+ * Set dataStore to global param && open module detail in left panel
+ * @param dataStore
+ * @param expand
+ */
+ function setDataStore(dataStore, expand, leftPanel){
+ $scope.selectedDatastore = dataStore;
+
+ if ( expand ) {
+ $scope.node = null;
+ setLeftPanel(leftPanel);
+ $scope.$broadcast(constants.YANGMAN_MODULE_D_INIT);
+ } else {
+
+ if ( $scope.node ) {
+ $scope.node.clear();
+ }
+ }
+ }
+
+ /**
+ * Build request json from root node
+ */
+ function buildRootRequest() {
+ var obj = {};
+ $scope.node.buildRequest(RequestBuilderService, obj, $scope.node.module);
+ return obj;
+ }
+
+ /**
+ * Set api and sub api to global param
+ * @param api
+ * @param subApi
+ */
+ function setApi(api, subApi, setUrl, clearPathArray){
+ $scope.selectedApi = api;
+ $scope.selectedSubApi = subApi;
+
+ if ( clearPathArray ){
+ PathUtilsService.clearPath($scope.selectedSubApi.pathArray);
+ }
+
+ $scope.$broadcast(constants.SET_SEL_OPERATIONS, subApi ? $scope.selectedSubApi.operations : [], setUrl);
+ }
+
+ /**
+ * Call broadcast from root to child controllers
+ * @param broadcast
+ * @param params
+ * @param cbk
+ */
+ function rootBroadcast(broadcast, params, cbk){
+ $scope.$broadcast(broadcast, { params: params, cbk: cbk });
+ }
+
+ /**
+ * Set request from history or collections to show data in code mirror
+ * @param reqObj
+ * @param {'sentData'|'receivedData'} dataType
+ */
+ function setRequestToShow(reqObj, dataType) {
+ $scope.requestToShow = reqObj;
+ $scope.requestDataToShow = dataType;
+ }
+
+ /**
+ * Set rightPanelSection to display current section in right panel
+ * @param section 'form', 'req-data'
+ */
+ function setRightPanelSection(section) {
+ $scope.rightPanelSection = section;
+ }
+
+ /**
+ * Which codemirror instances will be displayed
+ * @param received
+ * @param sent
+ */
+ function setJsonView(received, sent){
+ main.jsonView.received = received;
+ main.jsonView.sent = sent;
+ forceCMsRefresh();
+ YangmanDesignService.setJsonSplitter(forceCMsRefresh);
+ }
+
+ /**
+ * Force refresh of all codemirror instances
+ */
+ function forceCMsRefresh(){
+ var elems = angular.element(document).find('.CodeMirror');
+ for (var i = 0; i < elems.length; i++){
+ var cmInstance = elems[i].CodeMirror;
+ cmInstance._handlers.changes[0](cmInstance);
+ }
+ }
+
+ /**
+ * Global method for unset plugin
+ * @param selectedPlugin
+ * @param controller
+ */
+ function unsetPlugin(controller){
+ PluginsUnsetterService.unset($scope, controller);
+ }
+
+ /**
+ * Checks if the element list should be disabled
+ */
+ function checkAddingListElement(node) {
+ return $scope.node === node && $scope.node.type === 'list' &&
+ $scope.node.refKey && $scope.node.refKey.length;
+ }
+ }
+
+});
--- /dev/null
+define(['angular'], function (angular) {
+ 'use strict';
+
+ angular.module('app.yangman').directive('abnApiTree', [
+ '$timeout', 'constants', function ($timeout, constants) {
+ return {
+ restrict: 'E',
+ templateUrl: 'src/app/yangman/views/directives/abn-tree.tpl.html',
+ replace: true,
+ scope: {
+ treeData: '=',
+ onSelect: '&',
+ initialSelection: '@',
+ treeControl: '=',
+ treeRows: '=',
+ },
+ link: function (scope, element, attrs) {
+ var expandAllParents,
+ expandLevel,
+ forAllAncestors,
+ forEachBranch,
+ getParent,
+ n,
+ onTreeDataChange,
+ selectBranch,
+ selectedBranch,
+ tree;
+
+ if (attrs.iconExpand == null) {
+ attrs.iconExpand = constants.ICON_EXPAND_ADD;
+ }
+ if (attrs.iconCollapse == null) {
+ attrs.iconCollapse = constants.ICON_COLLAPSE_REMOVE;
+ }
+ if (attrs.iconLeaf == null) {
+ attrs.iconLeaf = constants.ICON_KEYBOARD_ARROW_RIGHT;
+ }
+ if (attrs.expandLevel == null) {
+ attrs.expandLevel = constants.EXPAND_LEVEL_THREE;
+ }
+ expandLevel = parseInt(attrs.expandLevel, 10);
+ if (!scope.treeData) {
+ return;
+ }
+ if (scope.treeData.length == null) {
+ if (scope.treeData.label != null) {
+ scope.treeData = [scope.treeData];
+ } else {
+ return;
+ }
+ }
+ forEachBranch = function (f) {
+ var do_f,
+ root_branch,
+ _i,
+ _len,
+ _ref,
+ _results;
+
+ do_f = function (branch, level) {
+ var child,
+ _i,
+ _len,
+ _ref,
+ _results;
+
+ f(branch, level);
+ if (branch.children != null) {
+ _ref = branch.children;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ _results.push(do_f(child, level + 1));
+ }
+ return _results;
+ }
+ };
+ _ref = scope.treeData;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ root_branch = _ref[_i];
+ _results.push(do_f(root_branch, 1));
+ }
+ return _results;
+ };
+ selectedBranch = null;
+ selectBranch = function (branch) {
+ if (!branch) {
+ if (selectedBranch != null) {
+ selectedBranch.selected = false;
+ }
+ selectedBranch = null;
+ return;
+ }
+
+ if (selectedBranch != null) {
+ selectedBranch.selected = false;
+ }
+ branch.selected = true;
+ selectedBranch = branch;
+ expandAllParents(branch);
+ if (branch.onSelect != null) {
+ return $timeout(function () {
+ return branch.onSelect(branch);
+ });
+ } else {
+ if (scope.onSelect != null) {
+ return $timeout(function () {
+ return scope.onSelect({
+ branch: branch,
+ });
+ });
+ }
+ }
+
+ };
+ scope.user_clicks_branch = function (branch) {
+
+ scope.tree_rows.forEach(function (item){
+ item.branch.selected = false;
+ });
+
+ if (branch === selectedBranch) {
+ branch.selected = true;
+ }
+
+ return selectBranch(branch);
+ };
+
+ getParent = function (child) {
+ var parent;
+ parent = void 0;
+ if (child.parent_uid) {
+ forEachBranch(function (b) {
+ if (b.uid === child.parent_uid) {
+ return parent = b;
+ }
+ });
+ }
+ return parent;
+ };
+ forAllAncestors = function (child, fn) {
+ var parent;
+ parent = getParent(child);
+ if (parent != null) {
+ fn(parent);
+ return forAllAncestors(parent, fn);
+ }
+ };
+ expandAllParents = function (child) {
+ return forAllAncestors(child, function (b) {
+ return b.expanded = true;
+ });
+ };
+
+ scope.expandedTree = false;
+ scope.expand_collapse_all_items = function (){
+
+ var expand = !scope.expandedTree ? true : false;
+
+ scope.tree_rows.forEach(function (child){
+ child.branch.expanded = expand;
+ });
+
+ scope.expandedTree = !scope.expandedTree;
+ };
+ scope.collapse_others = function (){
+ var parentId = null,
+ expandParent = function (parentId){
+ if ( parentId ) {
+ scope.tree_rows.forEach(function (child){
+ if ( child.branch.uid === parentId ) {
+ child.branch.expanded = true;
+ parentId = child.branch.parent_uid;
+
+ if ( parentId ) {
+ expandParent(parentId);
+ }
+ }
+ });
+ }
+ };
+
+ scope.tree_rows.forEach(function (child){
+ if ( child.branch.selected ) {
+ parentId = child.branch.parent_uid;
+ }
+ child.branch.expanded = child.branch.selected ? child.branch.expanded : false;
+ });
+
+ if ( parentId ) {
+ expandParent(parentId);
+ }
+
+ };
+
+ scope.$watch(constants.TREE_ROWS, function () {
+ scope.treeRows = scope.tree_rows;
+ scope.$emit(constants.SET_SCOPE_TREE_ROWS, scope.treeRows);
+ });
+
+ scope.tree_rows = [];
+ onTreeDataChange = function () {
+ var add_branch_to_list,
+ root_branch,
+ _i,
+ _len,
+ _ref,
+ _results;
+
+ forEachBranch(function (b) {
+ if (!b.uid) {
+ return b.uid = '' + Math.random();
+ }
+ });
+ forEachBranch(function (b) {
+ var child,
+ _i,
+ _len,
+ _ref,
+ _results;
+
+ if (angular.isArray(b.children)) {
+ _ref = b.children;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ _results.push(child.parent_uid = b.uid);
+ }
+ return _results;
+ }
+ });
+ scope.tree_rows = [];
+ forEachBranch(function (branch) {
+ var child,
+ f;
+
+ if (branch.children) {
+ if (branch.children.length > 0) {
+ f = function (e) {
+ if (typeof e === 'string') {
+ return {
+ label: e,
+ children: [],
+ };
+ } else {
+ return e;
+ }
+ };
+ return branch.children = (function () {
+ var _i,
+ _len,
+ _ref,
+ _results;
+
+ _ref = branch.children;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ _results.push(f(child));
+ }
+ return _results;
+ })();
+ }
+ } else {
+ return branch.children = [];
+ }
+ });
+ add_branch_to_list = function (level, branch, visible) {
+ var child,
+ child_visible,
+ tree_icon,
+ _i,
+ _len,
+ _ref,
+ _results;
+
+ if (branch.expanded == null) {
+ branch.expanded = false;
+ }
+ if (!branch.children || branch.children.length === 0) {
+ tree_icon = attrs.iconLeaf;
+ } else {
+ if (branch.expanded) {
+ tree_icon = attrs.iconCollapse;
+ } else {
+ tree_icon = attrs.iconExpand;
+ }
+ }
+ scope.tree_rows.push({
+ level: level,
+ branch: branch,
+ label: branch.label,
+ tree_icon: tree_icon,
+ visible: visible,
+ });
+ if (branch.children != null) {
+ _ref = branch.children;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ child_visible = visible && branch.expanded;
+ _results.push(add_branch_to_list(level + 1, child, child_visible));
+ }
+ return _results;
+ }
+ };
+ _ref = scope.treeData;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ root_branch = _ref[_i];
+ _results.push(add_branch_to_list(1, root_branch, true));
+ }
+ return _results;
+ };
+ scope.$watch('treeData', onTreeDataChange, true);
+ if (attrs.initialSelection != null) {
+ forEachBranch(function (b) {
+ if (b.label === attrs.initialSelection) {
+ return $timeout(function () {
+ return selectBranch(b);
+ });
+ }
+ });
+ }
+ n = scope.treeData.length;
+ forEachBranch(function (b, level) {
+ b.level = level;
+ return b.expanded = b.level < expandLevel;
+ });
+ if (scope.treeControl != null) {
+ if (angular.isObject(scope.treeControl)) {
+ tree = scope.treeControl;
+ tree.expand_all = function () {
+ return forEachBranch(function (b) {
+ return b.expanded = true;
+ });
+ };
+ tree.collapse_all = function () {
+ return forEachBranch(function (b) {
+ return b.expanded = false;
+ });
+ };
+ tree.get_first_branch = function () {
+ n = scope.treeData.length;
+ if (n > 0) {
+ return scope.treeData[0];
+ }
+ };
+ tree.select_first_branch = function () {
+ var b;
+ b = tree.get_first_branch();
+ return tree.selectBranch(b);
+ };
+ tree.get_selected_branch = function () {
+ return selectedBranch;
+ };
+ tree.get_parent_branch = function (b) {
+ return getParent(b);
+ };
+ tree.select_branch = function (b) {
+ selectBranch(b);
+ return b;
+ };
+ tree.get_children = function (b) {
+ return b.children;
+ };
+ tree.select_parent_branch = function (b) {
+ var p;
+ if (b == null) {
+ b = tree.get_selected_branch();
+ }
+ if (b != null) {
+ p = tree.get_parent_branch(b);
+ if (p != null) {
+ tree.select_branch(p);
+ return p;
+ }
+ }
+ };
+ tree.add_branch = function (parent, new_branch) {
+ if (parent != null) {
+ parent.children.push(new_branch);
+ parent.expanded = true;
+ } else {
+ scope.treeData.push(new_branch);
+ }
+ return new_branch;
+ };
+ tree.add_root_branch = function (new_branch) {
+ tree.add_branch(null, new_branch);
+ return new_branch;
+ };
+ tree.expand_branch = function (b) {
+ if (b == null) {
+ b = tree.get_selected_branch();
+ }
+ if (b != null) {
+ b.expanded = true;
+ return b;
+ }
+ };
+ tree.collapse_branch = function (b) {
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ b.expanded = false;
+ return b;
+ }
+ };
+ tree.get_siblings = function (b) {
+ var p,
+ siblings;
+
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ p = tree.get_parent_branch(b);
+ if (p) {
+ siblings = p.children;
+ } else {
+ siblings = scope.treeData;
+ }
+ return siblings;
+ }
+ };
+ tree.get_next_sibling = function (b) {
+ var i,
+ siblings;
+
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ siblings = tree.get_siblings(b);
+ n = siblings.length;
+ i = siblings.indexOf(b);
+ if (i < n) {
+ return siblings[i + 1];
+ }
+ }
+ };
+ tree.get_prev_sibling = function (b) {
+ var i,
+ siblings;
+
+ if (b == null) {
+ b = selectedBranch;
+ }
+ siblings = tree.get_siblings(b);
+ n = siblings.length;
+ i = siblings.indexOf(b);
+ if (i > 0) {
+ return siblings[i - 1];
+ }
+ };
+ tree.select_next_sibling = function (b) {
+ var next;
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ next = tree.get_next_sibling(b);
+ if (next != null) {
+ return tree.select_branch(next);
+ }
+ }
+ };
+ tree.select_prev_sibling = function (b) {
+ var prev;
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ prev = tree.get_prev_sibling(b);
+ if (prev != null) {
+ return tree.select_branch(prev);
+ }
+ }
+ };
+ tree.get_first_child = function (b) {
+ var _ref;
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ if (((_ref = b.children) != null ? _ref.length : void 0) > 0) {
+ return b.children[0];
+ }
+ }
+ };
+ tree.get_closest_ancestor_next_sibling = function (b) {
+ var next,
+ parent;
+
+ next = tree.get_next_sibling(b);
+ if (next != null) {
+ return next;
+ } else {
+ parent = tree.get_parent_branch(b);
+ return tree.get_closest_ancestor_next_sibling(parent);
+ }
+ };
+ tree.get_next_branch = function (b) {
+ var next;
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ next = tree.get_first_child(b);
+ if (next != null) {
+ return next;
+ } else {
+ next = tree.get_closest_ancestor_next_sibling(b);
+ return next;
+ }
+ }
+ };
+ tree.select_next_branch = function (b) {
+ var next;
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ next = tree.get_next_branch(b);
+ if (next != null) {
+ tree.select_branch(next);
+ return next;
+ }
+ }
+ };
+ tree.last_descendant = function (b) {
+ var last_child;
+ if (b == null) {
+ // debugger;
+ }
+ n = b.children.length;
+ if (n === 0) {
+ return b;
+ } else {
+ last_child = b.children[n - 1];
+ return tree.last_descendant(last_child);
+ }
+ };
+ tree.get_prev_branch = function (b) {
+ var parent,
+ prev_sibling;
+
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ prev_sibling = tree.get_prev_sibling(b);
+ if (prev_sibling != null) {
+ return tree.last_descendant(prev_sibling);
+ } else {
+ parent = tree.get_parent_branch(b);
+ return parent;
+ }
+ }
+ };
+ return tree.select_prev_branch = function (b) {
+ var prev;
+ if (b == null) {
+ b = selectedBranch;
+ }
+ if (b != null) {
+ prev = tree.get_prev_branch(b);
+ if (prev != null) {
+ tree.select_branch(prev);
+ return prev;
+ }
+ }
+ };
+ }
+ }
+ },
+ };
+ },
+ ]);
+
+
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').directive('onReadFile', readFileDirective);
+
+ readFileDirective.$inject = ['$parse'];
+
+ function readFileDirective($parse) {
+ return {
+ restrict: 'A',
+ scope: false,
+ link: function (scope, element, attrs) {
+ var fn = $parse(attrs.onReadFile);
+
+ element.on('change', function (onChangeEvent) {
+ var reader = new FileReader();
+
+ reader.onload = function (onLoadEvent) {
+ scope.$apply(function () {
+ fn(scope, { $fileContent: onLoadEvent.target.result });
+ });
+ };
+
+ reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
+ });
+ },
+ };
+ }
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').directive('uiCodemirror', uiCodemirrorDirective);
+
+ /**
+ * @ngInject
+ */
+ function uiCodemirrorDirective($timeout, ymUiCodemirrorConfig) {
+
+ return {
+ restrict: 'EA',
+ require: '?ngModel',
+ compile: function compile() {
+
+ // Require CodeMirror
+ if (angular.isUndefined(window.CodeMirror)) {
+ throw new Error('ui-codemirror needs CodeMirror to work... (o rly?)');
+ }
+
+ return postLink;
+ }
+ };
+
+ function postLink(scope, iElement, iAttrs, ngModel) {
+ var codemirrorOptions = angular.extend(
+ {value: iElement.text()},
+ ymUiCodemirrorConfig.codemirror || {},
+ scope.$eval(iAttrs.uiCodemirror),
+ scope.$eval(iAttrs.uiCodemirrorOpts)
+ );
+
+ var codemirror = newCodemirrorEditor(iElement, codemirrorOptions);
+
+ configOptionsWatcher(
+ codemirror,
+ iAttrs.uiCodemirror || iAttrs.uiCodemirrorOpts,
+ scope
+ );
+
+ configNgModelLink(codemirror, ngModel, scope);
+
+ configUiRefreshAttribute(codemirror, iAttrs.uiRefresh, scope);
+
+ // Allow access to the CodeMirror instance through a broadcasted event
+ // eg: $broadcast('CodeMirror', function(cm){...});
+ scope.$on('CodeMirror', function (event, callback) {
+ if (angular.isFunction(callback)) {
+ callback(codemirror);
+ } else {
+ throw new Error('the CodeMirror event requires a callback function');
+ }
+ });
+
+ // onLoad callback
+ if (angular.isFunction(codemirrorOptions.onLoad)) {
+ codemirrorOptions.onLoad(codemirror);
+ }
+ }
+
+ function newCodemirrorEditor(iElement, codemirrorOptions) {
+ var codemirrot;
+
+ if (iElement[0].tagName === 'TEXTAREA') {
+ // Might bug but still ...
+ codemirrot = window.CodeMirror.fromTextArea(iElement[0], codemirrorOptions);
+ } else {
+ iElement.html('');
+ codemirrot = new window.CodeMirror(function (cm_el) {
+ iElement.append(cm_el);
+ }, codemirrorOptions);
+ }
+
+ return codemirrot;
+ }
+
+ function configOptionsWatcher(codemirrot, uiCodemirrorAttr, scope) {
+ if (!uiCodemirrorAttr) {
+ return;
+ }
+
+ var codemirrorDefaultsKeys = Object.keys(window.CodeMirror.defaults);
+ scope.$watch(uiCodemirrorAttr, updateOptions, true);
+ function updateOptions(newValues, oldValue) {
+ if (!angular.isObject(newValues)) {
+ return;
+ }
+ codemirrorDefaultsKeys.forEach(function (key) {
+ if (newValues.hasOwnProperty(key)) {
+
+ if (oldValue && newValues[key] === oldValue[key]) {
+ return;
+ }
+
+ codemirrot.setOption(key, newValues[key]);
+ }
+ });
+ }
+ }
+
+ function configNgModelLink(codemirror, ngModel, scope) {
+ if (!ngModel) {
+ return;
+ }
+ // CodeMirror expects a string, so make sure it gets one.
+ // This does not change the model.
+ ngModel.$formatters.push(function (value) {
+ if (angular.isUndefined(value) || value === null) {
+ return '';
+ } else if (angular.isObject(value) || angular.isArray(value)) {
+ throw new Error('ui-codemirror cannot use an object or an array as a model');
+ }
+ return value;
+ });
+
+
+ // Override the ngModelController $render method, which is what gets called when the model is updated.
+ // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
+ ngModel.$render = function () {
+ //Code mirror expects a string so make sure it gets one
+ //Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive)
+ var safeViewValue = ngModel.$viewValue || '';
+ codemirror.setValue(safeViewValue);
+ };
+
+
+ // Keep the ngModel in sync with changes from CodeMirror
+ codemirror.on('change', function (instance) {
+ var newValue = instance.getValue();
+ if (newValue !== ngModel.$viewValue) {
+ scope.$evalAsync(function () {
+ ngModel.$setViewValue(newValue);
+ });
+ }
+ });
+
+
+ // Fix for using codemirror in tabs (or modal window)
+ codemirror.on('changes', function (instance, changes) {
+ $timeout(function () {
+ instance.refresh();
+ });
+ });
+ }
+
+ function configUiRefreshAttribute(codeMirror, uiRefreshAttr, scope) {
+ if (!uiRefreshAttr) {
+ return;
+ }
+
+ scope.$watch(uiRefreshAttr, function (newVal, oldVal) {
+ // Skip the initial watch firing
+ if (newVal !== oldVal) {
+ $timeout(function () {
+ codeMirror.refresh();
+ });
+ }
+ });
+ }
+
+ }
+
+ uiCodemirrorDirective.$inject = ['$timeout', 'ymUiCodemirrorConfig'];
+
+});
--- /dev/null
+define(['angular'], function (angular) {
+ 'use strict';
+
+ angular.module('app.yangman').directive('yangFormMenu', menuDirective);
+
+ menuDirective.$inject = [];
+
+ function menuDirective() {
+ return {
+ restrict: 'E',
+ templateUrl: 'src/app/yangman/views/directives/yang-form-menu.tpl.html',
+ scope: {
+ node: '=',
+ augmentations: '=',
+ allowItems: '=',
+ isActionMenu: '&',
+ addListItemFunc: '&',
+ addListItem: '=',
+ yangForm: '=',
+ yangList: '=',
+ },
+ controller: function ($scope) {
+ var lastSection = null;
+
+ $scope.infoBox = false;
+ $scope.infoBoxSection = '';
+ $scope.selectedListItem = 0;
+
+ // methods
+ $scope.switchSection = switchSection;
+ $scope.hideInfoBox = hideInfoBox;
+
+ /**
+ * Switcher for info box section
+ * @param section
+ */
+ function switchSection(section){
+ if ( $scope.infoBox ) {
+ if ( section === lastSection ) {
+ $scope.infoBox = false;
+ } else {
+ $scope.infoBoxSection = section;
+ }
+ } else {
+ $scope.infoBox = true;
+ $scope.infoBoxSection = section;
+ }
+ lastSection = section;
+ }
+
+ /**
+ * Hide menu info box
+ */
+ function hideInfoBox(){
+ $scope.infoBox = false;
+ angular.element('#infoBox').addClass('ng-hide');
+ }
+
+ $scope.$on('hideInfoBox', function () {
+ hideInfoBox();
+ });
+ },
+ link: function (scope, element, attrs) {
+ scope.isActive = false;
+
+ // methods
+ scope.closeMenu = closeMenu;
+ scope.openMenu = openMenu;
+
+ /**
+ * Close Yang menu
+ */
+ function closeMenu(){
+ scope.isActive = false;
+ }
+
+ /**
+ * Open Yang menu
+ */
+ function openMenu(){
+ scope.isActive = true;
+ }
+
+ },
+ };
+ }
+});
--- /dev/null
+define(['angular'], function (angular) {
+ 'use strict';
+
+ angular.module('app.yangman').directive('ymInfoBox', infoBoxDirective);
+
+ infoBoxDirective.$inject = [];
+
+ function infoBoxDirective() {
+ return {
+ restrict: 'A',
+ templateUrl: 'src/app/yangman/views/directives/ym-info-box.tpl.html',
+ transclude: true,
+ scope: {
+ node: '=',
+ },
+ link: function (scope, element) {
+ element.addClass('info-box-container');
+ },
+ controller: function ($scope) {
+ var description = $scope.node.getChildren('description', null, null, 'label')[0];
+
+ $scope.description = description ? description : '';
+ $scope.infoBox = false;
+
+ // methods
+ $scope.dividerCheck = dividerCheck;
+ $scope.executeInfoBox = executeInfoBox;
+ $scope.showBoxCheck = showBoxCheck;
+
+ /**
+ * Set info box value - true, false
+ * @param value
+ */
+ function executeInfoBox(value){
+ $scope.infoBox = value;
+ }
+
+ /**
+ * Check if box info could be shown
+ * @returns {boolean|*}
+ */
+ function showBoxCheck(){
+ return $scope.infoBox && ($scope.description.length || $scope.node.augmentationId);
+ }
+
+ /**
+ * Check for showing divider between different shown info
+ * @param key
+ * @returns {*}
+ */
+ function dividerCheck(key){
+ return key ? $scope.description.length || $scope.node.augmentationId : $scope.description.length;
+ }
+ },
+ };
+ }
+});
--- /dev/null
+require.config({
+});
+
+define(['app/yangman/yangman.module']);
--- /dev/null
+define([], function (){
+ 'use strict';
+
+
+ /**
+ * Base list object for extending history and collection object
+ * @constructor
+ * @param ParsingJsonService
+ */
+ function BaseListModel($filter, ParsingJsonService) {
+
+ var self = this;
+
+ /**
+ * General list of all objects to simply treat them
+ * @type {Array}
+ */
+ self.list = [];
+ /**
+ * Simple list of selected items from self.list
+ * @type {Array}
+ */
+ self.selectedItems = [];
+
+ self.addFromJSON = addFromJSON;
+ self.addItemToList = addItemToList;
+ self.createItem = createItem;
+ self.loadListFromStorage = loadListFromStorage;
+ self.saveToStorage = saveToStorage;
+ self.setName = setName;
+ self.selectAllFilteredItems = selectAllFilteredItems;
+ self.deselectAllFilteredItems = deselectAllFilteredItems;
+ self.getSelectedItems = getSelectedItems;
+ self.deselectAllItems = deselectAllItems;
+
+ function deselectAllItems() {
+ self.list.forEach(function (item) {
+ item.selected = false;
+ });
+ self.selectedItems = [];
+ }
+
+ /**
+ * @returns {Array}
+ */
+ function getSelectedItems(filterFunc) {
+ if (filterFunc) {
+ return $filter('filter')(self.selectedItems, filterFunc);
+ }
+ else {
+ return self.selectedItems;
+ }
+ }
+
+ /**
+ * Mark all items matching filter as selected
+ * Toggle only items matching filter, other items let be as they are
+ * @param filterFunc function returning boolean
+ */
+ function selectAllFilteredItems(filterFunc) {
+ $filter('filter')(self.list, filterFunc).forEach(function (item) {
+ item.selected = true;
+ if (self.selectedItems.indexOf(item) === -1){
+ self.selectedItems.push(item);
+ }
+ });
+ }
+
+ /**
+ * Mark all requests matching filter as deselected
+ * Toggle only requests matching filter, other requests let be as they are
+ * @param filterFunc
+ */
+ function deselectAllFilteredItems(filterFunc) {
+ $filter('filter')(self.list, filterFunc).forEach(function (item) {
+ item.selected = false;
+ self.selectedItems.splice(self.selectedItems.indexOf(item), 1);
+ });
+ }
+
+ function setName(name) {
+ self.name = name;
+ }
+
+ function createItem(elem) {
+ return elem;
+ }
+
+ function addItemToList(){}
+
+ /**
+ * Loading from localStorage
+ */
+ function loadListFromStorage(){
+ var storageList = localStorage.getItem(self.name);
+
+ if (storageList){
+ self.clear();
+ ParsingJsonService.parseJson(storageList).map(function (elem) {
+ return self.createItem(elem);
+ }).forEach(function (elem) {
+ self.addItemToList(elem);
+ });
+ }
+ }
+
+ /**
+ * Saving to local storage
+ */
+ function saveToStorage(){
+ try {
+ localStorage.setItem(self.name, JSON.stringify(self.toJSON()));
+ } catch (e) {
+ }
+ }
+
+ /**
+ * Add each request from json
+ * @param json
+ */
+ function addFromJSON(json) {
+ json.forEach(function (elem) {
+ var item = self.createItem(elem);
+ self.addItemToList(item);
+ });
+ }
+ }
+
+ return BaseListModel;
+});
--- /dev/null
+define([], function (){
+ 'use strict';
+
+ /**
+ * Collection object used in CollectionListModel
+ * @param name
+ * @constructor
+ */
+ function CollectionModel(name){
+ var self = this;
+ self.name = name;
+ self.expanded = false;
+ self.data = [];
+
+ self.clone = clone;
+ self.toggleExpanded = toggleExpanded;
+
+ function clone(newName){
+ var result = new CollectionModel(newName);
+ self.data.forEach(function (item){
+ var newItem = item.clone();
+ newItem.collection = newName;
+ result.data.push(newItem);
+ });
+ return result;
+ }
+
+ function toggleExpanded(){
+ self.expanded = !self.expanded;
+ }
+
+ }
+
+ return CollectionModel;
+});
--- /dev/null
+define(
+ ['app/yangman/models/baselist.model', 'app/yangman/models/collection.model'],
+ function (BaseListModel, CollectionModel){
+
+ 'use strict';
+
+ /**
+ * Base collection list object
+ * @constructor
+ * @param ParsingJsonService
+ * @param RequestsService
+ */
+ function CollectionListModel($filter, ParsingJsonService, RequestsService){
+
+ BaseListModel.call(this, $filter, ParsingJsonService);
+
+ /* jshint validthis: true */
+ var self = this;
+
+ /**
+ * Array of collections in which are requests from self.list groupped
+ * @type {Array}
+ */
+ self.collections = [];
+
+ self.addItemToList = addItemToList;
+ self.clear = clear;
+ self.collectionExists = collectionExists;
+ self.createItem = createItem;
+ self.deleteCollection = deleteCollection;
+ self.deleteRequestItem = deleteRequestItem;
+ self.duplicateCollection = duplicateCollection;
+ self.getCollection = getCollection;
+ self.getCollectionNames = getCollectionNames;
+ self.loadListFromFile = loadListFromFile;
+ self.renameCollection = renameCollection;
+ self.toggleReqSelection = toggleReqSelection;
+ self.toJSON = toJSON;
+ self.getCollectionInJSON = getCollectionInJSON;
+ self.getExpandedCollectionNames = getExpandedCollectionNames;
+ self.expandCollectionByNames = expandCollectionByNames;
+ self.getCollectionInRawJSON = getCollectionInRawJSON;
+
+ /**
+ *
+ * @param collectionName
+ */
+ function getCollectionInJSON(collectionName){
+ return JSON.stringify(self.toJSON(collectionName));
+ }
+
+ function getCollectionInRawJSON(collectionName){
+ return self.toJSON(collectionName);
+ }
+
+
+ /**
+ * @param collObj
+ */
+ function deleteCollection(collObj){
+
+ var colIndex = self.collections.indexOf(collObj);
+ // first check if collObj is the same as got by index to prevent delete wrong collection because of the
+ // asynchron processes (when user is pressing enter many times, this method could be called more times
+ // and in some other proceeding might be this collection already deleted)
+ if (self.collections[colIndex] && self.collections[colIndex].name === collObj.name){
+ self.collections.splice(colIndex, 1);
+ }
+ }
+
+ /**
+ *
+ * @param srcColName
+ * @param destColName
+ */
+ function duplicateCollection(srcColName, destColName){
+ var newCol = self.getCollection(srcColName).clone(destColName);
+ self.collections.push(newCol);
+ }
+
+ /**
+ *
+ * @param collObj
+ * @param name
+ */
+ function setCollObjNewName(collObj, newName){
+ collObj.name = newName;
+ collObj.data.forEach(function (item){
+ item.collection = newName;
+ });
+ }
+
+ /**
+ * Mark reqObj as selected
+ * @param reqObj HistoryRequest object to be selected
+ */
+ function toggleReqSelection(onlyOneSelected, reqObj){
+ if (onlyOneSelected){
+ self.selectedItems.forEach(function (req){
+ req.selected = false;
+ });
+ self.selectedItems = [];
+ }
+
+ if (reqObj.selected && !onlyOneSelected){
+ self.selectedItems.splice(self.selectedItems.indexOf(reqObj), 1);
+ }
+
+ reqObj.selected = (reqObj.selected && onlyOneSelected) || !reqObj.selected;
+ if (reqObj.selected){
+ self.selectedItems.push(reqObj);
+ }
+ }
+
+ /**
+ *
+ * @param oldName
+ * @param newName
+ */
+ function renameCollection(oldName, newName){
+ var col = self.getCollection(oldName);
+ setCollObjNewName(col, newName);
+ }
+
+ /**
+ *
+ * @param elem
+ * @returns {HistoryRequest|*}
+ */
+ function createItem(elem) {
+ return RequestsService.createHistoryRequestFromElement(elem);
+ }
+
+ /**
+ *
+ * @param {string} colName
+ * @returns {boolean}
+ */
+ function collectionExists(colName) {
+ return self.collections.some(function (col){
+ return col.name === colName;
+ });
+ }
+
+ /**
+ *
+ * @returns {Array}
+ */
+ function getCollectionNames(){
+ return self.collections.map(function (elem){
+ return elem.name;
+ });
+ }
+
+ /**
+ *
+ * @param colName
+ * @returns {T}
+ */
+ function getCollection(colName){
+ return self.collections.filter(function (col){
+ return col.name === colName;
+ })[0];
+ }
+
+
+ /**
+ *
+ * @param reqObj
+ */
+ function addItemToList(reqObj){
+ self.list.push(reqObj);
+ if (reqObj.collection) {
+ var col = null;
+ if (self.collectionExists(reqObj.collection)) {
+ col = self.getCollection(reqObj.collection);
+ }
+ else {
+ col = new CollectionModel(reqObj.collection);
+ self.collections.push(col);
+ }
+ col.data.push(reqObj);
+ }
+ }
+
+
+ /**
+ *
+ * @param elem
+ */
+ function deleteRequestItem(elem){
+ var col = self.getCollection(elem.collection);
+ col.data.splice(col.data.indexOf(elem), 1);
+ if (col.data.length === 0){
+ self.collections.splice(self.collections.indexOf(col), 1);
+ }
+
+ }
+
+ function clear() {
+ self.collections = [];
+ self.selectedItems = [];
+ self.list = [];
+ }
+
+ /**
+ *
+ * @param collectionName
+ * @returns {*}
+ */
+ function toJSON(collectionName) {
+ if (collectionName){
+ return self.getCollection(collectionName).data.map(function (elem){
+ return elem.toJSON();
+ });
+ }
+ else {
+ var list = [];
+ self.collections.forEach(function (collection){
+ collection.data.forEach(function (elem){
+ list.push(elem.toJSON());
+ });
+ });
+ return list;
+ }
+ }
+
+ /**
+ *
+ * @param data
+ */
+ function loadListFromFile(data){
+ if (data){
+ ParsingJsonService.parseJson(data).map(function (elem) {
+ return RequestsService.createHistoryRequest(elem.sentData, elem.receivedData, elem.path,
+ elem.method, elem.status, elem.name, elem.collection);
+ }).forEach(function (elem) {
+ self.addItemToList(elem);
+ });
+ }
+ }
+
+ /**
+ * Get expanded collection names
+ */
+ function getExpandedCollectionNames(){
+ return self.collections.filter(function(collection){
+ return collection.expanded;
+ }).map(function(collection){
+ return collection.name;
+ });
+ }
+
+ /**
+ * Expand collections by expandCollectionNames
+ */
+ function expandCollectionByNames(expandCollectionNames){
+ self.collections.forEach(function(collection){
+ if (findName(collection.name)) {
+ collection.expanded = true;
+ }
+ });
+
+ function findName(name) {
+ return expandCollectionNames.some(function(collectionName){
+ return name === collectionName;
+ });
+ }
+ }
+
+ }
+ CollectionListModel.prototype = Object.create(BaseListModel.prototype);
+
+ return CollectionListModel;
+ }
+);
--- /dev/null
+define([], function (){
+ 'use strict';
+
+ /**
+ * Base history request object
+ * @constructor
+ * @param PathUtilsService
+ * @param YangUtilsService
+ * @param ParsingJsonService
+ */
+ function HistoryRequestModel(PathUtilsService, YangUtilsService, ParsingJsonService){
+ var self = this;
+
+ // properties
+ self.collection = '';
+ self.method = '';
+ self.name = '';
+ self.path = '';
+ self.receivedData = null;
+ self.selected = false;
+ self.sentData = null;
+ self.status = '';
+ self.timestamp = '';
+ self.responseStatus = '';
+ self.responseStatusText = '';
+ self.responseTime = '';
+
+ // functions
+ self.clone = clone;
+ self.toJSON = toJSON;
+ self.getLastPathDataElemName = getLastPathDataElemName;
+ self.setDataForView = setDataForView;
+ self.setData = setData;
+ self.setExecutionData = setExecutionData;
+
+ /**
+ * Grouped setter
+ *
+ * @param sentData
+ * @param receivedData
+ * @param status
+ * @param path
+ * @param operation
+ * @param name
+ * @param collection
+ * @param timestamp
+ * @param responseStatus
+ * @param responseTime
+ * @param responseStatusText
+ */
+ function setData(sentData, receivedData, status, path, operation, name, collection, timestamp, responseStatus, responseStatusText, responseTime) {
+
+ self.sentData = sentData === null || sentData === undefined || $.isEmptyObject(sentData) ? null : sentData;
+ self.name = name;
+ self.path = path;
+ self.method = operation;
+ self.status = status;
+ self.receivedData = receivedData === null || receivedData === undefined || $.isEmptyObject(receivedData) ?
+ null : receivedData;
+ self.collection = collection;
+ self.timestamp = timestamp;
+ self.responseStatus = responseStatus;
+ self.responseStatusText = responseStatusText;
+ self.responseTime = responseTime;
+ }
+
+ /**
+ * Set data which might be available after executing request
+ * @param sentData
+ * @param receivedData
+ * @param status - http status from response header
+ * @param responseStatus
+ * @param responseTime
+ * @param responseStatusText
+ */
+ function setExecutionData(sentData, receivedData, status, responseStatus, responseStatusText, responseTime) {
+ self.sentData = sentData;
+ self.receivedData = receivedData;
+ self.status = status ? (status > 199 && status < 205 ? 'success' : 'erorr') : '';
+ self.responseStatus = responseStatus;
+ self.responseStatusText = responseStatusText;
+ self.responseTime = responseTime;
+ }
+
+
+ /**
+ *
+ * @returns {{sentData: (null|*), receivedData: (null|*), path: (string|*), collection: (string|*),
+ * method: (string|*), status: (string|*), name: (string|*), timestamp: (string|*), responseStatus: (string|*),
+ * responseTime: (string|*)}}
+ */
+ function toJSON() {
+ var obj = {
+ sentData: self.sentData,
+ receivedData: self.receivedData,
+ path: self.path,
+ collection: self.collection,
+ method: self.method,
+ status: self.status,
+ name: self.name,
+ timestamp: self.timestamp,
+ responseStatus: self.responseStatus,
+ responseStatusText: self.responseStatusText,
+ responseTime: self.responseTime,
+ };
+
+ return obj;
+ }
+
+
+
+ /**
+ *
+ * @returns {*}
+ */
+ function getLastPathDataElemName() {
+ var pathArray = self.path.split(':');
+ return pathArray[pathArray.length - 1];
+ }
+
+ /**
+ *
+ * @param data
+ * @returns {string}
+ */
+ function setDataForView(data){
+ var result = '';
+
+ if (data instanceof Object) {
+ result = JSON.stringify(
+ YangUtilsService.stripAngularGarbage(
+ angular.copy(data),
+ self.getLastPathDataElemName()
+ ),
+ null,
+ 4
+ );
+ }
+ else {
+ result = data;
+ }
+
+ return result;
+
+ }
+
+
+ /**
+ *
+ * @returns {HistoryRequest}
+ */
+ function clone() {
+ /**
+ *
+ * @type {HistoryRequestModel}
+ */
+ var result = new HistoryRequestModel(PathUtilsService, YangUtilsService, ParsingJsonService);
+ result.setData(self.sentData, self.receivedData, self.status, self.path, self.method, self.name,
+ self.collection, self.timestamp, self.responseStatus, self.responseStatusText, self.responseTime);
+ return result;
+ }
+
+ }
+
+ return HistoryRequestModel;
+});
--- /dev/null
+define(['app/yangman/models/baselist.model'], function (BaseListModel){
+ 'use strict';
+
+ /**
+ * Base history list object
+
+ * @constructor
+ * @param ParsingJsonService
+ * @param RequestsService
+ */
+ function HistoryListModel($filter, ParsingJsonService, RequestsService){
+
+ BaseListModel.call(this, $filter, ParsingJsonService);
+
+ /* jshint validthis: true */
+ var self = this;
+
+
+ /**
+ * Array of groups in which are requests from self.list groupped
+ * @type {Array}
+ */
+ self.dateGroups = [];
+
+ self.addItemToList = addItemToList;
+ self.clear = clear;
+ self.createItem = createItem;
+ self.deleteRequestItem = deleteRequestItem;
+ self.deselectReqs = deselectReqs;
+ self.selectReqs = selectReqs;
+ self.toggleReqSelection = toggleReqSelection;
+ self.getNewestRequest = getNewestRequest;
+
+
+ /**
+ * Get request with max timestamp (was executed as the last)
+ */
+ function getNewestRequest() {
+ return $filter('orderBy')(self.list, '-timestamp')[0];
+ }
+
+ /**
+ * Mark reqObj as selected
+ * @param {boolean} onlyOneSelected boolean if only this object should be marked as selected
+ * @param reqObj HistoryRequest object to be selected
+ */
+ function toggleReqSelection(onlyOneSelected, reqObj){
+ if (onlyOneSelected){
+ self.selectedItems.forEach(function (req){
+ req.selected = false;
+ });
+ self.selectedItems = [];
+ }
+
+ if (reqObj.selected && !onlyOneSelected){
+ self.selectedItems.splice(self.selectedItems.indexOf(reqObj), 1);
+ }
+
+ reqObj.selected = (reqObj.selected && onlyOneSelected) || !reqObj.selected;
+ if (reqObj.selected){
+ self.selectedItems.push(reqObj);
+ }
+
+ }
+
+ /**
+ * Round timestamp to day
+ * @param timeStamp
+ * @returns {number|*}
+ */
+ function roundTimestampToDate(timeStamp){
+ timeStamp -= timeStamp % (24 * 60 * 60 * 1000);//subtract amount of time since midnight
+ timeStamp += new Date().getTimezoneOffset() * 60 * 1000;//add on the timezone offset
+ return timeStamp;
+ }
+
+ /**
+ * Add element to date group
+ * @param elem
+ */
+ function addElemToListDateGroup(elem){
+ if (elem.timestamp){
+ var groupName = roundTimestampToDate(elem.timestamp),
+ dateGroupArr = self.dateGroups.filter(function (group){
+ return group.name === groupName;
+ }),
+ dateGroup = null;
+
+ if (dateGroupArr.length){
+ dateGroup = dateGroupArr[0];
+ }
+ else {
+ dateGroup = {
+ name: groupName,
+ longName: new Date(groupName).toDateString(),
+ requests: [],
+ };
+ self.dateGroups.push(dateGroup);
+ }
+ dateGroup.requests.push(elem);
+ }
+ }
+
+
+ /**
+ *
+ * @param elem
+ * @returns {HistoryRequest|*}
+ */
+ function createItem(elem) {
+ return RequestsService.createHistoryRequestFromElement(elem);
+ }
+
+ /**
+ *
+ * @param reqObj
+ */
+ function addItemToList(reqObj){
+ self.list.push(reqObj);
+ addElemToListDateGroup(reqObj);
+ }
+
+ /**
+ *
+ * @param elem
+ */
+ function deleteRequestItem(elem){
+ self.list.splice(self.list.indexOf(elem), 1);
+ }
+
+ function clear() {
+ self.list = [];
+ self.dateGroups = [];
+ self.selectedItems = [];
+ }
+
+ /**
+ *
+ * @returns {Array}
+ */
+ self.toJSON = function () {
+ return self.list.map(function (elem) {
+ return elem.toJSON();
+ });
+ };
+
+ /**
+ * Mark all history requests as deselected
+ */
+ function deselectReqs(){
+ self.selectedItems.forEach(function (request){
+ request.selected = false;
+ });
+ self.selectedItems = [];
+ }
+
+ /**
+ * Mark all history requests as selected
+ */
+ function selectReqs(requestsList){
+ requestsList.forEach(function (reqObj){
+ reqObj.selected = true;
+ self.selectedItems.push(reqObj);
+ });
+ }
+ }
+
+ HistoryListModel.prototype = Object.create(BaseListModel.prototype);
+
+ return HistoryListModel;
+
+});
--- /dev/null
+define([], function (){
+ 'use strict';
+
+ /**
+ * Base parameter object
+ * @constructor
+ */
+ function ParameterModel(){
+ var self = this;
+
+ // properties
+ self.name = '';
+ self.value = '';
+
+ // attributes with underscore prefix are used for filtering in params admin
+ self._name = '';
+ self._value = '';
+
+ // functions
+ self.toJSON = toJSON;
+ self.setData = setData;
+ self.clone = clone;
+ self.applyValsForFilters = applyValsForFilters;
+
+ /**
+ * Copy model name and value to _name and _value properties, which are used when sorting and filtering list
+ * of parameters
+ */
+ function applyValsForFilters() {
+ self._name = self.name;
+ self._value = self.value;
+ }
+
+ /**
+ * Grouped setter
+ *
+ * @param name
+ * @param value
+ */
+ function setData(name, value) {
+ self.name = name;
+ self.value = value;
+ self._name = name;
+ self._value = value;
+ }
+
+ /**
+ *
+ * @returns {{name: (string|*), value: (string|*)}}
+ */
+ function toJSON() {
+ var obj = {
+ name: self.name,
+ value: self.value,
+ };
+
+ return obj;
+ }
+
+ /**
+ *
+ * @returns {ParameterModel}
+ */
+ function clone() {
+ var result = new ParameterModel();
+ result.setData(self.name, self.val);
+ return result;
+ }
+
+
+ }
+
+ return ParameterModel;
+});
--- /dev/null
+define(['app/yangman/models/baselist.model'], function (BaseListModel){
+ 'use strict';
+
+ /**
+ * Base parameters list object
+ * @constructor
+ * @param ParsingJsonService
+ * @param ParametersService
+ */
+ function ParametersListModel($filter, ParsingJsonService, ParametersService){
+
+ BaseListModel.call(this, $filter, ParsingJsonService);
+
+ /* jshint validthis: true */
+ var self = this;
+ self.list = [];
+
+ self.addItemToList = addItemToList;
+ self.clear = clear;
+ self.createItem = createItem;
+ self.deleteParameterItem = deleteParameterItem;
+ self.setName = setName;
+ self.addEmptyItem = addEmptyItem;
+ self.toJSON = toJSON;
+ self.createParamsFromJson = createParamsFromJson;
+ self.isNameUnique = isNameUnique;
+ self.removeEmptyParams = removeEmptyParams;
+ self.applyValsForFilters = applyValsForFilters;
+
+ /**
+ * Apply all parameters names and values for filtering
+ */
+ function applyValsForFilters() {
+ self.list.forEach(function (param) {
+ param.applyValsForFilters();
+ });
+ }
+
+ /**
+ * Returns false if name is already used
+ * @param nameValue
+ * @returns {boolean}
+ */
+ function isNameUnique(nameValue) {
+ return !nameValue || self.list.filter(function (item) {
+ return item.name === nameValue;
+ }).length === 1;
+ }
+
+ /**
+ * Using when importing data from json file
+ * @param data
+ */
+ function createParamsFromJson(data){
+ if (data){
+ self.clear();
+ ParsingJsonService.parseJson(data).map(function (elem) {
+ return ParametersService.createParameter(elem);
+ }).forEach(function (elem) {
+ self.addItemToList(elem);
+ });
+ }
+ }
+
+ /**
+ * Get all parameters in json for exporting
+ * @returns {Array}
+ */
+ function toJSON() {
+ return self.list.map(function (param){
+ return param.toJSON();
+ });
+ }
+
+ /**
+ * Set list name
+ * @param name
+ */
+ function setName(name) {
+ self.name = name;
+ }
+
+ /**
+ * Add empty param to list
+ */
+ function addEmptyItem() {
+ self.addItemToList(self.createItem());
+ }
+
+ function removeEmptyParams() {
+ self.list = self.list.filter(function (param) {
+ return param.name && param.name.length > 0;
+ });
+ }
+
+ /**
+ *
+ * @param elem
+ * @returns {Parameter|*}
+ */
+ function createItem(element) {
+ if (!element){
+ element = {
+ name: '',
+ value: '',
+ };
+ }
+ return ParametersService.createParameter(element);
+ }
+
+ /**
+ *
+ * @param paramObj
+ */
+ function addItemToList(paramObj){
+ self.list.push(paramObj);
+ }
+
+ /**
+ *
+ * @param paramObj
+ */
+ function deleteParameterItem(paramObj){
+ self.list.splice(self.list.indexOf(paramObj), 1);
+ }
+
+ function clear() {
+ self.list = [];
+ }
+
+ /**
+ *
+ * @returns {Array}
+ */
+ self.toJSON = function () {
+ return self.list.filter(notEmptyParam).map(function (elem) {
+ return elem.toJSON();
+ });
+
+ function notEmptyParam(item){
+ return item.name;
+ }
+ };
+ }
+
+ ParametersListModel.prototype = Object.create(BaseListModel.prototype);
+
+ return ParametersListModel;
+
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').service('YMHandleFileService', YMHandleFileService);
+
+ YMHandleFileService.$inject = ['$window'];
+
+ function YMHandleFileService($window){
+ var service = {
+ downloadFile: downloadFile,
+ };
+
+ return service;
+
+ /**
+ * Service for preparing file and creating link for downloading
+ * @param filename
+ * @param data
+ * @param format
+ * @param charset
+ * @param successCbk
+ * @param errorCbk
+ */
+ function downloadFile(filename, data, format, charset, successCbk, errorCbk){
+ try {
+ var blob = new Blob([JSON.stringify(data, null, 4)], { type: 'application/' + format + '; ' + charset + ';' }),
+ downloadLink = angular.element('<a></a>');
+
+ var clickEvent = new MouseEvent('click', {
+ 'view': window,
+ 'bubbles': true,
+ 'cancelable': false
+ });
+
+ downloadLink.attr('href', window.URL.createObjectURL(blob));
+ if(downloadLink.attr('download', filename) !== undefined) {
+ downloadLink[0].dispatchEvent(clickEvent);
+ successCbk();
+ }
+ else {
+ $window.location.href = downloadLink[0].href;
+ }
+ } catch (e) {
+ errorCbk(e);
+ }
+ }
+ }
+});
--- /dev/null
+define([
+ 'common/yangutils/constants',
+], function (constants) {
+ 'use strict';
+
+ angular.module('app.yangman').service('MountPointsConnectorService', MountPointsConnectorService);
+
+ MountPointsConnectorService.$inject = [
+ 'YangUiApisService', 'NodeWrapperService',
+ 'YangUtilsService', 'EventDispatcherService',
+ 'YinParserService', 'PathUtilsService', 'YangUtilsRestangularService',
+ ];
+
+ function MountPointsConnectorService(
+ YangUiApisService, NodeWrapperService,
+ YangUtilsService, EventDispatcherService,
+ YinParserService, PathUtilsService, YangUtilsRestangularService){
+
+ var mountPrefix = constants.MPPREFIX,
+ service = {
+ addPathElemsToPathArray: addPathElemsToPathArray,
+ alterMpPath: alterMpPath,
+ createCustomButton: createCustomButton,
+ createMPRootNode: createMPRootNode,
+ discoverMountPoints: discoverMountPoints,
+ getMPModulesAPI: getMPModulesAPI,
+ updateMountPointApis: updateMountPointApis,
+ };
+
+ return service;
+
+ // TODO: add service's description
+ function createMPRootNode(mpNodes) {
+ var node = null,
+ yangParser = YinParserService.yangParser;
+
+ yangParser.setCurrentModuleObj(new YinParserService.Module('yang-ext', null, null));
+ node = yangParser.createNewNode('mount', 'container', null, constants.NODE_UI_DISPLAY);
+ NodeWrapperService.wrapAll(node);
+
+ node.buildRequest = function (builder, req, module) {
+ var added = false,
+ builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
+
+ if (builderNodes.length) {
+ builderNodes.forEach(function (child) {
+ var childAdded = child.buildRequest(builder, req, module);
+ });
+ }
+
+ return added;
+ };
+
+ node.fill = function (name, data) {
+ var nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
+
+ nodesToFill.forEach(function (child) {
+ var childFilled = child.fill(name, data);
+ });
+ };
+
+
+ mpNodes.forEach(function (mp){
+ node.addChild(mp);
+ });
+
+ return node;
+ }
+
+ // TODO: add service's description
+ function addPathElemsToPathArray(pathElems, pathArray, index) {
+ var updatedPath = pathArray.slice();
+
+ pathElems.forEach(function (pe, offset) {
+ // pe.disabled = true; //add disabled flag so user won't be able to change it in the UI
+ updatedPath.splice(index + offset, 0, pe);
+ });
+
+ return updatedPath;
+ }
+
+ // TODO: add service's description
+ function alterMpPath(path) {
+ var pathParts = path.split('/'),
+ restconfIndex = PathUtilsService.findIndexOfStrInPathStr(pathParts, 'restconf'),
+ mpIndex = PathUtilsService.findIndexOfStrInPathStr(pathParts, mountPrefix),
+ mpPath = path.slice(),
+ mpPathParts = '';
+
+ if (mpIndex !== -1){
+ mpPathParts = pathParts.slice(mpIndex);
+
+ var unshiftIndex = restconfIndex !== -1 ? restconfIndex + 1 : 0;
+
+ mpPathParts.unshift(pathParts[unshiftIndex]);
+ mpPath = mpPathParts.join('/');
+ }
+
+ return mpPath;
+ }
+
+ /**
+ * function for adding path to mountpoint + yang:ext-mount to mount point patharray so the request string
+ * will be built correctly
+ * @param basePathArray
+ * @param mpApis
+ */
+ function updateMountPointApis(basePathArray, mpApis) {
+ var actualPath = basePathArray.slice(1); // we don't want to have config/operational storage in path
+ // actualPath.push(PathUtilsService.createPathElement(mountPrefix, null, null, false));
+ // we want to push yang-ext:mount to the path - not if we have yang-ext:mount rootNode
+
+ mpApis.forEach(function (api) {
+ api.subApis.forEach(function (subApi) {
+ subApi.pathArray = addPathElemsToPathArray(actualPath, subApi.pathArray, 1);
+ });
+ });
+ }
+
+ // TODO: add service's description
+ function getMPModulesAPI(api) {
+ var apiArray = api.split('/'),
+ yangExtMountStr = mountPrefix;
+
+ if (apiArray[apiArray.length - 1] !== yangExtMountStr) {
+ apiArray.push(yangExtMountStr);
+ }
+
+ return apiArray.slice(1).join('/');
+ }
+
+ // TODO: add service's description
+ function discoverMountPoints(api, getModulesCbk, callback) {
+ var modulesCbk = getModulesCbk || angular.noop,
+ mpNodes = [],
+ baseApiPath = getMPModulesAPI(api),
+ time = {
+ started: 0,
+ finished: 0,
+ };
+
+ YangUtilsRestangularService.setFullResponse(true);
+
+ time.started = new Date().getMilliseconds();
+
+ return YangUiApisService.getCustomModules(baseApiPath).then(
+ function (response) {
+ time.finished = new Date().getMilliseconds();
+
+ var reqObj = {
+ status: response.status,
+ statusText: response.statusText,
+ time: (time.finished - time.started),
+ };
+
+ YangUtilsService.processModulesMP(response.data.modules, baseApiPath, function (result, augments) {
+ EventDispatcherService.dispatch(constants.EV_SRC_MAIN, 'Linking modules to Apis');
+ var allRootNodes = result.map(function (node) {
+ var copy = node.deepCopy(['augmentionGroups', 'augmentationId']);
+
+ NodeWrapperService.wrapAll(copy);
+ return copy;
+ });
+
+ var moduleNames = response.data.modules.module.map(function (m) {
+ return m.name;
+ });
+
+ allRootNodes.forEach(function (n) {
+ if (moduleNames.indexOf(n.module) > -1 && ['container', 'list'].indexOf(n.type) > -1) {
+ mpNodes.push(n);
+ }
+ });
+
+ callback(mpNodes, augments, reqObj);
+ YangUtilsRestangularService.setFullResponse(false);
+ });
+ },
+ function (response) {
+ time.finished = new Date().getMilliseconds();
+
+ var reqObj = {
+ status: response.status,
+ statusText: response.statusText,
+ time: (time.finished - time.started),
+ };
+
+ callback([], [], reqObj);
+ YangUtilsRestangularService.setFullResponse(false);
+ });
+ }
+
+ // TODO: add service's description
+ function createCustomButton(label, show, click){
+ return {
+ label: label,
+ show: show,
+ onclick: click,
+ };
+ }
+ }
+
+});
--- /dev/null
+define([
+ 'app/yangman/models/parameter.model',
+ 'app/yangman/models/parameterslist.model',
+],
+ function (ParameterModel, ParametersListModel) {
+ 'use strict';
+
+ angular.module('app.yangman').service('ParametersService', ParametersService);
+
+ ParametersService.$inject = ['$filter', 'ParsingJsonService'];
+
+ function ParametersService($filter, ParsingJsonService){
+
+ var service = {};
+
+ service.createEmptyParametersList = createEmptyParametersList;
+ service.createParameter = createParameter;
+ service.validateFile = validateFile;
+
+ /**
+ * Validating collection import file
+ * @param data
+ * @param checkArray
+ * @returns {*}
+ */
+ function validateFile(data, checkArray){
+ try {
+ var obj = ParsingJsonService.parseJson(data);
+
+ return obj && obj.every(function (el){
+ return checkArray.every(function (arr){
+ return el.hasOwnProperty(arr);
+ });
+ });
+ } catch (e) {
+ return e;
+ }
+ }
+
+ /**
+ * Service for creating basic parameter object
+ * @returns {*}
+ * @param name
+ * @param value
+ */
+ function createParameter(element){
+ var result = new ParameterModel();
+ result.setData(element.name, element.value);
+ return result;
+ }
+
+
+ /**
+ * Service for creating empty parameters list
+ * @param name used as name in local storage
+ * @returns {*}
+ */
+ function createEmptyParametersList(name){
+ var result = new ParametersListModel($filter, ParsingJsonService, service);
+ result.setName(name);
+ return result;
+ }
+
+
+ return service;
+
+ }
+
+ });
--- /dev/null
+var yangmanPluginsFactories = [
+ 'ymDisplayMountPoints',
+];
+
+var yangmanPluginContollers = [
+];
+
+define([
+ 'common/yangutils/services/custom-funct.services',
+].concat(yangmanPluginsFactories.map(function (plugin) {
+ 'use strict';
+ return 'app/yangman/services/plugins/' + plugin + '.services';
+})).concat(yangmanPluginContollers.map(function (ctrl) {
+ 'use strict';
+ return 'app/yangman/plugins/cv/' + ctrl + '.controller';
+})), function () {
+ 'use strict';
+
+ angular.module('app.yangman').service('PluginsHandlerService', PluginsHandlerService);
+
+ function PluginsHandlerService($injector, CustomFuncService) {
+
+ var service = {
+ addPlugins: addPlugins,
+ plugAll: plugAll,
+ plugins: [],
+ };
+
+ service.addPlugins();
+
+ return service;
+
+ // TODO: add service's description
+ function addPlugins() {
+ yangmanPluginsFactories.forEach(function (pluginFactFullName) {
+ var pluginServiceName = pluginFactFullName.split('/'),
+ pluginName = pluginServiceName[pluginServiceName.length - 1].split('.')[0];
+
+ $injector.invoke([pluginName, function (pluginFact) {
+ service.plugins.push(pluginFact);
+ }]);
+ });
+
+ }
+
+ /**
+ * Method for importing additional plugins
+ * @param apis
+ */
+ function plugAll(apis) {
+ service.plugins.forEach(function (plugin) {
+ plugin.module.forEach(function (plModule, i){
+ CustomFuncService.createCustomFunctionalityApis(apis, plModule, plugin.revision,
+ plugin.pathString[i], plugin.label,
+ plugin.getCallback, plugin.view,
+ plugin.hideButtonOnSelect);
+ });
+ });
+ }
+ }
+});
--- /dev/null
+define(['angular'], function (angular) {
+ 'use strict';
+
+ angular.module('app.yangman').service('PluginsUnsetterService',
+ ['PathUtilsService', 'DataBackupService', PluginsUnsetterService]);
+
+ PluginsUnsetterService.$inject = ['constants'];
+
+ function PluginsUnsetterService(PathUtilsService, DataBackupService, constants){
+ var service = {
+ 'YANGMAN_CUST_MOUNT_POINTS': unsetMountPoint,
+ unset: unset,
+ };
+
+ return service;
+
+ /**
+ * Method for unset mount point from application
+ * @param scope
+ */
+ function unsetMountPoint(scope){
+ var modulesListObj = {};
+
+ DataBackupService.getToScope(
+ [
+ 'selectedDatastore', 'node', 'apis',
+ 'selectedApi', 'selectedSubApi', 'augmentations', 'selectedModule',
+ ],
+ scope,
+ 'MAIN_SCOPE'
+ );
+
+ DataBackupService.getToScope(['treeApis'], modulesListObj, 'MODULES_LIST');
+ scope.$broadcast(constants.YANGMAN_SET_API_TREE_DATA, { params: modulesListObj.treeApis });
+ scope.$broadcast(constants.YANGMAN_SET_MODULE_LIST_TITLE, { params: '' });
+
+ if ( scope.selectedDatastore ){
+ scope.$broadcast(constants.YANGMAN_MODULE_D_INIT);
+ }
+ }
+
+ /**
+ * General method for pick correct unset method for plugins
+ * @param scope
+ * @param controller
+ */
+ function unset(scope, controller) {
+ if (service.hasOwnProperty(controller.selectedPlugin.label)) {
+ service[controller.selectedPlugin.label](scope);
+ }
+ }
+
+ }
+
+});
--- /dev/null
+define([
+ 'app/yangman/services/mount-points-connector.services',
+], function (yangman) {
+ 'use strict';
+
+ angular.module('app.yangman').service('ymDisplayMountPoints', DisplayMountPoints);
+
+ DisplayMountPoints.$inject =
+ ['MountPointsConnectorService', '$timeout', 'YangUtilsService', '$filter', 'ApiBuilderService', 'constants'];
+
+ function DisplayMountPoints(
+ MountPointsConnectorService, $timeout, YangUtilsService, $filter, ApiBuilderService, constants) {
+ var loadId = 0;
+
+ return {
+ module: ['network-topology', 'opendaylight-inventory', 'network-topology', 'opendaylight-inventory'],
+ revision: null,
+ pathString: [
+ 'operational/network-topology:network-topology/topology/{topology-id}/node/{node-id}/',
+ 'operational/opendaylight-inventory:nodes/node/{id}/',
+ ],
+ label: 'YANGMAN_CUST_MOUNT_POINTS',
+ hideButtonOnSelect: true,
+ getCallback: displayMountPointsCallback,
+ };
+
+ function displayMountPointsCallback(args) {
+ var controller = args.controller,
+ scope = args.scope,
+ path = scope.selectedSubApi.buildApiRequestString();
+
+ scope.rootBroadcast(constants.YANGMAN_SET_LOADING_BOX, true, function () {
+ scope.setLeftPanel(0);
+ $timeout(function () {
+ MountPointsConnectorService.discoverMountPoints(path, getNodesMPData, createMPStructure);
+ }, 1000);
+ });
+
+ /**
+ * Get Mount point data from received raw data
+ * @param data
+ * @returns {*}
+ */
+ function getNodesMPData(data) {
+ var node = data.node[0];
+ return node && node['netconf-node-inventory:initial-capability'] ?
+ node['netconf-node-inventory:initial-capability'].map(function (c) {
+ return c.slice(c.lastIndexOf(')') + 1);
+ }) : [];
+ }
+
+ // TODO :: description
+ function findFirstSubApiIndex(subApis) {
+ var firstConfigSubApiIndex = 0;
+
+ subApis.some(function (sa, index) {
+ var condition = sa.storage === constants.DATA_STORE_CONFIG;
+ if (condition) {
+ firstConfigSubApiIndex = index;
+ }
+ return condition;
+ });
+
+ return firstConfigSubApiIndex;
+ }
+
+ /**
+ * Create base params for setup mount points in app
+ * @param mpNodes
+ * @param mpAugments
+ * @param reqObj
+ */
+ function createMPStructure(mpNodes, mpAugments, reqObj) {
+ if (mpNodes.length){
+ var mpRootNode = MountPointsConnectorService.createMPRootNode(mpNodes),
+ mountPointApis = ApiBuilderService.processAllRootNodes([mpRootNode]),
+ // root node has isConfigStm undefined, we need to create root config SubApi by hand
+ // if we set the variable isConfigStm to true and then generate the subApis it will do it
+ // incorrectly because, the variable is inherited to children and we would malform the data
+ // we need just to get operational root subApi...
+ rootApi = mountPointApis[0],
+ rootOperSubApi = rootApi.subApis.filter(function (sa) {
+ return sa.pathTemplateString === 'yang-ext:mount/' && sa.storage === constants.DATA_STORE_OPERATIONAL;
+ })[0];
+
+ if (rootOperSubApi) {
+ var rootConfigSubApi = rootOperSubApi.clone(), // clone it and...
+ firstConfigSubApiIndex = findFirstSubApiIndex(rootApi.subApis);
+ // we need to find first index of config
+ // subApi - because generating treeApis depends on order
+
+ // set storage to config
+ rootConfigSubApi.storage = constants.DATA_STORE_CONFIG;
+ rootConfigSubApi.pathArray[0].name = constants.DATA_STORE_CONFIG;
+
+ // and add it to rest of the apis
+ rootApi.subApis.splice(firstConfigSubApiIndex, 0, rootConfigSubApi);
+ rootConfigSubApi.parent = rootApi;
+ }
+
+ var mountPointTreeApis = YangUtilsService.generateApiTreeData(mountPointApis),
+ pathItems = path.split('/');
+
+ MountPointsConnectorService.updateMountPointApis(scope.selectedSubApi.pathArray, mountPointApis);
+
+ // call initialization after necessary things are loaded
+ controller.initMountPoint(mountPointTreeApis, mountPointApis, mpAugments, reqObj);
+
+ scope.rootBroadcast(
+ constants.YANGMAN_SET_MODULE_LIST_TITLE,
+ pathItems[pathItems.length - 1] + ' [ ' + $filter('translate')(constants.YANGMAN_MOUNT_POINT) + ' ]'
+ );
+
+ controller.selectedPluginsButtons.push(
+ MountPointsConnectorService.createCustomButton(constants.YANGMAN_CANCEL_MP, function (){
+ return controller.selectedPlugin.label === constants.YANGMAN_CUST_MOUNT_POINTS;
+ },
+ function (){
+ controller.unsetPluginFunctionality();
+ })
+ );
+
+ } else {
+ $timeout(function (){
+ controller.selectedPlugin = null;
+ scope.rootBroadcast(constants.YANGMAN_SET_LOADING_BOX, false);
+ scope.rootBroadcast(constants.YANGMAN_SHOW_TOAST, constants.YANGMAN_NO_MOUNT_POINT);
+ }, 100);
+ }
+ }
+
+ }
+ }
+});
--- /dev/null
+define([
+ 'app/yangman/models/historylist.model',
+ 'app/yangman/models/collectionlist.model',
+ 'app/yangman/models/history-request.model',
+], function (HistoryListModel, CollectionListModel, HistoryRequestModel) {
+ 'use strict';
+
+ angular.module('app.yangman').service('RequestsService', RequestsService);
+
+ RequestsService.$inject = [
+ '$filter', 'PathUtilsService', 'ParametersService', 'ParsingJsonService', 'YangUtilsService',
+ 'RequestBuilderService', 'constants',
+ ];
+
+ function RequestsService($filter, PathUtilsService, ParametersService, ParsingJsonService, YangUtilsService,
+ RequestBuilderService, constants) {
+
+ var service = {};
+
+ service.applyParamsToObj = applyParamsToObj;
+ service.applyParamsToStr = applyParamsToStr;
+ service.clearUnnecessaryProperties = clearUnnecessaryProperties;
+ service.createEmptyCollectionList = createEmptyCollectionList;
+ service.createEmptyHistoryList = createEmptyHistoryList;
+ service.createHistoryRequestFromElement = createHistoryRequestFromElement;
+ service.createHistoryRequest = createHistoryRequest;
+ service.fillRequestByMethod = fillRequestByMethod;
+ service.fillRequestByViewType = fillRequestByViewType;
+ service.findIdentifierByParam = findIdentifierByParam;
+ service.scanDataParams = scanDataParams;
+ service.replaceStringInText = replaceStringInText;
+
+ /**
+ * Clear unnecesary properties for saving to collection
+ * @param request
+ */
+ function clearUnnecessaryProperties(request){
+ request.status = '';
+ request.responseStatus = null;
+ request.responseStatusText = null;
+ request.responseTime = null;
+
+ return request;
+ }
+
+ /**
+ * Find parametrized identifier in path array
+ * @param params
+ * @param pathElement
+ * @returns {*}
+ */
+ function findIdentifierByParam(params, pathElement){
+ var foundIdentifier = null;
+
+ if ( pathElement.hasIdentifier() ){
+ pathElement.identifiers.some(function (item){
+ return params.list.some(function (param){
+ var contained = item.value.indexOf('<<' + param.name + '>>') > -1;
+
+ if ( contained ){
+ foundIdentifier = item;
+ }
+
+ return contained;
+ });
+ });
+ }
+
+ return foundIdentifier;
+ }
+
+ /**
+ * Get data for saving request depend on view type
+ * @param node
+ * @param viewType
+ * @param requestData
+ * @param dataType
+ * @param method
+ * @returns {*}
+ */
+ function fillRequestByViewType(node, viewType, requestData, dataType, method){
+ var setDataByViewType = {
+ form: function () {
+ var data = {},
+ emptyObject = method === constants.OPERATION_POST && dataType.toUpperCase() === constants.REQUEST_DATA_TYPE_RECEIVED && node.type !== constants.NODE_RPC;
+
+ if ( !emptyObject ) {
+ node.buildRequest(RequestBuilderService, data, node.module);
+ data = checkNodeTypeData(node, data, dataType, requestData);
+ }
+
+ return data;
+ },
+ 'req-data': function (){
+ return requestData ? angular.fromJson(requestData) : {};
+ },
+ };
+
+ return setDataByViewType[viewType]();
+
+ /**
+ * Exceptions based on node type
+ * @param node
+ * @param data
+ * @param dataType
+ * @param requestData
+ * @returns {*}
+ */
+ function checkNodeTypeData(node, data, dataType, requestData){
+ var copyData = angular.copy(data),
+ setDataByNodeType = {
+ rpc: function (){
+
+ if ( dataType.toUpperCase() === constants.REQUEST_DATA_TYPE_RECEIVED ) {
+ copyData = requestData ? angular.fromJson(requestData) : {};
+ }
+
+ return copyData;
+ },
+ default: function () {
+ return data;
+ },
+ };
+
+ return (setDataByNodeType[node.type] || setDataByNodeType.default)();
+ }
+ }
+
+ /**
+ * Fill history request data depend on selected method - saving to collection
+ * @param requestObj
+ * @param sentData
+ * @param receivedData
+ * @param method
+ */
+ function fillRequestByMethod(requestObj, sentData, receivedData, method, node, viewType){
+ var setDataByMethod = {
+ GET: function (){
+ return {
+ sentData: {},
+ receivedData: receivedData.reqData ? angular.fromJson(receivedData.reqData) : {},
+ };
+ },
+ POST: function (){
+ return {
+ sentData: fillRequestByViewType(node, viewType, sentData.reqData, 'sent', method),
+ receivedData: fillRequestByViewType(
+ node, viewType, receivedData.reqData, constants.REQUEST_DATA_TYPE_RECEIVED, method
+ ),
+ };
+ },
+ PUT: function (){
+ return {
+ sentData: fillRequestByViewType(node, viewType, sentData.reqData, 'sent', method),
+ receivedData: {},
+ };
+ },
+ DELETE: function (){
+ return {
+ sentData: {},
+ receivedData: {},
+ };
+ },
+ },
+ data = setDataByMethod[method]();
+
+ requestObj.setExecutionData(data.sentData, data.receivedData, '');
+ }
+
+ /**
+ * Scan used parameters in current line of codemirror
+ * @param {ParametersListModel} paramsObj - list of parameters to be searched for
+ * @param {string} lineString - line from current codemirror to be inspected
+ * @returns array of {ParameterModel}
+ */
+ function scanDataParams(paramsObj, lineString) {
+
+ var usedParamLabelArray = [];
+
+ var params = lineString ? lineString.match(/<<(?!<<)[a-zA-Z0-9]+>>/g) : null;
+
+ if ( params ) {
+ params
+ .filter(onlyUnique)
+ .forEach(function (param) {
+ usedParamLabelArray.push(removeUnwantedChars(param));
+ });
+ }
+
+ var returnedParamsList = paramsObj.list.filter( function (param){
+ var paramIndex = usedParamLabelArray.indexOf(param.name);
+
+ if ( paramIndex !== -1 ) {
+ return usedParamLabelArray.splice(paramIndex, 1);
+ }
+ else {
+ return false;
+ }
+ });
+
+ usedParamLabelArray.forEach(function (param){
+ returnedParamsList.push(ParametersService.createParameter({ name: param }));
+ });
+
+ return returnedParamsList;
+
+ /**
+ * remove chars greater then and less then from parameter definition
+ * @param val
+ * @returns {string}
+ */
+ function removeUnwantedChars(val){
+ var string = val.substring(2);
+ return string.substring(0, string.indexOf('>>'));
+ }
+
+ /**
+ * Filter function
+ * @param value
+ * @param index
+ * @param self
+ * @returns {boolean}
+ */
+ function onlyUnique(value, index, self) {
+ return self.indexOf(value) === index;
+ }
+ }
+
+ /**
+ * Replace all parameters with its values
+ * @param paramsObj
+ * @param str
+ * @returns {*}
+ */
+ function applyParamsToStr(paramsObj, str) {
+ if (paramsObj && paramsObj.hasOwnProperty('list')) {
+ paramsObj.list.forEach(function (param){
+ str = service.replaceStringInText(str, '<<' + param.name + '>>', param.value);
+ });
+ }
+
+ return str;
+ }
+
+ /**
+ * Replace all parameters with its values
+ * @param paramsObj
+ * @param requestData
+ * @returns {*}
+ */
+ function applyParamsToObj(paramsObj, data) {
+ var dataStr = JSON.stringify(data);
+
+ dataStr = service.applyParamsToStr(paramsObj, dataStr);
+
+ return ParsingJsonService.parseJson(dataStr);
+ }
+
+ /**
+ * Service for replacing string in text
+ * @param text
+ * @param strToReplace
+ * @param newStr
+ * @returns {*}
+ */
+ function replaceStringInText(text, strToReplace, newStr) {
+ var replacedText = text;
+ if (text.indexOf(strToReplace) > -1) {
+ replacedText = text.split(strToReplace).join(newStr);
+ }
+ return replacedText;
+ }
+
+ /**
+ * Service for creating basic history object
+ * @param sentData
+ * @param receivedData
+ * @param path
+ * @param operation
+ * @param status
+ * @param name
+ * @param collection
+ * @returns {*}
+ * @param timestamp
+ */
+ function createHistoryRequest(sentData, receivedData, path, operation, status, name, collection, timestamp,
+ responseStatus, responseStatusText, responseTime) {
+ var result = new HistoryRequestModel(PathUtilsService, YangUtilsService, ParsingJsonService);
+
+ timestamp = timestamp || Date.now();
+
+ result.setData(sentData, receivedData, status, path, operation, name, collection, timestamp,
+ responseStatus, responseStatusText, responseTime);
+
+ return result;
+ }
+
+ /**
+ * Creating {HistoryRequest} from elem containing all necessary data
+ * @param {Object} elem
+ * @returns {*}
+ */
+ function createHistoryRequestFromElement(elem) {
+ if (!elem.hasOwnProperty('timestamp') || elem.timestamp === ''){
+ elem.timestamp = Date.now();
+ }
+
+ return service.createHistoryRequest(elem.sentData, elem.receivedData, elem.path, elem.method,
+ elem.status, elem.name, elem.collection, elem.timestamp, elem.responseStatus,
+ elem.responseStatusText, elem.responseTime
+ );
+ }
+
+ /**
+ * Service for creating empty collection list
+ * @param name
+ * @param getApiFunction
+ * @returns {CollectionList}
+ */
+ function createEmptyCollectionList(name){
+ var result = new CollectionListModel($filter, ParsingJsonService, service);
+ result.setName(name);
+ return result;
+ }
+
+ /**
+ * Service for creating empty history list
+ * @param name
+ * @returns {*}
+ */
+ function createEmptyHistoryList(name){
+ var result = new HistoryListModel($filter, ParsingJsonService, service);
+ result.setName(name);
+ return result;
+ }
+
+ return service;
+
+ }
+
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').service('TimeTrackingService', TimeTrackingService);
+
+ function TimeTrackingService(){
+ var service = {
+ startTimer: startTimer,
+ returnTime: returnTime,
+ },
+ timeStarted = 0;
+ return service;
+
+ function startTimer(){
+ timeStarted = new Date().getTime();
+ }
+
+ function returnTime(){
+ return new Date().getTime() - timeStarted;
+ }
+ }
+
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').service('YangmanDesignService', YangmanDesignService);
+
+ YangmanDesignService.$inject = ['$timeout'];
+
+ function YangmanDesignService($timeout){
+
+ var service = {
+ disableMdMenuItem: disableMdMenuItem,
+ enableMdMenuItem: enableMdMenuItem,
+ hideMainMenu: hideMainMenu,
+ setDraggableLeftPanel: setDraggableLeftPanel,
+ setJsonSplitter: setJsonSplitter,
+ setModuleDetailHeight: setModuleDetailHeight,
+ };
+
+ return service;
+
+
+ /**
+ * Get button dom element from mdMenuItem ng-click $event
+ * @param event
+ */
+ function getButtElemFromMdMenuItemEvent(event) {
+ var elemSelAttempt = angular.element(event.toElement.parentElement).find('.md-button'),
+ result = null;
+
+ // if mdMenuItem was clicked, it should contain only one button
+ if (elemSelAttempt.length === 1) {
+ result = elemSelAttempt[0];
+ }
+ // if span or icon inside button was clicked, button element should be its parent
+ else if (elemSelAttempt.length === 0) {
+ result = angular.element(event.toElement.parentElement)[0];
+ }
+
+ if (result.nodeName === 'BUTTON') {
+ return result;
+ }
+ else {
+ return null;
+ }
+ }
+
+ /**
+ * Disable md menu item on which was clicked in event
+ * Use to prevent accidentally doubleclicking or enterhitting
+ * @param event - $event object from ng-click
+ */
+ function disableMdMenuItem(event) {
+ var buttElem = getButtElemFromMdMenuItemEvent(event);
+ if (buttElem) {
+ buttElem.disabled = true;
+ }
+ }
+
+
+ /**
+ * Disable md menu item on which was clicked in event
+ * Use to prevent accidentally doubleclicking or enterhitting
+ * @param event - $event object from ng-click
+ */
+ function enableMdMenuItem(event) {
+ var buttElem = getButtElemFromMdMenuItemEvent(event);
+ if (buttElem) {
+ buttElem.disabled = false;
+ }
+ }
+
+
+ /**
+ * Hide main menu
+ */
+ function hideMainMenu(){
+ angular.element('#wrapper').addClass('toggled');
+ }
+
+ /**
+ * Sets Draggable Left Side
+ * #left-panel
+ */
+ function setDraggableLeftPanel(){
+ if (localStorage.getItem('yangman__left-panel-width') !== null) {
+ angular.element('#left-panel').width(localStorage.getItem('yangman__left-panel-width'));
+ }
+
+ angular.element('.ym-resizable-e').resizable({
+ handles: 'e',
+ minWidth: 300,
+ stop: function(event, ui) {
+ if (typeof(Storage) !== 'undefined') {
+ localStorage.setItem('yangman__left-panel-width', ui.size.width);
+ }
+ },
+ resize: function() {
+ setModuleDetailHeight();
+ }
+ });
+ }
+
+ function setJsonSplitter(cbk){
+ $timeout(function () {
+ angular.element('.ym-resizable-s').resizable({
+ handles: 's',
+ minHeight: 200,
+ stop: function(event, ui) {
+ cbk();
+ }
+ });
+ });
+ }
+
+ /**
+ * Set module detail height
+ * .yangmanModule__module-detail .tabs
+ */
+ function setModuleDetailHeight() {
+ var height = 'calc(100% - ' + angular.element('.yangmanModule__module-detail h4').outerHeight(true) + 'px)';
+ angular.element('.yangmanModule__module-detail .tabs').css({ height: height });
+ }
+
+ }
+});
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').service('YangmanService', YangmanService);
+
+ YangmanService.$inject = [
+ 'RequestBuilderService',
+ 'YangUtilsService',
+ 'YangUtilsRestangularService',
+ 'ENV',
+ 'ParsingJsonService',
+ 'RequestsService',
+ 'PathUtilsService',
+ 'constants',
+ ];
+
+ function YangmanService(
+ RequestBuilderService,
+ YangUtilsService,
+ YangUtilsRestangularService,
+ ENV,
+ ParsingJsonService,
+ RequestsService,
+ PathUtilsService,
+ constants
+ ){
+ var service = {
+ cutUrl: cutUrl,
+ checkRpcReceivedData: checkRpcReceivedData,
+ executeRequestOperation: executeRequestOperation,
+ fillNodeFromResponse: fillNodeFromResponse,
+ getDataStoreIndex: getDataStoreIndex,
+ handleNodeIdentifier: handleNodeIdentifier,
+ prepareAllRequestData: prepareAllRequestData,
+ prepareReceivedData: prepareReceivedData,
+ putIntoObj: putIntoObj,
+ setSrcDataByDataType: setSrcDataByDataType,
+ validateFile: validateFile,
+ };
+
+ return service;
+
+ /**
+ * Handle param continuum between header path array and node data
+ * @param parametersList
+ * @param selectedSubApi
+ * @param node
+ */
+ function handleNodeIdentifier(parametersList, selectedSubApi, node){
+ var identifier = RequestsService.findIdentifierByParam(
+ parametersList, selectedSubApi.pathArray[selectedSubApi.pathArray.length - 1]
+ );
+
+ if ( identifier ){
+ PathUtilsService.fillListNode(node, identifier.label, identifier.value);
+ }
+ }
+
+ /**
+ * Put data to output container if root node is rpc
+ * @param data
+ * @param node
+ * @returns {*}
+ */
+ function checkRpcReceivedData(data, node){
+ return node.type === constants.NODE_RPC ? cutData(data) : data;
+
+ function cutData(data){
+ return {
+ output: data[node.label].output,
+ };
+ }
+ }
+
+ /**
+ * Put source object into destination object by source properties
+ * @param sourceObj
+ * @param destinationObj
+ */
+ function putIntoObj(sourceObj, destinationObj, containter){
+ if ( sourceObj ) {
+ Object.keys(sourceObj).forEach(function(prop){
+ destinationObj[containter] = destinationObj[containter] ? destinationObj[containter] : {};
+ destinationObj[containter][prop] = sourceObj[prop];
+ });
+ }
+ }
+
+ /**
+ * Prepare request date before filling into node depends on method and node type
+ * @param node
+ * @param method
+ * @param rData
+ * @param sData
+ * @param outputType
+ * @returns {*}
+ */
+ function prepareReceivedData(node, method, rData, sData, outputType){
+ var prepareType = {
+ rpc: function (){
+
+ if ( outputType === constants.DISPLAY_TYPE_FORM ){
+ var dObj = {};
+
+ if ( !sData ) {
+ sData = {};
+ sData[node.label] = {};
+ }
+
+ putIntoObj(rData, dObj, node.label);
+ putIntoObj(sData[node.label] ? sData[node.label] : sData, dObj, node.label);
+ return dObj;
+ } else {
+ return rData;
+ }
+ },
+ default: function (){
+ var methodType = {
+ GET: function () {
+ if ( node ){
+ node.clear();
+ }
+ return rData;
+ },
+ DELETE: function () {
+ if ( node ) {
+ node.clear();
+ }
+ return {};
+ },
+ DEFAULT: function () {
+ return rData;
+ },
+ };
+
+ return (methodType[method] || methodType.DEFAULT)();
+ },
+ };
+
+ return (prepareType[node ? node.type : 'default'] || prepareType.default)();
+ }
+
+ /**
+ * Validating collection import file
+ * @param data
+ * @param checkArray
+ * @returns {*}
+ */
+ function validateFile(data, checkArray){
+ try {
+ var obj = ParsingJsonService.parseJson(data);
+
+ return obj && obj.every(function (el){
+ return checkArray.every(function (arr){
+ return el.hasOwnProperty(arr);
+ });
+ });
+ } catch (e) {
+ return e;
+ }
+ }
+
+ /**
+ * Return index of selected datastore in list
+ * @param list
+ * @param dataStore
+ * @returns {*}
+ */
+ function getDataStoreIndex(list, dataStore){
+ var rIndex = null,
+ result = list.some(function (item, index) {
+ rIndex = index;
+ return item.label === dataStore;
+ });
+
+ return result ? rIndex : null;
+ }
+
+ /**
+ * Apply all parametrized values into request (data, url, pathArray)
+ * @param allPreparedData
+ * @param params
+ * @param selSubApiCopy
+ * @param requestUrl
+ */
+ function setParametrizedData(allPreparedData, params, selSubApiCopy, requestUrl){
+ allPreparedData.reqFullUrl = RequestsService.applyParamsToStr(params, requestUrl);
+
+ // apply parametrized value into request data in string form
+ allPreparedData.reqString =
+ selSubApiCopy ? RequestsService.applyParamsToStr(params, selSubApiCopy.buildApiRequestString()) : '';
+
+ if ( !angular.equals(allPreparedData.reqFullUrl, requestUrl) && selSubApiCopy ){
+ // fill parametrized data into path array
+ PathUtilsService.fillPath(selSubApiCopy.pathArray, allPreparedData.reqFullUrl);
+ }
+
+ allPreparedData.reqData = RequestsService.applyParamsToObj(params, allPreparedData.srcData);
+ }
+
+ /**
+ * Set source data into request object based on shown data type
+ * @param allPreparedData
+ * @param node
+ * @param requestData
+ * @param dataType
+ */
+ function setSrcDataByDataType(allPreparedData, node, requestData, dataType){
+ if ( dataType === constants.DISPLAY_TYPE_FORM && node){
+ node.buildRequest(RequestBuilderService, requestData, node.module);
+ allPreparedData.srcData = angular.copy(requestData);
+ }
+ else {
+ allPreparedData.srcData = requestData;
+ }
+ }
+
+ /**
+ * Prepare all necessary data for executing or saving request
+ * @param selectedApi
+ * @param selectedSubApi
+ * @param operation
+ * @param node
+ * @param dataType
+ * @param requestUrl
+ * @param requestData
+ * @param params
+ * @returns {{customRestangular: null, headers: {}, operation: string, reqString: string, reqHeaders: {},
+ * reqData: {}}}
+ */
+ function prepareAllRequestData(selectedApi, selectedSubApi, operation, node, dataType, requestUrl, requestData,
+ params) {
+ var allPreparedData = {
+ customRestangular: null,
+ headers: {},
+ operation: '',
+ reqString: '',
+ reqHeaders: {},
+ reqData: '',
+ srcData: '',
+ reqFullUrl: '',
+ },
+ selSubApiCopy = angular.copy(selectedSubApi);
+
+ setSrcDataByDataType(allPreparedData, node, requestData, dataType);
+ setParametrizedData(allPreparedData, params, selSubApiCopy, requestUrl);
+
+ // prepare req data
+ if (operation === constants.OPERATION_GET || operation === constants.OPERATION_DELETE){
+ allPreparedData.srcData = null;
+ allPreparedData.reqData = null;
+ }
+ else if ( operation === constants.OPERATION_POST ){
+
+ if ( selSubApiCopy ) {
+ allPreparedData.reqData = YangUtilsService.postRequestData(
+ allPreparedData.reqData,
+ allPreparedData.reqString,
+ selSubApiCopy
+ );
+ }
+ }
+
+ // set correct host into restangular based on shown data type and prepare data
+ if ( dataType === constants.DISPLAY_TYPE_REQ_DATA ){
+ var parser = locationHelper(allPreparedData.reqFullUrl, ['pathname', 'origin']),
+ raParam = '';
+
+ YangUtilsRestangularService.setBaseUrl(parser.origin);
+ allPreparedData.reqString = parser.pathname.slice(1).split('/');
+ raParam = allPreparedData.reqString.shift();
+ allPreparedData.reqString = allPreparedData.reqString.join('/');
+
+ allPreparedData.customRestangular = YangUtilsRestangularService.one(raParam);
+
+ } else {
+
+ YangUtilsRestangularService.setBaseUrl(ENV.getBaseURL('MD_SAL'));
+ allPreparedData.customRestangular = YangUtilsRestangularService.one('restconf');
+
+ if ( node ) {
+ allPreparedData.headers = YangUtilsService.prepareHeaders(allPreparedData.reqData);
+ }
+ }
+
+ allPreparedData.operation = YangUtilsService.prepareOperation(operation);
+ return allPreparedData;
+ }
+
+ function cutUrl(url){
+ return url.indexOf('restconf') > -1 ? url.split('restconf')[1].substring(1) : url;
+ }
+
+ /**
+ * Execute request built from this data
+ * @param selectedApi
+ * @param selectedSubApi
+ * @param operation
+ * @param node
+ * @param dataType
+ * @param requestUrl
+ * @param requestData
+ * @param successCbk
+ * @param errorCbk
+ * @param params
+ */
+ function executeRequestOperation(selectedApi, selectedSubApi, operation, node, dataType, requestUrl,
+ requestData, params, successCbk, errorCbk) {
+
+ YangUtilsRestangularService.setFullResponse(true);
+
+ // prepare all necessary data
+ var allPreparedData = prepareAllRequestData(selectedApi, selectedSubApi, operation, node, dataType,
+ requestUrl, requestData, params);
+
+ // executing operation
+ allPreparedData.customRestangular.customOperation(
+ allPreparedData.operation.toLowerCase(),
+ allPreparedData.reqString,
+ null,
+ allPreparedData.headers,
+ allPreparedData.reqData
+ )
+ .then(
+ function (response) {
+ (successCbk || angular.noop)(finishExecuting(response), response);
+ },
+ function (response) {
+ (errorCbk || angular.noop)(finishExecuting(response), response);
+ }
+ );
+
+ function finishExecuting(response){
+
+ return {
+ status: response.status,
+ statusText: response.statusText,
+ time: null,
+ requestData: allPreparedData.reqData,
+ requestSrcData: allPreparedData.srcData,
+ };
+ }
+ }
+
+ /**
+ * Method for parsing path to additional properties based on JS LOCATION
+ * @param path
+ * @param properties
+ * @returns {{}}
+ */
+ function locationHelper(path, properties){
+ var parser = document.createElement('a'),
+ obj = {};
+
+ parser.href = path;
+
+ properties.forEach(function (prop) {
+ obj[prop] = parser[prop];
+ });
+
+ return obj;
+ }
+
+ /**
+ * Fill node values from response
+ * @param node
+ * @param data
+ */
+ function fillNodeFromResponse(node, data){
+ var props = data ? Object.getOwnPropertyNames(data) : [];
+
+ // fill each property - needed for root mountpoint node,
+ // in other cases there should be only one property anyway
+ props.forEach(function (p) {
+ node.fill(p, data[p]);
+ });
+ }
+ }
+
+});
--- /dev/null
+<md-list class="directive__abn-tree">
+ <md-list-item ng-repeat="row in tree_rows | filter:{visible:true} track by row.branch.uid"
+ ng-class="'level-' + {{ row.level }} + (row.branch.selected ? ' active':'')"
+ ng-click="user_clicks_branch(row.branch)"
+ ng-init="(_dataCollection = []).length = row.level;">
+ <span ng-repeat="i in _dataCollection track by $index" ng-class="{'empty-box' : $index !== 0}"></span>
+ <md-icon md-font-set="material-icons" class="pointer" ng-click="row.branch.expanded = !row.branch.expanded">{{row.tree_icon}}</md-icon>
+ <span flex class="indented tree-label">{{ row.label }} {{ row.branch.identifier }}</span>
+ </md-list-item>
+</md-list>
+
--- /dev/null
+<div ng-if="isActionMenu()" class="menu-container md-menu">
+ <!-- Close menu (click catcher) -->
+ <div ng-show="isActive">
+ <md-backdrop ng-click="closeMenu()" class="md-menu-backdrop md-click-catcher" style="position: fixed;"></md-backdrop>
+ </div>
+ <!-- open menu button -->
+ <md-button class="md-icon-button" ng-click="openMenu(); hideInfoBox();">
+ <md-icon md-font-set="material-icons">reorder</md-icon>
+ </md-button>
+
+ <!-- Menu content -->
+ <div class="yang-menu-content md-menu-content" ng-show="isActive">
+ <h5 class="title">
+ {{ 'YANGMAN_YANG_MENU' | translate }}
+ <md-icon md-font-set="material-icons">reorder</md-icon>
+ </h5>
+ <md-divider></md-divider>
+
+ <!-- add list item -->
+ <div class="yang-menu-item md-menu-item" ng-if="addListItem">
+ <md-button ng-click="addListItemFunc(); closeMenu();">
+ <md-icon md-font-set="material-icons">library_add</md-icon>
+ <span md-menu-align-target>{{'YANGMAN_ADD_LIST_ITEM' | translate}}</span>
+ </md-button>
+ </div>
+
+ <!-- show items list -->
+ <div class="yang-menu-item md-menu-item" ng-if="yangList && node.actElemStructure">
+ <md-button ng-click="switchSection('items'); setItemList();">
+ <md-icon md-font-set="material-icons">list</md-icon>
+ <span md-menu-align-target>{{'YANGMAN_SHOW_LIST_ITEM' | translate}}</span>
+ </md-button>
+ </div>
+
+ <!-- augmentations menu item -->
+ <div class="yang-menu-item md-menu-item" ng-if="node.augmentionGroups.length">
+ <md-button ng-click="switchSection('augmentations')">
+ <md-icon md-font-set="material-icons">brightness_auto</md-icon>
+ <span md-menu-align-target>{{'YANGMAN_AUGMENTATIONS' | translate}}</span>
+ </md-button>
+ </div>
+
+ <!-- info box -->
+ <div id="infoBox" class="md-whiteframe-z2 info-box" ng-show="infoBox" ng-switch="infoBoxSection">
+ <div ng-switch-when="augmentations">
+ <md-list flex>
+ <md-list-item ng-repeat="augmentation in node.augmentionGroups">
+ <md-switch ng-model="augmentations.getAugmentation(node, augmentation).expanded"
+ aria-label="{{augmentation}}"
+ md-prevent-menu-close>
+ {{augmentation}}
+ </md-switch>
+ </md-list-item>
+ </md-list>
+ </div>
+
+ <!-- yang list items -->
+ <div ng-switch-when="items">
+ <md-list>
+ <md-list-item ng-repeat="_ in node.listData" class="no-wrap">
+ <!-- icon -->
+ <md-icon md-font-set="material-icons">
+ {{ [yangList.currentDisplayIndex, yangList.currentDisplayIndex + 1, yangList.currentDisplayIndex - 1].indexOf($index) !== -1 ? 'remove_red_eye' : ''}}
+ </md-icon>
+
+ <!-- title -->
+ <p ng-class="{'active' : node.actElemIndex === $index}"
+ class="pointer"
+ ng-click="node.changeActElementData($index)">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}} {{node.createListName($index) || '[' + $index + ']'}}
+ </p>
+
+ <!-- duplicated key -->
+ <md-icon md-font-set="material-icons" ng-show="node.doubleKeyIndexes.indexOf($index) > -1">
+ <md-tooltip md-direction="top">{{ 'YANGMAN_LIST_INDEX_DUPLICATE' | translate }}</md-tooltip>
+ error_outline
+ </md-icon>
+
+ <!-- remove button -->
+ <md-icon md-font-set="material-icons"
+ class="pointer"
+ ng-if="addListItem"
+ ng-click="yangList.removeListElem($index)">
+ <md-tooltip md-direction="top">{{ 'YANGMAN_LIST_DELETE_ITEM' | translate }}</md-tooltip>
+ remove_circle_outline
+ </md-icon>
+
+ <md-ink-bar ng-if="node.actElemIndex === $index" class="custom"></md-ink-bar>
+ </md-list-item>
+ </md-list>
+ </div>
+ </div>
+ </div>
+</div>
--- /dev/null
+<span ng-mouseenter="executeInfoBox(true)" ng-mouseleave="executeInfoBox(false)" class="info-box-container__hover-wrapper">
+ <span ng-transclude></span>
+
+ <div class="md-whiteframe-z2 info-box" ng-show="showBoxCheck()">
+ <div class="info-box__padding">
+ <!-- key -->
+ <span ng-show="node.isKey()">
+ {{'Key for "' + node.parent.label + '"'}}
+ <md-menu-divider ng-show="dividerCheck(true)"></md-menu-divider>
+ </span>
+ <!-- augment -->
+ <span ng-show="node.augmentationId">
+ {{ 'YANGMAN_IS_AUGMENT' | translate }} <i>{{node.type}}</i> "{{ node.augmentationId }}"
+ <md-menu-divider ng-show="dividerCheck()"></md-menu-divider>
+ </span>
+ <!-- description -->
+ <span ng-show="description.length">{{description}}</span>
+ </div>
+ </div>
+</span>
--- /dev/null
+<section class="yangmanModule" id="yangmanModule" layout="row">
+
+ <!-- LEFT SIDE -->
+ <md-content layout="column" style="width: 400px; height: 100%;" class="yangmanModule__left-panel ym-resizable-e" id="left-panel">
+ <!-- module arrow button -->
+ <md-icon md-font-set="material-icons "
+ class="arrow-switcher"
+ ng-click="main.toggleLeftPanel(); main.initModuleDetailHeight();"
+ ng-class="{'arrow-switcher__left' : main.leftPanelTab === 0}"
+ ng-show="selectedDatastore"> play_arrow </md-icon>
+ <!--ng-show="!main.selectedMainTab && selectedDatastore"> play_arrow </md-icon>-->
+ <!-- content -->
+ <md-tabs md-border-bottom md-selected="main.leftPanelTab" class="yangmanModule__left-panel__detail-list-tabs-container">
+ <md-tab label="models tree">
+ <md-content>
+
+ <!-- MODULES HISTORY COLLECTION TABS -->
+ <md-tabs class="yangmanModule__mhc-tabs inline-tabs" md-no-pagination md-dynamic-height md-stretch-tabs="always">
+ <!-- Modules tab -->
+ <md-tab label="{{'YANGMAN_MODULES' | translate}}" md-on-select="main.switchedTab(0)">
+ <div ng-include src="globalViewPath + 'leftpanel/modules-tab.tpl.html'" class="h100"></div>
+ </md-tab>
+ <!-- History tab -->
+ <md-tab label="{{'YANGMAN_HISTORY' | translate}}" md-on-select="main.switchedTab(1)">
+ <div ng-include src="globalViewPath + 'leftpanel/history-tab.tpl.html'" class="historyTab"></div>
+ </md-tab>
+ <!-- Collection tab -->
+ <md-tab label="{{'YANGMAN_COLLECTIONS' | translate}}" md-on-select="main.switchedTab(2)">
+ <div ng-include src="globalViewPath + 'leftpanel/collections-tab.tpl.html'" class="collectionsTab"></div>
+ </md-tab>
+ </md-tabs>
+ </md-content>
+ </md-tab>
+
+ <!-- MODULE TREE DETAIL -->
+ <md-tab label="model detail" md-on-select="main.initModuleDetailHeight()">
+ <md-content class="yangmanModule__module-detail">
+ <div ng-include src="globalViewPath + 'leftpanel/module-detail.tpl.html'"></div>
+ </md-content>
+ </md-tab>
+ </md-tabs>
+ </md-content>
+
+ <!-- RIGHT SIDE -->
+ <md-content layout="column" flex
+ class="md-whiteframe-3dp md-padding yangmanModule__right-panel"
+ ng-include src="globalViewPath + 'rightpanel/detail.tpl.html'"></md-content>
+</section>
--- /dev/null
+<md-list class="yangmanModule__requests-list__collections-list"
+ ng-cloak
+ ng-controller="RequestsListCtrl as reqList"
+ ng-init="reqList.init('collections')">
+
+ <md-content class="searchBox yangmanModule__left-panel__search" layout="row">
+
+ <!-- searching -->
+ <md-input-container layout="row" md-no-float class="modules-list-search" flex>
+ <!-- search icon, form, clear button -->
+ <md-icon class="material-icons">search</md-icon>
+ <input class="ng-pristine ng-valid ng-touched"
+ type="text"
+ flex
+ placeholder="{{'YANGMAN_SEARCH' | translate}}"
+ ng-model="reqList.search"
+ aria-invalid="false" />
+ <md-button aria-label="{{'YANGMAN_CLEAR_SEARCH'| translate}}" flex="none"
+ ng-click="reqList.clearFilter()"
+ ng-if="reqList.search">
+ <md-icon class="material-icons clickable">
+ close
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_CLEAR_SEARCH'| translate}}</md-tooltip>
+ </md-button>
+ <!-- /search icon, form, clear button -->
+ </md-input-container>
+
+ <!-- sorting -->
+ <span class="collection-button-container">
+ <md-button ng-click="reqList.toggleCollectionsSort()"
+ ng-disabled="reqList.collectionList.collections.length <= 1">
+ <md-icon class="material-icons clickable" > sort</md-icon>
+ </md-button>
+ <md-tooltip md-direction="bottom">
+ {{ ( reqList.collectionsSortAsc ? 'YANGMAN_SORT_COLLECTIONS_DESC' : 'YANGMAN_SORT_COLLECTIONS_ASC' )| translate}}
+ </md-tooltip>
+ </span>
+ <!-- /sorting -->
+
+ <!-- save -->
+ <span class="collection-button-container">
+ <md-button ng-click="reqList.showDgSaveReq($event)"
+ ng-disabled="reqList.mainList.getSelectedItems(reqList.filterCollReq).length === 0">
+ <md-icon class="material-icons clickable">
+ save
+ </md-icon>
+ </md-button>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_REQS_SAVE_TO_COL'| translate}}</md-tooltip>
+ </span>
+ <!-- /save -->
+
+ <!-- importing -->
+ <span class="collection-button-container">
+ <input type="file" accept=".json" id="importCollection" on-read-file="reqList.readCollectionFromFile($fileContent)">
+ <md-button>
+ <label for="importCollection">
+ <md-icon class="material-icons clickable" >
+ file_upload
+ </md-icon>
+ </label>
+ </md-button>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_IMPORT_COLLECTION'| translate}}</md-tooltip>
+ </span>
+ <!-- /importing -->
+
+ <md-menu layout-align="center start">
+ <md-button ng-disabled="!reqList.mainList.list.length" aria-label="menu" ng-click="$mdOpenMenu()">
+ <md-icon class="material-icons clickable"> delete</md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_DELETE_OPTIONS' | translate}}</md-tooltip>
+ </md-button>
+ <md-menu-content>
+ <!-- delete selected -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_REQS_DELETE'| translate}}"
+ ng-click="reqList.showDgDeleteRequests($event)"
+ ng-disabled="reqList.mainList.getSelectedItems(reqList.filterCollReq).length === 0">
+ <md-icon class="material-icons clickable">
+ delete
+ </md-icon>
+ {{'YANGMAN_REQS_DELETE'| translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- / delete selected -->
+ <!-- clear collections -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_DELETE_COLLECTIONS' | translate}}"
+ ng-click="reqList.clearCollectionList($event)">
+ <md-icon class="material-icons clickable">
+ delete_forever
+ </md-icon>
+ {{'YANGMAN_DELETE_COLLECTIONS' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- / clear history -->
+ </md-menu-content>
+ </md-menu>
+ <!-- / menu for deleting and clearing -->
+
+ <!-- menu for selecting and deselecting-->
+ <md-menu layout-align="center start">
+ <md-button ng-disabled="( !reqList.mainList.list.length)" aria-label="menu" ng-click="$mdOpenMenu()">
+ <md-icon class="material-icons clickable">
+ playlist_add_check
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_SELECT_OPTIONS' | translate}}</md-tooltip>
+ </md-button>
+ <md-menu-content>
+ <!-- select all -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_SELECT_ALL' | translate}}"
+ ng-click="reqList.selectAllFilteredRequests()">
+ <md-icon class="material-icons clickable">
+ done
+ </md-icon>
+ {{'YANGMAN_SELECT_ALL' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- /select all -->
+ <!-- deselect all -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_DESELECT_ALL' | translate}}"
+ ng-click="reqList.deselectAllFilteredRequests()"
+ ng-disabled="reqList.mainList.getSelectedItems(reqList.filterCollReq).length === 0">
+ <md-icon class="material-icons clickable">
+ close
+ </md-icon>
+ {{'YANGMAN_DESELECT_ALL' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- / deselect all -->
+ </md-menu-content>
+ </md-menu>
+ <!-- / menu for selecting and deselecting -->
+ </md-content>
+
+ <md-divider></md-divider>
+
+ <!-- collection list -->
+ <md-content class="scrollableY">
+
+ <div ng-repeat="collection in reqList.mainList.collections | filter: reqList.filterCol | orderBy: (reqList.collectionsSortAsc ? '' : '-')+'name'">
+
+ <div layout="row">
+
+ <md-list-item class="yangmanModule__requests-list__collection"
+ flex
+ ng-class="{'expanded' : collection.expanded, 'selected': collection.expanded}"
+ ng-click="collection.toggleExpanded()">
+
+ <div layout="row">
+ <md-icon md-font-set="material-icons" class="top-icon">
+ folder_open
+ </md-icon>
+ <div layout="column">
+
+ <p flex>
+ <span md-highlight-text="reqList.search" md-highlight-flags="i">
+ {{collection.name}}
+ </span><br />
+ <span class="desc">
+ <span class="desc" ng-if="reqList.search && !reqList.filterColName(collection)">{{'YANGMAN_MATCHING'| translate}} {{reqList.colMatchingReqsCount(collection)}} / </span>
+ {{collection.data.length}} {{(collection.data.length>1 ? 'YANGMAN_COLLECTION_REQUESTS' : 'YANGMAN_COLLECTION_REQUEST')| translate}}
+ </span>
+ </p>
+ </div>
+ </div>
+
+ </md-list-item>
+ <md-menu class="yangmanModule__requests-list__group__collectionMenu"
+ md-offset="35 15"
+ layout-align="center start">
+ <md-button aria-label="menu" class="md-primary" ng-click="$mdOpenMenu()">
+ <i class="material-icons">menu</i>
+ </md-button>
+ <md-menu-content class="reqMenu">
+ <md-menu-item>
+ <md-button aria-label="Duplicate collection"
+ ng-click="reqList.showDgEditCollection($event, collection, false)">
+ <i class="material-icons">mode_edit</i>
+ {{'YANGMAN_COLLECTION_EDIT'| translate}}
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_COLLECTION_DUPLICATE'| translate}}"
+ ng-click="reqList.showDgEditCollection($event, collection, true)">
+ <i class="material-icons">control_point_duplicate</i>
+ {{'YANGMAN_COLLECTION_DUPLICATE'| translate}}
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_COLLECTION_DOWNLOAD'| translate}}"
+ ng-click="reqList.downloadCollection(collection)">
+ <i class="material-icons">file_download</i>
+ {{'YANGMAN_COLLECTION_DOWNLOAD'| translate}}
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_COLLECTION_DELETE'| translate}}"
+ ng-click="reqList.showDgDeleteCollection($event, collection)">
+ <i class="material-icons">delete</i>
+ {{'YANGMAN_COLLECTION_DELETE'| translate}}
+ </md-button>
+ </md-menu-item>
+ </md-menu-content>
+ </md-menu>
+ </div>
+
+
+ <md-list ng-show="collection.expanded" class="yangmanModule__requests-list__collection__requests">
+ <div ng-repeat="request in collection.data | filter: reqList.filterReq"
+ layout="row"
+ class="yangmanModule__requests-list__item-container"
+ ng-include src="globalViewPath + 'leftpanel/request-item.tpl.html'">
+ </div>
+ </md-list>
+ <md-divider></md-divider>
+
+ </div>
+ </md-content>
+
+</md-list>
--- /dev/null
+<md-dialog aria-label="{{'YANGMAN_COLLECTION_NAME'| translate}}" ng-cloak>
+ <form name="collectionForm">
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>{{(dialog.duplicate ? 'YANGMAN_COLLECTION_DUPLICATE' : 'YANGMAN_COLLECTION_CHANGE_NAME')| translate}}</h2>
+ <span flex></span>
+ </div>
+ </md-toolbar>
+ <md-dialog-content style="width:300px;">
+ <div class="md-dialog-content" layout="column">
+ <div layout="row">
+ <md-input-container flex>
+ <label>{{(dialog.duplicate ? 'YANGMAN_COLLECTION_NEW_NAME' : 'YANGMAN_COLLECTION_NAME') | translate}}</label>
+ <input name="collectionName"
+ ng-model="dialog.collectionName"
+ autocomplete="off"
+ ng-required="true">
+ <div ng-messages="collectionForm.collectionName.$error" multiple md-auto-hide="false">
+ <div ng-message="required">
+ {{'YANGMAN_COLLECTION_NAME_REQUIRED'| translate}}
+ </div>
+ </div>
+ </md-input-container>
+ </div>
+ </div>
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="dialog.cancel()">
+ {{'YANGMAN_CANCEL'| translate}}
+ </md-button>
+ <md-button ng-click="dialog.save()" ng-disabled="!collectionForm.$valid">
+ {{'YANGMAN_SAVE'| translate}}
+ </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
--- /dev/null
+<md-list class="yangmanModule__requests-list h100"
+ ng-cloak
+ ng-init="reqList.init('history')"
+ ng-controller="RequestsListCtrl as reqList">
+
+ <md-content class="searchBox yangmanModule__left-panel__search" layout="row">
+
+ <!-- searching -->
+ <md-input-container layout="row" md-no-float class="modules-list-search" flex>
+ <!-- search icon, form, clear button -->
+ <md-icon class="material-icons">search</md-icon>
+ <input class="ng-pristine ng-valid ng-touched"
+ type="text"
+ flex
+ placeholder="{{'YANGMAN_SEARCH' | translate}}"
+ ng-model="reqList.search"
+ aria-invalid="false" />
+ <md-button aria-label="{{'YANGMAN_CLEAR_SEARCH'| translate}}" flex="none"
+ ng-click="reqList.clearFilter()"
+ ng-if="reqList.search">
+ <md-icon class="material-icons clickable">
+ close
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_CLEAR_SEARCH'| translate}}</md-tooltip>
+ </md-button>
+ <!-- /search icon, form, clear button -->
+ </md-input-container>
+
+ <!-- save -->
+ <md-button ng-click="reqList.showDgSaveReq($event)"
+ ng-disabled="!reqList.mainList.getSelectedItems(reqList.filterReq).length">
+ <md-icon class="material-icons clickable">
+ save
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_REQS_SAVE_TO_COL'| translate}}</md-tooltip>
+ </md-button>
+ <!-- /save -->
+
+ <!-- menu for deleting and clearing-->
+ <md-menu layout-align="center start">
+ <md-button ng-disabled="!reqList.mainList.list.length" aria-label="menu" ng-click="$mdOpenMenu()">
+ <md-icon class="material-icons clickable"> delete</md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_DELETE_OPTIONS' | translate}}</md-tooltip>
+ </md-button>
+ <md-menu-content>
+ <!-- delete selected -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_REQS_DELETE'| translate}}"
+ ng-click="reqList.showDgDeleteRequests($event)"
+ ng-disabled="!reqList.mainList.getSelectedItems(reqList.filterReq).length">
+ <md-icon class="material-icons clickable"> delete</md-icon>
+ {{'YANGMAN_REQS_DELETE'| translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- / delete selected -->
+ <!-- clear history -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_DELETE_HISTORY' | translate}}"
+ ng-click="reqList.clearHistoryList($event)"
+ ng-disabled="!reqList.mainList.list.length">
+ <md-icon class="material-icons clickable"> delete_forever</md-icon>
+ {{'YANGMAN_DELETE_HISTORY' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- / clear history -->
+ </md-menu-content>
+ </md-menu>
+ <!-- / menu for deleting and clearing -->
+
+ <!-- menu for selecting and deselecting-->
+ <md-menu layout-align="center start">
+ <md-button ng-disabled="!reqList.mainList.list.length" aria-label="menu" ng-click="$mdOpenMenu()">
+ <md-icon class="material-icons clickable">
+ playlist_add_check
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_SELECT_OPTIONS' | translate}}</md-tooltip>
+ </md-button>
+ <md-menu-content>
+ <!-- select all -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_SELECT_ALL' | translate}}"
+ ng-click="reqList.selectAllFilteredRequests()">
+ <md-icon class="material-icons clickable">
+ done
+ </md-icon>
+ {{'YANGMAN_SELECT_ALL' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- /select all -->
+ <!-- deselect all -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_DESELECT_ALL' | translate}}"
+ ng-click="reqList.deselectAllFilteredRequests()" ng-disabled="reqList.mainList.getSelectedItems(reqList.filterReq).length === 0">
+ <md-icon class="material-icons clickable">
+ close
+ </md-icon>
+ {{'YANGMAN_DESELECT_ALL' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- / deselect all -->
+ </md-menu-content>
+ </md-menu>
+ <!-- / menu for selecting and deselecting -->
+
+ </md-content>
+
+ <md-divider></md-divider>
+
+ <!-- list of items grouped by date -->
+ <md-content class="scrollableY">
+ <md-list-item ng-repeat="group in reqList.mainList.dateGroups | orderBy: 'name': true"
+ class="yangmanModule__requests-list__group"
+ ng-if="(group.requests | filter:reqList.filterReq).length">
+
+ <div layout="column" flex>
+
+ <!-- date group header -->
+ <md-subheader class="md-no-sticky">
+ {{group.longName}}
+ </md-subheader>
+ <!-- /date group header -->
+
+ <!-- list of requests in current group -->
+ <md-list>
+ <div ng-repeat="request in group.requests | filter: reqList.filterReq | orderBy: '-timestamp' track by $index"
+ layout="row"
+ class="yangmanModule__requests-list__item-container"
+ ng-include src="globalViewPath + 'leftpanel/request-item.tpl.html'">
+ </div>
+ </md-list>
+ <!-- /list of requests in current group -->
+
+ </div>
+
+ <md-divider></md-divider>
+
+ </md-list-item>
+ </md-content>
+ <!-- /list of items grouped by date -->
+
+</md-list>
--- /dev/null
+<md-content ng-controller="ModuleDetailCtrl as moduleDetail">
+ <!-- Module title -->
+ <h4 class="text-center"><small>module</small> {{selectedModule.label}}</h4>
+ <!-- DATA STORE || RPC TABS -->
+ <md-tabs md-no-pagination md-dynamic-height
+ md-stretch-tabs="always"
+ md-selected="moduleDetail.selectedDataStoreIndex"
+ class="tabs inline-tabs">
+ <md-tab ng-repeat="item in selectedModule.children">
+ <md-tab-label>
+ <div layout="row">
+ <span flex="grow" ng-click="moduleDetail.setDataDetailStore(item)">{{item.label}}</span>
+ </div>
+ </md-tab-label>
+
+ <md-tab-body>
+ <div class="scrollableY scrollableX">
+ <abn-api-tree tree-data="moduleDetail.treeApis"
+ tree-rows="moduleDetail.treeRows"
+ on-select="moduleDetail.setApiNode(branch.indexApi, branch.indexSubApi)"></abn-api-tree>
+ </div>
+ </md-tab-body>
+ </md-tab>
+ </md-tabs>
+</md-content>
--- /dev/null
+<section ng-cloak ng-controller="ModulesListCtrl as modulesList" class="h100">
+ <!-- searching -->
+ <section class="yangmanModule__left-panel__search">
+ <md-input-container layout="row" md-no-float class="modules-list-search">
+ <md-icon class="material-icons">search</md-icon>
+ <input class="ng-pristine ng-valid ng-touched"
+ type="text"
+ flex
+ placeholder="{{'YANGMAN_SEARCH' | translate}}"
+ ng-model="modulesList.search"
+ aria-invalid="false" />
+
+ <!-- search clear button -->
+ <md-button aria-label="{{'YANGMAN_CLEAR_SEARCH'| translate}}" flex="none"
+ ng-click="modulesList.clearFilter()"
+ ng-if="modulesList.search">
+ <md-icon class="material-icons clickable">
+ close
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_CLEAR_SEARCH'| translate}}</md-tooltip>
+ </md-button>
+ </md-input-container>
+
+ </section>
+
+ <!-- divider -->
+ <md-divider ng-hide="modulesList.showLoadingBox"></md-divider>
+
+ <!-- modules list -->
+ <md-list ng-cloak class="yangmanModule__modules-list scrollableY">
+
+ <!-- Loading bar -->
+ <md-progress-linear md-mode="indeterminate" ng-show="modulesList.showLoadingBox"></md-progress-linear>
+
+ <!-- Mount point title -->
+ <section ng-show="modulesList.moduleListTitle.length">
+ <h4>{{ modulesList.moduleListTitle }}</h4>
+ <!-- Line -->
+ <md-divider></md-divider>
+ </section>
+
+ <!-- Modules list -->
+ <md-list-item ng-repeat="module in modulesList.treeApis | filter: modulesList.customSearch | orderBy: 'label'"
+ class="yangmanModule__modules-list__item"
+ ng-class="{'expanded' : module.expanded, 'selected' : modulesList.checkSelectedModule(module)}"
+ ng-hide="modulesList.showLoadingBox"
+ ng-click="modulesList.setModule(module, $event)">
+ <!-- Item content -->
+ <div layout="column" flex>
+ <!-- Module title -->
+ <div layout="row" layout-align="center center" class="pointer title">
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ {{module.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+ <p flex class="top-element" md-highlight-text="modulesList.search" md-highlight-flags="i"> {{module.label}} </p>
+ </div>
+
+ <!-- Datastore && rpc -->
+ <md-list flex class="yangmanModule__datastore-list" ng-show="module.expanded">
+ <md-list-item ng-repeat="item in module.children">
+ <div flex
+ layout="row"
+ layout-align="center center"
+ class="pointer"
+ ng-click="modulesList.setDataStore(item, module)">
+ <md-icon md-font-set="material-icons">keyboard_arrow_right</md-icon>
+ <p flex> {{item.label}} </p>
+ </div>
+ </md-list-item>
+ </md-list>
+ </div>
+ <!-- Line -->
+ <md-divider></md-divider>
+ </md-list-item>
+ </md-list>
+</section>
--- /dev/null
+<!-- request row -->
+<md-list-item class="yangmanModule__requests-list__group__item"
+ ng-class="{selected: request.selected}"
+ layout="row"
+ flex="100"
+ ng-click="reqList.selectRequest($event, request);">
+
+ <div flex="15" class="yangmanModule__requests-list__group__item__method" layout-align="center center">
+ <p class="{{request.status === 'success' || !request.status ? request.method : 'error'}}"> {{request.method === vm.constants.OPERATION_DELETE ? 'DEL' : request.method }} </p>
+ <md-tooltip md-direction="bottom" ng-show="request.status">{{request.status | uppercase }}</md-tooltip>
+ </div>
+
+ <div flex class="yangmanModule__requests-list__group__item__path" layout="column">
+ <p md-highlight-text="reqList.search" md-highlight-flags="i">
+ {{ request.path }}
+ </p>
+ </div>
+ <div flex="10"></div>
+</md-list-item>
+<!-- /request row -->
+
+<!-- request submenu -->
+<md-menu class="yangmanModule__requests-list__group__itemMenu"
+ md-offset="35 15"
+ layout-align="center start"
+ ng-class="{selected: request.selected}">
+
+ <md-button aria-label="menu" class="md-primary" ng-click="reqList.selectOnlyThisRequest(request); $mdOpenMenu()">
+ <i class="material-icons">menu</i>
+ </md-button>
+
+ <md-menu-content class="reqMenu">
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_REQ_RUN'| translate}}" class="" ng-click="reqList.executeRequest(request)">
+ <i class="material-icons">play_arrow</i>
+ {{'YANGMAN_REQ_RUN'| translate}}
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_REQ_SHOW_FORM'| translate}}" ng-click="reqList.showForm(request)">
+ <i class="material-icons">exit_to_app</i>
+ {{'YANGMAN_REQ_SHOW_FORM'| translate}}
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_REQ_SHOW_SENT_DATA'| translate}}"
+ ng-click="reqList.showData(request)">
+ <i class="material-icons">call_made</i>
+ {{'YANGMAN_REQ_SHOW_JSON_DATA'| translate}}
+ </md-button>
+ </md-menu-item>
+ <md-menu-item ng-if="request.collection.length">
+ <md-button aria-label="{{'YANGMAN_REQ_DUPLICATE'| translate}}"
+ ng-click="reqList.showDgSaveReq($event, request, true)">
+ <i class="material-icons">control_point_duplicate</i>
+ {{'YANGMAN_REQ_DUPLICATE'| translate}}
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_REQ_DELETE'| translate}}" ng-click="reqList.showDgDeleteRequests($event, request)">
+ <i class="material-icons">delete</i>
+ {{'YANGMAN_REQ_DELETE'| translate}}
+ </md-button>
+ </md-menu-item>
+ </md-menu-content>
+</md-menu>
+<!-- /request submenu -->
--- /dev/null
+<md-dialog aria-label="Save to collection" ng-cloak>
+ <form name="dialog.saveReqForm">
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>{{( dialog.duplicate ? 'YANGMAN_REQS_DUPLICATE' : 'YANGMAN_REQS_SAVE_TO_COL')| translate}}</h2>
+ <span flex></span>
+ </div>
+ </md-toolbar>
+ <md-dialog-content style="width: 400px;">
+ <div class="md-dialog-content" layout="column">
+ <md-input-container>
+ <md-autocomplete
+ md-selected-item="dialog.selectedItem"
+ md-search-text="dialog.collectionName"
+ md-items="item in dialog.getColAutocomplete()"
+ md-floating-label="{{'YANGMAN_CREATING_COLLECTION'|translate}}"
+ md-item-text="item"
+ md-min-length="0"
+ ng-required="true">
+ <md-item-template>
+ <span md-highlight-text="dialog.collectionName" md-highlight-flags="^i">{{item}}</span>
+ </md-item-template>
+ <md-not-found>
+ <span ng-if="dialog.collectionName.length">
+ {{'YANGMAN_COLLECTION_NEW_COL_'| translate}} "{{dialog.collectionName}}" {{'YANGMAN_COLLECTION_WILL_BE_CREATED'| translate}}.
+ </span>
+ <span ng-if="dialog.collectionName.length === 0">
+ {{'YANGMAN_NO_COLLECTIONS'| translate}}
+ </span>
+ </md-not-found>
+ </md-autocomplete>
+ <input name="collectionName"
+ ng-model="dialog.collectionName"
+ ng-required="true" style="display: none;">
+ <div ng-messages="dialog.saveReqForm.collectionName.$error" multiple md-auto-hide="false">
+ <div ng-message="required">
+ {{'YANGMAN_COLLECTION_NAME_REQUIRED'| translate}}
+ </div>
+ </div>
+ </md-input-container>
+
+ </div>
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="dialog.cancel()">
+ {{'YANGMAN_CANCEL'| translate}}
+ </md-button>
+ <md-button ng-click="dialog.save()" ng-disabled="!dialog.saveReqForm.$valid">
+ {{'YANGMAN_SAVE'| translate}}
+ </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
--- /dev/null
+<md-dialog aria-label="{{'YANGMAN_PARAMETERS_ADMINISTRATION'| translate}}" ng-cloak>
+ <form name="paramsAdmin.paramsForm">
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>{{'YANGMAN_PARAMETERS_ADMINISTRATION'| translate}}</h2>
+ <span flex></span>
+ <md-button aria-label="{{'YANGMAN_CLOSE'| translate}}"
+ ng-click="paramsAdmin.close()">
+ <md-icon class="material-icons clickable" >
+ close
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_CLOSE'| translate}}</md-tooltip>
+ </md-button>
+ </div>
+ </md-toolbar>
+ <md-dialog-content class="paramsAdminDialog" layout="column">
+ <div class="md-dialog-content" layout="column">
+ <!-- top part for search and sort bar -->
+ <div class="paramsAdminDialog__searchBox" layout="row">
+
+ <!-- search icon, form, clear button -->
+ <md-icon class="material-icons">search</md-icon>
+ <input class=""
+ type="text"
+ flex
+ ng-change="paramsAdmin.filterChange()"
+ placeholder="{{'YANGMAN_SEARCH' | translate}}"
+ ng-model="paramsAdmin.search"
+ aria-invalid="false" />
+ <md-button aria-label="{{'YANGMAN_CLEAR_SEARCH'| translate}}"
+ ng-click="paramsAdmin.clearFilter()"
+ ng-if="paramsAdmin.search">
+ <md-icon class="material-icons clickable" >
+ close
+ </md-icon>
+ <md-tooltip md-direction="bottom">{{'YANGMAN_CLEAR_SEARCH'| translate}}</md-tooltip>
+ </md-button>
+ <!-- /search icon, form, clear button -->
+
+ <!-- sorting menu -->
+ <md-menu md-offset="35 15" layout-align="center start">
+ <md-button aria-label="{{'YANGMAN_SORT'| translate}}" class="" ng-click="$mdOpenMenu()">
+ <i class="material-icons">sort</i>
+ <md-tooltip md-direction="bottom">
+ {{'YANGMAN_SORTING' | translate}}
+ </md-tooltip>
+ </md-button>
+ <md-menu-content>
+ <!-- sort by name -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_PARAMS_KEY'| translate}}"
+ ng-click="paramsAdmin.sortBy('_name', '_value')">
+ {{'YANGMAN_SORT_BY'| translate}}
+ {{'YANGMAN_PARAMS_KEY'| translate}}
+ {{paramsAdmin.sortAsc ? 'YANGMAN_SORT_DESC' : 'YANGMAN_SORT_ASC' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- /sort by name -->
+
+ <!-- sort by value -->
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_PARAMS_VALUE'| translate}}"
+ ng-click="paramsAdmin.sortBy('_value', '_name')">
+ {{'YANGMAN_SORT_BY'| translate}}
+ {{'YANGMAN_PARAMS_VALUE'| translate}}
+ {{paramsAdmin.sortAsc ? 'YANGMAN_SORT_DESC' : 'YANGMAN_SORT_ASC' | translate}}
+ </md-button>
+ </md-menu-item>
+ <!-- /sort by value -->
+
+ </md-menu-content>
+ </md-menu>
+ <!-- /sorting menu -->
+
+ <!-- menu for import and export parameters -->
+ <input type="file" accept=".json" id="importParameters" on-read-file="paramsAdmin.importParameters($fileContent)">
+ <md-menu md-offset="35 15" layout-align="center start">
+ <md-button aria-label="{{ 'YANGMAN_PARAMS_IMPORT_EXPORT' | translate }}" ng-click="$mdOpenMenu()">
+ <i class="material-icons">import_export</i>
+ <md-tooltip md-direction="bottom">
+ {{ 'YANGMAN_PARAMS_IMPORT_EXPORT' | translate }}
+ </md-tooltip>
+ </md-button>
+ <md-menu-content>
+ <md-menu-item>
+ <md-button>
+ <label for="importParameters">
+ {{'YANGMAN_IMPORT_PARAMS'| translate}}
+ </label>
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button aria-label="{{'YANGMAN_EXPORT_PARAMETERS' | translate}}" ng-click="paramsAdmin.exportParameters()">
+ {{'YANGMAN_EXPORT_PARAMETERS' | translate}}
+ </md-button>
+ </md-menu-item>
+ </md-menu-content>
+ </md-menu>
+ <!-- /menu for import and export parameters -->
+
+ </div>
+
+ <md-divider></md-divider>
+ <!-- /top part for search and sort bar -->
+
+ <!-- parameters list -->
+ <md-content class="paramsAdminDialog__paramsList scrollableY" layout="column">
+
+ <div layout="row"
+ ng-repeat="param in paramsAdmin.parametersList.list |
+ filter: paramsAdmin.filterParam |
+ orderBy: paramsAdmin.sortFunc : !paramsAdmin.sortAsc
+ track by $index">
+ <!-- name input -->
+ <md-input-container>
+ <label>{{'YANGMAN_PARAM_KEY' | translate}}</label>
+ <input name="name_{{$index}}"
+ ng-model="param.name"
+ ng-required="param.value"
+ ng-change="paramsAdmin.validateNamesUnique()"
+ ng-focus="$last && paramsAdmin.createEmptyParam()"
+ autocomplete="off">
+ <div ng-messages="paramsAdmin.paramsForm['name_'+$index].$error" multiple md-auto-hide="false">
+ <div ng-message="required">
+ {{'YANGMAN_PARAM_KEY_REQUIRED'| translate}}
+ </div>
+ <div ng-message="unique">
+ {{'YANGMAN_PARAM_EXISTING_KEY'| translate}}
+ </div>
+ </div>
+ </md-input-container>
+ <!-- / name input -->
+
+ <!-- value input -->
+ <md-input-container flex>
+ <label>{{'YANGMAN_PARAM_VALUE' | translate}}</label>
+ <input ng-model="param.value" ng-focus="$last && paramsAdmin.createEmptyParam()">
+ </md-input-container>
+ <!-- /value input -->
+
+ <!-- remove param button -->
+ <md-button aria-label="{{'YANGMAN_REMOVE_PARAM' | translate}}"
+ class=""
+ ng-if="!$last"
+ ng-click="paramsAdmin.removeParam(param)">
+ <md-tooltip md-direction="bottom">
+ {{'YANGMAN_REMOVE_PARAM' | translate}}
+ </md-tooltip>
+ <i class="material-icons">close</i>
+ </md-button>
+ <!-- /remove param button -->
+
+
+ </div>
+ </md-content>
+ <!-- /parameters list -->
+
+ </div>
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="paramsAdmin.close()">
+ {{'YANGMAN_CLOSE'| translate}}
+ </md-button>
+ <md-button ng-click="paramsAdmin.save()" ng-disabled="!paramsAdmin.paramsForm.$valid">
+ {{'YANGMAN_SAVE'| translate}}
+ </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
--- /dev/null
+<!-- Header -->
+<section md-whiteframe="1"
+ class="yangmanModule__right-panel__header"
+ style="margin-bottom: 0px!important;"
+ ng-include src="globalViewPath + 'rightpanel/request-header.tpl.html'">
+</section>
+<!-- /Header -->
+
+<!--<section class="yangmanModule__right-panel__request-progress">-->
+ <!--<div class="yangmanModule__right-panel__request-progress__loading-container">-->
+ <!--<md-progress-linear md-mode="query"></md-progress-linear>-->
+ <!--<div class="bottom-block">-->
+ <!--<span>{{ 'YANGMAN_EXECUTING_REQUEST' | translate }}...</span>-->
+ <!--</div>-->
+ <!--</div>-->
+<!--</section>-->
+
+<!-- Form section -->
+<section class="yangmanModule__right-panel__form bottom-content"
+ ng-show="rightPanelSection === main.constants.DISPLAY_TYPE_FORM"
+ ng-if="node"
+ ng-controller="YangFormCtrl as yangForm">
+ <div ng-show="yangForm.errorMsg"><p class="error">{{ yangForm.errorMsg }}</p></div>
+ <div ng-include src="yangForm.viewPath + '/' + selectedDatastore.label + '/' + node.type+'.tpl.html'"></div>
+</section>
+<!-- /Form section -->
+
+<!-- JSON section -->
+<section class="yangmanModule__right-panel__req-data bottom-content"
+ ng-cloak
+ ng-show="rightPanelSection === main.constants.DISPLAY_TYPE_REQ_DATA">
+
+ <!-- Sent data -->
+ <div ng-controller="RequestDataCtrl as requestData"
+ layout="column"
+ ng-show="main.jsonView.sent"
+ ng-init="requestData.init('SENT')"
+ ng-class="{'half-size': main.jsonView.received && main.jsonView.sent}"
+ class="yangmanModule__right-panel__req-data__cm-SENT ym-resizable-s">
+
+ <section class="yangmanModule__right-panel__req-data__header" layout="row">
+ <h5 flex>{{'YANGMAN_SENT_DATA' | translate}}</h5>
+ <md-button ng-click="requestData.enlargeCMFont()">
+ <i class="material-icons bigger">text_format</i>
+ <i class="material-icons additional">arrow_drop_up</i>
+ <md-tooltip>
+ {{ 'YANGMAN_CM_ENLARGE_FONT_SIZE' | translate }}
+ </md-tooltip>
+ </md-button>
+ <md-button ng-click="requestData.reduceCMFont()">
+ <i class="material-icons smaller">text_format</i>
+ <i class="material-icons additional">arrow_drop_down</i>
+ <md-tooltip md-direction="bottom right">
+ {{ 'YANGMAN_CM_REDUCE_FONT_SIZE' | translate }}
+ </md-tooltip>
+ </md-button>
+ </section>
+ <div md-whiteframe="2" ng-include src="globalViewPath + 'rightpanel/request-data.tpl.html'"></div>
+ </div>
+
+ <!-- Received data -->
+ <div ng-controller="RequestDataCtrl as requestData"
+ ng-show="main.jsonView.received"
+ ng-init="requestData.init(main.constants.REQUEST_DATA_TYPE_RECEIVED)"
+ ng-class="{'half-size': main.jsonView.received && main.jsonView.sent}"
+ class="yangmanModule__right-panel__req-data__cm-RECEIVED ym-resizable-s">
+
+ <section class="yangmanModule__right-panel__req-data__header" layout="row">
+ <h5 flex>{{'YANGMAN_RECEIVED_DATA' | translate}}</h5>
+ <md-button ng-click="requestData.enlargeCMFont()">
+ <i class="material-icons bigger">text_format</i>
+ <i class="material-icons additional">arrow_drop_up</i>
+ <md-tooltip>
+ {{ 'YANGMAN_CM_ENLARGE_FONT_SIZE' | translate }}
+ </md-tooltip>
+ </md-button>
+ <md-button ng-click="requestData.reduceCMFont()">
+ <i class="material-icons smaller">text_format</i>
+ <i class="material-icons additional">arrow_drop_down</i>
+ <md-tooltip md-direction="bottom right">
+ {{ 'YANGMAN_CM_REDUCE_FONT_SIZE' | translate }}
+ </md-tooltip>
+ </md-button>
+ </section>
+ <div md-whiteframe="2" ng-include src="globalViewPath + 'rightpanel/request-data.tpl.html'"></div>
+ </div>
+</section>
+<!-- /JSON section -->
--- /dev/null
+<md-list flex>
+ <md-list-item ng-repeat="augmentation in node.augmentionGroups">
+ <md-switch ng-model="augmentations.getAugmentation(node, augmentation).expanded" aria-label="{{augmentation}}">
+ {{augmentation}}
+ </md-switch>
+ </md-list-item>
+
+</md-list>
\ No newline at end of file
--- /dev/null
+<div ng-controller="YMCaseCtrl as yangCase" ng-hide="yangCase.empty">
+ <!-- case's children -->
+ <div ng-repeat="node in case.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + node.type + '.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded"></div>
+</div>
--- /dev/null
+<div ng-controller="YMChoiceCtrl as yangChoice"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}">
+
+ <!-- choice title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element" ng-click="yangChoice.toggleExpanded()">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Choice label -->
+ <p class="top-element" ym-info-box node="node" ng-click="yangChoice.toggleExpanded()"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangChoice.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ <!-- Choice select -->
+ <md-input-container>
+ <md-select ng-model="node.choice" aria-label="Choice select">
+ <md-option ng-repeat="node in node.getChildren(null, null, constants.NODE_UI_DISPLAY) | filter:caseShowing" ng-value="node">
+ {{node.label}}
+ </md-option>
+ </md-select>
+ </md-input-container>
+ </div>
+
+ <!-- choice's children -->
+ <div ng-repeat="case in node.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + case.type +'.tpl.html'"
+ ng-show="node.choice.id === case.id && node.expanded"
+ ng-if="!(case.augmentationId && !augmentations.getAugmentation(case.parent, case.augmentationId).expanded)"></div>
+</div>
--- /dev/null
+<div ng-controller="YMContainerCtrl as yangContainer"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons"
+ class="top-icon top-element pointer"
+ ng-click="yangContainer.toggleExpanded()">
+
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element pointer"
+ ng-click="yangContainer.toggleExpanded()" ym-info-box node="node">
+
+ {{yangForm.getNodeName(node.localeLabel, node.label)}}
+ </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangContainer.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- container's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMInputCtrl as yangInput"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label"
+ ng-click="yangInput.toggleExpanded()">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangInput.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- output's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMLeafListCtrl as yangLeafList"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element" ng-click="yangLeafList.toggleExpanded()">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ng-click="yangLeafList.toggleExpanded()" ym-info-box node="node">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}}
+ </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangLeafList.isActionMenu()"
+ augmentations="augmentations"
+ add-list-item-func="yangLeafList.addListElem()"
+ add-list-item="true"
+ node="node"></yang-form-menu>
+ </div>
+
+ <div ng-repeat="elem in node.value" ng-show="node.expanded">
+ <!-- Leaf list values -->
+ <md-input-container md-no-float class="input-icon-container">
+ <!-- input -->
+ <input ng-change="yangLeafList.changed()" ng-model="elem.value" aria-label="{{elem.value}}">
+
+ <!-- remove Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-click="yangLeafList.removeListElem(elem)">
+ <md-tooltip md-direction="right">{{ 'REMOVE_ELEM' | translate }}</md-tooltip>
+ remove_circle_outline
+ </md-icon>
+ </md-input-container>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMLeafCtrl as yangLeaf"
+ layout="row"
+ layout-align="start {{yangLeaf.getLeafCentering()}}"
+ class="yangmanModule__right-panel__form__leaf-container {{yangLeaf.getLeafType()}}">
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangLeaf.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ <!-- Empty placeholder for better look -->
+ <div class="menu-placeholder" ng-if="!yangLeaf.isActionMenu() && !yangLeaf.isNodeInfo()"></div>
+
+ <div ng-controller="YMTypeCtrl as yangType"
+ ng-repeat="type in node.getChildren('type')"
+ ng-include="yangForm.viewPath + '/config/types/' + yangLeaf.getLeafType() + '.tpl.html'"
+ {{yangLeaf.getLeafType() === 'union' ? 'flex="grow"' : ''}}
+ layout="row">
+ </div>
+</div>
--- /dev/null
+<!-- previous item button -->
+<button ng-click="shiftDisplayPrev()"
+ ng-show="showPrevButton()"
+ tooltip="{{ 'YANGMAN_LIST_PREV_ITEM' | translate }}"
+ class="yangButton iconPrev"></button>
+
+<!-- item list -->
+<div class="listButtonWrapper"
+ ng-repeat="offset in displayOffsets"
+ ng-if="currentDisplayIndex + offset > -1 && node.filteredListData.length > currentDisplayIndex + offset">
+
+ <button class="btn btn-like-tab {{ (currentDisplayIndex + offset === node.actElemIndex ? 'btn-selected':'') }}"
+ ng-click="node.changeActElementData(currentDisplayIndex + offset,false)"
+ tooltip="{{getListName(offset, false).tooltip}}">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}} {{ getListName(offset, true).name }}
+ </button>
+
+ <!-- delete button -->
+ <button class="yangButton iconClose"
+ tooltip="{{ 'YANGMAN_LIST_DELETE_ITEM' | translate }}"
+ ng-click='removeListElem(currentDisplayIndex + offset,true)'></button>
+
+ <!-- duplicate indicator -->
+ <button class="yangButton iconDanger"
+ tooltip="{{ 'YANGMAN_LIST_INDEX_DUPLICATE' | translate }}"
+ ng-show="node.doubleKeyIndexes.indexOf(currentDisplayIndex + offset)>-1"></button>
+</div>
+
+<!-- next item button -->
+<button ng-click="shiftDisplayNext('filteredListData')"
+ ng-show="showNextButton('filteredListData')"
+ tooltip="{{ 'YANGMAN_LIST_NEXT_ITEM' | translate }}"
+ class="yangButton iconNext"></button>
--- /dev/null
+<div ng-controller="YMListCtrl as yangList"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-init="yangList.init()">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-click="yangList.toggleExpanded()">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- list label -->
+ <p class="top-element pointer list-label" ng-click="yangList.toggleExpanded()" ym-info-box node="node">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}}
+ </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangList.isActionMenu()"
+ augmentations="augmentations"
+ add-list-item-func="yangList.addListElem()"
+ add-list-item="!yangList.disableAddingListElement"
+ yang-form="yangForm"
+ yang-list="yangList"
+ node="node"></yang-form-menu>
+
+ <!--<ng-include src="currentPath+'/filter.tpl.html'"></ng-include>-->
+
+ <section layout="row"
+ layout-align="start center"
+ class="yangmanModule__right-panel__form__list__paginator"
+ ng-include="yangForm.viewPath + '/list-data-top.tpl.html'"
+ ng-if="!(node.filteredListData && node.filteredListData.length)"></section>
+
+ <div class="listItemWrapper"
+ ng-include="yangForm.viewPath + '/config/list-filtered-data-top.tpl.html'"
+ ng-if="(node.filteredListData && node.filteredListData.length)"></div>
+
+ </div>
+
+ <!-- list's children -->
+ <div ng-if="node.actElemStructure" ng-show="node.expanded">
+ <div ng-repeat="node in node.actElemStructure.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMOutputCtrl as yangOutput"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label"
+ ng-click="yangOutput.toggleExpanded()">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangOutput.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- output's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMRpcCtrl as yangRpc"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label"
+ ng-click="yangRpc.toggleExpanded()">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangRpc.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- Rpc's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + node.type + '.tpl.html'"></div>
+ </div>
+</div>
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<section ng-controller="YMTypeBitCtrl as yangTypeBit"
+ layout="row"
+ flex="50"
+ class="md-whiteframe-z2 box-container"
+ layout-wrap
+ layout-padding>
+
+ <md-checkbox ng-model="type.bitsValues[$index]"
+ ng-repeat="bit in type.getChildren('bit')"
+ ng-true-value="1"
+ ng-false-value="0"
+ ng-change="yangTypeBit.valueChanged()"
+ ng-disabled="{{ yangOutput.notEditable }}"
+ aria-label="{{bit.label}}">
+ {{bit.label}}
+ </md-checkbox>
+</section>
--- /dev/null
+<section ng-controller="YMTypeBooleanCtrl as yangTypeBolean" layout="row" class="layout-row flex-center" flex>
+ <span class="mr8">F</span>
+ <md-switch ng-model="node.value"
+ id="{{ node.label + node.id }}"
+ aria-label="Boolean"
+ ng-disabled="{{ yangOutput.notEditable }}">
+ </md-switch>
+ <span>T</span>
+</section>
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
+
--- /dev/null
+<section ng-controller="YMTypeEmptyCtrl as yangTypeEmpty"
+ layout="row"
+ flex="50"
+ class="md-whiteframe-z2 box-container"
+ layout-wrap
+ layout-padding>
+
+ <md-checkbox ng-model="type.emptyValue"
+ ng-true-value="1"
+ ng-false-value="0"
+ ng-change="yangTypeEmpty.valueChanged()"
+ ng-disabled="{{ yangOutput.notEditable }}"
+ aria-label="{{type.label}}"></md-checkbox>
+</section>
--- /dev/null
+<md-input-container ng-controller="YMTypeEnumCtrl as yangTypeEnum">
+ <md-select ng-model="type.selEnum" md-on-close="yangTypeEnum.valueChanged()" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-option ng-repeat="enum in type.getChildren('enum')" ng-value="enum">
+ {{enum.label}}
+ </md-option>
+ </md-select>
+</md-input-container>
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-input-container md-no-float>
+ <input ng-change="yangType.valueChanged()" ng-model="node.value" aria-label="{{node.value}}" placeholder="{{type.label}}" ng-disabled="{{ yangOutput.notEditable }}">
+ <md-tooltip md-direction="top">{{type.label}}</md-tooltip>
+</md-input-container>
+
+<md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-show="type.errors.length > 0">
+ <md-tooltip md-direction="top">{{type.errors.join('\n')}}</md-tooltip>
+ error_outline
+</md-icon>
\ No newline at end of file
--- /dev/null
+<md-content flex="nogrow" md-whiteframe="2" class="box-container union">
+ <md-tabs md-dynamic-height
+ md-border-bottom
+ md-no-pagination
+ md-stretch-tabs="always"
+ class="union-tabs">
+ <md-tab ng-repeat="type in type.getChildren('type') track by $index">
+ <md-tab-label>
+ <!--<md-tooltip md-direction="top">{{type.label}}</md-tooltip>-->
+ {{type.label}}
+ </md-tab-label>
+ <md-tab-body>
+ <md-content class="md-padding"
+ ng-include="yangForm.viewPath + '/config/types/' + type.label + '.tpl.html'"></md-content>
+ </md-tab-body>
+ </md-tab>
+ </md-tabs>
+</md-content>
--- /dev/null
+<!-- Previous button -->
+<button ng-click="yangList.shiftDisplayPrev()"
+ ng-show="yangList.showPrevButton()">
+ <md-icon class="material-icons">{{yangList.showPrevButton() ? 'arrow_back' : ''}}</md-icon>
+ <md-tooltip md-direction="top">{{ 'YANGMAN_LIST_PREV_ITEM' | translate }}</md-tooltip>
+</button>
+
+<section ng-repeat="offset in yangList.displayOffsets" class="yangmanModule__right-panel__form__list-item"
+ layout="row" layout-align="start center"
+ ng-if="yangList.currentDisplayIndex + offset > -1 && node.listData.length > yangList.currentDisplayIndex + offset">
+
+ <!-- label -->
+ <md-tab-item class="md-tab pointer" ng-click="node.changeActElementData(yangList.currentDisplayIndex + offset)"
+ ng-class="{'': yangList.currentDisplayIndex + offset === node.actElemIndex}">
+ <div layout="row">
+ <span flex="grow">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}} {{ yangList.getListName(offset, true).name }}
+ </span>
+ </div>
+
+ <md-tooltip md-direction="top" ng-if="yangList.getListName(offset, false).tooltip.length">
+ {{yangList.getListName(offset, false).tooltip}}
+ </md-tooltip>
+
+ <md-ink-bar class="custom" ng-if="yangList.currentDisplayIndex + offset === node.actElemIndex"></md-ink-bar>
+ </md-tab-item>
+
+ <!-- remove button -->
+ <md-icon md-font-set="material-icons"
+ class="pointer"
+ ng-click="yangList.removeListElem(yangList.currentDisplayIndex + offset,false)"
+ ng-if="(selectedDatastore.label === yangList.constants.DATA_STORE_CONFIG ||
+ selectedDatastore.label === yangList.constants.DATA_STORE_OPERATIONS) && !yangList.disableAddingListElement">
+ <md-tooltip md-direction="top">{{ 'YANGMAN_LIST_DELETE_ITEM' | translate }}</md-tooltip>
+ remove_circle_outline
+ </md-icon>
+
+ <!-- duplicated key -->
+ <md-icon md-font-set="material-icons"
+ ng-show="node.doubleKeyIndexes.indexOf(yangList.currentDisplayIndex + offset) > -1"
+ ng-if="selectedDatastore.label === yangList.constants.DATA_STORE_CONFIG">
+ <md-tooltip md-direction="top">{{ 'YANGMAN_LIST_INDEX_DUPLICATE' | translate }}</md-tooltip>
+ error_outline
+ </md-icon>
+</section>
+
+<!-- Next button -->
+<button ng-click="yangList.shiftDisplayNext('listData')"
+ ng-show="yangList.showNextButton('listData')">
+ <md-icon class="material-icons">arrow_forward</md-icon>
+ <md-tooltip md-direction="top">{{ 'YANGMAN_LIST_NEXT_ITEM' | translate }}</md-tooltip>
+</button>
--- /dev/null
+<div ng-controller="YMCaseCtrl as yangCase" ng-show="case.isFilled() && yangCase.empty">
+ <!-- case's children -->
+ <div ng-repeat="node in case.getChildren(null,null,constants.NODE_UI_DISPLAY)"
+ ng-include="yangForm.viewPath + '/operational/' + node.type + '.tpl.html'"></div>
+</div>
--- /dev/null
+<div ng-controller="YMChoiceCtrl as yangChoice"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-show="node.isFilled()">
+
+ <!-- choice title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element" ng-click="yangChoice.toggleExpanded()">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Choice label -->
+ <p class="top-element" ym-info-box node="node" ng-click="yangChoice.toggleExpanded()">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}}
+ </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangChoice.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ <!-- Choice select -->
+ <md-input-container>
+ <input ng-model="node.choice.label" aria-label="{{node.choice.label}}" ng-disabled="true">
+ </md-input-container>
+ </div>
+
+ <!-- choice's children -->
+ <div ng-repeat="case in node.getChildren(null,null,constants.NODE_UI_DISPLAY)"
+ ng-include="yangForm.viewPath + '/operational/' + case.type +'.tpl.html'"
+ ng-show="node.choice.id === case.id && node.expanded"
+ ng-if="!(case.augmentationId && !augmentations.getAugmentation(case.parent, case.augmentationId).expanded)"></div>
+</div>
--- /dev/null
+<div ng-controller="YMContainerCtrl as yangContainer"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-show="node.isFilled()">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons"
+ class="top-icon top-element pointer"
+ ng-click="yangContainer.toggleExpanded()">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element pointer" ng-click="yangContainer.toggleExpanded()" ym-info-box node="node">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}}
+ </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangContainer.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- container's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY)"
+ ng-include="yangForm.viewPath + '/operational/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMInputCtrl as yangInput"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-show="node.isFilled()">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label"
+ ng-click="yangInput.toggleExpanded()">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangInput.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- output's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY)"
+ ng-include="yangForm.viewPath + '/operational/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMLeafListCtrl as yangLeafList"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-show="node.isFilled()">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element" ng-click="yangLeafList.toggleExpanded()">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node" ng-click="yangLeafList.toggleExpanded()">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}}
+ </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangLeafList.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+ </div>
+
+ <div ng-repeat="elem in node.value" ng-show="node.expanded">
+ <!-- Leaf list values -->
+ <md-input-container md-no-float class="input-icon-container">
+ <!-- input -->
+ <input ng-model="elem.value" aria-label="{{elem.value}}" ng-disabled="true">
+ </md-input-container>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMLeafCtrl as yanfLeaf"
+ layout="row"
+ layout-align="start center"
+ class="yangmanModule__right-panel__form__leaf-container"
+ ng-show="node.isFilled()">
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yanfLeaf.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ <!-- Empty placeholder for better look -->
+ <div class="menu-placeholder" ng-if="!yanfLeaf.isActionMenu() && !yanfLeaf.isNodeInfo()"></div>
+
+ <md-input-container>
+ <input ng-model="node.value" aria-label="{{node.value}}" ng-disabled="true">
+ </md-input-container>
+</div>
--- /dev/null
+<!-- previous item button -->
+<button ng-click="shiftDisplayPrev()"
+ ng-show="showPrevButton()"
+ tooltip="{{ 'YANGMAN_LIST_PREV_ITEM' | translate }}"
+ class="yangButton iconPrev"></button>
+
+<!-- item list -->
+<div class="listButtonWrapper"
+ ng-repeat="offset in displayOffsets"
+ ng-if="currentDisplayIndex + offset > -1 && node.filteredListData.length > currentDisplayIndex + offset">
+
+ <button class="btn btn-like-tab {{ (currentDisplayIndex + offset === node.actElemIndex ? 'btn-selected':'') }}"
+ ng-click="node.changeActElementData(currentDisplayIndex + offset,false)"
+ tooltip="{{getListName(offset, false).tooltip}}">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}} {{ getListName(offset, true).name }}
+ </button>
+</div>
+
+<!-- next item button -->
+<button ng-click="shiftDisplayNext('filteredListData')"
+ ng-show="showNextButton('filteredListData')"
+ tooltip="{{ 'YANGMAN_LIST_NEXT_ITEM' | translate }}"
+ class="yangButton iconNext"></button>
--- /dev/null
+<div ng-controller="YMListCtrl as yangList"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-show="node.isFilled()">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="container-label">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element pointer" ng-click="yangList.toggleExpanded()">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- list label -->
+ <p class="top-element pointer list-label" ng-click="yangList.toggleExpanded()" ym-info-box node="node">
+ {{yangForm.getNodeName(node.localeLabel, node.label)}}
+ </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangList.isActionMenu()"
+ augmentations="augmentations"
+ yang-form="yangForm"
+ yang-list="yangList"
+ node="node"></yang-form-menu>
+
+ <!--<ng-include src="currentPath+'/filter.tpl.html'"></ng-include>-->
+
+ <section layout="row"
+ layout-align="start center"
+ class="yangmanModule__right-panel__form__list__paginator"
+ ng-include="yangForm.viewPath + '/list-data-top.tpl.html'"
+ ng-if="!(node.filteredListData && node.filteredListData.length)"></section>
+
+ <div class="listItemWrapper"
+ ng-include="yangForm.viewPath + '/config/list-filtered-data-top.tpl.html'"
+ ng-if="(node.filteredListData && node.filteredListData.length)"></div>
+
+ </div>
+
+ <!-- list's children -->
+ <div ng-if="node.actElemStructure" ng-show="node.expanded">
+ <div ng-repeat="node in node.actElemStructure.getChildren(null,null,constants.NODE_UI_DISPLAY)"
+ ng-include="yangForm.viewPath + '/operational/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
+
--- /dev/null
+<div ng-controller="YMOutputCtrl as yangOutput"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-show="node.isFilled()">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label"
+ ng-click="yangOutput.toggleExpanded()">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangOutput.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- output's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY)"
+ ng-include="yangForm.viewPath + '/operational/' + node.type+'.tpl.html'"
+ ng-hide="node.augmentationId && !augmentations.getAugmentation(node.parent, node.augmentationId).expanded">
+ </div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMRpcCtrl as yangRpc"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}"
+ ng-show="node.isFilled()">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label"
+ ng-click="yangRpc.toggleExpanded()">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangRpc.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- Rpc's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY)"
+ ng-include="yangForm.viewPath + '/operational/' + node.type + '.tpl.html'"></div>
+ </div>
+</div>
--- /dev/null
+<div ng-controller="YMRpcCtrl as yangRpc"
+ class="yangmanModule__right-panel__form__element-container"
+ ng-class="{'expanded' : node.expanded}">
+
+ <!-- container title -->
+ <div layout="row"
+ layout-align="start center"
+ class="pointer container-label"
+ ng-click="yangRpc.toggleExpanded()">
+
+ <!-- Expand Icon -->
+ <md-icon md-font-set="material-icons" class="top-icon top-element">
+ <md-tooltip md-direction="left">{{ 'YANGMAN_SHOW_HIDE_CON' | translate }}</md-tooltip>
+ {{node.expanded ? 'keyboard_arrow_down':'keyboard_arrow_right'}}
+ </md-icon>
+
+ <!-- Container label -->
+ <p class="top-element" ym-info-box node="node"> {{yangForm.getNodeName(node.localeLabel, node.label)}} </p>
+
+ <!-- Action menu -->
+ <yang-form-menu is-action-menu="yangRpc.isActionMenu()"
+ augmentations="augmentations"
+ node="node"></yang-form-menu>
+
+ </div>
+
+ <!-- Rpc's children -->
+ <div ng-if="node.expanded">
+ <div ng-repeat="node in node.getChildren(null,null,constants.NODE_UI_DISPLAY) | ymOnlyConfigElem"
+ ng-include="yangForm.viewPath + '/config/' + node.type + '.tpl.html'"></div>
+ </div>
+</div>
--- /dev/null
+<textarea ng-model="requestData.data"
+ ui-codemirror
+ ui-codemirror-opts="requestData.dataEditorOptions"
+ class="codemirror-container">
+</textarea>
+
+<div class="paramsBox" ng-show="requestData.paramsArray.length">
+ <div ng-repeat="param in requestData.paramsArray" class="line">
+ <strong><<{{param.name}}>></strong> : <span>{{param.value !== undefined ? param.value : 'YANGMAN_PARAM_DONT_REPLACE' | translate}}</span>
+ </div>
+</div>
--- /dev/null
+<md-content layout="column" layout-wrap class="md-padding" ng-controller="RequestHeaderCtrl as requestHeader">
+ <section layout="row">
+ <!-- Methods selector -->
+ <md-input-container flex="initial">
+ <md-select ng-model="requestHeader.selectedOperation"
+ md-on-close="requestHeader.setJsonView()"
+ placeholder="{{'YANGMAN_SEL_METHOD' | translate}}">
+
+ <md-option ng-value="operation" ng-repeat="operation in requestHeader.selectedOperationsList">
+ {{ operation }}
+ </md-option>
+ </md-select>
+ </md-input-container>
+
+ <!-- Request url input -->
+ <section flex layout="row" layout-wrap>
+ <md-input-container flex md-no-float ng-if="rightPanelSection === requestHeader.constants.DISPLAY_TYPE_REQ_DATA">
+ <input type="text"
+ ng-model="requestHeader.requestUrl"
+ placeholder="{{'YANGMAN_REQ_URL' | translate}}"
+ spellcheck="false">
+ </md-input-container>
+
+ <div ng-repeat="pathElem in selectedSubApi.pathArray"
+ flex="nogrow"
+ layout="row"
+ ng-if="rightPanelSection === requestHeader.constants.DISPLAY_TYPE_FORM">
+
+ <md-input-container flex="nogrow" md-no-float class="input-span nrp" >
+ <span class="md-input" disabled>
+ {{(pathElem.moduleChanged ? '/' + pathElem.module + ':' : '/') + pathElem.name}}
+ {{pathElem.hasIdentifier() ? '/' : ''}}
+ </span>
+ </md-input-container>
+
+ <!-- Identifier's inputs -->
+ <md-input-container flex="nogrow" md-no-float
+ ng-repeat="identifier in pathElem.identifiers"
+ ng-show="pathElem.hasIdentifier()"
+ layout="column"
+ class="nrp">
+
+ <input type="text"
+ class="input-identifier"
+ ng-change="requestHeader.fillNodeData(pathElem, identifier)"
+ ng-model="identifier.value"
+ aria-label="{{identifier.value}}"
+ ng-class="{'md-has-error': !identifier.value.length}"
+ spellcheck="false">
+ <!-- input error message -->
+ <div ng-show="!identifier.value.length" class="md-custom-error">
+ {{'YANGMAN_INPUT_REQUIRED' | translate}}
+ </div>
+ </md-input-container>
+ </div>
+
+ <md-input-container flex md-no-float
+ ng-if="rightPanelSection === requestHeader.constants.DISPLAY_TYPE_FORM"
+ class="input-span">
+
+ <input type="text"
+ placeholder="{{!selectedSubApi ? ('YANGMAN_REQ_URL' | translate) : ''}}"
+ ng-disabled="true">
+ </md-input-container>
+ </section>
+
+ <!-- Action buttons -->
+ <md-input-container flex="nogrow" layout="row" layout-align="start start" class="action-buttons">
+ <!-- Execute action button -->
+ <md-button class="md-raised md-primary has-progress"
+ ng-click="requestHeader.prepareDataAndExecute(
+ main.modulesTreeDisplayed() ? main.leftPanelShowModule : null
+ )">
+ {{'YANGMAN_SEND' | translate}}
+ </md-button>
+
+ <!-- Save request -->
+ <md-button class="md-raised md-warn" ng-click="requestHeader.saveRequestToCollection($event)">
+ {{'YANGMAN_SAVE' | translate}}
+ </md-button>
+
+ <!-- Parameters button -->
+ <md-button class="md-raised" ng-click="requestHeader.showParamsAdmin($event)">
+ {{'YANGMAN_PARAMETERS' | translate}}
+ </md-button>
+
+ <!-- sub api custom functionality menu -->
+ <md-menu ng-show="selectedSubApi.custFunct.length || requestHeader.selectedPluginsButtons.length">
+ <md-button aria-label="Open demo menu" class="md-icon-button" ng-click="$mdOpenMenu($event)">
+ <md-icon md-font-set="material-icons">more_vert</md-icon>
+ <md-tooltip md-direction="top">{{ 'YANGMAN_PLUGINS_MENU' | translate}}</md-tooltip>
+ </md-button>
+
+ <md-menu-content>
+ <!-- plugins buttons -->
+ <md-menu-item ng-repeat="pluginFunctionality in selectedSubApi.custFunct"
+ ng-hide="requestHeader.selectedPlugin">
+ <md-button ng-click="requestHeader.executePluginFunctionality(pluginFunctionality)">
+ {{ pluginFunctionality.label | translate }}
+ </md-button>
+ </md-menu-item>
+
+ <!-- plugin own buttons -->
+ <md-menu-item ng-repeat="button in requestHeader.selectedPluginsButtons" ng-show="button.show()">
+ <md-button ng-click="button.onclick()">
+ {{ button.label | translate }}
+ </md-button>
+ </md-menu-item>
+ </md-menu-content>
+ </md-menu>
+ </md-input-container>
+ </section>
+
+ <md-divider flex="grow"></md-divider>
+
+ <section layout="row" layout-align="center center" class="status-bar">
+ <!-- Data type switcher - radio button -->
+ <md-radio-group ng-model="requestHeader.selectedShownDataType"
+ class="type-switcher"
+ flex="50"
+ layout="row"
+ layout-align="start center"
+ ng-change="requestHeader.changeDataType()">
+ <md-radio-button value="form" aria-label="{{'YANGMAN_FORM' | translate}}">
+ {{'YANGMAN_FORM' | translate}}
+ </md-radio-button>
+
+ <md-radio-button value="req-data" aria-label="{{'YANGMAN_JSON' | translate}}">
+ {{'YANGMAN_JSON' | translate}}
+ </md-radio-button>
+ </md-radio-group>
+
+ <!-- Request info box -->
+ <md-content flex="50"
+ layout="row"
+ layout-align="end center"
+ class="status-text">
+
+ <!-- Status -->
+ <span flex="30">
+ {{'YANGMAN_STATUS' | translate}}:
+ <span ng-if="requestHeader.statusObj && requestHeader.statusObj.statusText">
+ {{requestHeader.statusObj.status}} {{requestHeader.statusObj.statusText}}
+ </span>
+ <span ng-if="!(requestHeader.statusObj && requestHeader.statusObj.statusText)">
+ ...
+ </span>
+ </span>
+
+ <!-- Request time -->
+ <span flex="30">
+ {{'YANGMAN_TIME' | translate}}:
+ <span ng-if="requestHeader.statusObj && requestHeader.statusObj.time">
+ {{requestHeader.statusObj.time}} ms
+ </span>
+ <span ng-if="!(requestHeader.statusObj && requestHeader.statusObj.time)">
+ ...
+ </span>
+ </span>
+ </md-content>
+ </section>
+</md-content>
+<md-progress-linear md-mode="indeterminate" ng-show="main.executingRequestProgress"></md-progress-linear>
--- /dev/null
+<div class="main yangmanModule row" ui-view></div>
--- /dev/null
+define([], function () {
+ 'use strict';
+
+ angular.module('app.yangman').filter('ymOnlyConfigElem', YmOnlyConfigElemFilter);
+
+ YmOnlyConfigElemFilter.$inject = ['NodeUtilsService'];
+
+ function YmOnlyConfigElemFilter(NodeUtilsService){
+ return function (nodes){
+ if (nodes.length) {
+ nodes = nodes.filter(function (n){
+ return NodeUtilsService.isOnlyOperationalNode(n);
+ });
+ }
+
+ return nodes;
+ };
+ }
+
+});
--- /dev/null
+// general
+@fontColor : #505050;
+@fontColorLight: #a9a9a9;
+@fontHighlight: orange;
+@listBackColor: #f8f8f8;
+@listActiveColor: #E7E7E7;
+@appBackColor: #ffffff;
+@unactiveTabFontColor: #a9a9a9;
+@colorActive: rgb(64,196,255);
+@popupHeaderColor: #ffffff;
+
+// yangman
+@leftPanelBackColor: #f3f3f3;
+@infoBoxBackColor: rgba(255, 255, 255, 0.25);
+@infoBoxBorderColor: #aad1f9;
+@dataStoreListHoverColor: #dadada;
+@dataStoreListShadowColor: rgba(0,0,0,.14);
+@dataStoreListBorderColor: rgba(0,0,0,0.12);
+@dashedBorderColor: rgba(0,0,0,0.54);
+@inputColor: rgba(0,0,0,0.87);
+@reqMethodGet: #63d33b;
+@reqMethodPut: #6fbad3;
+@reqMethodPost: #ea9c30;
+@reqMethodDelete: #eabb2f;
+@reqError: #ff0000;
+@darkBlueColor: rgb(33,150,243);
+
+// helpers
+.pointer{
+ cursor: pointer;
+ outline: 0 none;
+}
+
+.no-wrap{
+ white-space: nowrap;
+}
+
+.text-center{
+ text-align: center;
+}
+
+.text-left{
+ text-align: left;
+}
+
+.h100{
+ height: 100%;
+}
+
+.mb30{
+ margin-bottom: 30px;
+}
+
+.mr8{
+ margin-right: 8px;
+}
+
+.nrp{
+ padding-right: 0!important;
+}
+
+.flex-center {
+ align-items: center;
+ justify-content: center;
+}
+
+// general
+.md-open-menu-container{
+ span{
+ color: @fontColor;
+ }
+
+ h5{
+ margin: 0 16px;
+ color: @unactiveTabFontColor;
+
+ md-icon{
+ color: @unactiveTabFontColor;
+ font-size: 18px;
+ }
+ }
+
+ md-menu-content{
+ .info-box{
+ position: absolute;
+ left: 100%;
+ top: 0;
+ margin-left: 10px;
+ min-width: 300px;
+ padding: 0;
+ z-index: 10;
+ background: #fff;
+ -webkit-transition: all 150ms linear;
+ -moz-transition: all 150ms linear;
+ -ms-transition: all 150ms linear;
+ -o-transition: all 150ms linear;
+ transition: all 150ms linear;
+ opacity: 1;
+ max-height: 300px;
+ overflow-y: auto;
+ overflow-x: hidden;
+
+ &__padding{
+ padding: 16px;
+ }
+
+ &.ng-hide{
+ opacity: 0;
+ }
+ }
+ }
+
+ svg {
+ border: none;
+ border-radius: 0px;
+ background-image: none;
+ }
+
+ .icon-wrapper{
+ padding: 0 16px;
+ }
+}
+
+.md-select-menu-container{
+ z-index: 1000;
+}
+
+.svg-icon{
+ width: 24px;
+ height: 24px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ color: @dashedBorderColor;
+}
+
+md-ink-bar.custom{
+ width: 100%;
+ color: @colorActive;
+ left: 0;
+ background: @colorActive;
+}
+
+button{
+ label{
+ font-weight: normal;
+ }
+}
+
+.ui-resizable-e{
+ cursor: e-resize;
+ height: 100%;
+ width: 7px;
+ top: 0;
+ position: absolute;
+ right: 0;
+}
+
+md-dialog{
+ md-autocomplete{
+ height: 50px !important;
+ }
+}
+
+.info-box-container{
+ position: relative;
+
+ &__hover-wrapper{
+ display: inline-block;
+ width: 100%;
+ }
+
+ .info-box{
+ position: absolute;
+ left: 90%;
+ top: 0;
+ margin-left: 10px;
+ margin-bottom: 10px;
+ min-width: 300px;
+ padding: 0;
+ z-index: 10;
+ background: #fff;
+ -webkit-transition: all 150ms linear;
+ -moz-transition: all 150ms linear;
+ -ms-transition: all 150ms linear;
+ -o-transition: all 150ms linear;
+ transition: all 150ms linear;
+ opacity: 1;
+ max-height: 300px;
+ overflow-y: auto;
+ overflow-x: hidden;
+
+ &__padding{
+ padding: 16px;
+ }
+
+ &.ng-hide{
+ opacity: 0;
+ }
+
+ span{
+ color: @fontColor;
+ }
+ }
+
+ md-menu-divider{
+ margin-top: 4px;
+ margin-bottom: 4px;
+ height: 1px;
+ min-height: 1px;
+ max-height: 1px;
+ width: 100%;
+ background-color: @dataStoreListBorderColor;
+ display: block;
+ }
+}
+
+md-input-container{
+ position: relative;
+
+ input.md-has-error{
+ border-color: @reqError!important;
+ }
+
+ .md-custom-error{
+ color: @reqError;
+ margin-top: 4px;
+ margin-left: 3px;
+ font-size: 11px;
+ line-height: 14px;
+ -webkit-order: 3;
+ -ms-flex-order: 3;
+ order: 3;
+ }
+}
+
+.md-dialog-container{
+ z-index: 99;
+}
+
+// yangman
+.yangmanModule{
+ background-color: @appBackColor;
+ color: @fontColor;
+ height: 100%;
+
+ .ui-resizable-s{
+ height: 13px;
+ }
+
+ .box-container{
+ padding: 16px;
+ margin: 8px 0;
+ }
+
+ .historyTab{
+ height: calc(~'100% - 62px');
+ }
+
+ .collectionsTab{
+ height: calc(~'100% - 62px');
+ }
+
+
+ p{
+ margin: 0;
+ }
+
+ h1, h2, h3, h4, h5, h6{
+ color: @fontColor;
+ }
+
+ .scrollableY{
+ overflow-y: auto;
+ height: 100%;
+ }
+
+ .scrollableX{
+ overflow-x: auto;
+ //width: 100%;
+ }
+
+ .highlight{
+ color: @darkBlueColor;
+ }
+ md-tabs-content-wrapper{
+ top: 0!important;
+ }
+
+ // modules switcher -> list && detail
+ .arrow-switcher{
+ position: absolute;
+ top: 2px;
+ cursor: pointer;
+ outline: 0 none;
+ z-index: 10;
+ font-size: 2.5em;
+ left: -11px;
+ -webkit-transition: all 250ms ease-out;
+ -moz-transition: all 250ms ease-out;
+ -ms-transition: all 250ms ease-out;
+ -o-transition: all 250ms ease-out;
+ transition: all 250ms ease-out;
+
+ &__left{
+ //right: -11px;
+ left: calc(~'100% - 24px');
+ -moz-transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ transform: rotate(180deg);
+ }
+
+ &.ng-hide{
+ opacity: 0;
+ }
+ }
+
+ md-dialog{
+ h2{
+ color: @popupHeaderColor;
+ }
+
+ &-actions{
+ button{
+ span{
+ color: @fontColor;
+ }
+ }
+ }
+
+
+ }
+ // left panel
+ &__left-panel{
+ overflow-x: hidden;
+ background: @leftPanelBackColor;
+ position: relative;
+
+ &__search{
+ padding: 10px 13px;
+ background: @listBackColor;
+ min-height: 62px;
+
+ .md-errors-spacer{
+ display: none;
+ }
+
+ md-icon{
+ color: @dashedBorderColor;
+ }
+
+ .collection-button-container {
+ margin-top: 6px;
+ }
+
+ button {
+ margin: 0;
+ min-width: 35px;
+ }
+
+ md-menu button {
+ margin-top: 6px;
+ }
+
+
+
+
+
+ .md-has-icon.modules-list-search{
+ padding: 2px 25px;
+ margin: 0;
+
+ .md-input{
+ width: auto;
+ order: 0;
+ }
+
+ button{
+ margin: 0;
+ padding: 0;
+ min-width: 0;
+ min-height: 0;
+ line-height: normal;
+
+ &:hover, &:focus, &:active, &:visited{
+ background: transparent;
+ }
+
+ .md-ripple-container{
+ display: none;
+ }
+ }
+ }
+ }
+
+ md-tabs,
+ md-tab-content > div,
+ md-content,
+ .h100{
+ height: 100%;
+ }
+
+ md-tabs-canvas{
+ border-bottom: 1px solid #dbdbdb;
+ padding-top: 30px;
+ height: 78px;
+ }
+
+ md-ink-bar{
+ height: 4px;
+ }
+
+ md-content{
+ background: transparent;
+ }
+
+ .md-tab{
+ span{
+ color: @unactiveTabFontColor;
+ }
+
+ &.md-active{
+ span{
+ color: @fontColor;
+ }
+ }
+ }
+
+ &__detail-list-tabs-container{
+ > md-tabs-wrapper{
+ display: none;
+ }
+
+ .inline-tabs > md-tabs-wrapper{
+ display: inline;
+ }
+ }
+
+ .searchBox{
+ height: auto;
+ padding: 10px 13px;
+ font-size: 14px;
+
+ #importCollection{
+ display: none;
+ }
+
+ label{
+ margin-bottom: 0;
+ }
+
+ md-icon.clickable{
+ cursor: pointer;
+ }
+
+ #importParameters{
+ display: none;
+ }
+
+ > button{
+ margin: 6px 0 0 0;
+ height: 30px;
+ min-width: 35px;
+ padding: 0;
+ }
+
+ md-menu{
+ margin: 0;
+ height: 30px;
+ min-width: 35px;
+ padding: 0;
+
+ > button{
+ min-width: 35px;
+ }
+ }
+
+
+ }
+
+ //loading panel
+ &__loading-container {
+ display: block;
+ position: relative;
+ border: 2px solid @infoBoxBorderColor;
+ transition: opacity 0.1s linear;
+ border-top: 0px;
+ margin: 10px;
+
+ .bottom-block {
+ display: block;
+ position: relative;
+ background-color: @infoBoxBackColor;
+ height: 85px;
+
+ > span {
+ display: inline-block;
+ margin-top: 10px;
+ padding: 25px;
+ font-size: 0.9em;
+ }
+ }
+ }
+ }
+
+ // right panel
+ &__right-panel{
+ height: 100%;
+
+ .bottom-content{
+ height: calc(~'100% - 195px');
+ overflow-y: auto;
+ margin-top: 25px;
+
+ .codemirror-container{
+ height: 100%;
+ }
+ }
+
+ &__header{
+ margin-bottom: 30px;
+
+ > md-content{
+ background: @leftPanelBackColor;
+
+ md-content{
+ background: transparent;
+ }
+ }
+
+ md-progress-linear{
+ margin-top: -5px;
+ }
+
+ md-input-container{
+ margin: 0;
+ }
+
+ .md-errors-spacer{
+ display: none;
+ }
+
+ .input-span{
+ padding-top: 3px;
+ }
+
+ .input-identifier{
+ max-width: 80px;
+ border-color: @colorActive;
+ padding-left: 0;
+ }
+
+ md-divider{
+ margin-top: 20px;
+ }
+
+ .status-bar{
+ min-height: 60px;
+
+ .status-text{
+ span span{
+ color: @colorActive;
+ }
+ }
+ }
+ }
+
+ &__req-data{
+
+ &__header{
+
+ h5{
+ padding-top: 10px;
+ }
+
+ button{
+ margin: 0;
+ margin-bottom: 2px;
+ min-width: 0!important;
+ width: 46px;
+
+ .material-icons{
+ margin-bottom: 6px;
+ vertical-align: bottom;
+ }
+
+ .bigger{
+ font-size: 25px;
+ }
+
+ .smaller{
+ font-size: 18px;
+ }
+
+ .additional{
+ margin-left: -15px;
+ vertical-align: top;
+ }
+ }
+
+ }
+
+ > div{
+ height: 100%;
+ padding-right: 2px;
+ padding-bottom: 10px;
+ position: relative;
+
+
+ > div:not(.ui-resizable-handle) {
+ height: calc(~'100% - 28px');
+ overflow-y: auto;
+ }
+
+ h5{
+ margin-top: 0;
+ }
+
+ &.half-size{
+ height: 50%;
+ }
+ }
+
+ .paramsBox{
+ position: absolute;
+ top: 50px;
+ right: 26px;
+ background-color: rgba(235, 235, 228, 0.62);
+ padding: 15px;
+ }
+
+ .CodeMirror { height: 100%; }
+
+ md-toast{
+ margin-top: 24px;
+ }
+ }
+
+ &__form{
+
+ .box-container.union{
+ padding: 0;
+ }
+
+ .union-tabs{
+ margin: 8px 0;
+
+ md-content{
+ min-width: 250px;
+ }
+
+ .md-tab{
+ padding: 6px 12px;
+ }
+
+ md-pagination-wrapper,
+ md-tabs-canvas{
+ height: 36px;
+ }
+ }
+
+ md-input-container{
+ margin: 0;
+
+ > md-icon {
+ left: auto;
+ right: 2px;
+ color: @dashedBorderColor;
+ }
+
+ &.md-has-icon{
+ padding-right: 36px;
+ padding-left: 0px;
+ }
+
+ .md-errors-spacer{
+ display: none;
+ }
+ }
+
+ .md-menu.menu-container{
+ position: relative;
+ padding: 0;
+
+
+
+ .md-button{
+ margin: auto 0;
+ text-transform: none;
+ text-align: start;
+ height: 100%;
+ padding-left: 16px;
+ padding-right: 16px;
+ display: inline-block;
+ width: 100%;
+
+ &.md-icon-button{
+ padding: 0 8px;
+ }
+
+ }
+
+ .yang-menu-content{
+ box-shadow: 1px 1px 10px #888;
+ position: absolute;
+ left: 0;
+ z-index: 100;
+ background: #fff;
+ padding: 8px 0;
+
+ md-divider{
+ padding: 4px 0 4px 0;
+ }
+
+ .title{
+ color: #a9a9a9;
+ margin: 0 16px;
+
+ md-icon{
+ font-size: 18px;
+ }
+ }
+
+ .yang-menu-item{
+ min-height: 48px;
+ height: 48px;
+
+ md-icon{
+ margin: auto 16px auto 0;
+ }
+ }
+
+ }
+
+ .info-box{
+ position: absolute;
+ left: 100%;
+ top: 0;
+ margin-left: 10px;
+ min-width: 300px;
+ padding: 0;
+ z-index: 10;
+ background: #fff;
+ transition: all 150ms linear;
+ opacity: 1;
+ max-height: 300px;
+ overflow-y: auto;
+ overflow-x: hidden;
+
+ &__padding{
+ padding: 16px;
+ }
+
+ &.ng-hide{
+ opacity: 0;
+ }
+ }
+
+ }
+
+ .menu-placeholder{
+ padding: 11px 26px;
+ }
+
+ p.top-element{
+ margin: 5px 10px 0 0;
+ word-wrap: break-word;
+ width: 100px;
+
+ &.list-label{
+ color: @colorActive;
+ }
+ }
+
+ &__element-container{
+ margin: 25px 5px 5px 15px;
+ padding: 5px;
+
+ &.expanded{
+ border-left: 1px dashed @dashedBorderColor;
+ }
+
+ md-input-container{
+ &.input-icon-container{
+ margin-left: 15px;
+
+ md-icon{
+ margin: 0;
+ }
+ }
+ }
+
+ .container-label{
+ margin: -20px 0 10px -17px;
+
+ md-icon{
+ margin: 0;
+ }
+ }
+ }
+
+ &__leaf-container{
+ padding-left: 10px;
+
+ md-input-container,
+ md-switch,
+ md-checkbox{
+ margin: 5px 0;
+ }
+ }
+
+ &__list{
+ &__paginator{
+ //margin-left: 40px;
+ button {
+ background: transparent;
+ border: 0;
+ outline: 0 none;
+ }
+ }
+ }
+
+ &__list-item{
+ margin: 0 5px;
+
+ md-tab-item{
+ position: relative;
+
+ &.md-tab{
+ padding: 6px 12px;
+ }
+ }
+ }
+ }
+ }
+
+
+ //modules list
+ &__modules-list{
+ padding: 0;
+ background: @listBackColor;
+ height: calc(~"100% - 62px")!important;
+
+ h4{
+ margin: 0;
+ padding: 10px 20px;
+ }
+
+ &__item{
+ padding: 0!important;
+
+ .title{
+ -webkit-transition: all 150ms ease;
+ -moz-transition: all 150ms ease;
+ -ms-transition: all 150ms ease;
+ -o-transition: all 150ms ease;
+ transition: all 150ms ease;
+ }
+
+ &.expanded{
+ background: @listActiveColor;
+ }
+
+ &.selected{
+ .title{
+ background-color: @colorActive!important;
+ color: #fff!important;
+ }
+ }
+
+ p.top-element{
+ padding: 6px 0;
+ }
+
+ md-icon{
+ margin: 12px 16px;
+
+ &.top-element{
+ margin: 0;
+ padding: 12px 16px;
+ width: 56px;
+ height: 48px;
+ }
+ }
+
+ &:hover{
+ .title{
+ background: @listActiveColor;
+ }
+ }
+ }
+ }
+
+ // datastore list
+ &__datastore-list{
+ padding: 0;
+ border-top: 1px solid @dataStoreListBorderColor;
+ background: @listBackColor;
+ -webkit-box-shadow:inset 0 7px 7px -5px @dataStoreListShadowColor;
+ box-shadow:inset 0 7px 7px -5px @dataStoreListShadowColor;
+
+ md-list-item {
+ min-height: 0;
+ padding: 0;
+ font-size: .85em;
+
+ &:hover{
+ background: @dataStoreListHoverColor;
+ }
+
+ md-icon{
+ margin: 6px 16px 6px 48px;
+ font-size: 20.4px;
+ }
+ }
+ }
+
+ // module history collections tabs
+ &__mhc-tabs{
+
+ md-list-item{
+ .md-no-style{
+ padding: 0;
+ }
+ }
+
+ > md-tabs-content-wrapper{
+ height: calc(~'100% - 78px');
+
+ > md-tab-content{
+ height: 100%;
+ }
+ }
+ }
+
+ // module detail
+ &__module-detail{
+ h4{
+ padding-top: 30px;
+ margin: 0 15px;
+ }
+
+ .tabs{
+ height: calc(~'100% - 49px');
+
+ md-tabs-canvas{
+ padding-top: 0;
+ height: 48px;
+ }
+
+ > md-tabs-content-wrapper{
+ height: calc(~'100% - 48px');
+
+ > md-tab-content{
+ height: 100%;
+ }
+ }
+
+ .md-tab{
+ padding: 0;
+ }
+
+ md-tab-item{
+ span{
+ outline: 0 none;
+ padding: 12px 24px;
+ }
+ }
+ }
+
+ > div{
+ height: 100%;
+
+ > md-content{
+ overflow-y: hidden;
+ }
+ }
+ }
+
+ &__requests-list{
+ background: @listBackColor;
+ padding: 0;
+
+ .md-subheader{
+ background: none;
+
+ }
+
+ md-list{
+ padding-top: 0;
+ }
+
+ &__item-container{
+ position: relative;
+ }
+
+ &__group{
+
+ padding: 0!important;
+
+ &__item{
+
+ &.selected{
+ background-color: @colorActive;
+
+ .yangmanModule__requests-list__group__item__path{
+ color: #fff;
+ }
+
+ .yangmanModule__requests-list__group__item__method{
+ .GET, .PUT, .POST, .DELETE, .error{
+ color: #fff;
+ }
+ }
+ }
+
+ &__path{
+ white-space: -webkit-pre-wrap; /*Chrome & Safari */
+ word-break: break-all;
+ white-space: normal;
+ line-height: 18px;
+ color: @fontColor;
+ padding: 5px 0;
+
+ p{
+ padding: 0 9px;
+ }
+ }
+
+ &__method{
+
+ padding-left: 17px;
+ min-width: 70px;
+
+ .GET{
+ color: @reqMethodGet;
+ }
+ .PUT{
+ color: @reqMethodPut;
+ }
+ .POST{
+ color: @reqMethodPost;
+ }
+ .DELETE{
+ color: @reqMethodDelete;
+ }
+ .error{
+ color: @reqError;
+ }
+ }
+ }
+
+ &__itemMenu{
+ position: absolute;
+ top: 50%;
+ margin: -20px 0 0 0;
+ right: 5px;
+ padding: 0;
+
+ &.selected{
+ > button{
+ i.material-icons{
+ color: #fff;
+ }
+ }
+ }
+
+ > button{
+ min-width: 0;
+ margin: 2px 5px;
+
+ i.material-icons{
+ vertical-align: middle;
+ color: @fontColorLight;
+
+ }
+ }
+
+ }
+
+ &__collectionMenu{
+ position: relative;
+ margin-left: -52px;
+ margin-right: 6px;
+
+ > button{
+ min-width: 0;
+ margin: 2px 5px;
+
+ i.material-icons{
+ vertical-align: middle;
+ color: @fontColorLight;
+ }
+ }
+
+ }
+ }
+
+ &__collections-list{
+ padding: 0;
+ background: @listBackColor;
+ height: 100%;
+ }
+
+ &__collection{
+ padding: 0;
+ background: @listBackColor;
+
+ &__requests{
+ padding: 0;
+ border-top: 1px solid @dataStoreListBorderColor;
+ background: @listBackColor;
+ -webkit-box-shadow:inset 0 7px 7px -5px @dataStoreListShadowColor;
+ box-shadow:inset 0 7px 7px -5px @dataStoreListShadowColor;
+ }
+
+ .md-subheader{
+ background: none;
+ }
+
+ .md-subheader-inner{
+ padding: 0;
+ }
+
+ .material-icons{
+ margin: 15px 25px;
+ }
+
+ &.expanded{
+ background: @listActiveColor;
+ }
+
+ p{
+ line-height: 18px;
+ padding: 12px 0;
+
+ .desc{
+ color: @fontColorLight;
+ }
+ }
+
+ }
+
+ }
+}
+.reqMenu{
+ button{
+ span{
+ color: @fontColor
+
+ }
+ i.material-icons{
+ vertical-align: middle;
+ margin-right: 5px;
+ margin-bottom: 5px;
+ }
+ }
+}
+
+
+.md-autocomplete-suggestions{
+ span{
+ color: @fontColor;
+ }
+}
+
+md-dialog{
+
+ .md-toolbar-tools{
+ button{
+ min-width: auto;
+ }
+ }
+
+ md-dialog-content, md-dialog-actions{
+ h2, span{
+ color: @fontColor;
+ }
+
+ }
+
+}
+
+// directives
+.directive{
+ &__abn-tree{
+ padding: 0;
+ display:inline-block;
+ white-space: nowrap;
+ min-width: 100%;
+
+ md-icon{
+ margin: 6px 16px!important;
+ }
+
+ md-list-item{
+ min-height: 0;
+
+ &.active{
+ background: @listActiveColor;
+ }
+
+ .md-no-style{
+ padding: 0;
+
+ &.md-button{
+ white-space: nowrap;
+ }
+ }
+
+ .md-list-item-inner{
+ min-height: 0;
+ }
+
+ .empty-box{
+ display: inline-block;
+ margin-top: -10px;
+ margin-left: 27px;
+ border-left: 1px dashed @dashedBorderColor;
+ height: 36px;
+ width: 1px;
+ }
+
+ .md-button{
+ overflow: visible;
+ }
+
+ .tree-label{
+ padding-right: 15px;
+ }
+ }
+ }
+}
+
+.paramsAdminDialog{
+
+ .md-dialog-content{
+
+ height: 400px;
+
+ button{
+ height: 30px;
+ min-width: 30px;
+ margin-top: 15px;
+ i{
+ vertical-align: middle;
+ }
+ }
+
+
+ }
+ &__searchBox{
+
+ height: 80px;
+
+ > button{
+ margin-top: 13px!important;
+ margin-right: 0px!important;
+ }
+
+ #importParameters{
+ display: none;
+ }
+
+ label{
+ md-icon{
+ color: @fontColor;
+ }
+ }
+
+ md-menu{
+ button{
+ margin-top: 5px!important;
+ }
+ }
+
+ input{
+ border: none;
+ height: auto;
+ outline: none;
+ }
+ }
+ &__paramsList{
+ width: 450px;
+ padding-top: 35px;
+
+ > div{
+ min-height: 60px;
+ margin-top: 10px;
+ }
+
+
+ }
+}
--- /dev/null
+define([
+ 'angular',
+ 'app/routingConfig',
+ 'Restangular',
+ 'angular-translate',
+ 'angular-translate-loader-partial',
+ 'ngMaterial',
+ 'ngMessages',
+ 'common/yangutils/yangutils.module',
+ 'codemirror',
+ 'codeMirror-showHint',
+ 'codeMirror-jsonParametersHint',
+ 'codeMirror-javascriptMode',
+ 'codeMirror-matchBrackets',
+], function () {
+ 'use strict';
+
+ angular.module('app.yangman', [
+ 'ui.router.state',
+ 'app.core',
+ 'app.common.yangUtils',
+ 'restangular',
+ 'pascalprecht.translate',
+ 'ngMaterial',
+ 'ngMessages',
+ ]);
+
+ angular.module('app.yangman')
+ .config(YangManConfig)
+ .constant('ymUiCodemirrorConfig', {});
+
+ function YangManConfig($stateProvider, $mdThemingProvider, $translatePartialLoaderProvider, NavHelperProvider) {
+
+ $translatePartialLoaderProvider.addPart('app/yangman/assets/data/locale');
+
+ $mdThemingProvider.theme('default')
+ .primaryPalette('blue')
+ .accentPalette('light-blue');
+
+ NavHelperProvider.addControllerUrl('app/yangman/controllers/yangman.controller');
+ NavHelperProvider.addToMenu('yangman', {
+ link: '#/yangman/index',
+ active: 'main.yangman',
+ title: 'Yangman',
+ icon: 'icon-rocket',
+ page: {
+ title: 'Yangman',
+ description: 'Yangman',
+ },
+ });
+
+ var access = routingConfig.accessLevels;
+ $stateProvider.state('main.yangman', {
+ url: 'yangman',
+ abstract: true,
+ views: {
+ content: {
+ templateUrl: 'src/app/yangman/views/root.tpl.html',
+ },
+ },
+ });
+
+ $stateProvider.state('main.yangman.index', {
+ url: '/index',
+ access: access.admin,
+ views: {
+ '': {
+ controller: 'YangmanCtrl',
+ controllerAs: 'main',
+ templateUrl: 'src/app/yangman/views/index.tpl.html',
+ },
+ },
+ });
+ }
+});
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
+++ /dev/null
-List of CodeMirror contributors. Updated before every release.
-
-4r2r
-Aaron Brooks
-Abdelouahab
-Abe Fettig
-Adam Ahmed
-Adam King
-adanlobato
-Adán Lobato
-Adrian Aichner
-aeroson
-Ahmad Amireh
-Ahmad M. Zawawi
-ahoward
-Akeksandr Motsjonov
-Alberto González Palomo
-Alberto Pose
-Albert Xing
-Alexander Pavlov
-Alexander Schepanovski
-Alexander Shvets
-Alexander Solovyov
-Alexandre Bique
-alexey-k
-Alex Piggott
-Aliaksei Chapyzhenka
-Amin Shali
-Amsul
-amuntean
-Amy
-Ananya Sen
-anaran
-AndersMad
-Anders Nawroth
-Anderson Mesquita
-Andrea G
-Andreas Reischuck
-Andre von Houck
-Andrey Fedorov
-Andrey Klyuchnikov
-Andrey Lushnikov
-Andy Joslin
-Andy Kimball
-Andy Li
-Angelo
-angelozerr
-angelo.zerr@gmail.com
-Ankit
-Ankit Ahuja
-Ansel Santosa
-Anthony Dugois
-Anthony Grimes
-Anton Kovalyov
-AQNOUCH Mohammed
-areos
-as3boyan
-AtomicPages LLC
-Atul Bhouraskar
-Aurelian Oancea
-Bastian Müller
-Bem Jones-Bey
-benbro
-Beni Cherniavsky-Paskin
-Benjamin DeCoste
-Ben Keen
-Bernhard Sirlinger
-Bert Chang
-Billy Moon
-binny
-B Krishna Chaitanya
-Blaine G
-blukat29
-boomyjee
-borawjm
-Brad Metcalf
-Brandon Frohs
-Brandon Wamboldt
-Brett Zamir
-Brian Grinstead
-Brian Sletten
-Bruce Mitchener
-Calin Barbat
-Chandra Sekhar Pydi
-Charles Skelton
-Cheah Chu Yeow
-Chris Coyier
-Chris Granger
-Chris Houseknecht
-Chris Lohfink
-Chris Morgan
-Christian Oyarzun
-Christian Petrov
-Christopher Brown
-Christopher Mitchell
-Christopher Pfohl
-ciaranj
-CodeAnimal
-coderaiser
-ComFreek
-Curtis Gagliardi
-dagsta
-daines
-Dale Jung
-Dan Bentley
-Dan Heberden
-Daniel, Dao Quang Minh
-Daniele Di Sarli
-Daniel Faust
-Daniel Huigens
-Daniel KJ
-Daniel Neel
-Daniel Parnell
-Danny Yoo
-darealshinji
-Darius Roberts
-Dave Myers
-David Barnett
-David Mignot
-David Pathakjee
-David Vázquez
-deebugger
-Deep Thought
-Devon Carew
-dignifiedquire
-Dimage Sapelkin
-Dmitry Kiselyov
-domagoj412
-Dominator008
-Domizio Demichelis
-Doug Wikle
-Drew Bratcher
-Drew Hintz
-Drew Khoury
-Dror BG
-duralog
-eborden
-edsharp
-ekhaled
-Enam Mijbah Noor
-Eric Allam
-eustas
-Fabien O'Carroll
-Fabio Zendhi Nagao
-Faiza Alsaied
-Fauntleroy
-fbuchinger
-feizhang365
-Felipe Lalanne
-Felix Raab
-Filip Noetzel
-flack
-ForbesLindesay
-Forbes Lindesay
-Ford_Lawnmower
-Forrest Oliphant
-Frank Wiegand
-Gabriel Gheorghian
-Gabriel Horner
-Gabriel Nahmias
-galambalazs
-Gautam Mehta
-gekkoe
-Gerard Braad
-Gergely Hegykozi
-Giovanni Calò
-Glenn Jorde
-Glenn Ruehle
-Golevka
-Gordon Smith
-Grant Skinner
-greengiant
-Gregory Koberger
-Guillaume Massé
-Guillaume Massé
-Gustavo Rodrigues
-Hakan Tunc
-Hans Engel
-Hardest
-Hasan Karahan
-Hector Oswaldo Caballero
-Herculano Campos
-Hiroyuki Makino
-hitsthings
-Hocdoc
-Ian Beck
-Ian Dickinson
-Ian Wehrman
-Ian Wetherbee
-Ice White
-ICHIKAWA, Yuji
-ilvalle
-Ingo Richter
-Irakli Gozalishvili
-Ivan Kurnosov
-Ivoah
-Jacob Lee
-Jakob Miland
-Jakub Vrana
-Jakub Vrána
-James Campos
-James Thorne
-Jamie Hill
-Jan Jongboom
-jankeromnes
-Jan Keromnes
-Jan Odvarko
-Jan T. Sott
-Jared Forsyth
-Jason
-Jason Barnabe
-Jason Grout
-Jason Johnston
-Jason San Jose
-Jason Siefken
-Jaydeep Solanki
-Jean Boussier
-jeffkenton
-Jeff Pickhardt
-jem (graphite)
-Jeremy Parmenter
-Jochen Berger
-Johan Ask
-John Connor
-John Lees-Miller
-John Snelson
-John Van Der Loo
-Jonas Döbertin
-Jonathan Malmaud
-jongalloway
-Jon Malmaud
-Jon Sangster
-Joost-Wim Boekesteijn
-Joseph Pecoraro
-Joshua Newman
-Josh Watzman
-jots
-jsoojeon
-ju1ius
-Juan Benavides Romero
-Jucovschi Constantin
-Juho Vuori
-Justin Hileman
-jwallers@gmail.com
-kaniga
-Ken Newman
-Ken Rockot
-Kevin Earls
-Kevin Sawicki
-Kevin Ushey
-Klaus Silveira
-Koh Zi Han, Cliff
-komakino
-Konstantin Lopuhin
-koops
-ks-ifware
-kubelsmieci
-KwanEsq
-Lanfei
-Lanny
-Laszlo Vidacs
-leaf corcoran
-Leonid Khachaturov
-Leon Sorokin
-Leonya Khachaturov
-Liam Newman
-Libo Cannici
-LloydMilligan
-LM
-lochel
-Lorenzo Stoakes
-Luciano Longo
-Luke Stagner
-lynschinzer
-Madhura Jayaratne
-Maksim Lin
-Maksym Taran
-Malay Majithia
-Manuel Rego Casasnovas
-Marat Dreizin
-Marcel Gerber
-Marco Aurélio
-Marco Munizaga
-Marcus Bointon
-Marek Rudnicki
-Marijn Haverbeke
-Mário Gonçalves
-Mario Pietsch
-Mark Lentczner
-Marko Bonaci
-Martin Balek
-Martín Gaitán
-Martin Hasoň
-Martin Hunt
-Mason Malone
-Mateusz Paprocki
-Mathias Bynens
-mats cronqvist
-Matthew Beale
-Matthew Rathbone
-Matthias Bussonnier
-Matthias BUSSONNIER
-Matt McDonald
-Matt Pass
-Matt Sacks
-mauricio
-Maximilian Hils
-Maxim Kraev
-Max Kirsch
-Max Xiantu
-mbarkhau
-Metatheos
-Micah Dubinko
-Michael Grey
-Michael Kaminsky
-Michael Lehenbauer
-Michael Zhou
-Michal Dorner
-Mighty Guava
-Miguel Castillo
-mihailik
-Mike
-Mike Brevoort
-Mike Diaz
-Mike Ivanov
-Mike Kadin
-MinRK
-Miraculix87
-misfo
-mloginov
-Moritz Schwörer
-mps
-ms
-mtaran-google
-Narciso Jaramillo
-Nathan Williams
-ndr
-nerbert
-nextrevision
-ngn
-nguillaumin
-Ng Zhi An
-Nicholas Bollweg
-Nicholas Bollweg (Nick)
-Nick Kreeger
-Nick Small
-Niels van Groningen
-nightwing
-Nikita Beloglazov
-Nikita Vasilyev
-Nikolay Kostov
-nilp0inter
-Nisarg Jhaveri
-nlwillia
-noragrossman
-Norman Rzepka
-pablo
-Page
-Panupong Pasupat
-paris
-Paris
-Patil Arpith
-Patrick Stoica
-Patrick Strawderman
-Paul Garvin
-Paul Ivanov
-Pavel Feldman
-Pavel Strashkin
-Paweł Bartkiewicz
-peteguhl
-Peter Flynn
-peterkroon
-Peter Kroon
-prasanthj
-Prasanth J
-Radek Piórkowski
-Rahul
-Randall Mason
-Randy Burden
-Randy Edmunds
-Rasmus Erik Voel Jensen
-ray ratchup
-Ray Ratchup
-Richard van der Meer
-Richard Z.H. Wang
-Robert Crossfield
-Roberto Abdelkader Martínez Pérez
-robertop23
-Robert Plummer
-Ruslan Osmanov
-Ryan Prior
-sabaca
-Samuel Ainsworth
-sandeepshetty
-Sander AKA Redsandro
-santec
-Sascha Peilicke
-satamas
-satchmorun
-sathyamoorthi
-SCLINIC\jdecker
-Scott Aikin
-Scott Goodhew
-Sebastian Zaha
-shaund
-shaun gilchrist
-Shawn A
-sheopory
-Shiv Deepak
-Shmuel Englard
-Shubham Jain
-silverwind
-snasa
-soliton4
-sonson
-spastorelli
-srajanpaliwal
-Stanislav Oaserele
-Stas Kobzar
-Stefan Borsje
-Steffen Beyer
-Steve O'Hara
-stoskov
-Taha Jahangir
-Takuji Shimokawa
-Tarmil
-tel
-tfjgeorge
-Thaddee Tyl
-TheHowl
-think
-Thomas Dvornik
-Thomas Schmid
-Tim Alby
-Tim Baumann
-Timothy Farrell
-Timothy Hatcher
-TobiasBg
-Tomas-A
-Tomas Varaneckas
-Tom Erik Støwer
-Tom MacWright
-Tony Jian
-Travis Heppe
-Triangle717
-twifkak
-Vestimir Markov
-vf
-Vincent Woo
-Volker Mische
-wenli
-Wesley Wiser
-Will Binns-Smith
-William Jamieson
-William Stein
-Willy
-Wojtek Ptak
-Xavier Mendez
-Yassin N. Hassan
-YNH Webdev
-Yunchi Luo
-Yuvi Panda
-Zachary Dremann
-Zhang Hao
-zziuni
-魏鹏刚
+++ /dev/null
-# How to contribute
-
-- [Getting help](#getting-help-)
-- [Submitting bug reports](#submitting-bug-reports-)
-- [Contributing code](#contributing-code-)
-
-## Getting help
-
-Community discussion, questions, and informal bug reporting is done on the
-[discuss.CodeMirror forum](http://discuss.codemirror.net).
-
-## Submitting bug reports
-
-The preferred way to report bugs is to use the
-[GitHub issue tracker](http://github.com/codemirror/CodeMirror/issues). Before
-reporting a bug, read these pointers.
-
-**Note:** The issue tracker is for *bugs*, not requests for help. Questions
-should be asked on the
-[discuss.CodeMirror forum](http://discuss.codemirror.net) instead.
-
-### Reporting bugs effectively
-
-- CodeMirror is maintained by volunteers. They don't owe you anything, so be
- polite. Reports with an indignant or belligerent tone tend to be moved to the
- bottom of the pile.
-
-- Include information about **the browser in which the problem occurred**. Even
- if you tested several browsers, and the problem occurred in all of them,
- mention this fact in the bug report. Also include browser version numbers and
- the operating system that you're on.
-
-- Mention which release of CodeMirror you're using. Preferably, try also with
- the current development snapshot, to ensure the problem has not already been
- fixed.
-
-- Mention very precisely what went wrong. "X is broken" is not a good bug
- report. What did you expect to happen? What happened instead? Describe the
- exact steps a maintainer has to take to make the problem occur. We can not
- fix something that we can not observe.
-
-- If the problem can not be reproduced in any of the demos included in the
- CodeMirror distribution, please provide an HTML document that demonstrates
- the problem. The best way to do this is to go to
- [jsbin.com](http://jsbin.com/ihunin/edit), enter it there, press save, and
- include the resulting link in your bug report.
-
-## Contributing code
-
-- Make sure you have a [GitHub Account](https://github.com/signup/free)
-- Fork [CodeMirror](https://github.com/codemirror/CodeMirror/)
- ([how to fork a repo](https://help.github.com/articles/fork-a-repo))
-- Make your changes
-- If your changes are easy to test or likely to regress, add tests.
- Tests for the core go into `test/test.js`, some modes have their own
- test suite under `mode/XXX/test.js`. Feel free to add new test
- suites to modes that don't have one yet (be sure to link the new
- tests into `test/index.html`).
-- Follow the general code style of the rest of the project (see
- below). Run `bin/lint` to verify that the linter is happy.
-- Make sure all tests pass. Visit `test/index.html` in your browser to
- run them.
-- Submit a pull request
-([how to create a pull request](https://help.github.com/articles/fork-a-repo))
-
-By contributing code to CodeMirror you
-
- - agree to license the contributed code under CodeMirror's [MIT
- license](http://codemirror.net/LICENSE).
-
- - confirm that you have the right to contribute and license the code
- in question. (Either you hold all rights on the code, or the rights
- holder has explicitly granted the right to use it like this,
- through a compatible open source license or through a direct
- agreement with you.)
-
-### Coding standards
-
-- 2 spaces per indentation level, no tabs.
-- Include semicolons after statements.
-- Note that the linter (`bin/lint`) which is run after each commit
- complains about unused variables and functions. Prefix their names
- with an underscore to muffle it.
-
-- CodeMirror does *not* follow JSHint or JSLint prescribed style.
- Patches that try to 'fix' code to pass one of these linters will be
- unceremoniously discarded.
+++ /dev/null
-Copyright (C) 2015 by Marijn Haverbeke <marijnh@gmail.com> and others
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+++ /dev/null
-# CodeMirror
-[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
-[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
-[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?again)](https://marijnhaverbeke.nl/fund/)
-
-CodeMirror is a JavaScript component that provides a code editor in
-the browser. When a mode is available for the language you are coding
-in, it will color your code, and optionally help with indentation.
-
-The project page is http://codemirror.net
-The manual is at http://codemirror.net/doc/manual.html
-The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)
* Created by dakuzma on 25. 8. 2015.
*/
require.config({
- packages: [{
- name: "codemirror",
- location: "app/yangui/assets/js/codemirror",
- main: "lib/codemirror"
- }],
- paths: {
- 'codeMirror-showHint' : 'app/yangui/assets/js/codemirror/addon/hint/show-hint',
- 'codeMirror-yanguiJsonHint' : 'app/yangui/assets/js/codemirror/addon/hint/yangui-json-hint',
- 'codeMirror-javascriptMode' : 'app/yangui/assets/js/codemirror/mode/javascript/javascript',
- 'codeMirror-matchBrackets' : 'app/yangui/assets/js/codemirror/addon/edit/matchbrackets'
- },
- shim:{
- 'codeMirros_showHint': ['codemirror'],
- 'codeMirros_javascriptHint': ['codemirror'],
- 'codeMirror_javascriptMode': ['codemirror'],
- 'codeMirror_matchBrackets': ['codemirror']
- }
});
define(['app/yangui/yangui.module']);
-/*PLUGINS importing*/\r
-@import 'assets/js/codemirror/lib/codemirror.less';\r
-@import 'assets/js/codemirror/theme/eclipse.less';\r
-@import 'assets/js/codemirror/theme/eclipse-disabled.less';\r
-@import 'assets/js/codemirror/addon/hint/show-hint.less';\r
-/*PLUGINS importing END*/\r
-\r
@iconsNewRootPath : '../src/app/yangui/assets/images/';\r
\r
/******** WINDOW SCROLLBARS *****/\r
}*/\r
\r
.previewContainer{\r
- min-width:204px; \r
+ min-width:204px;\r
min-height:97px;\r
}\r
\r
\r
/* --------------------------------------------------------------------------------- COMMON OWN RULES */\r
.opacityDeph(@opacity: 0.5){\r
- -ms-filter: ~"'progid:DXImageTransform.Microsoft.Alpha(Opacity=" @opacity*100 ~")'"; \r
+ -ms-filter: ~"'progid:DXImageTransform.Microsoft.Alpha(Opacity=" @opacity*100 ~")'";\r
filter: ~"alpha(opacity=" @opacity*100 ~")";\r
-moz-opacity: @opacity;\r
-khtml-opacity: @opacity;\r
/* --------------------------------------------------------------------------------- YANG UI */\r
.yangUIwrapper{\r
\r
+ input[type=text]{\r
+ background-color: #58595B;\r
+ color: white;\r
+ }\r
+\r
+ span{\r
+ color: white;\r
+ }\r
+\r
+ .yangUIwrapper .CodeMirror span{\r
+ color: auto;\r
+ }\r
+\r
::-webkit-scrollbar {\r
width: 10px;\r
height: 10px;\r
.roundedCorners(0px);\r
border: 0;\r
}\r
- \r
+\r
label.classic{\r
min-width: 90px;\r
}\r
\r
.historyRequestBox{\r
position: relative;\r
- \r
+\r
.changeGroup{\r
left: -365px;\r
}\r
.scroll{\r
overflow-y: auto;\r
position: relative;\r
- height: calc(~"100% - 50px"); \r
+ height: calc(~"100% - 50px");\r
}\r
\r
\r
span{\r
color: auto;\r
}\r
- \r
+\r
pre span{\r
color: auto;\r
}\r
- \r
- \r
+\r
+\r
textarea{\r
width: 100%;\r
min-height: 50px;\r
margin-bottom: 1px;\r
font-size: 12px;\r
}\r
- \r
+\r
span{\r
color: @text-color;\r
}\r
\r
\r
.reqParams {\r
- \r
+\r
.thdiv{\r
.rh-col3{\r
width: calc(~"100% - 450px");\r
}\r
}\r
- \r
+\r
.rh-col2{\r
width: 235px;\r
}\r
.listButtonWrapper{\r
margin: 2px 15px 0 5px;\r
.inlineBlock;\r
- \r
+\r
button.yangButton{\r
margin: 0px;\r
}\r
&.containerBullet{\r
/* margin: 0 0px 0 -14px;\r
line-height: 25px;*/\r
- top: -25px; \r
+ top: -25px;\r
left: -25px;\r
}\r
}\r
\r
.tooltip-inner{\r
color: #fff;\r
- white-space: pre-wrap; /* CSS3 */ \r
- white-space: -moz-pre-wrap; /* Firefox */ \r
- white-space: -pre-wrap; /* Opera <7 */ \r
- white-space: -o-pre-wrap; /* Opera 7 */ \r
+ white-space: pre-wrap; /* CSS3 */\r
+ white-space: -moz-pre-wrap; /* Firefox */\r
+ white-space: -pre-wrap; /* Opera <7 */\r
+ white-space: -o-pre-wrap; /* Opera 7 */\r
word-wrap: break-word; /* IE */\r
}\r
\r
cursor: se-resize;\r
}\r
}\r
- \r
+\r
\r
.ui-resizable-s {\r
cursor: s-resize;\r
'jquery-ui',\r
'codemirror',\r
'codeMirror-showHint',\r
- 'codeMirror-yanguiJsonHint',\r
+ 'codeMirror-jsonParametersHint',\r
'codeMirror-javascriptMode',\r
'codeMirror-matchBrackets',\r
'ngClip',\r
<parent>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
- <version>1.7.0-SNAPSHOT</version>
+ <version>1.8.0-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.dlux</groupId>
- <artifactId>dlux-parent</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>dlux</name> <!-- Used by Sonar to set project name -->
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>dlux-parent</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>dlux</name> <!-- Used by Sonar to set project name -->
- <properties>
- <commons.opendaylight.version>1.7.0-SNAPSHOT</commons.opendaylight.version>
- <loader.resources.version>0.3.0-SNAPSHOT</loader.resources.version>
- <core.resources.version>0.3.0-SNAPSHOT</core.resources.version>
- <node.resources.version>0.3.0-SNAPSHOT</node.resources.version>
- <connection_manager.resources.version>0.3.0-SNAPSHOT</connection_manager.resources.version>
- <container.resources.version>0.3.0-SNAPSHOT</container.resources.version>
- <flow.resources.version>0.3.0-SNAPSHOT</flow.resources.version>
- <network.resources.version>0.3.0-SNAPSHOT</network.resources.version>
- <topology.resources.version>0.3.0-SNAPSHOT</topology.resources.version>
- <yangui.resources.version>0.3.0-SNAPSHOT</yangui.resources.version>
- <yangvisualizer.resources.version>0.3.0-SNAPSHOT</yangvisualizer.resources.version>
- <common.authentication.resources.version>0.3.0-SNAPSHOT</common.authentication.resources.version>
- <common.general.resources.version>0.3.0-SNAPSHOT</common.general.resources.version>
- <common.navigation.resources.version>0.3.0-SNAPSHOT</common.navigation.resources.version>
- <common.layout.resources.version>0.3.0-SNAPSHOT</common.layout.resources.version>
- <common.topbar.resources.version>0.3.0-SNAPSHOT</common.topbar.resources.version>
- <common.login.resources.version>0.3.0-SNAPSHOT</common.login.resources.version>
- <common.yangutils.resources.version>0.3.0-SNAPSHOT</common.yangutils.resources.version>
- <common.sigmatopology.resources.version>0.3.0-SNAPSHOT</common.sigmatopology.resources.version>
- <restconf.version>1.4.0-SNAPSHOT</restconf.version>
- <l2switch.version>0.4.0-SNAPSHOT</l2switch.version>
- <mdsal.version>1.4.0-SNAPSHOT</mdsal.version>
- <branding.version>1.3.0-SNAPSHOT</branding.version>
- <karaf.resources.version>1.7.0-SNAPSHOT</karaf.resources.version>
- <feature.l2switch.version>0.4.0-SNAPSHOT</feature.l2switch.version>
- <feature.aaa.version>0.4.0-SNAPSHOT</feature.aaa.version>
- <feature.openflowplugin.version>0.3.0-SNAPSHOT</feature.openflowplugin.version>
+ <properties>
+ <commons.opendaylight.version>1.8.0-SNAPSHOT</commons.opendaylight.version>
+ <loader.resources.version>0.5.0-SNAPSHOT</loader.resources.version>
+ <core.resources.version>0.5.0-SNAPSHOT</core.resources.version>
+ <node.resources.version>0.5.0-SNAPSHOT</node.resources.version>
+ <connection_manager.resources.version>0.5.0-SNAPSHOT</connection_manager.resources.version>
+ <container.resources.version>0.5.0-SNAPSHOT</container.resources.version>
+ <flow.resources.version>0.5.0-SNAPSHOT</flow.resources.version>
+ <network.resources.version>0.5.0-SNAPSHOT</network.resources.version>
+ <topology.resources.version>0.5.0-SNAPSHOT</topology.resources.version>
+ <yangui.resources.version>0.5.0-SNAPSHOT</yangui.resources.version>
+ <yangman.resources.version>0.5.0-SNAPSHOT</yangman.resources.version>
+ <yangvisualizer.resources.version>0.5.0-SNAPSHOT</yangvisualizer.resources.version>
+ <common.authentication.resources.version>0.5.0-SNAPSHOT</common.authentication.resources.version>
+ <common.general.resources.version>0.5.0-SNAPSHOT</common.general.resources.version>
+ <common.navigation.resources.version>0.5.0-SNAPSHOT</common.navigation.resources.version>
+ <common.layout.resources.version>0.5.0-SNAPSHOT</common.layout.resources.version>
+ <common.topbar.resources.version>0.5.0-SNAPSHOT</common.topbar.resources.version>
+ <common.login.resources.version>0.5.0-SNAPSHOT</common.login.resources.version>
+ <common.yangutils.resources.version>0.5.0-SNAPSHOT</common.yangutils.resources.version>
+ <common.sigmatopology.resources.version>0.5.0-SNAPSHOT</common.sigmatopology.resources.version>
+ <restconf.version>1.5.0-SNAPSHOT</restconf.version>
+ <l2switch.version>0.5.0-SNAPSHOT</l2switch.version>
+ <mdsal.version>1.5.0-SNAPSHOT</mdsal.version>
+ <branding.version>1.4.0-SNAPSHOT</branding.version>
+ <karaf.resources.version>1.8.0-SNAPSHOT</karaf.resources.version>
+ <feature.l2switch.version>0.5.0-SNAPSHOT</feature.l2switch.version>
+ <feature.aaa.version>0.5.0-SNAPSHOT</feature.aaa.version>
+ <feature.openflowplugin.version>0.4.0-SNAPSHOT</feature.openflowplugin.version>
- <feature.test.version>1.7.0-SNAPSHOT</feature.test.version>
- <feature.mdsal.version>1.4.0-SNAPSHOT</feature.mdsal.version>
- <feature.dlux.version>0.4.0-SNAPSHOT</feature.dlux.version>
- <feature.flow.version>1.4.0-SNAPSHOT</feature.flow.version>
- <feature.yangtools.version>1.0.0-SNAPSHOT</feature.yangtools.version>
- <apache.felix.osgi.compendium.version>1.4.0</apache.felix.osgi.compendium.version>
- <javax.servlet-api.version>3.0.1</javax.servlet-api.version>
- <karaf.empty.version>1.7.0-SNAPSHOT</karaf.empty.version>
- </properties>
+ <feature.test.version>1.8.0-SNAPSHOT</feature.test.version>
+ <feature.mdsal.version>1.5.0-SNAPSHOT</feature.mdsal.version>
+ <feature.dlux.version>0.5.0-SNAPSHOT</feature.dlux.version>
+ <feature.flow.version>1.5.0-SNAPSHOT</feature.flow.version>
+ <feature.yangtools.version>1.1.0-SNAPSHOT</feature.yangtools.version>
+ <apache.felix.osgi.compendium.version>1.4.0</apache.felix.osgi.compendium.version>
+ <javax.servlet-api.version>3.0.1</javax.servlet-api.version>
+ <karaf.empty.version>1.8.0-SNAPSHOT</karaf.empty.version>
+ </properties>
- <modules>
- <module>modules</module>
- <module>dlux-web</module>
- <module>loader/api</module>
- <module>loader/impl</module>
- <module>bundles</module>
- <module>features</module>
- <module>archetype</module>
- </modules>
+ <modules>
+ <module>modules</module>
+ <module>dlux-web</module>
+ <module>loader/api</module>
+ <module>loader/impl</module>
+ <module>bundles</module>
+ <module>features</module>
+ <module>archetype</module>
+ </modules>
<scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</connection> <developerConnection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</developerConnection>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</developerConnection>
<tag>HEAD</tag>
<url>https://wiki.opendaylight.org/view/OpenDaylight_dlux:Main</url>
</scm>