diff --git a/.gitignore b/.gitignore index f45e08f9fc..8ee75bcc29 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ nb-configuration.xml # Intellij .idea/ +.run/ *.iml *.iws *.ipr diff --git a/nifi-assembly/LICENSE b/nifi-assembly/LICENSE index 4ca6da5e73..0be047904a 100644 --- a/nifi-assembly/LICENSE +++ b/nifi-assembly/LICENSE @@ -440,163 +440,6 @@ For details see http://qtip2.com FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -This product bundles 'json2.js' which is available in the 'public domain'. - For details see https://github.com/douglascrockford/JSON-js - -This product bundles 'reset.css' which is available in the 'public domain'. - For details see http://meyerweb.com/eric/tools/css/reset/ - -This product bundles 'Angular' which is available under an MIT license. - - Copyright (c) 2010-2016 Google, Inc. http://angularjs.org - - 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. - -This product bundles 'Angular Material' which is available under an MIT license. - - Copyright (c) 2014-2016 Google, Inc. http://angularjs.org - - 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. - -This product bundles 'Angular Aria' which is available under an MIT license. - - Copyright (c) 2010-2016 Google, Inc. http://angularjs.org - - 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 - -This product bundles 'Angular Animate' which is available under an MIT license. - - Copyright (c) 2010-2016 Google, Inc. http://angularjs.org - - 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 - -This product bundles 'Angular Messages' which is available under an MIT license. - - Copyright (c) 2010-2016 Google, Inc. http://angularjs.org - - 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 - -This product bundles 'AngularUI Codemirror' which is available under an MIT license. - - Copyright (c) 2012 the AngularUI Team, http://angular-ui.github.com - - 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. - -This product bundles 'AngularUI Router' which is available under an MIT license. - - Copyright (c) 2013-2015 The AngularUI Team, Karsten Sperling - - 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. - This product bundles 'Fontello' which is available under an MIT license. Copyright (C) 2011 by Vitaly Puzrin @@ -619,29 +462,6 @@ This product bundles 'Fontello' which is available under an MIT license. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -This product bundles HexViewJS available under an MIT License - - Copyright (c) 2010 Nick McVeity - - 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. - The binary distribution of this product includes modules from Groovy which bundles ANTLR SOFTWARE RIGHTS @@ -2872,4 +2692,7 @@ For the binary distribution of nifi-jolt-transform-json-ui see its 3rdpartylicen for additional license and notice information. For the binary distribution of nifi-standard-content-viewer see its 3rdpartylicenses.txt +for additional license and notice information. + +For the binary distribution of nifi-update-attribute-ui see its 3rdpartylicenses.txt for additional license and notice information. \ No newline at end of file diff --git a/nifi-assembly/NOTICE b/nifi-assembly/NOTICE index 25839e6b9a..4291421b05 100644 --- a/nifi-assembly/NOTICE +++ b/nifi-assembly/NOTICE @@ -2581,4 +2581,7 @@ For the binary distribution of nifi-jolt-transform-json-ui see its 3rdpartylicen for additional license and notice information. For the binary distribution of nifi-standard-content-viewer see its 3rdpartylicenses.txt +for additional license and notice information. + +For the binary distribution of nifi-update-attribute-ui see its 3rdpartylicenses.txt for additional license and notice information. \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-transform-json-ui/src/main/webapp/WEB-INF/web.xml b/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-transform-json-ui/src/main/webapp/WEB-INF/web.xml index 4e61df0b44..ca2d8942c3 100644 --- a/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-transform-json-ui/src/main/webapp/WEB-INF/web.xml +++ b/nifi-extension-bundles/nifi-jolt-bundle/nifi-jolt-transform-json-ui/src/main/webapp/WEB-INF/web.xml @@ -35,7 +35,7 @@ /api/* - + FragmentFilter org.apache.nifi.web.servlet.filter.QueryStringToFragmentFilter diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/LICENSE b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/LICENSE index 0234b15694..b2e21467bf 100644 --- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/LICENSE +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/LICENSE @@ -206,47 +206,7 @@ APACHE NIFI SUBCOMPONENTS: The Apache NiFi project contains subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the following -licenses. +licenses. -This product bundles 'CodeMirror' which is available under an MIT style license. - - Copyright (C) 2014 by Marijn Haverbeke 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. - -This product bundles 'JQuery' which is available under and MIT style license. - (c) 2005, 2014 jQuery Foundation, Inc. - - 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. \ No newline at end of file +For the binary distribution of nifi-standard-content-viewer see its 3rdpartylicenses.txt +for additional license and notice information. \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/NOTICE b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/NOTICE index d8293f4ac5..051fb74f7f 100644 --- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/NOTICE +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/resources/META-INF/NOTICE @@ -4,6 +4,9 @@ Copyright 2014-2024 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). +For the binary distribution of nifi-standard-content-viewer see its 3rdpartylicenses.txt +for additional license and notice information. + =========================================== Apache Software License v2 =========================================== diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/src/main/resources/docs/org.apache.nifi.processors.attributes.UpdateAttribute/additionalDetails.md b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/src/main/resources/docs/org.apache.nifi.processors.attributes.UpdateAttribute/additionalDetails.md index 1da1c907d4..3f730b68b8 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/src/main/resources/docs/org.apache.nifi.processors.attributes.UpdateAttribute/additionalDetails.md +++ b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/src/main/resources/docs/org.apache.nifi.processors.attributes.UpdateAttribute/additionalDetails.md @@ -79,20 +79,18 @@ The preceding examples illustrate how to make changes to every FlowFile that goe UpdateAttribute processor may also be used to make conditional changes. To change attributes based on some condition, use the Advanced User Interface (UI) in the processor by clicking the * -*Advanced** button in the lower right corner. +*Advanced** menu item in the Canvas context menu. -Clicking the Advanced button displays the Advanced UI. In the Advanced UI, Conditions and their associated Actions are +Clicking the Advanced menu item displays the Advanced UI. In the Advanced UI, Conditions and their associated Actions are entered as "Rules". Each rule basically says, "If these conditions are met, then do this action." One or more conditions may be used in a given rule, and they all must be met in order for the designated action(s) to be taken. **Adding Rules** -To add rules and their associated conditions and actions, click on the buttons with the plus symbol located to the right -of the "Rules", "Conditions", and "Actions" labels. - -Upon adding a rule with its condition(s) and action(s), it is important to save it by clicking the **Save** button in -the lower right corner. If you do not do so and attempt to add or navigate to another rule, an error message will -appear, asking you if you want to save your changes. +To add the first rule, click on the "Create Rule" button in center of the screen. The Edit Rule form will display where +the name, comments, conditions, and actions for the rule can be entered. Once the rule is defined, click the **Add** +button. Additional rules can be added by clicking the button with the plus symbol located to the top right of the +Rule listing. **Example Rules** @@ -116,9 +114,9 @@ Taken together, this rule says: **Adding another Rule** Continuing with this example, we can add another rule to check for files that are larger than one gigabyte. When we add -this second rule, we can use the previous rule as a template, so to speak, by taking advantage of the "Copy from -existing rule" option in the New Rule window. Simply start typing the name of an existing rule, and it will show up in a -dropdown menu below the entry field. +this second rule, we can use the previous rule as a template, so to speak, by taking advantage of the "Clone Rule" option +in the menu for the Rule that you wan to clone. This will open with new Rule form with the exisitng Rules criteria +pre-populated. In this example, the CheckForGiantFiles rule has these conditions: @@ -159,8 +157,8 @@ The delete attributes function does not produce a Provenance Event if the **alte **FlowFile Policy** Another setting in the Advanced UI is the FlowFile Policy. It is located in the upper-left corner of the UI, and it -defines the processor's behavior when multiple rules match. It may be changed using the dropdown menu. By default, the -FlowFile Policy is set to "use clone". +defines the processor's behavior when multiple rules match. It may be changed using the slide toggle. By default, the +FlowFile Policy is set to use a clone of the original FlowFile for each matching rule. If the FlowFile policy is set to "use clone", and multiple rules match, then a copy of the incoming FlowFile is created, such that the number of outgoing FlowFiles is equal to the number of rules that match. In other words, if two rules (A @@ -172,7 +170,8 @@ If the FlowFile policy is set to "use original", then all matching rules are app there is only one outgoing FlowFile with all the attribute changes applied. In this case, the order of the rules matters and the action for each rule that matches will be applied in that order. If multiple rules contain actions that update the same attribute, the action from the last matching rule will take precedence. Notably, you can drag and drop the -rules into a certain order within the Rules list. +rules into a certain order within the Rules list once the FlowFile Policy is set to "use original" and the user has +toggled the "Reorder rules" control. While in this reordering mode, other Rule modifications are not allowed. **Filtering Rules** @@ -182,7 +181,7 @@ in the name, condition, or action. **Closing the Advanced UI** -Once all changes have been saved in the Advanced UI, the UI can be closed using the X in the top right corner. +Once all changes have been saved in the Advanced UI, you can navigate back to the Canvas using the navigation at the top. **Stateful Usage** diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml index 04c08c0a1a..91a6ad7ea2 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml +++ b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml @@ -23,128 +23,45 @@ nifi-update-attribute-ui war - ${basedir}/src/main/frontend - ${project.build.directory}/frontend-working-directory - ${project.build.directory}/${project.build.finalName}/assets + ${project.build.directory}/update-attribute-ui-working-directory + org.apache.maven.plugins - maven-resources-plugin + maven-dependency-plugin - copy-client-side-deps + unpack-update-attribute-ui prepare-package - copy-resources + unpack-dependencies - ${frontend.assets} - - - ${frontend.working.dir}/node_modules - false - - - font-awesome/css/**/* - font-awesome/fonts/**/* - font-awesome/README.md - - jquery/dist/jquery.min* - jquery/LICENSE.txt - - jquery-ui-dist/jquery-ui.min.js - jquery-ui-dist/jquery-ui.min.css - jquery-ui-dist/images/**/* - jquery-ui-dist/LICENSE.txt - - reset.css/reset.css - reset.css/README.md - - qtip2/dist/*.css - qtip2/dist/jquery.qtip.min* - qtip2/LICENSE - - JSON2/json2.js - - slickgrid/slick.core.js - slickgrid/slick.dataview.js - slickgrid/slick.editors.js - slickgrid/slick.formatters.js - slickgrid/slick.grid.js - slickgrid/plugins/slick.autotooltips.js - slickgrid/plugins/slick.cellrangedecorator.js - slickgrid/plugins/slick.cellrangeselector.js - slickgrid/plugins/slick.cellselectionmodel.js - slickgrid/plugins/slick.rowselectionmodel.js - slickgrid/lib/jquery.event.drag-2.3.0.js - slickgrid/slick.grid.css - slickgrid/images/collapse.gif - slickgrid/images/expand.gif - slickgrid/MIT-LICENSE.txt - - - - - - - copy-package-json - generate-sources - - copy-resources - - - ${frontend.working.dir} - - - ${frontend.dependency.configs} - false - - package.json - package-lock.json - - - + org.apache.nifi + nifi-frontend + true + false + ${update-attribute.ui.working.dir} + update-attribute/**/* + - com.github.eirslett - frontend-maven-plugin - ${frontend.mvn.plugin.version} - - ${frontend.working.dir} - - - - install-node-and-npm - - install-node-and-npm - - generate-resources - - ${node.version} - - - - npm install - - npm - - - run ci - ${frontend.working.dir} - - - - - - org.apache.maven.plugins maven-war-plugin + + ${update-attribute.ui.working.dir}/update-attribute + **/* + src/main/webapp/META-INF META-INF @@ -154,18 +71,7 @@ true - - - - org.apache.rat - apache-rat-plugin - - - src/main/frontend/package.json - src/main/frontend/package-lock.json - src/main/webapp/js/codemirror/ - src/main/webapp/fonts/**/* - + WEB-INF/lib/nifi-frontend*.jar @@ -177,7 +83,6 @@ 2.1.0-SNAPSHOT provided - org.apache.nifi nifi-framework-api @@ -233,5 +138,15 @@ org.apache.commons commons-lang3 + + org.apache.nifi + nifi-web-servlet-shared + 2.1.0-SNAPSHOT + + + org.apache.nifi + nifi-frontend + 2.1.0-SNAPSHOT + diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/frontend/package-lock.json b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/frontend/package-lock.json deleted file mode 100644 index b6503fd5b8..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/frontend/package-lock.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "apache-nifi-update-attribute-ui", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "apache-nifi-update-attribute-ui", - "dependencies": { - "font-awesome": "4.7.0", - "jquery": "3.6.4", - "jquery-ui-dist": "1.13.2", - "JSON2": "0.1.0", - "qtip2": "3.0.3", - "reset.css": "2.0.2", - "slickgrid": "2.4.45" - }, - "engines": { - "node": ">=16.13.2", - "npm": ">=8.1.2" - } - }, - "node_modules/ev-emitter": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ev-emitter/-/ev-emitter-2.1.2.tgz", - "integrity": "sha512-jQ5Ql18hdCQ4qS+RCrbLfz1n+Pags27q5TwMKvZyhp5hh2UULUYZUy1keqj6k6SYsdqIYjnmz7xyyEY0V67B8Q==" - }, - "node_modules/font-awesome": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==", - "engines": { - "node": ">=0.10.3" - } - }, - "node_modules/imagesloaded": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/imagesloaded/-/imagesloaded-5.0.0.tgz", - "integrity": "sha512-/0JGSubc1MTCoDKVmonLHgbifBWHdyLkun+R/151E1c5n79hiSxcd7cB7mPXFgojYu8xnRZv7GYxzKoxW8BetQ==", - "dependencies": { - "ev-emitter": "^2.1.2" - } - }, - "node_modules/jquery": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz", - "integrity": "sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ==" - }, - "node_modules/jquery-ui": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.3.tgz", - "integrity": "sha512-D2YJfswSJRh/B8M/zCowDpNFfwsDmtfnMPwjJTyvl+CBqzpYwQ+gFYIbUUlzijy/Qvoy30H1YhoSui4MNYpRwA==", - "dependencies": { - "jquery": ">=1.8.0 <4.0.0" - } - }, - "node_modules/jquery-ui-dist": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/jquery-ui-dist/-/jquery-ui-dist-1.13.2.tgz", - "integrity": "sha512-oVDRd1NLtTbBwpRKAYdIRgpWVDzeBhfy7Gu0RmY6JEaZtmBq6kDn1pm5SgDiAotrnDS+RoTRXO6xvcNTxA9tOA==", - "dependencies": { - "jquery": ">=1.8.0 <4.0.0" - } - }, - "node_modules/JSON2": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/JSON2/-/JSON2-0.1.0.tgz", - "integrity": "sha512-MRguCg79vy8Kx15/CXzoO5pEPi0tQq7T70mL/t1Hv3G+hVfJVO2BZqX3sl2kbWW08GAmzQYSRfWRtQhmK/eaYA==", - "engines": { - "node": "*" - } - }, - "node_modules/qtip2": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/qtip2/-/qtip2-3.0.3.tgz", - "integrity": "sha512-vfSEVYg1teA4g3RhT9fnBXzEQrkgyU5CrQE8j6WzZs5LBupG+Nq97mFq4BmDKcA6mGSMFiIqm70+ydvWW1KnGg==", - "dependencies": { - "imagesloaded": ">=3.0.0", - "jquery": ">=1.6.0" - } - }, - "node_modules/reset.css": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/reset.css/-/reset.css-2.0.2.tgz", - "integrity": "sha512-HG5RQLYcAxou3yw+Gnzwan1jJCbOcIBZjwoD/YLWuAd8kkuDI/ZqC0uRhY4ReKOOJaM1Y1kvwebHOwK4P8Sevg==" - }, - "node_modules/slickgrid": { - "version": "2.4.45", - "resolved": "https://registry.npmjs.org/slickgrid/-/slickgrid-2.4.45.tgz", - "integrity": "sha512-WvygGTaLU9LnMWZSxqW1agwq8IcDGeCZ289vP1E07eh3ffyLm5TGQsYHXvTwWCHtriZBw+L9RFK/h7TsIMcoLQ==", - "dependencies": { - "jquery": ">=1.8.0", - "jquery-ui": ">=1.8.0" - } - } - } -} diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/frontend/package.json b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/frontend/package.json deleted file mode 100644 index 0c6bd1d542..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/frontend/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "//-01": "Licensed to the Apache Software Foundation (ASF) under one or more", - "//-02": "contributor license agreements. See the NOTICE file distributed with", - "//-03": "this work for additional information regarding copyright ownership.", - "//-04": "The ASF licenses this file to You under the Apache License, Version 2.0", - "//-05": "(the \"License\"); you may not use this file except in compliance with", - "//-06": "the License. You may obtain a copy of the License at", - "//-07": "", - "//-08": "http://www.apache.org/licenses/LICENSE-2.0", - "//-09": "", - "//-10": "Unless required by applicable law or agreed to in writing, software", - "//-11": "distributed under the License is distributed on an \"AS IS\" BASIS,", - "//-12": "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "//-13": "See the License for the specific language governing permissions and", - "//-14": "limitations under the License.", - "name": "apache-nifi-update-attribute-ui", - "description": "Apache NiFi 3rd party client side resources.", - "scripts": { - "ci": "npm ci --ignore-scripts" - }, - "dependencies": { - "font-awesome": "4.7.0", - "jquery": "3.6.4", - "jquery-ui-dist": "1.13.2", - "reset.css": "2.0.2", - "slickgrid": "2.4.45", - "qtip2": "3.0.3", - "JSON2": "0.1.0" - }, - "engines": { - "node": ">=16.13.2", - "npm": ">=8.1.2" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/apache/nifi.git" - }, - "bugs": { - "url": "https://github.com/apache/nifi/issues" - }, - "homepage": "https://github.com/apache/nifi#readme" -} diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/java/org/apache/nifi/update/attributes/api/RuleResource.java b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/java/org/apache/nifi/update/attributes/api/RuleResource.java index 94879c46ea..8f8485a800 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/java/org/apache/nifi/update/attributes/api/RuleResource.java +++ b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/java/org/apache/nifi/update/attributes/api/RuleResource.java @@ -157,12 +157,12 @@ public class RuleResource { } // save the criteria - saveCriteria(requestContext, criteria); + final ComponentDetails componentDetails = saveCriteria(requestContext, criteria); // create the response entity final EvaluationContextEntity responseEntity = new EvaluationContextEntity(); - responseEntity.setClientId(requestEntity.getClientId()); - responseEntity.setRevision(requestEntity.getRevision()); + responseEntity.setClientId(componentDetails.getRevision().getClientId()); + responseEntity.setRevision(componentDetails.getRevision().getVersion()); responseEntity.setProcessorId(requestEntity.getProcessorId()); responseEntity.setFlowFilePolicy(criteria.getFlowFilePolicy().name()); responseEntity.setRuleOrder(criteria.getRuleOrder()); @@ -229,12 +229,12 @@ public class RuleResource { criteria.addRule(rule); // save the criteria - saveCriteria(requestContext, criteria); + final ComponentDetails componentDetails = saveCriteria(requestContext, criteria); // create the response entity final RuleEntity responseEntity = new RuleEntity(); - responseEntity.setClientId(requestEntity.getClientId()); - responseEntity.setRevision(requestEntity.getRevision()); + responseEntity.setClientId(componentDetails.getRevision().getClientId()); + responseEntity.setRevision(componentDetails.getRevision().getVersion()); responseEntity.setProcessorId(requestEntity.getProcessorId()); responseEntity.setRule(DtoFactory.createRuleDTO(rule)); @@ -522,12 +522,12 @@ public class RuleResource { } // save the criteria - saveCriteria(requestContext, criteria); + final ComponentDetails componentDetails = saveCriteria(requestContext, criteria); // create the response entity final RuleEntity responseEntity = new RuleEntity(); - responseEntity.setClientId(requestEntity.getClientId()); - responseEntity.setRevision(requestEntity.getRevision()); + responseEntity.setClientId(componentDetails.getRevision().getClientId()); + responseEntity.setRevision(componentDetails.getRevision().getVersion()); responseEntity.setProcessorId(requestEntity.getProcessorId()); responseEntity.setRule(DtoFactory.createRuleDTO(rule)); @@ -570,12 +570,12 @@ public class RuleResource { criteria.deleteRule(rule); // save the criteria - saveCriteria(requestContext, criteria); + final ComponentDetails componentDetails = saveCriteria(requestContext, criteria); // create the response entity final RulesEntity responseEntity = new RulesEntity(); - responseEntity.setClientId(clientId); - responseEntity.setRevision(revision); + responseEntity.setClientId(componentDetails.getRevision().getClientId()); + responseEntity.setRevision(componentDetails.getRevision().getVersion()); responseEntity.setProcessorId(processorId); // generate the response @@ -615,7 +615,7 @@ public class RuleResource { return criteria; } - private void saveCriteria(final NiFiWebConfigurationRequestContext requestContext, final Criteria criteria) { + private ComponentDetails saveCriteria(final NiFiWebConfigurationRequestContext requestContext, final Criteria criteria) { // serialize the criteria final String annotationData = CriteriaSerDe.serialize(criteria); @@ -624,7 +624,7 @@ public class RuleResource { try { // save the annotation data - configurationContext.updateComponent(requestContext, annotationData, null); + return configurationContext.updateComponent(requestContext, annotationData, null); } catch (final InvalidRevisionException ire) { throw new WebApplicationException(ire, invalidRevision(ire.getMessage())); } catch (final IllegalArgumentException iae) { diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/LICENSE b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/LICENSE index ebe652d246..911f4de6ac 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/LICENSE +++ b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/LICENSE @@ -206,7 +206,10 @@ APACHE NIFI SUBCOMPONENTS: The Apache NiFi project contains subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the following -licenses. +licenses. + +For the binary distribution of nifi-update-attribute-ui see its 3rdpartylicenses.txt +for additional license and notice information. The binary distribution of this product bundles 'Antlr 3' which is available under a "3-clause BSD" license. For details see http://www.antlr3.org/license.html @@ -237,168 +240,3 @@ licenses. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -This product bundles 'Fontello' which is available under an MIT license. - - Copyright (C) 2011 by Vitaly Puzrin - - 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. - -This product bundles 'CodeMirror' which is available under an MIT style license. - - Copyright (C) 2014 by Marijn Haverbeke 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. - -This product bundles 'JQuery' which is available under and MIT style license. - (c) 2005, 2014 jQuery Foundation, Inc. - - 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. - -This product bundles 'jQuery UI' which is available under an MIT style license. -For details see http://jqueryui.com - - Copyright 2014 jQuery Foundation and other contributors - - 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. - -This product bundles 'JQuery Event Drag' which is available under an MIT style -license. - Copyright (c) 2008-2015 ThreeDubMedia - - 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. - -This product bundles 'json2.js' which is available in the 'public domain'. - For details see https://github.com/douglascrockford/JSON-js - -This product bundles 'reset.css' which is available in the 'public domain'. - For details see http://meyerweb.com/eric/tools/css/reset/ - -This product bundles 'SlickGrid v2.4' which is available under an MIT style license. - - Copyright (c) 2009-present Michael Leibman and Ben McIntyre, http://github.com/6pac/slickgrid - - 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. - -This product bundles 'qTip2' which is available under an MIT style license. -For details see http://qtip2.com - - Copyright (c) 2012 Craig Michael Thompson - - 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. \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/NOTICE b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/NOTICE index 9a41bf6b6c..552029a078 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/NOTICE +++ b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/resources/META-INF/NOTICE @@ -4,6 +4,9 @@ Copyright 2014-2024 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). +For the binary distribution of nifi-update-attribute-ui see its 3rdpartylicenses.txt +for additional license and notice information. + ****************** Apache Software License v2 ****************** diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/jsp/worksheet.jsp b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/jsp/worksheet.jsp deleted file mode 100644 index cd0cebf239..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/jsp/worksheet.jsp +++ /dev/null @@ -1,199 +0,0 @@ -<%-- - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---%> -<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Update Attribute - - - - - - - -
-
-
- -
FlowFile Policy
-
-
-
-
-
-
Rules
-
- -
-
-
-
    -
    -
    No rules found.
    - -
    -
    -
    -
    Rule Name
    - -
    No rule selected.
    - -
    -
    -
    Rule Comments
    - -
    -
    -
    -
    Conditions
    -
    - -
    -
    -
    -
    -
    -
    -
    Actions
    - -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    Rule name
    -
    - -
    -
    -
    -
    Copy from existing rule (optional)
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    Expression
    -
    -
    -
    -
    -
    -
    -
    Add
    -
    Cancel
    -
    -
    -
    -
    -
    -
    -
    Attribute
    -
    - -
    -
    -
    -
    Value
    -
    -
    -
    -
    -
    -
    -
    Add
    -
    Cancel
    -
    -
    -
    -
    - - diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/web.xml b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/web.xml index 0418cf5d0a..1e11930f47 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/web.xml +++ b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/web.xml @@ -33,13 +33,19 @@ api /api/* - - - worksheet - /WEB-INF/jsp/worksheet.jsp - + + + + FragmentFilter + org.apache.nifi.web.servlet.filter.QueryStringToFragmentFilter + + + FragmentFilter + + + - worksheet + default diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/common-ui.css b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/common-ui.css deleted file mode 100644 index f07bfd38d6..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/common-ui.css +++ /dev/null @@ -1,734 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), - local('Roboto-Light'), - url('../fonts/Roboto/Roboto-Light.ttf') format('truetype'); -} - -@font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 300; - src: local('Roboto LightItalic'), - local('Roboto-LightItalic'), - url('../fonts/Roboto/Roboto-LightItalic.ttf') format('truetype'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: normal; - src: local('Roboto Regular'), - local('Roboto-Regular'), - url('../fonts/Roboto/Roboto-Regular.ttf') format('truetype'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), - local('Roboto-Medium'), - url('../fonts/Roboto/Roboto-Medium.ttf') format('truetype'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: bold; - src: local('Roboto Bold'), - local('Roboto-Bold'), - url('../fonts/Roboto/Roboto-Bold.ttf') format('truetype'); -} - -@font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: normal; - src: local('Roboto Italic'), - local('Roboto-Italic'), - url('../fonts/Roboto/Roboto-Italic.ttf') format('truetype'); -} - -@font-face { - font-family: 'Roboto Slab'; - font-style: normal; - font-weight: normal; - src: local('RobotoSlab Regular'), - local('RobotoSlab-Regular'), - url('../fonts/Roboto_Slab/RobotoSlab-Regular.ttf') format('truetype'); -} - -@font-face { - font-family: 'Roboto Slab'; - font-style: normal; - font-weight: bold; - src: local('RobotoSlab Bold'), - local('RobotoSlab-Bold'), - url('../fonts/Roboto_Slab/RobotoSlab-Bold.ttf') format('truetype'); -} - -/*remove margin from font awesome*/ -i[class^="fa-"]:before, i[class*=" fa-"]:before { - margin: -1px; -} - -/*remove margin from flowfont*/ -i[class^="icon-"]:before, i[class*=" icon-"]:before { - margin: -2px; -} - -/*shift rotated font awesome icons*/ -.fa-rotate-90 { - left: -2px !important; -} - -body { - display: block; - font-family: Roboto, sans-serif; - overflow: hidden; - color: #262626; -} - -body.md-default-theme, body, html.md-default-theme, html { - background-color: white; -} - -button { - border-radius: 0; -} - -.value-color { - color: #775351; -} - -ul.links li { - float: left; - display: block; - margin-left: 10px; - padding: 4px; - text-align: center; - font-size: 11px; - font-weight: normal; - text-decoration: none; -} - -ul.links span.header-link-over { - color: #264c58; - text-decoration: underline; -} - -/* - General Styles -*/ - -.unselectable { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.clear { - clear: both; -} - -.pointer { - cursor: pointer !important; -} - -.hidden { - display: none; -} - -.blank, .unset, .sensitive { - font-weight: normal !important; - color: #a8a8a8 !important; -} - -.required { - font-weight: bold !important; -} - -.ellipsis { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.ellipsis.multiline { - white-space: normal; -} - -.table-cell { - overflow: hidden; - white-space: nowrap; - line-height: normal; - float: left; - margin-top: 4px; -} - -label { - font-family: 'Roboto Slab', serif; - font-size: 12px; - color: #262626; /*base-font-color*/ - letter-spacing: 0.05rem; - display: block; - margin-bottom: 2px; -} - -/* placeholder styles */ - -*::placeholder { - color: #728e9b; -} -*::-webkit-input-placeholder { - color: #728e9b; -} -*:-moz-placeholder { - color: #728e9b; -} -*::-moz-placeholder { - color: #728e9b; -} -*:-ms-input-placeholder { - color: #728e9b; -} - -input[type=text], input[type=password] { - background-color: #eaeef0; - border: 1px solid #eaeef0; - font-family: Roboto, sans-serif; - font-size: 13px; - padding: 0px 10px 0px 10px; - resize: none; - height: 32px; - width: 100%; - -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; /* Firefox, other Gecko */ - box-sizing: border-box; - color: #262626; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -input:focus, textarea:focus { - background-color: #fff; - border: 1px solid #004849; /*link-color*/ - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.4); - outline: none; -} - -textarea { - background-color: #eaeef0; - border: 1px solid #eaeef0; - font-family: Roboto, sans-serif; - font-size: 13px !important; - padding: 10px 10px; - resize: vertical; - height: 32px; - width: 100%; - -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; /* Firefox, other Gecko */ - box-sizing: border-box; - color: #262626; - white-space: pre-wrap; - overflow-y: auto; - overflow-x: hidden; - text-overflow: ellipsis; -} - -textarea[disabled] { - background: #b2b8c1; - color: #dbdee2; - border: 1px solid #b2b8c1; -} - -ul.property-info { - list-style-type: disc; - margin-left: 10px; -} - -ul.property-info li { - padding: 0px 0px; - margin-left: 10px; -} - -div.nf-checkbox { - cursor: pointer; - width: 12px; - height: 12px; - float: left; - margin-right: 4px; -} - -.nf-checkbox-label { - cursor: pointer; -} - -div.nf-checkbox.disabled { - opacity: .5; - cursor: not-allowed; -} - -div.checkbox-unchecked { - background: transparent url(../images/inputCheckbox.png) no-repeat scroll top left; -} - -div.checkbox-checked { - background: transparent url(../images/inputCheckbox.png) no-repeat scroll top right; -} - -div.ajax-loading { - background-image: url(../images/iconLoading.gif); -} - -div.ajax-complete:before { - font-family: FontAwesome; - content: "\f00c"; - font-size: 16px; - color: #70B59A; -} - -div.ajax-error:before { - font-family: FontAwesome; - content: "\f00d"; - font-size: 16px; - color: #D18686; -} - -.refresh-button { - float: left; -} - -.ui-draggable .dialog-header { - cursor: move; -} - -span.link:focus { - outline: none; -} - -span.link { - cursor: pointer; - color: #004849; /*link-color*/ - font-weight: normal; - display: inline-block; - border-bottom: 1px solid #CCDADB; - font-size: 13px; - font-family: Roboto; -} - -span.link-over { - border-bottom: 1px solid #004849; -} - -span.link-bold { - font-weight: bold; - border-bottom: none; -} - -button { - height: 28px; - width: 28px; - border: 1px solid #CCDADB; /*tint link-color 80%*/ - background-color: rgba(249, 250, 251, 0.97); - color: #004849; -} - -button.refresh-button { - font-size: 16px; -} - -button:hover { - border: 1px solid #004849; /*link-color*/ -} - -button:disabled { - color: #CCDADB !important; /*tint link-color 80%*/ - cursor: not-allowed; - border: 1px solid #CCDADB; /*tint link-color 80%*/ -} - -/* angular material override */ - -button:focus { - outline: none; -} - -div:focus { - outline: none; -} - -input:focus { - background-color: #fff; - border: 1px solid #004849; /*link-color*/ - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.4); - outline: none; -} - -/* filter controls */ - -.filter-controls { - position: absolute; - top: 10px; -} - -.filter-container { - height: 32px; - width: 100%; - float: left; -} - -.filter { - margin-right: 3px; - float: left; -} - -input.filter { - width: 173px; -} - -.filter-type, -.filter-status-dropdown { - float: left; - width: 148px; -} - -.filter-status { - margin-top: 10px; - color: #775351; - font-family: Roboto; - font-size: 13px; - font-weight: 500; - margin-bottom: 5px; -} - -.setting-field.summary-filter-primary-node-container { - display: inline-block; - margin-left: 10px; - margin-top: 8px; - width: auto; -} - -/* overlay icon styles */ - -.stop-configure-icon.fa-stop { - display : inline-block; - font-size: 15px; - position : relative; - top : -1px; -} - -.stop-configure-icon::after { - content : "\f013"; - font-size: 14px; - position : relative; - top : 0px; - left : -8px; - color : #ffffff; - -webkit-text-stroke-width : 1px; - -webkit-text-stroke-color : #004849; - -} - -*.stop-configure-icon + span { - display : inline-block; - padding : 0px 0px 0px 0px; - margin-left : -10px; -} - -/* buttons */ - -button.fa { - color: #004849; - font-size: 16px; - cursor: pointer; - line-height: 25px; -} - -button.icon { - color: #004849; - font-size: 16px; -} - -div.button-icon span { - padding-left: 5px; - vertical-align: middle; - font-style: normal; - font-family: Roboto; - font-size: 11px; -} - -div.button-icon { - float: left !important; - margin-left: 0; - font-size: 18px !important; -} - -div.button.auto-width, -div.button-icon.auto-width { - width : auto !important; -} - -div.button { - height: 32px; - width: 90px; - padding: 0 8px; - text-transform: uppercase; - font-weight: 500; - font-size: 11px; - line-height: 33px; - text-align: center; - border: 0px; - float: right; - position: relative; - background: #728E9B; - color: #fff; - cursor: pointer; -} - -div.button.disabled-button { - color: #a8a8a8 !important; - cursor: not-allowed; - opacity: 0.7; -} - -div.button:hover:not(.disabled-button) { - background-color: #004849; -} - -div.secondary-button { - height: 32px; - width: 90px; - padding: 0 8px; - text-transform: uppercase; - font-weight: 500; - font-size: 11px; - line-height: 33px; - text-align: center; - border: 0px; - float: right; - position: relative; - background: #E3E8EB; - color: #004849; - cursor:pointer -} - -div.secondary-button:hover { - background-color: #C7D2D7; -} - -/* tooltips */ - -.qtip-nifi { - border: 0px !important; - border-radius: 2px; - background-color: rgba(0, 0, 0, 0.54) !important; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); - font-family: Roboto; - font-weight: 500; - font-size: 13px; - color: #fff !important; -} - -div.nifi-tooltip { - border: 0px !important; - border-radius: 2px; - background-color: rgba(0, 0, 0, 0.80) !important; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); - font-family: Roboto; - font-weight: 500; - font-size: 13px; - color: #fff !important; - max-width: 500px; - word-wrap: break-word; -} - -.scrollable { - border-bottom: 1px solid #d0dbe0; -} - -/*context menu */ - -.context-menu { - display: none; - position: absolute; - z-index: 10006; - font-size: 13px; - padding:3px 0; - background-color:rgba(249,250,251,0.97); /*tint base-color 96%*/ - border:1px solid #004849; /*link-color*/ - box-shadow: 0 3px 6px rgba(0,0,0,0.3); - width: 215px; - max-height: inherit; - color:#004849 -} - -div.context-menu-item { - cursor: pointer; - height: 20px; - padding-top: 4px; - padding-left: 4px; -} - -div.context-menu-item.hover { - background-color:#C7D2D7; /*tint base-color 60%*/ - box-shadow:0 1px 1px rgba(0,0,0,0.15); -} - -.context-menu-item-img { - float: left; - width: 16px; - height: 16px; - background-size: cover; -} - -.context-menu-item-img.fa { - position: relative; - top: 2px; - left: 2px; -} - -.context-menu-item-img.icon { - position: relative; - top: 1px; - left: 3px; -} - -div.context-menu-item-text { - margin-left: 4px; - line-height: 16px; - float: left; - color: #262626; -} - -div.context-menu-group-item-img { - float: right; - width: 16px; - height: 16px; - background-size: cover; - font-size: 14px; -} - -div.context-menu-item-separator { - height: 1px; - background-color: #C7D2D7; - margin-top: 3px; - margin-bottom: 3px; -} - -/* search */ - -li.search-no-matches { - padding: 4px; - font-weight: bold; - color: #aaa; - font-style: italic; -} - -/* progress bars */ - -md-progress-linear > div { - background-color: #eaeef0 !important; -} - -.setting { - margin-bottom: 15px; -} - -.setting-name { - font-size: 12px; - font-weight: 500; - font-family: Roboto Slab; - text-transform: capitalize; - padding-bottom: 4px; - color: #262626; -} - -.setting-name .fa { - color: #004849; - margin-left: 5px; -} - -.setting-field .fa { - color: #004849; - margin-left: 5px; - line-height: 22px; -} - -.setting-field { - line-height: normal; - width: 100%; - color: #775351; - font-size: 13px; - font-weight: 500; -} - -.setting-header { - color: #728e9b; - font-size: 12pt; - font-family: 'Roboto Slab'; - font-style: normal; - font-weight: bold; - padding-bottom: 20px; - text-overflow: ellipsis; -} - -.CodeMirror { - border: 1px solid #aaa; - font-family: monospace; - background-color: #fff; - cursor: default; - line-height: normal; -} - -/* jquery ui autocomplete override */ - -.ui-autocomplete { - overflow: auto !important; - border: 1px solid #aaaaaa !important; - font-size: 12px !important; - font-family: Roboto !important; -} - -.ui-menu .ui-menu-item a { - display: block; - border: 1px solid transparent; - line-height: 1.5; - margin: 0 !important; - color: #333 !important; -} - -.ui-menu .ui-menu-item a.ui-state-active { - background: #D4E0E5 !important; - border: 1px solid #999999; -} - -/* jquery ui slider override */ - -.ui-slider-handle.ui-state-active { - background: #fff !important; -} diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/main.css b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/main.css deleted file mode 100644 index e6280d57ce..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/main.css +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - document styles -*/ - -body { - display: block; - font-family: Roboto, sans-serif; - font-size: 62.5%; - overflow: hidden; - color: #262626; -} - -#update-attributes-content { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 5px; -} - -/* new rule */ - -div.new-rule { - float: right; - background: url("../images/buttonNew.png") no-repeat scroll left top transparent; - cursor: pointer; - height: 19px; - width: 19px; -} - -#new-rule-dialog { - display: none; - z-index: 1301; -} - -#update-attributes-content .ui-autocomplete { - max-height: 400px; - overflow: auto; - border: 1px solid #aaaaaa; - z-index: 1351; - border-radius: 0; -} - -#update-attributes-content .ui-menu .ui-menu-item a.ui-state-focus { - background: #D4E0E5 !important; - border: 1px solid #999999; - border-radius: 0; -} - -/* rule list panel */ - -#rule-label-container { - line-height: 28px; -} - -div.large-label { - color: #728e9b; - font-size: 12pt; - font-family: 'Roboto Slab'; - font-style: normal; - font-weight: bold; - padding-bottom: 10px; - text-overflow: ellipsis; - float: left; -} - -div.label { - font-size: 12px; - font-weight: 500; - font-family: Roboto Slab; - padding-bottom: 4px; - color: #262626; -} - -#rule-list-panel { - position: absolute; - top: 5px; - bottom: 5px; - left: 20px; - right: 65%; -} - -#rule-list-container { - overflow-y: auto; - display: none; - position: absolute; - top: 116px; - bottom: 175px; - left: 0px; - right: 0px; - min-height: 45px; -} - -#flowfile-policy-container { - margin-bottom: 20px; -} - -#rule-list { - list-style-type: none; - background: #eaeef0; - padding: 4px 3px 1px 3px; -} - -#rule-list li { - background: #fff; - border-top: 1px solid #CCDADB; - border-right: 1px solid #CCDADB; - border-bottom: 1px solid #CCDADB; - border-left: 1px solid #CCDADB; - color: #004849; - font-weight: 500; - cursor: grab; - cursor: -moz-grab; - cursor: -webkit-grab; - line-height: 32px; - height: 32px; - padding: 0px 10px; - box-shadow: 0 1px 1px rgba(0,0,0,0.4); - margin-bottom: 5px; - display: flex; -} - -#rule-list li.selected { - background: #355B6A; - border-top: 1px solid #AAC1CE; - border-right: 1px solid #85A6B8; - border-bottom: 1px solid #618BA3; - border-left: 1px solid #85A6B8; - color: #fff; - font-weight: bold; - line-height: 32px; - height: 32px; - padding: 0px 10px; -} - -#rule-list li.unsaved { - font-weight: bold; - font-size: 13px; - cursor: default; -} - -div.rule-label { - float: left; - flex-grow: 1; -} - -div.remove-rule { - float: right; - cursor: pointer; - line-height: 32px; -} - -#rule-filter-controls { - position: absolute; - bottom: 63px; - left: 0px; - right: 0px; -} - -#rule-filter-type { - margin-top: 10px; -} - -/* rule details panel */ - -#rule-details-panel { - overflow: auto; - position: absolute; - top: 5px; - bottom: 42px; - left: 37%; - right: 20px; -} - -#no-rule-selected-label { - line-height: 32px; - position: absolute; - left: 0px; - top: 26px; -} - -div.large-label-container { - margin-top: 10px; - line-height: 28px; -} - -#flowfile-policy { - clear: both; -} - -#new-condition { - cursor: pointer; - position: absolute; - right: 0px; -} - -#actions-label { - float: left; - line-height: 28px; -} - -#selected-rule-conditions { - height: 200px; -} - -#selected-rule-comments-container { - margin-top: 75px; -} - -#selected-rule-comments { - height: 50px; -} - -#selected-rule-actions-container { - padding-top: 20px; -} - -#selected-rule-actions-container div.slick-viewport { - overflow-x: hidden !important; -} - -#selected-rule-conditions-container { - padding-top: 8px; -} - -#selected-rule-conditions-container div.slick-viewport { - overflow-x: hidden !important; -} - -#selected-rule-name { - position: absolute; - right: 0px; - top: 26px; -} - -#new-action { - cursor: pointer; - position: absolute; - right: 0px; -} - -#new-rule { - float: right; -} - -#selected-rule-actions { - height: 200px; -} - -#message { - color: #f0ad4e; - margin-left: 20px; - margin-right: 20px; - line-height: 32px; - font-size: 13px; - font-weight: bold; - flex-grow: 1; - overflow: auto; - width: 100%; - height: 41px; -} - -#message-and-save-container { - position: absolute; - right: 0px; - left: 0px; - bottom: 0px; - display: flex; -} - -#selected-rule-save { - margin-right: 20px; - margin-top: 10px; -} - -input.editor-text { - background: none repeat scroll 0 0 transparent; - border: 0 none; - height: 100%; - margin: 0; - outline: 0 none; - padding: 0; - width: 100%; -} - -/* general styles */ - -#ok-dialog { - display: none; -} - -#yes-no-dialog { - display: none; -} - -#new-condition-dialog { - display: none; - z-index: 1299; - cursor: move; - padding: 10px; -} - -#new-condition-dialog .nf-editor { - margin-bottom: 32px; -} - -#new-condition-attribute { - width: 374px; -} - -#new-action-button-container, #new-condition-button-container { - bottom: 0; - left: 0; - position: absolute; - right: 0; -} - -#new-action-dialog { - display: none; - z-index: 1299; - cursor: move; - padding: 10px; -} - -#new-action-dialog .nf-editor { - margin-bottom: 32px; -} - -div.slickgrid-nf-editor .nf-editor { - margin-bottom: 37px; -} - -div.property-detail .nf-editor { - margin-bottom: 30px; -} - -div.rule-setting { - margin-bottom: 10px; -} - -.hidden { - display: none; -} - -.clear { - clear: both; -} - -.unset { - font-style: italic; - color: #aaa; -} - -.pointer { - cursor: pointer; -} - -.info { - color: #004849; - margin-left: 5px; - font-size: 12px; -} diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/slick-nifi-theme.css b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/slick-nifi-theme.css deleted file mode 100755 index a9c67c8ab4..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/slick-nifi-theme.css +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* nifi specific slick grid theme based on the supplied slick-default-theme.css */ - -.slick-header-columns { - color: #fff; - background-color: #728E9B; -} - -.slick-header-column { - background: #728E9B; - color: #fff; - font-weight: bold; - cursor: pointer; -} - -.slick-header-column:hover, .slick-header-column-active { - color: #fff; -} - -.slick-row { - position: absolute; - background: white; - border: 0; - line-height: 22px; -} - -.slick-row:hover { - background-color: #dce3e6 !important; -} - -.slick-cell { - padding-left: 10px; - padding-right: 10px; -} - -.slick-cell.selected { - background-color: #ffef85; - border-top: 1px solid #000000; - border-bottom: 1px solid #000000; - padding-top: 0px; -} - -.slick-row.odd { - background: #f4f6f7; -} - -.slick-cell.invalid { - border-color: #ba554a; -} - -.slickgrid-editor > textarea { - resize: both; -} - -.grid-canvas .slick-cell:first-child{ - border-left: 0; -} - -.slick-viewport .fa { - color: #004849; - line-height: 22px; - margin-top: 0; - width: 12px; - height: 12px; - float: left; - margin-right: 5px; - text-align: center; -} - -.slick-viewport .icon { - color: #004849; - line-height: 24px; - margin-top: 0; - width: 12px; - height: 12px; - float: left; - margin-right: 5px; - text-align: center; -} - -.slick-header.ui-state-default { - background-color: #728E9B; -} - -.slick-header.ui-state-default, .slick-headerrow.ui-state-default { - font-family: Roboto; - font-weight: 500; - font-size: 12px; - font-style: normal; - border: 0px; -} - -.slick-header-column.ui-state-default { - height: 24px; - line-height: 24px; - border-right: 1px solid #728E9B; -} - -.slick-sortable-placeholder { - background: #728E9B; -} - -.slick-row.ui-widget-content, .slick-row.ui-state-active { - font-family: Roboto; - font-size: 12px; - font-style: normal; - font-weight: normal; - color: #262626; -} - -.slick-cell, .slick-headerrow-column { - border-right: 0; - border-top: 0; - border-left: 1px solid #c7d2d7; - border-bottom: 1px solid #c7d2d7; - padding: 1px 2px 5px 10px; -} - -div.status-text { - padding-left: 4px; - line-height: 22px; - overflow: hidden; - text-overflow: ellipsis; - float: left; -} - -.slick-sort-indicator { - float: none !important; -} - -.slick-sort-indicator-desc { - background: url(../images/sort-desc.gif) !important; -} - -.slick-sort-indicator-asc { - background: url(../images/sort-asc.gif) !important; -} \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/LICENSE.txt b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/LICENSE.txt deleted file mode 100755 index d645695673..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Bold.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Bold.ttf deleted file mode 100755 index a355c27cde..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Bold.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Italic.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Italic.ttf deleted file mode 100755 index ff6046d5bf..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Italic.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Light.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Light.ttf deleted file mode 100755 index 94c6bcc67e..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Light.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-LightItalic.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-LightItalic.ttf deleted file mode 100755 index 04cc002302..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-LightItalic.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Medium.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Medium.ttf deleted file mode 100755 index 39c63d7461..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Medium.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Regular.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Regular.ttf deleted file mode 100755 index 8c082c8de0..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto/Roboto-Regular.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/LICENSE.txt b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/LICENSE.txt deleted file mode 100755 index d645695673..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/RobotoSlab-Bold.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/RobotoSlab-Bold.ttf deleted file mode 100755 index df5d1df273..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/RobotoSlab-Bold.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/RobotoSlab-Regular.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/RobotoSlab-Regular.ttf deleted file mode 100755 index eb52a79073..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/Roboto_Slab/RobotoSlab-Regular.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.css b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.css deleted file mode 100644 index 47a8014dab..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.css +++ /dev/null @@ -1,87 +0,0 @@ -@font-face { - font-family: 'flowfont'; - src: url('./flowfont.eot?8516181'); - src: url('./flowfont.eot?8516181#iefix') format('embedded-opentype'), - url('./flowfont.woff2?8516181') format('woff2'), - url('./flowfont.woff?8516181') format('woff'), - url('./flowfont.ttf?8516181') format('truetype'), - url('./flowfont.svg?8516181#flowfont') format('svg'); - font-weight: normal; - font-style: normal; -} -/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ -/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ -/* -@media screen and (-webkit-min-device-pixel-ratio:0) { - @font-face { - font-family: 'flowfont'; - src: url('../font/flowfont.svg?8516181#flowfont') format('svg'); - } -} -*/ -[class^="icon-"]:before, [class*=" icon-"]:before { - font-family: "flowfont"; - font-style: normal; - font-weight: normal; - speak: never; - - display: inline-block; - text-decoration: inherit; - width: 1em; - margin-right: .2em; - text-align: center; - /* opacity: .8; */ - - /* For safety - reset parent styles, that can break glyph codes*/ - font-variant: normal; - text-transform: none; - - /* fix buttons height, for twitter bootstrap */ - line-height: 1em; - - /* Animation center compensation - margins should be symmetric */ - /* remove if not needed */ - margin-left: .2em; - - /* you can be more comfortable with increased icons size */ - /* font-size: 120%; */ - - /* Font smoothing. That was taken from TWBS */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - /* Uncomment for 3D effect */ - /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ -} - -.icon-funnel-add:before { content: '\e800'; } /* '' */ -.icon-counter:before { content: '\e801'; } /* '' */ -.icon-enable-false:before { content: '\e802'; } /* '' */ -.icon-funnel:before { content: '\e803'; } /* '' */ -.icon-group:before { content: '\e804'; } /* '' */ -.icon-group-remote:before { content: '\e805'; } /* '' */ -.icon-label:before { content: '\e806'; } /* '' */ -.icon-processor:before { content: '\e807'; } /* '' */ -.icon-provenance:before { content: '\e808'; } /* '' */ -.icon-template:before { content: '\e809'; } /* '' */ -.icon-transmit-false:before { content: '\e80a'; } /* '' */ -.icon-zoom-actual:before { content: '\e80b'; } /* '' */ -.icon-zoom-fit:before { content: '\e80c'; } /* '' */ -.icon-label-add:before { content: '\e80d'; } /* '' */ -.icon-template-add:before { content: '\e80e'; } /* '' */ -.icon-group-add:before { content: '\e80f'; } /* '' */ -.icon-template-import:before { content: '\e810'; } /* '' */ -.icon-template-save:before { content: '\e811'; } /* '' */ -.icon-group-remote-add:before { content: '\e812'; } /* '' */ -.icon-port-out-add:before { content: '\e813'; } /* '' */ -.icon-port-in-add:before { content: '\e814'; } /* '' */ -.icon-processor-add:before { content: '\e815'; } /* '' */ -.icon-lineage:before { content: '\e816'; } /* '' */ -.icon-import-from-registry-add:before { content: '\e81d'; } /* '' */ -.icon-import-from-registry:before { content: '\e81e'; } /* '' */ -.icon-port-in:before { content: '\e832'; } /* '' */ -.icon-port-out:before { content: '\e833'; } /* '' */ -.icon-connect:before { content: '\e834'; } /* '' */ -.icon-connect-add:before { content: '\e835'; } /* '' */ -.icon-threads:before { content: '\e83f'; } /* '' */ -.icon-drop:before { content: '\e888'; } /* '' */ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.eot b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.eot deleted file mode 100644 index f0d0fe0410..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.eot and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.svg b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.svg deleted file mode 100644 index 5427d62811..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - -Copyright (C) 2023 by original authors @ fontello.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.ttf b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.ttf deleted file mode 100644 index c16425cc28..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.ttf and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.woff b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.woff deleted file mode 100644 index 799454c3b2..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.woff and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.woff2 b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.woff2 deleted file mode 100644 index 1917ea71cd..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/fonts/flowfont/flowfont.woff2 and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/bgInputText.png b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/bgInputText.png deleted file mode 100755 index 54c481ae60..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/bgInputText.png and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/buttonNew.png b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/buttonNew.png deleted file mode 100644 index 2d836ce6bf..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/buttonNew.png and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconDelete.png b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconDelete.png deleted file mode 100644 index 139394820e..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconDelete.png and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconInfo.png b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconInfo.png deleted file mode 100644 index 99a048e447..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconInfo.png and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconLoading.gif b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconLoading.gif deleted file mode 100755 index 4cb019f162..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconLoading.gif and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconResize.png b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconResize.png deleted file mode 100644 index 9d27563ba1..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/iconResize.png and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/inputCheckbox.png b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/inputCheckbox.png deleted file mode 100644 index 564b73bab3..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/inputCheckbox.png and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/sort-asc.gif b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/sort-asc.gif deleted file mode 100755 index 1788551a74..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/sort-asc.gif and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/sort-desc.gif b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/sort-desc.gif deleted file mode 100755 index 3b31122f26..0000000000 Binary files a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/images/sort-desc.gif and /dev/null differ diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/application.js b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/application.js deleted file mode 100644 index 15e5f936fa..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/application.js +++ /dev/null @@ -1,2062 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* global Slick, nf */ - -$(document).ready(function () { - ua.editable = $('#attribute-updater-editable').text() === 'true'; - ua.init(); -}); - -/** - * Determine if an `element` has content overflow and adds a colored bottom border if it does. - * - * @param {HTMLElement} element The DOM element to toggle .scrollable upon. - */ -var toggleScrollable = function (element) { - if ($(element).is(':visible')){ - if (element.offsetHeight < element.scrollHeight || - element.offsetWidth < element.scrollWidth) { - // your element has overflow - $(element).css({ - 'border-bottom': '1px solid #d0dbe0' - }); - } else { - $(element).css({ - 'border-bottom': '1px solid #ffffff' - }); - } - } -}; - -var ua = { - newRuleIndex: 0, - editable: false, - - /** - * Initializes this web application. - * - * @returns {undefined} - */ - init: function () { - - // configure the dialogs - ua.initNewRuleDialog(); - ua.initNewConditionDialog(); - ua.initNewActionDialog(); - ua.initOkDialog(); - ua.initYesNoDialog(); - - // configure the grids - var conditionsGrid = ua.initConditionsGrid(); - var actionsGrid = ua.initActionsGrid(); - - // enable grid resizing - $(window).resize(function (e) { - if (e.target === window) { - var conditionsLock = conditionsGrid.getEditorLock(); - if (!conditionsLock.isActive()) { - conditionsGrid.resizeCanvas(); - } - - var actionsLock = actionsGrid.getEditorLock(); - if (!actionsLock.isActive()) { - actionsGrid.resizeCanvas(); - } - - // toggle .scrollable when appropriate - toggleScrollable($('#rule-details-panel').get(0)); - - // resize dialogs when appropriate - var dialogs = $('.dialog'); - for (var i = 0, len = dialogs.length; i < len; i++) { - if ($(dialogs[i]).is(':visible')){ - setTimeout(function(dialog){ - dialog.modal('resize'); - }, 50, $(dialogs[i])); - } - } - } - }); - - toggleScrollable($('#rule-details-panel').get(0)); - - // initialize the rule list - ua.initRuleList(); - - var destroyEditors = function(){ - if($('.slickgrid-nf-editor').is(':visible') || $('.slickgrid-custom-long-text-editor').is(':visible')){ - - $('#selected-rule-actions').data('gridInstance').getEditController().cancelCurrentEdit(); - $('#selected-rule-conditions').data('gridInstance').getEditController().cancelCurrentEdit(); - } - if( $('#new-condition-dialog').is(':visible')){ - $('#new-condition-dialog').modal('hide'); - } - if( $('#new-action-dialog').is(':visible')){ - $('#new-action-dialog').modal('hide'); - } - }; - - // button click for new rules - $('#new-rule').on('click', function () { - destroyEditors(); - $('#new-rule-dialog').modal('show'); - $('#new-rule-name').focus(); - }); - - // button click for new conditions/actions - $('#new-condition').on('click', function () { - destroyEditors(); - var ruleId = $('#selected-rule-id').text(); - - if (ruleId === '') { - $('#ok-dialog-content').text('No rule is selected.'); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - } else { - // clear the current content - $('#new-condition-expression').nfeditor('setValue', ''); - - // show the dialog - $('#new-condition-dialog').center().show(); - $('#new-condition-expression').nfeditor('refresh').nfeditor('focus'); - } - }); - $('#new-action').on('click', function () { - destroyEditors(); - var ruleId = $('#selected-rule-id').text(); - - if (ruleId === '') { - $('#ok-dialog-content').text('No rule is selected.'); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - } else { - // clear the current content - $('#new-action-attribute').val(''); - $('#new-action-value').nfeditor('setValue', ''); - - // show the dialog - $('#new-action-dialog').center().show(); - $('#new-action-attribute').focus(); - $('#new-action-value').nfeditor('refresh'); - } - }); - - // handle rule name changes - $('#selected-rule-name').on('blur', function () { - var ruleName = $(this).val(); - var ruleItem = $('#rule-list').children('li.selected'); - var rule = ruleItem.data('rule'); - if (rule.name !== ruleName) { - ruleItem.addClass('unsaved'); - } - }).on('focus', function () { - if (ua.editable) { - // commit any condition edits - var conditionsEditController = conditionsGrid.getEditController(); - conditionsEditController.commitCurrentEdit(); - - // commit any action edits - var actionsEditController = actionsGrid.getEditController(); - actionsEditController.commitCurrentEdit(); - } else { - ua.removeAllDetailDialogs(); - } - }); - - // add the handler for saving the rules - $('#selected-rule-save').on('click', function () { - ua.saveSelectedRule(); - }); - - // define the function for filtering the list - $('#rule-filter').keyup(function () { - ua.applyRuleFilter(); - }); - - // filter type - $('#rule-filter-type').combo({ - options: [{ - text: 'by name', - value: 'name' - }, { - text: 'by comments', - value: 'comments' - }, { - text: 'by condition', - value: 'condition' - }, { - text: 'by action', - value: 'action' - }, { - text: 'by any field', - value: 'any' - }], - select: function (option) { - ua.applyRuleFilter(); - } - }); - - // show the save button if appropriate - if (ua.editable) { - $('#selected-rule-save').show(); - $('#new-rule').show(); - $('#new-condition').show(); - $('#new-action').show(); - - // make the combo for the flow file policy - $('#flowfile-policy').combo({ - options: [{ - text: 'use clone', - value: 'USE_CLONE', - description: 'Matching rules are executed with a copy of the original flowfile.' - }, { - text: 'use original', - value: 'USE_ORIGINAL', - description: 'Matching rules are executed with the original flowfile in the order specified below.' - }], - select: function (selectedOption) { - var selectedFlowFilePolicy = $('#selected-flowfile-policy').text(); - - // only consider saving the new flowfile policy when appropriate - if (selectedFlowFilePolicy !== '' && selectedFlowFilePolicy !== selectedOption.value) { - var entity = { - processorId: ua.getProcessorId(), - revision: ua.getRevision(), - clientId: ua.getClientId(), - disconnectedNodeAcknowledged: ua.getDisconnectionAcknowledged(), - flowFilePolicy: selectedOption.value - }; - - $.ajax({ - type: 'PUT', - url: 'api/criteria/evaluation-context', - data: JSON.stringify(entity), - processData: false, - contentType: 'application/json' - }).then(function (evaluationContext) { - ua.showMessage('FlowFile Policy saved as "' + selectedOption.text + '".'); - - // record the newly selected value - $('#selected-flowfile-policy').text(evaluationContext.flowFilePolicy); - }, function (xhr, status, error) { - // show an error message - $('#ok-dialog-content').text('Unable to save new FlowFile Policy due to:' + xhr.responseText); - $('#ok-dialog').modal('setHeaderText', 'Error').modal('show'); - }); - } - } - }); - } else { - // make the rule name read only when not editable - $('#selected-rule-name').attr('readonly', 'readonly'); - - // make the combo for the flow file policy - $('#flowfile-policy').combo({ - options: [{ - text: 'use clone', - value: 'USE_CLONE', - description: 'Matching rules are executed with a copy of the original flowfile.', - disabled: true - }, { - text: 'use original', - value: 'USE_ORIGINAL', - description: 'Matching rules are executed with the original flowfile in the order specified below.', - disabled: true - }] - }); - } - - // load the rules - ua.loadRuleList(); - - // initialize the tooltips - $('.info').qtip({ - style: { - classes: 'ui-tooltip-tipped ui-tooltip-shadow nifi-tooltip' - }, - show: { - solo: true, - effect: false - }, - hide: { - effect: false - }, - position: { - at: 'bottom right', - my: 'top left' - } - }); - }, - - /** - * Initializes the new rule dialog. - * - * @returns {undefined} - */ - initNewRuleDialog: function () { - // new rule dialog configuration - $('#new-rule-dialog').modal({ - headerText: 'Add Rule', - scrollableContentStyle: 'scrollable', - overlayBackground: false, - buttons: [{ - buttonText: 'Add', - color: { - base: '#728E9B', - hover: '#004849', - text: '#ffffff' - }, - handler: { - click: function () { - var ruleName = $('#new-rule-name').val(); - var copyFromRuleField = $('#copy-from-rule-name'); - var copyFromRuleAutoComplete = copyFromRuleField.data('copy-from-rule'); - var copyFromRuleName = copyFromRuleField.val(); - - $.Deferred(function (deferred) { - // rule name must be specified - if (ruleName === '') { - deferred.rejectWith(this, ['The rule name must be specified.']); - return; - } - - // use the rule from autocomplete if present - if (typeof copyFromRuleAutoComplete !== 'undefined' && copyFromRuleAutoComplete !== null) { - deferred.resolveWith(this, [copyFromRuleAutoComplete]); - return; - } - - // use no existing rule - if (copyFromRuleField.hasClass('search') || copyFromRuleName === '') { - deferred.resolve(); - return; - } - - // query to get the details on the specified rule - $.ajax({ - type: 'GET', - data: { - processorId: ua.getProcessorId(), - q: copyFromRuleName - }, - dataType: 'json', - url: 'api/criteria/rules/search-results' - }).then(function (response) { - var rules = response.rules; - - if ($.isArray(rules)) { - if (rules.length > 1) { - deferred.rejectWith(this, ['Unable to copy existing rule. Multiple rules match the name "' + copyFromRuleName + '".']); - } else if (rules.length === 0 || rules[0].name !== copyFromRuleName) { - deferred.rejectWith(this, ['Unable to copy existing rule. Specified rule "' + copyFromRuleName + '" does not exist.']); - } else { - deferred.resolveWith(this, [rules[0]]); - } - } - - }, function (xhr, status, error) { - deferred.rejectWith(this, [xhr.responseText]); - }); - }).then(function (copyFromRule) { - // add the new rule - var ruleElement = ua.createNewRuleItem({ - id: 'unsaved-rule-' + (ua.newRuleIndex++), - name: ruleName - }); - - // select the new rule - ruleElement.click(); - - // if we are copying from another rule load the details - if (typeof copyFromRule !== 'undefined' && copyFromRule !== null) { - var commentsData = $('#selected-rule-comments').val(copyFromRule.comments); - - var conditionsGrid = $('#selected-rule-conditions').data('gridInstance'); - var conditionsData = conditionsGrid.getData(); - conditionsData.setItems(copyFromRule.conditions); - - var actionsGrid = $('#selected-rule-actions').data('gridInstance'); - var actionsData = actionsGrid.getData(); - actionsData.setItems(copyFromRule.actions); - } - - // mark the rule as modified - $('#rule-list').children('li.selected').addClass('unsaved'); - - // ensure the rule list is visible - if ($('#no-rules').is(':visible')) { - ua.showRuleList(); - } else { - // re-apply the rule filter - ua.applyRuleFilter(); - } - }, function (error) { - $('#ok-dialog-content').text(error); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - }); - - // close the dialog - $('#new-rule-dialog').modal('hide'); - } - } - }, { - buttonText: 'Cancel', - color: { - base: '#E3E8EB', - hover: '#C7D2D7', - text: '#004849' - }, - handler: { - click: function () { - // close the dialog - $('#new-rule-dialog').modal('hide'); - } - } - }], - handler: { - close: function () { - // reset the content - $('#new-rule-name').val(''); - $('#copy-from-rule-name').removeData('copy-from-rule').val(''); - } - } - }); - - // initialize the access control auto complete - $.widget('nf.copyFromRuleAutocomplete', $.ui.autocomplete, { - _normalize: function(searchResults) { - var items = []; - items.push(searchResults); - return items; - }, - _resizeMenu: function () { - var ul = this.menu.element; - var padding = ($('#copy-from-rule-name').outerWidth()-$('#copy-from-rule-name').width())/2; - ul.width($('#copy-from-rule-name').outerWidth() - padding); - }, - _renderMenu: function (ul, items) { - var self = this; - - // the object that holds the search results is normalized into a single element array - var searchResults = items[0]; - - if ($.isArray(searchResults.rules) && searchResults.rules.length > 0) { - // go through each matching rule - $.each(searchResults.rules, function (i, rule) { - // add the user match - self._renderRule(ul, rule); - }); - } - - // ensure there were some results - if (ul.children().length === 0) { - ul.append('
  • No rules match
  • '); - } - }, - _renderRule: function (ul, ruleMatch) { - var ruleContent = $('').append($('
    ').text(ruleMatch.name)); - return $('
  • ').data('ui-autocomplete-item', ruleMatch).append(ruleContent).appendTo(ul); - } - }); - - // configure the autocomplete field - $('#copy-from-rule-name').copyFromRuleAutocomplete({ - minLength: 0, - appendTo: '#update-attributes-content', - position: { - my: 'left top', - at: 'left bottom', - offset: '0 1' - }, - source: function (request, response) { - // create the search request - $.ajax({ - type: 'GET', - data: { - processorId: ua.getProcessorId(), - q: request.term - }, - dataType: 'json', - url: 'api/criteria/rules/search-results' - }).done(function (searchResponse) { - response(searchResponse); - }); - }, - select: function (event, ui) { - var rule = ui.item; - - // store the selected rule - $(this).data('copy-from-rule', rule).val(rule.name); - - // stop event propagation - return false; - } - }); - }, - - /** - * Initializes the new condition dialog. - */ - initNewConditionDialog: function () { - var add = function () { - var conditionExpression = $('#new-condition-expression').nfeditor('getValue'); - - // ensure the appropriate details have been specified - if (conditionExpression === '') { - $('#ok-dialog-content').text('Expression is required.'); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - } else { - var condition = { - expression: conditionExpression - }; - - var entity = { - processorId: ua.getProcessorId(), - revision: ua.getRevision(), - clientId: ua.getClientId(), - condition: condition - }; - - // create the condition - $.ajax({ - type: 'POST', - url: 'api/criteria/rules/conditions', - data: JSON.stringify(entity), - processData: false, - contentType: 'application/json' - }).then(function (response) { - var conditionsGrid = $('#selected-rule-conditions').data('gridInstance'); - var conditionsData = conditionsGrid.getData(); - - // add the new condition - conditionsData.addItem(response.condition); - - // mark the selected rule as unsaved - $('#rule-list').children('li.selected').addClass('unsaved'); - - // only hide the the dialog once the condition has been validated - $('#new-condition-dialog').hide(); - }, function (xhr, status, error) { - $('#ok-dialog-content').text(xhr.responseText); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - }); - } - }; - - var cancel = function () { - // close the dialog - $('#new-condition-dialog').hide(); - }; - - // create the editor - $('#new-condition-expression').addClass('nf-editor').nfeditor({ - languageMode: nf.nfel, - width: 374, - minWidth: 374, - height: 135, - minHeight: 135, - resizable: true, - escape: cancel, - enter: add - }); - - // new condition dialog configuration - $('#new-condition-dialog').draggable({ - cancel: 'input, textarea, pre, .button, .nf-editor', - containment: 'parent' - }).on('click', '#new-condition-add', add).on('click', '#new-condition-cancel', cancel); - }, - - /** - * Initializes the new action dialog. - */ - initNewActionDialog: function () { - var add = function () { - var actionAttribute = $('#new-action-attribute').val(); - var actionValue = $('#new-action-value').nfeditor('getValue'); - - // ensure the appropriate details have been specified - if (actionAttribute === '') { - $('#ok-dialog-content').text('Attribute name is required.'); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - } else { - var action = { - attribute: actionAttribute, - value: actionValue - }; - - var entity = { - processorId: ua.getProcessorId(), - revision: ua.getRevision(), - clientId: ua.getClientId(), - action: action - }; - - // create the condition - $.ajax({ - type: 'POST', - url: 'api/criteria/rules/actions', - data: JSON.stringify(entity), - processData: false, - contentType: 'application/json' - }).then(function (response) { - var actionsGrid = $('#selected-rule-actions').data('gridInstance'); - var actionsData = actionsGrid.getData(); - - // add the new condition - actionsData.addItem(response.action); - - // mark the selected rule as unsaved - $('#rule-list').children('li.selected').addClass('unsaved'); - - // only close the dialog once the action has been validated - $('#new-action-dialog').hide(); - }, function (xhr, status, error) { - $('#ok-dialog-content').text(xhr.responseText); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - }); - } - }; - - var cancel = function () { - // close the dialog - $('#new-action-dialog').hide(); - }; - - // create the editor - $('#new-action-value').addClass('nf-editor').nfeditor({ - languageMode: nf.nfel, - width: 374, - minWidth: 374, - height: 135, - minHeight: 135, - resizable: true, - escape: cancel, - enter: add - }); - - // configuration the dialog - $('#new-action-dialog').draggable({ - cancel: 'input, textarea, pre, .button, .nf-editor', - containment: 'parent' - }).on('click', '#new-action-add', add).on('click', '#new-action-cancel', cancel); - - // enable tabs in the property value - $('#new-action-attribute').on('keydown', function (e) { - if (e.which === $.ui.keyCode.ENTER && !e.shiftKey) { - add(); - } else if (e.which === $.ui.keyCode.ESCAPE) { - e.preventDefault(); - cancel(); - } - }); - }, - - /** - * Configure the ok dialog. - * - * @returns {undefined} - */ - initOkDialog: function () { - $('#ok-dialog').modal({ - overlayBackground: false, - scrollableContentStyle: 'scrollable', - buttons: [{ - buttonText: 'Ok', - color: { - base: '#728E9B', - hover: '#004849', - text: '#ffffff' - }, - handler: { - click: function () { - // close the dialog - $('#ok-dialog').modal('hide'); - } - } - }], - handler: { - close: function () { - // clear the content - $('#ok-dialog-content').empty(); - } - } - }); - }, - - /** - * Configure the yes no dialog. - * - * @returns {undefined} - */ - initYesNoDialog: function () { - $('#yes-no-dialog').modal({ - scrollableContentStyle: 'scrollable', - overlayBackground: false - }); - }, - - /** - * Initializes the conditions grid. - * - * @returns {undefined} - */ - initConditionsGrid: function () { - // custom formatter for the actions column - var conditionsActionFormatter = function (row, cell, value, columnDef, dataContext) { - return '
    '; - }; - - // initialize the conditions grid - var conditionsColumns = [ - {id: "expression", name: "Expression", field: "expression", sortable: true, cssClass: 'pointer', editor: ua.getNfelEditor, validator: ua.requiredFieldValidator} - ]; - - var conditionsOptions = { - autosizeColsMode: Slick.GridAutosizeColsMode.LegacyForceFit, - enableCellNavigation: true, - enableColumnReorder: false, - enableAddRow: false, - autoEdit: false - }; - - if (ua.editable) { - // add the delete column - conditionsColumns.push({id: "actions", name: " ", formatter: conditionsActionFormatter, resizable: false, sortable: true, width: 50, maxWidth: 50}); - - // make the table editable - conditionsOptions = $.extend({ - editable: true - }, conditionsOptions); - } - - // initialize the dataview - var conditionsData = new Slick.Data.DataView({inlineFilters: false}); - conditionsData.setItems([]); - - // initialize the grid - var conditionsGrid = new Slick.Grid('#selected-rule-conditions', conditionsData, conditionsColumns, conditionsOptions); - conditionsGrid.setSelectionModel(new Slick.RowSelectionModel()); - conditionsGrid.onBeforeEditCell.subscribe(function (e, args) { - return !ua.preventEdit(e, args); - }); - conditionsGrid.onCellChange.subscribe(function (e, args) { - $('#rule-list').children('li.selected').addClass('unsaved'); - }); - conditionsGrid.onSort.subscribe(function (e, args) { - var comparer = function (a, b) { - return a[args.sortCol.field] > b[args.sortCol.field]; - }; - conditionsData.sort(comparer, args.sortAsc); - }); - conditionsGrid.onClick.subscribe(function (e, args) { - if (ua.editable) { - // edits the clicked cell - conditionsGrid.gotoCell(args.row, args.cell, true); - } else { - ua.showValue(conditionsGrid, args.row, args.cell); - } - - // prevents standard edit logic - e.stopImmediatePropagation(); - }); - - if (ua.editable) { - conditionsGrid.onBeforeCellEditorDestroy.subscribe(function (e, args) { - setTimeout(function() { - conditionsGrid.resizeCanvas(); - - var actionsGrid = $('#selected-rule-actions').data('gridInstance'); - actionsGrid.resizeCanvas(); - }, 50); - }); - } - - // wire up the dataview to the grid - conditionsData.onRowCountChanged.subscribe(function (e, args) { - conditionsGrid.updateRowCount(); - conditionsGrid.render(); - }); - conditionsData.onRowsChanged.subscribe(function (e, args) { - conditionsGrid.invalidateRows(args.rows); - conditionsGrid.render(); - }); - - // hold onto an instance of the grid - $('#selected-rule-conditions').data('gridInstance', conditionsGrid); - return conditionsGrid; - }, - - /** - * Initializes the actions grid. - */ - initActionsGrid: function () { - // custom formatter for the actions column - var actionsActionFormatter = function (row, cell, value, columnDef, dataContext) { - return '
    '; - }; - - // initialize the actions grid - var actionsColumns = [ - {id: "attribute", name: "Attribute", field: "attribute", sortable: true, cssClass: 'pointer', editor: ua.getCustomLongTextEditor, validator: ua.requiredFieldValidator}, - {id: "value", name: "Value", field: "value", sortable: true, cssClass: 'pointer', editor: ua.getNfelEditor, validator: ua.requiredFieldValidator} - ]; - var actionsOptions = { - autosizeColsMode: Slick.GridAutosizeColsMode.LegacyForceFit, - enableCellNavigation: true, - enableColumnReorder: false, - enableAddRow: false, - autoEdit: false - }; - - if (ua.editable) { - // add the delete column - actionsColumns.push({id: "actions", name: " ", formatter: actionsActionFormatter, resizable: false, sortable: true, width: 50, maxWidth: 50}); - - // make the table editable - actionsOptions = $.extend({ - editable: true - }, actionsOptions); - } - - // initialize the dataview - var actionsData = new Slick.Data.DataView({inlineFilters: false}); - actionsData.setItems([]); - - // initialize the grid - var actionsGrid = new Slick.Grid('#selected-rule-actions', actionsData, actionsColumns, actionsOptions); - actionsGrid.setSelectionModel(new Slick.RowSelectionModel()); - actionsGrid.onBeforeEditCell.subscribe(function (e, args) { - return !ua.preventEdit(e, args); - }); - actionsGrid.onCellChange.subscribe(function (e, args) { - $('#rule-list').children('li.selected').addClass('unsaved'); - }); - actionsGrid.onSort.subscribe(function (e, args) { - var comparer = function (a, b) { - return a[args.sortCol.field] > b[args.sortCol.field]; - }; - actionsData.sort(comparer, args.sortAsc); - }); - actionsGrid.onClick.subscribe(function (e, args) { - if (ua.editable) { - // edits the clicked cell - actionsGrid.gotoCell(args.row, args.cell, true); - } else { - ua.showValue(actionsGrid, args.row, args.cell); - } - - // prevents standard edit logic - e.stopImmediatePropagation(); - }); - - if (ua.editable) { - actionsGrid.onBeforeCellEditorDestroy.subscribe(function (e, args) { - setTimeout(function() { - actionsGrid.resizeCanvas(); - - var conditionsGrid = $('#selected-rule-conditions').data('gridInstance'); - conditionsGrid.resizeCanvas(); - }, 50); - }); - } - - // wire up the dataview to the grid - actionsData.onRowCountChanged.subscribe(function (e, args) { - actionsGrid.updateRowCount(); - actionsGrid.render(); - }); - actionsData.onRowsChanged.subscribe(function (e, args) { - actionsGrid.invalidateRows(args.rows); - actionsGrid.render(); - }); - - // hold onto an instance of the grid - $('#selected-rule-actions').data('gridInstance', actionsGrid); - return actionsGrid; - }, - - /** - * Initializes the rule list. - * - * @returns {undefined} - */ - initRuleList: function () { - var conditionsGrid = $('#selected-rule-conditions').data('gridInstance'); - var actionsGrid = $('#selected-rule-actions').data('gridInstance'); - - // handle rule clicks - var ruleList = $('#rule-list'); - - // conditionally support reordering - if (ua.editable) { - // make the list sortable - ruleList.sortable({ - helper: 'clone', - cancel: 'li.unsaved', - update: function (event, ui) { - // attempt save the rule order - ua.saveRuleOrder().fail(function () { - // and if it fails, revert - ruleList.sortable('cancel'); - }); - } - }); - } - - ruleList.on('click', 'li', function () { - var li = $(this); - var rule = li.data('rule'); - - // get the currently selected rule to see if a change is necessary - var currentlySelectedRuleItem = ruleList.children('li.selected'); - - // dont do anything if this is already selected - if (li.attr('id') === currentlySelectedRuleItem.attr('id')) { - return; - } - - // handle saving if necessary - var saveModifiedRule = $.Deferred(function (deferred) { - if (currentlySelectedRuleItem.length) { - // if we're editable, ensure any active edits are committed before continuing - if (ua.editable) { - // commit any condition edits - var conditionsEditController = conditionsGrid.getEditController(); - conditionsEditController.commitCurrentEdit(); - - // commit any action edits - var actionsEditController = actionsGrid.getEditController(); - actionsEditController.commitCurrentEdit(); - } - - // get the currently selected rule - var currentlySelectedRule = currentlySelectedRuleItem.data('rule'); - - // determine if the currently selected rule has been modified - if (currentlySelectedRuleItem.hasClass('unsaved')) { - $('#yes-no-dialog-content').text('Rule \'' + currentlySelectedRule.name + '\' has unsaved changes. Do you want to save?'); - $('#yes-no-dialog').modal('setHeaderText', 'Save Changes').modal('setButtonModel', [{ - buttonText: 'Yes', - color: { - base: '#728E9B', - hover: '#004849', - text: '#ffffff' - }, - handler: { - click: function () { - // close the dialog - $('#yes-no-dialog').modal('hide'); - - // save the previous rule - ua.saveSelectedRule().then(function () { - deferred.resolve(); - }, function () { - deferred.reject(); - }); - } - } - }, { - buttonText: 'No', - color: { - base: '#E3E8EB', - hover: '#C7D2D7', - text: '#004849' - }, - handler: { - click: function () { - // close the dialog - $('#yes-no-dialog').modal('hide'); - - // since changes are being discarded, remove the modified indicator when the rule has been previously saved - if (currentlySelectedRuleItem.attr('id').indexOf('unsaved-rule') === -1) { - currentlySelectedRuleItem.removeClass('unsaved'); - } - - // no save selected... resolve - deferred.resolve(); - } - } - }]).modal('show'); - } else { - deferred.resolve(); - } - } else { - deferred.resolve(); - } - }).promise(); - - // ensure any modified rule is saved before continuing - saveModifiedRule.done(function () { - // select the specified rule - ua.selectRule(rule).done(function (rule) { - // update the selection - li.data('rule', rule).addClass('selected').siblings().removeClass('selected'); - }); - }); - }).on('click', 'div.remove-rule', function (e) { - var li = $(this).closest('li'); - var rule = li.data('rule'); - - // remove the rule - ua.deleteRule(rule).done(function () { - li.remove(); - - // attempt to get the first visible rule - var firstVisibleRule = ruleList.children('li:visible:first'); - if (firstVisibleRule.length === 1) { - firstVisibleRule.click(); - } else { - // only hide the rule list when we know there are no rules (could be filtered out) - if (ruleList.is(':empty')) { - // update the rule list visibility - ua.hideRuleList(); - // clear the selected rule id - $('#selected-rule-id').text(''); - } - - // clear the rule details - ua.clearRuleDetails(); - } - - // re-apply the rule filter - ua.applyRuleFilter(); - }); - - // stop event propagation; - e.stopPropagation(); - }).children(':first').click(); - }, - - /** - * Saves the current rule order - */ - saveRuleOrder: function () { - var ruleList = $('#rule-list'); - - // get the proper order - var ruleOrder = ruleList.sortable('toArray'); - - // only include existing rules - var existingRuleOrder = $.grep(ruleOrder, function (ruleId) { - return ruleId.indexOf('unsaved-rule-') === -1; - }); - - var entity = { - processorId: ua.getProcessorId(), - revision: ua.getRevision(), - clientId: ua.getClientId(), - disconnectedNodeAcknowledged: ua.getDisconnectionAcknowledged(), - ruleOrder: existingRuleOrder - }; - - return $.ajax({ - type: 'PUT', - url: 'api/criteria/evaluation-context', - data: JSON.stringify(entity), - processData: false, - contentType: 'application/json' - }).then(function () { - ua.showMessage('New rule ordering saved.'); - }, function (xhr, status, error) { - // show an error message - $('#ok-dialog-content').text('Unable to reorder the rules due to:' + xhr.responseText); - $('#ok-dialog').modal('setHeaderText', 'Error').modal('show'); - }); - }, - - /** - * Clears the rule details. - */ - clearRuleDetails: function () { - var conditionsGrid = $('#selected-rule-conditions').data('gridInstance'); - var actionsGrid = $('#selected-rule-actions').data('gridInstance'); - - if (ua.editable) { - // cancel any condition edits - var conditionsEditController = conditionsGrid.getEditController(); - conditionsEditController.cancelCurrentEdit(); - - // cancel any action edits - var actionsEditController = actionsGrid.getEditController(); - actionsEditController.cancelCurrentEdit(); - } else { - // ensure all detail dialogs are closed - ua.removeAllDetailDialogs(); - } - - // update the selected rule name - $('#selected-rule-name').val('').hide(); - $('#no-rule-selected-label').show(); - - // clear comments - $('#selected-rule-comments').val(''); - - // clear the grids - var conditionsData = conditionsGrid.getData(); - conditionsData.setItems([]); - - var actionsData = actionsGrid.getData(); - actionsData.setItems([]); - }, - - /** - * Loads the rule list. - * - * @returns {undefined} - */ - loadRuleList: function () { - var ruleList = $.ajax({ - type: 'GET', - url: 'api/criteria/rules?' + $.param({ - processorId: ua.getProcessorId(), - verbose: true - }) - }).done(function (response) { - var rules = response.rules; - - // populate the rules - if (rules && rules.length > 0) { - // add each rules - $.each(rules, function (_, rule) { - ua.createNewRuleItem(rule); - }); - - // show the listing - ua.showRuleList(); - - // select the first rule - $('#rule-list').children('li:visible:first').click(); - } else { - ua.hideRuleList(); - } - }); - - var evaluationContext = $.ajax({ - type: 'GET', - url: 'api/criteria/evaluation-context?' + $.param({ - processorId: ua.getProcessorId() - }) - }).done(function (evaluationContext) { - // record the currently selected value - $('#selected-flowfile-policy').text(evaluationContext.flowFilePolicy); - - // populate the control - $('#flowfile-policy').combo('setSelectedOption', { - value: evaluationContext.flowFilePolicy - }); - }); - - // allow the rule list and evaluation context to load - return $.Deferred(function (deferred) { - $.when(ruleList, evaluationContext).then(function () { - deferred.resolve(); - }, function () { - $('#ok-dialog-content').text('Unable to load the rule list and evalaution criteria.'); - $('#ok-dialog').modal('setHeaderText', 'Error').modal('show'); - - deferred.reject(); - }); - }).promise(); - }, - - /** - * Selects the specified rule and populates its details. - * - * @param {object} rule - * @returns - */ - selectRule: function (rule) { - var ruleId = rule.id; - - var conditionsGrid = $('#selected-rule-conditions').data('gridInstance'); - var conditionsData = conditionsGrid.getData(); - - var actionsGrid = $('#selected-rule-actions').data('gridInstance'); - var actionsData = actionsGrid.getData(); - - return $.Deferred(function (deferred) { - // if this is an existing rule, load it - if (ruleId.indexOf('unsaved-rule-') === -1) { - $.ajax({ - type: 'GET', - url: 'api/criteria/rules/' + encodeURIComponent(ruleId) + '?' + $.param({ - processorId: ua.getProcessorId(), - verbose: true - }) - }).then(function (response) { - deferred.resolveWith(this, [response.rule]); - }, function () { - // show an error message - $('#ok-dialog-content').text('Unable to load details for rule \'' + rule.name + '\'.'); - $('#ok-dialog').modal('setHeaderText', 'Error').modal('show'); - - // reject the deferred - deferred.reject(); - }); - } else { - deferred.resolveWith(this, [$.extend({ - conditions: [], - actions: [] - }, rule)]); - } - }).done(function (selectedRule) { - if (!ua.editable) { - // if we are in read only mode, ensure there are no lingering pop ups - ua.removeAllDetailDialogs(); - } - - // populate the rule details - $('#selected-rule-id').text(selectedRule.id); - $('#selected-rule-name').val(selectedRule.name).show(); - $('#selected-rule-comments').val(selectedRule.comments).show(); - $('#no-rule-selected-label').hide(); - - // populate the rule conditions - conditionsGrid.setSortColumn('expression', true); - conditionsData.setItems(selectedRule.conditions); - conditionsGrid.invalidate(); - - // populate the rule actions - actionsGrid.setSortColumn('attribute', true); - actionsData.setItems(selectedRule.actions); - actionsGrid.invalidate(); - }).promise(); - }, - - /** - * Deletes the specified rule. - * - * @param {type} rule - * @returns - */ - deleteRule: function (rule) { - var ruleId = rule.id; - - return $.Deferred(function (deferred) { - - // confirm the rule deletion - $('#yes-no-dialog-content').text('Delete rule \'' + rule.name + '\'?'); - $('#yes-no-dialog').modal('setHeaderText', 'Delete Confirmation').modal('setButtonModel', [{ - buttonText: 'Yes', - color: { - base: '#728E9B', - hover: '#004849', - text: '#ffffff' - }, - handler: { - click: function () { - // close the dialog - $('#yes-no-dialog').modal('hide'); - - // if this is an existing rule, delete it - if (ruleId.indexOf('unsaved-rule-') === -1) { - $.ajax({ - type: 'DELETE', - url: 'api/criteria/rules/' + encodeURIComponent(ruleId) + '?' + $.param({ - processorId: ua.getProcessorId(), - revision: ua.getRevision(), - clientId: ua.getClientId(), - disconnectedNodeAcknowledged: ua.getDisconnectionAcknowledged(), - verbose: true - }) - }).then(function () { - ua.showMessage('Rule \'' + rule.name + '\' was deleted successfully.'); - deferred.resolve(); - }, function (xhr, status, error) { - $('#ok-dialog-content').text('Unable to delete the rule "' + rule.name + '" because ' + xhr.responseText); - $('#ok-dialog').modal('setHeaderText', 'Error').modal('show'); - deferred.rejectWith(this, arguments); - }); - } else { - deferred.resolve(); - } - } - } - }, { - buttonText: 'No', - color: { - base: '#E3E8EB', - hover: '#C7D2D7', - text: '#004849' - }, - handler: { - click: function () { - // close the dialog - $('#yes-no-dialog').modal('hide'); - - // no save selected... resolve - deferred.reject(); - } - } - }]).modal('show'); - - }).promise(); - }, - - /** - * Saves the currently selected rule. - * - * @returns {unresolved} - */ - saveSelectedRule: function () { - var ruleId = $('#selected-rule-id').text(); - - var conditionsGrid = $('#selected-rule-conditions').data('gridInstance'); - var conditionsData = conditionsGrid.getData(); - - var actionsGrid = $('#selected-rule-actions').data('gridInstance'); - var actionsData = actionsGrid.getData(); - - // ensure a rule was populated - if (ruleId === '') { - $('#ok-dialog-content').text('No rule is selected.'); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - return; - } - - // commit any condition edits - var conditionsEditController = conditionsGrid.getEditController(); - conditionsEditController.commitCurrentEdit(); - - // commit any action edits - var actionsEditController = actionsGrid.getEditController(); - actionsEditController.commitCurrentEdit(); - - // marshal the rule - var rule = { - name: $('#selected-rule-name').val(), - comments: $('#selected-rule-comments').val(), - conditions: conditionsData.getItems(), - actions: actionsData.getItems() - }; - - // marshal the entity - var entity = { - processorId: ua.getProcessorId(), - clientId: ua.getClientId(), - revision: ua.getRevision(), - disconnectedNodeAcknowledged: ua.getDisconnectionAcknowledged(), - rule: rule - }; - - // determine the type of request to make - var url = 'api/criteria/rules'; - var httpMethod = 'POST'; - if (ruleId.indexOf('unsaved-rule-') === -1) { - rule['id'] = ruleId; - httpMethod = 'PUT'; - url = url + '/' + encodeURIComponent(ruleId); - } - - // create/update the rule - return $.ajax({ - type: httpMethod, - url: url, - data: JSON.stringify(entity), - processData: false, - contentType: 'application/json' - }).then(function (response) { - var rule = response.rule; - - // update the id of the rule - $('#selected-rule-id').text(rule.id); - - // update the rule item - var selectedRuleItem = $('#rule-list').children('li.selected'); - selectedRuleItem.data('rule', rule).attr('id', rule.id).removeClass('unsaved').children('div.rule-label').text(rule.name); - - // indicate that that message was saved - ua.showMessage('Rule \'' + rule.name + '\' was saved successfully.'); - }, function (xhr, status, error) { - $('#ok-dialog-content').text(xhr.responseText); - $('#ok-dialog').modal('setHeaderText', 'Error').modal('show'); - }); - }, - - /** - * Deletes the specified row from the specified grid. - * - * @param {type} gridSelector - * @param {type} row - * @returns {undefined} - */ - deleteRow: function (gridSelector, row) { - var grid = $(gridSelector).data('gridInstance'); - var data = grid.getData(); - var item = data.getItem(row); - data.deleteItem(item.id); - - // mark the rule as modified - $('#rule-list').children('li.selected').addClass('unsaved'); - }, - - /** - * Creates a new rule and adds it to the rule list. - * - * @param {type} rule - */ - createNewRuleItem: function (rule) { - var ruleList = $('#rule-list'); - - // create the rule item - var ruleLabel = $('
    ').addClass('rule-label ellipsis').text(rule.name).ellipsis(); - var ruleItem = $('
  • ').attr('id', rule.id).data('rule', rule).append(ruleLabel).appendTo(ruleList); - - if (ua.editable) { - $('
    ').addClass('remove-rule fa fa-close').appendTo(ruleItem); - } else { - // remove the pointer cursor when not editable - ruleItem.css('cursor', 'default'); - } - - // apply the ellipsis - ruleLabel.attr('title', rule.name).ellipsis(); - - return ruleItem; - }, - - /** - * Hides the rule list. - * - * @returns {undefined} - */ - hideRuleList: function () { - $('#rule-list-container').hide(); - $('#no-rules').show(); - $('#rule-filter-controls').hide(); - }, - - /** - * Shows the rule list. - * - * @returns {undefined} - */ - showRuleList: function () { - $('#rule-list-container').show(); - $('#no-rules').hide(); - $('#rule-filter-controls').show(); - - // apply the filter - ua.applyRuleFilter(); - }, - - // Rule filter functions. - - /** - * Get the filter text. - * - * @returns {unresolved} - */ - getFilterText: function () { - return $('#rule-filter').val(); - }, - - /** - * Get the text for the rule to be filtered. - * - * @param {type} li - * @returns {Array} - */ - getRuleText: function (li) { - var rule = li.data('rule'); - var filterType = $('#rule-filter-type').combo('getSelectedOption'); - - // determine the filter type (name, condition, action) - if (filterType.value === 'name') { - return [rule.name]; - } else if (filterType.value === 'comments') { - return [rule.comments]; - } else if (filterType.value === 'condition') { - var conditions = []; - $.each(rule.conditions, function (_, condition) { - conditions.push(condition.expression); - }); - return conditions; - } else if (filterType.value === 'action') { - var actions = []; - $.each(rule.actions, function (_, action) { - actions.push(action.attribute); - actions.push(action.value); - }); - return actions; - } else if (filterType.value === 'any') { - // Return all relevant details for the rule - var allDetails = []; - allDetails.push(rule.name); - allDetails.push(rule.comments); - - // Add conditions - $.each(rule.conditions, function (_, condition) { - allDetails.push(condition.expression); - }); - - // Add actions - $.each(rule.actions, function (_, action) { - allDetails.push(action.attribute); - allDetails.push(action.value); - }); - return allDetails; - } - return []; - }, - - /** - * Apply the rule filter. - * - * @returns {undefined} - */ - applyRuleFilter: function () { - var ruleList = $('#rule-list'); - var ruleItems = ruleList.children(); - var filter = ua.getFilterText(); - - var matchingRules; - if (filter !== '') { - matchingRules = 0; - - // determines if the specified str matches the filter - var matchRuleText = function (ruleText) { - try { - var filterExp = new RegExp(filter, 'i'); - return ruleText.search(filterExp) >= 0; - } catch (e) { - // the regex is invalid - return false; - } - }; - - // update the displayed rule count - $.each(ruleItems, function (_, ruleItem) { - var li = $(ruleItem); - - // get the rule text for matching - var ruleTextList = ua.getRuleText(li); - - // see if any of the text from this rule matches - var ruleMatches = false; - $.each(ruleTextList, function (_, ruleText) { - // update the count and item visibility as appropriate - if (matchRuleText(ruleText)) { - ruleMatches = true; - - // stop iteration - return false; - } - }); - - // handle whether the rule matches - if (ruleMatches || li.hasClass('unsaved')) { - li.show(); - matchingRules++; - } else { - // if we are hiding the currently selected rule, clear it - if (li.hasClass('selected')) { - ua.clearRuleDetails(); - } - - // hide the rule - li.removeClass('selected').hide(); - } - }); - } else { - // ensure every rule is visible - ruleItems.show(); - - // set the number of displayed rules - matchingRules = ruleItems.length; - } - - // update the rule count - $('#displayed-rules').text(matchingRules); - $('#total-rules').text(ruleItems.length); - }, - - /** - * Adds a hover effects to the specified selector. - * - * @param {type} selector - * @param {type} normalStyle - * @param {type} overStyle - */ - addHoverEffect: function (selector, normalStyle, overStyle) { - $(document).on('mouseenter', selector, function () { - $(this).removeClass(normalStyle).addClass(overStyle); - }).on('mouseleave', selector, function () { - $(this).removeClass(overStyle).addClass(normalStyle); - }); - return $(selector).addClass(normalStyle); - }, - - /** - * Shows the specified text and clears it after 10 seconds. - * - * @param {type} text - * @returns {undefined} - */ - showMessage: function (text) { - toggleScrollable($('#message').text(text).get(0)); - setTimeout(function () { - toggleScrollable($('#message').text('').get(0)); - }, 10000); - }, - - /** - * Custom validator for required fields. - * - * @param {type} value - */ - requiredFieldValidator: function (value) { - if (value === null || value === undefined || !value.length) { - return {valid: false, msg: "This is a required field"}; - } else { - return {valid: true, msg: null}; - } - }, - - /** - * Function for prevent cell editing before a rule is selected. - * - * @param {type} e - * @param {type} args - */ - preventEdit: function (e, args) { - var ruleId = $('#selected-rule-id').text(); - - if (ruleId === '') { - $('#ok-dialog-content').text('No rule is selected.'); - $('#ok-dialog').modal('setHeaderText', 'Configuration Error').modal('show'); - return true; - } else { - return false; - } - }, - - /** - * Shows the property value for the specified row and cell. - * - * @param {slickgrid} grid - * @param {integer} row - * @param {integer} cell - */ - showValue: function (grid, row, cell) { - // remove any currently open detail dialogs - ua.removeAllDetailDialogs(); - - var container = $('#update-attributes-content'); - - // get the property in question - var data = grid.getData(); - var item = data.getItem(row); - - // get the column in question - var columns = grid.getColumns(); - var columnDefinition = columns[cell]; - var value = item[columnDefinition.field]; - - // get details about the location of the cell - var cellNode = $(grid.getCellNode(row, cell)); - var offset = cellNode.offset(); - - // create the wrapper - var wrapper = $('
    ').css({ - 'z-index': 100000, - 'position': 'absolute', - 'background': 'white', - 'padding': '5px', - 'overflow': 'hidden', - 'border-radius': '2px', - 'box-shadow': 'rgba(0, 0, 0, 0.247059) 0px 2px 5px', - 'cursor': 'move', - 'top': offset.top - 5, - 'left': offset.left - 5 - }).appendTo(container); - - var editor = null; - - // the attribute column does not get the nfel editor - if (columnDefinition.id === 'attribute') { - // make it draggable - wrapper.draggable({ - containment: 'parent' - }); - - // create the input field - $('').text(content).appendTo($(this)); - - // define a mode for NiFi expression language - if (isFunction(languageMode.color)) { - CodeMirror.commands.autocomplete = function (cm) { - if (isFunction(languageMode.suggest)) { - CodeMirror.showHint(cm, languageMode.suggest); - } - }; - - CodeMirror.defineMode(languageMode.getLanguageId(), languageMode.color); - - // is the editor read only - var readOnly = options.readOnly === true; - - var editor = CodeMirror.fromTextArea(field.get(0), { - mode: languageMode.getLanguageId(), - lineNumbers: true, - matchBrackets: true, - readOnly: readOnly, - extraKeys: { - 'Ctrl-Space': 'autocomplete', - 'Esc': function (cm) { - if (isFunction(options.escape)) { - options.escape(); - } - }, - 'Enter': function (cm) { - if (isFunction(options.enter)) { - options.enter(); - } - } - } - }); - - // set the size - var width = null; - if (isDefinedAndNotNull(options.width)) { - width = options.width; - } - var height = null; - if (isDefinedAndNotNull(options.height)) { - height = options.height; - } - editor.setSize(width, height); - - // store the editor instance for later - $(this).data('editorInstance', editor); - - // get a reference to the codemirror - var codeMirror = $(this).find('.CodeMirror'); - - // reference the code portion - var code = codeMirror.find('.CodeMirror-code'); - - // make this resizable if specified - if (resizable) { - codeMirror.append('
    ').resizable({ - handles: { - 'se': '.ui-resizable-se' - }, - resize: function () { - editor.setSize($(this).width(), $(this).height()); - editor.refresh(); - } - }); - } - - // handle keydown to signify the content has changed - editor.on('change', function (cm, event) { - codeMirror.addClass('modified'); - }); - - // handle keyHandled to stop event propagation/default as necessary - editor.on('keyHandled', function (cm, name, evt) { - if (name === 'Esc') { - // stop propagation of the escape event - evt.stopImmediatePropagation(); - evt.preventDefault(); - } - }); - - // handle sensitive values differently - if (sensitive) { - code.addClass('sensitive'); - - var handleSensitive = function (cm, event) { - if (code.hasClass('sensitive')) { - code.removeClass('sensitive'); - editor.setValue(''); - } - }; - - // remove the sensitive style if necessary - editor.on('mousedown', handleSensitive); - editor.on('keydown', handleSensitive); - } - - // set the min width/height - if (isDefinedAndNotNull(options.minWidth)) { - codeMirror.resizable('option', 'minWidth', options.minWidth); - } - if (isDefinedAndNotNull(options.minHeight)) { - codeMirror.resizable('option', 'minHeight', options.minHeight); - } - } - }); - }, - - /** - * Refreshes the editor. - */ - refresh: function () { - return this.each(function () { - var editor = $(this).data('editorInstance'); - - // ensure the editor was initialized - if (isDefinedAndNotNull(editor)) { - editor.refresh(); - } - }); - }, - - /** - * Sets the size of the editor. - * - * @param {integer} width - * @param {integer} height - */ - setSize: function (width, height) { - return this.each(function () { - var editor = $(this).data('editorInstance'); - - // ensure the editor was initialized - if (isDefinedAndNotNull(editor)) { - editor.setSize(width, height); - } - }); - }, - - /** - * Sets whether the editor is read only. - * - * @param {boolean|string} readOnly - */ - setReadOnly: function (readOnly) { - return this.each(function () { - var editor = $(this).data('editorInstance'); - - // ensure the editor was initialized - if (isDefinedAndNotNull(editor)) { - editor.setOption('readOnly', readOnly); - - if (readOnly === false) { - $(this).find('.CodeMirror').removeClass('blank'); - } else { - $(this).find('.CodeMirror').addClass('blank'); - } - } - }); - }, - - /** - * Gets the value of the editor in the first matching selector. - */ - getValue: function () { - var value; - - this.each(function () { - var editor = $(this).data('editorInstance'); - - // ensure the editor was initialized - if (isDefinedAndNotNull(editor)) { - value = editor.getValue(); - } - - return false; - }); - - return value; - }, - - /** - * Sets the value of the editor. - * - * @param {string} value - */ - setValue: function (value) { - return this.each(function () { - var editor = $(this).data('editorInstance'); - - // ensure the editor was initialized - if (isDefinedAndNotNull(editor)) { - editor.setValue(value); - - // remove the modified marking since the value was reset - $(this).find('.CodeMirror').removeClass('modified'); - } - }); - }, - - /** - * Sets the focus. - */ - focus: function () { - return this.each(function () { - var editor = $(this).data('editorInstance'); - - // ensure the editor was initialized - if (isDefinedAndNotNull(editor)) { - editor.focus(); - } - }); - }, - - /** - * Sets the focus. - */ - selectAll: function () { - return this.each(function () { - var editor = $(this).data('editorInstance'); - - // ensure the editor was initialized - if (isDefinedAndNotNull(editor)) { - editor.execCommand('selectAll'); - } - }); - }, - - /** - * Gets whether the value of the editor in the first matching selector has been modified. - */ - isModified: function () { - var modified; - - this.each(function () { - modified = $(this).find('.CodeMirror').hasClass('modified'); - return false; - }); - - return modified; - }, - - /** - * Destroys the editor. - */ - destroy: function () { - return this.removeData('editorInstance').find('.CodeMirror').removeClass('modified'); - } - }; - - $.fn.nfeditor = function (method) { - if (methods[method]) { - return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); - } else { - return methods.init.apply(this, arguments); - } - }; -})); diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/nfeditor/languages/nfeditor.css b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/nfeditor/languages/nfeditor.css deleted file mode 100644 index 24093e000a..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/nfeditor/languages/nfeditor.css +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -ul.CodeMirror-hints { - overflow-y: scroll; -} - -div.el-section { - margin: 5px 0; -} - -div.el-name { - font-weight: bold; - font-family: monospace; - font-size: 16px; - margin-bottom: 10px; -} - -div.el-header { - float: left; - width: 75px; - font-weight: bold; -} - -ul.el-arguments { - margin-top: 5px; - list-style-type: disc; - list-style-position: inside; -} - -span.el-argument-name { - font-family: monospace; -} - -div.nf-tooltip { - max-width: 350px; -} - -div.mode-hint-tip { - z-index: 14000; - width: 455px; - padding: 10px; - position: absolute; - border: 1px solid #ddd; - border-radius: 2px; - background-color: #fff; - box-shadow: 0 3px 12px rgba(0, 0, 0, 0.16); - font-size: 13px; - display: none; -} - -div.mode-hint-tip > :first-child { - margin-bottom: 15px; -} - -div.mode-hint-tip-title-container { - display: flex; - font-weight: bold; - margin-bottom: 5px; -} - -div.mode-hint-tip-title-container > :first-child { - width: 10px; - margin-right: 10px; - color: #898989; -} - -div.mode-hint-tip-title-container > .mode-supported { - color: #151515; -} - -div.mode-hint-tip-title-container > .mode-unsupported { - color: #676767; -} - -div.mode-hint-tip-description-container { - margin-left: 20px; -} - -div.mode-hint-tip-description-container .hint-pattern { - padding: 0 2px; - letter-spacing: 1px; - font-weight: 400; - background-color: rgba(20, 145, 193, 0.12); -} - -div.mode-hint-tip-description-container .hint-keystroke { - font-weight: 300; - font-style: italic; -} - -div.mode-hint-container { - margin-top: 5px; - display: flex; - justify-content: flex-end; - height: 13px; - font-size: 11px; - color: #898989; -} - -div.mode-hint-element { - cursor: default; - display: flex; - justify-content: space-between; - width: 96px; -} - -div.mode-hint { - display: flex; - font-weight: bold; - font-style: italic; -} - -div.mode-hint-value { - margin-left: 5px; - color: #898989; -} diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/nfeditor/languages/nfel.js b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/nfeditor/languages/nfel.js deleted file mode 100644 index 1f23b08565..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/nfeditor/languages/nfel.js +++ /dev/null @@ -1,1086 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* global define, module, require, exports */ - -/* requires qtip plugin to be loaded first*/ - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define(['jquery', - 'CodeMirror'], - function ($, CodeMirror) { - return (nf.nfel = factory($, CodeMirror)); - }); - } else if (typeof exports === 'object' && typeof module === 'object') { - module.exports = (nf.nfel = - factory(require('jquery'), - require('CodeMirror'))); - } else { - nf.nfel = factory(root.$, - root.CodeMirror); - } -}(this, function ($, CodeMirror) { - 'use strict'; - - /** - * Formats the specified function definition. - * - * @param details - * @returns {jQuery|HTMLElement} - */ - var formatDetails = function (details) { - var detailsContainer = $('
    '); - - // add the detail name - $('
    ').text(details.name).appendTo(detailsContainer); - - // add the detail description - $('
    ').text(details.description).appendTo(detailsContainer); - - // add the function arguments - if (typeof details.args !== 'undefined') { - var argumentsContainer = $('
    ').appendTo(detailsContainer); - $('
    Arguments
    ').appendTo(argumentsContainer); - - if ($.isEmptyObject(details.args)) { - $('None').appendTo(argumentsContainer); - } else { - $('
    ').appendTo(argumentsContainer); - - // add the argument - var argumentContainer = $('
      ').appendTo(argumentsContainer); - $.each(details.args, function (key, value) { - var argName = $('').text(key); - var argDescription = $('').text(value); - $('
    • ').append(argName).append(' - ').append(argDescription).appendTo(argumentContainer); - }); - } - } - - // add the function subject - if (typeof details.subject !== 'undefined') { - var subjectContainer = $('
      ').appendTo(detailsContainer); - $('
      Subject
      ').appendTo(subjectContainer); - $('

      ').text(details.subject).appendTo(subjectContainer); - $('
      ').appendTo(subjectContainer); - } - - // add the function return type - if (typeof details.returnType !== 'undefined') { - var returnTypeContainer = $('
      ').appendTo(detailsContainer); - $('
      Returns
      ').appendTo(returnTypeContainer); - $('

      ').text(details.returnType).appendTo(returnTypeContainer); - $('
      ').appendTo(returnTypeContainer); - } - - return detailsContainer; - }; - - var parameterKeyRegex = /^[a-zA-Z0-9-_. ]+/; - - var parameters = []; - var parameterRegex = new RegExp('^$'); - - var parameterDetails = {}; - var parametersSupported = false; - - var subjectlessFunctions = []; - var functions = []; - - var subjectlessFunctionRegex = new RegExp('^$'); - var functionRegex = new RegExp('^$'); - - var functionDetails = {}; - - $.ajax({ - type: 'GET', - url: '../nifi-docs/html/expression-language-guide.html', - dataType: 'html' - }).done(function(response) { - $(response).find('div.function').each(function() { - var elFunction = $(this); - - var name = elFunction.find('h3').text(); - var description = elFunction.find('span.description').text(); - var returnType = elFunction.find('span.returnType').text(); - - var subject; - var subjectSpan = subject = elFunction.find('span.subject'); - var subjectless = elFunction.find('span.subjectless'); - - // Determine if this function supports running subjectless - if (subjectless.length) { - subjectlessFunctions.push(name); - subject = 'None'; - } - - // Determine if this function supports running with a subject - if (subjectSpan.length) { - functions.push(name); - subject = elFunction.find('span.subject').text(); - } - - // find the arguments - var args = {}; - elFunction.find('span.argName').each(function() { - var argName = $(this); - var argDescription = argName.next('span.argDesc'); - args[argName.text()] = argDescription.text(); - }); - - // record the function details - functionDetails[name] = { - name: name, - description: description, - args: args, - subject: subject, - returnType: returnType - }; - }); - }).always(function() { - // build the regex for all functions discovered - subjectlessFunctionRegex = new RegExp('^((' + subjectlessFunctions.join(')|(') + '))$'); - functionRegex = new RegExp('^((' + functions.join(')|(') + '))$'); - }); - - // valid context states - var SUBJECT = 'subject'; - var FUNCTION = 'function'; - var SUBJECT_OR_FUNCTION = 'subject-or-function'; - var EXPRESSION = 'expression'; - var ARGUMENTS = 'arguments'; - var ARGUMENT = 'argument'; - var PARAMETER = 'parameter'; - var INVALID = 'invalid'; - - /** - * Handles dollars identifies on the stream. - * - * @param {string} startChar The start character - * @param {string} context The context to transition to if we match on the specified start character - * @param {object} stream The character stream - * @param {object} states The states - */ - var handleStart = function (startChar, context, stream, states) { - // determine the number of sequential start chars - var startCharCount = 0; - stream.eatWhile(function (ch) { - if (ch === startChar) { - startCharCount++; - return true; - } - return false; - }); - - // if there is an even number of consecutive start chars this expression is escaped - if (startCharCount % 2 === 0) { - // do not style an escaped expression - return null; - } - - // if there was an odd number of consecutive start chars and there was more than 1 - if (startCharCount > 1) { - // back up one char so we can process the start sequence next iteration - stream.backUp(1); - - // do not style the preceding start chars - return null; - } - - // if the next character isn't the start of an expression - if (stream.peek() === '{') { - // consume the open curly - stream.next(); - - // new expression start - states.push({ - context: context - }); - - // consume any addition whitespace - stream.eatSpace(); - - return 'bracket'; - } - // not a valid start sequence - return null; - }; - - /** - * Handles dollars identifies on the stream. - * - * @param {object} stream The character stream - * @param {object} state The current state - */ - var handleStringLiteral = function (stream, state) { - var current = stream.next(); - var foundTrailing = false; - var foundEscapeChar = false; - - // locate a closing string delimitor - var foundStringLiteral = stream.eatWhile(function (ch) { - // we've just found the trailing delimitor, stop - if (foundTrailing === true) { - return false; - } - - // if this is the trailing delimitor, only consume - // if we did not see the escape character on the - // previous iteration - if (ch === current) { - foundTrailing = foundEscapeChar === false; - } - - // reset the escape character flag - foundEscapeChar = false; - - // if this is the escape character, set the flag - if (ch === '\\') { - foundEscapeChar = true; - } - - // consume this character - return true; - }); - - // if we found the trailing delimitor - if (foundStringLiteral) { - return 'string'; - } - - // there is no trailing delimitor... clear the current context - state.context = INVALID; - stream.skipToEnd(); - return null; - }; - - // the api for the currently selected completion - var currentApi = null; - - // the identifier to cancel showing the tip for the next completion - var showTip = null; - - // the apis of every completion rendered - var apis = []; - - /** - * Listens for select event on the auto complete. - * - * @param {type} completion - * @param {type} element - * @returns {undefined} - */ - var select = function(completion, element) { - hide(); - - currentApi = $(element).qtip('api'); - showTip = setTimeout(function() { - currentApi.show(); - }, 500); - }; - - /** - * Cancels the next tip to show, if applicable. Hides the currently - * visible tip, if applicable. - * - * @returns {undefined} - */ - var hide = function() { - if (showTip !== null) { - clearInterval(showTip); - showTip = null; - } - - if (currentApi !== null) { - currentApi.hide(); - } - }; - - /** - * Listens for close events for the auto complete. - * - * @returns {undefined} - */ - var close = function() { - if (showTip !== null) { - clearInterval(showTip); - showTip = null; - } - - // clear the current api (since its in the apis array) - currentApi = null; - - // destroy the tip from every applicable function - $.each(apis, function(_, api) { - api.destroy(true); - }); - - // reset the apis - apis = []; - }; - - /** - * Renders an auto complete item. - * - * @param {type} element - * @param {type} self - * @param {type} data - * @returns {undefined} - */ - var renderer = function(element, self, data) { - var item = $('
      ').text(data.text); - var li = $(element).qtip({ - content: formatDetails(data.details), - style: { - classes: 'nifi-tooltip nf-tooltip', - tip: false, - width: 350 - }, - show: { - event: false, - effect: false - }, - hide: { - event: false, - effect: false - }, - position: { - at: 'bottom right', - my: 'bottom left', - adjust: { - x: 20 - } - } - }).append(item); - - // record the api for destruction later - apis.push(li.qtip('api')); - }; - - return { - - /** - * Enables parameter referencing. - */ - enableParameters: function () { - parameters = []; - parameterRegex = new RegExp('^$'); - parameterDetails = {}; - - parametersSupported = true; - }, - - /** - * Sets the available parameters. - * - * @param parameterListing - */ - setParameters: function (parameterListing) { - parameterListing.forEach(function (parameter) { - parameters.push(parameter.name); - parameterDetails[parameter.name] = parameter; - }); - - parameterRegex = new RegExp('^((' + parameters.join(')|(') + '))$'); - }, - - /** - * Disables parameter referencing. - */ - disableParameters: function () { - parameters = []; - parameterRegex = new RegExp('^$'); - parameterDetails = {}; - - parametersSupported = false; - }, - - /** - * Returns an object that provides syntax highlighting for NiFi expression language. - */ - color: function () { - // builds the states based off the specified initial value - var buildStates = function (initialStates) { - // each state has a context - var states = initialStates; - - return { - copy: function () { - var copy = []; - for (var i = 0; i < states.length; i++) { - copy.push({ - context: states[i].context - }); - } - return copy; - }, - get: function () { - if (states.length === 0) { - return { - context: null - }; - } else { - return states[states.length - 1]; - } - }, - push: function (state) { - return states.push(state); - }, - pop: function () { - return states.pop(); - } - }; - }; - - return { - startState: function () { - // build states with an empty array - return buildStates([]); - }, - - copyState: function (state) { - // build states with - return buildStates(state.copy()); - }, - - token: function (stream, states) { - // consume any whitespace - if (stream.eatSpace()) { - return null; - } - - // if we've hit the end of the line - if (stream.eol()) { - return null; - } - - // get the current character - var current = stream.peek(); - - // if we've hit some comments... will consume the remainder of the line - if (current === '#') { - // consume the pound - stream.next(); - - var afterPound = stream.peek(); - if (afterPound !== '{') { - stream.skipToEnd(); - return 'comment'; - } else { - // unconsume the pound - stream.backUp(1); - } - } - - // get the current state - var state = states.get(); - - // the current input is invalid - if (state.context === INVALID) { - stream.skipToEnd(); - return null; - } - - // within an expression - if (state.context === EXPRESSION) { - var attributeOrSubjectlessFunctionExpression = /^[^'"#${}()[\],:;\/*\\\s\t\r\n0-9][^'"#${}()[\],:;\/*\\\s\t\r\n]*/; - - // attempt to extract a function name - var attributeOrSubjectlessFunctionName = stream.match(attributeOrSubjectlessFunctionExpression, false); - - // if the result returned a match - if (attributeOrSubjectlessFunctionName !== null && attributeOrSubjectlessFunctionName.length === 1) { - // consume the entire token to better support suggest below - stream.match(attributeOrSubjectlessFunctionExpression); - - // if the result returned a match and is followed by a ( - if (subjectlessFunctionRegex.test(attributeOrSubjectlessFunctionName) && stream.peek() === '(') { - // -------------------- - // subjectless function - // -------------------- - - // context change to function - state.context = ARGUMENTS; - - // style for function - return 'builtin'; - } else { - // --------------------- - // attribute or function - // --------------------- - - // context change to function or subject... not sure yet - state.context = SUBJECT_OR_FUNCTION; - - // this could be an attribute or a partial function name... style as attribute until we know - return 'variable-2'; - } - } else if (current === '\'' || current === '"') { - // -------------- - // string literal - // -------------- - - // handle the string literal - var expressionStringResult = handleStringLiteral(stream, state); - - // considered a quoted variable - if (expressionStringResult !== null) { - // context change to function - state.context = SUBJECT; - } - - return expressionStringResult; - } else if (current === '$') { - // ----------------- - // nested expression - // ----------------- - - var expressionDollarResult = handleStart('$', EXPRESSION, stream, states); - - // if we've found an embedded expression we need to... - if (expressionDollarResult !== null) { - // transition back to subject when this expression completes - state.context = SUBJECT; - } - - return expressionDollarResult; - } else if (current === '#' && parametersSupported) { - // -------------------------- - // nested parameter reference - // -------------------------- - - // handle the nested parameter reference - var parameterReferenceResult = handleStart('#', PARAMETER, stream, states); - - // if we've found an embedded parameter reference we need to... - if (parameterReferenceResult !== null) { - // transition back to subject when this parameter reference completes - state.context = SUBJECT; - } - - return parameterReferenceResult; - } else if (current === '}') { - // ----------------- - // end of expression - // ----------------- - - // consume the close - stream.next(); - - // signifies the end of an expression - if (typeof states.pop() === 'undefined') { - return null; - } else { - // style as expression - return 'bracket'; - } - } else { - // ---------- - // unexpected - // ---------- - - // consume to move along - stream.skipToEnd(); - state.context = INVALID; - - // unexpected... - return null; - } - } - - // within a subject - if (state.context === SUBJECT || state.context === SUBJECT_OR_FUNCTION) { - // if the next character indicates the start of a function call - if (current === ':') { - // ------------------------- - // trigger for function name - // ------------------------- - - // consume the colon and update the context - stream.next(); - state.context = FUNCTION; - - // consume any addition whitespace - stream.eatSpace(); - - // don't style - return null; - } else if (current === '}') { - // ----------------- - // end of expression - // ----------------- - - // consume the close - stream.next(); - - // signifies the end of an expression - if (typeof states.pop() === 'undefined') { - return null; - } else { - // style as expression - return 'bracket'; - } - } else { - // ---------- - // unexpected - // ---------- - - // consume to move along - stream.skipToEnd(); - state.context = INVALID; - - // unexpected... - return null; - } - } - - // within a function - if (state.context === FUNCTION) { - // attempt to extract a function name - var functionName = stream.match(/^[a-zA-Z]+/, false); - - // if the result returned a match - if (functionName !== null && functionName.length === 1) { - // consume the entire token to ensure the whole function - // name is matched. this is an issue with functions like - // substring and substringAfter since 'substringA' would - // match the former and when we really want to autocomplete - // against the latter. - stream.match(/^[a-zA-Z]+/); - - // see if this matches a known function and is followed by ( - if (functionRegex.test(functionName) && stream.peek() === '(') { - // -------- - // function - // -------- - - // change context to arugments - state.context = ARGUMENTS; - - // style for function - return 'builtin'; - } else { - // ------------------------------ - // maybe function... not sure yet - // ------------------------------ - - // not sure yet... - return null; - } - } else { - // ---------- - // unexpected - // ---------- - - // consume and move along - stream.skipToEnd(); - state.context = INVALID; - - // unexpected... - return null; - } - } - - // within arguments - if (state.context === ARGUMENTS) { - if (current === '(') { - // -------------- - // argument start - // -------------- - - // consume the open paranthesis - stream.next(); - - // change context to handle an argument - state.context = ARGUMENT; - - // start of arguments - return null; - } else if (current === ')') { - // -------------- - // argument close - // -------------- - - // consume the close paranthesis - stream.next(); - - // change context to subject for potential chaining - state.context = SUBJECT; - - // end of arguments - return null; - } else if (current === ',') { - // ------------------ - // argument separator - // ------------------ - - // consume the comma - stream.next(); - - // change context back to argument - state.context = ARGUMENT; - - // argument separator - return null; - } else { - // ---------- - // unexpected - // ---------- - - // consume and move along - stream.skipToEnd(); - state.context = INVALID; - - // unexpected... - return null; - } - } - - // within a specific argument - if (state.context === ARGUMENT) { - if (current === '\'' || current === '"') { - // -------------- - // string literal - // -------------- - - // handle the string literal - var argumentStringResult = handleStringLiteral(stream, state); - - // successfully processed a string literal... - if (argumentStringResult !== null) { - // change context back to arguments - state.context = ARGUMENTS; - } - - return argumentStringResult; - } else if (stream.match(/^[-\+]?((([0-9]+\.[0-9]*)([eE][+-]?([0-9])+)?)|((\.[0-9]+)([eE][+-]?([0-9])+)?)|(([0-9]+)([eE][+-]?([0-9])+)))/)) { - // ------------- - // Decimal value - // ------------- - // This matches the following ANTLR spec for deciamls - // - // DECIMAL : OP? ('0'..'9')+ '.' ('0'..'9')* EXP? ^([0-9]+\.[0-9]*)([eE][+-]?([0-9])+)? - // | OP? '.' ('0'..'9')+ EXP? - // | OP? ('0'..'9')+ EXP; - // - // fragment OP: ('+'|'-'); - // fragment EXP : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; - - // change context back to arguments - state.context = ARGUMENTS; - - // style for decimal (use same as number) - return 'number'; - } else if (stream.match(/^[-\+]?[0-9]+/)) { - // ------------- - // integer value - // ------------- - - // change context back to arguments - state.context = ARGUMENTS; - - // style for integers - return 'number'; - } else if (stream.match(/^((true)|(false))/)) { - // ------------- - // boolean value - // ------------- - - // change context back to arguments - state.context = ARGUMENTS; - - // style for boolean (use same as number) - return 'number'; - } else if (current === ')') { - // ---------------------------------- - // argument close (zero arg function) - // ---------------------------------- - - // consume the close paranthesis - stream.next(); - - // change context to subject for potential chaining - state.context = SUBJECT; - - // end of arguments - return null; - } else if (current === '$') { - // ----------------- - // nested expression - // ----------------- - - // handle the nested expression - var argumentDollarResult = handleStart('$', EXPRESSION, stream, states); - - // if we've found an embedded expression we need to... - if (argumentDollarResult !== null) { - // transition back to arguments when then expression completes - state.context = ARGUMENTS; - } - - return argumentDollarResult; - } else if (current === '#' && parametersSupported) { - // -------------------------- - // nested parameter reference - // -------------------------- - - // handle the nested parameter reference - var parameterReferenceResult = handleStart('#', PARAMETER, stream, states); - - // if we've found an embedded parameter reference we need to... - if (parameterReferenceResult !== null) { - // transition back to arguments when this parameter reference completes - state.context = ARGUMENTS; - } - - return parameterReferenceResult; - } else { - // ---------- - // unexpected - // ---------- - - // consume and move along - stream.skipToEnd(); - state.context = INVALID; - - // unexpected... - return null; - } - } - - // within a parameter reference - if (state.context === PARAMETER) { - // attempt to extract a parameter name - var parameterName = stream.match(parameterKeyRegex, false); - - // if the result returned a match - if (parameterName !== null && parameterName.length === 1) { - // consume the entire token to ensure the whole function - // name is matched. this is an issue with functions like - // substring and substringAfter since 'substringA' would - // match the former and when we really want to autocomplete - // against the latter. - stream.match(parameterKeyRegex); - - // see if this matches a known function and is followed by ( - if (parameterRegex.test(parameterName)) { - // ------------------ - // resolved parameter - // ------------------ - - // style for function - return 'builtin'; - } else { - // -------------------- - // unresolved parameter - // -------------------- - - // style for function - return 'string'; - } - } - - if (current === '}') { - // ----------------- - // end of expression - // ----------------- - - // consume the close - stream.next(); - - // signifies the end of an parameter reference - if (typeof states.pop() === 'undefined') { - return null; - } else { - // style as expression - return 'bracket'; - } - } else { - // ---------- - // unexpected - // ---------- - - // consume and move along - stream.skipToEnd(); - state.context = INVALID; - - // unexpected... - return null; - } - } - - // signifies the potential start of an expression - if (current === '$') { - return handleStart('$', EXPRESSION, stream, states); - } - - // signifies the potential start of a parameter reference - if (current === '#' && parametersSupported) { - return handleStart('#', PARAMETER, stream, states); - } - - // signifies the end of an expression - if (current === '}') { - stream.next(); - if (typeof states.pop() === 'undefined') { - return null; - } else { - return 'bracket'; - } - } - - // ---------------------------------------------------------- - // extra characters that are around expression[s] end up here - // ---------------------------------------------------------- - - // consume the character to keep things moving along - stream.next(); - return null; - } - }; - }, - - /** - * Returns the suggestions for the content at the current cursor. - * - * @param {type} editor - */ - suggest: function (editor) { - // Find the token at the cursor - var cursor = editor.getCursor(); - var token = editor.getTokenAt(cursor); - var includeAll = false; - var state = token.state.get(); - - // whether or not the current context is within a function - var isFunction = function (context) { - // attempting to match a function name or already successfully matched a function name - return context === FUNCTION || context === ARGUMENTS; - }; - - // whether or not the current context is within a subject-less funciton - var isSubjectlessFunction = function (context) { - // within an expression when no characters are found or when the string may be an attribute or a function - return context === EXPRESSION || context === SUBJECT_OR_FUNCTION; - }; - - // whether or not the current context is within a parameter reference - var isParameterReference = function (context) { - // attempting to match a function name or already successfully matched a function name - return context === PARAMETER; - }; - - // only support suggestion in certain cases - var context = state.context; - if (!isSubjectlessFunction(context) && !isFunction(context) && !isParameterReference(context)) { - return null; - } - - // lower case for case insensitive comparison - var value = token.string.toLowerCase(); - - // trim to ignore extra whitespace - var trimmed = $.trim(value); - - // identify potential patterns and increment the start location appropriately - if (trimmed === '${' || trimmed === ':' || trimmed === '#{') { - includeAll = true; - token.start += value.length; - } - - var options = functions; - var useFunctionDetails = true; - if (isSubjectlessFunction(context)) { - options = subjectlessFunctions; - } else if (isParameterReference(context)) { - options = parameters; - useFunctionDetails = false; - } - - var getCompletions = function(options) { - var found = []; - - $.each(options, function (i, opt) { - if ($.inArray(opt, found) === -1) { - if (includeAll || opt.toLowerCase().indexOf(value) === 0) { - found.push({ - text: opt, - details: useFunctionDetails ? functionDetails[opt] : parameterDetails[opt], - render: renderer - }); - } - } - }); - - return found; - }; - - // get the suggestions for the current context - var completionList = getCompletions(options); - completionList = completionList.sort(function (a, b) { - var aLower = a.text.toLowerCase(); - var bLower = b.text.toLowerCase(); - return aLower === bLower ? 0 : aLower > bLower ? 1 : -1; - }); - - var completions = { - list: completionList, - from: { - line: cursor.line, - ch: token.start - }, - to: { - line: cursor.line, - ch: token.end - } - }; - - CodeMirror.on(completions, 'select', select); - CodeMirror.on(completions, 'close', close); - - return completions; - }, - - /** - * Returns the language id. - * - * @returns {string} language id - */ - getLanguageId: function () { - return 'nfel'; - }, - - /** - * Returns whether this editor mode supports EL. - * - * @returns {boolean} Whether the editor supports EL - */ - supportsEl: function () { - return true; - }, - - /** - * Returns whether this editor mode supports parameter reference. - * - * @returns {boolean} Whether the editor supports parameter reference - */ - supportsParameterReference: function () { - return parametersSupported; - } - }; -})); diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-ajax-setup.js b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-ajax-setup.js deleted file mode 100644 index 193de91065..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-ajax-setup.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* global define, module, require, exports */ - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define(['jquery', - 'nf.AuthorizationStorage'], - function ($, nfAuthorizationStorage) { - return (nf.AjaxSetup = factory($, nfAuthorizationStorage)); - }); - } else if (typeof exports === 'object' && typeof module === 'object') { - module.exports = (nf.AjaxSetup = factory(require('jquery'), - require('nf.AuthorizationStorage'))); - } else { - nf.AjaxSetup = factory(root.$, - root.nf.AuthorizationStorage); - } -}(this, function ($, nfAuthorizationStorage) { - /** - * Performs ajax setup for use within NiFi. - */ - $(document).ready(function ($) { - $.ajaxSetup({ - 'beforeSend': function (xhr) { - // Get the Request Token for CSRF mitigation on and send on all requests - var requestToken = nfAuthorizationStorage.getRequestToken(); - if (requestToken !== null) { - xhr.setRequestHeader('Request-Token', requestToken); - } - } - }); - }); -})); \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-authorization-storage.js b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-authorization-storage.js deleted file mode 100644 index 1847c09fe1..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-authorization-storage.js +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* global define, module, require, exports */ - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define([], function () { - return (nf.AuthorizationStorage = factory()); - }); - } else if (typeof exports === 'object' && typeof module === 'object') { - module.exports = (nf.AuthorizationStorage = factory()); - } else { - nf.AuthorizationStorage = factory(); - } -}(this, function () { - var TOKEN_ITEM_KEY = 'Access-Token-Expiration'; - - var REQUEST_TOKEN_PATTERN = new RegExp('Request-Token=([^;]+)'); - - return { - /** - * Get Request Token from document cookies - * - * @return Request Token string or null when not found - */ - getRequestToken: function () { - var requestToken = null; - var requestTokenMatcher = REQUEST_TOKEN_PATTERN.exec(document.cookie); - if (requestTokenMatcher) { - requestToken = requestTokenMatcher[1]; - } - return requestToken; - }, - - /** - * Get Token from Session Storage - * - * @return Bearer Token string - */ - getToken: function () { - return sessionStorage.getItem(TOKEN_ITEM_KEY); - }, - - /** - * Has Token returns the status of whether Session Storage contains the Token - * - * @return Boolean status of whether Session Storage contains the Token - */ - hasToken: function () { - var token = this.getToken(); - return typeof token === 'string'; - }, - - /** - * Remove Token from Session Storage - * - */ - removeToken: function () { - sessionStorage.removeItem(TOKEN_ITEM_KEY); - }, - - /** - * Set Token in Session Storage - * - * @param token Token String - */ - setToken: function (token) { - sessionStorage.setItem(TOKEN_ITEM_KEY, token); - } - }; -})); \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-storage.js b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-storage.js deleted file mode 100644 index 155b84461c..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-storage.js +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* global define, module, require, exports */ - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define([], function () { - return (nf.Storage = factory()); - }); - } else if (typeof exports === 'object' && typeof module === 'object') { - module.exports = (nf.Storage = factory()); - } else { - nf.Storage = factory(); - } -}(this, function () { - - var disconnectionAcknowledged = false; - - // Store items for two days before being eligible for removal. - var MILLIS_PER_DAY = 86400000; - var TWO_DAYS = MILLIS_PER_DAY * 2; - - var isUndefined = function (obj) { - return typeof obj === 'undefined'; - }; - - var isNull = function (obj) { - return obj === null; - }; - - var isDefinedAndNotNull = function (obj) { - return !isUndefined(obj) && !isNull(obj); - }; - - /** - * Checks the expiration for the specified entry. - * - * @param {object} entry - * @returns {boolean} - */ - var checkExpiration = function (entry) { - if (isDefinedAndNotNull(entry.expires)) { - // get the expiration - var expires = new Date(entry.expires); - var now = new Date(); - - // return whether the expiration date has passed - return expires.valueOf() < now.valueOf(); - } else { - return false; - } - }; - - /** - * Gets an enty for the key. The entry expiration is not checked. - * - * @param {string} key - */ - var getEntry = function (key) { - try { - // parse the entry - var entry = JSON.parse(localStorage.getItem(key)); - - // ensure the entry and item are present - if (isDefinedAndNotNull(entry)) { - return entry; - } else { - return null; - } - } catch (e) { - return null; - } - }; - - return { - /** - * Initializes the storage. Items will be persisted for two days. Once the scripts runs - * thereafter, all eligible items will be removed. This strategy does not support persistence. - */ - init: function () { - for (var i = 0; i < localStorage.length; i++) { - try { - // get the next item - var key = localStorage.key(i); - - // attempt to get the item which will expire if necessary - this.getItem(key); - } catch (e) { - } - } - }, - - acknowledgeDisconnection: function () { - disconnectionAcknowledged = true; - }, - - resetDisconnectionAcknowledgement: function () { - disconnectionAcknowledged = false; - }, - - isDisconnectionAcknowledged: function () { - return disconnectionAcknowledged; - }, - - /** - * Stores the specified item. - * - * @param {string} key - * @param {object} item - * @param {integer} expires - */ - setItem: function (key, item, expires) { - // calculate the expiration - expires = isDefinedAndNotNull(expires) ? expires : new Date().valueOf() + TWO_DAYS; - - // create the entry - var entry = { - expires: expires, - item: item - }; - - // store the item - localStorage.setItem(key, JSON.stringify(entry)); - }, - - /** - * Returns whether there is an entry for this key. This will not check the expiration. If - * the entry is expired, it will return null on a subsequent getItem invocation. - * - * @param {string} key - * @returns {boolean} - */ - hasItem: function (key) { - return getEntry(key) !== null; - }, - - /** - * Gets the item with the specified key. If an item with this key does - * not exist, null is returned. If an item exists but cannot be parsed - * or is malformed/unrecognized, null is returned. - * - * @param {type} key - */ - getItem: function (key) { - var entry = getEntry(key); - if (entry === null) { - return null; - } - - // if the entry is expired, drop it and return null - if (checkExpiration(entry)) { - this.removeItem(key); - return null; - } - - // if the entry has the specified field return its value - if (isDefinedAndNotNull(entry['item'])) { - return entry['item']; - } else { - return null; - } - }, - - /** - * Gets the expiration for the specified item. This will not check the expiration. If - * the entry is expired, it will return null on a subsequent getItem invocation. - * - * @param {string} key - * @returns {integer} - */ - getItemExpiration: function (key) { - var entry = getEntry(key); - if (entry === null) { - return null; - } - - // if the entry has the specified field return its value - if (isDefinedAndNotNull(entry['expires'])) { - return entry['expires']; - } else { - return null; - } - }, - - /** - * Removes the item with the specified key. - * - * @param {type} key - */ - removeItem: function (key) { - localStorage.removeItem(key); - } - }; -})); \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-universal-capture.js b/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-universal-capture.js deleted file mode 100644 index c0cc37d624..0000000000 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-universal-capture.js +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* global define, module, require, exports */ - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define(['jquery'], function ($) { - return (nf.UniversalCapture = factory($)); - }); - } else if (typeof exports === 'object' && typeof module === 'object') { - module.exports = (nf.UniversalCapture = factory(require('jquery'))); - } else { - nf.UniversalCapture = factory(root.$); - } -}(this, function ($) { - 'use strict'; - - /** - * Captures keydown on the window to ensure certain keystrokes are handled in a consistent manner, particularly those - * that can lead to browser navigation/reload. - */ - $(document).ready(function ($) { - // setup a listener to ensure keystrokes are being overridden in a consistent manner - $(window).on('keydown', function (evt) { - // consider escape, before checking dialogs - var isCtrl = evt.ctrlKey || evt.metaKey; - if (!isCtrl && evt.keyCode === 27) { - // esc - - // prevent escape when editing a property with allowable values - that component does not handle key - // events so it can bubble up to here. once here we are unable to cancel the current edit so we simply - // return. this is not an issue for viewing in read only mode as the table is not in an edit mode. this - // is not an issue for other fields as they can handle key events locally and cancel the edit appropriately - var visibleCombo = $('div.value-combo'); - if (visibleCombo.is(':visible') && visibleCombo.parent().hasClass('combo-editor')) { - return; - } - - // consider property detail dialogs - if ($('div.property-detail').is(':visible')) { - nfUniversalDialog.removeAllPropertyDetailDialogs(); - - // prevent further bubbling as we're already handled it - evt.stopImmediatePropagation(); - evt.preventDefault(); - } else { - var target = $(evt.target); - if (target.length) { - // special handling for body as the target - var cancellables = $('.cancellable'); - if (cancellables.length) { - var zIndexMax = null; - var dialogMax = null; - - // identify the top most cancellable - $.each(cancellables, function (_, cancellable) { - var dialog = $(cancellable); - var zIndex = dialog.css('zIndex'); - - // if the dialog has a zIndex consider it - if (dialog.is(':visible') && (zIndex !== null && typeof zIndex !== 'undefined')) { - zIndex = parseInt(zIndex, 10); - if (zIndexMax === null || zIndex > zIndexMax) { - zIndexMax = zIndex; - dialogMax = dialog; - } - } - }); - - // if we've identified a dialog to close do so and stop propagation - if (dialogMax !== null) { - // hide the cancellable - if (dialogMax.hasClass('modal')) { - dialogMax.modal('hide'); - } else { - dialogMax.hide(); - } - - // prevent further bubbling as we're already handled it - evt.stopImmediatePropagation(); - evt.preventDefault(); - - return; - } - } - - // now see if we're in a frame - if (top !== window) { - // and our parent has shell defined - if (typeof parent.nf !== 'undefined' && typeof parent.nf.Shell !== 'undefined') { - parent.$('#shell-close-button').click(); - - // prevent further bubbling as we're already handled it - evt.stopImmediatePropagation(); - evt.preventDefault(); - - return; - } - } - } - } - } else { - if (isCtrl) { - if (evt.keyCode === 82) { - // ctrl-r - evt.preventDefault(); - } - } else { - if (!$('input, textarea').is(':focus') && (evt.keyCode == 8 || evt.keyCode === 46)) { - // backspace or delete - evt.preventDefault(); - } - } - } - }); - }); - - var nfUniversalDialog = { - /** - * Removes all read only property detail dialogs. - */ - removeAllPropertyDetailDialogs: function () { - var propertyDetails = $('body').find('div.property-detail'); - propertyDetails.find('div.nf-editor').nfeditor('destroy'); // look for any nfel editors - propertyDetails.find('div.value-combo').combo('destroy'); // look for any combos - propertyDetails.hide().remove(); - } - }; - - return nfUniversalDialog; -})); diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java index 2f59c6c7b1..9d2be4ce6a 100644 --- a/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java +++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java @@ -26,6 +26,7 @@ import java.util.Map; public class ComponentDetails { private final String id; + private final Revision revision; private final String name; private final String type; private final String state; @@ -37,6 +38,7 @@ public class ComponentDetails { private ComponentDetails(final Builder builder) { this.id = builder.id; + this.revision = builder.revision; this.name = builder.name; this.type = builder.type; this.state = builder.state; @@ -44,7 +46,6 @@ public class ComponentDetails { this.properties = builder.properties; this.descriptors = builder.descriptors; this.validationErrors = builder.validationErrors; - } /** @@ -54,6 +55,13 @@ public class ComponentDetails { return id; } + /** + * @return component revision + */ + public Revision getRevision() { + return revision; + } + /** * @return component name */ @@ -107,6 +115,7 @@ public class ComponentDetails { public static final class Builder { private String id; + private Revision revision; private String name; private String type; private String state; @@ -121,6 +130,11 @@ public class ComponentDetails { return this; } + public Builder revision(final Revision revision) { + this.revision = revision; + return this; + } + public Builder name(final String name) { this.name = name; return this; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeParameterReference.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeParameterReference.java index 60a6d743f6..fb89bc37fd 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeParameterReference.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeParameterReference.java @@ -62,6 +62,26 @@ public class AuthorizeParameterReference { } } + public static void authorizeParameterReferences(final String annotationData, final Authorizer authorizer, final Authorizable parameterContextAuthorizable, final NiFiUser user) { + if (annotationData == null || parameterContextAuthorizable == null) { + return; + } + + final ParameterParser parameterParser = new ExpressionLanguageAgnosticParameterParser(); + + boolean referencesParameter = false; + + // Check if any Parameter is referenced. If so, user must have READ policy on the Parameter Context + ParameterTokenList tokenList = parameterParser.parseTokens(annotationData); + if (!tokenList.toReferenceList().isEmpty()) { + referencesParameter = true; + } + + if (referencesParameter) { + parameterContextAuthorizable.authorize(authorizer, RequestAction.READ, user); + } + } + public static void authorizeParameterReferences(final ComponentAuthorizable authorizable, final Authorizer authorizer, final Authorizable parameterContextAuthorizable, final NiFiUser user) { if (parameterContextAuthorizable == null) { return; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java index 475e7acf9d..3e57058705 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java @@ -25,6 +25,7 @@ import org.apache.nifi.action.component.details.FlowChangeExtensionDetails; import org.apache.nifi.action.details.FlowChangeConfigureDetails; import org.apache.nifi.admin.service.AuditService; import org.apache.nifi.authorization.AuthorizeControllerServiceReference; +import org.apache.nifi.authorization.AuthorizeParameterReference; import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.ComponentAuthorizable; import org.apache.nifi.authorization.RequestAction; @@ -102,6 +103,10 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration }); } + private Revision getRevision(final RevisionDTO revision, final String id) { + return new Revision(revision.getVersion(), revision.getClientId(), id); + } + @Override public ControllerService getControllerService(final String serviceIdentifier, final String componentId) { final NiFiUser user = NiFiUserUtils.getNiFiUser(); @@ -354,7 +359,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); }); - final ProcessorDTO processor; + ProcessorEntity entity; if (properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -380,17 +385,16 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return processor - ProcessorEntity entity = (ProcessorEntity) nodeResponse.getUpdatedEntity(); + entity = (ProcessorEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ProcessorEntity.class); } - processor = entity.getComponent(); } else { - processor = serviceFacade.getProcessor(id).getComponent(); + entity = serviceFacade.getProcessor(id); } // return the processor info - return getComponentConfiguration(processor); + return getComponentConfiguration(entity); } @Override @@ -407,9 +411,13 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration // authorize any referenced service AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup); + + // authorize any parameter references + AuthorizeParameterReference.authorizeParameterReferences(properties, authorizer, authorizable.getParameterContext(), user); + AuthorizeParameterReference.authorizeParameterReferences(annotationData, authorizer, authorizable.getParameterContext(), user); }); - final ProcessorDTO processor; + ProcessorEntity entity; if (StandardNiFiWebConfigurationContext.this.properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -449,20 +457,18 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return processor - ProcessorEntity entity = (ProcessorEntity) nodeResponse.getUpdatedEntity(); + entity = (ProcessorEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ProcessorEntity.class); } - processor = entity.getComponent(); } else { // update processor within write lock ProcessorDTO processorDTO = buildProcessorDto(id, annotationData, properties); - final ProcessorEntity entity = serviceFacade.updateProcessor(revision, processorDTO); - processor = entity.getComponent(); + entity = serviceFacade.updateProcessor(revision, processorDTO); } // return the processor info - return getComponentConfiguration(processor); + return getComponentConfiguration(entity); } private ProcessorDTO buildProcessorDto(String id, final String annotationData, Map properties) { @@ -473,13 +479,14 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration configDto.setAnnotationData(annotationData); configDto.setProperties(properties); return processorDto; - } - private ComponentDetails getComponentConfiguration(final ProcessorDTO processor) { + private ComponentDetails getComponentConfiguration(final ProcessorEntity entity) { + final ProcessorDTO processor = entity.getComponent(); final ProcessorConfigDTO processorConfig = processor.getConfig(); return new ComponentDetails.Builder() .id(processor.getId()) + .revision(getRevision(entity.getRevision(), entity.getId())) .name(processor.getName()) .type(processor.getType()) .state(processor.getState()) @@ -530,7 +537,6 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration @Override public ComponentDetails getComponentDetails(final NiFiWebRequestContext requestContext) { final String id = requestContext.getId(); - final ControllerServiceDTO controllerService; // authorize access serviceFacade.authorizeAccess(lookup -> { @@ -538,6 +544,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); }); + ControllerServiceEntity entity; if (properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -563,17 +570,16 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return controller service - ControllerServiceEntity entity = (ControllerServiceEntity) nodeResponse.getUpdatedEntity(); + entity = (ControllerServiceEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ControllerServiceEntity.class); } - controllerService = entity.getComponent(); } else { - controllerService = serviceFacade.getControllerService(id, true).getComponent(); + entity = serviceFacade.getControllerService(id, true); } // return the controller service info - return getComponentConfiguration(controllerService); + return getComponentConfiguration(entity); } @Override @@ -590,9 +596,13 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration // authorize any referenced service AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup); + + // authorize any parameter references + AuthorizeParameterReference.authorizeParameterReferences(properties, authorizer, authorizable.getParameterContext(), user); + AuthorizeParameterReference.authorizeParameterReferences(annotationData, authorizer, authorizable.getParameterContext(), user); }); - final ControllerServiceDTO controllerService; + ControllerServiceEntity entity; if (StandardNiFiWebConfigurationContext.this.properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -635,11 +645,10 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return controller service - ControllerServiceEntity entity = (ControllerServiceEntity) nodeResponse.getUpdatedEntity(); + entity = (ControllerServiceEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ControllerServiceEntity.class); } - controllerService = entity.getComponent(); } else { final ControllerServiceDTO controllerServiceDto = new ControllerServiceDTO(); controllerServiceDto.setId(id); @@ -647,17 +656,18 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration controllerServiceDto.setProperties(properties); // update controller service - final ControllerServiceEntity entity = serviceFacade.updateControllerService(revision, controllerServiceDto); - controllerService = entity.getComponent(); + entity = serviceFacade.updateControllerService(revision, controllerServiceDto); } // return the controller service info - return getComponentConfiguration(controllerService); + return getComponentConfiguration(entity); } - private ComponentDetails getComponentConfiguration(final ControllerServiceDTO controllerService) { + private ComponentDetails getComponentConfiguration(final ControllerServiceEntity entity) { + final ControllerServiceDTO controllerService = entity.getComponent(); return new ComponentDetails.Builder() .id(controllerService.getId()) + .revision(getRevision(entity.getRevision(), entity.getId())) .name(controllerService.getName()) .type(controllerService.getType()) .state(controllerService.getState()) @@ -675,7 +685,6 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration @Override public ComponentDetails getComponentDetails(final NiFiWebRequestContext requestContext) { final String id = requestContext.getId(); - final ReportingTaskDTO reportingTask; // authorize access serviceFacade.authorizeAccess(lookup -> { @@ -683,6 +692,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); }); + ReportingTaskEntity entity; if (properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -708,17 +718,16 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return reporting task - ReportingTaskEntity entity = (ReportingTaskEntity) nodeResponse.getUpdatedEntity(); + entity = (ReportingTaskEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ReportingTaskEntity.class); } - reportingTask = entity.getComponent(); } else { - reportingTask = serviceFacade.getReportingTask(id).getComponent(); + entity = serviceFacade.getReportingTask(id); } // return the reporting task info - return getComponentConfiguration(reportingTask); + return getComponentConfiguration(entity); } @Override @@ -737,7 +746,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup); }); - final ReportingTaskDTO reportingTask; + ReportingTaskEntity entity; if (StandardNiFiWebConfigurationContext.this.properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -780,11 +789,10 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return reporting task - ReportingTaskEntity entity = (ReportingTaskEntity) nodeResponse.getUpdatedEntity(); + entity = (ReportingTaskEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ReportingTaskEntity.class); } - reportingTask = entity.getComponent(); } else { final ReportingTaskDTO reportingTaskDto = new ReportingTaskDTO(); reportingTaskDto.setId(id); @@ -793,17 +801,18 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration // obtain write lock serviceFacade.verifyRevision(revision, user); - final ReportingTaskEntity entity = serviceFacade.updateReportingTask(revision, reportingTaskDto); - reportingTask = entity.getComponent(); + entity = serviceFacade.updateReportingTask(revision, reportingTaskDto); } // return the processor info - return getComponentConfiguration(reportingTask); + return getComponentConfiguration(entity); } - private ComponentDetails getComponentConfiguration(final ReportingTaskDTO reportingTask) { + private ComponentDetails getComponentConfiguration(final ReportingTaskEntity entity) { + final ReportingTaskDTO reportingTask = entity.getComponent(); return new ComponentDetails.Builder() .id(reportingTask.getId()) + .revision(getRevision(entity.getRevision(), entity.getId())) .name(reportingTask.getName()) .type(reportingTask.getType()) .state(reportingTask.getState()) @@ -821,7 +830,6 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration @Override public ComponentDetails getComponentDetails(final NiFiWebRequestContext requestContext) { final String id = requestContext.getId(); - final ParameterProviderDTO parameterProvider; // authorize access serviceFacade.authorizeAccess(lookup -> { @@ -829,6 +837,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); }); + ParameterProviderEntity entity; if (properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -854,17 +863,16 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return parameter provider - ParameterProviderEntity entity = (ParameterProviderEntity) nodeResponse.getUpdatedEntity(); + entity = (ParameterProviderEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ParameterProviderEntity.class); } - parameterProvider = entity.getComponent(); } else { - parameterProvider = serviceFacade.getParameterProvider(id).getComponent(); + entity = serviceFacade.getParameterProvider(id); } // return the parameter provider info - return getComponentConfiguration(parameterProvider); + return getComponentConfiguration(entity); } @Override @@ -883,7 +891,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup); }); - final ParameterProviderDTO parameterProvider; + ParameterProviderEntity entity; if (StandardNiFiWebConfigurationContext.this.properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -926,11 +934,10 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return parameter provider - ParameterProviderEntity entity = (ParameterProviderEntity) nodeResponse.getUpdatedEntity(); + entity = (ParameterProviderEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(ParameterProviderEntity.class); } - parameterProvider = entity.getComponent(); } else { final ParameterProviderDTO parameterProviderDto = new ParameterProviderDTO(); parameterProviderDto.setId(id); @@ -939,17 +946,18 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration // obtain write lock serviceFacade.verifyRevision(revision, user); - final ParameterProviderEntity entity = serviceFacade.updateParameterProvider(revision, parameterProviderDto); - parameterProvider = entity.getComponent(); + entity = serviceFacade.updateParameterProvider(revision, parameterProviderDto); } // return the processor info - return getComponentConfiguration(parameterProvider); + return getComponentConfiguration(entity); } - private ComponentDetails getComponentConfiguration(final ParameterProviderDTO parameterProvider) { + private ComponentDetails getComponentConfiguration(final ParameterProviderEntity entity) { + final ParameterProviderDTO parameterProvider = entity.getComponent(); return new ComponentDetails.Builder() .id(parameterProvider.getId()) + .revision(getRevision(entity.getRevision(), entity.getId())) .name(parameterProvider.getName()) .type(parameterProvider.getType()) .annotationData(parameterProvider.getAnnotationData()) @@ -966,7 +974,6 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration @Override public ComponentDetails getComponentDetails(final NiFiWebRequestContext requestContext) { final String id = requestContext.getId(); - final FlowRegistryClientDTO flowRegistryClient; // authorize access serviceFacade.authorizeAccess(lookup -> { @@ -974,6 +981,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); }); + FlowRegistryClientEntity entity; if (properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -999,17 +1007,16 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return flow registry client - FlowRegistryClientEntity entity = (FlowRegistryClientEntity) nodeResponse.getUpdatedEntity(); + entity = (FlowRegistryClientEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(FlowRegistryClientEntity.class); } - flowRegistryClient = entity.getComponent(); } else { - flowRegistryClient = serviceFacade.getRegistryClient(id).getComponent(); + entity = serviceFacade.getRegistryClient(id); } // return the flow registry client info - return getComponentConfiguration(flowRegistryClient); + return getComponentConfiguration(entity); } @Override @@ -1028,7 +1035,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup); }); - final FlowRegistryClientDTO flowRegistryClient; + FlowRegistryClientEntity entity; if (StandardNiFiWebConfigurationContext.this.properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) { // create the request URL URI requestUrl; @@ -1071,11 +1078,10 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration checkResponse(nodeResponse, id); // return flow registry client - FlowRegistryClientEntity entity = (FlowRegistryClientEntity) nodeResponse.getUpdatedEntity(); + entity = (FlowRegistryClientEntity) nodeResponse.getUpdatedEntity(); if (entity == null) { entity = nodeResponse.getClientResponse().readEntity(FlowRegistryClientEntity.class); } - flowRegistryClient = entity.getComponent(); } else { final FlowRegistryClientDTO flowRegistryClientDTO = new FlowRegistryClientDTO(); flowRegistryClientDTO.setId(id); @@ -1084,17 +1090,18 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration // obtain write lock serviceFacade.verifyRevision(revision, user); - final FlowRegistryClientEntity entity = serviceFacade.updateRegistryClient(revision, flowRegistryClientDTO); - flowRegistryClient = entity.getComponent(); + entity = serviceFacade.updateRegistryClient(revision, flowRegistryClientDTO); } // return the processor info - return getComponentConfiguration(flowRegistryClient); + return getComponentConfiguration(entity); } - private ComponentDetails getComponentConfiguration(final FlowRegistryClientDTO parameterProvider) { + private ComponentDetails getComponentConfiguration(final FlowRegistryClientEntity entity) { + final FlowRegistryClientDTO parameterProvider = entity.getComponent(); return new ComponentDetails.Builder() .id(parameterProvider.getId()) + .revision(getRevision(entity.getRevision(), entity.getId())) .name(parameterProvider.getName()) .type(parameterProvider.getType()) .annotationData(parameterProvider.getAnnotationData()) diff --git a/nifi-frontend/pom.xml b/nifi-frontend/pom.xml index 1da5d27072..99f33eaced 100644 --- a/nifi-frontend/pom.xml +++ b/nifi-frontend/pom.xml @@ -156,6 +156,32 @@ + + copy-built-update-attribute-app + process-resources + + copy-resources + + + ${project.build.directory}/${project.build.finalName}/update-attribute + + + ${frontend.working.dir}/dist/update-attribute/browser + false + + **/* + + + + ${frontend.working.dir}/dist/update-attribute + false + + 3rdpartylicenses.txt + + + + + @@ -216,6 +242,25 @@ + + bundle-built-update-attribute-app + prepare-package + + copy-resources + + + ${project.build.outputDirectory}/update-attribute + + + ${project.build.directory}/${project.build.finalName}/update-attribute + false + + **/* + + + + + diff --git a/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/project.json b/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/project.json index c1e9401a57..f085b20428 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/project.json +++ b/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/project.json @@ -89,7 +89,7 @@ }, "development": { "buildTarget": "nifi-jolt-transform-ui:build:development", - "servePath": "/nifi-jolt-transform-json-ui-2.0.0-SNAPSHOT/" + "servePath": "/nifi-jolt-transform-json-ui-2.1.0-SNAPSHOT/" } }, "defaultConfiguration": "development" diff --git a/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/src/app/pages/jolt-transform-json-ui/feature/jolt-transform-json-ui.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/src/app/pages/jolt-transform-json-ui/feature/jolt-transform-json-ui.component.spec.ts index 29d0a23e82..70397950a7 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/src/app/pages/jolt-transform-json-ui/feature/jolt-transform-json-ui.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi-jolt-transform-ui/src/app/pages/jolt-transform-json-ui/feature/jolt-transform-json-ui.component.spec.ts @@ -19,7 +19,7 @@ import { JoltTransformJsonUi } from './jolt-transform-json-ui.component'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../state/jolt-transform-json-processor-details/jolt-transform-json-processor-details.reducer'; -import { joltTransformJsonUiFeatureKey } from '../state'; +import { joltTransformJsonProcessorDetailsFeatureKey, joltTransformJsonUiFeatureKey } from '../state'; describe('jolt-transform-json-ui', () => { let component: JoltTransformJsonUi; @@ -32,7 +32,7 @@ describe('jolt-transform-json-ui', () => { provideMockStore({ initialState: { [joltTransformJsonUiFeatureKey]: { - [joltTransformJsonUiFeatureKey]: initialState + [joltTransformJsonProcessorDetailsFeatureKey]: initialState } } }) diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/access-policy/access-policy.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/access-policy/access-policy.effects.ts index 2de6b763ff..2496e87718 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/access-policy/access-policy.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/access-policy/access-policy.effects.ts @@ -28,8 +28,7 @@ import { MatDialog } from '@angular/material/dialog'; import { AccessPolicyService } from '../../service/access-policy.service'; import { AccessPolicyEntity, ComponentResourceAction, PolicyStatus, ResourceAction } from '../shared'; import { selectAccessPolicy, selectResourceAction, selectSaving } from './access-policy.selectors'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; -import { isDefinedAndNotNull, MEDIUM_DIALOG, SMALL_DIALOG } from 'libs/shared/src'; +import { isDefinedAndNotNull, MEDIUM_DIALOG, SMALL_DIALOG, YesNoDialog } from '@nifi/shared'; import { TenantEntity } from '../../../../state/shared'; import { AddTenantToPolicyDialog } from '../../ui/common/add-tenant-to-policy-dialog/add-tenant-to-policy-dialog.component'; import { AddTenantsToPolicyRequest } from './index'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/shared/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/shared/index.ts index 02c3980b67..46692c2ea8 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/shared/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/state/shared/index.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { AccessPolicySummary, Permissions, Revision, TenantEntity } from '../../../../state/shared'; +import { AccessPolicySummary, TenantEntity } from '../../../../state/shared'; +import { Revision, Permissions } from '@nifi/shared'; export enum PolicyStatus { Found = 'Found', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/component-access-policies/component-access-policies.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/component-access-policies/component-access-policies.component.ts index ba9a12f15c..5d4a851e66 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/component-access-policies/component-access-policies.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/component-access-policies/component-access-policies.component.ts @@ -39,8 +39,7 @@ import { import { distinctUntilChanged } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { NiFiCommon, TextTip } from '@nifi/shared'; -import { ComponentType, isDefinedAndNotNull, SelectOption } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull, NiFiCommon, SelectOption, TextTip } from '@nifi/shared'; import { AccessPolicyEntity, Action, PolicyStatus, ResourceAction } from '../../state/shared'; import { selectFlowConfiguration } from '../../../../state/flow-configuration/flow-configuration.selectors'; import { loadTenants, resetTenantsState } from '../../state/tenants/tenants.actions'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/global-access-policies/global-access-policies.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/global-access-policies/global-access-policies.component.ts index 0d96299db3..7aa1d783de 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/global-access-policies/global-access-policies.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/access-policies/ui/global-access-policies/global-access-policies.component.ts @@ -38,8 +38,7 @@ import { import { distinctUntilChanged } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { NiFiCommon, TextTip } from '@nifi/shared'; -import { ComponentType, isDefinedAndNotNull, SelectOption } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull, NiFiCommon, SelectOption, TextTip } from '@nifi/shared'; import { RequiredPermission } from '../../../../state/shared'; import { AccessPolicyEntity, Action, PolicyStatus } from '../../state/shared'; import { loadExtensionTypesForPolicies } from '../../../../state/extension-types/extension-types.actions'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/state/bulletin-board/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/state/bulletin-board/index.ts index 03478ad45b..131bb56379 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/state/bulletin-board/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/state/bulletin-board/index.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { BulletinEntity } from '../../../../state/shared'; +import { BulletinEntity } from '@nifi/shared'; export const bulletinBoardFeatureKey = 'bulletin-board'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/ui/bulletin-board/bulletin-board-list/bulletin-board-list.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/ui/bulletin-board/bulletin-board-list/bulletin-board-list.component.ts index da3a08ac02..9d1b6ab60c 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/ui/bulletin-board/bulletin-board-list/bulletin-board-list.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/bulletins/ui/bulletin-board/bulletin-board-list/bulletin-board-list.component.ts @@ -27,16 +27,13 @@ import { Output, ViewChild } from '@angular/core'; - import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; -import { NiFiCommon } from '@nifi/shared'; +import { BulletinEntity, ComponentType, NiFiCommon } from '@nifi/shared'; import { BulletinBoardEvent, BulletinBoardFilterArgs, BulletinBoardItem } from '../../../state/bulletin-board'; -import { ComponentType } from 'libs/shared/src'; -import { BulletinEntity } from '../../../../../state/shared'; import { debounceTime, delay, Subject } from 'rxjs'; import { RouterLink } from '@angular/router'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/state/cluster-listing/cluster-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/state/cluster-listing/cluster-listing.effects.ts index 800b51e3ed..acc4520047 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/state/cluster-listing/cluster-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/state/cluster-listing/cluster-listing.effects.ts @@ -28,8 +28,7 @@ import { selectClusterListingStatus } from './cluster-listing.selectors'; import { reloadSystemDiagnostics } from '../../../../state/system-diagnostics/system-diagnostics.actions'; import { ClusterService } from '../../service/cluster.service'; import { MatDialog } from '@angular/material/dialog'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; -import { LARGE_DIALOG, MEDIUM_DIALOG, SMALL_DIALOG } from 'libs/shared/src'; +import { LARGE_DIALOG, MEDIUM_DIALOG, SMALL_DIALOG, YesNoDialog } from '@nifi/shared'; import { ClusterNodeDetailDialog } from '../../ui/cluster-node-listing/cluster-node-detail-dialog/cluster-node-detail-dialog.component'; import * as ErrorActions from '../../../../state/error/error.actions'; import { SelectClusterNodeRequest } from './index'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-content-storage-listing/cluster-content-storage-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-content-storage-listing/cluster-content-storage-listing.component.ts index 0d8701e9ea..90fe0a8143 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-content-storage-listing/cluster-content-storage-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-content-storage-listing/cluster-content-storage-listing.component.ts @@ -26,7 +26,7 @@ import { selectClusterStorageRepositoryIdFromRoute } from '../../state/cluster-listing/cluster-listing.selectors'; import { selectSystemNodeSnapshots } from '../../../../state/system-diagnostics/system-diagnostics.selectors'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull } from '@nifi/shared'; import { map } from 'rxjs'; import { ClusterNodeRepositoryStorageUsage } from '../../../../state/system-diagnostics'; import { Store } from '@ngrx/store'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-flow-file-storage-listing/cluster-flow-file-storage-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-flow-file-storage-listing/cluster-flow-file-storage-listing.component.ts index 0f9e7aaead..02ffa091b0 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-flow-file-storage-listing/cluster-flow-file-storage-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-flow-file-storage-listing/cluster-flow-file-storage-listing.component.ts @@ -29,7 +29,7 @@ import { NiFiState } from '../../../../state'; import { initialClusterState } from '../../state/cluster-listing/cluster-listing.reducer'; import { ClusterNodeRepositoryStorageUsage } from '../../../../state/system-diagnostics'; import { map } from 'rxjs'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull } from '@nifi/shared'; import { AsyncPipe } from '@angular/common'; import { clearFlowFileStorageNodeSelection, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-provenance-storage-listing/cluster-provenance-storage-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-provenance-storage-listing/cluster-provenance-storage-listing.component.ts index 789b75e6e9..6ea57b1d7d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-provenance-storage-listing/cluster-provenance-storage-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/cluster/ui/cluster-provenance-storage-listing/cluster-provenance-storage-listing.component.ts @@ -23,7 +23,7 @@ import { selectClusterStorageRepositoryIdFromRoute } from '../../state/cluster-listing/cluster-listing.selectors'; import { selectSystemNodeSnapshots } from '../../../../state/system-diagnostics/system-diagnostics.selectors'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull } from '@nifi/shared'; import { map } from 'rxjs'; import { ClusterNodeRepositoryStorageUsage } from '../../../../state/system-diagnostics'; import { Store } from '@ngrx/store'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/counters/state/counter-listing/counter-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/counters/state/counter-listing/counter-listing.effects.ts index 34e0e3bbe9..641ae0d1ef 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/counters/state/counter-listing/counter-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/counters/state/counter-listing/counter-listing.effects.ts @@ -24,12 +24,11 @@ import * as CounterListingActions from './counter-listing.actions'; import { catchError, from, map, of, switchMap, take, tap } from 'rxjs'; import { CountersService } from '../../service/counters.service'; import { MatDialog } from '@angular/material/dialog'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { SMALL_DIALOG, YesNoDialog } from '@nifi/shared'; import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; import { selectStatus } from './counter-listing.selectors'; -import { SMALL_DIALOG } from 'libs/shared/src'; @Injectable() export class CounterListingEffects { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/state/flow-configuration-history-listing/flow-configuration-history-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/state/flow-configuration-history-listing/flow-configuration-history-listing.effects.ts index 3bb6c17287..ca3ae39d3e 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/state/flow-configuration-history-listing/flow-configuration-history-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/state/flow-configuration-history-listing/flow-configuration-history-listing.effects.ts @@ -31,11 +31,9 @@ import { HttpErrorResponse } from '@angular/common/http'; import { Router } from '@angular/router'; import { ActionDetails } from '../../ui/flow-configuration-history-listing/action-details/action-details.component'; import { PurgeHistory } from '../../ui/flow-configuration-history-listing/purge-history/purge-history.component'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull, MEDIUM_DIALOG, SMALL_DIALOG, YesNoDialog } from '@nifi/shared'; import * as ErrorActions from '../../../../state/error/error.actions'; import { selectAbout } from '../../../../state/about/about.selectors'; -import { MEDIUM_DIALOG, SMALL_DIALOG } from 'libs/shared/src'; @Injectable() export class FlowConfigurationHistoryListingEffects { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/ui/flow-configuration-history-listing/flow-configuration-history-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/ui/flow-configuration-history-listing/flow-configuration-history-listing.component.ts index 5dbad4e993..c067aed7b7 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/ui/flow-configuration-history-listing/flow-configuration-history-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-configuration-history/ui/flow-configuration-history-listing/flow-configuration-history-listing.component.ts @@ -36,7 +36,6 @@ import { MatPaginatorModule, PageEvent } from '@angular/material/paginator'; import { FlowConfigurationHistoryTable } from './flow-configuration-history-table/flow-configuration-history-table.component'; import { Sort } from '@angular/material/sort'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { isDefinedAndNotNull } from 'libs/shared/src'; import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; @@ -45,7 +44,7 @@ import { MatSelectModule } from '@angular/material/select'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { selectAbout } from '../../../../state/about/about.selectors'; import { debounceTime } from 'rxjs'; -import { NiFiCommon } from '@nifi/shared'; +import { isDefinedAndNotNull, NiFiCommon } from '@nifi/shared'; import { MatButtonModule } from '@angular/material/button'; import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts index 0f05dc5050..4e7b254895 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts @@ -27,7 +27,7 @@ import { Client } from '../../../../service/client.service'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MoveComponentRequest, UpdateComponentRequest } from '../../state/flow'; import { Position } from '../../state/shared'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; @Injectable({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-actions.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-actions.service.ts index e1ffa989ff..6dce407f6f 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-actions.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-actions.service.ts @@ -52,7 +52,7 @@ import { CanvasState } from '../state'; import * as d3 from 'd3'; import { MatDialog } from '@angular/material/dialog'; import { CanvasView } from './canvas-view.service'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { Client } from '../../../service/client.service'; import { CopyRequestContext, CopyRequestEntity, CopyResponseEntity } from '../../../state/copy'; import { CopyPasteService } from './copy-paste.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts index 0a2158e470..5397a990a0 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts @@ -51,7 +51,7 @@ import { terminateThreads, updatePositions } from '../state/flow/flow.actions'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { ConfirmStopVersionControlRequest, MoveComponentRequest, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts index 8e574fa3cd..d0c16a765b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts @@ -32,9 +32,7 @@ import { initialState as initialFlowState } from '../state/flow/flow.reducer'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { BulletinsTip } from '../../../ui/common/tooltips/bulletins-tip/bulletins-tip.component'; import { BreadcrumbEntity, Position } from '../state/shared'; -import { ComponentType } from 'libs/shared/src'; -import { BulletinEntity, ParameterContextReferenceEntity, Permissions } from '../../../state/shared'; -import { NiFiCommon } from '@nifi/shared'; +import { BulletinEntity, ComponentType, NiFiCommon, ParameterContextReferenceEntity, Permissions } from '@nifi/shared'; import { CurrentUser } from '../../../state/current-user'; import { initialState as initialUserState } from '../../../state/current-user/current-user.reducer'; import { selectCurrentUser } from '../../../state/current-user/current-user.selectors'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/flow.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/flow.service.ts index 34ca5d26b7..19fecaf321 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/flow.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/flow.service.ts @@ -50,9 +50,8 @@ import { UploadProcessGroupRequest, VersionControlInformationEntity } from '../state/flow'; -import { ComponentType } from 'libs/shared/src'; import { Client } from '../../../service/client.service'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { ClusterConnectionService } from '../../../service/cluster-connection.service'; import { PropertyDescriptorRetriever } from '../../../state/shared'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manage-remote-port.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manage-remote-port.service.ts index 8beb365cdd..5e14820da4 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manage-remote-port.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manage-remote-port.service.ts @@ -18,10 +18,9 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { ConfigureRemotePortRequest, ToggleRemotePortTransmissionRequest } from '../state/manage-remote-ports'; import { Client } from '../../../service/client.service'; -import { ComponentType } from 'libs/shared/src'; @Injectable({ providedIn: 'root' }) export class ManageRemotePortService { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts index 1abf215ec7..633f830b83 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts @@ -40,11 +40,10 @@ import { updateConnection } from '../../state/flow/flow.actions'; import { UnorderedListTip } from '../../../../ui/common/tooltips/unordered-list-tip/unordered-list-tip.component'; -import { ComponentType, SelectOption } from 'libs/shared/src'; import { Dimension, Position } from '../../state/shared'; import { loadBalanceStrategies, UpdateComponentRequest } from '../../state/flow'; import { filter, Subject, switchMap, takeUntil } from 'rxjs'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon, SelectOption } from '@nifi/shared'; import { QuickSelectBehavior } from '../behavior/quick-select-behavior.service'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.ts index f8eef099b7..55b2b870ec 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/funnel-manager.service.ts @@ -29,7 +29,7 @@ import { selectTransitionRequired } from '../../state/flow/flow.selectors'; import { Dimension } from '../../state/shared'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { filter, Subject, switchMap, takeUntil } from 'rxjs'; @Injectable({ providedIn: 'root' }) diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts index 5e288f8d70..d0e4c747c3 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts @@ -32,10 +32,9 @@ import { import { Client } from '../../../../service/client.service'; import { updateComponent } from '../../state/flow/flow.actions'; import { QuickSelectBehavior } from '../behavior/quick-select-behavior.service'; -import { ComponentType } from 'libs/shared/src'; import { UpdateComponentRequest } from '../../state/flow'; import { filter, Subject, switchMap, takeUntil } from 'rxjs'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; @Injectable({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts index ab9073c74c..f5f0e63787 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts @@ -30,10 +30,9 @@ import { selectTransitionRequired } from '../../state/flow/flow.selectors'; import { QuickSelectBehavior } from '../behavior/quick-select-behavior.service'; -import { TextTip, NiFiCommon } from '@nifi/shared'; +import { ComponentType, TextTip, NiFiCommon } from '@nifi/shared'; import { ValidationErrorsTip } from '../../../../ui/common/tooltips/validation-errors-tip/validation-errors-tip.component'; import { Dimension } from '../../state/shared'; -import { ComponentType } from 'libs/shared/src'; import { filter, Subject, switchMap, takeUntil } from 'rxjs'; import { renderConnectionsForComponent } from '../../state/flow/flow.actions'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts index 6bafc31a03..1d3140b553 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts @@ -32,9 +32,8 @@ import { CanvasUtils } from '../canvas-utils.service'; import { enterProcessGroup } from '../../state/flow/flow.actions'; import { VersionControlTip } from '../../ui/common/tooltips/version-control-tip/version-control-tip.component'; import { Dimension } from '../../state/shared'; -import { ComponentType } from 'libs/shared/src'; import { filter, Subject, switchMap, takeUntil } from 'rxjs'; -import { NiFiCommon, TextTip } from '@nifi/shared'; +import { ComponentType, NiFiCommon, TextTip } from '@nifi/shared'; @Injectable({ providedIn: 'root' diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts index 215ab599df..2f4a71002a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts @@ -31,9 +31,8 @@ import { } from '../../state/flow/flow.selectors'; import { QuickSelectBehavior } from '../behavior/quick-select-behavior.service'; import { ValidationErrorsTip } from '../../../../ui/common/tooltips/validation-errors-tip/validation-errors-tip.component'; -import { TextTip, NiFiCommon } from '@nifi/shared'; +import { ComponentType, TextTip, NiFiCommon } from '@nifi/shared'; import { Dimension } from '../../state/shared'; -import { ComponentType } from 'libs/shared/src'; import { filter, Subject, switchMap, takeUntil } from 'rxjs'; @Injectable({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts index b3c41051e5..c4e1df26e3 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts @@ -32,9 +32,8 @@ import { import { QuickSelectBehavior } from '../behavior/quick-select-behavior.service'; import { ValidationErrorsTip } from '../../../../ui/common/tooltips/validation-errors-tip/validation-errors-tip.component'; import { Dimension } from '../../state/shared'; -import { ComponentType } from 'libs/shared/src'; import { filter, Subject, switchMap, takeUntil } from 'rxjs'; -import { NiFiCommon, TextTip } from '@nifi/shared'; +import { ComponentType, NiFiCommon, TextTip } from '@nifi/shared'; @Injectable({ providedIn: 'root' diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts index b01ee74080..ffa19782bd 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts @@ -29,7 +29,7 @@ import { selectParameterSaving, selectParameterState } from '../state/parameter/ import { ParameterState } from '../state/parameter'; import * as ErrorActions from '../../../state/error/error.actions'; import * as ParameterActions from '../state/parameter/parameter.actions'; -import { MEDIUM_DIALOG } from 'libs/shared/src'; +import { MEDIUM_DIALOG } from '@nifi/shared'; import { ClusterConnectionService } from '../../../service/cluster-connection.service'; import { ErrorHelper } from '../../../service/error-helper.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts index 91f2d6721d..da49358fdf 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/controller-service-advanced-ui-params.resolver.ts @@ -68,7 +68,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn { const revision = client.getRevision(entity); - const editable = entity.status.runStatus === 'DISABLED'; + const editable = entity.status.runStatus === 'DISABLED' && entity.permissions.canWrite; return { url: entity.component.customUiUrl, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/processor-advanced-ui-params.resolver.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/processor-advanced-ui-params.resolver.ts index d331c299dc..c099c638f6 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/processor-advanced-ui-params.resolver.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/resolver/processor-advanced-ui-params.resolver.ts @@ -66,10 +66,11 @@ export const processorAdvancedUiParamsResolver: ResolveFn = (r map((entity) => { const revision = client.getRevision(entity); - const editable = !( - entity.status.aggregateSnapshot.runStatus === 'Running' || - entity.status.aggregateSnapshot.activeThreadCount > 0 - ); + const editable = + !( + entity.status.aggregateSnapshot.runStatus === 'Running' || + entity.status.aggregateSnapshot.activeThreadCount > 0 + ) && entity.permissions.canWrite; return { url: entity.component.config.customUiUrl, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/snippet.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/snippet.service.ts index f97db726f2..9a4a6d5a35 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/snippet.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/snippet.service.ts @@ -20,7 +20,7 @@ import { Observable } from 'rxjs'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Snippet, SnippetComponentRequest } from '../state/flow'; import { ClusterConnectionService } from '../../../service/cluster-connection.service'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { Client } from '../../../service/client.service'; @Injectable({ providedIn: 'root' }) diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts index 7464a08f58..af6e0fded6 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts @@ -26,7 +26,7 @@ import { NiFiState } from '../../../../state'; import { selectControllerServiceTypes } from '../../../../state/extension-types/extension-types.selectors'; import { CreateControllerService } from '../../../../ui/common/controller-service/create-controller-service/create-controller-service.component'; import { Client } from '../../../../service/client.service'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { YesNoDialog } from '@nifi/shared'; import { EditControllerService } from '../../../../ui/common/controller-service/edit-controller-service/edit-controller-service.component'; import { ControllerServiceReferencingComponent, @@ -49,7 +49,6 @@ import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; import { ParameterHelperService } from '../../service/parameter-helper.service'; -import { ComponentType, LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from 'libs/shared/src'; import { ExtensionTypesService } from '../../../../service/extension-types.service'; import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; import { FlowService } from '../../service/flow.service'; @@ -63,7 +62,7 @@ import { } from '../../../../state/property-verification/property-verification.selectors'; import { VerifyPropertiesRequestContext } from '../../../../state/property-verification'; import { BackNavigation } from '../../../../state/navigation'; -import { NiFiCommon, Storage } from '@nifi/shared'; +import { ComponentType, LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG, NiFiCommon, Storage } from '@nifi/shared'; import { ErrorContextKey } from '../../../../state/error'; @Injectable() diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/index.ts index 9bf4fd460d..0e0b7809ed 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/controller-services/index.ts @@ -15,8 +15,9 @@ * limitations under the License. */ -import { ControllerServiceEntity, ParameterContextReferenceEntity } from '../../../../state/shared'; +import { ControllerServiceEntity } from '../../../../state/shared'; import { BreadcrumbEntity } from '../shared'; +import { ParameterContextReferenceEntity } from '@nifi/shared'; export const controllerServicesFeatureKey = 'controllerServiceListing'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow-analysis/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow-analysis/index.ts index 49deb49658..75a4a7a224 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow-analysis/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow-analysis/index.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { PropertyDescriptor, Bundle, Permissions } from '../../../../state/shared'; +import { PropertyDescriptor, Bundle } from '../../../../state/shared'; +import { Permissions } from '@nifi/shared'; export const flowAnalysisFeatureKey = 'flowAnalysis'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts index 7819a895be..f126ea1d81 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts @@ -119,7 +119,7 @@ import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component'; import { GroupComponents } from '../../ui/canvas/items/process-group/group-components/group-components.component'; import { EditProcessGroup } from '../../ui/canvas/items/process-group/edit-process-group/edit-process-group.component'; import { ControllerServiceService } from '../../service/controller-service.service'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { YesNoDialog } from '@nifi/shared'; import { PropertyTableHelperService } from '../../../../service/property-table-helper.service'; import { ParameterHelperService } from '../../service/parameter-helper.service'; import { RegistryService } from '../../service/registry.service'; @@ -127,14 +127,6 @@ import { ImportFromRegistry } from '../../ui/canvas/items/flow/import-from-regis import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; import { NoRegistryClientsDialog } from '../../ui/common/no-registry-clients-dialog/no-registry-clients-dialog.component'; import { EditRemoteProcessGroup } from '../../ui/canvas/items/remote-process-group/edit-remote-process-group/edit-remote-process-group.component'; -import { - ComponentType, - isDefinedAndNotNull, - LARGE_DIALOG, - MEDIUM_DIALOG, - SMALL_DIALOG, - XL_DIALOG -} from 'libs/shared/src'; import { HttpErrorResponse } from '@angular/common/http'; import { SaveVersionDialog } from '../../ui/canvas/items/flow/save-version-dialog/save-version-dialog.component'; import { ChangeVersionDialog } from '../../ui/canvas/items/flow/change-version-dialog/change-version-dialog'; @@ -159,7 +151,16 @@ import { } from '../../../../state/property-verification/property-verification.selectors'; import { VerifyPropertiesRequestContext } from '../../../../state/property-verification'; import { BackNavigation } from '../../../../state/navigation'; -import { NiFiCommon, Storage } from '@nifi/shared'; +import { + ComponentType, + isDefinedAndNotNull, + LARGE_DIALOG, + MEDIUM_DIALOG, + SMALL_DIALOG, + XL_DIALOG, + NiFiCommon, + Storage +} from '@nifi/shared'; import { resetPollingFlowAnalysis } from '../flow-analysis/flow-analysis.actions'; import { selectDocumentVisibilityState } from '../../../../state/document-visibility/document-visibility.selectors'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts index 4cff6a7b2d..758c68930e 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts @@ -89,7 +89,7 @@ import { uploadProcessGroup } from './flow.actions'; import { ComponentEntity, FlowState } from './index'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { produce } from 'immer'; export const initialState: FlowState = { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts index 31e04c68e7..fda8e4da4f 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts @@ -18,8 +18,7 @@ import { flowFeatureKey, FlowState, SelectedComponent } from './index'; import { createSelector } from '@ngrx/store'; import { CanvasState, selectCanvasState } from '../index'; -import { selectCurrentRoute } from '@nifi/shared'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType, selectCurrentRoute } from '@nifi/shared'; export const selectFlowState = createSelector(selectCanvasState, (state: CanvasState) => state[flowFeatureKey]); diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/index.ts index 5160c70c8f..08615c32ac 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/index.ts @@ -17,21 +17,24 @@ import { BreadcrumbEntity, Position } from '../shared'; import { - BulletinEntity, Bundle, ComponentHistory, DocumentedType, ParameterContextEntity, - ParameterContextReferenceEntity, - Permissions, RegistryClientEntity, - Revision, SparseVersionedFlow, VersionedFlowSnapshotMetadataEntity } from '../../../../state/shared'; import { HttpErrorResponse } from '@angular/common/http'; import { BackNavigation } from '../../../../state/navigation'; -import { ComponentType, SelectOption } from 'libs/shared/src'; +import { + BulletinEntity, + ComponentType, + ParameterContextReferenceEntity, + Permissions, + Revision, + SelectOption +} from '@nifi/shared'; import { CopyResponseEntity, PasteRequestStrategy } from '../../../../state/copy'; export const flowFeatureKey = 'flowState'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/index.ts index db566e8ea3..4d29ad4a73 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/index.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; export const remotePortsFeatureKey = 'remotePortListing'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts index c809476d54..d72dad83c1 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/manage-remote-ports/manage-remote-ports.effects.ts @@ -32,10 +32,9 @@ import { ManageRemotePortService } from '../../service/manage-remote-port.servic import { PortSummary } from './index'; import { EditRemotePortComponent } from '../../ui/manage-remote-ports/edit-remote-port/edit-remote-port.component'; import { EditRemotePortDialogRequest } from '../flow'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull, MEDIUM_DIALOG } from '@nifi/shared'; import { selectTimeOffset } from '../../../../state/flow-configuration/flow-configuration.selectors'; import { selectAbout } from '../../../../state/about/about.selectors'; -import { MEDIUM_DIALOG } from 'libs/shared/src'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; import { ErrorContextKey } from '../../../../state/error'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/parameter/parameter.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/parameter/parameter.effects.ts index 4e8335faec..4967dea96b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/parameter/parameter.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/parameter/parameter.effects.ts @@ -22,7 +22,7 @@ import * as ParameterActions from './parameter.actions'; import { Store } from '@ngrx/store'; import { CanvasState } from '../index'; import { asyncScheduler, catchError, filter, from, interval, map, of, switchMap, takeUntil } from 'rxjs'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull } from '@nifi/shared'; import { ParameterContextUpdateRequest } from '../../../../state/shared'; import { selectUpdateRequest } from './parameter.selectors'; import { ParameterService } from '../../service/parameter.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/queue/queue.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/queue/queue.effects.ts index 9ecefc242b..64f7bf4698 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/queue/queue.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/queue/queue.effects.ts @@ -27,12 +27,10 @@ import { QueueService } from '../../service/queue.service'; import { DropRequest } from './index'; import { CancelDialog } from '../../../../ui/common/cancel-dialog/cancel-dialog.component'; import { MatDialog } from '@angular/material/dialog'; -import { isDefinedAndNotNull } from 'libs/shared/src'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { isDefinedAndNotNull, SMALL_DIALOG, YesNoDialog } from '@nifi/shared'; import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component'; import { loadChildProcessGroup, loadConnection, loadProcessGroup } from '../flow/flow.actions'; import { resetQueueState } from './queue.actions'; -import { SMALL_DIALOG } from 'libs/shared/src'; import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { selectCurrentProcessGroupId } from '../flow/flow.selectors'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/shared/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/shared/index.ts index aa64ccef55..44cef213cd 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/shared/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/shared/index.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Permissions } from '../../../../state/shared'; +import { Permissions } from '@nifi/shared'; import { VersionControlInformation } from '../flow'; export interface Dimension { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/canvas-routing.module.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/canvas-routing.module.ts index b81c324ce0..49162d6ce4 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/canvas-routing.module.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/canvas-routing.module.ts @@ -20,7 +20,7 @@ import { RouterModule, Routes } from '@angular/router'; import { Canvas } from './canvas.component'; import { AdvancedUi } from '../../../../ui/common/advanced-ui/advanced-ui.component'; import { processorAdvancedUiParamsResolver } from '../../service/resolver/processor-advanced-ui-params.resolver'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; const routes: Routes = [ { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/change-color-dialog/change-color-dialog.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/change-color-dialog/change-color-dialog.component.ts index e75e418200..77fb0eba73 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/change-color-dialog/change-color-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/change-color-dialog/change-color-dialog.component.ts @@ -30,9 +30,8 @@ import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spin import { ChangeColorRequest } from '../../../state/flow'; import { MatFormField, MatLabel } from '@angular/material/form-field'; import { MatInput } from '@angular/material/input'; -import { ComponentType } from 'libs/shared/src'; import { CanvasUtils } from '../../../service/canvas-utils.service'; -import { NiFiCommon, ComponentTypeNamePipe, ComponentContext, CloseOnEscapeDialog } from '@nifi/shared'; +import { ComponentType, NiFiCommon, ComponentTypeNamePipe, ComponentContext, CloseOnEscapeDialog } from '@nifi/shared'; import { MatCheckbox } from '@angular/material/checkbox'; @Component({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts index fb3a16fc6c..4295139b3c 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts @@ -21,15 +21,13 @@ import { Store } from '@ngrx/store'; import { CanvasState } from '../../../../state'; import { CanvasUtils } from '../../../../service/canvas-utils.service'; import { initialState } from '../../../../state/flow/flow.reducer'; -import { Storage, ComponentContext } from '@nifi/shared'; - +import { ComponentType, Storage, ComponentContext } from '@nifi/shared'; import { BreadcrumbEntity } from '../../../../state/shared'; import { MatButtonModule } from '@angular/material/button'; import * as d3 from 'd3'; import { CanvasView } from '../../../../service/canvas-view.service'; import { Client } from '../../../../../../service/client.service'; import { CanvasActionsService } from '../../../../service/canvas-actions.service'; -import { ComponentType } from 'libs/shared/src'; @Component({ selector: 'operation-control', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts index 83b6233f99..adabd60497 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts @@ -19,10 +19,10 @@ import { Component, Input } from '@angular/core'; import { ControllerStatus } from '../../../../state/flow'; import { initialState } from '../../../../state/flow/flow.reducer'; import { BulletinsTip } from '../../../../../../ui/common/tooltips/bulletins-tip/bulletins-tip.component'; -import { BulletinEntity, BulletinsTipInput } from '../../../../../../state/shared'; +import { BulletinsTipInput } from '../../../../../../state/shared'; import { Search } from '../search/search.component'; -import { NifiTooltipDirective, Storage } from '@nifi/shared'; +import { BulletinEntity, NifiTooltipDirective, Storage } from '@nifi/shared'; import { ClusterSummary } from '../../../../../../state/cluster-summary'; import { ConnectedPosition } from '@angular/cdk/overlay'; import { FlowAnalysisState } from '../../../../state/flow-analysis'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/header.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/header.component.ts index 4ec1e91f72..196af83b93 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/header.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/header.component.ts @@ -16,7 +16,7 @@ */ import { Component } from '@angular/core'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { Store } from '@ngrx/store'; import { CanvasState } from '../../../state'; import { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts index 9743a94d59..8370a55261 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts @@ -23,9 +23,8 @@ import { createComponentRequest, setDragging } from '../../../../state/flow/flow import { Client } from '../../../../../../service/client.service'; import { selectDragging } from '../../../../state/flow/flow.selectors'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { ComponentType } from 'libs/shared/src'; import { CanvasView } from '../../../../service/canvas-view.service'; -import { NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { ComponentType, NifiTooltipDirective, TextTip } from '@nifi/shared'; import { ConnectedPosition } from '@angular/cdk/overlay'; @Component({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/search/search.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/search/search.component.ts index c95032c72f..1bbf310449 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/search/search.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/header/search/search.component.ts @@ -27,7 +27,6 @@ import { OriginConnectionPosition, OverlayConnectionPosition } from '@angular/cdk/overlay'; -import { ComponentType } from 'libs/shared/src'; import { SearchMatchTipInput } from '../../../../../../state/shared'; import { NgTemplateOutlet } from '@angular/common'; import { RouterLink } from '@angular/router'; @@ -38,7 +37,7 @@ import { Store } from '@ngrx/store'; import * as FlowActions from '../../../../state/flow/flow.actions'; import { centerSelectedComponents, setAllowTransition } from '../../../../state/flow/flow.actions'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { NifiTooltipDirective, selectCurrentRoute } from '@nifi/shared'; +import { ComponentType, NifiTooltipDirective, selectCurrentRoute } from '@nifi/shared'; import { SearchMatchTip } from '../../../../../../ui/common/tooltips/search-match-tip/search-match-tip.component'; import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../../../../../service/error-helper.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts index 0825a9af71..0cd657fde0 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.spec.ts @@ -22,7 +22,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { CreateConnectionDialogRequest } from '../../../../../state/flow'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { DocumentedType } from '../../../../../../../state/shared'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { of } from 'rxjs'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts index 753aa4c476..18d7308a53 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts @@ -35,8 +35,7 @@ import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; import { MatTabsModule } from '@angular/material/tabs'; -import { TextTip, NifiTooltipDirective, CloseOnEscapeDialog } from '@nifi/shared'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType, TextTip, NifiTooltipDirective, CloseOnEscapeDialog } from '@nifi/shared'; import { NiFiState } from '../../../../../../../state'; import { selectPrioritizerTypes } from '../../../../../../../state/extension-types/extension-types.selectors'; import { Prioritizers } from '../prioritizers/prioritizers.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/destination/destination-remote-process-group/destination-remote-process-group.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/destination/destination-remote-process-group/destination-remote-process-group.component.ts index afd2063b35..b6a2e9992c 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/destination/destination-remote-process-group/destination-remote-process-group.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/destination/destination-remote-process-group/destination-remote-process-group.component.ts @@ -18,12 +18,10 @@ import { Component, forwardRef, Input } from '@angular/core'; import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; - import { MatFormFieldModule } from '@angular/material/form-field'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; -import { NifiTooltipDirective, TextTip } from '@nifi/shared'; -import { SelectOption } from 'libs/shared/src'; +import { NifiTooltipDirective, TextTip, SelectOption } from '@nifi/shared'; @Component({ selector: 'destination-remote-process-group', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.spec.ts index ef9f0cbf0c..f57a7d1805 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.spec.ts @@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditConnectionComponent } from './edit-connection.component'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { EditConnectionDialogRequest } from '../../../../../state/flow'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { selectPrioritizerTypes } from '../../../../../../../state/extension-types/extension-types.selectors'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts index 6a6aa9726a..f6f52f1eb7 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts @@ -33,9 +33,8 @@ import { MatInputModule } from '@angular/material/input'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; -import { CopyDirective, NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { ComponentType, CopyDirective, NifiTooltipDirective, TextTip } from '@nifi/shared'; import { MatTabsModule } from '@angular/material/tabs'; -import { ComponentType } from 'libs/shared/src'; import { NiFiState } from '../../../../../../../state'; import { selectPrioritizerTypes } from '../../../../../../../state/extension-types/extension-types.selectors'; import { Prioritizers } from '../prioritizers/prioritizers.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-process-group/source-process-group.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-process-group/source-process-group.component.ts index 5976dfd05d..62ac1e6ffe 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-process-group/source-process-group.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-process-group/source-process-group.component.ts @@ -22,8 +22,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; -import { NifiTooltipDirective, TextTip } from '@nifi/shared'; -import { SelectOption } from 'libs/shared/src'; +import { NifiTooltipDirective, SelectOption, TextTip } from '@nifi/shared'; @Component({ selector: 'source-process-group', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-remote-process-group/source-remote-process-group.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-remote-process-group/source-remote-process-group.component.ts index 93925a3014..5b5e098ca2 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-remote-process-group/source-remote-process-group.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/source/source-remote-process-group/source-remote-process-group.component.ts @@ -19,11 +19,10 @@ import { Component, forwardRef, Input } from '@angular/core'; import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { TextTip, NifiTooltipDirective } from '@nifi/shared'; +import { TextTip, NifiTooltipDirective, SelectOption } from '@nifi/shared'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; -import { SelectOption } from 'libs/shared/src'; @Component({ selector: 'source-remote-process-group', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts index 91f986f267..82c5fcc3a9 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.spec.ts @@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ImportFromRegistry } from './import-from-registry.component'; import { ImportFromRegistryDialogRequest } from '../../../../../state/flow'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts index ed9b47e2c3..2d71088827 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/import-from-registry/import-from-registry.component.ts @@ -44,13 +44,19 @@ import { Observable, of, take } from 'rxjs'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { MatSortModule, Sort } from '@angular/material/sort'; -import { NiFiCommon, TextTip, NifiTooltipDirective, CloseOnEscapeDialog } from '@nifi/shared'; +import { + isDefinedAndNotNull, + SelectOption, + NiFiCommon, + TextTip, + NifiTooltipDirective, + CloseOnEscapeDialog +} from '@nifi/shared'; import { selectTimeOffset } from '../../../../../../../state/flow-configuration/flow-configuration.selectors'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Client } from '../../../../../../../service/client.service'; import { importFromRegistry } from '../../../../../state/flow/flow.actions'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; -import { isDefinedAndNotNull, SelectOption } from 'libs/shared/src'; import { ErrorContextKey } from '../../../../../../../state/error'; import { ContextErrorBanner } from '../../../../../../../ui/common/context-error-banner/context-error-banner.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-dialog.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-dialog.spec.ts index 38700bb755..70b58f1287 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-dialog.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-dialog.spec.ts @@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { LocalChangesDialog } from './local-changes-dialog'; import { LocalChangesDialogRequest } from '../../../../../state/flow'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts index f36fd3ce73..146b6bdd7a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts @@ -21,11 +21,10 @@ import { MatInput } from '@angular/material/input'; import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { MatSortModule, Sort } from '@angular/material/sort'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { ComponentDifference, NavigateToComponentRequest } from '../../../../../../state/flow'; import { debounceTime } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { ComponentType } from 'libs/shared/src'; import { MatIconButton } from '@angular/material/button'; import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/save-version-dialog/save-version-dialog.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/save-version-dialog/save-version-dialog.component.ts index 7e6c305899..7cb7aacc49 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/save-version-dialog/save-version-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/save-version-dialog/save-version-dialog.component.ts @@ -30,10 +30,9 @@ import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nif import { MatError, MatFormField, MatLabel } from '@angular/material/form-field'; import { MatOption, MatSelect } from '@angular/material/select'; import { Observable, of, take } from 'rxjs'; -import { SelectOption } from 'libs/shared/src'; import { BranchEntity, BucketEntity, RegistryClientEntity } from '../../../../../../../state/shared'; import { SaveVersionDialogRequest, SaveVersionRequest, VersionControlInformation } from '../../../../../state/flow'; -import { TextTip, NiFiCommon, NifiTooltipDirective, CloseOnEscapeDialog } from '@nifi/shared'; +import { TextTip, NiFiCommon, NifiTooltipDirective, CloseOnEscapeDialog, SelectOption } from '@nifi/shared'; import { NgForOf, NgIf } from '@angular/common'; import { MatInput } from '@angular/material/input'; import { ErrorContextKey } from '../../../../../../../state/error'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.spec.ts index b10c6b5013..1a0abd2745 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.spec.ts @@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditLabel } from './edit-label.component'; import { EditComponentDialogRequest } from '../../../../../state/flow'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts index 3a8e917d96..a9d0cb8b35 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts @@ -23,7 +23,6 @@ import { Store } from '@ngrx/store'; import { updateComponent } from '../../../../../state/flow/flow.actions'; import { Client } from '../../../../../../../service/client.service'; import { EditComponentDialogRequest } from '../../../../../state/flow'; -import { SelectOption } from 'libs/shared/src'; import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; import { MatInputModule } from '@angular/material/input'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -34,7 +33,7 @@ import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nif import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; import { MatOption } from '@angular/material/autocomplete'; import { MatSelect } from '@angular/material/select'; -import { NifiTooltipDirective, CloseOnEscapeDialog } from '@nifi/shared'; +import { NifiTooltipDirective, CloseOnEscapeDialog, SelectOption } from '@nifi/shared'; import { ErrorContextKey } from '../../../../../../../state/error'; import { ContextErrorBanner } from '../../../../../../../ui/common/context-error-banner/context-error-banner.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.spec.ts index 87fb95c072..3301b9bdf2 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.spec.ts @@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CreatePort } from './create-port.component'; import { CreateComponentRequest } from '../../../../../state/flow'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.ts index da81c4fb9d..2a5cb20565 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/create-port/create-port.component.ts @@ -24,14 +24,13 @@ import { selectParentProcessGroupId, selectSaving } from '../../../../../state/f import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { createPort } from '../../../../../state/flow/flow.actions'; import { CreateComponentRequest } from '../../../../../state/flow'; -import { ComponentType, SelectOption } from 'libs/shared/src'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; import { AsyncPipe } from '@angular/common'; import { MatButtonModule } from '@angular/material/button'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; -import { NifiTooltipDirective, TextTip, CloseOnEscapeDialog } from '@nifi/shared'; +import { ComponentType, SelectOption, NifiTooltipDirective, TextTip, CloseOnEscapeDialog } from '@nifi/shared'; import { ErrorContextKey } from '../../../../../../../state/error'; import { ContextErrorBanner } from '../../../../../../../ui/common/context-error-banner/context-error-banner.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts index b0941bb7e9..8e13947e9e 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.spec.ts @@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditPort } from './edit-port.component'; import { EditComponentDialogRequest } from '../../../../../state/flow'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts index 46cb11c911..b69fbc947d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts @@ -23,7 +23,6 @@ import { Store } from '@ngrx/store'; import { updateComponent } from '../../../../../state/flow/flow.actions'; import { Client } from '../../../../../../../service/client.service'; import { EditComponentDialogRequest } from '../../../../../state/flow'; -import { ComponentType } from 'libs/shared/src'; import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; import { MatInputModule } from '@angular/material/input'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -33,7 +32,7 @@ import { selectSaving } from '../../../../../state/flow/flow.selectors'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; import { CanvasUtils } from '../../../../../service/canvas-utils.service'; -import { NifiTooltipDirective, TextTip, CloseOnEscapeDialog } from '@nifi/shared'; +import { ComponentType, NifiTooltipDirective, TextTip, CloseOnEscapeDialog } from '@nifi/shared'; import { ErrorContextKey } from '../../../../../../../state/error'; import { ContextErrorBanner } from '../../../../../../../ui/common/context-error-banner/context-error-banner.component'; @Component({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.spec.ts index 2ef00b22a4..3e9529e24b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.spec.ts @@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CreateProcessGroup } from './create-process-group.component'; import { CreateProcessGroupDialogRequest } from '../../../../../state/flow'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.ts index 56dd16379c..e102fb8131 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/create-process-group/create-process-group.component.ts @@ -21,7 +21,6 @@ import { CreateProcessGroupDialogRequest } from '../../../../../state/flow'; import { Store } from '@ngrx/store'; import { CanvasState } from '../../../../../state'; import { createProcessGroup, uploadProcessGroup } from '../../../../../state/flow/flow.actions'; -import { SelectOption } from 'libs/shared/src'; import { selectSaving } from '../../../../../state/flow/flow.selectors'; import { AsyncPipe } from '@angular/common'; import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; @@ -34,7 +33,7 @@ import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nif import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { MatIconModule } from '@angular/material/icon'; import { NiFiCommon, TextTip, NifiTooltipDirective } from '@nifi/shared'; -import { CloseOnEscapeDialog } from '@nifi/shared'; +import { CloseOnEscapeDialog, SelectOption } from '@nifi/shared'; import { ErrorContextKey } from '../../../../../../../state/error'; import { ContextErrorBanner } from '../../../../../../../ui/common/context-error-banner/context-error-banner.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts index 8f2a1c36d1..e0edbb0834 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts @@ -26,11 +26,10 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { Observable } from 'rxjs'; -import { SelectOption } from 'libs/shared/src'; import { ParameterContextEntity } from '../../../../../../../state/shared'; import { Client } from '../../../../../../../service/client.service'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; -import { NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { NifiTooltipDirective, SelectOption, TextTip } from '@nifi/shared'; import { EditComponentDialogRequest } from '../../../../../state/flow'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; import { TabbedDialog } from '../../../../../../../ui/common/tabbed-dialog/tabbed-dialog.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.spec.ts index 116bfce791..849e153929 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.spec.ts @@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { GroupComponents } from './group-components.component'; import { GroupComponentsDialogRequest } from '../../../../../state/flow'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.ts index b36843af64..b8be35788b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/group-components/group-components.component.ts @@ -21,7 +21,6 @@ import { GroupComponentsDialogRequest } from '../../../../../state/flow'; import { Store } from '@ngrx/store'; import { CanvasState } from '../../../../../state'; import { groupComponents } from '../../../../../state/flow/flow.actions'; -import { ComponentType, SelectOption } from 'libs/shared/src'; import { selectSaving } from '../../../../../state/flow/flow.selectors'; import { AsyncPipe } from '@angular/common'; import { MatButtonModule } from '@angular/material/button'; @@ -31,7 +30,7 @@ import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; -import { TextTip, NifiTooltipDirective } from '@nifi/shared'; +import { ComponentType, SelectOption, TextTip, NifiTooltipDirective } from '@nifi/shared'; import { MatIconModule } from '@angular/material/icon'; import { Client } from '../../../../../../../service/client.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/create-processor/create-processor.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/create-processor/create-processor.component.spec.ts index 24fb04085c..07a834ffb3 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/create-processor/create-processor.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/create-processor/create-processor.component.spec.ts @@ -22,7 +22,7 @@ import { CreateProcessorDialogRequest } from '../../../../../state/flow'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../../../state/extension-types/extension-types.reducer'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('CreateProcessor', () => { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts index 579ab3e036..fc1b28a551 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.spec.ts @@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditProcessor } from './edit-processor.component'; import { EditComponentDialogRequest } from '../../../../../state/flow'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts index b1264b036d..2ef97cebef 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts @@ -37,13 +37,11 @@ import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { Observable, of } from 'rxjs'; import { - BulletinEntity, BulletinsTipInput, InlineServiceCreationRequest, InlineServiceCreationResponse, ParameterContextEntity, - Property, - Revision + Property } from '../../../../../../../state/shared'; import { Client } from '../../../../../../../service/client.service'; import { @@ -56,7 +54,16 @@ import { } from '../../../../../state/flow'; import { PropertyTable } from '../../../../../../../ui/common/property-table/property-table.component'; import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive'; -import { NifiTooltipDirective, NiFiCommon, TextTip, CopyDirective } from '@nifi/shared'; +import { + ComponentType, + SelectOption, + NifiTooltipDirective, + NiFiCommon, + TextTip, + CopyDirective, + Revision, + BulletinEntity +} from '@nifi/shared'; import { RunDurationSlider } from './run-duration-slider/run-duration-slider.component'; import { RelationshipConfiguration, @@ -72,7 +79,6 @@ import { VerifyPropertiesRequestContext } from '../../../../../../../state/property-verification'; import { TabbedDialog } from '../../../../../../../ui/common/tabbed-dialog/tabbed-dialog.component'; -import { ComponentType, SelectOption } from 'libs/shared/src'; import { ErrorContextKey } from '../../../../../../../state/error'; import { ContextErrorBanner } from '../../../../../../../ui/common/context-error-banner/context-error-banner.component'; import { BulletinsTip } from '../../../../../../../ui/common/tooltips/bulletins-tip/bulletins-tip.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/create-remote-process-group/create-remote-process-group.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/create-remote-process-group/create-remote-process-group.component.spec.ts index 24738425e4..201e49b199 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/create-remote-process-group/create-remote-process-group.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/create-remote-process-group/create-remote-process-group.component.spec.ts @@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CreateRemoteProcessGroup } from './create-remote-process-group.component'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/edit-remote-process-group/edit-remote-process-group.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/edit-remote-process-group/edit-remote-process-group.component.spec.ts index 0d567adc9a..ed46f34aa3 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/edit-remote-process-group/edit-remote-process-group.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/remote-process-group/edit-remote-process-group/edit-remote-process-group.component.spec.ts @@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditRemoteProcessGroup } from './edit-remote-process-group.component'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../../state/flow/flow.reducer'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts index 21913e743d..7f83a03cf4 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts @@ -43,7 +43,7 @@ import { selectControllerService } from '../../state/controller-services/controller-services.actions'; import { initialState } from '../../state/controller-services/controller-services.reducer'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { ControllerServiceEntity } from '../../../../state/shared'; import { BreadcrumbEntity } from '../../state/shared'; import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts index a693295ab9..4b470e0a32 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.spec.ts @@ -22,7 +22,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { provideMockStore } from '@ngrx/store/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EditComponentDialogRequest } from '../../../state/flow'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { initialState } from '../../../state/manage-remote-ports/manage-remote-ports.reducer'; import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts index 8fd37a6201..d47addef6f 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/edit-remote-port/edit-remote-port.component.ts @@ -28,12 +28,11 @@ import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spin import { selectSaving } from '../../../state/manage-remote-ports/manage-remote-ports.selectors'; import { EditRemotePortDialogRequest } from '../../../state/flow'; import { Client } from '../../../../../service/client.service'; -import { ComponentType } from 'libs/shared/src'; import { PortSummary } from '../../../state/manage-remote-ports'; import { configureRemotePort } from '../../../state/manage-remote-ports/manage-remote-ports.actions'; import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; import { NifiTooltipDirective, TextTip } from '@nifi/shared'; -import { CloseOnEscapeDialog } from '@nifi/shared'; +import { ComponentType, CloseOnEscapeDialog } from '@nifi/shared'; import { CanvasState } from '../../../state'; import { ErrorContextKey } from '../../../../../state/error'; import { ContextErrorBanner } from '../../../../../ui/common/context-error-banner/context-error-banner.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.ts index a54c04b7bc..c3bc81201c 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.ts @@ -39,10 +39,9 @@ import { stopRemotePortTransmission } from '../../state/manage-remote-ports/manage-remote-ports.actions'; import { initialState } from '../../state/manage-remote-ports/manage-remote-ports.reducer'; -import { isDefinedAndNotNull } from 'libs/shared/src'; import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; import { NiFiState } from '../../../../state'; -import { NiFiCommon, TextTip } from '@nifi/shared'; +import { isDefinedAndNotNull, NiFiCommon, TextTip } from '@nifi/shared'; import { MatTableDataSource } from '@angular/material/table'; import { Sort } from '@angular/material/sort'; import { concatLatestFrom } from '@ngrx/operators'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/feature/login.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/feature/login.component.ts index 69523307dd..ae3bc4b7f2 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/feature/login.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/feature/login.component.ts @@ -22,7 +22,7 @@ import { selectCurrentUserState } from '../../../state/current-user/current-user import { take } from 'rxjs'; import { selectLoginConfiguration } from '../../../state/login-configuration/login-configuration.selectors'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull } from '@nifi/shared'; @Component({ selector: 'login', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/state/access/access.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/state/access/access.effects.ts index fe6605719c..0f08ce310d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/state/access/access.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/login/state/access/access.effects.ts @@ -23,7 +23,7 @@ import { AuthService } from '../../../../service/auth.service'; import { Router } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component'; -import { MEDIUM_DIALOG } from 'libs/shared/src'; +import { MEDIUM_DIALOG } from '@nifi/shared'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; import { Store } from '@ngrx/store'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.effects.ts index 40dffc6566..ddc65aa457 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.effects.ts @@ -39,7 +39,7 @@ import { Store } from '@ngrx/store'; import { NiFiState } from '../../../../state'; import { Router } from '@angular/router'; import { ParameterContextService } from '../../service/parameter-contexts.service'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { Parameter, YesNoDialog } from '@nifi/shared'; import { EditParameterContext } from '../../ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component'; import { selectParameterContexts, @@ -47,19 +47,13 @@ import { selectSaving, selectUpdateRequest } from './parameter-context-listing.selectors'; -import { - EditParameterRequest, - EditParameterResponse, - Parameter, - ParameterContextUpdateRequest -} from '../../../../state/shared'; +import { EditParameterRequest, EditParameterResponse, ParameterContextUpdateRequest } from '../../../../state/shared'; import { EditParameterDialog } from '../../../../ui/common/edit-parameter-dialog/edit-parameter-dialog.component'; import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; -import { isDefinedAndNotNull, MEDIUM_DIALOG, SMALL_DIALOG, XL_DIALOG } from 'libs/shared/src'; import { BackNavigation } from '../../../../state/navigation'; -import { NiFiCommon, Storage } from '@nifi/shared'; +import { isDefinedAndNotNull, MEDIUM_DIALOG, SMALL_DIALOG, XL_DIALOG, NiFiCommon, Storage } from '@nifi/shared'; import { ErrorContextKey } from '../../../../state/error'; @Injectable() diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.reducer.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.reducer.ts index 025b6bbe3b..4677631e05 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.reducer.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.reducer.ts @@ -32,7 +32,8 @@ import { submitParameterContextUpdateRequestSuccess, deleteParameterContextUpdateRequestSuccess } from './parameter-context-listing.actions'; -import { ParameterContextUpdateRequestEntity, Revision } from '../../../../state/shared'; +import { ParameterContextUpdateRequestEntity } from '../../../../state/shared'; +import { Revision } from '@nifi/shared'; export const initialState: ParameterContextListingState = { parameterContexts: [], diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts index 295c155b81..9c725a2d98 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts @@ -32,7 +32,6 @@ import { Client } from '../../../../../service/client.service'; import { ParameterTable } from '../parameter-table/parameter-table.component'; import { EditParameterResponse, - Parameter, ParameterContextEntity, ParameterContextUpdateRequestEntity, ParameterEntity, @@ -42,10 +41,9 @@ import { ProcessGroupReferences } from '../process-group-references/process-grou import { ParameterContextInheritance } from '../parameter-context-inheritance/parameter-context-inheritance.component'; import { ParameterReferences } from '../../../../../ui/common/parameter-references/parameter-references.component'; import { RouterLink } from '@angular/router'; -import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; import { TabbedDialog } from '../../../../../ui/common/tabbed-dialog/tabbed-dialog.component'; -import { NiFiCommon, TextTip, NifiTooltipDirective, CopyDirective } from '@nifi/shared'; +import { NiFiCommon, TextTip, NifiTooltipDirective, CopyDirective, Parameter } from '@nifi/shared'; import { ErrorContextKey } from '../../../../../state/error'; import { ContextErrorBanner } from '../../../../../ui/common/context-error-banner/context-error-banner.component'; @@ -70,7 +68,6 @@ import { ContextErrorBanner } from '../../../../../ui/common/context-error-banne ParameterContextInheritance, ParameterReferences, RouterLink, - ErrorBanner, NifiTooltipDirective, ContextErrorBanner, CopyDirective diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts index b45f1dbbec..d2128f2f5e 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts @@ -20,12 +20,9 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatDialogModule } from '@angular/material/dialog'; import { MatTableModule } from '@angular/material/table'; -import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; -import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; -import { RouterLink } from '@angular/router'; -import { ParameterContextEntity, ParameterContextReferenceEntity } from '../../../../../state/shared'; -import { NifiTooltipDirective, NiFiCommon, TextTip } from '@nifi/shared'; -import { ParameterReferences } from '../../../../../ui/common/parameter-references/parameter-references.component'; +import { NgTemplateOutlet } from '@angular/common'; +import { ParameterContextEntity } from '../../../../../state/shared'; +import { NifiTooltipDirective, NiFiCommon, TextTip, ParameterContextReferenceEntity } from '@nifi/shared'; import { DragDropModule, CdkDrag, @@ -45,12 +42,7 @@ import { MatTableModule, DragDropModule, NgTemplateOutlet, - CdkOverlayOrigin, - CdkConnectedOverlay, - RouterLink, - AsyncPipe, NifiTooltipDirective, - ParameterReferences, CdkDropList, CdkDrag ], diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts index 1d1c5fe01a..97c919dc9b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts @@ -23,8 +23,8 @@ import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; import { RouterLink } from '@angular/router'; -import { EditParameterResponse, Parameter, ParameterEntity } from '../../../../../state/shared'; -import { NifiTooltipDirective, NiFiCommon, TextTip } from '@nifi/shared'; +import { EditParameterResponse, ParameterEntity } from '../../../../../state/shared'; +import { NifiTooltipDirective, NiFiCommon, TextTip, Parameter } from '@nifi/shared'; import { Observable, take } from 'rxjs'; import { ParameterReferences } from '../../../../../ui/common/parameter-references/parameter-references.component'; import { Store } from '@ngrx/store'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/lineage/lineage.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/lineage/lineage.effects.ts index 0700656f34..a7a198c47a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/lineage/lineage.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/lineage/lineage.effects.ts @@ -29,7 +29,7 @@ import { selectActiveLineageId, selectClusterNodeIdFromActiveLineage } from './l import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; -import { isDefinedAndNotNull, NiFiCommon } from 'libs/shared/src'; +import { isDefinedAndNotNull, NiFiCommon } from '@nifi/shared'; import { ErrorContextKey } from '../../../../state/error'; @Injectable() diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts index e791ab21ba..70873155c6 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts @@ -41,10 +41,9 @@ import { CancelDialog } from '../../../../ui/common/cancel-dialog/cancel-dialog. import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; -import { isDefinedAndNotNull, NiFiCommon } from 'libs/shared/src'; +import { isDefinedAndNotNull, NiFiCommon, LARGE_DIALOG, MEDIUM_DIALOG } from '@nifi/shared'; import { selectClusterSummary } from '../../../../state/cluster-summary/cluster-summary.selectors'; import { ClusterService } from '../../../../service/cluster.service'; -import { LARGE_DIALOG, MEDIUM_DIALOG } from 'libs/shared/src'; import { Attribute } from '../../../../state/shared'; import { ErrorContextKey } from '../../../../state/error'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-search-dialog/provenance-search-dialog.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-search-dialog/provenance-search-dialog.component.ts index 21da7f6fac..cdae96be9e 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-search-dialog/provenance-search-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-search-dialog/provenance-search-dialog.component.ts @@ -29,10 +29,9 @@ import { } from '../../../state/provenance-event-listing'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { NiFiCommon, TextTip, NifiTooltipDirective } from '@nifi/shared'; -import { SelectOption } from 'libs/shared/src'; import { MatOption } from '@angular/material/autocomplete'; import { MatSelect } from '@angular/material/select'; -import { CloseOnEscapeDialog } from '@nifi/shared'; +import { CloseOnEscapeDialog, SelectOption } from '@nifi/shared'; @Component({ selector: 'provenance-search-dialog', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.effects.ts index 42c06eea5b..e978d5cd6b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.effects.ts @@ -29,13 +29,11 @@ import { CancelDialog } from '../../../../ui/common/cancel-dialog/cancel-dialog. import { MatDialog } from '@angular/material/dialog'; import { selectAbout } from '../../../../state/about/about.selectors'; import { FlowFileDialog } from '../../ui/queue-listing/flowfile-dialog/flowfile-dialog.component'; -import { NiFiCommon } from '@nifi/shared'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull, NiFiCommon, LARGE_DIALOG } from '@nifi/shared'; import { HttpErrorResponse } from '@angular/common/http'; import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { stopPollingQueueListingRequest } from './queue-listing.actions'; -import { LARGE_DIALOG } from 'libs/shared/src'; import { ErrorContextKey } from '../../../../state/error'; @Injectable() diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts index 6ca955cc5b..254a0230bf 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/controller-service-advanced-ui-params.resolver.ts @@ -70,7 +70,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn { const revision = client.getRevision(entity); - const editable = entity.status.runStatus === 'DISABLED'; + const editable = entity.status.runStatus === 'DISABLED' && entity.permissions.canWrite; return { url: entity.component.customUiUrl, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/parameter-provider-advanced-ui-params.resolver.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/parameter-provider-advanced-ui-params.resolver.ts index d254183555..45e592969d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/parameter-provider-advanced-ui-params.resolver.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/service/resolver/parameter-provider-advanced-ui-params.resolver.ts @@ -73,7 +73,7 @@ export const parameterProviderAdvancedUiParamsResolver: ResolveFn map((entity) => { const revision = client.getRevision(entity); - const editable = entity.status.runStatus === 'STOPPED' || entity.status.runStatus === 'DISABLED'; + const editable = + (entity.status.runStatus === 'STOPPED' || entity.status.runStatus === 'DISABLED') && + entity.permissions.canWrite; return { url: entity.component.customUiUrl, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts index de4397ced8..9c2bc4ce4b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts @@ -24,7 +24,7 @@ import { MatDialog } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { NiFiState } from '../../../../state'; import { selectFlowAnalysisRuleTypes } from '../../../../state/extension-types/extension-types.selectors'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG, YesNoDialog } from '@nifi/shared'; import { FlowAnalysisRuleService } from '../../service/flow-analysis-rule.service'; import { ManagementControllerServiceService } from '../../service/management-controller-service.service'; import { CreateFlowAnalysisRule } from '../../ui/flow-analysis-rules/create-flow-analysis-rule/create-flow-analysis-rule.component'; @@ -42,7 +42,6 @@ import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { selectStatus } from './flow-analysis-rules.selectors'; import { HttpErrorResponse } from '@angular/common/http'; -import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from 'libs/shared/src'; import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; import { ExtensionTypesService } from '../../../../service/extension-types.service'; import { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/index.ts index 0124769ac6..9d6ac48920 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/flow-analysis-rules/index.ts @@ -15,14 +15,8 @@ * limitations under the License. */ -import { - BulletinEntity, - Bundle, - ComponentHistory, - DocumentedType, - Permissions, - Revision -} from '../../../../state/shared'; +import { Bundle, ComponentHistory, DocumentedType } from '../../../../state/shared'; +import { BulletinEntity, Permissions, Revision } from '@nifi/shared'; export const flowAnalysisRulesFeatureKey = 'flowAnalysisRules'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.effects.ts index ef3e2647ca..2f6ab625bc 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.effects.ts @@ -29,7 +29,7 @@ import { selectStatus } from './general.selectors'; import { NiFiState } from '../../../../state'; import { Store } from '@ngrx/store'; import { HttpErrorResponse } from '@angular/common/http'; -import { SMALL_DIALOG } from 'libs/shared/src'; +import { SMALL_DIALOG } from '@nifi/shared'; @Injectable() export class GeneralEffects { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.reducer.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.reducer.ts index 6d1ba8bf45..30fe016e34 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.reducer.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/general.reducer.ts @@ -25,7 +25,7 @@ import { updateControllerConfig, updateControllerConfigSuccess } from './general.actions'; -import { Revision } from '../../../../state/shared'; +import { Revision } from '@nifi/shared'; export const INITIAL_REVISION: Revision = { version: 0, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/index.ts index e10364ef0c..37fc27e03d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/general/index.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Revision } from '../../../../state/shared'; +import { Revision } from '@nifi/shared'; export const generalFeatureKey = 'general'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts index f231e82212..d656f23467 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts @@ -28,7 +28,6 @@ import { NiFiState } from '../../../../state'; import { selectControllerServiceTypes } from '../../../../state/extension-types/extension-types.selectors'; import { CreateControllerService } from '../../../../ui/common/controller-service/create-controller-service/create-controller-service.component'; import { Client } from '../../../../service/client.service'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; import { EditControllerService } from '../../../../ui/common/controller-service/edit-controller-service/edit-controller-service.component'; import { ControllerServiceReferencingComponent, @@ -43,7 +42,7 @@ import { DisableControllerService } from '../../../../ui/common/controller-servi import { PropertyTableHelperService } from '../../../../service/property-table-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../../../service/error-helper.service'; -import { ComponentType, LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from 'libs/shared/src'; +import { ComponentType, LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG, YesNoDialog } from '@nifi/shared'; import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; import { ExtensionTypesService } from '../../../../service/extension-types.service'; import { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/index.ts index f8bdceefa7..513dd9782b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/index.ts @@ -16,16 +16,13 @@ */ import { - AffectedComponentEntity, Bundle, ComponentHistory, DocumentedType, - ParameterContextReferenceEntity, ParameterEntity, - Permissions, - PropertyDescriptor, - Revision + PropertyDescriptor } from '../../../../state/shared'; +import { AffectedComponentEntity, ParameterContextReferenceEntity, Permissions, Revision } from '@nifi/shared'; export const parameterProvidersFeatureKey = 'parameterProviders'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/parameter-providers.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/parameter-providers.effects.ts index b4cf986301..3fbb0cf499 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/parameter-providers.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/parameter-providers/parameter-providers.effects.ts @@ -47,7 +47,6 @@ import { } from './parameter-providers.selectors'; import { selectParameterProviderTypes } from '../../../../state/extension-types/extension-types.selectors'; import { CreateParameterProvider } from '../../ui/parameter-providers/create-parameter-provider/create-parameter-provider.component'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; import { EditParameterProvider } from '../../ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component'; import { PropertyTableHelperService } from '../../../../service/property-table-helper.service'; import { EditParameterProviderRequest, ParameterProviderEntity, UpdateParameterProviderRequest } from './index'; @@ -56,7 +55,7 @@ import { FetchParameterProviderParameters } from '../../ui/parameter-providers/f import * as ErrorActions from '../../../../state/error/error.actions'; import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../../../service/error-helper.service'; -import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from 'libs/shared/src'; +import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG, YesNoDialog } from '@nifi/shared'; import { resetPropertyVerificationState, verifyProperties diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/index.ts index e972ecadf8..a1caa68e4a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/index.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { Bundle, DocumentedType, RegistryClientEntity, Revision } from '../../../../state/shared'; +import { Bundle, DocumentedType, RegistryClientEntity } from '../../../../state/shared'; +import { Revision } from '@nifi/shared'; export const registryClientsFeatureKey = 'registryClients'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/registry-clients.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/registry-clients.effects.ts index ae69cc414d..023f724797 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/registry-clients.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/registry-clients/registry-clients.effects.ts @@ -24,7 +24,7 @@ import { MatDialog } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { NiFiState } from '../../../../state'; import { selectRegistryClientTypes } from '../../../../state/extension-types/extension-types.selectors'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { LARGE_DIALOG, SMALL_DIALOG, YesNoDialog } from '@nifi/shared'; import { Router } from '@angular/router'; import { RegistryClientService } from '../../service/registry-client.service'; import { CreateRegistryClient } from '../../ui/registry-clients/create-registry-client/create-registry-client.component'; @@ -36,7 +36,6 @@ import { PropertyTableHelperService } from '../../../../service/property-table-h import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; -import { LARGE_DIALOG, SMALL_DIALOG } from 'libs/shared/src'; import { BackNavigation } from '../../../../state/navigation'; import { ErrorContextKey } from '../../../../state/error'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/index.ts index 33abaa4c99..7741a94d7e 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/index.ts @@ -15,14 +15,8 @@ * limitations under the License. */ -import { - BulletinEntity, - Bundle, - ComponentHistory, - DocumentedType, - Permissions, - Revision -} from '../../../../state/shared'; +import { Bundle, ComponentHistory, DocumentedType } from '../../../../state/shared'; +import { BulletinEntity, Permissions, Revision } from '@nifi/shared'; export const reportingTasksFeatureKey = 'reportingTasks'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts index 0bcf5d1954..e5eff115d8 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts @@ -24,7 +24,7 @@ import { MatDialog } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { NiFiState } from '../../../../state'; import { selectReportingTaskTypes } from '../../../../state/extension-types/extension-types.selectors'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG, YesNoDialog } from '@nifi/shared'; import { ReportingTaskService } from '../../service/reporting-task.service'; import { CreateReportingTask } from '../../ui/reporting-tasks/create-reporting-task/create-reporting-task.component'; import { Router } from '@angular/router'; @@ -38,7 +38,6 @@ import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { selectStatus } from './reporting-tasks.selectors'; import { HttpErrorResponse } from '@angular/common/http'; -import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from 'libs/shared/src'; import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; import { ExtensionTypesService } from '../../../../service/extension-types.service'; import { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts index ec2ebcc38c..9ffdb4b645 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component.ts @@ -27,7 +27,7 @@ import { AbstractControl, FormBuilder, FormControl, FormGroup, ReactiveFormsModu import { Observable, of } from 'rxjs'; import { Client } from '../../../../../service/client.service'; import { InlineServiceCreationRequest, InlineServiceCreationResponse, Property } from '../../../../../state/shared'; -import { CopyDirective, NiFiCommon, NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { CopyDirective, NiFiCommon, NifiTooltipDirective, TextTip, SelectOption } from '@nifi/shared'; import { PropertyTable } from '../../../../../ui/common/property-table/property-table.component'; import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spinner.directive'; import { @@ -45,7 +45,6 @@ import { } from '../../../../../state/property-verification'; import { PropertyVerification } from '../../../../../ui/common/property-verification/property-verification.component'; import { TabbedDialog } from '../../../../../ui/common/tabbed-dialog/tabbed-dialog.component'; -import { SelectOption } from 'libs/shared/src'; import { ErrorContextKey } from '../../../../../state/error'; import { ContextErrorBanner } from '../../../../../ui/common/context-error-banner/context-error-banner.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts index e4c58e3c24..d6e286d5b8 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/edit-parameter-provider/edit-parameter-provider.component.ts @@ -22,12 +22,7 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatButtonModule } from '@angular/material/button'; import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spinner.directive'; import { Observable, of } from 'rxjs'; -import { - InlineServiceCreationRequest, - InlineServiceCreationResponse, - ParameterContextReferenceEntity, - Property -} from '../../../../../state/shared'; +import { InlineServiceCreationRequest, InlineServiceCreationResponse, Property } from '../../../../../state/shared'; import { EditParameterProviderRequest, ParameterProviderEntity, @@ -37,13 +32,17 @@ import { AbstractControl, FormBuilder, FormControl, FormGroup, ReactiveFormsModu import { Client } from '../../../../../service/client.service'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; -import { ControllerServiceReferences } from '../../../../../ui/common/controller-service/controller-service-references/controller-service-references.component'; import { ParameterProviderReferences } from '../parameter-context-references/parameter-provider-references.component'; import { PropertyTable } from '../../../../../ui/common/property-table/property-table.component'; -import { ErrorBanner } from '../../../../../ui/common/error-banner/error-banner.component'; import { CommonModule } from '@angular/common'; import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; -import { TextTip, NiFiCommon, NifiTooltipDirective, CopyDirective } from '@nifi/shared'; +import { + TextTip, + NiFiCommon, + NifiTooltipDirective, + CopyDirective, + ParameterContextReferenceEntity +} from '@nifi/shared'; import { ConfigVerificationResult, ModifiedProperties, @@ -65,10 +64,8 @@ import { ContextErrorBanner } from '../../../../../ui/common/context-error-banne ReactiveFormsModule, MatFormFieldModule, MatInputModule, - ControllerServiceReferences, ParameterProviderReferences, PropertyTable, - ErrorBanner, CommonModule, NifiTooltipDirective, PropertyVerification, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts index 0a0eced6cd..799c858b21 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/fetch-parameter-provider-parameters/fetch-parameter-provider-parameters.component.ts @@ -34,14 +34,13 @@ import { ParameterStatusEntity } from '../../../state/parameter-providers'; import { debounceTime, Observable, Subject } from 'rxjs'; -import { TextTip, NiFiCommon, NifiTooltipDirective, PipesModule } from '@nifi/shared'; +import { TextTip, NiFiCommon, NifiTooltipDirective, PipesModule, AffectedComponentEntity } from '@nifi/shared'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { MatSortModule, Sort } from '@angular/material/sort'; import { ParameterGroupsTable } from './parameter-groups-table/parameter-groups-table.component'; import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox'; import { MatInputModule } from '@angular/material/input'; import { ParameterReferences } from '../../../../../ui/common/parameter-references/parameter-references.component'; -import { AffectedComponentEntity } from '../../../../../state/shared'; import * as ParameterProviderActions from '../../../state/parameter-providers/parameter-providers.actions'; import { Store } from '@ngrx/store'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-context-references/parameter-provider-references.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-context-references/parameter-provider-references.component.ts index 0fb8810696..1425d71f6f 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-context-references/parameter-provider-references.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-context-references/parameter-provider-references.component.ts @@ -17,8 +17,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { ParameterContextReferenceEntity } from '../../../../../state/shared'; -import { NiFiCommon } from '@nifi/shared'; +import { NiFiCommon, ParameterContextReferenceEntity } from '@nifi/shared'; import { RouterLink } from '@angular/router'; @Component({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers.component.ts index 308934d068..76e0df9b0d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers.component.ts @@ -32,7 +32,7 @@ import * as ParameterProviderActions from '../../state/parameter-providers/param import { initialParameterProvidersState } from '../../state/parameter-providers/parameter-providers.reducer'; import { switchMap, take } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { navigateToComponentDocumentation } from '../../../../state/documentation/documentation.actions'; @Component({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts index d4d5a01398..49f01bd8e0 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/settings/ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component.ts @@ -51,7 +51,7 @@ import { } from '../../../../../state/property-verification'; import { PropertyVerification } from '../../../../../ui/common/property-verification/property-verification.component'; import { TabbedDialog } from '../../../../../ui/common/tabbed-dialog/tabbed-dialog.component'; -import { SelectOption } from 'libs/shared/src'; +import { SelectOption } from '@nifi/shared'; import { ErrorContextKey } from '../../../../../state/error'; import { ContextErrorBanner } from '../../../../../ui/common/context-error-banner/context-error-banner.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/feature/summary.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/feature/summary.component.ts index 942f1942b1..40a1b4cb8d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/feature/summary.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/feature/summary.component.ts @@ -22,7 +22,7 @@ import { loadSummaryListing, resetSummaryState } from '../state/summary-listing/ import { loadClusterSummary, searchCluster } from '../../../state/cluster-summary/cluster-summary.actions'; import { selectClusterSummary } from '../../../state/cluster-summary/cluster-summary.selectors'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull } from '@nifi/shared'; import { selectSelectedClusterNode } from '../state/summary-listing/summary-listing.selectors'; interface TabLink { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/service/component-cluster-status.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/service/component-cluster-status.service.ts index 13b7fa0679..8c87828d33 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/service/component-cluster-status.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/service/component-cluster-status.service.ts @@ -18,7 +18,7 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; @Injectable({ providedIn: 'root' }) export class ComponentClusterStatusService { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.effects.ts index 3e82301d5b..5308434d33 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.effects.ts @@ -27,10 +27,9 @@ import { ComponentClusterStatusService } from '../../service/component-cluster-s import { MatDialog } from '@angular/material/dialog'; import { ClusterSummaryDialog } from '../../ui/common/cluster-summary-dialog/cluster-summary-dialog.component'; import { selectComponentClusterStatusLatestRequest } from './component-cluster-status.selectors'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull, XL_DIALOG } from '@nifi/shared'; import { HttpErrorResponse } from '@angular/common/http'; import * as ErrorActions from '../../../../state/error/error.actions'; -import { XL_DIALOG } from 'libs/shared/src'; @Injectable() export class ComponentClusterStatusEffects { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.reducer.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.reducer.ts index 0841737514..74091ad19a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.reducer.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/component-cluster-status.reducer.ts @@ -18,7 +18,7 @@ import { createReducer, on } from '@ngrx/store'; import { ComponentClusterStatusState } from './index'; import * as ClusterStatusActions from './component-cluster-status.actions'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; export const initialComponentClusterStatusState: ComponentClusterStatusState = { clusterStatus: null, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/index.ts index 648d221b10..8b15a6c418 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/component-cluster-status/index.ts @@ -16,7 +16,7 @@ */ import { ConnectionStatus, PortStatus, ProcessGroupStatus, ProcessorStatus, RemoteProcessGroupStatus } from '../index'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; export const componentClusterStatusFeatureKey = 'component-cluster-status'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/summary-listing/summary-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/summary-listing/summary-listing.effects.ts index 4ed0cfb26f..686dc30927 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/summary-listing/summary-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/state/summary-listing/summary-listing.effects.ts @@ -25,7 +25,7 @@ import * as SummaryListingActions from './summary-listing.actions'; import * as StatusHistoryActions from '../../../../state/status-history/status-history.actions'; import { catchError, filter, from, map, of, switchMap, tap } from 'rxjs'; import { Router } from '@angular/router'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; import { selectSelectedClusterNode, selectSummaryListingStatus } from './summary-listing.selectors'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.spec.ts index 4ae39d09ad..fc56ff7505 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.spec.ts @@ -22,7 +22,7 @@ import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/materia import { provideMockStore } from '@ngrx/store/testing'; import { initialComponentClusterStatusState } from '../../../state/component-cluster-status/component-cluster-status.reducer'; import { ComponentClusterStatusRequest, ComponentClusterStatusState } from '../../../state/component-cluster-status'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('ClusterSummaryDialog', () => { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.ts index 5289dba0be..3f998d0d39 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/cluster-summary-dialog/cluster-summary-dialog.component.ts @@ -24,8 +24,7 @@ import { MatDialogTitle } from '@angular/material/dialog'; import { MatButton, MatButtonModule } from '@angular/material/button'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; -import { ComponentContext } from '@nifi/shared'; +import { ComponentType, isDefinedAndNotNull, ComponentContext, CloseOnEscapeDialog } from '@nifi/shared'; import { ClusterStatusEntity, ComponentClusterStatusRequest, @@ -47,7 +46,6 @@ import { PortClusterTable } from './port-cluster-table/port-cluster-table.compon import { RemoteProcessGroupClusterTable } from './remote-process-group-cluster-table/remote-process-group-cluster-table.component'; import { ConnectionClusterTable } from './connection-cluster-table/connection-cluster-table.component'; import { ProcessGroupClusterTable } from './process-group-cluster-table/process-group-cluster-table.component'; -import { CloseOnEscapeDialog } from '@nifi/shared'; interface Helper { getName: () => string; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/port-status-table/port-status-table.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/port-status-table/port-status-table.component.ts index 442dec0d14..1607665b6a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/port-status-table/port-status-table.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/common/port-status-table/port-status-table.component.ts @@ -21,9 +21,8 @@ import { MatSortModule, Sort } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { SummaryTableFilterModule } from '../summary-table-filter/summary-table-filter.module'; import { SummaryTableFilterColumn } from '../summary-table-filter/summary-table-filter.component'; -import { ComponentType } from 'libs/shared/src'; import { RouterLink } from '@angular/router'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { MatPaginatorModule } from '@angular/material/paginator'; import { PortStatusSnapshot, PortStatusSnapshotEntity } from '../../../state'; import { ComponentStatusTable } from '../component-status-table/component-status-table.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-listing.component.ts index bbdef3f78b..e8cce64a88 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-listing.component.ts @@ -33,7 +33,7 @@ import { selectCurrentUser } from '../../../../state/current-user/current-user.s import { filter, map, switchMap, take } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { getStatusHistoryAndOpenDialog } from '../../../../state/status-history/status-history.actions'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { loadClusterSummary } from '../../../../state/cluster-summary/cluster-summary.actions'; import { ConnectionStatusSnapshotEntity } from '../../state'; import { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-table/connection-status-table.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-table/connection-status-table.component.ts index 1d8cdda565..9c69301e0f 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-table/connection-status-table.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/connection-status-listing/connection-status-table/connection-status-table.component.ts @@ -19,10 +19,9 @@ import { Component } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SummaryTableFilterModule } from '../../common/summary-table-filter/summary-table-filter.module'; import { MatSortModule, Sort } from '@angular/material/sort'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { SummaryTableFilterColumn } from '../../common/summary-table-filter/summary-table-filter.component'; import { MatTableModule } from '@angular/material/table'; -import { ComponentType } from 'libs/shared/src'; import { RouterLink } from '@angular/router'; import { MatPaginatorModule } from '@angular/material/paginator'; import { ConnectionStatusSnapshot, ConnectionStatusSnapshotEntity } from '../../../state'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/input-port-status-listing/input-port-status-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/input-port-status-listing/input-port-status-listing.component.ts index ac4d6e2d73..9a7651560a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/input-port-status-listing/input-port-status-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/input-port-status-listing/input-port-status-listing.component.ts @@ -34,7 +34,7 @@ import { selectClusterSearchResults, selectClusterSummary } from '../../../../state/cluster-summary/cluster-summary.selectors'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { map } from 'rxjs'; import { NodeSearchResult } from '../../../../state/cluster-summary'; import * as ClusterStatusActions from '../../state/component-cluster-status/component-cluster-status.actions'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/output-port-status-listing/output-port-status-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/output-port-status-listing/output-port-status-listing.component.ts index dd66a9cb83..dcb5e3b863 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/output-port-status-listing/output-port-status-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/output-port-status-listing/output-port-status-listing.component.ts @@ -34,7 +34,7 @@ import { selectClusterSearchResults, selectClusterSummary } from '../../../../state/cluster-summary/cluster-summary.selectors'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { map } from 'rxjs'; import { NodeSearchResult } from '../../../../state/cluster-summary'; import * as ClusterStatusActions from '../../state/component-cluster-status/component-cluster-status.actions'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/process-group-status-listing/process-group-status-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/process-group-status-listing/process-group-status-listing.component.ts index 344772ac09..af91e151c8 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/process-group-status-listing/process-group-status-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/process-group-status-listing/process-group-status-listing.component.ts @@ -33,7 +33,7 @@ import { import { filter, map, switchMap, take } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { getStatusHistoryAndOpenDialog } from '../../../../state/status-history/status-history.actions'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; import { loadClusterSummary } from '../../../../state/cluster-summary/cluster-summary.actions'; import { ProcessGroupStatusSnapshotEntity } from '../../state'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-listing.component.ts index 23c663a75e..44e7694bee 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-listing.component.ts @@ -30,7 +30,7 @@ import { SummaryListingState } from '../../state/summary-listing'; import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; import { initialState } from '../../state/summary-listing/summary-listing.reducer'; import { getStatusHistoryAndOpenDialog } from '../../../../state/status-history/status-history.actions'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { combineLatest, delay, filter, map, Subject, switchMap, take } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import * as SummaryListingActions from '../../state/summary-listing/summary-listing.actions'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-table/processor-status-table.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-table/processor-status-table.component.ts index 054f098878..8eaa31a214 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-table/processor-status-table.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/processor-status-listing/processor-status-table/processor-status-table.component.ts @@ -22,8 +22,7 @@ import { SummaryTableFilterColumn } from '../../common/summary-table-filter/summ import { RouterLink } from '@angular/router'; import { SummaryTableFilterModule } from '../../common/summary-table-filter/summary-table-filter.module'; import { NgClass } from '@angular/common'; -import { ComponentType } from 'libs/shared/src'; -import { NiFiCommon } from '@nifi/shared'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { MatPaginatorModule } from '@angular/material/paginator'; import { ProcessorStatusSnapshot, ProcessorStatusSnapshotEntity } from '../../../state'; import { ComponentStatusTable } from '../../common/component-status-table/component-status-table.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-listing.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-listing.component.ts index 532f95cd45..b00324770d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-listing.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-listing.component.ts @@ -31,7 +31,7 @@ import { SummaryListingState } from '../../state/summary-listing'; import { filter, map, switchMap, take } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { getStatusHistoryAndOpenDialog } from '../../../../state/status-history/status-history.actions'; -import { ComponentType, isDefinedAndNotNull } from 'libs/shared/src'; +import { ComponentType, isDefinedAndNotNull } from '@nifi/shared'; import { initialState } from '../../state/summary-listing/summary-listing.reducer'; import * as SummaryListingActions from '../../state/summary-listing/summary-listing.actions'; import { loadClusterSummary } from '../../../../state/cluster-summary/cluster-summary.actions'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-table/remote-process-group-status-table.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-table/remote-process-group-status-table.component.ts index 8808caba1c..abf4e93956 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-table/remote-process-group-status-table.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/summary/ui/remote-process-group-status-listing/remote-process-group-status-table/remote-process-group-status-table.component.ts @@ -21,8 +21,7 @@ import { SummaryTableFilterModule } from '../../common/summary-table-filter/summ import { MatSortModule, Sort } from '@angular/material/sort'; import { SummaryTableFilterColumn } from '../../common/summary-table-filter/summary-table-filter.component'; import { MatTableModule } from '@angular/material/table'; -import { NiFiCommon } from '@nifi/shared'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType, NiFiCommon } from '@nifi/shared'; import { RouterLink } from '@angular/router'; import { MatPaginatorModule } from '@angular/material/paginator'; import { RemoteProcessGroupStatusSnapshot, RemoteProcessGroupStatusSnapshotEntity } from '../../../state'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/index.ts index b04cf2297d..21492ed313 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/index.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { AccessPolicySummaryEntity, Revision, UserEntity, UserGroupEntity } from '../../../../state/shared'; +import { AccessPolicySummaryEntity, UserEntity, UserGroupEntity } from '../../../../state/shared'; +import { Revision } from '@nifi/shared'; export interface SelectedTenant { id: string; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/user-listing.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/user-listing.effects.ts index b46d38ff50..e5525170a2 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/user-listing.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/state/user-listing/user-listing.effects.ts @@ -26,17 +26,16 @@ import { selectTenant } from './user-listing.actions'; import { catchError, combineLatest, filter, from, map, mergeMap, of, switchMap, take, takeUntil, tap } from 'rxjs'; import { MatDialog } from '@angular/material/dialog'; import { UsersService } from '../../service/users.service'; -import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component'; +import { YesNoDialog } from '@nifi/shared'; import { EditTenantDialog } from '../../../../ui/common/edit-tenant/edit-tenant-dialog.component'; import { selectSaving, selectStatus, selectUserGroups, selectUsers } from './user-listing.selectors'; import { EditTenantRequest, UserGroupEntity } from '../../../../state/shared'; import { Client } from '../../../../service/client.service'; -import { NiFiCommon } from '@nifi/shared'; +import { LARGE_DIALOG, MEDIUM_DIALOG, SMALL_DIALOG, NiFiCommon } from '@nifi/shared'; import { UserAccessPolicies } from '../../ui/user-listing/user-access-policies/user-access-policies.component'; import * as ErrorActions from '../../../../state/error/error.actions'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; -import { LARGE_DIALOG, MEDIUM_DIALOG, SMALL_DIALOG } from 'libs/shared/src'; import { ErrorContextKey } from '../../../../state/error'; @Injectable() diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/ui/user-listing/user-access-policies/user-access-policies.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/ui/user-listing/user-access-policies/user-access-policies.component.ts index e8777487d4..c08d30494a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/ui/user-listing/user-access-policies/user-access-policies.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/users/ui/user-listing/user-access-policies/user-access-policies.component.ts @@ -22,12 +22,10 @@ import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { MatSortModule, Sort } from '@angular/material/sort'; import { AccessPolicySummaryEntity, ComponentReferenceEntity } from '../../../../../state/shared'; -import { NiFiCommon } from '@nifi/shared'; import { RouterLink } from '@angular/router'; import { UserAccessPoliciesDialogRequest } from '../../../state/user-listing'; import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu'; -import { CloseOnEscapeDialog } from '@nifi/shared'; -import { ComponentType, SelectOption } from 'libs/shared/src'; +import { ComponentType, SelectOption, CloseOnEscapeDialog, NiFiCommon } from '@nifi/shared'; @Component({ selector: 'user-access-policies', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/property-table-helper.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/property-table-helper.service.ts index 9d057c1b1b..562a707666 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/property-table-helper.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/property-table-helper.service.ts @@ -39,7 +39,7 @@ import { NiFiState } from '../state'; import { Store } from '@ngrx/store'; import { snackBarError } from '../state/error/error.actions'; import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { LARGE_DIALOG, SMALL_DIALOG } from 'libs/shared/src'; +import { LARGE_DIALOG, SMALL_DIALOG } from '@nifi/shared'; import { ErrorHelper } from './error-helper.service'; @Injectable({ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/status-history.service.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/status-history.service.ts index dd7c36fa94..fe1e15d8c0 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/status-history.service.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/service/status-history.service.ts @@ -18,7 +18,7 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Client } from './client.service'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; @Injectable({ providedIn: 'root' }) export class StatusHistoryService { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/about/about.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/about/about.effects.ts index a2b5e61b2e..14b43d10af 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/about/about.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/about/about.effects.ts @@ -24,7 +24,7 @@ import { AboutService } from '../../service/about.service'; import { HttpErrorResponse } from '@angular/common/http'; import { MatDialog } from '@angular/material/dialog'; import { AboutDialog } from '../../ui/common/about-dialog/about-dialog.component'; -import { MEDIUM_DIALOG } from 'libs/shared/src'; +import { MEDIUM_DIALOG } from '@nifi/shared'; import { ErrorHelper } from '../../service/error-helper.service'; @Injectable() diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts index 58d1df7ea4..8e816cfb43 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/cluster-summary/cluster-summary.effects.ts @@ -23,13 +23,12 @@ import { acknowledgeClusterConnectionChange, setDisconnectionAcknowledged } from import { asyncScheduler, catchError, delay, filter, from, interval, map, of, switchMap, takeUntil, tap } from 'rxjs'; import { ClusterService } from '../../service/cluster.service'; import { selectClusterSummary } from './cluster-summary.selectors'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull, MEDIUM_DIALOG } from '@nifi/shared'; import { Store } from '@ngrx/store'; import { ClusterSummary, ClusterSummaryState } from './index'; import { HttpErrorResponse } from '@angular/common/http'; import * as ErrorActions from '../error/error.actions'; import { OkDialog } from '../../ui/common/ok-dialog/ok-dialog.component'; -import { MEDIUM_DIALOG } from 'libs/shared/src'; import { MatDialog } from '@angular/material/dialog'; import { ErrorHelper } from '../../service/error-helper.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/component-state/component-state.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/component-state/component-state.effects.ts index 3598384ab6..a0108b2453 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/component-state/component-state.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/component-state/component-state.effects.ts @@ -27,7 +27,7 @@ import { MatDialog } from '@angular/material/dialog'; import { ComponentStateService } from '../../service/component-state.service'; import { ComponentStateDialog } from '../../ui/common/component-state/component-state.component'; import { selectComponentUri } from './component-state.selectors'; -import { isDefinedAndNotNull, LARGE_DIALOG } from 'libs/shared/src'; +import { isDefinedAndNotNull, LARGE_DIALOG } from '@nifi/shared'; import * as ErrorActions from '../error/error.actions'; import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../service/error-helper.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/controller-service-state.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/controller-service-state.effects.ts index 6c2a3b1b34..b8c12d4199 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/controller-service-state.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/controller-service-state.effects.ts @@ -28,7 +28,7 @@ import { MatDialog } from '@angular/material/dialog'; import { ControllerServiceStateService } from '../../service/controller-service-state.service'; import { ControllerServiceEntity, ControllerServiceReferencingComponentEntity } from '../shared'; import { SetEnableRequest, SetEnableStep } from './index'; -import { isDefinedAndNotNull, MEDIUM_DIALOG } from 'libs/shared/src'; +import { isDefinedAndNotNull, MEDIUM_DIALOG } from '@nifi/shared'; import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../service/error-helper.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/index.ts index caaf8dc4ab..26cb80ac96 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/contoller-service-state/index.ts @@ -16,7 +16,7 @@ */ import { ControllerServiceEntity, ControllerServiceReferencingComponentEntity } from '../shared'; -import { SelectOption } from 'libs/shared/src'; +import { SelectOption } from '@nifi/shared'; export const controllerServiceStateFeatureKey = 'enableControllerService'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/current-user.reducer.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/current-user.reducer.ts index a63740fe39..a1b57ea94f 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/current-user.reducer.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/current-user.reducer.ts @@ -17,7 +17,7 @@ import { createReducer, on } from '@ngrx/store'; import { CurrentUserState } from './index'; -import { Permissions } from '../shared'; +import { Permissions } from '@nifi/shared'; import { loadCurrentUser, loadCurrentUserSuccess, resetCurrentUser } from './current-user.actions'; export const NO_PERMISSIONS: Permissions = { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/index.ts index ea683f857c..4dfd972c66 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/current-user/index.ts @@ -15,7 +15,8 @@ * limitations under the License. */ -import { Permissions, RequiredPermission } from '../shared'; +import { RequiredPermission } from '../shared'; +import { Permissions } from '@nifi/shared'; export const currentUserFeatureKey = 'currentUser'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/property-verification/property-verification.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/property-verification/property-verification.effects.ts index 8e083dc9e3..8349663160 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/property-verification/property-verification.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/property-verification/property-verification.effects.ts @@ -33,10 +33,9 @@ import { selectPropertyVerificationRequestContext } from './property-verification.selectors'; import { PropertyVerificationProgress } from '../../ui/common/property-verification/common/property-verification-progress/property-verification-progress.component'; -import { isDefinedAndNotNull, MEDIUM_DIALOG, SMALL_DIALOG } from 'libs/shared/src'; import { ReferencedAttributesDialog } from '../../ui/common/property-verification/common/referenced-attributes-dialog/referenced-attributes-dialog.component'; import { PropertyTableHelperService } from '../../service/property-table-helper.service'; -import { MapTableHelperService, MapTableEntry } from '@nifi/shared'; +import { isDefinedAndNotNull, MEDIUM_DIALOG, SMALL_DIALOG, MapTableHelperService, MapTableEntry } from '@nifi/shared'; @Injectable() export class PropertyVerificationEffects { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/shared/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/shared/index.ts index dad3971841..a2075d6c95 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/shared/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/shared/index.ts @@ -17,6 +17,14 @@ import { Observable } from 'rxjs'; import { GarbageCollection } from '../system-diagnostics'; +import { + AffectedComponentEntity, + BulletinEntity, + Parameter, + ParameterContextReferenceEntity, + Permissions, + Revision +} from '@nifi/shared'; export interface OkDialogRequest { title: string; @@ -28,11 +36,6 @@ export interface CancelDialogRequest { message: string; } -export interface YesNoDialogRequest { - title: string; - message: string; -} - export interface NewPropertyDialogRequest { existingProperties: string[]; allowsSensitive: boolean; @@ -249,20 +252,6 @@ export interface PropertyTipInput { propertyHistory?: PropertyHistory; } -export interface ParameterTipInput { - parameter: Parameter; -} - -export interface ElFunctionTipInput { - elFunction: ElFunction; -} - -export interface PropertyHintTipInput { - supportsEl: boolean; - supportsParameters: boolean; - hasParameterContext: boolean; -} - export interface RestrictionsTipInput { usageRestriction: string; explicitRestrictions: ExplicitRestriction[]; @@ -272,11 +261,6 @@ export interface GarbageCollectionTipInput { garbageCollections: GarbageCollection[]; } -export interface Permissions { - canRead: boolean; - canWrite: boolean; -} - export interface ExplicitRestriction { requiredPermission: RequiredPermission; explanation: string; @@ -287,56 +271,11 @@ export interface RequiredPermission { label: string; } -export interface Revision { - version: number; - clientId?: string; - lastModifier?: string; -} - -export interface BulletinEntity { - canRead: boolean; - id: number; - sourceId: string; - groupId: string; - timestamp: string; - nodeAddress?: string; - bulletin: { - id: number; - sourceId: string; - groupId: string; - category: string; - level: string; - message: string; - sourceName: string; - timestamp: string; - nodeAddress?: string; - sourceType: string; - }; -} - -export interface ReferencedAsset { - id: string; - name: string; -} - export interface ParameterEntity { canWrite?: boolean; parameter: Parameter; } -export interface Parameter { - name: string; - description: string; - sensitive: boolean; - value: string | null; - valueRemoved?: boolean; - provided?: boolean; - referencingComponents?: AffectedComponentEntity[]; - parameterContext?: ParameterContextReferenceEntity; - inherited?: boolean; - referencedAssets?: ReferencedAsset[]; -} - export interface ParameterContextEntity { revision: Revision; permissions: Permissions; @@ -362,43 +301,11 @@ export interface BoundProcessGroup { component: any; } -export interface ParameterContextReferenceEntity { - permissions: Permissions; - id: string; - component?: ParameterContextReference; - bulletins?: BulletinEntity[]; -} - -export interface ParameterContextReference { - id: string; - name: string; -} - export interface ParameterConfig { supportsParameters: boolean; parameters: Parameter[] | null; } -export interface AffectedComponentEntity { - permissions: Permissions; - id: string; - revision: Revision; - bulletins: BulletinEntity[]; - component: AffectedComponent; - processGroup: ProcessGroupName; - referenceType: string; -} - -export interface AffectedComponent { - processGroupId: string; - id: string; - referenceType: string; - name: string; - state: string; - activeThreadCount?: number; - validationErrors: string[]; -} - export interface SubmitParameterContextUpdate { id: string; payload: any; @@ -426,19 +333,6 @@ export interface ParameterContextUpdateRequestEntity { request: ParameterContextUpdateRequest; } -export interface ElFunction { - name: string; - description: string; - args: { [key: string]: string }; - subject?: string; - returnType: string; -} - -export interface ProcessGroupName { - id: string; - name: string; -} - export interface ControllerServiceReferencingComponent { groupId: string; id: string; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/status-history/index.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/status-history/index.ts index 98c7674bb0..ce6de4b921 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/status-history/index.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/status-history/index.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; export const statusHistoryFeatureKey = 'status-history'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/system-diagnostics/system-diagnostics.effects.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/system-diagnostics/system-diagnostics.effects.ts index beee9b92a4..cb92214df9 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/system-diagnostics/system-diagnostics.effects.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/state/system-diagnostics/system-diagnostics.effects.ts @@ -25,7 +25,7 @@ import * as SystemDiagnosticsActions from './system-diagnostics.actions'; import { catchError, from, map, of, switchMap, tap } from 'rxjs'; import { SystemDiagnosticsRequest } from './index'; import { SystemDiagnosticsDialog } from '../../ui/common/system-diagnostics-dialog/system-diagnostics-dialog.component'; -import { LARGE_DIALOG } from 'libs/shared/src'; +import { LARGE_DIALOG } from '@nifi/shared'; import * as ErrorActions from '../error/error.actions'; import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../service/error-helper.service'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts index 6481897d12..6f700aed59 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/advanced-ui/advanced-ui.component.ts @@ -22,8 +22,7 @@ import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { HttpParams } from '@angular/common/http'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Navigation } from '../navigation/navigation.component'; -import { selectRouteData } from '@nifi/shared'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull, selectRouteData } from '@nifi/shared'; import { AdvancedUiParams } from '../../../state/shared'; import { selectDisconnectionAcknowledged } from '../../../state/cluster-summary/cluster-summary.selectors'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/component-state/component-state.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/component-state/component-state.component.ts index ee9838255c..28ec4bd2b8 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/component-state/component-state.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/component-state/component-state.component.ts @@ -21,7 +21,7 @@ import { MatDialogModule } from '@angular/material/dialog'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { MatSortModule, Sort } from '@angular/material/sort'; import { AsyncPipe } from '@angular/common'; -import { CloseOnEscapeDialog, NiFiCommon, NifiTooltipDirective } from '@nifi/shared'; +import { isDefinedAndNotNull, CloseOnEscapeDialog, NiFiCommon, NifiTooltipDirective } from '@nifi/shared'; import { NifiSpinnerDirective } from '../spinner/nifi-spinner.directive'; import { ComponentStateState, StateEntry, StateItem, StateMap } from '../../../state/component-state'; import { Store } from '@ngrx/store'; @@ -31,7 +31,6 @@ import { selectComponentName, selectComponentState } from '../../../state/component-state/component-state.selectors'; -import { isDefinedAndNotNull } from 'libs/shared/src'; import { debounceTime, Observable } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/disable-controller-service/disable-controller-service.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/disable-controller-service/disable-controller-service.component.spec.ts index d81e424a67..69f6495b0b 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/disable-controller-service/disable-controller-service.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/disable-controller-service/disable-controller-service.component.spec.ts @@ -21,7 +21,7 @@ import { DisableControllerService } from './disable-controller-service.component import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../state/contoller-service-state/controller-service-state.reducer'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { SetEnableControllerServiceDialogRequest } from '../../../../state/shared'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/enable-controller-service/enable-controller-service.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/enable-controller-service/enable-controller-service.component.spec.ts index f1e0bbeca3..2bce671014 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/enable-controller-service/enable-controller-service.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/controller-service/enable-controller-service/enable-controller-service.component.spec.ts @@ -22,7 +22,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../../state/contoller-service-state/controller-service-state.reducer'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; -import { ComponentType } from 'libs/shared/src'; +import { ComponentType } from '@nifi/shared'; import { SetEnableControllerServiceDialogRequest } from '../../../../state/shared'; describe('EnableControllerService', () => { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-parameter-dialog/edit-parameter-dialog.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-parameter-dialog/edit-parameter-dialog.component.ts index 3e2df46cf8..fd17d0c622 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-parameter-dialog/edit-parameter-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-parameter-dialog/edit-parameter-dialog.component.ts @@ -17,7 +17,7 @@ import { Component, EventEmitter, Inject, Input, Output } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; -import { EditParameterRequest, EditParameterResponse, Parameter } from '../../../state/shared'; +import { EditParameterRequest, EditParameterResponse } from '../../../state/shared'; import { MatButtonModule } from '@angular/material/button'; import { AbstractControl, @@ -37,7 +37,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; import { NifiSpinnerDirective } from '../spinner/nifi-spinner.directive'; import { AsyncPipe } from '@angular/common'; import { Observable } from 'rxjs'; -import { NifiTooltipDirective, TextTip, CloseOnEscapeDialog } from '@nifi/shared'; +import { NifiTooltipDirective, TextTip, CloseOnEscapeDialog, Parameter } from '@nifi/shared'; @Component({ selector: 'edit-parameter-dialog', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-tenant/edit-tenant-dialog.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-tenant/edit-tenant-dialog.component.ts index bcb7a76b40..5d593c65c8 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-tenant/edit-tenant-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/edit-tenant/edit-tenant-dialog.component.ts @@ -17,7 +17,7 @@ import { Component, EventEmitter, Inject, Input, Output } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; -import { EditTenantRequest, EditTenantResponse, Revision, UserEntity, UserGroupEntity } from '../../../state/shared'; +import { EditTenantRequest, EditTenantResponse, UserEntity, UserGroupEntity } from '../../../state/shared'; import { MatButtonModule } from '@angular/material/button'; import { AbstractControl, @@ -39,8 +39,7 @@ import { AsyncPipe } from '@angular/common'; import { Observable } from 'rxjs'; import { MatListModule } from '@angular/material/list'; import { Client } from '../../../service/client.service'; -import { NiFiCommon, CloseOnEscapeDialog } from '@nifi/shared'; -import { ErrorBanner } from '../error-banner/error-banner.component'; +import { NiFiCommon, CloseOnEscapeDialog, Revision } from '@nifi/shared'; import { ErrorContextKey } from '../../../state/error'; import { ContextErrorBanner } from '../context-error-banner/context-error-banner.component'; @@ -59,7 +58,6 @@ import { ContextErrorBanner } from '../context-error-banner/context-error-banner NifiSpinnerDirective, AsyncPipe, MatListModule, - ErrorBanner, ContextErrorBanner ], templateUrl: './edit-tenant-dialog.component.html', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/parameter-references/parameter-references.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/parameter-references/parameter-references.component.ts index b6effe7727..123187c7c9 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/parameter-references/parameter-references.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/parameter-references/parameter-references.component.ts @@ -22,14 +22,14 @@ import { MatButtonModule } from '@angular/material/button'; import { NgClass, NgTemplateOutlet } from '@angular/common'; import { RouterLink } from '@angular/router'; import { MatDialogModule } from '@angular/material/dialog'; +import { BulletinsTipInput, ValidationErrorsTipInput } from '../../../state/shared'; import { AffectedComponent, AffectedComponentEntity, - BulletinsTipInput, - ProcessGroupName, - ValidationErrorsTipInput -} from '../../../state/shared'; -import { NiFiCommon, NifiTooltipDirective } from '@nifi/shared'; + NiFiCommon, + NifiTooltipDirective, + ProcessGroupName +} from '@nifi/shared'; import { ValidationErrorsTip } from '../tooltips/validation-errors-tip/validation-errors-tip.component'; import { BulletinsTip } from '../tooltips/bulletins-tip/bulletins-tip.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts index dc54db5897..006b0437b6 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts @@ -19,8 +19,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComboEditor } from './combo-editor.component'; import { PropertyItem } from '../../property-table.component'; -import { Parameter } from '../../../../../state/shared'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { Parameter } from '@nifi/shared'; describe('ComboEditor', () => { let component: ComboEditor; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts index ea4fedb7a0..af24188e0d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts @@ -24,10 +24,10 @@ import { MatInputModule } from '@angular/material/input'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { NgForOf, NgIf } from '@angular/common'; -import { AllowableValue, Parameter, ParameterConfig, PropertyDescriptor } from '../../../../../state/shared'; +import { AllowableValue, ParameterConfig, PropertyDescriptor } from '../../../../../state/shared'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; -import { TextTip, NifiTooltipDirective, NiFiCommon } from '@nifi/shared'; +import { TextTip, NifiTooltipDirective, NiFiCommon, Parameter } from '@nifi/shared'; import { A11yModule } from '@angular/cdk/a11y'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfel.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfel.ts index a22dac4076..0bee35ce42 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfel.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfel.ts @@ -18,12 +18,9 @@ import { ComponentRef, Injectable, Renderer2, ViewContainerRef } from '@angular/core'; import * as CodeMirror from 'codemirror'; import { Editor, Hint, Hints, StringStream } from 'codemirror'; -import { ElFunction, Parameter } from '../../../../../../state/shared'; -import { ParameterTip } from '../../../../tooltips/parameter-tip/parameter-tip.component'; import { ElService } from './el.service'; import { take } from 'rxjs'; -import { ElFunctionTip } from '../../../../tooltips/el-function-tip/el-function-tip.component'; -import { NiFiCommon } from '@nifi/shared'; +import { NiFiCommon, ElFunction, Parameter, ParameterTip, ElFunctionTip } from '@nifi/shared'; export interface NfElHint extends Hint { parameterDetails?: Parameter; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfpr.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfpr.ts index 4960dff64f..1f839a6d96 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfpr.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/modes/nfpr.ts @@ -18,9 +18,7 @@ import { ComponentRef, Injectable, Renderer2, ViewContainerRef } from '@angular/core'; import { Editor, Hint, Hints, StringStream } from 'codemirror'; import * as CodeMirror from 'codemirror'; -import { Parameter } from '../../../../../../state/shared'; -import { ParameterTip } from '../../../../tooltips/parameter-tip/parameter-tip.component'; -import { NiFiCommon } from '@nifi/shared'; +import { NiFiCommon, Parameter, ParameterTip } from '@nifi/shared'; @Injectable({ providedIn: 'root' }) export class NfPr { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.html b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.html index 8c70c6897f..063c383f29 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.html +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.html @@ -24,27 +24,11 @@
      -
      -
      -
      EL
      - -
      -
      -
      PARAM
      - -
      -
      - -
      -
      - -
      -
      +
      { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NfEditor, HttpClientTestingModule] + imports: [NfEditor, HttpClientTestingModule, MockComponent(PropertyHint)] }); fixture = TestBed.createComponent(NfEditor); component = fixture.componentInstance; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts index 36dd4e7dfa..9e17ecace5 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts @@ -17,21 +17,19 @@ import { Component, EventEmitter, Input, OnDestroy, Output, Renderer2, ViewContainerRef } from '@angular/core'; import { PropertyItem } from '../../property-table.component'; -import { CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop'; +import { CdkDrag } from '@angular/cdk/drag-drop'; import { AbstractControl, FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { MatDialogModule } from '@angular/material/dialog'; import { MatInputModule } from '@angular/material/input'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { NgTemplateOutlet } from '@angular/common'; -import { NifiTooltipDirective, Resizable } from '@nifi/shared'; -import { PropertyHintTip } from '../../../tooltips/property-hint-tip/property-hint-tip.component'; -import { Parameter, ParameterConfig, PropertyHintTipInput } from '../../../../../state/shared'; +import { Resizable, Parameter, PropertyHint } from '@nifi/shared'; +import { ParameterConfig } from '../../../../../state/shared'; import { A11yModule } from '@angular/cdk/a11y'; import { CodemirrorModule } from '@ctrl/ngx-codemirror'; +import { Editor } from 'codemirror'; import { NfEl } from './modes/nfel'; import { NfPr } from './modes/nfpr'; -import { Editor } from 'codemirror'; @Component({ selector: 'nf-editor', @@ -39,17 +37,15 @@ import { Editor } from 'codemirror'; templateUrl: './nf-editor.component.html', imports: [ CdkDrag, - CdkDragHandle, ReactiveFormsModule, MatDialogModule, MatInputModule, MatButtonModule, MatCheckboxModule, - NgTemplateOutlet, - NifiTooltipDirective, A11yModule, CodemirrorModule, - Resizable + Resizable, + PropertyHint ], styleUrls: ['./nf-editor.component.scss'] }) @@ -92,8 +88,6 @@ export class NfEditor implements OnDestroy { @Output() ok: EventEmitter = new EventEmitter(); @Output() cancel: EventEmitter = new EventEmitter(); - protected readonly PropertyHintTip = PropertyHintTip; - itemSet = false; getParametersSet = false; @@ -198,14 +192,6 @@ export class NfEditor implements OnDestroy { }; } - getPropertyHintTipData(): PropertyHintTipInput { - return { - supportsEl: this.supportsEl, - supportsParameters: this.supportsParameters, - hasParameterContext: this.parameters !== null - }; - } - resized(event: any): void { // Note: We calculate the height of the codemirror to fit into an `.nf-editor` overlay. The // height of the codemirror needs to be set in order to handle large amounts of text in the codemirror editor. diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.html b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.html index 436861c893..24cc44fcf6 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.html +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.html @@ -173,6 +173,7 @@ cdkConnectedOverlay [cdkConnectedOverlayOrigin]="editorTrigger" [cdkConnectedOverlayPositions]="editorPositions" + [cdkConnectedOverlayPush]="true" [cdkConnectedOverlayHasBackdrop]="true" [cdkConnectedOverlayBackdropClass]="'cdk-overlay-transparent-backdrop'" [cdkConnectedOverlayOpen]="editorOpen" diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.ts index 2729a291d3..7796aa0a20 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/property-table.component.ts @@ -30,14 +30,13 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatDialogModule } from '@angular/material/dialog'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; -import { NiFiCommon, NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { NiFiCommon, NifiTooltipDirective, Parameter, TextTip } from '@nifi/shared'; import { NgTemplateOutlet } from '@angular/common'; import { AllowableValueEntity, ComponentHistory, InlineServiceCreationRequest, InlineServiceCreationResponse, - Parameter, ParameterConfig, ParameterContextEntity, Property, diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/status-history/status-history.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/status-history/status-history.component.ts index 1cbf17449e..9128d1d76c 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/status-history/status-history.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/status-history/status-history.component.ts @@ -42,8 +42,14 @@ import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatSelectModule } from '@angular/material/select'; import * as d3 from 'd3'; -import { CloseOnEscapeDialog, NiFiCommon, NifiTooltipDirective, Resizable, TextTip } from '@nifi/shared'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { + isDefinedAndNotNull, + CloseOnEscapeDialog, + NiFiCommon, + NifiTooltipDirective, + Resizable, + TextTip +} from '@nifi/shared'; import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox'; import { Instance, NIFI_NODE_CONFIG, Stats } from './index'; import { StatusHistoryChart } from './status-history-chart/status-history-chart.component'; diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/system-diagnostics-dialog/system-diagnostics-dialog.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/system-diagnostics-dialog/system-diagnostics-dialog.component.ts index d3c9334032..b6669353a3 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/system-diagnostics-dialog/system-diagnostics-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/system-diagnostics-dialog/system-diagnostics-dialog.component.ts @@ -28,10 +28,8 @@ import { } from '../../../state/system-diagnostics/system-diagnostics.selectors'; import { MatButtonModule } from '@angular/material/button'; import { reloadSystemDiagnostics } from '../../../state/system-diagnostics/system-diagnostics.actions'; -import { NiFiCommon, NifiTooltipDirective, TextTip } from '@nifi/shared'; -import { isDefinedAndNotNull } from 'libs/shared/src'; +import { isDefinedAndNotNull, NiFiCommon, NifiTooltipDirective, TextTip } from '@nifi/shared'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { ErrorBanner } from '../error-banner/error-banner.component'; import { TabbedDialog } from '../tabbed-dialog/tabbed-dialog.component'; import { ErrorContextKey } from '../../../state/error'; import { ContextErrorBanner } from '../context-error-banner/context-error-banner.component'; @@ -46,7 +44,6 @@ import { ContextErrorBanner } from '../context-error-banner/context-error-banner MatButtonModule, NifiTooltipDirective, MatProgressBarModule, - ErrorBanner, ContextErrorBanner ], templateUrl: './system-diagnostics-dialog.component.html', diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/styles.scss b/nifi-frontend/src/main/frontend/apps/nifi/src/styles.scss index 3ae320876c..da74f6f69d 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/styles.scss +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/styles.scss @@ -51,7 +51,7 @@ @use 'app/ui/common/navigation/navigation.component-theme' as navigation; @use 'app/ui/common/property-table/editors/nf-editor/nf-editor.component-theme' as nf-editor; @use 'app/ui/common/status-history/status-history.component-theme' as status-history; -@use 'app/ui/common/tooltips/property-hint-tip/property-hint-tip.component-theme' as property-hint-tip; +@use 'libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component-theme' as property-hint-tip; @use 'app/pages/summary/ui/processor-status-listing/processor-status-table/processor-status-table.component-theme' as processor-status-table; @use 'app/pages/flow-designer/ui/canvas/change-color-dialog/change-color-dialog.component-theme' as change-color-dialog; diff --git a/nifi-frontend/src/main/frontend/apps/standard-content-viewer/project.json b/nifi-frontend/src/main/frontend/apps/standard-content-viewer/project.json index 90a5e986dd..d31192f47a 100644 --- a/nifi-frontend/src/main/frontend/apps/standard-content-viewer/project.json +++ b/nifi-frontend/src/main/frontend/apps/standard-content-viewer/project.json @@ -89,7 +89,7 @@ }, "development": { "buildTarget": "standard-content-viewer:build:development", - "servePath": "/nifi-standard-content-viewer-2.0.0-SNAPSHOT/" + "servePath": "/nifi-standard-content-viewer-2.1.0-SNAPSHOT/" } }, "defaultConfiguration": "development" diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/.eslintrc.json b/nifi-frontend/src/main/frontend/apps/update-attribute/.eslintrc.json new file mode 100644 index 0000000000..46e0dbdb31 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/.eslintrc.json @@ -0,0 +1,45 @@ +{ + "root": true, + "ignorePatterns": ["!**/*"], + "parserOptions": { + "ecmaVersion": "latest" + }, + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates", + "plugin:prettier/recommended" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "", + "style": "kebab-case" + } + ], + "@angular-eslint/component-class-suffix": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-this-alias": "warn", + "@typescript-eslint/no-unused-vars": "warn", + "no-useless-escape": "off" + } + } + ] +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/jest.config.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/jest.config.ts new file mode 100644 index 0000000000..91c0d40dc6 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/jest.config.ts @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Config } from 'jest'; + +const config: Config = { + displayName: 'Update Attribute UI', + clearMocks: true, + coverageDirectory: '../../coverage/apps/nifi', + extensionsToTreatAsEsm: ['.ts'], + + // A preset that is used as a base for Jest's configuration + preset: '../../jest.preset.js', + + // The paths to modules that run some code to configure or set up the testing environment before each test + setupFilesAfterEnv: ['/setup-jest.ts'], + + // The test environment that will be used for testing + testEnvironment: '@happy-dom/jest-environment', + + // A map from regular expressions to paths to transformers + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + useESM: true + } + ] + }, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + transformIgnorePatterns: [] +}; + +export default config; diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/project.json b/nifi-frontend/src/main/frontend/apps/update-attribute/project.json new file mode 100644 index 0000000000..28e90f4e3d --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/project.json @@ -0,0 +1,134 @@ +{ + "name": "update-attribute", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "generators": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "sourceRoot": "apps/update-attribute/src", + "prefix": "app", + "targets": { + "build": { + "executor": "@nx/angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/update-attribute", + "index": "apps/update-attribute/src/index.html", + "browser": "apps/update-attribute/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/update-attribute/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*.svg", + "input": "libs/shared/src/assets/", + "output": "./assets" + } + ], + "styles": ["apps/update-attribute/src/styles.scss"], + "stylePreprocessorOptions": { + "includePaths": [""] + }, + "scripts": [], + "allowedCommonJsDependencies": ["codemirror"], + "preserveSymlinks": true + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "3mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all", + "optimization": true + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "preserveSymlinks": true, + "namedChunks": true, + "outputHashing": "none", + "assets": [ + { + "glob": "**/*.svg", + "input": "libs/shared/src/assets/", + "output": "./assets" + } + ], + "fileReplacements": [ + { + "replace": "apps/update-attribute/src/environments/environment.ts", + "with": "apps/update-attribute/src/environments/environment.development.ts" + } + ] + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@nx/angular:dev-server", + "options": { + "port": 4203, + "proxyConfig": "apps/update-attribute/proxy.config.mjs", + "buildTarget": "update-attribute:build" + }, + "configurations": { + "production": { + "buildTarget": "update-attribute:build:production" + }, + "development": { + "buildTarget": "update-attribute:build:development", + "servePath": "/nifi-update-attribute-ui-2.1.0-SNAPSHOT/" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/update-attribute/jest.config.ts" + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + }, + "lint:fix": { + "executor": "@nx/eslint:lint", + "options": { + "fix": true + }, + "outputs": ["{options.outputFile}"] + }, + "prettier": { + "executor": "nx:run-commands", + "options": { + "command": "npm run prettier" + } + }, + "prettier:format": { + "executor": "nx:run-commands", + "options": { + "command": "npm run prettier-format" + } + } + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/proxy.config.mjs b/nifi-frontend/src/main/frontend/apps/update-attribute/proxy.config.mjs new file mode 100644 index 0000000000..dfd9abb434 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/proxy.config.mjs @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const target = { + target: 'https://localhost:8443', + secure: false, + logLevel: 'debug', + changeOrigin: true, + headers: { + 'X-ProxyScheme': 'http', + 'X-ProxyPort': 4203 + }, + configure: (proxy, _options) => { + proxy.on('error', (err, _req, _res) => { + console.log('proxy error', err); + }); + proxy.on('proxyReq', (proxyReq, req, _res) => { + console.log('Sending Request to the Target:', req.method, req.url); + }); + proxy.on('proxyRes', (proxyRes, req, _res) => { + console.log('Received Response from the Target:', proxyRes.statusCode, req.url); + }); + }, + bypass: function (req) { + if (!req.url.includes('/api/') && !req.url.includes('/nifi-api/')) { + return req.url; + } + } +}; + +export default { + '/**': target +}; diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/setup-jest.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/setup-jest.ts new file mode 100644 index 0000000000..31d33e1140 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/setup-jest.ts @@ -0,0 +1,17 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import 'jest-preset-angular/setup-jest'; diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/jquery.center.js b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app-routing.module.ts similarity index 58% rename from nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/jquery.center.js rename to nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app-routing.module.ts index 407bd47e1e..2b10ab6337 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/jquery.center.js +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app-routing.module.ts @@ -15,21 +15,24 @@ * limitations under the License. */ -/** - * Simple jQuery plugin to center any matched elements. Implementation - * specifics suggested on StackOverflow. - * - * @param {type} $ - * @returns {undefined} - */ -(function ($) { - $.fn.center = function () { - return this.each(function () { - $(this).css({ - 'position': 'absolute', - 'top': ($(window).height() - $(this).outerHeight()) / 2 + $(window).scrollTop() + 'px', - 'left': ($(window).width() - $(this).outerWidth()) / 2 + $(window).scrollLeft() + 'px' - }); - }); - }; -})(jQuery); +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +const routes: Routes = [ + { + path: '', + loadChildren: () => + import('./pages/update-attribute/feature/update-attribute.module').then((m) => m.UpdateAttributeModule) + } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(routes, { + paramsInheritanceStrategy: 'always', + useHash: true + }) + ], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.html new file mode 100644 index 0000000000..c3a79d415a --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.html @@ -0,0 +1,18 @@ + + + diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.scss similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.scss rename to nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.scss diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.spec.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.spec.ts new file mode 100644 index 0000000000..65cf670431 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.spec.ts @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('AppComponent', () => { + beforeEach(() => + TestBed.configureTestingModule({ + imports: [RouterTestingModule, HttpClientTestingModule], + declarations: [AppComponent] + }) + ); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'update-attribute'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('update-attribute'); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.ts new file mode 100644 index 0000000000..11364699c6 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.component.ts @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component } from '@angular/core'; +import { Storage, ThemingService } from '@nifi/shared'; + +@Component({ + selector: 'app', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'] +}) +export class AppComponent { + title = 'update-attribute'; + + constructor( + private storage: Storage, + private themingService: ThemingService + ) { + let theme = this.storage.getItem('theme'); + + // Initially check if dark mode is enabled on system + const darkModeOn = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; + + // If dark mode is enabled then directly switch to the dark-theme + this.themingService.toggleTheme(darkModeOn, theme); + + if (window.matchMedia) { + // Watch for changes of the preference + window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => { + theme = this.storage.getItem('theme'); + this.themingService.toggleTheme(e.matches, theme); + }); + } + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.module.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.module.ts new file mode 100644 index 0000000000..b15074aba1 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/app.module.ts @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { + BrowserAnimationsModule, + provideAnimations, + provideNoopAnimations +} from '@angular/platform-browser/animations'; +import { StoreModule } from '@ngrx/store'; +import { StoreDevtoolsModule } from '@ngrx/store-devtools'; +import { environment } from '../environments/environment'; +import { provideHttpClient, withInterceptors, withXsrfConfiguration } from '@angular/common/http'; +import { NavigationActionTiming, RouterState, StoreRouterConnectingModule } from '@ngrx/router-store'; +import { rootReducers } from './state'; +import { EffectsModule } from '@ngrx/effects'; +import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field'; + +const entry = localStorage.getItem('disable-animations'); +let disableAnimations: string = entry !== null ? JSON.parse(entry).item : ''; + +// honor OS settings if user has not explicitly disabled animations for the application +if (disableAnimations !== 'true' && disableAnimations !== 'false') { + disableAnimations = window.matchMedia('(prefers-reduced-motion: reduce)').matches.toString(); +} + +@NgModule({ + declarations: [AppComponent], + bootstrap: [AppComponent], + imports: [ + BrowserModule, + AppRoutingModule, + BrowserAnimationsModule, + StoreModule.forRoot(rootReducers), + StoreRouterConnectingModule.forRoot({ + routerState: RouterState.Minimal, + navigationActionTiming: NavigationActionTiming.PostActivation + }), + EffectsModule.forRoot(), + StoreDevtoolsModule.instrument({ + maxAge: 25, + logOnly: environment.production, + autoPause: true + }) + ], + providers: [ + disableAnimations === 'true' ? provideNoopAnimations() : provideAnimations(), + { provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'outline' } }, + provideHttpClient( + withInterceptors([]), + withXsrfConfiguration({ + cookieName: '__Secure-Request-Token', + headerName: 'Request-Token' + }) + ) + ] +}) +export class AppModule {} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute-routing.module.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute-routing.module.ts new file mode 100644 index 0000000000..3c1343f187 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute-routing.module.ts @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { RouterModule, Routes } from '@angular/router'; +import { NgModule } from '@angular/core'; +import { UpdateAttribute } from './update-attribute.component'; + +const routes: Routes = [ + { + path: '', + component: UpdateAttribute + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class UpdateAttributeRoutingModule {} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.html new file mode 100644 index 0000000000..676f3f89f7 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.html @@ -0,0 +1,57 @@ + + +
      +
      +

      Advanced

      + @if (rulesState(); as rulesState) { + @if (rulesState.error && rulesState.rules === null) { +
      + {{ rulesState.error }} +
      + } @else if (rulesState.loading) { +
      + +
      + } @else if (rulesState.rules) { + @if (evaluationContextState(); as evaluationContextState) { + @if (evaluationContextState.error && evaluationContextState.evaluationContext === null) { +
      + {{ evaluationContextState.error }} +
      + } @else if (evaluationContextState.loading) { +
      + +
      + } @else if (evaluationContextState.evaluationContext) { +
      + +
      + } @else { +
      + Unable to load advanced rules +
      + } + } + } + } +
      +
      diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.scss new file mode 100644 index 0000000000..3651a8ab70 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.scss @@ -0,0 +1,16 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.spec.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.spec.ts new file mode 100644 index 0000000000..ea7406db60 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.spec.ts @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { UpdateAttribute } from './update-attribute.component'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { provideMockStore } from '@ngrx/store/testing'; +import { initialState } from '../state/rules/rules.reducer'; +import { updateAttributeFeatureKey } from '../state'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('UpdateAttribute', () => { + let component: UpdateAttribute; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [UpdateAttribute], + imports: [HttpClientTestingModule], + providers: [ + provideMockStore({ + initialState: { + [updateAttributeFeatureKey]: { + [updateAttributeFeatureKey]: initialState + } + } + }) + ] + }); + fixture = TestBed.createComponent(UpdateAttribute); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.ts new file mode 100644 index 0000000000..b06386d5e5 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.component.ts @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the 'License'); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnDestroy } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { UpdateAttributeApplicationState } from '../../../state'; +import { isDefinedAndNotNull } from '@nifi/shared'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { loadRules, resetRulesState } from '../state/rules/rules.actions'; +import { + loadEvaluationContext, + resetEvaluationContextState +} from '../state/evaluation-context/evaluation-context.actions'; +import { + selectAdvancedUiParametersFromRoute, + selectEditable +} from '../state/advanced-ui-parameters/advanced-ui-parameters.selectors'; +import { + resetAdvancedUiParametersState, + setAdvancedUiParameters +} from '../state/advanced-ui-parameters/advanced-ui-parameters.actions'; +import { selectRulesState } from '../state/rules/rules.selectors'; +import { selectEvaluationContextState } from '../state/evaluation-context/evaluation-context.selectors'; +import { NfEl } from '../ui/ua-editor/modes/nfel'; + +@Component({ + selector: 'update-attribute', + templateUrl: './update-attribute.component.html', + styleUrls: ['./update-attribute.component.scss'] +}) +export class UpdateAttribute implements OnDestroy { + rulesState = this.store.selectSignal(selectRulesState); + evaluationContextState = this.store.selectSignal(selectEvaluationContextState); + editable = this.store.selectSignal(selectEditable); + + constructor( + private store: Store, + private nfel: NfEl // note: nfel is referenced here to ensure the el function details are loaded when the application loads + ) { + this.store + .select(selectAdvancedUiParametersFromRoute) + .pipe(isDefinedAndNotNull(), takeUntilDestroyed()) + .subscribe((advancedUiParameters) => { + this.store.dispatch( + setAdvancedUiParameters({ + advancedUiParameters + }) + ); + this.store.dispatch(loadEvaluationContext()); + this.store.dispatch(loadRules()); + }); + } + + ngOnDestroy(): void { + this.store.dispatch(resetRulesState()); + this.store.dispatch(resetEvaluationContextState()); + this.store.dispatch(resetAdvancedUiParametersState()); + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.module.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.module.ts new file mode 100644 index 0000000000..069ea01b72 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/feature/update-attribute.module.ts @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { UpdateAttribute } from './update-attribute.component'; +import { UpdateAttributeRoutingModule } from './update-attribute-routing.module'; +import { StoreModule } from '@ngrx/store'; +import { updateAttributeFeatureKey, reducers } from '../state'; +import { EffectsModule } from '@ngrx/effects'; +import { RulesEffects } from '../state/rules/rules.effects'; +import { EvaluationContextEffects } from '../state/evaluation-context/evaluation-context.effects'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { RuleListing } from '../ui/rule-listing/rule-listing.component'; + +@NgModule({ + declarations: [UpdateAttribute], + exports: [UpdateAttribute], + imports: [ + CommonModule, + UpdateAttributeRoutingModule, + StoreModule.forFeature(updateAttributeFeatureKey, reducers), + EffectsModule.forFeature(RulesEffects, EvaluationContextEffects), + MatProgressSpinnerModule, + RuleListing + ] +}) +export class UpdateAttributeModule {} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/service/update-attribute.service.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/service/update-attribute.service.ts new file mode 100644 index 0000000000..3be42f4028 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/service/update-attribute.service.ts @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { EvaluationContext, EvaluationContextEntity } from '../state/evaluation-context'; +import { AdvancedUiParameters } from '../state/advanced-ui-parameters'; +import { NewRule, Rule, RuleEntity, RulesEntity } from '../state/rules'; + +@Injectable({ providedIn: 'root' }) +export class UpdateAttributeService { + private static readonly API: string = 'api'; + + constructor(private httpClient: HttpClient) {} + + getEvaluationContext(processorId: string): Observable { + const params = new HttpParams({ + fromObject: { + processorId + } + }); + + return this.httpClient.get( + `${UpdateAttributeService.API}/criteria/evaluation-context`, + { params } + ); + } + + saveEvaluationContext( + advancedUiParameters: AdvancedUiParameters, + evaluationContext: EvaluationContext + ): Observable { + const entity = { + revision: advancedUiParameters.revision, + disconnectedNodeAcknowledged: advancedUiParameters.disconnectedNodeAcknowledged, + clientId: advancedUiParameters.clientId, + processorId: advancedUiParameters.processorId, + ...evaluationContext + } as EvaluationContextEntity; + + return this.httpClient.put( + `${UpdateAttributeService.API}/criteria/evaluation-context`, + entity + ); + } + + getRules(processorId: string): Observable { + const params = new HttpParams({ + fromObject: { + processorId, + verbose: true + } + }); + + return this.httpClient.get(`${UpdateAttributeService.API}/criteria/rules`, { params }); + } + + createRule(advancedUiParameters: AdvancedUiParameters, newRule: NewRule): Observable { + const entity = { + revision: advancedUiParameters.revision, + disconnectedNodeAcknowledged: advancedUiParameters.disconnectedNodeAcknowledged, + clientId: advancedUiParameters.clientId, + processorId: advancedUiParameters.processorId, + rule: { + ...newRule + } + } as RuleEntity; + + return this.httpClient.post(`${UpdateAttributeService.API}/criteria/rules`, entity); + } + + saveRule(advancedUiParameters: AdvancedUiParameters, rule: Rule): Observable { + const entity = { + revision: advancedUiParameters.revision, + disconnectedNodeAcknowledged: advancedUiParameters.disconnectedNodeAcknowledged, + clientId: advancedUiParameters.clientId, + processorId: advancedUiParameters.processorId, + rule + } as RuleEntity; + + return this.httpClient.put(`${UpdateAttributeService.API}/criteria/rules/${rule.id}`, entity); + } + + deleteRule(advancedUiParameters: AdvancedUiParameters, ruleId: string): Observable { + const params = new HttpParams({ + fromObject: { + revision: advancedUiParameters.revision, + disconnectedNodeAcknowledged: advancedUiParameters.disconnectedNodeAcknowledged, + clientId: advancedUiParameters.clientId, + processorId: advancedUiParameters.processorId + } + }); + + return this.httpClient.delete(`${UpdateAttributeService.API}/criteria/rules/${ruleId}`, { + params + }); + } + + getErrorString(errorResponse: HttpErrorResponse): string { + let errorMessage = 'An unspecified error occurred.'; + if (errorResponse.status !== 0) { + if (errorResponse.error) { + errorMessage = errorResponse.error; + } else { + errorMessage = errorResponse.message || `${errorResponse.status}`; + } + } + return errorMessage; + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.actions.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.actions.ts new file mode 100644 index 0000000000..e83ccccc53 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.actions.ts @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createAction, props } from '@ngrx/store'; +import { AdvancedUiParameters } from './index'; + +const ADVANCED_UI_PARAMETERS_PREFIX = '[Advanced UI Parameters]'; + +export const resetAdvancedUiParametersState = createAction( + `${ADVANCED_UI_PARAMETERS_PREFIX} Reset Advanced UI Parameters State` +); + +export const setAdvancedUiParameters = createAction( + `${ADVANCED_UI_PARAMETERS_PREFIX} Set Advanced UI Parameters State`, + props<{ advancedUiParameters: AdvancedUiParameters }>() +); + +export const updateRevision = createAction( + `${ADVANCED_UI_PARAMETERS_PREFIX} Update Revision`, + props<{ revision: number }>() +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.reducer.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.reducer.ts new file mode 100644 index 0000000000..561a93d901 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.reducer.ts @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AdvancedUiParametersState } from './index'; +import { createReducer, on } from '@ngrx/store'; +import { + resetAdvancedUiParametersState, + setAdvancedUiParameters, + updateRevision +} from './advanced-ui-parameters.actions'; + +export const initialState: AdvancedUiParametersState = { + advancedUiParameters: { + clientId: '', + revision: 0, + disconnectedNodeAcknowledged: false, + editable: false, + processorId: '' + } +}; + +export const advancedUiParametersReducer = createReducer( + initialState, + on(setAdvancedUiParameters, (state, { advancedUiParameters }) => ({ + advancedUiParameters + })), + on(updateRevision, (state, { revision }) => ({ + advancedUiParameters: { + ...state.advancedUiParameters, + revision + } + })), + on(resetAdvancedUiParametersState, () => ({ + ...initialState + })) +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.selectors.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.selectors.ts new file mode 100644 index 0000000000..589cb7c5bc --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/advanced-ui-parameters.selectors.ts @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createSelector } from '@ngrx/store'; +import { selectUpdateAttributeState, UpdateAttributeState } from '../index'; +import { AdvancedUiParameters, advancedUiParametersFeatureKey, AdvancedUiParametersState } from './index'; +import { selectCurrentRoute } from '@nifi/shared'; + +export const selectAdvancedUiParametersState = createSelector( + selectUpdateAttributeState, + (state: UpdateAttributeState) => state[advancedUiParametersFeatureKey] +); + +export const selectAdvancedUiParameters = createSelector( + selectAdvancedUiParametersState, + (state: AdvancedUiParametersState) => state.advancedUiParameters +); + +export const selectAdvancedUiParametersFromRoute = createSelector(selectCurrentRoute, (route) => { + if (route) { + return { + clientId: route.queryParams.clientId, + revision: Number(route.queryParams.revision) || 0, + disconnectedNodeAcknowledged: route.queryParams.disconnectedNodeAcknowledged === 'true', + editable: route.queryParams.editable === 'true', + processorId: route.queryParams.id + } as AdvancedUiParameters; + } + return null; +}); + +export const selectEditable = createSelector( + selectAdvancedUiParameters, + (state: AdvancedUiParameters) => state.editable +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/index.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/index.ts new file mode 100644 index 0000000000..fee8a96f29 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/advanced-ui-parameters/index.ts @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const advancedUiParametersFeatureKey = 'advancedUiParameters'; + +export interface AdvancedUiParameters { + clientId: string; + revision: number; + disconnectedNodeAcknowledged: boolean; + processorId: string; + editable: boolean; +} + +export interface AdvancedUiParametersState { + advancedUiParameters: AdvancedUiParameters; +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.actions.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.actions.ts new file mode 100644 index 0000000000..7e33d50c40 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.actions.ts @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createAction, props } from '@ngrx/store'; +import { EvaluationContext, EvaluationContextEntity } from './index'; + +const EVALUATION_CONTEXT_PREFIX = '[Evaluation Context]'; + +export const resetEvaluationContextState = createAction(`${EVALUATION_CONTEXT_PREFIX} Reset Evaluation Context State`); + +export const loadEvaluationContext = createAction(`${EVALUATION_CONTEXT_PREFIX} Load Evaluation Context`); + +export const loadEvaluationContextSuccess = createAction( + `${EVALUATION_CONTEXT_PREFIX} Load Evaluation Context Success`, + props<{ evaluationContextEntity: EvaluationContextEntity }>() +); + +export const loadEvaluationContextFailure = createAction( + `${EVALUATION_CONTEXT_PREFIX} Load Evaluation Context Failure`, + props<{ error: string }>() +); + +export const saveEvaluationContext = createAction( + `${EVALUATION_CONTEXT_PREFIX} Save Evaluation Context`, + props<{ evaluationContext: EvaluationContext }>() +); + +export const saveEvaluationContextSuccess = createAction( + `${EVALUATION_CONTEXT_PREFIX} Save Evaluation Context Success`, + props<{ evaluationContextEntity: EvaluationContextEntity }>() +); + +export const saveEvaluationContextFailure = createAction( + `${EVALUATION_CONTEXT_PREFIX} Save Evaluation Context Failure`, + props<{ error: string }>() +); + +export const resetEvaluationContextFailure = createAction( + `${EVALUATION_CONTEXT_PREFIX} Reset Evaluation Context Failure` +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.effects.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.effects.ts new file mode 100644 index 0000000000..d47c928416 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.effects.ts @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import * as EvaluationContextActions from './evaluation-context.actions'; +import { UpdateAttributeService } from '../../service/update-attribute.service'; +import { HttpErrorResponse } from '@angular/common/http'; +import { catchError, from, map, of, switchMap, tap } from 'rxjs'; +import { Store } from '@ngrx/store'; +import { UpdateAttributeApplicationState } from '../../../../state'; +import { concatLatestFrom } from '@ngrx/operators'; +import { selectAdvancedUiParameters } from '../advanced-ui-parameters/advanced-ui-parameters.selectors'; +import { EvaluationContextEntity } from './index'; +import { updateRevision } from '../advanced-ui-parameters/advanced-ui-parameters.actions'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { resetEvaluationContextFailure } from './evaluation-context.actions'; + +@Injectable() +export class EvaluationContextEffects { + constructor( + private actions$: Actions, + private snackBar: MatSnackBar, + private store: Store, + private updateAttributeService: UpdateAttributeService + ) {} + + loadEvaluationContext$ = createEffect(() => + this.actions$.pipe( + ofType(EvaluationContextActions.loadEvaluationContext), + concatLatestFrom(() => this.store.select(selectAdvancedUiParameters)), + switchMap(([, advancedUiParameters]) => + from(this.updateAttributeService.getEvaluationContext(advancedUiParameters.processorId)).pipe( + map((evaluationContextEntity: EvaluationContextEntity) => + EvaluationContextActions.loadEvaluationContextSuccess({ + evaluationContextEntity + }) + ), + catchError((errorResponse: HttpErrorResponse) => { + const error = this.updateAttributeService.getErrorString(errorResponse); + return of( + EvaluationContextActions.loadEvaluationContextFailure({ + error + }) + ); + }) + ) + ) + ) + ); + + saveEvaluationContext$ = createEffect(() => + this.actions$.pipe( + ofType(EvaluationContextActions.saveEvaluationContext), + map((action) => action.evaluationContext), + concatLatestFrom(() => this.store.select(selectAdvancedUiParameters)), + switchMap(([evaluationContext, advancedUiParameters]) => + from(this.updateAttributeService.saveEvaluationContext(advancedUiParameters, evaluationContext)).pipe( + map((evaluationContextEntity: EvaluationContextEntity) => + EvaluationContextActions.saveEvaluationContextSuccess({ + evaluationContextEntity + }) + ), + catchError((errorResponse: HttpErrorResponse) => { + const error = this.updateAttributeService.getErrorString(errorResponse); + return of( + EvaluationContextActions.saveEvaluationContextFailure({ + error + }) + ); + }) + ) + ) + ) + ); + + saveEvaluationContextSuccess$ = createEffect(() => + this.actions$.pipe( + ofType(EvaluationContextActions.saveEvaluationContextSuccess), + map((action) => action.evaluationContextEntity), + tap(() => { + this.snackBar.open('Evaluation criteria successfully saved', 'Ok', { duration: 30000 }); + }), + switchMap((evaluationContextEntity) => + of( + updateRevision({ + revision: evaluationContextEntity.revision + }) + ) + ) + ) + ); + + saveEvaluationContextFailure$ = createEffect(() => + this.actions$.pipe( + ofType(EvaluationContextActions.saveEvaluationContextFailure), + map((action) => action.error), + tap((error) => { + this.snackBar.open(error, 'Dismiss', { duration: 30000 }); + }), + switchMap(() => of(resetEvaluationContextFailure())) + ) + ); +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.reducer.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.reducer.ts new file mode 100644 index 0000000000..ab972049d4 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.reducer.ts @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EvaluationContextState } from './index'; +import { createReducer, on } from '@ngrx/store'; +import { + loadEvaluationContext, + loadEvaluationContextFailure, + loadEvaluationContextSuccess, + resetEvaluationContextFailure, + resetEvaluationContextState, + saveEvaluationContext, + saveEvaluationContextFailure, + saveEvaluationContextSuccess +} from './evaluation-context.actions'; + +export const initialState: EvaluationContextState = { + loading: false, + saving: false, + error: null, + evaluationContext: null +}; + +export const evaluationContextReducer = createReducer( + initialState, + on(resetEvaluationContextState, () => ({ + ...initialState + })), + on(loadEvaluationContext, (state) => ({ + ...state, + loading: true + })), + on(loadEvaluationContextSuccess, (state, { evaluationContextEntity }) => ({ + ...state, + loading: false, + evaluationContext: { + ruleOrder: evaluationContextEntity.ruleOrder, + flowFilePolicy: evaluationContextEntity.flowFilePolicy + } + })), + on(loadEvaluationContextFailure, (state, { error }) => ({ + ...state, + error, + loading: false + })), + on(saveEvaluationContext, (state) => ({ + ...state, + saving: true + })), + on(saveEvaluationContextSuccess, (state, { evaluationContextEntity }) => ({ + ...state, + saving: false, + evaluationContext: { + ruleOrder: evaluationContextEntity.ruleOrder, + flowFilePolicy: evaluationContextEntity.flowFilePolicy + } + })), + on(saveEvaluationContextFailure, (state, { error }) => ({ + ...state, + error, + saving: false + })), + on(resetEvaluationContextFailure, (state) => ({ + ...state, + error: null + })) +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.selectors.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.selectors.ts new file mode 100644 index 0000000000..8c30dc56a3 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/evaluation-context.selectors.ts @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createSelector } from '@ngrx/store'; +import { selectUpdateAttributeState, UpdateAttributeState } from '../index'; +import { evaluationContextFeatureKey, EvaluationContextState } from './index'; + +export const selectEvaluationContextState = createSelector( + selectUpdateAttributeState, + (state: UpdateAttributeState) => state[evaluationContextFeatureKey] +); + +export const selectEvaluationContextError = createSelector( + selectEvaluationContextState, + (state: EvaluationContextState) => state.error +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/index.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/index.ts new file mode 100644 index 0000000000..f53bf2ac52 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/evaluation-context/index.ts @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const evaluationContextFeatureKey = 'evaluationContext'; + +export interface EvaluationContextEntity { + clientId: string; + revision: number; + disconnectedNodeAcknowledged: boolean; + processorId: string; + ruleOrder: string[]; + flowFilePolicy: string; +} + +export interface EvaluationContext { + ruleOrder: string[]; + flowFilePolicy: string; +} + +export interface EvaluationContextState { + saving: boolean; + loading: boolean; + error: string | null; + evaluationContext: EvaluationContext | null; +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/index.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/index.ts new file mode 100644 index 0000000000..c4654db854 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/index.ts @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Action, combineReducers, createFeatureSelector } from '@ngrx/store'; +import { evaluationContextFeatureKey, EvaluationContextState } from './evaluation-context'; +import { evaluationContextReducer } from './evaluation-context/evaluation-context.reducer'; +import { rulesFeatureKey, RulesState } from './rules'; +import { rulesReducer } from './rules/rules.reducer'; +import { advancedUiParametersFeatureKey, AdvancedUiParametersState } from './advanced-ui-parameters'; +import { advancedUiParametersReducer } from './advanced-ui-parameters/advanced-ui-parameters.reducer'; + +export const updateAttributeFeatureKey = 'updateAttribute'; + +export interface UpdateAttributeState { + [advancedUiParametersFeatureKey]: AdvancedUiParametersState; + [rulesFeatureKey]: RulesState; + [evaluationContextFeatureKey]: EvaluationContextState; +} + +export function reducers(state: any, action: Action) { + return combineReducers({ + [advancedUiParametersFeatureKey]: advancedUiParametersReducer, + [rulesFeatureKey]: rulesReducer, + [evaluationContextFeatureKey]: evaluationContextReducer + })(state, action); +} + +export const selectUpdateAttributeState = createFeatureSelector(updateAttributeFeatureKey); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/index.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/index.ts new file mode 100644 index 0000000000..5c0ae656d9 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/index.ts @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const rulesFeatureKey = 'rules'; + +export interface DeleteSuccessResponse { + revision: number; + id: string; +} + +export interface Rule { + id: string; + name: string; + comments: string; + conditions: Condition[]; + actions: Action[]; +} + +export interface RuleEntity { + clientId: string; + revision: number; + processorId: string; + disconnectedNodeAcknowledged: boolean; + rule: Rule; +} + +export interface RulesEntity { + clientId: string; + revision: number; + processorId: string; + rules: Rule[]; +} + +export interface Action { + id: string; + attribute: string; + value: string; +} + +export interface Condition { + id: string; + expression: string; +} + +export interface NewRule { + name: string; + comments: string; + conditions: Condition[]; + actions: Action[]; +} + +export interface RulesState { + loading: boolean; + saving: boolean; + error: string | null; + newRule?: NewRule; + rules: Rule[] | null; +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.actions.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.actions.ts new file mode 100644 index 0000000000..e0c1992a78 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.actions.ts @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createAction, props } from '@ngrx/store'; +import { DeleteSuccessResponse, NewRule, Rule, RuleEntity, RulesEntity } from './index'; + +const RULES_PREFIX = '[Rules]'; + +export const resetRulesState = createAction(`${RULES_PREFIX} Reset Rules State`); + +export const loadRules = createAction(`${RULES_PREFIX} Load Rules`); + +export const loadRulesSuccess = createAction( + `${RULES_PREFIX} Load Rules Success`, + props<{ rulesEntity: RulesEntity }>() +); + +export const loadRulesFailure = createAction(`${RULES_PREFIX} Load Rules Failure`, props<{ error: string }>()); + +export const saveRuleFailure = createAction(`${RULES_PREFIX} Save Rule Failure`, props<{ error: string }>()); + +export const populateNewRule = createAction( + `${RULES_PREFIX} Populate New Rule`, + props<{ + rule?: Rule; + }>() +); + +export const resetNewRule = createAction(`${RULES_PREFIX} Reset New Rule`); + +export const createRule = createAction(`${RULES_PREFIX} Create Rule`, props<{ newRule: NewRule }>()); + +export const createRuleSuccess = createAction(`${RULES_PREFIX} Create Rule Success`, props<{ entity: RuleEntity }>()); + +export const editRule = createAction(`${RULES_PREFIX} Edit Rule`, props<{ rule: Rule }>()); + +export const editRuleSuccess = createAction(`${RULES_PREFIX} Edit Rule Success`, props<{ entity: RuleEntity }>()); + +export const promptRuleDeletion = createAction(`${RULES_PREFIX} Prompt Rule Deletion`, props<{ rule: Rule }>()); + +export const deleteRule = createAction(`${RULES_PREFIX} Delete Rule`, props<{ rule: Rule }>()); + +export const deleteRuleSuccess = createAction( + `${RULES_PREFIX} Delete Rule Success`, + props<{ response: DeleteSuccessResponse }>() +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.effects.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.effects.ts new file mode 100644 index 0000000000..b9568d8a99 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.effects.ts @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import * as RulesActions from './rules.actions'; +import { UpdateAttributeService } from '../../service/update-attribute.service'; +import { HttpErrorResponse } from '@angular/common/http'; +import { catchError, from, map, of, switchMap, take, tap } from 'rxjs'; +import { concatLatestFrom } from '@ngrx/operators'; +import { Store } from '@ngrx/store'; +import { UpdateAttributeApplicationState } from '../../../../state'; +import { selectAdvancedUiParameters } from '../advanced-ui-parameters/advanced-ui-parameters.selectors'; +import { RulesEntity } from './index'; +import { MatDialog } from '@angular/material/dialog'; +import { SMALL_DIALOG, YesNoDialog } from '@nifi/shared'; +import { updateRevision } from '../advanced-ui-parameters/advanced-ui-parameters.actions'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { loadEvaluationContext } from '../evaluation-context/evaluation-context.actions'; + +@Injectable() +export class RulesEffects { + constructor( + private actions$: Actions, + private dialog: MatDialog, + private snackBar: MatSnackBar, + private store: Store, + private updateAttributeService: UpdateAttributeService + ) {} + + loadRules$ = createEffect(() => + this.actions$.pipe( + ofType(RulesActions.loadRules), + concatLatestFrom(() => this.store.select(selectAdvancedUiParameters)), + switchMap(([, advancedUiParameters]) => + from(this.updateAttributeService.getRules(advancedUiParameters.processorId)).pipe( + map((rulesEntity: RulesEntity) => + RulesActions.loadRulesSuccess({ + rulesEntity + }) + ), + catchError((errorResponse: HttpErrorResponse) => { + const error = this.updateAttributeService.getErrorString(errorResponse); + return of( + RulesActions.loadRulesFailure({ + error + }) + ); + }) + ) + ) + ) + ); + + createRule$ = createEffect(() => + this.actions$.pipe( + ofType(RulesActions.createRule), + map((action) => action.newRule), + concatLatestFrom(() => this.store.select(selectAdvancedUiParameters)), + switchMap(([newRule, advancedUiParameters]) => + from(this.updateAttributeService.createRule(advancedUiParameters, newRule)).pipe( + map((entity) => + RulesActions.createRuleSuccess({ + entity + }) + ), + catchError((errorResponse: HttpErrorResponse) => { + const error = this.updateAttributeService.getErrorString(errorResponse); + return of( + RulesActions.saveRuleFailure({ + error + }) + ); + }) + ) + ) + ) + ); + + createRuleSuccess$ = createEffect(() => + this.actions$.pipe( + ofType(RulesActions.createRuleSuccess), + map((action) => action.entity), + tap(() => { + this.snackBar.open('Rule successfully added', 'Ok', { duration: 30000 }); + this.store.dispatch(loadEvaluationContext()); + }), + switchMap((entity) => + of( + updateRevision({ + revision: entity.revision + }) + ) + ) + ) + ); + + editRule$ = createEffect(() => + this.actions$.pipe( + ofType(RulesActions.editRule), + map((action) => action.rule), + concatLatestFrom(() => this.store.select(selectAdvancedUiParameters)), + switchMap(([rule, advancedUiParameters]) => + from(this.updateAttributeService.saveRule(advancedUiParameters, rule)).pipe( + map((entity) => + RulesActions.editRuleSuccess({ + entity + }) + ), + catchError((errorResponse: HttpErrorResponse) => { + const error = this.updateAttributeService.getErrorString(errorResponse); + return of( + RulesActions.saveRuleFailure({ + error + }) + ); + }) + ) + ) + ) + ); + + editRuleSuccess$ = createEffect(() => + this.actions$.pipe( + ofType(RulesActions.editRuleSuccess), + map((action) => action.entity), + tap(() => { + this.snackBar.open('Rule successfully saved', 'Ok', { duration: 30000 }); + }), + switchMap((entity) => + of( + updateRevision({ + revision: entity.revision + }) + ) + ) + ) + ); + + promptRuleDeletion$ = createEffect( + () => + this.actions$.pipe( + ofType(RulesActions.promptRuleDeletion), + map((action) => action.rule), + tap((rule) => { + const dialogReference = this.dialog.open(YesNoDialog, { + ...SMALL_DIALOG, + data: { + title: 'Delete Rule', + message: `Delete rule ${rule.name}?` + } + }); + + dialogReference.componentInstance.yes.pipe(take(1)).subscribe(() => { + this.store.dispatch( + RulesActions.deleteRule({ + rule + }) + ); + }); + }) + ), + { dispatch: false } + ); + + deleteRule$ = createEffect(() => + this.actions$.pipe( + ofType(RulesActions.deleteRule), + map((action) => action.rule), + concatLatestFrom(() => this.store.select(selectAdvancedUiParameters)), + switchMap(([rule, advancedUiParameters]) => + from(this.updateAttributeService.deleteRule(advancedUiParameters, rule.id)).pipe( + map((entity) => + RulesActions.deleteRuleSuccess({ + response: { + id: rule.id, + revision: entity.revision + } + }) + ), + catchError((errorResponse: HttpErrorResponse) => { + const error = this.updateAttributeService.getErrorString(errorResponse); + return of( + RulesActions.saveRuleFailure({ + error + }) + ); + }) + ) + ) + ) + ); + + deleteRuleSuccess$ = createEffect(() => + this.actions$.pipe( + ofType(RulesActions.deleteRuleSuccess), + map((action) => action.response), + tap(() => { + this.snackBar.open('Rule successfully deleted', 'Ok', { duration: 30000 }); + this.store.dispatch(loadEvaluationContext()); + }), + switchMap((response) => + of( + updateRevision({ + revision: response.revision + }) + ) + ) + ) + ); + + saveRuleFailure$ = createEffect( + () => + this.actions$.pipe( + ofType(RulesActions.saveRuleFailure), + map((action) => action.error), + tap((error) => { + this.snackBar.open(error, 'Dismiss', { duration: 30000 }); + }) + ), + { dispatch: false } + ); +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.reducer.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.reducer.ts new file mode 100644 index 0000000000..7d2885469b --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.reducer.ts @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { RulesState } from './index'; +import { createReducer, on } from '@ngrx/store'; +import { + createRule, + createRuleSuccess, + deleteRule, + deleteRuleSuccess, + editRule, + editRuleSuccess, + loadRules, + loadRulesFailure, + loadRulesSuccess, + populateNewRule, + resetNewRule, + resetRulesState, + saveRuleFailure +} from './rules.actions'; +import { produce } from 'immer'; + +export const initialState: RulesState = { + loading: false, + saving: false, + error: null, + rules: null +}; + +export const rulesReducer = createReducer( + initialState, + on(resetRulesState, () => ({ + ...initialState + })), + on(loadRules, (state) => ({ + ...state, + error: null, + loading: true + })), + on(loadRulesSuccess, (state, { rulesEntity }) => ({ + ...state, + loading: false, + rules: rulesEntity.rules + })), + on(loadRulesFailure, (state, { error }) => ({ + ...state, + loading: false, + error + })), + on(populateNewRule, (state, { rule }) => ({ + ...state, + newRule: { + name: rule ? `Copy of ${rule.name}` : '', + comments: rule ? rule.comments : '', + conditions: rule ? rule.conditions : [], + actions: rule ? rule.actions : [] + } + })), + on(resetNewRule, (state) => ({ + ...state, + newRule: undefined + })), + on(createRule, editRule, deleteRule, (state) => ({ + ...state, + saving: true + })), + on(saveRuleFailure, (state) => ({ + ...state, + saving: false + })), + on(createRuleSuccess, (state, { entity }) => { + return produce(state, (draftState) => { + if (draftState.rules) { + draftState.rules.push(entity.rule); + } + draftState.saving = false; + draftState.newRule = undefined; + }); + }), + on(editRuleSuccess, (state, { entity }) => { + return produce(state, (draftState) => { + if (draftState.rules) { + const componentIndex: number = draftState.rules.findIndex((r: any) => entity.rule.id === r.id); + if (componentIndex > -1) { + draftState.rules[componentIndex] = { + ...entity.rule + }; + } + } + draftState.saving = false; + }); + }), + on(deleteRuleSuccess, (state, { response }) => { + return produce(state, (draftState) => { + if (draftState.rules) { + const componentIndex: number = draftState.rules.findIndex((r: any) => response.id === r.id); + if (componentIndex > -1) { + draftState.rules.splice(componentIndex, 1); + } + } + draftState.saving = false; + }); + }) +); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.selectors.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.selectors.ts new file mode 100644 index 0000000000..f3fbb33e5d --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/state/rules/rules.selectors.ts @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createSelector } from '@ngrx/store'; +import { UpdateAttributeState, selectUpdateAttributeState } from '../index'; +import { Rule, rulesFeatureKey, RulesState } from './index'; + +export const selectRulesState = createSelector( + selectUpdateAttributeState, + (state: UpdateAttributeState) => state[rulesFeatureKey] +); + +export const selectRules = createSelector(selectRulesState, (state: RulesState) => state.rules); + +export const selectRule = (id: string) => + createSelector(selectRules, (rules: Rule[] | null) => rules?.find((rule) => id == rule.id)); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.html new file mode 100644 index 0000000000..9ebb9a07d2 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.html @@ -0,0 +1,161 @@ + + +
      +
      +
      Actions
      + @if (!isDisabled) { + + } +
      + @if (hasActions()) { +
      + + + + + + + + + + + + + + + + + + + + + +
      Attribute +
      + +
      +
      Value +
      + +
      +
      +
      + + + + +
      +
      + + + +
      Empty string set
      +
      + +
      +
      + {{ expression }} +
      + @if (hasExtraWhitespace(expression)) { +
      + } +
      +
      +
      + + + + + + +
      + } +
      diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.scss new file mode 100644 index 0000000000..c117e55c53 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.scss @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.action-table { + .mat-column-attribute { + width: 50%; + } + + .mat-column-value { + width: 50%; + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.spec.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.spec.ts new file mode 100644 index 0000000000..ee37679f88 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.spec.ts @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ActionTable } from './action-table.component'; + +import 'codemirror/addon/hint/show-hint'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('ActionTable', () => { + let component: ActionTable; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ActionTable, HttpClientTestingModule] + }); + fixture = TestBed.createComponent(ActionTable); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.ts new file mode 100644 index 0000000000..35c1e92194 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/action-table/action-table.component.ts @@ -0,0 +1,347 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + AfterViewInit, + ChangeDetectorRef, + Component, + DestroyRef, + forwardRef, + inject, + Input, + QueryList, + ViewChildren +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { NiFiCommon, NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { NgTemplateOutlet } from '@angular/common'; +import { + CdkConnectedOverlay, + CdkOverlayOrigin, + ConnectionPositionPair, + OriginConnectionPosition, + OverlayConnectionPosition +} from '@angular/cdk/overlay'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { MatMenu, MatMenuItem, MatMenuModule } from '@angular/material/menu'; +import { Action } from '../../state/rules'; +import { v4 as uuidv4 } from 'uuid'; +import { UaEditor } from '../ua-editor/ua-editor.component'; + +export interface ActionItem { + id: string; + triggerEdit: boolean; + action: Action; +} + +@Component({ + selector: 'action-table', + standalone: true, + templateUrl: './action-table.component.html', + imports: [ + MatButtonModule, + MatDialogModule, + MatTableModule, + MatMenuModule, + NifiTooltipDirective, + NgTemplateOutlet, + CdkOverlayOrigin, + CdkConnectedOverlay, + MatMenu, + MatMenuItem, + UaEditor + ], + styleUrls: ['./action-table.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => ActionTable), + multi: true + } + ] +}) +export class ActionTable implements AfterViewInit, ControlValueAccessor { + @Input() isNew: boolean = false; + + private destroyRef = inject(DestroyRef); + + protected readonly TextTip = TextTip; + + displayedColumns: string[] = ['attribute', 'value', 'actions']; + dataSource: MatTableDataSource = new MatTableDataSource(); + selectedItem!: ActionItem; + + @ViewChildren('trigger') valueTriggers!: QueryList; + + isDisabled = false; + isTouched = false; + onTouched!: () => void; + onChange!: (actions: Action[]) => void; + + attributeEditorOpen = false; + attributeEditorTrigger: any = null; + + valueEditorOpen = false; + valueEditorTrigger: any = null; + + editorItem!: ActionItem; + editorWidth = 0; + editorOffsetX = 8; + editorOffsetY = 0; + + private originPos: OriginConnectionPosition = { + originX: 'center', + originY: 'center' + }; + private editorOverlayPos: OverlayConnectionPosition = { + overlayX: 'center', + overlayY: 'center' + }; + public editorPositions: ConnectionPositionPair[] = []; + + constructor( + private changeDetector: ChangeDetectorRef, + private nifiCommon: NiFiCommon + ) {} + + ngAfterViewInit(): void { + this.valueTriggers.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { + const item: ActionItem | undefined = this.dataSource.data.find((item) => item.triggerEdit); + + if (item) { + const valueTrigger: CdkOverlayOrigin | undefined = this.valueTriggers.find( + (valueTrigger: CdkOverlayOrigin) => { + return this.formatId(item) == valueTrigger.elementRef.nativeElement.getAttribute('id'); + } + ); + + if (valueTrigger) { + // scroll into view + valueTrigger.elementRef.nativeElement.scrollIntoView({ block: 'center', behavior: 'instant' }); + + window.setTimeout(function () { + // trigger a click to start editing the new item + valueTrigger.elementRef.nativeElement.click(); + }, 0); + } + + item.triggerEdit = false; + } + }); + } + + registerOnChange(onChange: (actions: Action[]) => void): void { + this.onChange = onChange; + } + + registerOnTouched(onTouch: () => void): void { + this.onTouched = onTouch; + } + + setDisabledState(isDisabled: boolean): void { + this.isDisabled = isDisabled; + } + + writeValue(actions: Action[]): void { + const actionItems: ActionItem[] = actions.map((action) => { + // create the action item + const item: ActionItem = { + id: action.id, + triggerEdit: false, + action: { + ...action + } + }; + + return item; + }); + + this.setActionItems(actionItems); + } + + private setActionItems(actionItems: ActionItem[]): void { + this.dataSource = new MatTableDataSource(actionItems); + } + + newActionClicked(): void { + const currentActionItems: ActionItem[] = this.dataSource.data; + + const id = uuidv4(); + const item: ActionItem = { + id, + triggerEdit: true, + action: { + id, + attribute: '', + value: '' + } + }; + + this.setActionItems([...currentActionItems, item]); + this.handleChanged(); + } + + formatId(item: ActionItem): string { + return 'action-' + item.id; + } + + isEmptyString(value: string): boolean { + return value === ''; + } + + hasExtraWhitespace(value: string): boolean { + return this.nifiCommon.hasLeadTrailWhitespace(value); + } + + openAttributeEditor(editorTrigger: any, item: ActionItem, event: MouseEvent): void { + if (event.target) { + const target: HTMLElement = event.target as HTMLElement; + + // find the table cell regardless of the target of the click + const td: HTMLElement | null = target.closest('td'); + if (td) { + const { width } = td.getBoundingClientRect(); + + this.editorPositions.pop(); + this.editorItem = item; + this.attributeEditorTrigger = editorTrigger; + this.attributeEditorOpen = true; + + this.editorWidth = width; + + this.editorPositions.push( + new ConnectionPositionPair( + this.originPos, + this.editorOverlayPos, + this.editorOffsetX, + this.editorOffsetY + ) + ); + this.changeDetector.detectChanges(); + } + } + } + + openValueEditor(editorTrigger: any, item: ActionItem, event: MouseEvent): void { + if (event.target) { + const target: HTMLElement = event.target as HTMLElement; + + // find the table cell regardless of the target of the click + const td: HTMLElement | null = target.closest('td'); + if (td) { + const { width } = td.getBoundingClientRect(); + + this.editorPositions.pop(); + this.editorItem = item; + this.valueEditorTrigger = editorTrigger; + this.valueEditorOpen = true; + + this.editorWidth = width; + + this.editorPositions.push( + new ConnectionPositionPair( + this.originPos, + this.editorOverlayPos, + this.editorOffsetX, + this.editorOffsetY + ) + ); + this.changeDetector.detectChanges(); + } + } + } + + deleteAction(item: ActionItem): void { + const index = this.dataSource.data.indexOf(item); + if (index > -1) { + this.dataSource.data.splice(index, 1); + this.handleChanged(); + } + } + + hasActions(): boolean { + return this.dataSource.data.length > 0; + } + + saveActionAttribute(item: ActionItem, attribute: string): void { + if (item.action.attribute !== attribute) { + item.action = { + ...item.action, + attribute + }; + + this.handleChanged(); + } + + this.closeAttributeEditor(); + } + + saveActionValue(item: ActionItem, value: string): void { + if (item.action.value !== value) { + item.action = { + ...item.action, + value + }; + + this.handleChanged(); + } + + this.closeValueEditor(); + } + + private handleChanged() { + // this is needed to trigger the filter to be reapplied + this.dataSource._updateChangeSubscription(); + this.changeDetector.markForCheck(); + + // mark the component as touched if not already + if (!this.isTouched) { + this.isTouched = true; + this.onTouched(); + } + + // emit the changes + this.onChange(this.serializeActions()); + } + + private serializeActions(): Action[] { + const actions: ActionItem[] = this.dataSource.data; + return actions.map((item) => item.action); + } + + closeAttributeEditor(): void { + this.attributeEditorOpen = false; + } + + closeValueEditor(): void { + this.valueEditorOpen = false; + } + + selectAction(item: ActionItem): void { + this.selectedItem = item; + } + + isSelected(item: ActionItem): boolean { + if (this.selectedItem) { + return item.id === this.selectedItem.id; + } + return false; + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.html new file mode 100644 index 0000000000..e6b9cbc08c --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.html @@ -0,0 +1,117 @@ + + +
      +
      +
      Conditions
      + @if (!isDisabled) { + + } +
      + @if (hasConditions()) { +
      + + + + + + + + + + + + + + + +
      Expression +
      + + +
      Empty string set
      +
      + +
      +
      + {{ expression }} +
      + @if (hasExtraWhitespace(expression)) { +
      + } +
      +
      +
      +
      +
      + + + + +
      +
      + + + +
      + } +
      diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-namespace.js b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.scss similarity index 93% rename from nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-namespace.js rename to nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.scss index 7301e37f12..2944f98194 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/nf/nf-namespace.js +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.scss @@ -14,7 +14,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// register the nf namespace -var nf; -if (!nf) - nf = {}; \ No newline at end of file diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.spec.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.spec.ts new file mode 100644 index 0000000000..fd36a5b24c --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.spec.ts @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConditionTable } from './condition-table.component'; + +import 'codemirror/addon/hint/show-hint'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('ConditionTable', () => { + let component: ConditionTable; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ConditionTable, HttpClientTestingModule] + }); + fixture = TestBed.createComponent(ConditionTable); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.ts new file mode 100644 index 0000000000..ef1d8b9533 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/condition-table/condition-table.component.ts @@ -0,0 +1,296 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + AfterViewInit, + ChangeDetectorRef, + Component, + DestroyRef, + forwardRef, + inject, + Input, + QueryList, + ViewChildren +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { NiFiCommon, NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { NgTemplateOutlet } from '@angular/common'; +import { + CdkConnectedOverlay, + CdkOverlayOrigin, + ConnectionPositionPair, + OriginConnectionPosition, + OverlayConnectionPosition +} from '@angular/cdk/overlay'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { MatMenu, MatMenuItem, MatMenuModule } from '@angular/material/menu'; +import { Condition } from '../../state/rules'; +import { v4 as uuidv4 } from 'uuid'; +import { UaEditor } from '../ua-editor/ua-editor.component'; + +export interface ConditionItem { + id: string; + triggerEdit: boolean; + condition: Condition; +} + +@Component({ + selector: 'condition-table', + standalone: true, + templateUrl: './condition-table.component.html', + imports: [ + MatButtonModule, + MatDialogModule, + MatTableModule, + MatMenuModule, + NifiTooltipDirective, + NgTemplateOutlet, + CdkOverlayOrigin, + CdkConnectedOverlay, + MatMenu, + MatMenuItem, + UaEditor + ], + styleUrls: ['./condition-table.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => ConditionTable), + multi: true + } + ] +}) +export class ConditionTable implements AfterViewInit, ControlValueAccessor { + @Input() isNew: boolean = false; + + private destroyRef = inject(DestroyRef); + + protected readonly TextTip = TextTip; + + displayedColumns: string[] = ['expression', 'actions']; + dataSource: MatTableDataSource = new MatTableDataSource(); + selectedItem!: ConditionItem; + + @ViewChildren('trigger') valueTriggers!: QueryList; + + isDisabled = false; + isTouched = false; + onTouched!: () => void; + onChange!: (conditions: Condition[]) => void; + + editorOpen = false; + editorTrigger: any = null; + editorItem!: ConditionItem; + editorWidth = 0; + editorOffsetX = 8; + editorOffsetY = 0; + + private originPos: OriginConnectionPosition = { + originX: 'center', + originY: 'center' + }; + private editorOverlayPos: OverlayConnectionPosition = { + overlayX: 'center', + overlayY: 'center' + }; + public editorPositions: ConnectionPositionPair[] = []; + + constructor( + private changeDetector: ChangeDetectorRef, + private nifiCommon: NiFiCommon + ) {} + + ngAfterViewInit(): void { + this.valueTriggers.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { + const item: ConditionItem | undefined = this.dataSource.data.find((item) => item.triggerEdit); + + if (item) { + const valueTrigger: CdkOverlayOrigin | undefined = this.valueTriggers.find( + (valueTrigger: CdkOverlayOrigin) => { + return this.formatId(item) == valueTrigger.elementRef.nativeElement.getAttribute('id'); + } + ); + + if (valueTrigger) { + // scroll into view + valueTrigger.elementRef.nativeElement.scrollIntoView({ block: 'center', behavior: 'instant' }); + + window.setTimeout(function () { + // trigger a click to start editing the new item + valueTrigger.elementRef.nativeElement.click(); + }, 0); + } + + item.triggerEdit = false; + } + }); + } + + registerOnChange(onChange: (conditions: Condition[]) => void): void { + this.onChange = onChange; + } + + registerOnTouched(onTouch: () => void): void { + this.onTouched = onTouch; + } + + setDisabledState(isDisabled: boolean): void { + this.isDisabled = isDisabled; + } + + writeValue(conditions: Condition[]): void { + const conditionItems: ConditionItem[] = conditions.map((condition) => { + // create the condition item + const item: ConditionItem = { + id: condition.id, + triggerEdit: false, + condition: { + ...condition + } + }; + + return item; + }); + + this.setConditionItems(conditionItems); + } + + private setConditionItems(conditionItems: ConditionItem[]): void { + this.dataSource = new MatTableDataSource(conditionItems); + } + + newConditionClicked(): void { + const currentConditionItems: ConditionItem[] = this.dataSource.data; + + const id = uuidv4(); + const item: ConditionItem = { + id, + triggerEdit: true, + condition: { + id, + expression: '' + } + }; + + this.setConditionItems([...currentConditionItems, item]); + this.handleChanged(); + } + + formatId(item: ConditionItem): string { + return 'condition-' + item.id; + } + + isEmptyString(value: string): boolean { + return value === ''; + } + + hasExtraWhitespace(value: string): boolean { + return this.nifiCommon.hasLeadTrailWhitespace(value); + } + + openEditor(editorTrigger: any, item: ConditionItem, event: MouseEvent): void { + if (event.target) { + const target: HTMLElement = event.target as HTMLElement; + + // find the table cell regardless of the target of the click + const td: HTMLElement | null = target.closest('td'); + if (td) { + const { width } = td.getBoundingClientRect(); + + this.editorPositions.pop(); + this.editorItem = item; + this.editorTrigger = editorTrigger; + this.editorOpen = true; + + this.editorWidth = width; + + this.editorPositions.push( + new ConnectionPositionPair( + this.originPos, + this.editorOverlayPos, + this.editorOffsetX, + this.editorOffsetY + ) + ); + this.changeDetector.detectChanges(); + } + } + } + + deleteCondition(item: ConditionItem): void { + const index = this.dataSource.data.indexOf(item); + if (index > -1) { + this.dataSource.data.splice(index, 1); + this.handleChanged(); + } + } + + hasConditions(): boolean { + return this.dataSource.data.length > 0; + } + + saveConditionValue(item: ConditionItem, expression: string | null): void { + if (expression && item.condition.expression != expression) { + item.condition = { + ...item.condition, + expression + }; + + this.handleChanged(); + } + + this.closeEditor(); + } + + private handleChanged() { + // this is needed to trigger the filter to be reapplied + this.dataSource._updateChangeSubscription(); + this.changeDetector.markForCheck(); + + // mark the component as touched if not already + if (!this.isTouched) { + this.isTouched = true; + this.onTouched(); + } + + // emit the changes + this.onChange(this.serializeConditions()); + } + + private serializeConditions(): Condition[] { + const conditions: ConditionItem[] = this.dataSource.data; + return conditions.map((item) => item.condition); + } + + closeEditor(): void { + this.editorOpen = false; + } + + selectCondition(item: ConditionItem): void { + this.selectedItem = item; + } + + isSelected(item: ConditionItem): boolean { + if (this.selectedItem) { + return item.id === this.selectedItem.id; + } + return false; + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.html new file mode 100644 index 0000000000..559ce0343d --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.html @@ -0,0 +1,76 @@ + + + +
      +
      +
      + + Name + + @if (nameControl.invalid) { + {{ getNameErrorMessage() }} + } + +
      +
      +
      +
      + + Comments + + +
      +
      +
      + + @if (conditionControl.invalid) { +
      {{ getConditionErrorMessage() }}
      + } +
      +
      + + @if (actionControl.invalid) { +
      {{ getActionErrorMessage() }}
      + } +
      +
      + @if (isEditable) { + + @if (id) { + + } @else { + + } + } +
      +
      + diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.scss new file mode 100644 index 0000000000..b5f2f8e9c3 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.scss @@ -0,0 +1,32 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +@use '@angular/material' as mat; + +:host { + width: 100%; +} + +.edit-rule { + @include mat.button-density(-1); + + .mat-mdc-form-field { + width: 100%; + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.spec.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.spec.ts new file mode 100644 index 0000000000..1c046b01fa --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.spec.ts @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { EditRule } from './edit-rule.component'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; + +describe('EditRule', () => { + let component: EditRule; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [EditRule, NoopAnimationsModule] + }).compileComponents(); + + fixture = TestBed.createComponent(EditRule); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.ts new file mode 100644 index 0000000000..dec31c0683 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/edit-rule/edit-rule.component.ts @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { + AbstractControl, + FormBuilder, + FormControl, + FormGroup, + FormsModule, + PristineChangeEvent, + ReactiveFormsModule, + ValidationErrors, + ValidatorFn, + Validators +} from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { Action, Condition, NewRule, Rule } from '../../state/rules'; +import { ConditionTable } from '../condition-table/condition-table.component'; +import { ActionTable } from '../action-table/action-table.component'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; + +@Component({ + selector: 'edit-rule', + standalone: true, + imports: [ + CommonModule, + MatSlideToggleModule, + MatFormFieldModule, + FormsModule, + MatInputModule, + ReactiveFormsModule, + MatExpansionModule, + MatButtonModule, + ConditionTable, + ActionTable + ], + templateUrl: './edit-rule.component.html', + styleUrl: './edit-rule.component.scss' +}) +export class EditRule implements AfterViewInit { + @Input() id?: string; + @Input() set name(name: string) { + this.currentName = name; + this.nameControl.setValue(name); + } + @Input() set existingRuleNames(existingRuleNames: string[]) { + this.nameControl.setValidators([Validators.required, this.existingRuleValidator(existingRuleNames)]); + } + @Input() set comments(comments: string) { + this.currentComments = comments; + this.editRuleForm.get('comments')?.setValue(comments); + } + @Input() set conditions(conditions: Condition[]) { + this.currentConditions = conditions; + this.editRuleForm.get('conditions')?.setValue(conditions); + } + @Input() set actions(actions: Action[]) { + this.currentActions = actions; + this.editRuleForm.get('actions')?.setValue(actions); + } + @Input() set editable(editable: boolean) { + this.isEditable = editable; + + if (editable) { + this.editRuleForm.get('conditions')?.enable(); + this.editRuleForm.get('actions')?.enable(); + } else { + this.editRuleForm.get('conditions')?.disable(); + this.editRuleForm.get('actions')?.disable(); + } + } + @Input() saving: boolean = false; + @Input() set ruleUpdate(ruleUpdate: Rule) { + if (ruleUpdate && this.ruleSaved) { + this.editRuleForm.markAsPristine(); + } + } + + @Output() afterInit: EventEmitter = new EventEmitter(); + @Output() addRule: EventEmitter = new EventEmitter(); + @Output() editRule: EventEmitter = new EventEmitter(); + @Output() dirty: EventEmitter = new EventEmitter(); + @Output() cancel: EventEmitter = new EventEmitter(); + + editRuleForm: FormGroup; + isEditable: boolean = true; + + currentName: string | null = null; + currentComments: string | null = null; + currentConditions: Condition[] | null = null; + currentActions: Action[] | null = null; + + nameControl: FormControl; + conditionControl: FormControl; + actionControl: FormControl; + + private ruleSaved: boolean = false; + + constructor(private formBuilder: FormBuilder) { + this.nameControl = new FormControl('', Validators.required); + this.conditionControl = new FormControl({ value: [], disabled: !this.isEditable }, [ + this.conditionsValidator() + ]); + this.actionControl = new FormControl({ value: [], disabled: !this.isEditable }, [this.actionsValidator()]); + + this.editRuleForm = this.formBuilder.group({ + name: this.nameControl, + comments: new FormControl(''), + conditions: this.conditionControl, + actions: this.actionControl + }); + + this.editRuleForm.events.pipe(takeUntilDestroyed()).subscribe((event) => { + if (event instanceof PristineChangeEvent) { + this.dirty.next(!event.pristine); + } + }); + } + + ngAfterViewInit(): void { + this.afterInit.next(); + } + + private existingRuleValidator(existingRuleNames: string[]): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const value = control.value; + if (value === '') { + return null; + } + if (existingRuleNames.includes(value)) { + if (this.id) { + if (value !== this.currentName) { + return { + existingRuleName: true + }; + } + } else { + return { + existingRuleName: true + }; + } + } + return null; + }; + } + + getNameErrorMessage(): string { + if (this.nameControl.hasError('required')) { + return 'Rule name is required.'; + } + + return this.nameControl.hasError('existingRuleName') ? 'A rule with this name already exists.' : ''; + } + + private conditionsValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const conditions: Condition[] = control.value; + + if (conditions.length === 0) { + return { + conditionsRequired: true + }; + } + + if (conditions.some((condition) => condition.expression === '')) { + return { + emptyCondition: true + }; + } + + return null; + }; + } + + getConditionErrorMessage(): string { + if (this.conditionControl.hasError('conditionsRequired')) { + return 'No Conditions defined for this Rule. Create one using the Add button.'; + } + + return this.conditionControl.hasError('emptyCondition') ? 'All Conditions must have an expression.' : ''; + } + + private actionsValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const actions: Action[] = control.value; + + if (actions.length === 0) { + return { + actionsRequired: true + }; + } + + if (actions.some((action) => action.attribute === '')) { + return { + emptyAttribute: true + }; + } + + return null; + }; + } + + getActionErrorMessage(): string { + if (this.actionControl.hasError('actionsRequired')) { + return 'No Actions defined for this Rule. Create one using the Add button.'; + } + + return this.actionControl.hasError('emptyAttribute') ? 'All Actions must have an attribute.' : ''; + } + + cancelClicked(): void { + this.editRuleForm.reset({ + name: this.currentName, + comments: this.currentComments, + conditions: this.currentConditions, + actions: this.currentActions + }); + + this.dirty.next(false); + this.cancel.next(); + } + + saveClicked(): void { + const name: string = this.nameControl.value; + const comments: string = this.editRuleForm.get('comments')?.value; + const conditions: Condition[] = this.editRuleForm.get('conditions')?.value; + const actions: Action[] = this.editRuleForm.get('actions')?.value; + + if (this.id) { + this.editRule.next({ + id: this.id, + name, + comments, + conditions, + actions + }); + } else { + this.addRule.next({ + name, + comments, + conditions, + actions + }); + } + + this.ruleSaved = true; + } +} diff --git a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/jquery.each.js b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/_rule-listing.component-theme.scss similarity index 59% rename from nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/jquery.each.js rename to nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/_rule-listing.component-theme.scss index 90f76b880f..06dccf1af8 100644 --- a/nifi-extension-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/jquery/jquery.each.js +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/_rule-listing.component-theme.scss @@ -14,18 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -(function ($) { - // get a reference to the original each method - var origEach = $.each; - // override the jQuery each method (not $.fn.each as - // we are not calling with a jQuery 'instance', $.fn.each - // defers to this function with 'this' as the object param) - $.each = function (object, callback, args) { - // ensure the object specified is not undefined or null - if (typeof object !== 'undefined' && object !== null) { - return origEach.call(this, object, callback, args); +@use 'sass:map'; +@use '@angular/material' as mat; + +@mixin generate-theme($material-theme, $config) { + $alternate-surface: map.get($config, alternate-surface); + + .rule-listing { + .cdk-drop-list-dragging { + background-color: unset !important; } - return object; - }; -})(jQuery); \ No newline at end of file + + .cdk-drop-list { + background: unset; + } + + .cdk-drag { + background: $alternate-surface; + } + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.html new file mode 100644 index 0000000000..b662b2e9d5 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.html @@ -0,0 +1,199 @@ + +@if (rulesList.length === 0 && !newRule) { +
      + @if (isEditable) { +
      No rules configured for this Processor. Get started by defining your first.
      + + } @else { +
      No rules configured for this Processor.
      + } +
      +} @else { +
      + @if (rulesList.length > 0 || !newRule) { +
      +
      +
      +
      Use original FlowFile for matching rules
      + +
      +
      + +
      +
      +
      + } +
      +
      + @if (!newRule) { + + Search + + + } +
      +
      + @if (flowFilePolicy === 'USE_ORIGINAL' && !reorderDisabled()) { +
      +
      Reorder rules
      + +
      + } + @if (!newRule) { + + } +
      +
      + @if (filteredRulesList.length === 0 && !newRule) { +
      No matching rules
      + } @else { + @if (allowRuleReordering) { + + @for (rule of filteredRulesList; track rule.id) { + + + +
      + +
      + {{ rule.name }} +
      +
      +
      + + {{ rule.comments }} + +
      + +
      + } +
      + } @else { + + @for (rule of filteredRulesList; track rule.id) { + + + + {{ rule.name }} + + +
      +
      + {{ rule.comments }} +
      + @if (isEditable) { + + + + + + } +
      +
      +
      + +
      + } + @if (newRule) { + + + + New rule + + + + + } +
      + } + } +
      +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.scss new file mode 100644 index 0000000000..e469f1f62a --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.scss @@ -0,0 +1,56 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +:host { + width: 100%; +} + +.rule-listing { + .reorder-header { + mat-panel-title { + overflow: hidden; + display: block; + margin-top: auto; + margin-bottom: auto; + } + + mat-panel-description { + @apply truncate; + display: block; + margin-top: auto; + margin-bottom: auto; + } + } + + .editable-header { + mat-panel-title { + @apply truncate; + display: block; + margin-top: auto; + margin-bottom: auto; + } + + mat-panel-description { + overflow: hidden; + display: block; + margin-top: auto; + margin-bottom: auto; + } + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.spec.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.spec.ts new file mode 100644 index 0000000000..ebe003fb0b --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.spec.ts @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RuleListing } from './rule-listing.component'; +import { provideMockStore } from '@ngrx/store/testing'; +import { rulesFeatureKey } from '../../state/rules'; +import { initialState } from '../../state/rules/rules.reducer'; + +describe('RuleListing', () => { + let component: RuleListing; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RuleListing], + providers: [ + provideMockStore({ + initialState: { + [rulesFeatureKey]: initialState + } + }) + ] + }).compileComponents(); + + fixture = TestBed.createComponent(RuleListing); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.ts new file mode 100644 index 0000000000..28d6cc1853 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/rule-listing/rule-listing.component.ts @@ -0,0 +1,305 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { afterRender, Component, ElementRef, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Store } from '@ngrx/store'; +import { UpdateAttributeState } from '../../state'; +import { MatSlideToggleChange, MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop'; +import { Action, Condition, NewRule, Rule } from '../../state/rules'; +import { EvaluationContext } from '../../state/evaluation-context'; +import { saveEvaluationContext } from '../../state/evaluation-context/evaluation-context.actions'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { debounceTime, Observable } from 'rxjs'; +import { + createRule, + editRule, + populateNewRule, + promptRuleDeletion, + resetNewRule +} from '../../state/rules/rules.actions'; +import { EditRule } from '../edit-rule/edit-rule.component'; +import { isDefinedAndNotNull, NifiTooltipDirective, TextTip } from '@nifi/shared'; +import { MatMenu, MatMenuItem, MatMenuModule } from '@angular/material/menu'; +import { selectRule } from '../../state/rules/rules.selectors'; +import { selectEvaluationContextError } from '../../state/evaluation-context/evaluation-context.selectors'; + +@Component({ + selector: 'rule-listing', + standalone: true, + imports: [ + CommonModule, + MatSlideToggleModule, + MatFormFieldModule, + FormsModule, + MatInputModule, + ReactiveFormsModule, + MatExpansionModule, + MatButtonModule, + MatMenuModule, + CdkDropList, + CdkDrag, + EditRule, + MatMenu, + MatMenuItem, + NifiTooltipDirective + ], + templateUrl: './rule-listing.component.html', + styleUrl: './rule-listing.component.scss' +}) +export class RuleListing { + @Input() set evaluationContext(evaluationContext: EvaluationContext) { + this.ruleOrder = evaluationContext.ruleOrder; + this.flowFilePolicy = evaluationContext.flowFilePolicy; + this.updateFlowFilePolicy(); + } + + @Input() set rules(rules: Rule[]) { + this.originalRulesList = [...rules]; + this.rulesList = [...rules]; + this.filterRules(); + } + @Input() newRule?: NewRule; + @Input() set editable(editable: boolean) { + this.isEditable = editable; + + if (editable) { + this.flowFilePolicyForm.get('useOriginalFlowFilePolicy')?.enable(); + } else { + this.flowFilePolicyForm.get('useOriginalFlowFilePolicy')?.disable(); + } + } + + isEditable: boolean = false; + + ruleOrder: string[] = []; + allowRuleReordering: boolean = false; + originalRulesList: Rule[] = []; + rulesList: Rule[] = []; + dirtyRules: Set = new Set(); + + filteredRulesList: Rule[] = []; + searchForm: FormGroup; + + flowFilePolicyForm: FormGroup; + flowFilePolicy: string = 'USE_ORIGINAL'; + + scrollToNewRule: boolean = false; + + private openRuleCount: number = 0; + + constructor( + private store: Store, + private formBuilder: FormBuilder, + private ruleListing: ElementRef + ) { + this.searchForm = this.formBuilder.group({ searchRules: '' }); + this.flowFilePolicyForm = this.formBuilder.group({ useOriginalFlowFilePolicy: true }); + + this.searchForm + .get('searchRules') + ?.valueChanges.pipe(takeUntilDestroyed(), debounceTime(500)) + .subscribe(() => { + this.filterRules(); + }); + + this.store + .select(selectEvaluationContextError) + .pipe(isDefinedAndNotNull(), takeUntilDestroyed()) + .subscribe(() => { + this.updateFlowFilePolicy(); + + this.rulesList = [...this.originalRulesList]; + this.filterRules(); + }); + + afterRender(() => { + if (this.scrollToNewRule) { + const newRulePanel = this.ruleListing.nativeElement.querySelector('.new-rule'); + if (newRulePanel) { + window.setTimeout(function () { + newRulePanel.scrollIntoView({ + block: 'center' + }); + }, 0); + this.scrollToNewRule = false; + } + } + }); + } + + private filterRules(): void { + const filter: string | null | undefined = this.searchForm.get('searchRules')?.value; + if (filter) { + const filterText = filter.toLowerCase(); + this.filteredRulesList = this.rulesList.filter((rule) => this.ruleMatches(rule, filterText)); + } else { + this.filteredRulesList = [...this.rulesList]; + } + } + + private ruleMatches(rule: Rule, filterText: string): boolean { + return ( + rule.id.toLowerCase().includes(filterText) || + rule.name.toLowerCase().includes(filterText) || + rule.comments.toLowerCase().includes(filterText) || + rule.conditions.some((condition) => this.conditionMatches(condition, filterText)) || + rule.actions.some((action) => this.actionMatches(action, filterText)) + ); + } + + private conditionMatches(condition: Condition, filterText: string): boolean { + return ( + condition.id.toLowerCase().includes(filterText) || condition.expression.toLowerCase().includes(filterText) + ); + } + + private actionMatches(action: Action, filterText: string): boolean { + return ( + action.id.toLowerCase().includes(filterText) || + action.attribute.toLowerCase().includes(filterText) || + action.value.toLowerCase().includes(filterText) + ); + } + + private updateFlowFilePolicy(): void { + this.flowFilePolicyForm.get('useOriginalFlowFilePolicy')?.setValue(this.flowFilePolicy === 'USE_ORIGINAL'); + } + + reorderDisabled(): boolean { + return this.filterApplied() || this.areAnyExpanded() || this.newRule !== undefined || !this.isEditable; + } + + areAnyExpanded(): boolean { + // override the expansion panel check when allowing rule reordering + if (this.allowRuleReordering) { + return false; + } + + return this.openRuleCount > 0; + } + + filterApplied(): boolean { + return this.rulesList.length != this.filteredRulesList.length; + } + + populateNewRule(): void { + this.store.dispatch(populateNewRule({})); + } + + cloneRule(rule: Rule): void { + this.store.dispatch(populateNewRule({ rule })); + } + + newRuleExpanded(): void { + this.scrollToNewRule = true; + } + + deleteRule(rule: Rule): void { + this.store.dispatch(promptRuleDeletion({ rule })); + } + + flowFilePolicyToggled(event: MatSlideToggleChange): void { + this.store.dispatch( + saveEvaluationContext({ + evaluationContext: { + ruleOrder: this.ruleOrder, + flowFilePolicy: event.checked ? 'USE_ORIGINAL' : 'USE_CLONE' + } + }) + ); + } + + setAllowRuleReordering(event: MatSlideToggleChange): void { + this.allowRuleReordering = event.checked; + } + + panelOpened(): void { + this.openRuleCount++; + } + + panelClosed(): void { + this.openRuleCount--; + } + + getExistingRuleNames(): string[] { + return this.rulesList.map((rule) => rule.name); + } + + getRuleUpdates(id: string): Observable { + return this.store.select(selectRule(id)); + } + + createRule(newRule: NewRule): void { + this.store.dispatch( + createRule({ + newRule + }) + ); + } + + cancelNewRule(): void { + this.store.dispatch(resetNewRule()); + } + + editRule(rule: Rule): void { + this.store.dispatch( + editRule({ + rule + }) + ); + } + + setDirty(id: string, dirty: boolean): void { + if (dirty) { + this.dirtyRules.add(id); + } else { + this.dirtyRules.delete(id); + } + } + + isDirty(id: string): boolean { + return this.dirtyRules.has(id); + } + + reorderRules(event: CdkDragDrop): void { + if (event.previousIndex !== event.currentIndex) { + moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); + + this.store.dispatch( + saveEvaluationContext({ + evaluationContext: { + ruleOrder: event.container.data.map((rule) => rule.id), + flowFilePolicy: this.flowFilePolicy + } + }) + ); + + this.filterRules(); + } + } + + protected readonly TextTip = TextTip; +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/_ua-editor.component-theme.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/_ua-editor.component-theme.scss new file mode 100644 index 0000000000..fadae4377c --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/_ua-editor.component-theme.scss @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@use 'sass:map'; +@use '@angular/material' as mat; + +@mixin generate-theme() { + .ua-editor { + @include mat.button-density(-1); + + .editor { + &.blank { + border-color: var(--mdc-outlined-text-field-disabled-label-text-color); + cursor: not-allowed !important; + } + } + + .CodeMirror.cm-s-nifi { + height: 108px; + } + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/el.service.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/el.service.ts new file mode 100644 index 0000000000..54f2f586ba --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/el.service.ts @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; + +@Injectable({ providedIn: 'root' }) +export class ElService { + private static readonly DOCS: string = '../nifi-api'; + + constructor(private httpClient: HttpClient) {} + + getElGuide(): Observable { + return this.httpClient.get(`${ElService.DOCS}/html/expression-language-guide.html`, { responseType: 'text' }); + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/nfel.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/nfel.ts new file mode 100644 index 0000000000..0bee35ce42 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/nfel.ts @@ -0,0 +1,1106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentRef, Injectable, Renderer2, ViewContainerRef } from '@angular/core'; +import * as CodeMirror from 'codemirror'; +import { Editor, Hint, Hints, StringStream } from 'codemirror'; +import { ElService } from './el.service'; +import { take } from 'rxjs'; +import { NiFiCommon, ElFunction, Parameter, ParameterTip, ElFunctionTip } from '@nifi/shared'; + +export interface NfElHint extends Hint { + parameterDetails?: Parameter; + functionDetails?: ElFunction; +} + +@Injectable({ providedIn: 'root' }) +export class NfEl { + private viewContainerRef: ViewContainerRef | undefined; + private renderer: Renderer2 | undefined; + + constructor( + private elService: ElService, + private nifiCommon: NiFiCommon + ) { + const self: NfEl = this; + + this.elService + .getElGuide() + .pipe(take(1)) + .subscribe({ + next: (response) => { + const document: Document = new DOMParser().parseFromString(response, 'text/html'); + const elFunctions: Element[] = Array.from(document.querySelectorAll('div.function')); + + elFunctions.forEach((elFunction) => { + const name: string = elFunction.querySelector('h3')?.textContent ?? ''; + const description: string = elFunction.querySelector('span.description')?.textContent ?? ''; + const returnType: string = elFunction.querySelector('span.returnType')?.textContent ?? ''; + + let subject = ''; + const subjectSpan: Element | null = elFunction.querySelector('span.subject'); + const subjectless: Element | null = elFunction.querySelector('span.subjectless'); + + // Determine if this function supports running subjectless + if (subjectless) { + self.subjectlessFunctions.push(name); + subject = 'None'; + } + + // Determine if this function supports running with a subject + if (subjectSpan) { + self.functions.push(name); + subject = subjectSpan.textContent ?? ''; + } + + // find the arguments + const args: { [key: string]: string } = {}; + const argElements: Element[] = Array.from(elFunction.querySelectorAll('span.argName')); + argElements.forEach((argElement) => { + const argName: string = argElement.textContent ?? ''; + const next: Element | null = argElement.nextElementSibling; + if (next && next.matches('span.argDesc')) { + args[argName] = next.textContent ?? ''; + } + }); + + // record the function details + self.functionDetails[name] = { + name: name, + description: description, + args: args, + subject: subject, + returnType: returnType + }; + }); + }, + complete: () => { + // build the regex for all functions discovered + self.subjectlessFunctionRegex = new RegExp('^((' + self.subjectlessFunctions.join(')|(') + '))$'); + self.functionRegex = new RegExp('^((' + self.functions.join(')|(') + '))$'); + } + }); + + // register this custom mode + CodeMirror.defineMode(this.getLanguageId(), function () { + // builds the states based off the specified initial value + const buildStates = function (initialStates: any): any { + // each state has a context + const states = initialStates; + + return { + copy: function () { + const copy: any[] = []; + for (let i = 0; i < states.length; i++) { + copy.push({ + context: states[i].context + }); + } + return copy; + }, + get: function () { + if (states.length === 0) { + return { + context: null + }; + } else { + return states[states.length - 1]; + } + }, + push: function (state: any) { + return states.push(state); + }, + pop: function () { + return states.pop(); + } + }; + }; + + return { + startState: function () { + // build states with an empty array + return buildStates([]); + }, + + copyState: function (state: any) { + // build states with + return buildStates(state.copy()); + }, + + token: function (stream: StringStream, states: any) { + // consume any whitespace + if (stream.eatSpace()) { + return null; + } + + // if we've hit the end of the line + if (stream.eol()) { + return null; + } + + // get the current character + const current: string | null = stream.peek(); + + // if we've hit some comments... will consume the remainder of the line + if (current === '#') { + // consume the pound + stream.next(); + + const afterPound: string | null = stream.peek(); + if (afterPound !== '{') { + stream.skipToEnd(); + return 'comment'; + } else { + // unconsume the pound + stream.backUp(1); + } + } + + // get the current state + const state: any = states.get(); + + // the current input is invalid + if (state.context === NfEl.INVALID) { + stream.skipToEnd(); + return null; + } + + // within an expression + if (state.context === NfEl.EXPRESSION) { + const attributeOrSubjectlessFunctionExpression = + /^[^'"#${}()[\],:;\/*\\\s\t\r\n0-9][^'"#${}()[\],:;\/*\\\s\t\r\n]*/; + + // attempt to extract a function name + const attributeOrSubjectlessFunctionName: string[] = stream.match( + attributeOrSubjectlessFunctionExpression, + false + ); + + // if the result returned a match + if ( + attributeOrSubjectlessFunctionName !== null && + attributeOrSubjectlessFunctionName.length === 1 + ) { + // consume the entire token to better support suggest below + stream.match(attributeOrSubjectlessFunctionExpression); + + // if the result returned a match and is followed by a ( + if ( + self.subjectlessFunctionRegex.test(attributeOrSubjectlessFunctionName[0]) && + stream.peek() === '(' + ) { + // -------------------- + // subjectless function + // -------------------- + + // context change to function + state.context = NfEl.ARGUMENTS; + + // style for function + return 'builtin'; + } else { + // --------------------- + // attribute or function + // --------------------- + + // context change to function or subject... not sure yet + state.context = NfEl.SUBJECT_OR_FUNCTION; + + // this could be an attribute or a partial function name... style as attribute until we know + return 'variable-2'; + } + } else if (current === "'" || current === '"') { + // -------------- + // string literal + // -------------- + + // handle the string literal + const expressionStringResult: string | null = self.handleStringLiteral(stream, state); + + // considered a quoted variable + if (expressionStringResult !== null) { + // context change to function + state.context = NfEl.SUBJECT; + } + + return expressionStringResult; + } else if (current === '$') { + // ----------------- + // nested expression + // ----------------- + + const expressionDollarResult: string | null = self.handleStart( + '$', + NfEl.EXPRESSION, + stream, + states + ); + + // if we've found an embedded expression we need to... + if (expressionDollarResult !== null) { + // transition back to subject when this expression completes + state.context = NfEl.SUBJECT; + } + + return expressionDollarResult; + } else if (current === '#' && self.parametersSupported) { + // -------------------------- + // nested parameter reference + // -------------------------- + + // handle the nested parameter reference + const parameterReferenceResult = self.handleStart('#', NfEl.PARAMETER, stream, states); + + // if we've found an embedded parameter reference we need to... + if (parameterReferenceResult !== null) { + // transition back to subject when this parameter reference completes + state.context = NfEl.SUBJECT; + } + + return parameterReferenceResult; + } else if (current === '}') { + // ----------------- + // end of expression + // ----------------- + + // consume the close + stream.next(); + + // signifies the end of an expression + if (typeof states.pop() === 'undefined') { + return null; + } else { + // style as expression + return 'bracket'; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume to move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } + + // within a subject + if (state.context === NfEl.SUBJECT || state.context === NfEl.SUBJECT_OR_FUNCTION) { + // if the next character indicates the start of a function call + if (current === ':') { + // ------------------------- + // trigger for function name + // ------------------------- + + // consume the colon and update the context + stream.next(); + state.context = NfEl.FUNCTION; + + // consume any addition whitespace + stream.eatSpace(); + + // don't style + return null; + } else if (current === '}') { + // ----------------- + // end of expression + // ----------------- + + // consume the close + stream.next(); + + // signifies the end of an expression + if (typeof states.pop() === 'undefined') { + return null; + } else { + // style as expression + return 'bracket'; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume to move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } + + // within a function + if (state.context === NfEl.FUNCTION) { + // attempt to extract a function name + const functionName = stream.match(/^[a-zA-Z]+/, false); + + // if the result returned a match + if (functionName !== null && functionName.length === 1) { + // consume the entire token to ensure the whole function + // name is matched. this is an issue with functions like + // substring and substringAfter since 'substringA' would + // match the former and when we really want to autocomplete + // against the latter. + stream.match(/^[a-zA-Z]+/); + + // see if this matches a known function and is followed by ( + if (self.functionRegex.test(functionName[0]) && stream.peek() === '(') { + // -------- + // function + // -------- + + // change context to arguments + state.context = NfEl.ARGUMENTS; + + // style for function + return 'builtin'; + } else { + // ------------------------------ + // maybe function... not sure yet + // ------------------------------ + + // not sure yet... + return null; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } + + // within arguments + if (state.context === NfEl.ARGUMENTS) { + if (current === '(') { + // -------------- + // argument start + // -------------- + + // consume the open paranthesis + stream.next(); + + // change context to handle an argument + state.context = NfEl.ARGUMENT; + + // start of arguments + return null; + } else if (current === ')') { + // -------------- + // argument close + // -------------- + + // consume the close paranthesis + stream.next(); + + // change context to subject for potential chaining + state.context = NfEl.SUBJECT; + + // end of arguments + return null; + } else if (current === ',') { + // ------------------ + // argument separator + // ------------------ + + // consume the comma + stream.next(); + + // change context back to argument + state.context = NfEl.ARGUMENT; + + // argument separator + return null; + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } + + // within a specific argument + if (state.context === NfEl.ARGUMENT) { + if (current === "'" || current === '"') { + // -------------- + // string literal + // -------------- + + // handle the string literal + const argumentStringResult: string | null = self.handleStringLiteral(stream, state); + + // successfully processed a string literal... + if (argumentStringResult !== null) { + // change context back to arguments + state.context = NfEl.ARGUMENTS; + } + + return argumentStringResult; + } else if ( + stream.match( + /^[-\+]?((([0-9]+\.[0-9]*)([eE][+-]?([0-9])+)?)|((\.[0-9]+)([eE][+-]?([0-9])+)?)|(([0-9]+)([eE][+-]?([0-9])+)))/ + ) + ) { + // ------------- + // Decimal value + // ------------- + // This matches the following ANTLR spec for deciamls + // + // DECIMAL : OP? ('0'..'9')+ '.' ('0'..'9')* EXP? ^([0-9]+\.[0-9]*)([eE][+-]?([0-9])+)? + // | OP? '.' ('0'..'9')+ EXP? + // | OP? ('0'..'9')+ EXP; + // + // fragment OP: ('+'|'-'); + // fragment EXP : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; + + // change context back to arguments + state.context = NfEl.ARGUMENTS; + + // style for decimal (use same as number) + return 'number'; + } else if (stream.match(/^[-\+]?[0-9]+/)) { + // ------------- + // integer value + // ------------- + + // change context back to arguments + state.context = NfEl.ARGUMENTS; + + // style for integers + return 'number'; + } else if (stream.match(/^((true)|(false))/)) { + // ------------- + // boolean value + // ------------- + + // change context back to arguments + state.context = NfEl.ARGUMENTS; + + // style for boolean (use same as number) + return 'number'; + } else if (current === ')') { + // ---------------------------------- + // argument close (zero arg function) + // ---------------------------------- + + // consume the close parenthesis + stream.next(); + + // change context to subject for potential chaining + state.context = NfEl.SUBJECT; + + // end of arguments + return null; + } else if (current === '$') { + // ----------------- + // nested expression + // ----------------- + + // handle the nested expression + const argumentDollarResult: string | null = self.handleStart( + '$', + NfEl.EXPRESSION, + stream, + states + ); + + // if we've found an embedded expression we need to... + if (argumentDollarResult !== null) { + // transition back to arguments when then expression completes + state.context = NfEl.ARGUMENTS; + } + + return argumentDollarResult; + } else if (current === '#' && self.parametersSupported) { + // -------------------------- + // nested parameter reference + // -------------------------- + + // handle the nested parameter reference + const parameterReferenceResult: string | null = self.handleStart( + '#', + NfEl.PARAMETER, + stream, + states + ); + + // if we've found an embedded parameter reference we need to... + if (parameterReferenceResult !== null) { + // transition back to arguments when this parameter reference completes + state.context = NfEl.ARGUMENTS; + } + + return parameterReferenceResult; + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } + + // within a parameter reference + if ( + state.context === NfEl.PARAMETER || + state.context === NfEl.SINGLE_QUOTE_PARAMETER || + state.context === NfEl.DOUBLE_QUOTE_PARAMETER + ) { + // attempt to extract a parameter name + const parameterName: string[] = stream.match(self.parameterKeyRegex, false); + + // if the result returned a match + if (parameterName !== null && parameterName.length === 1) { + // consume the entire token to ensure the whole function + // name is matched. this is an issue with functions like + // substring and substringAfter since 'substringA' would + // match the former and when we really want to autocomplete + // against the latter. + stream.match(self.parameterKeyRegex); + + // see if this matches a known function and is followed by ( + if (self.parameterRegex.test(parameterName[0])) { + // ------------------ + // resolved parameter + // ------------------ + + // style for function + return 'builtin'; + } else { + // -------------------- + // unresolved parameter + // -------------------- + + // style for function + return 'string'; + } + } + + if (state.context === NfEl.SINGLE_QUOTE_PARAMETER) { + return self.handleParameterEnd(stream, state, states, () => current === "'"); + } + + if (state.context === NfEl.DOUBLE_QUOTE_PARAMETER) { + return self.handleParameterEnd(stream, state, states, () => current === '"'); + } + + if (current === '}') { + // ----------------- + // end of expression + // ----------------- + + // consume the close + stream.next(); + + // signifies the end of an parameter reference + if (typeof states.pop() === 'undefined') { + return null; + } else { + // style as expression + return 'bracket'; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } + + // signifies the potential start of an expression + if (current === '$') { + return self.handleStart('$', NfEl.EXPRESSION, stream, states); + } + + // signifies the potential start of a parameter reference + if (current === '#' && self.parametersSupported) { + return self.handleStart('#', NfEl.PARAMETER, stream, states); + } + + // signifies the end of an expression + if (current === '}') { + stream.next(); + if (typeof states.pop() === 'undefined') { + return null; + } else { + return 'bracket'; + } + } + + // ---------------------------------------------------------- + // extra characters that are around expression[s] end up here + // ---------------------------------------------------------- + + // consume the character to keep things moving along + stream.next(); + return null; + } + }; + }); + } + + private parameterKeyRegex = /^[a-zA-Z0-9-_. ]+/; + + private parameters: string[] = []; + private parameterRegex = new RegExp('^$'); + + private parameterDetails: { [key: string]: Parameter } = {}; + private parametersSupported = false; + + private subjectlessFunctions: string[] = []; + private functions: string[] = []; + + private subjectlessFunctionRegex = new RegExp('^$'); + private functionRegex = new RegExp('^$'); + + private functionDetails: { [key: string]: ElFunction } = {}; + + // valid context states + private static readonly SUBJECT: string = 'subject'; + private static readonly FUNCTION: string = 'function'; + private static readonly SUBJECT_OR_FUNCTION: string = 'subject-or-function'; + private static readonly EXPRESSION: string = 'expression'; + private static readonly ARGUMENTS: string = 'arguments'; + private static readonly ARGUMENT: string = 'argument'; + private static readonly PARAMETER: string = 'parameter'; + private static readonly SINGLE_QUOTE_PARAMETER: string = 'single-quote-parameter'; + private static readonly DOUBLE_QUOTE_PARAMETER: string = 'double-quote-parameter'; + private static readonly INVALID: string = 'invalid'; + + /** + * Handles dollars identifies on the stream. + * + * @param {string} startChar The start character + * @param {string} context The context to transition to if we match on the specified start character + * @param {object} stream The character stream + * @param {object} states The states + */ + private handleStart(startChar: string, context: string, stream: StringStream, states: any): null | string { + // determine the number of sequential start chars + let startCharCount = 0; + stream.eatWhile(function (ch: string) { + if (ch === startChar) { + startCharCount++; + return true; + } + return false; + }); + + // if there is an even number of consecutive start chars this expression is escaped + if (startCharCount % 2 === 0) { + // do not style an escaped expression + return null; + } + + // if there was an odd number of consecutive start chars and there was more than 1 + if (startCharCount > 1) { + // back up one char so we can process the start sequence next iteration + stream.backUp(1); + + // do not style the preceding start chars + return null; + } + + // if the next character isn't the start of an expression + if (stream.peek() === '{') { + // consume the open curly + stream.next(); + + if (NfEl.PARAMETER === context) { + // there may be an optional single/double quote + if (stream.peek() === "'") { + // consume the single quote + stream.next(); + + // new expression start + states.push({ + context: NfEl.SINGLE_QUOTE_PARAMETER + }); + } else if (stream.peek() === '"') { + // consume the double quote + stream.next(); + + // new expression start + states.push({ + context: NfEl.DOUBLE_QUOTE_PARAMETER + }); + } else { + // new expression start + states.push({ + context: NfEl.PARAMETER + }); + } + } else { + // new expression start + states.push({ + context: context + }); + } + + // consume any addition whitespace + stream.eatSpace(); + + return 'bracket'; + } + // not a valid start sequence + return null; + } + + /** + * Handles dollars identifies on the stream. + * + * @param {StringStream} stream The character stream + * @param {object} state The current state + */ + private handleStringLiteral(stream: StringStream, state: any): string | null { + const current: string | null = stream.next(); + let foundTrailing = false; + let foundEscapeChar = false; + + // locate a closing string delimitor + const foundStringLiteral: boolean = stream.eatWhile(function (ch: string) { + // we've just found the trailing delimitor, stop + if (foundTrailing) { + return false; + } + + // if this is the trailing delimitor, only consume + // if we did not see the escape character on the + // previous iteration + if (ch === current) { + foundTrailing = !foundEscapeChar; + } + + // reset the escape character flag + foundEscapeChar = false; + + // if this is the escape character, set the flag + if (ch === '\\') { + foundEscapeChar = true; + } + + // consume this character + return true; + }); + + // if we found the trailing delimitor + if (foundStringLiteral) { + return 'string'; + } + + // there is no trailing delimitor... clear the current context + state.context = NfEl.INVALID; + stream.skipToEnd(); + return null; + } + + private handleParameterEnd( + stream: StringStream, + state: any, + states: any, + parameterPredicate: () => boolean + ): string | null { + if (parameterPredicate()) { + // consume the single/double quote + stream.next(); + + // verify the next character closes the parameter reference + if (stream.peek() === '}') { + // ----------------- + // end of expression + // ----------------- + + // consume the close + stream.next(); + + // signifies the end of a parameter reference + if (typeof states.pop() === 'undefined') { + return null; + } else { + // style as expression + return 'bracket'; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfEl.INVALID; + + // unexpected... + return null; + } + } + + public setViewContainerRef(viewContainerRef: ViewContainerRef, renderer: Renderer2): void { + this.viewContainerRef = viewContainerRef; + this.renderer = renderer; + } + + public configureAutocomplete(): void { + const self: NfEl = this; + + CodeMirror.commands.autocomplete = function (cm: Editor) { + CodeMirror.showHint(cm, function (editor: Editor) { + // Find the token at the cursor + const cursor: CodeMirror.Position = editor.getCursor(); + const token: CodeMirror.Token = editor.getTokenAt(cursor); + let includeAll = false; + const state = token.state.get(); + + // whether the current context is within a function + const isFunction = function (context: string): boolean { + // attempting to match a function name or already successfully matched a function name + return context === NfEl.FUNCTION || context === NfEl.ARGUMENTS; + }; + + // whether the current context is within a subject-less funciton + const isSubjectlessFunction = function (context: string): boolean { + // within an expression when no characters are found or when the string may be an attribute or a function + return context === NfEl.EXPRESSION || context === NfEl.SUBJECT_OR_FUNCTION; + }; + + // whether the current context is within a parameter reference + const isParameterReference = function (context: string): boolean { + // attempting to match a function name or already successfully matched a function name + return ( + context === NfEl.PARAMETER || + context === NfEl.SINGLE_QUOTE_PARAMETER || + context === NfEl.DOUBLE_QUOTE_PARAMETER + ); + }; + + // only support suggestion in certain cases + const context: string = state.context; + if (!isSubjectlessFunction(context) && !isFunction(context) && !isParameterReference(context)) { + return null; + } + + // lower case for case-insensitive comparison + const value: string = token.string.toLowerCase(); + + // trim to ignore extra whitespace + const trimmed: string = value.trim(); + + // identify potential patterns and increment the start location appropriately + if (trimmed === '${' || trimmed === ':' || trimmed === '#{' || trimmed === "#{'" || trimmed === '#{"') { + includeAll = true; + token.start += value.length; + } + + let options: string[] = self.functions; + let useFunctionDetails = true; + if (isSubjectlessFunction(context)) { + options = self.subjectlessFunctions; + } else if (isParameterReference(context)) { + options = self.parameters; + useFunctionDetails = false; + } + + const getCompletions = function (options: string[]): Hint[] { + const found: NfElHint[] = []; + + options.forEach((opt: string) => { + if (!found.some((item) => item.text == opt)) { + if (includeAll || opt.toLowerCase().indexOf(value) === 0) { + if (useFunctionDetails) { + found.push({ + text: opt, + functionDetails: self.functionDetails[opt], + render: function (element: HTMLElement, hints: Hints, data: any): void { + element.textContent = data.text; + } + }); + } else { + found.push({ + text: opt, + parameterDetails: self.parameterDetails[opt], + render: function (element: HTMLElement, hints: Hints, data: any): void { + element.textContent = data.text; + } + }); + } + } + } + }); + + return found; + }; + + // get the suggestions for the current context + let completionList: Hint[] = getCompletions(options); + completionList = completionList.sort((a, b) => { + return self.nifiCommon.compareString(a.text, b.text); + }); + + const completions: Hints = { + list: completionList, + from: { + line: cursor.line, + ch: token.start + }, + to: { + line: cursor.line, + ch: token.end + } + }; + + CodeMirror.on(completions, 'select', function (completion: any, element: any) { + if (self.viewContainerRef && self.renderer) { + const { x, y, width, height } = element.getBoundingClientRect(); + + // clear any existing tooltips + self.viewContainerRef.clear(); + + // create and configure the tooltip + let componentRef: ComponentRef | undefined; + if (completion.parameterDetails) { + componentRef = self.viewContainerRef.createComponent(ParameterTip); + componentRef.setInput('bottom', window.innerHeight - (y + height)); + componentRef.setInput('left', x + width + 20); + componentRef.setInput('data', { + parameter: completion.parameterDetails + }); + } else if (completion.functionDetails) { + componentRef = self.viewContainerRef.createComponent(ElFunctionTip); + componentRef.setInput('bottom', window.innerHeight - (y + height)); + componentRef.setInput('left', x + width + 20); + componentRef.setInput('data', { + elFunction: completion.functionDetails + }); + } + + if (componentRef) { + // move the newly created component, so it's co-located with the completion list... this + // is helpful when it comes to ensuring the tooltip is cleaned up appropriately + self.renderer.appendChild(element.parentElement, componentRef.location.nativeElement); + } + } + }); + CodeMirror.on(completions, 'close', function () { + self.viewContainerRef?.clear(); + }); + + return completions; + }); + }; + } + + /** + * Enables parameter referencing. + */ + public enableParameters(): void { + this.parameters = []; + this.parameterRegex = new RegExp('^$'); + this.parameterDetails = {}; + + this.parametersSupported = true; + } + + /** + * Sets the available parameters. + * + * @param parameterListing + */ + public setParameters(parameterListing: Parameter[]): void { + parameterListing.forEach((parameter) => { + this.parameters.push(parameter.name); + this.parameterDetails[parameter.name] = parameter; + }); + + this.parameterRegex = new RegExp('^((' + this.parameters.join(')|(') + '))$'); + } + + /** + * Disables parameter referencing. + */ + public disableParameters(): void { + this.parameters = []; + this.parameterRegex = new RegExp('^$'); + this.parameterDetails = {}; + + this.parametersSupported = false; + } + + /** + * Returns the language id. + * + * @returns {string} language id + */ + public getLanguageId(): string { + return 'nfel'; + } + + /** + * Returns whether this editor mode supports EL. + * + * @returns {boolean} Whether the editor supports EL + */ + public supportsEl(): boolean { + return true; + } + + /** + * Returns whether this editor mode supports parameter reference. + * + * @returns {boolean} Whether the editor supports parameter reference + */ + public supportsParameterReference(): boolean { + return this.parametersSupported; + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/nfpr.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/nfpr.ts new file mode 100644 index 0000000000..1f839a6d96 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/modes/nfpr.ts @@ -0,0 +1,509 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentRef, Injectable, Renderer2, ViewContainerRef } from '@angular/core'; +import { Editor, Hint, Hints, StringStream } from 'codemirror'; +import * as CodeMirror from 'codemirror'; +import { NiFiCommon, Parameter, ParameterTip } from '@nifi/shared'; + +@Injectable({ providedIn: 'root' }) +export class NfPr { + private viewContainerRef: ViewContainerRef | undefined; + private renderer: Renderer2 | undefined; + + constructor(private nifiCommon: NiFiCommon) { + const self: NfPr = this; + + CodeMirror.defineMode(this.getLanguageId(), function (): any { + // builds the states based off the specified initial value + const buildStates = function (initialStates: any) { + // each state has a context + const states = initialStates; + + return { + copy: function () { + const copy: any[] = []; + for (let i = 0; i < states.length; i++) { + copy.push({ + context: states[i].context + }); + } + return copy; + }, + get: function () { + if (states.length === 0) { + return { + context: null + }; + } else { + return states[states.length - 1]; + } + }, + push: function (state: any) { + return states.push(state); + }, + pop: function () { + return states.pop(); + } + }; + }; + + return { + startState: function () { + // build states with an empty array + return buildStates([]); + }, + + copyState: function (state: any) { + // build states with + return buildStates(state.copy()); + }, + + token: function (stream: StringStream, states: any) { + // consume any whitespace + if (stream.eatSpace()) { + return null; + } + + // if we've hit the end of the line + if (stream.eol()) { + return null; + } + + // get the current character + const current: string | null = stream.peek(); + + // get the current state + const state = states.get(); + + // the current input is invalid + if (state.context === NfPr.INVALID) { + stream.skipToEnd(); + return null; + } + + // within a parameter reference + if ( + state.context === NfPr.PARAMETER || + state.context === NfPr.SINGLE_QUOTE_PARAMETER || + state.context === NfPr.DOUBLE_QUOTE_PARAMETER + ) { + // attempt to extract a parameter name + const parameterName: string[] = stream.match(self.parameterKeyRegex, false); + + // if the result returned a match + if (parameterName !== null && parameterName.length === 1) { + // consume the entire token to ensure the whole function + // name is matched. this is an issue with functions like + // substring and substringAfter since 'substringA' would + // match the former and when we really want to autocomplete + // against the latter. + stream.match(self.parameterKeyRegex); + + // see if this matches a known function and is followed by ( + if (self.parameterRegex.test(parameterName[0])) { + // ------------------ + // resolved parameter + // ------------------ + + // style for function + return 'builtin'; + } else { + // -------------------- + // unresolved parameter + // -------------------- + + // style for function + return 'string'; + } + } + + if (state.context === NfPr.SINGLE_QUOTE_PARAMETER) { + return self.handleParameterEnd(stream, state, states, () => current === "'"); + } + + if (state.context === NfPr.DOUBLE_QUOTE_PARAMETER) { + return self.handleParameterEnd(stream, state, states, () => current === '"'); + } + + if (current === '}') { + // ----------------- + // end of expression + // ----------------- + + // consume the close + stream.next(); + + // signifies the end of a parameter reference + if (typeof states.pop() === 'undefined') { + return null; + } else { + // style as expression + return 'bracket'; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfPr.INVALID; + + // unexpected... + return null; + } + } + + // signifies the potential start of an expression + if (current === '#' && self.parametersSupported) { + return self.handlePound(stream, states); + } + + // signifies the end of an expression + if (current === '}') { + stream.next(); + if (typeof states.pop() === 'undefined') { + return null; + } else { + return 'bracket'; + } + } + + // ---------------------------------------------------------- + // extra characters that are around expression[s] end up here + // ---------------------------------------------------------- + + // consume the character to keep things moving along + stream.next(); + return null; + } + }; + }); + } + + private parameterKeyRegex = /^[a-zA-Z0-9-_. ]+/; + + private parameters: string[] = []; + private parameterRegex = new RegExp('^$'); + + private parameterDetails: { [key: string]: Parameter } = {}; + private parametersSupported = false; + + // valid context states + private static readonly PARAMETER: string = 'parameter'; + private static readonly SINGLE_QUOTE_PARAMETER: string = 'single-quote-parameter'; + private static readonly DOUBLE_QUOTE_PARAMETER: string = 'double-quote-parameter'; + private static readonly INVALID: string = 'invalid'; + + /** + * Handles pound identifies on the stream. + * + * @param {object} stream The character stream + * @param {object} states The states + */ + private handlePound(stream: StringStream, states: any): string | null { + // determine the number of sequential pounds + let poundCount = 0; + stream.eatWhile(function (ch: string): boolean { + if (ch === '#') { + poundCount++; + return true; + } + return false; + }); + + // if there is an even number of consecutive pounds this expression is escaped + if (poundCount % 2 === 0) { + // do not style an escaped expression + return null; + } + + // if there was an odd number of consecutive pounds and there was more than 1 + if (poundCount > 1) { + // back up one char so we can process the start sequence next iteration + stream.backUp(1); + + // do not style the preceding pounds + return null; + } + + // if the next character isn't the start of an expression + if (stream.peek() === '{') { + // consume the open curly + stream.next(); + + // there may be an optional single/double quote + if (stream.peek() === "'") { + // consume the single quote + stream.next(); + + // new expression start + states.push({ + context: NfPr.SINGLE_QUOTE_PARAMETER + }); + } else if (stream.peek() === '"') { + // consume the double quote + stream.next(); + + // new expression start + states.push({ + context: NfPr.DOUBLE_QUOTE_PARAMETER + }); + } else { + // new expression start + states.push({ + context: NfPr.PARAMETER + }); + } + + // consume any addition whitespace + stream.eatSpace(); + + return 'bracket'; + } else { + // not a valid start sequence + return null; + } + } + + private handleParameterEnd( + stream: StringStream, + state: any, + states: any, + parameterPredicate: () => boolean + ): string | null { + if (parameterPredicate()) { + // consume the single/double quote + stream.next(); + + // verify the next character closes the parameter reference + if (stream.peek() === '}') { + // ----------------- + // end of expression + // ----------------- + + // consume the close + stream.next(); + + // signifies the end of a parameter reference + if (typeof states.pop() === 'undefined') { + return null; + } else { + // style as expression + return 'bracket'; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfPr.INVALID; + + // unexpected... + return null; + } + } else { + // ---------- + // unexpected + // ---------- + + // consume and move along + stream.skipToEnd(); + state.context = NfPr.INVALID; + + // unexpected... + return null; + } + } + + public setViewContainerRef(viewContainerRef: ViewContainerRef, renderer: Renderer2): void { + this.viewContainerRef = viewContainerRef; + this.renderer = renderer; + } + + public configureAutocomplete(): void { + const self: NfPr = this; + + CodeMirror.commands.autocomplete = function (cm: Editor) { + CodeMirror.showHint(cm, function (editor: Editor) { + // Find the token at the cursor + const cursor: CodeMirror.Position = editor.getCursor(); + const token: CodeMirror.Token = editor.getTokenAt(cursor); + let includeAll = false; + const state = token.state.get(); + + // whether the current context is within a function + const isParameterContext = function (context: string) { + // attempting to match a function name or already successfully matched a function name + return ( + context === NfPr.PARAMETER || + context === NfPr.SINGLE_QUOTE_PARAMETER || + context === NfPr.DOUBLE_QUOTE_PARAMETER + ); + }; + + // only support suggestion in certain cases + const context = state.context; + if (!isParameterContext(context)) { + return null; + } + + // lower case for case-insensitive comparison + const value: string = token.string.toLowerCase(); + + // trim to ignore extra whitespace + const trimmed: string = value.trim(); + + // identify potential patterns and increment the start location appropriately + if (trimmed === '#{' || trimmed === "#{'" || trimmed === '#{"') { + includeAll = true; + token.start += value.length; + } + + const getCompletions = function (parameterList: string[]) { + const found: Hint[] = []; + + parameterList.forEach((parameter: string) => { + if (!found.some((item) => item.text == parameter)) { + if (includeAll || parameter.toLowerCase().indexOf(value) === 0) { + found.push({ + text: parameter, + render: function (element: HTMLElement, hints: Hints, data: any): void { + element.textContent = data.text; + } + }); + } + } + }); + + return found; + }; + + // get the suggestions for the current context + let completionList: any[] = getCompletions(self.parameters); + completionList = completionList.sort((a, b) => { + return self.nifiCommon.compareString(a.text, b.text); + }); + + const completions: any = { + list: completionList, + from: { + line: cursor.line, + ch: token.start + }, + to: { + line: cursor.line, + ch: token.end + } + }; + + CodeMirror.on(completions, 'select', function (completion: any, element: any) { + if (self.viewContainerRef && self.renderer) { + const { x, y, width, height } = element.getBoundingClientRect(); + + // clear any existing tooltips + self.viewContainerRef.clear(); + + // create and configure the tooltip + const componentRef: ComponentRef = + self.viewContainerRef.createComponent(ParameterTip); + componentRef.setInput('bottom', window.innerHeight - (y + height)); + componentRef.setInput('left', x + width + 20); + componentRef.setInput('data', { + parameter: self.parameterDetails[completion.text] + }); + + // move the newly created component, so it's co-located with the completion list... this + // is helpful when it comes to ensuring the tooltip is cleaned up appropriately + self.renderer.appendChild(element.parentElement, componentRef.location.nativeElement); + } + }); + CodeMirror.on(completions, 'close', function () { + self.viewContainerRef?.clear(); + }); + + return completions; + }); + }; + } + + /** + * Enables parameter referencing. + */ + public enableParameters(): void { + this.parameters = []; + this.parameterRegex = new RegExp('^$'); + this.parameterDetails = {}; + + this.parametersSupported = true; + } + + /** + * Sets the available parameters. + * + * @param parameterListing + */ + public setParameters(parameterListing: Parameter[]): void { + parameterListing.forEach((parameter: any) => { + this.parameters.push(parameter.name); + this.parameterDetails[parameter.name] = parameter; + }); + + this.parameterRegex = new RegExp('^((' + this.parameters.join(')|(') + '))$'); + } + + /** + * Disables parameter referencing. + */ + public disableParameters(): void { + this.parameters = []; + this.parameterRegex = new RegExp('^$'); + this.parameterDetails = {}; + + this.parametersSupported = false; + } + + /** + * Returns the language id. + * + * @returns {string} language id + */ + public getLanguageId(): string { + return 'nfpr'; + } + + /** + * Returns whether this editor mode supports EL. + * + * @returns {boolean} Whether the editor supports EL + */ + public supportsEl(): boolean { + return false; + } + + /** + * Returns whether this editor mode supports parameter reference. + * + * @returns {boolean} Whether the editor supports parameter reference + */ + public supportsParameterReference(): boolean { + return this.parametersSupported; + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.html new file mode 100644 index 0000000000..6de5fde7c5 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.html @@ -0,0 +1,63 @@ + + +
      +
      +
      +
      + +
      +
      +
      + +
      +
      +
      + @if (readonly) { + + } @else { + + + } +
      +
      +
      +
      diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.scss new file mode 100644 index 0000000000..4193b3d629 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.scss @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@use '@angular/material' as mat; + +.ua-editor { + @include mat.button-density(-1); + + min-height: 240px; + min-width: 245px; + max-height: 100vh; + max-width: 100vw; + cursor: move; +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.spec.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.spec.ts new file mode 100644 index 0000000000..c49e6dbdf2 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.spec.ts @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UaEditor } from './ua-editor.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { MockComponent } from 'ng-mocks'; +import { PropertyHint } from '@nifi/shared'; + +import 'codemirror/addon/hint/show-hint'; + +describe('UaEditor', () => { + let component: UaEditor; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [UaEditor, HttpClientTestingModule, MockComponent(PropertyHint)] + }); + fixture = TestBed.createComponent(UaEditor); + component = fixture.componentInstance; + }); + + it('should create', () => { + fixture.detectChanges(); + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.ts new file mode 100644 index 0000000000..b286103afe --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/pages/update-attribute/ui/ua-editor/ua-editor.component.ts @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, EventEmitter, Input, OnDestroy, Output, Renderer2, ViewContainerRef } from '@angular/core'; +import { CdkDrag } from '@angular/cdk/drag-drop'; +import { AbstractControl, FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { Resizable, PropertyHint } from '@nifi/shared'; +import { A11yModule } from '@angular/cdk/a11y'; +import { CodemirrorModule } from '@ctrl/ngx-codemirror'; +import { Editor } from 'codemirror'; +import { NfEl } from './modes/nfel'; + +@Component({ + selector: 'ua-editor', + standalone: true, + templateUrl: './ua-editor.component.html', + imports: [ + CdkDrag, + ReactiveFormsModule, + MatDialogModule, + MatInputModule, + MatButtonModule, + MatCheckboxModule, + A11yModule, + CodemirrorModule, + Resizable, + PropertyHint + ], + styleUrls: ['./ua-editor.component.scss'] +}) +export class UaEditor implements OnDestroy { + @Input() set value(value: string) { + this.uaEditorForm.get('value')?.setValue(value); + } + @Input() supportsEl: boolean = false; + @Input() set required(required: boolean) { + this.isRequired = required; + + if (this.isRequired) { + this.uaEditorForm.get('value')?.setValidators([Validators.required]); + } else { + this.uaEditorForm.get('value')?.clearValidators(); + } + } + + @Input() width!: number; + @Input() readonly: boolean = false; + + @Output() ok: EventEmitter = new EventEmitter(); + @Output() cancel: EventEmitter = new EventEmitter(); + + isRequired: boolean = true; + + uaEditorForm: FormGroup; + editor!: Editor; + + constructor( + private formBuilder: FormBuilder, + private viewContainerRef: ViewContainerRef, + private renderer: Renderer2, + private nfel: NfEl + ) { + this.uaEditorForm = this.formBuilder.group({ + value: new FormControl('') + }); + + if (this.isRequired) { + this.uaEditorForm.get('value')?.setValidators([Validators.required]); + } + + this.nfel.setViewContainerRef(this.viewContainerRef, this.renderer); + this.nfel.configureAutocomplete(); + } + + codeMirrorLoaded(codeEditor: any): void { + this.editor = codeEditor.codeMirror; + + if (!this.readonly) { + this.editor.focus(); + this.editor.execCommand('selectAll'); + } + } + + getOptions(): { [p: string]: any } { + const options: { [p: string]: any } = { + readOnly: this.readonly, + lineNumbers: true, + theme: 'nifi', + matchBrackets: true, + extraKeys: { + Enter: () => { + if (this.uaEditorForm.dirty && this.uaEditorForm.valid) { + this.okClicked(); + } + } + } + }; + + if (this.supportsEl) { + options['mode'] = this.nfel.getLanguageId(); + options['extraKeys'] = { + 'Ctrl-Space': 'autocomplete', + ...options['extraKeys'] + }; + } + + return options; + } + + resized(event: any): void { + // Note: We calculate the height of the codemirror to fit into an `.ua-editor` overlay. The + // height of the codemirror needs to be set in order to handle large amounts of text in the codemirror editor. + // The height of the codemirror should be the height of the `.ua-editor` overlay minus the 132px of spacing + // needed to display the EL and Param tooltips, the 'Set Empty String' checkbox, the action buttons, + // and the resize handle. If the amount of spacing needed for additional UX is needed for the `.ua-editor` is + // changed then this value should also be updated. + this.editor.setSize('100%', event.height - 132); + } + + preventDrag(event: MouseEvent): void { + event.stopPropagation(); + } + + okClicked(): void { + const valueControl: AbstractControl | null = this.uaEditorForm.get('value'); + if (valueControl) { + this.ok.next(valueControl.value); + } + } + + cancelClicked(): void { + this.cancel.next(); + } + + ngOnDestroy(): void { + this.nfel.disableParameters(); + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/state/index.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/state/index.ts new file mode 100644 index 0000000000..442bfb6bd7 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/app/state/index.ts @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { routerReducer, RouterReducerState, DEFAULT_ROUTER_FEATURENAME } from '@ngrx/router-store'; +import { ActionReducerMap } from '@ngrx/store'; + +export interface UpdateAttributeApplicationState { + [DEFAULT_ROUTER_FEATURENAME]: RouterReducerState; +} + +export const rootReducers: ActionReducerMap = { + [DEFAULT_ROUTER_FEATURENAME]: routerReducer +}; diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/environments/environment.development.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/environments/environment.development.ts new file mode 100644 index 0000000000..584182e1d9 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/environments/environment.development.ts @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const environment = { + production: false +}; diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/environments/environment.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/environments/environment.ts new file mode 100644 index 0000000000..29d7aa9df3 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/environments/environment.ts @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const environment = { + production: true +}; diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/index.html b/nifi-frontend/src/main/frontend/apps/update-attribute/src/index.html new file mode 100644 index 0000000000..a82901d6fe --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/index.html @@ -0,0 +1,29 @@ + + + + + + + Update Attribute + + + + + + + diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/main.ts b/nifi-frontend/src/main/frontend/apps/update-attribute/src/main.ts new file mode 100644 index 0000000000..99cc54c60d --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/main.ts @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +import 'codemirror/addon/edit/matchbrackets'; +import 'codemirror/addon/fold/brace-fold'; +import 'codemirror/addon/fold/foldcode'; +import 'codemirror/addon/fold/foldgutter'; +import 'codemirror/addon/hint/show-hint'; + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/src/styles.scss b/nifi-frontend/src/main/frontend/apps/update-attribute/src/styles.scss new file mode 100644 index 0000000000..987de451f0 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/src/styles.scss @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Custom Theming for Angular Material +// For more information: https://v16.material.angular.io/guide/theming-your-components +@use '@angular/material' as mat; +@use 'sass:map'; +@use 'libs/shared/src/assets/styles/app' as app; +@use 'libs/shared/src/assets/styles/codemirror-theme' as codemirror-theme; +@use 'libs/shared/src/assets/styles/listing-table' as listing-table; +@use 'app/pages/update-attribute/ui/rule-listing/rule-listing.component-theme' as rule-listing; +@use 'app/pages/update-attribute/ui/ua-editor/ua-editor.component-theme' as ua-editor; +@use 'libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component-theme' as property-hint-tip; + +// Plus imports for other components in your app. +@use 'libs/shared/src/assets/fonts/flowfont/flowfont.css'; +@use 'codemirror/lib/codemirror.css'; +@use 'codemirror/addon/fold/foldgutter.css'; +@use 'codemirror/addon/hint/show-hint.css'; + +@import 'font-awesome'; +@import 'libs/shared/src/assets/themes/material'; + +// Include the common styles for Angular Material. We include this here so that you only +// have to load a single css file for Angular Material in your app. +// Be sure that you only ever include this mixin once! +@include mat.core(); + +@tailwind base; +@tailwind components; +@tailwind utilities; + +// only include these once (not needed for dark mode) +@include app.styles(); +@include listing-table.styles(); + +html { + @include mat.typography-hierarchy($m3-light-theme); + @include mat.all-component-themes($m3-light-theme); + @include app.generate-material-theme($m3-light-theme, $m3-light-theme-config); + @include listing-table.generate-theme($m3-light-theme, $m3-light-theme-config); + @include codemirror-theme.generate-codemirror-theme($m3-light-theme, $m3-light-theme-config); + @include rule-listing.generate-theme($m3-light-theme, $m3-light-theme-config); + @include ua-editor.generate-theme(); + @include property-hint-tip.generate-theme($m3-light-theme, $m3-light-theme-config); + + .dark-theme { + @include mat.all-component-colors($m3-dark-theme); + @include app.generate-material-theme($m3-dark-theme, $m3-dark-theme-config); + @include listing-table.generate-theme($m3-dark-theme, $m3-dark-theme-config); + @include codemirror-theme.generate-codemirror-theme($m3-dark-theme, $m3-dark-theme-config); + @include rule-listing.generate-theme($m3-dark-theme, $m3-dark-theme-config); + @include ua-editor.generate-theme(); + @include property-hint-tip.generate-theme($m3-dark-theme, $m3-dark-theme-config); + } +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/tailwind.config.js b/nifi-frontend/src/main/frontend/apps/update-attribute/tailwind.config.js new file mode 100644 index 0000000000..52c0148d7e --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/tailwind.config.js @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); +const baseTheme = require('../../libs/shared/tailwind.theme.json'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), ...createGlobPatternsForDependencies(__dirname)], + theme: { + ...baseTheme + }, + plugins: [] +}; diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.app.json b/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.app.json new file mode 100644 index 0000000000..8b1485b791 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.app.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/app", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"] +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.json b/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.json new file mode 100644 index 0000000000..31519cd103 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "useDefineForClassFields": false + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + }, + "extends": "../../tsconfig.base.json" +} diff --git a/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.spec.json b/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.spec.json new file mode 100644 index 0000000000..ad652198e3 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/update-attribute/tsconfig.spec.json @@ -0,0 +1,11 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jest"], + "module": "ES2022", + "esModuleInterop": true + }, + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/component-context/component-context.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/component-context/component-context.component.ts index 0788dcb6c4..ec18fe2822 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/components/component-context/component-context.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/component-context/component-context.component.ts @@ -17,8 +17,8 @@ import { Component, Input } from '@angular/core'; import { ComponentTypeNamePipe } from '../../pipes/component-type-name.pipe'; -import { ComponentType } from '../../index'; -import { CopyDirective } from '../../directives/index'; +import { ComponentType } from '../../types'; +import { CopyDirective } from '../../directives/copy/copy.directive'; @Component({ selector: 'component-context', diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts index 642ee0104b..10886bf7aa 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/index.ts @@ -17,9 +17,13 @@ export * from './close-on-escape-dialog/close-on-escape-dialog.component'; export * from './component-context/component-context.component'; -export * from './map-table/editors/text-editor/text-editor.component'; export * from './map-table/map-table.component'; export * from './copy-button/copy-button.component'; export * from './new-map-table-entry-dialog/new-map-table-entry-dialog.component'; +export * from './property-hint/property-hint.component'; export * from './resizable/resizable.component'; +export * from './yes-no-dialog/yes-no-dialog.component'; +export * from './tooltips/el-function-tip/el-function-tip.component'; +export * from './tooltips/parameter-tip/parameter-tip.component'; +export * from './tooltips/property-hint-tip/property-hint-tip.component'; export * from './tooltips/text-tip/text-tip.component'; diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/editors/text-editor/text-editor.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/editors/text-editor/text-editor.component.ts index 4cc4b01a0c..527de7bf8d 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/editors/text-editor/text-editor.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/editors/text-editor/text-editor.component.ts @@ -24,9 +24,8 @@ import { CdkTrapFocus } from '@angular/cdk/a11y'; import { CodemirrorModule } from '@ctrl/ngx-codemirror'; import { MatButton } from '@angular/material/button'; import { MatCheckbox } from '@angular/material/checkbox'; -import { NifiTooltipDirective } from '../../../../directives'; import { Resizable } from '../../../resizable/resizable.component'; -import { MapTableItem } from '../../../../index'; +import { MapTableItem } from '../../../../types'; @Component({ selector: 'text-editor', @@ -38,7 +37,6 @@ import { MapTableItem } from '../../../../index'; CodemirrorModule, MatButton, MatCheckbox, - NifiTooltipDirective, ReactiveFormsModule, Resizable ], diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/map-table.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/map-table.component.ts index 100b5feb87..51f30c886e 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/map-table.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/map-table.component.ts @@ -53,8 +53,10 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatIconButton } from '@angular/material/button'; import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu'; import { TextEditor } from './editors/text-editor/text-editor.component'; -import { NifiTooltipDirective } from '../../directives'; -import { MapTableEntry, MapTableItem, NiFiCommon, TextTip } from '../../index'; +import { NifiTooltipDirective } from '../../directives/nifi-tooltip.directive'; +import { NiFiCommon } from '../../services/nifi-common.service'; +import { TextTip } from '../tooltips/text-tip/text-tip.component'; +import { MapTableEntry, MapTableItem } from '../../types'; @Component({ selector: 'map-table', diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/new-map-table-entry-dialog/new-map-table-entry-dialog.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/new-map-table-entry-dialog/new-map-table-entry-dialog.component.ts index 013089500d..3f9374c369 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/components/new-map-table-entry-dialog/new-map-table-entry-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/new-map-table-entry-dialog/new-map-table-entry-dialog.component.ts @@ -39,7 +39,7 @@ import { MatButton } from '@angular/material/button'; import { MatError, MatFormField, MatLabel } from '@angular/material/form-field'; import { MatInput } from '@angular/material/input'; import { MatRadioButton, MatRadioGroup } from '@angular/material/radio'; -import { MapTableEntryData } from '../../index'; +import { MapTableEntryData } from '../../types'; @Component({ selector: 'new-map-table-entry-dialog', diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.html b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.html new file mode 100644 index 0000000000..f9766fd25a --- /dev/null +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.html @@ -0,0 +1,40 @@ + + +
      +
      +
      EL
      + +
      + @if (showParameters) { +
      +
      PARAM
      + +
      + } +
      + +
      +
      + +
      +
      diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.scss b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.scss new file mode 100644 index 0000000000..04742f53ed --- /dev/null +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.scss @@ -0,0 +1,20 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.property-hint { + cursor: default; +} diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.spec.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.spec.ts new file mode 100644 index 0000000000..49c2c1a59d --- /dev/null +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.spec.ts @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PropertyHint } from './property-hint.component'; + +describe('PropertyHint', () => { + let component: PropertyHint; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PropertyHint] + }).compileComponents(); + + fixture = TestBed.createComponent(PropertyHint); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.ts new file mode 100644 index 0000000000..2ea7c00a5d --- /dev/null +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/property-hint/property-hint.component.ts @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, Input } from '@angular/core'; +import { PropertyHintTip } from '../tooltips/property-hint-tip/property-hint-tip.component'; +import { NgTemplateOutlet } from '@angular/common'; +import { NifiTooltipDirective } from '../../directives/nifi-tooltip.directive'; +import { PropertyHintTipInput } from '../../types'; + +@Component({ + selector: 'property-hint', + standalone: true, + imports: [NgTemplateOutlet, NifiTooltipDirective], + templateUrl: './property-hint.component.html', + styleUrl: './property-hint.component.scss' +}) +export class PropertyHint { + @Input() supportsEl: boolean = true; + @Input() showParameters: boolean = true; + @Input() supportsParameters: boolean = true; + @Input() hasParameterContext: boolean = false; + + preventDrag(event: MouseEvent): void { + event.stopPropagation(); + } + + getPropertyHintTipData(): PropertyHintTipInput { + return { + supportsEl: this.supportsEl, + showParameters: this.showParameters, + supportsParameters: this.supportsParameters, + hasParameterContext: this.hasParameterContext + }; + } + + protected readonly PropertyHintTip = PropertyHintTip; +} diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.html b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.html similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.html rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.html diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.scss b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.scss similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.scss rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.scss diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.spec.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.spec.ts similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.spec.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.spec.ts diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.ts similarity index 85% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.ts index 963fb19741..df379de0ff 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.ts @@ -16,16 +16,13 @@ */ import { Component, Input } from '@angular/core'; - -import { ElFunction, ElFunctionTipInput } from '../../../../state/shared'; -import { NiFiCommon } from '@nifi/shared'; -import { ControllerServiceApi } from '../../controller-service/controller-service-api/controller-service-api.component'; +import { NiFiCommon } from '../../../services/nifi-common.service'; +import { ElFunction, ElFunctionTipInput } from '../../../types'; @Component({ selector: 'el-function-tip', standalone: true, templateUrl: './el-function-tip.component.html', - imports: [ControllerServiceApi], styleUrls: ['./el-function-tip.component.scss'] }) export class ElFunctionTip { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.html b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.html similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.html rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.html diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.scss b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.scss similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.scss rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.scss diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.spec.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.spec.ts similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.spec.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.spec.ts diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.ts similarity index 82% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.ts index 6bf57094db..cc98fda8a4 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/parameter-tip/parameter-tip.component.ts @@ -16,16 +16,13 @@ */ import { Component, Input } from '@angular/core'; - -import { Parameter, ParameterTipInput } from '../../../../state/shared'; -import { NiFiCommon } from '@nifi/shared'; -import { ControllerServiceApi } from '../../controller-service/controller-service-api/controller-service-api.component'; +import { NiFiCommon } from '../../../services/nifi-common.service'; +import { Parameter, ParameterTipInput } from '../../../types'; @Component({ selector: 'parameter-tip', standalone: true, templateUrl: './parameter-tip.component.html', - imports: [ControllerServiceApi], styleUrls: ['./parameter-tip.component.scss'] }) export class ParameterTip { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/_property-hint-tip.component-theme.scss b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/_property-hint-tip.component-theme.scss similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/_property-hint-tip.component-theme.scss rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/_property-hint-tip.component-theme.scss diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.html b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.html similarity index 94% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.html rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.html index 8914f78e08..5be859d094 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.html +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.html @@ -18,7 +18,10 @@
      - + @if (data?.showParameters) { + + }
      diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.scss b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.scss similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.scss rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.scss diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.spec.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.spec.ts similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.spec.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.spec.ts diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.ts similarity index 82% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.ts index 115a4e07c7..4186d1d4d6 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/property-hint-tip/property-hint-tip.component.ts @@ -17,14 +17,13 @@ import { Component, Input } from '@angular/core'; import { NgTemplateOutlet } from '@angular/common'; -import { PropertyHintTipInput } from '../../../../state/shared'; -import { ControllerServiceApi } from '../../controller-service/controller-service-api/controller-service-api.component'; +import { PropertyHintTipInput } from '../../../types'; @Component({ selector: 'property-hint-tip', standalone: true, templateUrl: './property-hint-tip.component.html', - imports: [ControllerServiceApi, NgTemplateOutlet], + imports: [NgTemplateOutlet], styleUrls: ['./property-hint-tip.component.scss'] }) export class PropertyHintTip { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.html b/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.html similarity index 100% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.html rename to nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.html diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.scss b/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.scss new file mode 100644 index 0000000000..2944f98194 --- /dev/null +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.scss @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.spec.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.spec.ts similarity index 95% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.spec.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.spec.ts index 2be02b9a4c..c1b6caace5 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.spec.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.spec.ts @@ -17,9 +17,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { YesNoDialog } from './yes-no-dialog.component'; +import { YesNoDialog, YesNoDialogRequest } from '../..'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { YesNoDialogRequest } from '../../../state/shared'; import { By } from '@angular/platform-browser'; describe('YesNoDialog', () => { diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.ts b/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.ts similarity index 91% rename from nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.ts rename to nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.ts index 5a877a8c6b..3a98c5e11a 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/yes-no-dialog/yes-no-dialog.component.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/components/yes-no-dialog/yes-no-dialog.component.ts @@ -17,9 +17,9 @@ import { Component, EventEmitter, Inject, Output } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; -import { YesNoDialogRequest } from '../../../state/shared'; import { MatButtonModule } from '@angular/material/button'; -import { CloseOnEscapeDialog } from '@nifi/shared'; +import { CloseOnEscapeDialog } from '../close-on-escape-dialog/close-on-escape-dialog.component'; +import { YesNoDialogRequest } from '../../types'; @Component({ selector: 'yes-no-dialog', diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/directives/copy/copy.directive.spec.ts b/nifi-frontend/src/main/frontend/libs/shared/src/directives/copy/copy.directive.spec.ts index 4f911cba8b..78f1a09b7e 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/directives/copy/copy.directive.spec.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/directives/copy/copy.directive.spec.ts @@ -30,10 +30,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; class TestComponent { copyText = 'copied value'; } + describe('CopyDirective', () => { let component: TestComponent; let fixture: ComponentFixture; let directiveDebugEl: any; + beforeEach(() => { TestBed.configureTestingModule({ imports: [CopyDirective, TestComponent] @@ -43,9 +45,11 @@ describe('CopyDirective', () => { fixture.detectChanges(); directiveDebugEl = fixture.debugElement.query(By.directive(CopyDirective)); }); + afterEach(() => { jest.restoreAllMocks(); }); + it('should create a copy button on mouse enter', () => { directiveDebugEl.triggerEventHandler('mouseenter', null); fixture.detectChanges(); @@ -53,6 +57,7 @@ describe('CopyDirective', () => { expect(copyButton).not.toBeNull(); expect(copyButton?.classList).toContain('fa-copy'); }); + it('should remove the copy button on mouse leave', () => { directiveDebugEl.triggerEventHandler('mouseenter', null); fixture.detectChanges(); @@ -61,7 +66,8 @@ describe('CopyDirective', () => { const copyButton = directiveDebugEl.nativeElement.querySelector('.copy-button'); expect(copyButton).toBeNull(); }); - it('should copy text to clipboard and change button appearance on click', async () => { + + xit('should copy text to clipboard and change button appearance on click', async () => { // Mock the clipboard's writeText method Object.assign(navigator, { clipboard: { @@ -79,6 +85,7 @@ describe('CopyDirective', () => { expect(copyButton?.classList).toContain('fa-check'); expect(copyButton?.classList).toContain('success-color-default'); }); + it('should unsubscribe from events on mouse leave', () => { directiveDebugEl.triggerEventHandler('mouseenter', null); fixture.detectChanges(); diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/directives/nifi-tooltip.directive.ts b/nifi-frontend/src/main/frontend/libs/shared/src/directives/nifi-tooltip.directive.ts index 0a4d7c50f4..e9c9e72c86 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/directives/nifi-tooltip.directive.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/directives/nifi-tooltip.directive.ts @@ -18,7 +18,7 @@ import { Directive, ElementRef, HostListener, Input, OnDestroy, Type } from '@angular/core'; import { ConnectedPosition, Overlay, OverlayRef, PositionStrategy } from '@angular/cdk/overlay'; import { ComponentPortal } from '@angular/cdk/portal'; -import { NiFiCommon } from '../services'; +import { NiFiCommon } from '../services/nifi-common.service'; @Directive({ selector: '[nifiTooltip]', diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/index.ts b/nifi-frontend/src/main/frontend/libs/shared/src/index.ts index e97c896e75..4d19bd96ea 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/index.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/index.ts @@ -15,93 +15,9 @@ * limitations under the License. */ -import { MatDialogConfig } from '@angular/material/dialog'; -import { filter, Observable } from 'rxjs'; - -export const SMALL_DIALOG: MatDialogConfig = { - maxWidth: '24rem', - minWidth: 320, - disableClose: true, - closeOnNavigation: false -}; -export const MEDIUM_DIALOG: MatDialogConfig = { - maxWidth: 470, - minWidth: 470, - disableClose: true, - closeOnNavigation: false -}; -export const LARGE_DIALOG: MatDialogConfig = { - maxWidth: 760, - minWidth: 760, - disableClose: true, - closeOnNavigation: false -}; -export const XL_DIALOG: MatDialogConfig = { - maxWidth: 1024, - minWidth: 1024, - disableClose: true, - closeOnNavigation: false -}; - -export enum ComponentType { - Processor = 'Processor', - ProcessGroup = 'ProcessGroup', - RemoteProcessGroup = 'RemoteProcessGroup', - InputPort = 'InputPort', - OutputPort = 'OutputPort', - Label = 'Label', - Funnel = 'Funnel', - Connection = 'Connection', - ControllerService = 'ControllerService', - ReportingTask = 'ReportingTask', - FlowAnalysisRule = 'FlowAnalysisRule', - ParameterProvider = 'ParameterProvider', - FlowRegistryClient = 'FlowRegistryClient', - Flow = 'Flow' -} - -export interface SelectGroup { - text: string; - options: SelectOption[]; -} - -export interface SelectOption { - text: string; - value: string | null; - description?: string; - disabled?: boolean; -} - -export interface MapTableEntry { - name: string; - value: string | null; -} - -export interface MapTableItem { - entry: MapTableEntry; - id: number; - triggerEdit: boolean; - deleted: boolean; - dirty: boolean; - added: boolean; -} - -export interface MapTableEntryData { - existingEntries: string[]; - entryTypeLabel?: string; -} - -export function isDefinedAndNotNull() { - return (source$: Observable) => - source$.pipe( - filter((input: null | undefined | T): input is T => { - return input !== null && typeof input !== 'undefined'; - }) - ); -} - export * from './components'; export * from './directives'; export * from './pipes'; export * from './services'; export * from './state'; +export * from './types'; diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/pipes/component-type-name.pipe.ts b/nifi-frontend/src/main/frontend/libs/shared/src/pipes/component-type-name.pipe.ts index 939d81b614..5ce2cea550 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/pipes/component-type-name.pipe.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/pipes/component-type-name.pipe.ts @@ -16,7 +16,7 @@ */ import { Pipe, PipeTransform } from '@angular/core'; -import { ComponentType } from '../index'; +import { ComponentType } from '../types'; @Pipe({ name: 'componentTypeName', diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/services/map-table-helper.service.ts b/nifi-frontend/src/main/frontend/libs/shared/src/services/map-table-helper.service.ts index b70e0bbe1e..fdbb399cc1 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/services/map-table-helper.service.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/services/map-table-helper.service.ts @@ -18,7 +18,8 @@ import { Injectable } from '@angular/core'; import { Observable, of, switchMap, takeUntil } from 'rxjs'; import { MatDialog } from '@angular/material/dialog'; -import { MapTableEntry, MapTableEntryData, NewMapTableEntryDialog, SMALL_DIALOG } from '../index'; +import { NewMapTableEntryDialog } from '../components/new-map-table-entry-dialog/new-map-table-entry-dialog.component'; +import { MapTableEntry, MapTableEntryData, SMALL_DIALOG } from '../types'; @Injectable({ providedIn: 'root' diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/services/nifi-common.service.ts b/nifi-frontend/src/main/frontend/libs/shared/src/services/nifi-common.service.ts index 9035bf2a89..7eeb87575e 100644 --- a/nifi-frontend/src/main/frontend/libs/shared/src/services/nifi-common.service.ts +++ b/nifi-frontend/src/main/frontend/libs/shared/src/services/nifi-common.service.ts @@ -16,7 +16,7 @@ */ import { Injectable } from '@angular/core'; -import { SelectOption } from '../index'; +import { SelectOption } from '../types'; @Injectable({ providedIn: 'root' diff --git a/nifi-frontend/src/main/frontend/libs/shared/src/types/index.ts b/nifi-frontend/src/main/frontend/libs/shared/src/types/index.ts new file mode 100644 index 0000000000..6defbab008 --- /dev/null +++ b/nifi-frontend/src/main/frontend/libs/shared/src/types/index.ts @@ -0,0 +1,216 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { MatDialogConfig } from '@angular/material/dialog'; +import { filter, Observable } from 'rxjs'; + +export const SMALL_DIALOG: MatDialogConfig = { + maxWidth: '24rem', + minWidth: 320, + disableClose: true, + closeOnNavigation: false +}; +export const MEDIUM_DIALOG: MatDialogConfig = { + maxWidth: 470, + minWidth: 470, + disableClose: true, + closeOnNavigation: false +}; +export const LARGE_DIALOG: MatDialogConfig = { + maxWidth: 760, + minWidth: 760, + disableClose: true, + closeOnNavigation: false +}; +export const XL_DIALOG: MatDialogConfig = { + maxWidth: 1024, + minWidth: 1024, + disableClose: true, + closeOnNavigation: false +}; + +export enum ComponentType { + Processor = 'Processor', + ProcessGroup = 'ProcessGroup', + RemoteProcessGroup = 'RemoteProcessGroup', + InputPort = 'InputPort', + OutputPort = 'OutputPort', + Label = 'Label', + Funnel = 'Funnel', + Connection = 'Connection', + ControllerService = 'ControllerService', + ReportingTask = 'ReportingTask', + FlowAnalysisRule = 'FlowAnalysisRule', + ParameterProvider = 'ParameterProvider', + FlowRegistryClient = 'FlowRegistryClient', + Flow = 'Flow' +} + +export interface SelectGroup { + text: string; + options: SelectOption[]; +} + +export interface SelectOption { + text: string; + value: string | null; + description?: string; + disabled?: boolean; +} + +export interface MapTableEntry { + name: string; + value: string | null; +} + +export interface MapTableItem { + entry: MapTableEntry; + id: number; + triggerEdit: boolean; + deleted: boolean; + dirty: boolean; + added: boolean; +} + +export interface MapTableEntryData { + existingEntries: string[]; + entryTypeLabel?: string; +} + +export interface PropertyHintTipInput { + supportsEl: boolean; + showParameters: boolean; + supportsParameters: boolean; + hasParameterContext: boolean; +} + +export interface ElFunction { + name: string; + description: string; + args: { [key: string]: string }; + subject?: string; + returnType: string; +} + +export interface Parameter { + name: string; + description: string; + sensitive: boolean; + value: string | null; + valueRemoved?: boolean; + provided?: boolean; + referencingComponents?: AffectedComponentEntity[]; + parameterContext?: ParameterContextReferenceEntity; + inherited?: boolean; + referencedAssets?: ReferencedAsset[]; +} + +export interface AffectedComponentEntity { + permissions: Permissions; + id: string; + revision: Revision; + bulletins: BulletinEntity[]; + component: AffectedComponent; + processGroup: ProcessGroupName; + referenceType: string; +} + +export interface ParameterContextReferenceEntity { + permissions: Permissions; + id: string; + component?: ParameterContextReference; + bulletins?: BulletinEntity[]; +} + +export interface ParameterContextReference { + id: string; + name: string; +} + +export interface AffectedComponent { + processGroupId: string; + id: string; + referenceType: string; + name: string; + state: string; + activeThreadCount?: number; + validationErrors: string[]; +} + +export interface ReferencedAsset { + id: string; + name: string; +} + +export interface Permissions { + canRead: boolean; + canWrite: boolean; +} + +export interface Revision { + version: number; + clientId?: string; + lastModifier?: string; +} + +export interface BulletinEntity { + canRead: boolean; + id: number; + sourceId: string; + groupId: string; + timestamp: string; + nodeAddress?: string; + bulletin: { + id: number; + sourceId: string; + groupId: string; + category: string; + level: string; + message: string; + sourceName: string; + timestamp: string; + nodeAddress?: string; + sourceType: string; + }; +} + +export interface ProcessGroupName { + id: string; + name: string; +} + +export interface ParameterTipInput { + parameter: Parameter; +} + +export interface ElFunctionTipInput { + elFunction: ElFunction; +} + +export interface YesNoDialogRequest { + title: string; + message: string; +} + +export function isDefinedAndNotNull() { + return (source$: Observable) => + source$.pipe( + filter((input: null | undefined | T): input is T => { + return input !== null && typeof input !== 'undefined'; + }) + ); +}