Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR rebrands the Open MCT-based UI toward “35N” and introduces a new “Signal” plugin (types, views, services, and map scaffolding), while removing several legacy plugins (Gauge, SummaryWidget, TelemetryMean, ConditionWidget) and related styling/workflow assets.
Changes:
- Update shell header layout/branding (new logo assets, app title, “SIGNALS” create button behavior).
- Add the Signal plugin with view providers, data-fetch services (EONET/USGS/OpenSky/AIS/GPSJam), and shared map-layer definitions + a GlobeMap wrapper.
- Remove legacy plugins (and their styles/tests/templates) plus multiple GitHub workflow/template files.
Reviewed changes
Copilot reviewed 128 out of 133 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ui/layout/layout.scss | Adjusts header grid columns and constrains GrandSearch width. |
| src/ui/layout/CreateButton.vue | Adds props for label/menu filtering/target root and async parent lookup for create. |
| src/ui/layout/assets/images/logo-35n.svg | Adds new 35N logo SVG asset. |
| src/ui/layout/assets/images/logo-35n-v3.svg | Adds new 35N v3 logo SVG (embedded image). |
| src/ui/layout/assets/images/logo-35n-v2.svg | Adds new 35N v2 logo SVG (embedded image). |
| src/ui/layout/AppLogo.vue | Disables About click behavior on the logo element. |
| src/ui/layout/AppLayout.vue | Updates header controls (Signals create button, indicators toggle removal) and removes time conductor view. |
| src/ui/layout/app-logo.scss | Switches logo background image and sizing for new branding. |
| src/styles/vue-styles.scss | Removes global style imports for removed plugins (condition widget, gauge). |
| src/plugins/telemetryMean/src/TelemetryAverager.js | Removes TelemetryMean averager implementation. |
| src/plugins/telemetryMean/src/MockTelemetryApi.js | Removes TelemetryMean test mock telemetry API. |
| src/plugins/telemetryMean/src/MeanTelemetryProvider.js | Removes TelemetryMean telemetry provider implementation. |
| src/plugins/telemetryMean/plugin.js | Removes TelemetryMean plugin registration/type definition. |
| src/plugins/summaryWidget/test/TestDataManagerSpec.js | Removes SummaryWidget test coverage for TestDataManager. |
| src/plugins/summaryWidget/test/TestDataItemSpec.js | Removes SummaryWidget test coverage for TestDataItem. |
| src/plugins/summaryWidget/test/SummaryWidgetViewPolicySpec.js | Removes SummaryWidget view policy tests. |
| src/plugins/summaryWidget/test/SummaryWidgetSpec.js | Removes SummaryWidget core widget tests. |
| src/plugins/summaryWidget/test/input/SelectSpec.js | Removes SummaryWidget Select input tests. |
| src/plugins/summaryWidget/test/input/PaletteSpec.js | Removes SummaryWidget Palette input tests. |
| src/plugins/summaryWidget/test/input/OperationSelectSpec.js | Removes SummaryWidget OperationSelect tests. |
| src/plugins/summaryWidget/test/input/ObjectSelectSpec.js | Removes SummaryWidget ObjectSelect tests. |
| src/plugins/summaryWidget/test/input/KeySelectSpec.js | Removes SummaryWidget KeySelect tests. |
| src/plugins/summaryWidget/test/input/IconPaletteSpec.js | Removes SummaryWidget IconPalette tests. |
| src/plugins/summaryWidget/test/input/ColorPaletteSpec.js | Removes SummaryWidget ColorPalette tests. |
| src/plugins/summaryWidget/test/ConditionSpec.js | Removes SummaryWidget Condition tests. |
| src/plugins/summaryWidget/src/WidgetDnD.js | Removes SummaryWidget drag-and-drop manager. |
| src/plugins/summaryWidget/src/views/SummaryWidgetViewProvider.js | Removes SummaryWidget view provider. |
| src/plugins/summaryWidget/src/views/SummaryWidgetView.js | Removes SummaryWidget view implementation. |
| src/plugins/summaryWidget/src/TestDataManager.js | Removes SummaryWidget test data manager implementation. |
| src/plugins/summaryWidget/src/TestDataItem.js | Removes SummaryWidget test data item implementation. |
| src/plugins/summaryWidget/src/telemetry/SummaryWidgetTelemetryProvider.js | Removes SummaryWidget telemetry provider. |
| src/plugins/summaryWidget/src/telemetry/SummaryWidgetRuleSpec.js | Removes SummaryWidget rule spec tests. |
| src/plugins/summaryWidget/src/telemetry/SummaryWidgetRule.js | Removes SummaryWidget rule implementation. |
| src/plugins/summaryWidget/src/telemetry/SummaryWidgetMetadataProvider.js | Removes SummaryWidget metadata provider. |
| src/plugins/summaryWidget/src/telemetry/SummaryWidgetConditionSpec.js | Removes SummaryWidget condition spec tests. |
| src/plugins/summaryWidget/src/telemetry/SummaryWidgetCondition.js | Removes SummaryWidget condition implementation. |
| src/plugins/summaryWidget/src/telemetry/operations.js | Removes SummaryWidget operations library. |
| src/plugins/summaryWidget/src/telemetry/EvaluatorPoolSpec.js | Removes SummaryWidget evaluator pool tests. |
| src/plugins/summaryWidget/src/telemetry/EvaluatorPool.js | Removes SummaryWidget evaluator pool implementation. |
| src/plugins/summaryWidget/src/input/Select.js | Removes SummaryWidget Select wrapper implementation. |
| src/plugins/summaryWidget/src/input/Palette.js | Removes SummaryWidget Palette input implementation. |
| src/plugins/summaryWidget/src/input/OperationSelect.js | Removes SummaryWidget OperationSelect implementation. |
| src/plugins/summaryWidget/src/input/ObjectSelect.js | Removes SummaryWidget ObjectSelect implementation. |
| src/plugins/summaryWidget/src/input/KeySelect.js | Removes SummaryWidget KeySelect implementation. |
| src/plugins/summaryWidget/src/input/IconPalette.js | Removes SummaryWidget IconPalette implementation. |
| src/plugins/summaryWidget/src/input/ColorPalette.js | Removes SummaryWidget ColorPalette implementation. |
| src/plugins/summaryWidget/src/eventHelpers.js | Removes SummaryWidget event helper utilities. |
| src/plugins/summaryWidget/res/widgetTemplate.html | Removes SummaryWidget edit template. |
| src/plugins/summaryWidget/res/testDataTemplate.html | Removes SummaryWidget test-data template. |
| src/plugins/summaryWidget/res/testDataItemTemplate.html | Removes SummaryWidget test-data item template. |
| src/plugins/summaryWidget/res/ruleTemplate.html | Removes SummaryWidget rule template. |
| src/plugins/summaryWidget/res/ruleImageTemplate.html | Removes SummaryWidget drag-image template. |
| src/plugins/summaryWidget/res/input/selectTemplate.html | Removes SummaryWidget select input template. |
| src/plugins/summaryWidget/res/input/paletteTemplate.html | Removes SummaryWidget palette input template. |
| src/plugins/summaryWidget/res/conditionTemplate.html | Removes SummaryWidget condition template. |
| src/plugins/summaryWidget/README.md | Removes SummaryWidget plugin documentation. |
| src/plugins/summaryWidget/plugin.js | Removes SummaryWidget plugin/type registration. |
| src/plugins/signal/views/signal-view-provider.js | Adds Signal object view providers (Signal View + Signal Map). |
| src/plugins/signal/SignalCompositionPolicy.js | Adds composition policy limiting where Signal modules can be created. |
| src/plugins/signal/services/wildfire-data.js | Implements wildfire fetching via shared EONET category fetcher. |
| src/plugins/signal/services/volcano-data.js | Implements volcano fetching via shared EONET category fetcher. |
| src/plugins/signal/services/useSignalPolling.js | Adds polling utility with backoff + hidden-tab multiplier. |
| src/plugins/signal/services/signal-api.js | Adds a generic fetch helper for signal module endpoints. |
| src/plugins/signal/services/severe-storm-data.js | Implements severe storms fetching via shared EONET category fetcher. |
| src/plugins/signal/services/opensky-data.js | Adds OpenSky relay fetch + transformation/classification logic. |
| src/plugins/signal/services/gpsjam-data.js | Adds GPSJam fetch + threshold-based filtering and transform. |
| src/plugins/signal/services/eonet-data.js | Adds shared EONET category fetch + transformation. |
| src/plugins/signal/services/earthquake-data.js | Adds USGS earthquake fetch/transform and summary helpers. |
| src/plugins/signal/services/ais-data.js | Adds AIS relay fetch + normalization/transform pipeline. |
| src/plugins/signal/plugin.js | Registers Signal types, composition policy, object/telemetry/view providers. |
| src/plugins/signal/objects/signal-object-provider.js | Adds get-interceptor to normalize Signal object config/composition. |
| src/plugins/signal/inspectors/SignalInspector.vue | Adds initial Signal inspector placeholder component. |
| src/plugins/plugins.js | Removes old plugin exports and registers the new Signal plugin export. |
| src/plugins/myItems/plugin.js | Renames default My Items to My Signals and supports custom root key. |
| src/plugins/myItems/createMyItemsIdentifier.js | Allows creating My Items identifier with a custom key. |
| src/plugins/gauge/GaugeViewProvider.js | Removes Gauge view provider. |
| src/plugins/gauge/GaugePlugin.js | Removes Gauge plugin/type registration. |
| src/plugins/gauge/gauge-limit-util.js | Removes Gauge limit utility. |
| src/plugins/gauge/components/GaugeFormController.vue | Removes Gauge form control component. |
| src/plugins/conditionWidget/pluginSpec.js | Removes ConditionWidget plugin tests. |
| src/plugins/conditionWidget/plugin.js | Removes ConditionWidget plugin/type registration. |
| src/plugins/conditionWidget/ConditionWidgetViewProvider.js | Removes ConditionWidget view provider. |
| src/plugins/conditionWidget/components/ConditionWidget.vue | Removes ConditionWidget UI component. |
| src/plugins/conditionWidget/components/condition-widget.scss | Removes ConditionWidget styles. |
| src/plugins/condition/plugin.js | Makes conditionSet non-creatable. |
| src/MCT.js | Stops installing ConditionWidget and Gauge plugins in core startup. |
| src/config/map-layer-definitions.js | Adds a centralized registry for map layer definitions + helpers. |
| src/components/GlobeMap.js | Adds globe.gl-based 3D globe map wrapper with layer-driven rendering. |
| package.json | Adds relay scripts and introduces mapping/globe-related dependencies. |
| index.html | Updates app title and installs MyItems with custom key + installs Signal plugin. |
| description.md | Adds a new product description document for “35N”. |
| copilot.md | Adds a Copilot handoff/resume note for ongoing Signal/relay work. |
| .webpack/webpack.common.mjs | Injects Signal relay URL/auth constants via DefinePlugin. |
| .github/workflows/prcop.yml | Removes PRCop workflow. |
| .github/workflows/prcop-config.json | Removes PRCop configuration. |
| .github/workflows/pr-platform.yml | Removes pr-platform workflow. |
| .github/workflows/npm-prerelease.yml | Removes npm prerelease publish workflow. |
| .github/workflows/e2e-perf.yml | Removes e2e performance workflow. |
| .github/workflows/e2e-full.yml | Removes full e2e workflow. |
| .github/workflows/e2e-couchdb.yml | Removes CouchDB e2e workflow. |
| .github/workflows/codeql-analysis.yml | Removes CodeQL workflow. |
| .github/release.yml | Removes GitHub release notes configuration. |
| .github/PULL_REQUEST_TEMPLATE.md | Removes PR template. |
| .github/ISSUE_TEMPLATE/maintenance-type.md | Removes maintenance issue template. |
| .github/ISSUE_TEMPLATE/enhancement-request.md | Removes enhancement issue template. |
| .github/ISSUE_TEMPLATE/config.yml | Removes issue template config. |
| .github/ISSUE_TEMPLATE/bug_report.md | Removes bug report issue template. |
| .github/dependabot.yml | Removes Dependabot config. |
| .github/codeql/codeql-config.yml | Removes CodeQL config. |
Comments suppressed due to low confidence (1)
src/plugins/signal/SignalCompositionPolicy.js:37
- This composition policy only allows Signal module children when the immediate parent identifier.key is exactly 'mine-signals'. That prevents creating Signals inside subfolders under My Signals (common workflow). If the intent is to allow Signals anywhere within the My Signals tree, the policy should allow when the parent is the root or a descendant of it (eg by checking the parent chain / object path), rather than only direct parent key equality. Also consider including namespace in the check to avoid collisions with same key in other namespaces.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+23
to
+24
| <!-- @click="launchAbout" disabled per request --> | ||
| <div ref="aboutLogo" class="l-shell__app-logo" role="button" aria-label="About Modal"></div> |
Comment on lines
1
to
+6
| .l-shell__app-logo { | ||
| cursor: pointer; | ||
| width: 70px; | ||
| width: 124px; | ||
| height: 20px; | ||
| background: url('assets/images/logo-openmct.svg') center no-repeat; | ||
| background: url('assets/images/logo-35n-v3.svg') center no-repeat; | ||
| background-size: 120px 20px; |
Comment on lines
+133
to
+142
| async create(key) { | ||
| const createAction = this.openmct.actions.getAction(CREATE_ACTION_KEY); | ||
| createAction.invoke(key, this.openmct.router.path[0]); | ||
| let targetParent = this.openmct.router.path[0]; | ||
|
|
||
| if (this.targetNamespace !== null || this.targetRootKey !== MY_ITEMS_KEY) { | ||
| targetParent = await this.openmct.objects.get({ | ||
| key: this.targetRootKey, | ||
| namespace: this.targetNamespace | ||
| }); | ||
| } |
Comment on lines
168
to
+226
| <script> | ||
| import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'; | ||
|
|
||
| import ObjectView from '../components/ObjectView.vue'; | ||
| import Inspector from '../inspector/InspectorPanel.vue'; | ||
| import Toolbar from '../toolbar/ToolbarContainer.vue'; | ||
| import AppLogo from './AppLogo.vue'; | ||
| import BrowseBar from './BrowseBar.vue'; | ||
| import CreateButton from './CreateButton.vue'; | ||
| import MctTree from './MctTree.vue'; | ||
| import Multipane from './MultipaneContainer.vue'; | ||
| import Pane from './PaneContainer.vue'; | ||
| import RecentObjectsList from './RecentObjectsList.vue'; | ||
| import GrandSearch from './search/GrandSearch.vue'; | ||
| import NotificationBanner from './status-bar/NotificationBanner.vue'; | ||
| import StatusIndicators from './status-bar/StatusIndicators.vue'; | ||
|
|
||
| const SHELL_HEAD_LOCAL_STORAGE_KEY = 'openmct-shell-head'; | ||
| const DEFAULT_HEAD_EXPANDED = true; | ||
| const DEFAULT_INDICATORS_MULTILINE = true; | ||
|
|
||
| export default { | ||
| components: { | ||
| Inspector, | ||
| MctTree, | ||
| ObjectView, | ||
| CreateButton, | ||
| GrandSearch, | ||
| Multipane, | ||
| Pane, | ||
| BrowseBar, | ||
| Toolbar, | ||
| AppLogo, | ||
| StatusIndicators, | ||
| NotificationBanner, | ||
| RecentObjectsList | ||
| }, | ||
| inject: ['openmct'], | ||
| setup() { | ||
| let resizeObserver; | ||
| let element; | ||
|
|
||
| const storedHeadProps = localStorage.getItem(SHELL_HEAD_LOCAL_STORAGE_KEY); | ||
| const storedHeadPropsObject = JSON.parse(storedHeadProps); | ||
| const storedHeadExpanded = storedHeadPropsObject?.expanded; | ||
| const storedIndicatorsMultiline = storedHeadPropsObject?.multiline; | ||
|
|
||
| // template ref of StatusIndicators component | ||
| const indicatorsComponent = ref(null); | ||
|
|
||
| const width = ref(null); | ||
| const scrollWidth = ref(null); | ||
| const headExpanded = ref(storedHeadExpanded ?? DEFAULT_HEAD_EXPANDED); | ||
| const indicatorsMultiline = ref(storedIndicatorsMultiline ?? DEFAULT_INDICATORS_MULTILINE); | ||
|
|
||
| const isOverflowing = computed(() => scrollWidth.value > width.value); | ||
| const indicatorsMultilineCssClass = computed(() => { | ||
| const multilineClass = indicatorsMultiline.value ? 'icon-singleline' : 'icon-multiline'; | ||
| const overflowingClass = | ||
| isOverflowing.value && !indicatorsMultiline.value | ||
| ? 'c-button c-button--major' | ||
| : 'c-icon-button'; | ||
| return `${multilineClass} ${overflowingClass}`; | ||
| }); | ||
| const indicatorsMultilineLabel = computed(() => { | ||
| return `Display as ${indicatorsMultiline.value ? 'single line' : 'multiple lines'}`; | ||
| }); | ||
|
|
||
| const initialHeadProps = JSON.stringify({ | ||
| expanded: headExpanded.value, | ||
| multiline: indicatorsMultiline.value | ||
| expanded: headExpanded.value | ||
| }); | ||
|
|
||
| if (initialHeadProps !== storedHeadProps) { | ||
| localStorage.setItem(SHELL_HEAD_LOCAL_STORAGE_KEY, initialHeadProps); | ||
| } | ||
|
|
||
| onMounted(() => { | ||
| resizeObserver = new ResizeObserver((entries) => { | ||
| width.value = entries[0].target.clientWidth; | ||
| scrollWidth.value = entries[0].target.scrollWidth; | ||
| }); | ||
|
|
||
| // indicatorsContainer is a template ref inside of indicatorsComponent | ||
| element = indicatorsComponent.value.$refs.indicatorsContainer; | ||
| onMounted(() => {}); | ||
|
|
||
| if (!indicatorsMultiline.value) { | ||
| observeIndicatorsOverflow(); | ||
| } | ||
| }); | ||
| onUnmounted(() => {}); | ||
|
|
||
| onUnmounted(() => { | ||
| resizeObserver.disconnect(); | ||
| }); | ||
|
|
||
| function observeIndicatorsOverflow() { | ||
| resizeObserver.observe(element); | ||
| } | ||
|
|
||
| function unObserveIndicatorsOverflow() { | ||
| resizeObserver.unobserve(element); | ||
| } | ||
|
|
||
| function checkIndicatorsElementWidths() { | ||
| if (!indicatorsMultiline.value) { | ||
| width.value = element.clientWidth; | ||
| scrollWidth.value = element.scrollWidth; | ||
| } | ||
| } | ||
| function checkIndicatorsElementWidths() {} |
Comment on lines
136
to
152
| <Pane class="l-shell__pane-main" role="main"> | ||
| <BrowseBar | ||
| ref="browseBar" | ||
| class="l-shell__main-view-browse-bar" | ||
| :action-collection="actionCollection" | ||
| @sync-tree-navigation="handleSyncTreeNavigation" | ||
| /> | ||
| <Toolbar v-if="toolbar" class="l-shell__toolbar" /> | ||
| <ObjectView | ||
| ref="browseObject" | ||
| class="l-shell__main-container js-main-container js-notebook-snapshot-item" | ||
| :class="{ '--has-toolbar': toolbar }" | ||
| data-selectable | ||
| :show-edit-view="true" | ||
| @change-action-collection="setActionCollection" | ||
| /> | ||
| <component | ||
| :is="conductorComponent" | ||
| class="l-shell__time-conductor" | ||
| aria-label="Global Time Conductor" | ||
| /> | ||
| </Pane> |
Comment on lines
+85
to
+92
| export async function fetchEarthquakesInRange(startTime, endTime) { | ||
| try { | ||
| const url = new URL(`${USGS_API_BASE}/all_hour.geojson`); | ||
| url.searchParams.append('starttime', startTime); | ||
| url.searchParams.append('endtime', endTime); | ||
|
|
||
| const response = await fetch(url.toString()); | ||
| if (!response.ok) { |
| "start:prod": "npx webpack serve --config ./.webpack/webpack.prod.mjs", | ||
| "start:coverage": "npx webpack serve --config ./.webpack/webpack.coverage.mjs", | ||
| "relay:start": "node ./scripts/ais-relay.cjs", | ||
| "relay:start:dev": "set PORT=3004&& node ./scripts/ais-relay.cjs", |
Comment on lines
+1
to
+8
| 35N (35 November) is a Signals Intelligence Analysis Platform that intercepts, analyzes, and fascilitates the reporting on foreign communications and electronic signals to provide actionable intelligence. It assists in the detection of operational patterns, maintaining a databases, and identifying targets using it's advanced technology to support tactical and strategic missions. | ||
|
|
||
| Key Features | ||
| Signal Analysis: Assists in the analysis of intercepted communications and non-communications information to isolate valid foreign intelligence. | ||
| Target Identification: Assists in establishing operational patterns and maintains Signal Intelligence technical data and Electronic Order of Battle (EOB) information. | ||
| Reporting: Assists in the preparation of technical and tactical intelligence reports to support military commands. | ||
| Database Management: Uses an automated data processing enviroment to maintain analytical working aids and databases. | ||
| Equipment Support: Assist in the emplacement, employment, and recovery of SIGINT assets. No newline at end of file |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes
Describe your changes:
All Submissions:
Author Checklist
type:label? Note: this is not necessarily the same as the original issue.Reviewer Checklist