openc3 5.8.1 → 5.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/ext/openc3/ext/crc/crc.c +1 -1
  3. data/lib/openc3/api/cmd_api.rb +1 -1
  4. data/lib/openc3/microservices/decom_microservice.rb +10 -2
  5. data/lib/openc3/microservices/reaction_microservice.rb +152 -81
  6. data/lib/openc3/microservices/timeline_microservice.rb +1 -1
  7. data/lib/openc3/microservices/trigger_group_microservice.rb +188 -118
  8. data/lib/openc3/migrations/20230615000000_autonomic.rb +86 -0
  9. data/lib/openc3/models/activity_model.rb +2 -4
  10. data/lib/openc3/models/microservice_model.rb +6 -2
  11. data/lib/openc3/models/model.rb +1 -3
  12. data/lib/openc3/models/reaction_model.rb +124 -119
  13. data/lib/openc3/models/scope_model.rb +15 -3
  14. data/lib/openc3/models/timeline_model.rb +1 -3
  15. data/lib/openc3/models/trigger_group_model.rb +16 -50
  16. data/lib/openc3/models/trigger_model.rb +86 -123
  17. data/lib/openc3/packets/json_packet.rb +2 -3
  18. data/lib/openc3/script/commands.rb +10 -0
  19. data/lib/openc3/script/script.rb +1 -0
  20. data/lib/openc3/top_level.rb +0 -12
  21. data/lib/openc3/utilities/authorization.rb +1 -1
  22. data/lib/openc3/utilities/bucket_require.rb +5 -1
  23. data/lib/openc3/utilities/bucket_utilities.rb +4 -1
  24. data/lib/openc3/utilities/cli_generator.rb +56 -4
  25. data/lib/openc3/utilities/ruby_lex_utils.rb +4 -0
  26. data/lib/openc3/version.rb +6 -6
  27. data/templates/plugin/README.md +54 -4
  28. data/templates/plugin/Rakefile +31 -3
  29. data/templates/tool_angular/.editorconfig +16 -0
  30. data/templates/tool_angular/.gitignore +44 -0
  31. data/templates/tool_angular/.vscode/extensions.json +4 -0
  32. data/templates/tool_angular/.vscode/launch.json +20 -0
  33. data/templates/tool_angular/.vscode/tasks.json +42 -0
  34. data/templates/tool_angular/angular.json +111 -0
  35. data/templates/tool_angular/extra-webpack.config.js +8 -0
  36. data/templates/tool_angular/package.json +47 -0
  37. data/templates/tool_angular/src/app/app-routing.module.ts +15 -0
  38. data/templates/tool_angular/src/app/app.component.html +31 -0
  39. data/templates/tool_angular/src/app/app.component.scss +26 -0
  40. data/templates/tool_angular/src/app/app.component.spec.ts +29 -0
  41. data/templates/tool_angular/src/app/app.component.ts +51 -0
  42. data/templates/tool_angular/src/app/app.module.ts +30 -0
  43. data/templates/tool_angular/src/app/custom-overlay-container.ts +17 -0
  44. data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +7 -0
  45. data/templates/tool_angular/src/app/openc3-api.d.ts +1 -0
  46. data/templates/tool_angular/src/assets/.gitkeep +0 -0
  47. data/templates/tool_angular/src/environments/environment.prod.ts +3 -0
  48. data/templates/tool_angular/src/environments/environment.ts +16 -0
  49. data/templates/tool_angular/src/favicon.ico +0 -0
  50. data/templates/tool_angular/src/index.html +13 -0
  51. data/templates/tool_angular/src/main.single-spa.ts +40 -0
  52. data/templates/tool_angular/src/single-spa/asset-url.ts +12 -0
  53. data/templates/tool_angular/src/single-spa/single-spa-props.ts +8 -0
  54. data/templates/tool_angular/src/styles.scss +1 -0
  55. data/templates/tool_angular/tsconfig.app.json +13 -0
  56. data/templates/tool_angular/tsconfig.json +33 -0
  57. data/templates/tool_angular/tsconfig.spec.json +14 -0
  58. data/templates/tool_angular/yarn.lock +8080 -0
  59. data/templates/tool_react/.eslintrc +7 -0
  60. data/templates/tool_react/.gitignore +72 -0
  61. data/templates/tool_react/.prettierignore +8 -0
  62. data/templates/tool_react/babel.config.json +29 -0
  63. data/templates/tool_react/jest.config.js +12 -0
  64. data/templates/tool_react/package.json +53 -0
  65. data/templates/tool_react/src/openc3-tool_name.js +24 -0
  66. data/templates/tool_react/src/root.component.js +88 -0
  67. data/templates/tool_react/src/root.component.test.js +9 -0
  68. data/templates/tool_react/webpack.config.js +27 -0
  69. data/templates/tool_react/yarn.lock +6854 -0
  70. data/templates/tool_svelte/.gitignore +72 -0
  71. data/templates/tool_svelte/.prettierignore +8 -0
  72. data/templates/tool_svelte/babel.config.js +12 -0
  73. data/templates/tool_svelte/build/smui.css +5 -0
  74. data/templates/tool_svelte/jest.config.js +9 -0
  75. data/templates/tool_svelte/package.json +46 -0
  76. data/templates/tool_svelte/rollup.config.js +72 -0
  77. data/templates/tool_svelte/src/App.svelte +42 -0
  78. data/templates/tool_svelte/src/App.test.js +9 -0
  79. data/templates/tool_svelte/src/services/api.js +92 -0
  80. data/templates/tool_svelte/src/services/axios.js +85 -0
  81. data/templates/tool_svelte/src/services/cable.js +65 -0
  82. data/templates/tool_svelte/src/services/config-parser.js +199 -0
  83. data/templates/tool_svelte/src/services/openc3-api.js +647 -0
  84. data/templates/tool_svelte/src/theme/_smui-theme.scss +25 -0
  85. data/templates/tool_svelte/src/tool_name.js +17 -0
  86. data/templates/tool_svelte/yarn.lock +5052 -0
  87. data/templates/tool_vue/.browserslistrc +16 -0
  88. data/templates/tool_vue/.env.standalone +1 -0
  89. data/templates/tool_vue/.eslintrc.js +43 -0
  90. data/templates/tool_vue/.gitignore +2 -0
  91. data/templates/tool_vue/.nycrc +3 -0
  92. data/templates/tool_vue/.prettierrc.js +5 -0
  93. data/templates/tool_vue/babel.config.json +11 -0
  94. data/templates/tool_vue/jsconfig.json +6 -0
  95. data/templates/tool_vue/package.json +52 -0
  96. data/templates/tool_vue/src/App.vue +15 -0
  97. data/templates/tool_vue/src/main.js +38 -0
  98. data/templates/tool_vue/src/router.js +29 -0
  99. data/templates/tool_vue/src/tools/tool_name/tool_name.vue +63 -0
  100. data/templates/tool_vue/vue.config.js +30 -0
  101. data/templates/tool_vue/yarn.lock +9145 -0
  102. data/templates/widget/package.json +9 -9
  103. data/templates/widget/yarn.lock +77 -73
  104. metadata +76 -2
