added openmct plugin and embedding
This commit is contained in:
parent
93be82f416
commit
8b8619dd8a
8
http.go
8
http.go
|
@ -69,6 +69,10 @@ func extractLimitModifier(r *http.Request) (*LimitOffsetModifier, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RouterMod func (chi.Router)
|
||||||
|
var RouterMods = []RouterMod{}
|
||||||
|
|
||||||
|
|
||||||
func TelemRouter(log *slog.Logger, broker *Broker, db *TelemDb) http.Handler {
|
func TelemRouter(log *slog.Logger, broker *Broker, db *TelemDb) http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
@ -84,6 +88,9 @@ func TelemRouter(log *slog.Logger, broker *Broker, db *TelemDb) http.Handler {
|
||||||
|
|
||||||
r.Mount("/api/v1", apiV1(broker, db))
|
r.Mount("/api/v1", apiV1(broker, db))
|
||||||
|
|
||||||
|
for _, mod := range RouterMods {
|
||||||
|
mod(r)
|
||||||
|
}
|
||||||
// To future residents - you can add new API calls/systems in /api/v2
|
// To future residents - you can add new API calls/systems in /api/v2
|
||||||
// Don't break anything in api v1! keep legacy code working!
|
// Don't break anything in api v1! keep legacy code working!
|
||||||
|
|
||||||
|
@ -301,3 +308,4 @@ func apiV1GetRecord(db *TelemDb) http.HandlerFunc {
|
||||||
func apiV1UpdateRecord(db *TelemDb) http.HandlerFunc {
|
func apiV1UpdateRecord(db *TelemDb) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {}
|
return func(w http.ResponseWriter, r *http.Request) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
openmct.go
Normal file
29
openmct.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
//go:build openmct
|
||||||
|
package gotelem
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// this package provides a web router for the statif openmct build.
|
||||||
|
// it should only be included if the build has been run,
|
||||||
|
// to do so, run npm install and then npm run build.
|
||||||
|
|
||||||
|
//go:embed web/dist
|
||||||
|
var public embed.FS
|
||||||
|
|
||||||
|
func OpenMCTRouter(r chi.Router) {
|
||||||
|
// strip the subdirectory
|
||||||
|
pfs, _ := fs.Sub(public, "web/dist")
|
||||||
|
|
||||||
|
// default route.
|
||||||
|
r.Handle("/*", http.FileServerFS(pfs))
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RouterMods = append(RouterMods, OpenMCTRouter)
|
||||||
|
}
|
131
web/.gitignore
vendored
Normal file
131
web/.gitignore
vendored
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
8710
web/package-lock.json
generated
Normal file
8710
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
30
web/package.json
Normal file
30
web/package.json
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "g1_openmct",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "dev environment for openmct plugins for g1 strategy tool",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"build": "webpack",
|
||||||
|
"serve": "webpack serve"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"dotenv-webpack": "^8.0.1",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"openmct": "^2.0.5",
|
||||||
|
"socket.io": "^4.6.0",
|
||||||
|
"socket.io-client": "^4.6.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
|
"eslint": "^8.28.0",
|
||||||
|
"html-webpack-plugin": "^5.5.0",
|
||||||
|
"ts-loader": "^9.4.2",
|
||||||
|
"typescript": "^4.9.5",
|
||||||
|
"webpack": "^5.75.0",
|
||||||
|
"webpack-cli": "^5.0.1",
|
||||||
|
"webpack-dev-server": "^4.11.1"
|
||||||
|
}
|
||||||
|
}
|
12
web/src/app.js
Normal file
12
web/src/app.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import openmct from 'openmct';
|
||||||
|
import PhoebusPlugin from "./phoebusPlugin";
|
||||||
|
openmct.setAssetPath('openmct');
|
||||||
|
openmct.install(openmct.plugins.LocalStorage());
|
||||||
|
openmct.install(openmct.plugins.MyItems());
|
||||||
|
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||||
|
openmct.time.clock('local', {start: -5 * 60 * 1000, end: 0});
|
||||||
|
openmct.time.timeSystem('utc');
|
||||||
|
openmct.install(openmct.plugins.Espresso());
|
||||||
|
openmct.install(PhoebusPlugin());
|
||||||
|
|
||||||
|
openmct.start();
|
11
web/src/index.html
Normal file
11
web/src/index.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Open MCT Tutorials</title>
|
||||||
|
<script src="openmct/openmct.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
243
web/src/phoebusPlugin.js
Normal file
243
web/src/phoebusPlugin.js
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
// import openmct from "openmct";
|
||||||
|
import {_} from "lodash";
|
||||||
|
import { io } from "socket.io-client";
|
||||||
|
// Pho
|
||||||
|
function PhoebusObjectProvider(identifier) {
|
||||||
|
// console.log("obj provider", identifier)
|
||||||
|
const board_regex = /^board\.([a-z-_]+)$/
|
||||||
|
const packet_regex = /^board\.([a-z-_]+)\.([a-z-_]+)$/
|
||||||
|
const data_field_regex = /^board\.([a-z-_]+)\.([a-z-_]+)\.([a-z-_]+)$/ // board.wavesculptor.wsl_heatsink_motor_temp.motor_temp
|
||||||
|
const data_field_regex_num = /^board\.([a-z-_]+)\.([a-z-_]+)\.([A-Za-z0-9]+)$/ // board.car_control.dashboard_system_timeout_test.flag_set0
|
||||||
|
const packet_regex_underscore_num = /^board\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)$/ // board.steering.steering_press_count_1
|
||||||
|
const data_field_regex_underscore_num1 = /^board\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)\.([A-Za-z0-9]+)$/ // board.steering.steering_press_count_1.button1
|
||||||
|
const data_field_regex_underscore_num2 = /^board\.([a-z-_]+)\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)$/ // board.wavesculptor.wsr_status_information.error_flags_0
|
||||||
|
const data_field_regex_underscore_num3 = /^board\.([a-z-_]+)\.([a-z-_]+(_[A-Za-z0-9]+)+)\.([A-Za-z0-9]+(_[A-Za-z0-9]+)+)$/ // board.wavesculptor.wsr_15_165_voltage_rail.reference_165v
|
||||||
|
if (identifier.key === 'car') {
|
||||||
|
// get the car schema from the phoebus server
|
||||||
|
return Promise.resolve({
|
||||||
|
identifier: identifier,
|
||||||
|
name: "car!",
|
||||||
|
type: 'folder',
|
||||||
|
location: "ROOT"
|
||||||
|
})
|
||||||
|
} else if (board_regex.test(identifier.key)) {
|
||||||
|
// it's a board object. get the last word (ie board.bms -> bms)
|
||||||
|
// then use it to construct a get request
|
||||||
|
// console.log("doing board for ", identifier)
|
||||||
|
const board_name = identifier.key.match(board_regex)[1]
|
||||||
|
return fetch(`${process.env.VUE_APP_TELEM}/schema/` + board_name).then((resp) => {
|
||||||
|
return resp.json()
|
||||||
|
})
|
||||||
|
} else if (packet_regex.test(identifier.key)) {
|
||||||
|
const m = identifier.key.match(packet_regex)
|
||||||
|
const board_name = m[1]
|
||||||
|
const pkt_name = m[2]
|
||||||
|
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name].join("/")).then((resp) => {
|
||||||
|
return resp.json()
|
||||||
|
})
|
||||||
|
} else if (data_field_regex.test(identifier.key)) {
|
||||||
|
const m = identifier.key.match(data_field_regex)
|
||||||
|
const board_name = m[1]
|
||||||
|
const pkt_name = m[2]
|
||||||
|
const df_name = m[3]
|
||||||
|
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
||||||
|
return resp.json();
|
||||||
|
})
|
||||||
|
} else if (data_field_regex_num.test(identifier.key)) {
|
||||||
|
const m = identifier.key.match(data_field_regex_num)
|
||||||
|
const board_name = m[1]
|
||||||
|
const pkt_name = m[2]
|
||||||
|
const df_name = m[3]
|
||||||
|
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
||||||
|
return resp.json();
|
||||||
|
})
|
||||||
|
} else if (packet_regex_underscore_num.test(identifier.key)) {
|
||||||
|
const m = identifier.key.match(packet_regex_underscore_num)
|
||||||
|
const board_name = m[1]
|
||||||
|
const pkt_name = m[2]
|
||||||
|
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name].join("/")).then((resp) => {
|
||||||
|
return resp.json();
|
||||||
|
})
|
||||||
|
} else if (data_field_regex_underscore_num1.test(identifier.key)) {
|
||||||
|
const m = identifier.key.match(data_field_regex_underscore_num1)
|
||||||
|
const board_name = m[1]
|
||||||
|
const pkt_name = m[2]
|
||||||
|
const df_name = m[4]
|
||||||
|
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
||||||
|
return resp.json();
|
||||||
|
})
|
||||||
|
} else if (data_field_regex_underscore_num2.test(identifier.key)) {
|
||||||
|
const m = identifier.key.match(data_field_regex_underscore_num2)
|
||||||
|
const board_name = m[1]
|
||||||
|
const pkt_name = m[2]
|
||||||
|
const df_name = m[3]
|
||||||
|
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
||||||
|
return resp.json();
|
||||||
|
})
|
||||||
|
} else if (data_field_regex_underscore_num3.test(identifier.key)) {
|
||||||
|
const m = identifier.key.match(data_field_regex_underscore_num3)
|
||||||
|
const board_name = m[1]
|
||||||
|
const pkt_name = m[2]
|
||||||
|
const df_name = m[4]
|
||||||
|
return fetch([`${process.env.VUE_APP_TELEM}/schema`, board_name, pkt_name, df_name].join("/")).then((resp) => {
|
||||||
|
return resp.json();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error("bad! no match for object.")
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSchema() {
|
||||||
|
return fetch(`${process.env.VUE_APP_TELEM}/schema`).then((resp) => {
|
||||||
|
const res = resp.json()
|
||||||
|
console.log("got schema", res)
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const CarCompositionProvider = {
|
||||||
|
appliesTo: function (domainObject) {
|
||||||
|
return domainObject.identifier.namespace === "umnsvp.phoebus" &&
|
||||||
|
domainObject.identifier.key === "car"
|
||||||
|
},
|
||||||
|
load: function (domainObject) {
|
||||||
|
return getSchema()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the board composition provider takes a board type object, and gets all the telem objects for that board.
|
||||||
|
// it's like a folder.
|
||||||
|
const BoardCompositionProvider = {
|
||||||
|
appliesTo: function (domainObject) {
|
||||||
|
return domainObject.identifier.namespace === "umnsvp.phoebus" &&
|
||||||
|
domainObject.type === "umnsvp-board"
|
||||||
|
},
|
||||||
|
load: function (domainObject) {
|
||||||
|
// console.log("board comp provider for ", domainObject.packets)
|
||||||
|
return Promise.resolve(domainObject.packets)
|
||||||
|
// const board_name = domainObject.identifier.key.match(/^board\.([a-z-_]+)$/)
|
||||||
|
// return fetch("${process.env.VUE_APP_TELEM}/schema/" + board_name[1] + "/packets").then((resp) => {
|
||||||
|
// return resp.json()
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PacketCompositionProvider = {
|
||||||
|
appliesTo: function (domainObject) {
|
||||||
|
return domainObject.identifier.namespace === "umnsvp.phoebus" && domainObject.type === "umnsvp-packet"
|
||||||
|
},
|
||||||
|
load: function (domainObject) {
|
||||||
|
// console.log("packet comp provider for ", domainObject.data_fields)
|
||||||
|
return Promise.resolve(domainObject.data_fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PhoebusCompositionProviders = [
|
||||||
|
CarCompositionProvider,
|
||||||
|
BoardCompositionProvider,
|
||||||
|
PacketCompositionProvider
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
function PhoebusRealTime() {
|
||||||
|
const socket = io(`ws://localhost:${process.env.VUE_APP_TELEM_PORT}`)
|
||||||
|
let callback_list = {};
|
||||||
|
socket.on("packet", (data) => {
|
||||||
|
// if (data[0].packet_name === "wsl_bus_measurement") {
|
||||||
|
// console.log("got a wave meas packt", data[0])
|
||||||
|
// }
|
||||||
|
try {
|
||||||
|
const data_fields = data[0].data[0] // object that defines the measurement in each packet which are sent to openmct
|
||||||
|
// const key = ["board", data[0].board, data[0].packet_name].join(".")
|
||||||
|
console.log(Object.keys(data_fields))
|
||||||
|
console.log(callback_list)
|
||||||
|
// for (let i = 0; i < callback_list.length; i++) {
|
||||||
|
// if (Object.keys(data_fields).includes())
|
||||||
|
// }
|
||||||
|
Object.keys(data_fields).forEach((data_field) => {
|
||||||
|
let key = ["board", data[0].board, data[0].packet_name, data_field].join(".");
|
||||||
|
if (Object.keys(callback_list).includes(key)) {
|
||||||
|
let callBack = callback_list[key];
|
||||||
|
let timestamp = new Date().getTime();
|
||||||
|
// let realTimeData = data_fields;
|
||||||
|
let realTimeData = {}
|
||||||
|
realTimeData[data_field] = data_fields[data_field]
|
||||||
|
realTimeData.timestamp = timestamp;
|
||||||
|
realTimeData.id = key;
|
||||||
|
// console.log(realTimeData)
|
||||||
|
callBack(realTimeData);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing
|
||||||
|
console.warn("a", e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const provider = {
|
||||||
|
supportsSubscribe(domainObject) {
|
||||||
|
console.log("checking if supports subscribe", domainObject)
|
||||||
|
return domainObject.type === "umnsvp-data"
|
||||||
|
},
|
||||||
|
subscribe(domainObject, callback) {
|
||||||
|
console.log("subscribing for ", domainObject)
|
||||||
|
console.log("callback", callback)
|
||||||
|
// register us in the callback list
|
||||||
|
callback_list[domainObject.identifier.key] = callback
|
||||||
|
return function unsubscribe() {
|
||||||
|
delete callback_list[domainObject.identifier.key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
function PhoebusHistorical() {
|
||||||
|
return {
|
||||||
|
supportsRequest(domainObject) {
|
||||||
|
return domainObject.type === "umnsvp-packet"
|
||||||
|
},
|
||||||
|
request(domainObject, options) {
|
||||||
|
// return fetch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function PhoebusPlugin() {
|
||||||
|
return function install(openmct) {
|
||||||
|
openmct.types.addType('umnsvp-board', {
|
||||||
|
name: "UMN SVP Board",
|
||||||
|
description: 'A board that sends telemetry packets/data',
|
||||||
|
createable: false,
|
||||||
|
cssClass: "icon-suitcase"
|
||||||
|
})
|
||||||
|
openmct.types.addType('umnsvp-packet', {
|
||||||
|
name: "UMN SVP Packet",
|
||||||
|
description: "A packet of telemetry from the car",
|
||||||
|
creatable: false,
|
||||||
|
cssClass: "icon-suitcase"
|
||||||
|
})
|
||||||
|
openmct.types.addType('umnsvp-data', {
|
||||||
|
name: "UMN SVP Data Field",
|
||||||
|
description: "A data field of a packet from the car",
|
||||||
|
creatable: false,
|
||||||
|
cssClass: "icon-telemetry"
|
||||||
|
})
|
||||||
|
openmct.objects.addRoot({
|
||||||
|
namespace: "umnsvp.phoebus",
|
||||||
|
key: 'car'
|
||||||
|
})
|
||||||
|
|
||||||
|
openmct.objects.addProvider('umnsvp.phoebus', {get:PhoebusObjectProvider})
|
||||||
|
|
||||||
|
openmct.telemetry.addProvider(PhoebusRealTime())
|
||||||
|
PhoebusCompositionProviders.forEach((provider) => {
|
||||||
|
openmct.composition.addProvider((provider))
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log("hello~!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PhoebusPlugin;
|
11
web/tsconfig.json
Normal file
11
web/tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"target": "es6",
|
||||||
|
"checkJs": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"paths": {
|
||||||
|
"openmct": ["node_modules/openmct/dist/openmct.d.ts"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
web/webpack.config.js
Normal file
47
web/webpack.config.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
const path = require('path');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const CopyPlugin = require("copy-webpack-plugin");
|
||||||
|
const Dotenv = require('dotenv-webpack');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './src/app.js',
|
||||||
|
mode: "development",
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: 'ts-loader',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: 'src/index.html',
|
||||||
|
filename: 'index.html',
|
||||||
|
}),
|
||||||
|
new Dotenv(),
|
||||||
|
new CopyPlugin({
|
||||||
|
patterns: [
|
||||||
|
{ from: "**/*", to: "openmct/", context: "node_modules/openmct/dist"},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js'],
|
||||||
|
},
|
||||||
|
externals: {
|
||||||
|
openmct: "openmct",
|
||||||
|
},
|
||||||
|
devServer: {
|
||||||
|
static: [{
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
directory: path.join(__dirname, '/node_modules/openmct/dist'),
|
||||||
|
publicPath: '/node_modules/openmct/dist'
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: 'main.js',
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
},
|
||||||
|
};
|
Loading…
Reference in a new issue