@@ -18,7 +18,7 @@
18
18
 
19
19
  module OpenC3
20
20
  class CliGenerator
21
- GENERATORS = %w(plugin target microservice widget conversion limits_response)
21
+ GENERATORS = %w(plugin target microservice widget conversion limits_response tool tool_vue tool_angular tool_react tool_svelte)
22
22
  TEMPLATES_DIR = "#{File.dirname(__FILE__)}/../../../templates"
23
23
 
24
24
  # Called by openc3cli with ARGV[1..-1]
@@ -27,18 +27,18 @@ module OpenC3
27
27
  abort("Unknown generator '#{args[0]}'. Valid generators: #{GENERATORS.join(', ')}")
28
28
  end
29
29
  check_args(args)
30
- send("generate_#{args[0]}", args)
30
+ send("generate_#{args[0].to_s.downcase.gsub('-', '_')}", args)
31
31
  end
32
32
 
33
33
  def self.check_args(args)
34
34
  args.each do |arg|
35
35
  if arg =~ /\s/
36
- abort("#{args[0].capitalize} arguments can not have spaces!")
36
+ abort("#{args[0].to_s.downcase} arguments can not have spaces!") unless args[0].to_s.downcase[0..3] == 'tool'
37
37
  end
38
38
  end
39
39
  # All generators except 'plugin' must be within an existing plugin
40
40
  if args[0] != 'plugin' and Dir.glob("*.gemspec").empty?
41
- abort("No gemspec file detected. #{args[0].capitalize} generator should be run within an existing plugin.")
41
+ abort("No gemspec file detected. #{args[0].to_s.downcase} generator should be run within an existing plugin.")
42
42
  end
43
43
  end
44
44
 
@@ -199,6 +199,58 @@ module OpenC3
199
199
  return widget_name
200
200
  end
201
201
 
202
+ def self.generate_tool(args)
203
+ if args.length != 2
204
+ abort("Usage: cli generate #{args[0]} 'Tool Name'")
205
+ end
206
+
207
+ # Create the local variables
208
+ tool_type = args[0].to_s.downcase.gsub('-', '_')
209
+ tool_type = 'tool_vue' if tool_type == 'tool'
210
+ tool_name_display = args[1]
211
+ tool_name = args[1].to_s.downcase.gsub('-', '').gsub(' ', '')
212
+ tool_path = "tools/#{tool_name}"
213
+ if File.exist?(tool_path)
214
+ abort("Tool #{tool_path} already exists!")
215
+ end
216
+ skip_package = false
217
+ if File.exist?('package.json')
218
+ puts "package.json already exists ... you'll have to manually add this tool and its dependencies"
219
+ skip_package = true
220
+ end
221
+
222
+ process_template("#{TEMPLATES_DIR}/#{tool_type}", binding) do |filename|
223
+ if skip_package && filename == 'package.json'
224
+ true # causes the block to skip processing this file
225
+ elsif filename.include?('node_modules')
226
+ true
227
+ else
228
+ filename.gsub!("tool_name", tool_name)
229
+ false
230
+ end
231
+ end
232
+
233
+ # Add this tool to plugin.txt
234
+ js_file = 'main.js'
235
+ js_file = 'js/app.js' if tool_type == 'tool_vue'
236
+ File.open("plugin.txt", 'a') do |file|
237
+ file.puts <<~DOC
238
+
239
+ TOOL #{tool_name} "#{tool_name_display}"
240
+ INLINE_URL #{js_file}
241
+ ICON mdi-file-cad-box
242
+ DOC
243
+ end
244
+
245
+ puts "Tool #{tool_name} successfully generated!"
246
+ puts "Please be sure #{tool_name} does not conflict with any other tools"
247
+ return tool_name
248
+ end
249
+ self.singleton_class.send(:alias_method, :generate_tool_vue, :generate_tool)
250
+ self.singleton_class.send(:alias_method, :generate_tool_react, :generate_tool)
251
+ self.singleton_class.send(:alias_method, :generate_tool_angular, :generate_tool)
252
+ self.singleton_class.send(:alias_method, :generate_tool_svelte, :generate_tool)
253
+
202
254
  def self.generate_conversion(args)
203
255
  if args.length != 3
204
256
  abort("Usage: cli generate conversion <TARGET> <NAME>")
@@ -283,7 +283,10 @@ class RubyLexUtils
283
283
  yield line, !contains_keyword?(line), inside_begin, lex.exp_line_no
284
284
  line = ''
285
285
  lex.exp_line_no = lex.line_no
286
+ # puts "clear line 1"
286
287
  lex.line = ''
288
+ previous_line_indent = indent
289
+ continue_indent = nil
287
290
  next
288
291
  end
289
292
  end
@@ -327,6 +330,7 @@ class RubyLexUtils
327
330
  end
328
331
  line = ''
329
332
  lex.exp_line_no = lex.line_no
333
+ # puts "clear line 2"
330
334
  lex.line = ''
331
335
  break
332
336
  end # loop do
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '5.8.1'
3
+ OPENC3_VERSION = '5.9.0'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '5'
7
- MINOR = '8'
8
- PATCH = '1'
7
+ MINOR = '9'
8
+ PATCH = '0'
9
9
  OTHER = ''
10
- BUILD = 'aa0bd75b6940b719d0fb32814365abd9e0aa6397'
10
+ BUILD = '7ad48e4189eb35c8a08051cc9856d0bd8be27f60'
11
11
  end
12
- VERSION = '5.8.1'
13
- GEM_VERSION = '5.8.1'
12
+ VERSION = '5.9.0'
13
+ GEM_VERSION = '5.9.0'
14
14
  end
@@ -2,15 +2,65 @@
2
2
 
3
3
  See the [OpenC3](https://openc3.com) documentation for all things OpenC3.
4
4
 
5
- ## Building the plugin
5
+ Update this comment with your own description.
6
6
 
7
- 1. <Path to COSMOS installation>\openc3.bat cli rake build VERSION=X.Y.Z
7
+ ## Getting Started
8
+
9
+ 1. Edit the .gemspec file fields: name, summary, description, authors, email, and homepage
10
+ 1. Update the LICENSE.txt file with your company name
11
+
12
+ ## Building non-tool / widget plugins
13
+
14
+ 1. <Path to COSMOS installation>/openc3.sh cli rake build VERSION=X.Y.Z (or openc3.bat for Windows)
8
15
  - VERSION is required
9
16
  - gem file will be built locally
10
17
 
11
- ## Upload plugin
18
+ ## Building tool / widget plugins using a local Ruby/Node/Yarn/Rake Environment
19
+
20
+ 1. yarn
21
+ 1. rake build VERSION=1.0.0
22
+
23
+ ## Building tool / widget plugins using Docker and the openc3-node container
24
+
25
+ If you don’t have a local node environment, you can use our openc3-node container to build custom tools and custom widgets
26
+
27
+ Mac / Linux:
28
+
29
+ ```
30
+ docker run -it -v `pwd`:/openc3/local:z -w /openc3/local docker.io/openc3inc/openc3-node sh
31
+ ```
32
+
33
+ Windows:
34
+
35
+ ```
36
+ docker run -it -v %cd%:/openc3/local -w /openc3/local docker.io/openc3inc/openc3-node sh
37
+ ```
12
38
 
13
- 1. Go to localhost:2900/tools/admin
39
+ 1. yarn
40
+ 1. rake build VERSION=1.0.0
41
+
42
+ ## Installing into OpenC3 COSMOS
43
+
44
+ 1. Go to the OpenC3 Admin Tool, Plugins Tab
14
45
  1. Click the paperclip icon and choose your plugin.gem file
15
46
  1. Fill out plugin parameters
16
47
  1. Click Install
48
+
49
+ ## Contributing
50
+
51
+ We encourage you to contribute to OpenC3!
52
+
53
+ Contributing is easy.
54
+
55
+ 1. Fork the project
56
+ 2. Create a feature branch
57
+ 3. Make your changes
58
+ 4. Submit a pull request
59
+
60
+ Before any contributions can be incorporated we do require all contributors to agree to a Contributor License Agreement
61
+
62
+ This protects both you and us and you retain full rights to any code you write.
63
+
64
+ ## License
65
+
66
+ This OpenC3 plugin is released under the MIT License. See [LICENSE.txt](LICENSE.txt)
@@ -7,11 +7,39 @@ task :require_version do
7
7
  end
8
8
  end
9
9
 
10
+ # Note: The sh command is built into Rake:
11
+ # https://rubydoc.info/gems/rake/FileUtils#sh-instance_method
10
12
  task :build => [:require_version] do
11
- # The sh command is built into Rake:
12
- # https://rubydoc.info/gems/rake/FileUtils#sh-instance_method
13
+ _, platform, *_ = RUBY_PLATFORM.split("-")
14
+ if platform == 'mswin32' or platform == 'mingw32'
15
+ puts "Warning: Building gem on Windows will lose file permissions"
16
+ end
17
+
18
+ # Run yarn build if we have a package.json
19
+ if File.exist?('package.json')
20
+ sh('yarn run build') do |ok, status|
21
+ raise "yarn run build failed" if !ok
22
+ end
23
+ end
24
+
25
+ split_version = ENV['VERSION'].to_s.split('.')
26
+ major = split_version[0]
27
+ minor = split_version[1]
28
+ if ENV['VERSION'] =~ /[a-zA-Z]+/
29
+ # Prerelease version
30
+ remainder = split_version[2..-1].join(".")
31
+ remainder.gsub!('-', '.pre.') # Rubygems replaces dashes with .pre.
32
+ remainder_split = remainder.split('.')
33
+ patch = remainder_split[0]
34
+ other = remainder_split[1..-1].join('.')
35
+ gem_version = "#{major}.#{minor}.#{patch}.#{other}"
36
+ else
37
+ gem_version = ENV['VERSION']
38
+ end
39
+ gem_name = PLUGIN_NAME + '-' + gem_version + '.gem'
40
+
13
41
  sh('gem', 'build', PLUGIN_NAME)
14
- sh('openc3cli validate *.gem') do |ok, status|
42
+ sh("openc3cli validate #{gem_name}") do |ok, status|
15
43
  if !ok && status.exitstatus == 127 # command not found
16
44
  puts "Install the openc3 gem to validate! (gem install openc3)"
17
45
  end
@@ -0,0 +1,16 @@
1
+ # Editor configuration, see https://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ indent_style = space
7
+ indent_size = 2
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.ts]
12
+ quote_type = single
13
+
14
+ [*.md]
15
+ max_line_length = off
16
+ trim_trailing_whitespace = false
@@ -0,0 +1,44 @@
1
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
2
+
3
+ # Compiled output
4
+ /dist
5
+ /tmp
6
+ /out-tsc
7
+ /bazel-out
8
+
9
+ # Node
10
+ /node_modules
11
+ npm-debug.log
12
+ yarn-error.log
13
+
14
+ # IDEs and editors
15
+ .idea/
16
+ .project
17
+ .classpath
18
+ .c9/
19
+ *.launch
20
+ .settings/
21
+ *.sublime-workspace
22
+
23
+ # Visual Studio Code
24
+ .vscode/*
25
+ !.vscode/settings.json
26
+ !.vscode/tasks.json
27
+ !.vscode/launch.json
28
+ !.vscode/extensions.json
29
+ .history/*
30
+
31
+ # Miscellaneous
32
+ /.angular/cache
33
+ .sass-cache/
34
+ /connect.lock
35
+ /coverage
36
+ /libpeerconnection.log
37
+ testem.log
38
+ /typings
39
+
40
+ # System files
41
+ .DS_Store
42
+ Thumbs.db
43
+
44
+ tools/*
@@ -0,0 +1,4 @@
1
+ {
2
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3
+ "recommendations": ["angular.ng-template"]
4
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3
+ "version": "0.2.0",
4
+ "configurations": [
5
+ {
6
+ "name": "ng serve",
7
+ "type": "chrome",
8
+ "request": "launch",
9
+ "preLaunchTask": "npm: start",
10
+ "url": "http://localhost:4200/"
11
+ },
12
+ {
13
+ "name": "ng test",
14
+ "type": "chrome",
15
+ "request": "launch",
16
+ "preLaunchTask": "npm: test",
17
+ "url": "http://localhost:9876/debug.html"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
3
+ "version": "2.0.0",
4
+ "tasks": [
5
+ {
6
+ "type": "npm",
7
+ "script": "start",
8
+ "isBackground": true,
9
+ "problemMatcher": {
10
+ "owner": "typescript",
11
+ "pattern": "$tsc",
12
+ "background": {
13
+ "activeOnStart": true,
14
+ "beginsPattern": {
15
+ "regexp": "(.*?)"
16
+ },
17
+ "endsPattern": {
18
+ "regexp": "bundle generation complete"
19
+ }
20
+ }
21
+ }
22
+ },
23
+ {
24
+ "type": "npm",
25
+ "script": "test",
26
+ "isBackground": true,
27
+ "problemMatcher": {
28
+ "owner": "typescript",
29
+ "pattern": "$tsc",
30
+ "background": {
31
+ "activeOnStart": true,
32
+ "beginsPattern": {
33
+ "regexp": "(.*?)"
34
+ },
35
+ "endsPattern": {
36
+ "regexp": "bundle generation complete"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ]
42
+ }
@@ -0,0 +1,111 @@
1
+ {
2
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+ "version": 1,
4
+ "newProjectRoot": "projects",
5
+ "projects": {
6
+ "openc3-tool-<%= tool_name %>": {
7
+ "projectType": "application",
8
+ "schematics": {
9
+ "@schematics/angular:component": {
10
+ "style": "scss"
11
+ }
12
+ },
13
+ "root": "",
14
+ "sourceRoot": "src",
15
+ "prefix": "openc3-tool-<%= tool_name %>",
16
+ "architect": {
17
+ "build": {
18
+ "builder": "@angular-builders/custom-webpack:browser",
19
+ "options": {
20
+ "outputPath": "tools/<%= tool_name %>",
21
+ "index": "src/index.html",
22
+ "main": "src/main.single-spa.ts",
23
+ "polyfills": [
24
+ "zone.js"
25
+ ],
26
+ "tsConfig": "tsconfig.app.json",
27
+ "inlineStyleLanguage": "scss",
28
+ "assets": [
29
+ "src/favicon.ico",
30
+ "src/assets"
31
+ ],
32
+ "styles": [
33
+ "src/styles.scss"
34
+ ],
35
+ "scripts": [],
36
+ "customWebpackConfig": {
37
+ "path": "extra-webpack.config.js",
38
+ "libraryName": "openc3-tool-<%= tool_name %>",
39
+ "libraryTarget": "system"
40
+ },
41
+ "deployUrl": "/tools/<%= tool_name %>"
42
+ },
43
+ "configurations": {
44
+ "production": {
45
+ "budgets": [
46
+ {
47
+ "type": "initial",
48
+ "maximumWarning": "500kb",
49
+ "maximumError": "1mb"
50
+ },
51
+ {
52
+ "type": "anyComponentStyle",
53
+ "maximumWarning": "150kb",
54
+ "maximumError": "150kb"
55
+ }
56
+ ],
57
+ "outputHashing": "none"
58
+ },
59
+ "development": {
60
+ "buildOptimizer": false,
61
+ "optimization": false,
62
+ "vendorChunk": true,
63
+ "extractLicenses": false,
64
+ "sourceMap": true,
65
+ "namedChunks": true,
66
+ "outputHashing": "none"
67
+ }
68
+ },
69
+ "defaultConfiguration": "production"
70
+ },
71
+ "serve": {
72
+ "builder": "@angular-builders/custom-webpack:dev-server",
73
+ "configurations": {
74
+ "production": {
75
+ "browserTarget": "openc3-tool-<%= tool_name %>:build:production"
76
+ },
77
+ "development": {
78
+ "browserTarget": "openc3-tool-<%= tool_name %>:build:development"
79
+ }
80
+ },
81
+ "defaultConfiguration": "development"
82
+ },
83
+ "extract-i18n": {
84
+ "builder": "@angular-devkit/build-angular:extract-i18n",
85
+ "options": {
86
+ "browserTarget": "openc3-tool-<%= tool_name %>:build"
87
+ }
88
+ },
89
+ "test": {
90
+ "builder": "@angular-devkit/build-angular:karma",
91
+ "options": {
92
+ "polyfills": [
93
+ "zone.js",
94
+ "zone.js/testing"
95
+ ],
96
+ "tsConfig": "tsconfig.spec.json",
97
+ "inlineStyleLanguage": "scss",
98
+ "assets": [
99
+ "src/favicon.ico",
100
+ "src/assets"
101
+ ],
102
+ "styles": [
103
+ "src/styles.scss"
104
+ ],
105
+ "scripts": []
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,8 @@
1
+ const singleSpaAngularWebpack = require('single-spa-angular/lib/webpack').default;
2
+
3
+ module.exports = (config, options) => {
4
+ const singleSpaWebpackConfig = singleSpaAngularWebpack(config, options);
5
+
6
+ // Feel free to modify this webpack config however you'd like to
7
+ return singleSpaWebpackConfig;
8
+ };
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "<%= tool_name %>",
3
+ "version": "5.9.0",
4
+ "scripts": {
5
+ "ng": "ng",
6
+ "start": "ng serve",
7
+ "build": "ng build",
8
+ "watch": "ng build --watch --configuration development",
9
+ "test": "ng test",
10
+ "build:single-spa:openc3-tool-template-angular": "ng build openc3-tool-<%= tool_name %> --configuration production",
11
+ "serve:single-spa:openc3-tool-template-angular": "ng s --project openc3-tool-<%= tool_name %> --disable-host-check --port 4200 --live-reload false"
12
+ },
13
+ "private": true,
14
+ "dependencies": {
15
+ "@angular/animations": "^16.1.3",
16
+ "@angular/cdk": "^16.1.3",
17
+ "@angular/common": "^16.1.3",
18
+ "@angular/compiler": "^16.1.3",
19
+ "@angular/core": "^16.1.3",
20
+ "@angular/forms": "^16.1.3",
21
+ "@angular/material": "16.1.3",
22
+ "@angular/platform-browser": "^16.1.3",
23
+ "@angular/platform-browser-dynamic": "^16.1.3",
24
+ "@angular/router": "^16.1.3",
25
+ "@openc3/tool-common": "5.9.0",
26
+ "rxjs": "~7.8.0",
27
+ "single-spa": ">=5.9.5",
28
+ "single-spa-angular": "^8.1.0",
29
+ "tslib": "^2.6.0",
30
+ "zone.js": "~0.13.1"
31
+ },
32
+ "devDependencies": {
33
+ "@angular-builders/custom-webpack": "16.0.0",
34
+ "@angular-devkit/build-angular": "^16.0.5",
35
+ "@angular/cli": "~16.1.3",
36
+ "@angular/compiler-cli": "^16.0.0",
37
+ "@types/jasmine": "~4.3.0",
38
+ "jasmine-core": "~5.0.1",
39
+ "karma": "~6.4.0",
40
+ "karma-chrome-launcher": "~3.2.0",
41
+ "karma-coverage": "~2.2.0",
42
+ "karma-jasmine": "~5.1.0",
43
+ "karma-jasmine-html-reporter": "~2.1.0",
44
+ "style-loader": "^3.3.1",
45
+ "typescript": "~5.1.6"
46
+ }
47
+ }
@@ -0,0 +1,15 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { RouterModule, Routes } from '@angular/router';
3
+ import {APP_BASE_HREF} from '@angular/common';
4
+ import { EmptyRouteComponent } from './empty-route/empty-route.component';
5
+
6
+ const routes: Routes = [
7
+ { path: '**', component: EmptyRouteComponent }
8
+ ];
9
+
10
+ @NgModule({
11
+ imports: [RouterModule.forRoot(routes)],
12
+ exports: [RouterModule],
13
+ providers: [{ provide: APP_BASE_HREF, useValue: '/tools/<%= tool_name %>' }]
14
+ })
15
+ export class AppRoutingModule { }
@@ -0,0 +1,31 @@
1
+ <!-- This menu position hack should only be necessary in the portal -->
2
+ <style>
3
+ ::ng-deep .mat-mdc-menu-panel.myMenu {
4
+ background-color:white;
5
+ color:black;
6
+ position:absolute !important;
7
+ top:0px;
8
+ left:60px;
9
+ }
10
+
11
+ .mat-mdc-card {
12
+ background: white;
13
+ }
14
+ </style>
15
+
16
+ <div class="content" role="main">
17
+
18
+ <mat-card color="accent">
19
+ <mat-card-content><button mat-raised-button color="primary" (click)="clickHandler()">Send Command</button></mat-card-content>
20
+ </mat-card>
21
+
22
+ <ng-template cdk-portal>
23
+ <button mat-raised-button [matMenuTriggerFor]="menu">File</button>
24
+ <mat-menu #menu="matMenu" class="myMenu">
25
+ <button mat-menu-item (click)="clickHandler()">Send Command</button>
26
+ </mat-menu>
27
+ <div style="display: inline-block; width: 80%; text-align: center"><%= tool_name_display %></div>
28
+ </ng-template>
29
+ </div>
30
+
31
+ <router-outlet></router-outlet>
@@ -0,0 +1,26 @@
1
+ @use '@angular/material' as mat;
2
+
3
+ @include mat.core();
4
+
5
+ // Define a dark theme
6
+ $dark-theme: mat.define-dark-theme((
7
+ color: (
8
+ primary: mat.define-palette(mat.$blue-palette),
9
+ accent: mat.define-palette(mat.$blue-grey-palette),
10
+ ),
11
+ // Only include `typography` and `density` in the default dark theme.
12
+ typography: mat.define-typography-config(),
13
+ density: 0,
14
+ ));
15
+
16
+ // Define a light theme
17
+ $light-theme: mat.define-light-theme((
18
+ color: (
19
+ primary: mat.define-palette(mat.$indigo-palette),
20
+ accent: mat.define-palette(mat.$pink-palette),
21
+ ),
22
+ ));
23
+
24
+ // Apply the dark theme by default
25
+ @include mat.core-theme($dark-theme);
26
+ @include mat.button-theme($dark-theme);
@@ -0,0 +1,29 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { RouterTestingModule } from '@angular/router/testing';
3
+ import { AppComponent } from './app.component';
4
+
5
+ describe('AppComponent', () => {
6
+ beforeEach(() => TestBed.configureTestingModule({
7
+ imports: [RouterTestingModule],
8
+ declarations: [AppComponent]
9
+ }));
10
+
11
+ it('should create the app', () => {
12
+ const fixture = TestBed.createComponent(AppComponent);
13
+ const app = fixture.componentInstance;
14
+ expect(app).toBeTruthy();
15
+ });
16
+
17
+ it(`should have as title 'openc3-tool-<%= tool_name %>'`, () => {
18
+ const fixture = TestBed.createComponent(AppComponent);
19
+ const app = fixture.componentInstance;
20
+ expect(app.title).toEqual('openc3-tool-<%= tool_name %>');
21
+ });
22
+
23
+ it('should render title', () => {
24
+ const fixture = TestBed.createComponent(AppComponent);
25
+ fixture.detectChanges();
26
+ const compiled = fixture.nativeElement as HTMLElement;
27
+ expect(compiled.querySelector('.content span')?.textContent).toContain('openc3-tool-<%= tool_name %> app is running!');
28
+ });
29
+ });