mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 02:29:24 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
0bf37fc492 | |||
d40204efe3 | |||
ff8288d10e | |||
c1dd82cf5f | |||
e43ddf6a4a | |||
018a64eb86 | |||
b1785da838 |
@ -15,7 +15,8 @@ module.exports = {
|
||||
'plugin:compat/recommended',
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:you-dont-need-lodash-underscore/compatible',
|
||||
'plugin:prettier/recommended'
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:no-unsanitized/DOM'
|
||||
],
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
|
3
API.md
3
API.md
@ -94,6 +94,9 @@ well as assets such as html, css, and images necessary for the UI.
|
||||
|
||||
## Starting an Open MCT application
|
||||
|
||||
> [!WARNING]
|
||||
> Open MCT provides a development server via `webpack-dev-server` (`npm start`). **This should be used for development purposes only and should never be deployed to a production environment**.
|
||||
|
||||
To start a minimally functional Open MCT application, it is necessary to
|
||||
include the Open MCT distributable, enable some basic plugins, and bootstrap
|
||||
the application. The tutorials walk through the process of getting Open MCT up
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openmct",
|
||||
"version": "3.1.0-next",
|
||||
"version": "3.1.1",
|
||||
"description": "The Open MCT core platform",
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "7.22.5",
|
||||
@ -27,6 +27,7 @@
|
||||
"eslint": "8.48.0",
|
||||
"eslint-config-prettier": "9.0.0",
|
||||
"eslint-plugin-compat": "4.2.0",
|
||||
"eslint-plugin-no-unsanitized": "4.0.2",
|
||||
"eslint-plugin-playwright": "0.12.0",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"eslint-plugin-simple-import-sort": "10.0.0",
|
||||
|
@ -50,15 +50,14 @@
|
||||
|
||||
<script>
|
||||
import Vue, { toRaw } from 'vue';
|
||||
|
||||
import StalenessUtils from '@/utils/staleness';
|
||||
|
||||
import LadRow from './LadRow.vue';
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LadRow
|
||||
},
|
||||
mixins: [stalenessMixin],
|
||||
inject: ['openmct', 'currentView', 'ladTableConfiguration'],
|
||||
props: {
|
||||
domainObject: {
|
||||
@ -74,7 +73,6 @@ export default {
|
||||
return {
|
||||
items: [],
|
||||
viewContext: {},
|
||||
staleObjects: [],
|
||||
configuration: this.ladTableConfiguration.getConfiguration()
|
||||
};
|
||||
},
|
||||
@ -96,11 +94,7 @@ export default {
|
||||
return !this.configuration?.hiddenColumns?.type;
|
||||
},
|
||||
staleClass() {
|
||||
if (this.staleObjects.length !== 0) {
|
||||
return 'is-stale';
|
||||
}
|
||||
|
||||
return '';
|
||||
return this.isStale ? 'is-stale' : '';
|
||||
},
|
||||
applyLayoutClass() {
|
||||
if (this.configuration.isFixedLayout) {
|
||||
@ -133,12 +127,16 @@ export default {
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.reorder);
|
||||
this.composition.load();
|
||||
this.stalenessSubscription = {};
|
||||
await Vue.nextTick();
|
||||
this.viewActionsCollection = this.openmct.actions.getActionsCollection(
|
||||
this.objectPath,
|
||||
this.currentView
|
||||
);
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
|
||||
this.initializeViewActions();
|
||||
},
|
||||
unmounted() {
|
||||
@ -147,11 +145,6 @@ export default {
|
||||
this.composition.off('add', this.addItem);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
this.composition.off('reorder', this.reorder);
|
||||
|
||||
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
|
||||
stalenessSubscription.unsubscribe();
|
||||
stalenessSubscription.stalenessUtils.destroy();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
addItem(domainObject) {
|
||||
@ -160,35 +153,16 @@ export default {
|
||||
item.key = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
this.items.push(item);
|
||||
|
||||
this.stalenessSubscription[item.key] = {};
|
||||
this.stalenessSubscription[item.key].stalenessUtils = new StalenessUtils(
|
||||
this.openmct,
|
||||
domainObject
|
||||
);
|
||||
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStaleness(item.key, stalenessResponse);
|
||||
}
|
||||
});
|
||||
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
|
||||
domainObject,
|
||||
(stalenessResponse) => {
|
||||
this.handleStaleness(item.key, stalenessResponse);
|
||||
}
|
||||
);
|
||||
|
||||
this.stalenessSubscription[item.key].unsubscribe = stalenessSubscription;
|
||||
this.subscribeToStaleness(domainObject);
|
||||
},
|
||||
removeItem(identifier) {
|
||||
const SKIP_CHECK = true;
|
||||
const keystring = this.openmct.objects.makeKeyString(identifier);
|
||||
const index = this.items.findIndex((item) => keystring === item.key);
|
||||
|
||||
const index = this.items.findIndex((item) => keystring === item.key);
|
||||
this.items.splice(index, 1);
|
||||
|
||||
this.stalenessSubscription[keystring].unsubscribe();
|
||||
this.handleStaleness(keystring, { isStale: false }, SKIP_CHECK);
|
||||
const domainObject = this.openmct.objects.get(keystring);
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
},
|
||||
reorder(reorderPlan) {
|
||||
const oldItems = this.items.slice();
|
||||
@ -204,23 +178,6 @@ export default {
|
||||
handleConfigurationChange(configuration) {
|
||||
this.configuration = configuration;
|
||||
},
|
||||
handleStaleness(id, stalenessResponse, skipCheck = false) {
|
||||
if (
|
||||
skipCheck ||
|
||||
this.stalenessSubscription[id].stalenessUtils.shouldUpdateStaleness(stalenessResponse)
|
||||
) {
|
||||
const index = this.staleObjects.indexOf(id);
|
||||
if (stalenessResponse.isStale) {
|
||||
if (index === -1) {
|
||||
this.staleObjects.push(id);
|
||||
}
|
||||
} else {
|
||||
if (index !== -1) {
|
||||
this.staleObjects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateViewContext(rowContext) {
|
||||
this.viewContext.row = rowContext;
|
||||
},
|
||||
|
@ -45,9 +45,9 @@
|
||||
:domain-object="ladRow.domainObject"
|
||||
:path-to-table="ladTable.objectPath"
|
||||
:has-units="hasUnits"
|
||||
:is-stale="staleObjects.includes(combineKeys(ladTable.key, ladRow.key))"
|
||||
:is-stale="staleObjects.includes(ladRow.key)"
|
||||
:configuration="configuration"
|
||||
@rowContextClick="updateViewContext"
|
||||
@row-context-click="updateViewContext"
|
||||
/>
|
||||
</template>
|
||||
</tbody>
|
||||
@ -56,7 +56,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StalenessUtils from '@/utils/staleness';
|
||||
import { toRaw } from 'vue';
|
||||
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
|
||||
import LadRow from './LadRow.vue';
|
||||
|
||||
@ -64,6 +66,7 @@ export default {
|
||||
components: {
|
||||
LadRow
|
||||
},
|
||||
mixins: [stalenessMixin],
|
||||
inject: ['openmct', 'objectPath', 'currentView', 'ladTableConfiguration'],
|
||||
props: {
|
||||
domainObject: {
|
||||
@ -76,8 +79,8 @@ export default {
|
||||
ladTableObjects: [],
|
||||
ladTelemetryObjects: {},
|
||||
viewContext: {},
|
||||
staleObjects: [],
|
||||
configuration: this.ladTableConfiguration.getConfiguration()
|
||||
configuration: this.ladTableConfiguration.getConfiguration(),
|
||||
subscribedObjects: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -108,11 +111,7 @@ export default {
|
||||
return !this.configuration?.hiddenColumns?.type;
|
||||
},
|
||||
staleClass() {
|
||||
if (this.staleObjects.length !== 0) {
|
||||
return 'is-stale';
|
||||
}
|
||||
|
||||
return '';
|
||||
return this.isStale ? 'is-stale' : '';
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -125,8 +124,10 @@ export default {
|
||||
this.composition.on('remove', this.removeLadTable);
|
||||
this.composition.on('reorder', this.reorderLadTables);
|
||||
this.composition.load();
|
||||
|
||||
this.stalenessSubscription = {};
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
unmounted() {
|
||||
this.ladTableConfiguration.off('change', this.handleConfigurationChange);
|
||||
@ -137,11 +138,6 @@ export default {
|
||||
c.composition.off('add', c.addCallback);
|
||||
c.composition.off('remove', c.removeCallback);
|
||||
});
|
||||
|
||||
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
|
||||
stalenessSubscription.unsubscribe();
|
||||
stalenessSubscription.stalenessUtils.destroy();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
addLadTable(domainObject) {
|
||||
@ -176,9 +172,18 @@ export default {
|
||||
);
|
||||
let ladTable = this.ladTableObjects[index];
|
||||
|
||||
this.ladTelemetryObjects[ladTable.key].forEach((telemetryObject) => {
|
||||
let combinedKey = this.combineKeys(ladTable.key, telemetryObject.key);
|
||||
this.unwatchStaleness(combinedKey);
|
||||
ladTable?.domainObject?.composition.forEach((telemetryObject) => {
|
||||
const telemetryKey = this.openmct.objects.makeKeyString(telemetryObject);
|
||||
if (!this.subscribedObjects?.[telemetryKey]) {
|
||||
return;
|
||||
}
|
||||
let subscribedObject = toRaw(this.subscribedObjects[telemetryKey]);
|
||||
if (subscribedObject?.count > 1) {
|
||||
subscribedObject.count -= 1;
|
||||
} else if (subscribedObject?.count === 1) {
|
||||
this.triggerUnsubscribeFromStaleness(subscribedObject.domainObject);
|
||||
delete this.subscribedObjects[telemetryKey];
|
||||
}
|
||||
});
|
||||
|
||||
delete this.ladTelemetryObjects[ladTable.key];
|
||||
@ -199,77 +204,35 @@ export default {
|
||||
let telemetryObject = {};
|
||||
telemetryObject.key = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
telemetryObject.domainObject = domainObject;
|
||||
const combinedKey = this.combineKeys(ladTable.key, telemetryObject.key);
|
||||
|
||||
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
|
||||
telemetryObjects.push(telemetryObject);
|
||||
|
||||
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
|
||||
|
||||
this.stalenessSubscription[combinedKey] = {};
|
||||
this.stalenessSubscription[combinedKey].stalenessUtils = new StalenessUtils(
|
||||
this.openmct,
|
||||
domainObject
|
||||
);
|
||||
|
||||
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStaleness(combinedKey, stalenessResponse);
|
||||
}
|
||||
});
|
||||
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
|
||||
domainObject,
|
||||
(stalenessResponse) => {
|
||||
this.handleStaleness(combinedKey, stalenessResponse);
|
||||
}
|
||||
);
|
||||
|
||||
this.stalenessSubscription[combinedKey].unsubscribe = stalenessSubscription;
|
||||
if (!this.subscribedObjects[telemetryObject?.key]) {
|
||||
this.subscribeToStaleness(domainObject);
|
||||
this.subscribedObjects[telemetryObject?.key] = { count: 1, domainObject };
|
||||
} else if (this.subscribedObjects?.[telemetryObject?.key]?.count) {
|
||||
this.subscribedObjects[telemetryObject?.key].count += 1;
|
||||
}
|
||||
};
|
||||
},
|
||||
removeTelemetryObject(ladTable) {
|
||||
return (identifier) => {
|
||||
const keystring = this.openmct.objects.makeKeyString(identifier);
|
||||
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
|
||||
const combinedKey = this.combineKeys(ladTable.key, keystring);
|
||||
let index = telemetryObjects.findIndex(
|
||||
(telemetryObject) => keystring === telemetryObject.key
|
||||
);
|
||||
|
||||
this.unwatchStaleness(combinedKey);
|
||||
|
||||
telemetryObjects.splice(index, 1);
|
||||
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
|
||||
};
|
||||
},
|
||||
unwatchStaleness(combinedKey) {
|
||||
const SKIP_CHECK = true;
|
||||
|
||||
this.stalenessSubscription[combinedKey].unsubscribe();
|
||||
this.stalenessSubscription[combinedKey].stalenessUtils.destroy();
|
||||
this.handleStaleness(combinedKey, { isStale: false }, SKIP_CHECK);
|
||||
|
||||
delete this.stalenessSubscription[combinedKey];
|
||||
},
|
||||
handleConfigurationChange(configuration) {
|
||||
this.configuration = configuration;
|
||||
},
|
||||
handleStaleness(combinedKey, stalenessResponse, skipCheck = false) {
|
||||
if (
|
||||
skipCheck ||
|
||||
this.stalenessSubscription[combinedKey].stalenessUtils.shouldUpdateStaleness(
|
||||
stalenessResponse
|
||||
)
|
||||
) {
|
||||
const index = this.staleObjects.indexOf(combinedKey);
|
||||
const foundStaleObject = index > -1;
|
||||
if (stalenessResponse.isStale && !foundStaleObject) {
|
||||
this.staleObjects.push(combinedKey);
|
||||
} else if (!stalenessResponse.isStale && foundStaleObject) {
|
||||
this.staleObjects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
updateViewContext(rowContext) {
|
||||
this.viewContext.row = rowContext;
|
||||
},
|
||||
|
@ -97,8 +97,10 @@ describe('The condition', function () {
|
||||
mockTimeSystems = {
|
||||
key: 'utc'
|
||||
};
|
||||
openmct.time = jasmine.createSpyObj('time', ['getAllTimeSystems']);
|
||||
openmct.time = jasmine.createSpyObj('time', ['getAllTimeSystems', 'on', 'off']);
|
||||
openmct.time.getAllTimeSystems.and.returnValue([mockTimeSystems]);
|
||||
openmct.time.on.and.returnValue(() => {});
|
||||
openmct.time.off.and.returnValue(() => {});
|
||||
|
||||
testConditionDefinition = {
|
||||
id: '123-456',
|
||||
|
@ -79,15 +79,15 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StalenessUtils from '@/utils/staleness';
|
||||
|
||||
import ConditionManager from '../ConditionManager';
|
||||
import Condition from './Condition.vue';
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Condition
|
||||
},
|
||||
mixins: [stalenessMixin],
|
||||
inject: ['openmct', 'domainObject'],
|
||||
props: {
|
||||
isEditing: Boolean,
|
||||
@ -135,13 +135,6 @@ export default {
|
||||
if (this.stopObservingForChanges) {
|
||||
this.stopObservingForChanges();
|
||||
}
|
||||
|
||||
if (this.stalenessSubscription) {
|
||||
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
|
||||
stalenessSubscription.unsubscribe();
|
||||
stalenessSubscription.stalenessUtils.destroy();
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
@ -153,7 +146,20 @@ export default {
|
||||
this.conditionManager = new ConditionManager(this.domainObject, this.openmct);
|
||||
this.conditionManager.on('conditionSetResultUpdated', this.handleConditionSetResultUpdated);
|
||||
this.conditionManager.on('noTelemetryObjects', this.emitNoTelemetryObjectEvent);
|
||||
this.stalenessSubscription = {};
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject, () => {
|
||||
this.emitStaleness({
|
||||
keyString: domainObject.identifier,
|
||||
stalenessResponse: { isStale: false }
|
||||
});
|
||||
});
|
||||
this.subscribeToStaleness(domainObject, (stalenessResponse) => {
|
||||
this.emitStaleness({
|
||||
keyString: domainObject.identifier,
|
||||
stalenessResponse: stalenessResponse
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
handleConditionSetResultUpdated(data) {
|
||||
@ -221,28 +227,12 @@ export default {
|
||||
this.telemetryObjs.push(domainObject);
|
||||
this.$emit('telemetryUpdated', this.telemetryObjs);
|
||||
|
||||
if (!this.stalenessSubscription[keyString]) {
|
||||
this.stalenessSubscription[keyString] = {};
|
||||
}
|
||||
|
||||
this.stalenessSubscription[keyString].stalenessUtils = new StalenessUtils(
|
||||
this.openmct,
|
||||
domainObject
|
||||
);
|
||||
|
||||
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
this.subscribeToStaleness(domainObject, (stalenessResponse) => {
|
||||
this.emitStaleness({
|
||||
keyString,
|
||||
stalenessResponse: stalenessResponse
|
||||
});
|
||||
});
|
||||
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
|
||||
domainObject,
|
||||
(stalenessResponse) => {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
);
|
||||
|
||||
this.stalenessSubscription[keyString].unsubscribe = stalenessSubscription;
|
||||
},
|
||||
removeTelemetryObject(identifier) {
|
||||
const keyString = this.openmct.objects.makeKeyString(identifier);
|
||||
@ -252,31 +242,17 @@ export default {
|
||||
return objId === keyString;
|
||||
});
|
||||
|
||||
const domainObject = this.telemetryObjs[index];
|
||||
this.triggerUnsubscribeFromStaleness(domainObject, () => {
|
||||
this.emitStaleness({
|
||||
keyString,
|
||||
stalenessResponse: { isStale: false }
|
||||
});
|
||||
});
|
||||
|
||||
if (index > -1) {
|
||||
this.telemetryObjs.splice(index, 1);
|
||||
}
|
||||
|
||||
if (this.stalenessSubscription[keyString]) {
|
||||
this.stalenessSubscription[keyString].unsubscribe();
|
||||
this.stalenessSubscription[keyString].stalenessUtils.destroy();
|
||||
this.emitStaleness({
|
||||
keyString,
|
||||
isStale: false
|
||||
});
|
||||
delete this.stalenessSubscription[keyString];
|
||||
}
|
||||
},
|
||||
handleStaleness(keyString, stalenessResponse) {
|
||||
if (
|
||||
this.stalenessSubscription[keyString].stalenessUtils.shouldUpdateStaleness(
|
||||
stalenessResponse
|
||||
)
|
||||
) {
|
||||
this.emitStaleness({
|
||||
keyString,
|
||||
isStale: stalenessResponse.isStale
|
||||
});
|
||||
}
|
||||
},
|
||||
emitStaleness(stalenessObject) {
|
||||
this.$emit('telemetryStaleness', stalenessObject);
|
||||
|
@ -57,12 +57,14 @@
|
||||
<script>
|
||||
import ConditionCollection from './ConditionCollection.vue';
|
||||
import TestData from './TestData.vue';
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TestData,
|
||||
ConditionCollection
|
||||
},
|
||||
mixins: [stalenessMixin],
|
||||
inject: ['openmct', 'domainObject'],
|
||||
props: {
|
||||
isEditing: Boolean
|
||||
@ -71,15 +73,9 @@ export default {
|
||||
return {
|
||||
currentConditionOutput: '',
|
||||
telemetryObjs: [],
|
||||
testData: {},
|
||||
staleObjects: []
|
||||
testData: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isStale() {
|
||||
return this.staleObjects.length !== 0;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.conditionSetIdentifier = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
this.testData = {
|
||||
@ -100,17 +96,8 @@ export default {
|
||||
updateTestData(testData) {
|
||||
this.testData = testData;
|
||||
},
|
||||
handleStaleness({ keyString, isStale }) {
|
||||
const index = this.staleObjects.indexOf(keyString);
|
||||
if (isStale) {
|
||||
if (index === -1) {
|
||||
this.staleObjects.push(keyString);
|
||||
}
|
||||
} else {
|
||||
if (index !== -1) {
|
||||
this.staleObjects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
handleStaleness({ keyString, stalenessResponse }) {
|
||||
this.addOrRemoveStaleObject(keyString, stalenessResponse);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -52,6 +52,8 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
|
||||
this.initialize();
|
||||
this.emitEvent('criterionUpdated', this);
|
||||
|
||||
this.openmct.time.on('clockChanged', this.subscribeToStaleness);
|
||||
}
|
||||
|
||||
initialize() {
|
||||
@ -95,6 +97,10 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
this.unsubscribeFromStaleness();
|
||||
}
|
||||
|
||||
if (!this.telemetryObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.stalenessUtils) {
|
||||
this.stalenessUtils = new StalenessUtils(this.openmct, this.telemetryObject);
|
||||
}
|
||||
@ -333,6 +339,8 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
delete this.ageCheck;
|
||||
}
|
||||
|
||||
this.openmct.time.off('clockChanged', this.subscribeToStaleness);
|
||||
|
||||
if (this.stalenessUtils) {
|
||||
this.stalenessUtils.destroy();
|
||||
}
|
||||
|
@ -88,7 +88,9 @@ describe('The telemetry criterion', function () {
|
||||
'timeSystem',
|
||||
'bounds',
|
||||
'getAllTimeSystems',
|
||||
'getContextForView'
|
||||
'getContextForView',
|
||||
'on',
|
||||
'off'
|
||||
]);
|
||||
openmct.time.timeSystem.and.returnValue({ key: 'system' });
|
||||
openmct.time.bounds.and.returnValue({
|
||||
@ -97,6 +99,8 @@ describe('The telemetry criterion', function () {
|
||||
});
|
||||
openmct.time.getAllTimeSystems.and.returnValue([{ key: 'system' }]);
|
||||
openmct.time.getContextForView.and.returnValue({});
|
||||
openmct.time.on.and.returnValue(() => {});
|
||||
openmct.time.off.and.returnValue(() => {});
|
||||
|
||||
testCriterionDefinition = {
|
||||
id: 'test-criterion-id',
|
||||
|
@ -240,6 +240,11 @@ export default {
|
||||
|
||||
this.status = this.openmct.status.get(this.item.identifier);
|
||||
this.removeStatusListener = this.openmct.status.observe(this.item.identifier, this.setStatus);
|
||||
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.removeStatusListener();
|
||||
|
@ -161,8 +161,11 @@ export default {
|
||||
let originalClassName = this.dragGhost.classList[0];
|
||||
this.dragGhost.className = '';
|
||||
this.dragGhost.classList.add(originalClassName, iconClass);
|
||||
this.dragGhost.textContent = '';
|
||||
const span = document.createElement('span');
|
||||
span.textContent = this.domainObject.name;
|
||||
this.dragGhost.appendChild(span);
|
||||
|
||||
this.dragGhost.innerHTML = `<span>${this.domainObject.name}</span>`;
|
||||
event.dataTransfer.setDragImage(this.dragGhost, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -541,6 +541,11 @@ export default {
|
||||
|
||||
this.openmct.time.on('bounds', this.refreshData);
|
||||
this.openmct.time.on('timeSystem', this.setTimeSystem);
|
||||
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
unmounted() {
|
||||
this.composition.off('add', this.addedToComposition);
|
||||
@ -620,7 +625,7 @@ export default {
|
||||
this.unsubscribe = null;
|
||||
}
|
||||
|
||||
this.triggerUnsubscribeFromStaleness();
|
||||
this.triggerUnsubscribeFromStaleness(this.domainObject);
|
||||
|
||||
this.curVal = DEFAULT_CURRENT_VALUE;
|
||||
this.formats = null;
|
||||
|
@ -32,7 +32,6 @@ export default class ImportAsJSONAction {
|
||||
this.cssClass = 'icon-import';
|
||||
this.group = 'import';
|
||||
this.priority = 2;
|
||||
this.newObjects = [];
|
||||
|
||||
this.openmct = openmct;
|
||||
}
|
||||
@ -83,9 +82,10 @@ export default class ImportAsJSONAction {
|
||||
* @param {object} parent
|
||||
* @param {object} tree
|
||||
* @param {object} seen
|
||||
* @param {Array} objectsToCreate tracks objects from import json that will need to be created
|
||||
*/
|
||||
_deepInstantiate(parent, tree, seen) {
|
||||
let objectIdentifiers = this._getObjectReferenceIds(parent);
|
||||
_deepInstantiate(parent, tree, seen, objectsToCreate) {
|
||||
const objectIdentifiers = this._getObjectReferenceIds(parent);
|
||||
|
||||
if (objectIdentifiers.length) {
|
||||
const parentId = this.openmct.objects.makeKeyString(parent.identifier);
|
||||
@ -100,15 +100,16 @@ export default class ImportAsJSONAction {
|
||||
const newModel = tree[keystring];
|
||||
delete newModel.persisted;
|
||||
|
||||
this.newObjects.push(newModel);
|
||||
objectsToCreate.push(newModel);
|
||||
|
||||
// make sure there weren't any errors saving
|
||||
if (newModel) {
|
||||
this._deepInstantiate(newModel, tree, seen);
|
||||
this._deepInstantiate(newModel, tree, seen, objectsToCreate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {object} parent
|
||||
@ -170,19 +171,19 @@ export default class ImportAsJSONAction {
|
||||
* @param {object} objTree
|
||||
*/
|
||||
async _importObjectTree(domainObject, objTree) {
|
||||
const objectsToCreate = [];
|
||||
const namespace = domainObject.identifier.namespace;
|
||||
const tree = this._generateNewIdentifiers(objTree, namespace);
|
||||
const rootId = tree.rootId;
|
||||
|
||||
const rootObj = tree.openmct[rootId];
|
||||
delete rootObj.persisted;
|
||||
this.newObjects.push(rootObj);
|
||||
|
||||
objectsToCreate.push(rootObj);
|
||||
if (this.openmct.composition.checkPolicy(domainObject, rootObj)) {
|
||||
this._deepInstantiate(rootObj, tree.openmct, []);
|
||||
this._deepInstantiate(rootObj, tree.openmct, [], objectsToCreate);
|
||||
|
||||
try {
|
||||
await Promise.all(this.newObjects.map(this._instantiate, this));
|
||||
await Promise.all(objectsToCreate.map(this._instantiate, this));
|
||||
} catch (error) {
|
||||
this.openmct.notifications.error('Error saving objects');
|
||||
|
||||
|
@ -62,13 +62,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StalenessUtils from '@/utils/staleness';
|
||||
|
||||
import ImageExporter from '../../exporters/ImageExporter';
|
||||
import ProgressBar from '../../ui/components/ProgressBar.vue';
|
||||
import PlotLegend from './legend/PlotLegend.vue';
|
||||
import eventHelpers from './lib/eventHelpers';
|
||||
import MctPlot from './MctPlot.vue';
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -76,6 +75,7 @@ export default {
|
||||
ProgressBar,
|
||||
PlotLegend
|
||||
},
|
||||
mixins: [stalenessMixin],
|
||||
inject: ['openmct', 'domainObject', 'path'],
|
||||
props: {
|
||||
options: {
|
||||
@ -131,7 +131,6 @@ export default {
|
||||
return {
|
||||
loading: false,
|
||||
status: '',
|
||||
staleObjects: [],
|
||||
limitLineLabels: undefined,
|
||||
lockHighlightPoint: false,
|
||||
highlights: [],
|
||||
@ -148,11 +147,7 @@ export default {
|
||||
return this.gridLines ?? !this.options.compact;
|
||||
},
|
||||
staleClass() {
|
||||
if (this.staleObjects.length !== 0) {
|
||||
return 'is-stale';
|
||||
}
|
||||
|
||||
return '';
|
||||
return this.isStale ? 'is-stale' : '';
|
||||
},
|
||||
plotLegendPositionClass() {
|
||||
return this.position ? `plot-legend-${this.position}` : '';
|
||||
@ -176,8 +171,11 @@ export default {
|
||||
created() {
|
||||
eventHelpers.extend(this);
|
||||
this.imageExporter = new ImageExporter(this.openmct);
|
||||
this.stalenessSubscription = {};
|
||||
this.loadComposition();
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
unmounted() {
|
||||
this.destroy();
|
||||
@ -187,76 +185,19 @@ export default {
|
||||
this.compositionCollection = this.openmct.composition.get(this.domainObject);
|
||||
|
||||
if (this.compositionCollection) {
|
||||
this.compositionCollection.on('add', this.addItem);
|
||||
this.compositionCollection.on('remove', this.removeItem);
|
||||
this.compositionCollection.on('add', this.subscribeToStaleness);
|
||||
this.compositionCollection.on('remove', this.triggerUnsubscribeFromStaleness);
|
||||
this.compositionCollection.load();
|
||||
}
|
||||
},
|
||||
addItem(object) {
|
||||
const keystring = this.openmct.objects.makeKeyString(object.identifier);
|
||||
|
||||
if (!this.stalenessSubscription[keystring]) {
|
||||
this.stalenessSubscription[keystring] = {};
|
||||
this.stalenessSubscription[keystring].stalenessUtils = new StalenessUtils(
|
||||
this.openmct,
|
||||
object
|
||||
);
|
||||
}
|
||||
|
||||
this.openmct.telemetry.isStale(object).then((stalenessResponse) => {
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStaleness(keystring, stalenessResponse);
|
||||
}
|
||||
});
|
||||
const unsubscribeFromStaleness = this.openmct.telemetry.subscribeToStaleness(
|
||||
object,
|
||||
(stalenessResponse) => {
|
||||
this.handleStaleness(keystring, stalenessResponse);
|
||||
}
|
||||
);
|
||||
|
||||
this.stalenessSubscription[keystring].unsubscribe = unsubscribeFromStaleness;
|
||||
},
|
||||
removeItem(object) {
|
||||
const SKIP_CHECK = true;
|
||||
const keystring = this.openmct.objects.makeKeyString(object);
|
||||
this.stalenessSubscription[keystring].unsubscribe();
|
||||
this.stalenessSubscription[keystring].stalenessUtils.destroy();
|
||||
this.handleStaleness(keystring, { isStale: false }, SKIP_CHECK);
|
||||
delete this.stalenessSubscription[keystring];
|
||||
},
|
||||
handleStaleness(id, stalenessResponse, skipCheck = false) {
|
||||
if (
|
||||
skipCheck ||
|
||||
this.stalenessSubscription[id].stalenessUtils.shouldUpdateStaleness(stalenessResponse, id)
|
||||
) {
|
||||
const index = this.staleObjects.indexOf(id);
|
||||
if (stalenessResponse.isStale) {
|
||||
if (index === -1) {
|
||||
this.staleObjects.push(id);
|
||||
}
|
||||
} else {
|
||||
if (index !== -1) {
|
||||
this.staleObjects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
loadingUpdated(loading) {
|
||||
this.loading = loading;
|
||||
this.$emit('loadingUpdated', ...arguments);
|
||||
},
|
||||
destroy() {
|
||||
if (this.stalenessSubscription) {
|
||||
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
|
||||
stalenessSubscription.unsubscribe();
|
||||
stalenessSubscription.stalenessUtils.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
if (this.compositionCollection) {
|
||||
this.compositionCollection.off('add', this.addItem);
|
||||
this.compositionCollection.off('remove', this.removeItem);
|
||||
this.compositionCollection.off('add', this.subscribeToStaleness);
|
||||
this.compositionCollection.off('remove', this.triggerUnsubscribeFromStaleness);
|
||||
}
|
||||
|
||||
this.imageExporter = null;
|
||||
|
@ -20,12 +20,10 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
|
||||
<template>
|
||||
<div class="gl-plot-chart-area">
|
||||
<span v-html="canvasTemplate"></span>
|
||||
<span v-html="canvasTemplate"></span>
|
||||
<canvas :style="canvasStyle"></canvas>
|
||||
<canvas :style="canvasStyle"></canvas>
|
||||
<div ref="limitArea" class="js-limit-area">
|
||||
<limit-label
|
||||
v-for="(limitLabel, index) in visibleLimitLabels"
|
||||
@ -146,12 +144,20 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
canvasTemplate:
|
||||
'<canvas style="position: absolute; background: none; width: 100%; height: 100%;"></canvas>',
|
||||
visibleLimitLabels: [],
|
||||
visibleLimitLines: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
canvasStyle() {
|
||||
return {
|
||||
position: 'absolute',
|
||||
background: 'none',
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
highlights: {
|
||||
handler() {
|
||||
@ -487,7 +493,10 @@ export default {
|
||||
// Have to throw away the old canvas elements and replace with new
|
||||
// canvas elements in order to get new drawing contexts.
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = this.canvasTemplate + this.canvasTemplate;
|
||||
div.innerHTML = `
|
||||
<canvas style="position: absolute; background: none; width: 100%; height: 100%;"></canvas>
|
||||
<canvas style="position: absolute; background: none; width: 100%; height: 100%;"></canvas>
|
||||
`;
|
||||
const mainCanvas = div.querySelectorAll('canvas')[1];
|
||||
const overlayCanvas = div.querySelectorAll('canvas')[0];
|
||||
this.canvas.parentNode.replaceChild(mainCanvas, this.canvas);
|
||||
|
@ -127,6 +127,10 @@ export default {
|
||||
this.config.series.forEach(this.onSeriesAdd, this);
|
||||
this.legend = this.config.legend;
|
||||
this.loaded = true;
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.stopListening();
|
||||
|
@ -150,6 +150,10 @@ export default {
|
||||
this.config.series.forEach(this.onSeriesAdd, this);
|
||||
this.legend = this.config.legend;
|
||||
this.loaded = true;
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.stopListening();
|
||||
|
@ -28,7 +28,6 @@ import mount from 'utils/mount';
|
||||
import configStore from '@/plugins/plot/configuration/ConfigStore';
|
||||
import PlotConfigurationModel from '@/plugins/plot/configuration/PlotConfigurationModel';
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
import StalenessUtils from '@/utils/staleness';
|
||||
|
||||
import Plot from '../Plot.vue';
|
||||
import conditionalStylesMixin from './mixins/objectStyles-mixin';
|
||||
@ -90,11 +89,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
staleObjects: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
gridLines(newGridLines) {
|
||||
this.updateComponentProp('gridLines', newGridLines);
|
||||
@ -116,20 +110,26 @@ export default {
|
||||
},
|
||||
staleObjects: {
|
||||
handler() {
|
||||
this.isStale = this.staleObjects.length > 0;
|
||||
this.updateComponentProp('isStale', this.isStale);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.stalenessSubscription = {};
|
||||
this.updateView();
|
||||
this.isEditing = this.openmct.editor.isEditing();
|
||||
this.openmct.editor.on('isEditing', this.setEditState);
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.openmct.editor.off('isEditing', this.setEditState);
|
||||
if (this.composition) {
|
||||
this.composition.off('add', this.subscribeToStaleness);
|
||||
this.composition.off('remove', this.triggerUnsubscribeFromStaleness);
|
||||
}
|
||||
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
@ -141,8 +141,6 @@ export default {
|
||||
if (this._destroy) {
|
||||
this._destroy();
|
||||
}
|
||||
|
||||
this.destroyStalenessListeners();
|
||||
},
|
||||
methods: {
|
||||
setEditState(isEditing) {
|
||||
@ -163,10 +161,6 @@ export default {
|
||||
}
|
||||
},
|
||||
updateView() {
|
||||
this.isStale = false;
|
||||
|
||||
this.destroyStalenessListeners();
|
||||
|
||||
if (this._destroy) {
|
||||
this._destroy();
|
||||
this.component = null;
|
||||
@ -190,15 +184,15 @@ export default {
|
||||
const isMissing = openmct.objects.isMissing(object);
|
||||
|
||||
if (this.openmct.telemetry.isTelemetryObject(object)) {
|
||||
this.subscribeToStaleness(object, (isStale) => {
|
||||
this.updateComponentProp('isStale', isStale);
|
||||
this.subscribeToStaleness(object, (stalenessResponse) => {
|
||||
this.updateComponentProp('isStale', stalenessResponse.isStale);
|
||||
});
|
||||
} else {
|
||||
// possibly overlay or other composition based plot
|
||||
this.composition = this.openmct.composition.get(object);
|
||||
|
||||
this.composition.on('add', this.watchStaleness);
|
||||
this.composition.on('remove', this.unwatchStaleness);
|
||||
this.composition.on('add', this.subscribeToStaleness);
|
||||
this.composition.on('remove', this.triggerUnsubscribeFromStaleness);
|
||||
this.composition.load();
|
||||
}
|
||||
|
||||
@ -260,54 +254,6 @@ export default {
|
||||
this.setSelection();
|
||||
}
|
||||
},
|
||||
watchStaleness(domainObject) {
|
||||
const keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
this.stalenessSubscription[keyString] = {};
|
||||
this.stalenessSubscription[keyString].stalenessUtils = new StalenessUtils(
|
||||
this.openmct,
|
||||
domainObject
|
||||
);
|
||||
|
||||
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
});
|
||||
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
|
||||
domainObject,
|
||||
(stalenessResponse) => {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
);
|
||||
|
||||
this.stalenessSubscription[keyString].unsubscribe = stalenessSubscription;
|
||||
},
|
||||
unwatchStaleness(domainObject) {
|
||||
const SKIP_CHECK = true;
|
||||
const keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
this.stalenessSubscription[keyString].unsubscribe();
|
||||
this.stalenessSubscription[keyString].stalenessUtils.destroy();
|
||||
this.handleStaleness(keyString, { isStale: false }, SKIP_CHECK);
|
||||
|
||||
delete this.stalenessSubscription[keyString];
|
||||
},
|
||||
handleStaleness(keyString, stalenessResponse, skipCheck = false) {
|
||||
if (
|
||||
skipCheck ||
|
||||
this.stalenessSubscription[keyString].stalenessUtils.shouldUpdateStaleness(
|
||||
stalenessResponse
|
||||
)
|
||||
) {
|
||||
const index = this.staleObjects.indexOf(keyString);
|
||||
const foundStaleObject = index > -1;
|
||||
if (stalenessResponse.isStale && !foundStaleObject) {
|
||||
this.staleObjects.push(keyString);
|
||||
} else if (!stalenessResponse.isStale && foundStaleObject) {
|
||||
this.staleObjects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
onLockHighlightPointUpdated() {
|
||||
this.$emit('lockHighlightPoint', ...arguments);
|
||||
},
|
||||
@ -405,20 +351,6 @@ export default {
|
||||
|
||||
return this.childObject;
|
||||
}
|
||||
},
|
||||
destroyStalenessListeners() {
|
||||
this.triggerUnsubscribeFromStaleness();
|
||||
|
||||
if (this.composition) {
|
||||
this.composition.off('add', this.watchStaleness);
|
||||
this.composition.off('remove', this.unwatchStaleness);
|
||||
this.composition = null;
|
||||
}
|
||||
|
||||
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
|
||||
stalenessSubscription.unsubscribe();
|
||||
stalenessSubscription.stalenessUtils.destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -214,7 +214,7 @@ define([
|
||||
const options = this.generateSelectOptions();
|
||||
|
||||
newInput = document.createElement('select');
|
||||
newInput.innerHTML = options;
|
||||
newInput.appendChild(options);
|
||||
|
||||
emitChange = true;
|
||||
} else {
|
||||
@ -244,12 +244,16 @@ define([
|
||||
|
||||
Condition.prototype.generateSelectOptions = function () {
|
||||
let telemetryMetadata = this.conditionManager.getTelemetryMetadata(this.config.object);
|
||||
let options = '';
|
||||
let fragment = document.createDocumentFragment();
|
||||
|
||||
telemetryMetadata[this.config.key].enumerations.forEach((enumeration) => {
|
||||
options += '<option value="' + enumeration.value + '">' + enumeration.string + '</option>';
|
||||
const option = document.createElement('option');
|
||||
option.value = enumeration.value;
|
||||
option.textContent = enumeration.string;
|
||||
fragment.appendChild(option);
|
||||
});
|
||||
|
||||
return options;
|
||||
return fragment;
|
||||
};
|
||||
|
||||
return Condition;
|
||||
|
@ -167,7 +167,8 @@ define([
|
||||
const ruleHeader = self.domElement
|
||||
.querySelectorAll('.widget-rule-header')[0]
|
||||
.cloneNode(true);
|
||||
indicator.innerHTML = ruleHeader;
|
||||
indicator.textContent = '';
|
||||
indicator.appendChild(ruleHeader);
|
||||
});
|
||||
self.widgetDnD.setDragImage(
|
||||
self.domElement.querySelectorAll('.widget-rule-header')[0].cloneNode(true)
|
||||
@ -239,8 +240,8 @@ define([
|
||||
this.listenTo(this.toggleConfigButton, 'click', toggleConfig);
|
||||
this.listenTo(this.trigger, 'change', onTriggerInput);
|
||||
|
||||
this.title.innerHTML = self.config.name;
|
||||
this.description.innerHTML = self.config.description;
|
||||
this.title.innerText = self.config.name;
|
||||
this.description.innerText = self.config.description;
|
||||
this.trigger.value = self.config.trigger;
|
||||
|
||||
this.listenTo(this.grippy, 'mousedown', onDragStart);
|
||||
@ -456,7 +457,7 @@ define([
|
||||
const lastOfType = self.conditionArea.querySelector('li:last-of-type');
|
||||
lastOfType.parentNode.insertBefore($condition, lastOfType);
|
||||
if (loopCnt > 0) {
|
||||
$condition.querySelector('.t-condition-context').innerHTML = triggerContextStr + ' when';
|
||||
$condition.querySelector('.t-condition-context').innerText = triggerContextStr + ' when';
|
||||
}
|
||||
|
||||
loopCnt++;
|
||||
@ -528,7 +529,7 @@ define([
|
||||
}
|
||||
|
||||
description = description === '' ? this.config.description : description;
|
||||
this.description.innerHTML = self.config.description;
|
||||
this.description.innerText = self.config.description;
|
||||
this.config.description = description;
|
||||
};
|
||||
|
||||
|
@ -247,9 +247,10 @@ define([
|
||||
SummaryWidget.prototype.updateWidget = function () {
|
||||
const WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';
|
||||
const activeRule = this.rulesById[this.activeId];
|
||||
|
||||
this.applyStyle(this.domElement.querySelector('#widget'), activeRule.getProperty('style'));
|
||||
this.domElement.querySelector('#widget').title = activeRule.getProperty('message');
|
||||
this.domElement.querySelector('#widgetLabel').innerHTML = activeRule.getProperty('label');
|
||||
this.domElement.querySelector('#widgetLabel').textContent = activeRule.getProperty('label');
|
||||
this.domElement.querySelector('#widgetIcon').classList =
|
||||
WIDGET_ICON_CLASS + ' ' + activeRule.getProperty('icon');
|
||||
};
|
||||
|
@ -44,11 +44,12 @@ define([
|
||||
self.setNullOption(this.nullOption);
|
||||
|
||||
self.items.forEach(function (item) {
|
||||
const itemElement = `<div class = "c-palette__item ${item}" data-item = "${item}"></div>`;
|
||||
const temp = document.createElement('div');
|
||||
temp.innerHTML = itemElement;
|
||||
self.itemElements[item] = temp.firstChild;
|
||||
self.domElement.querySelector('.c-palette__items').appendChild(temp.firstChild);
|
||||
const itemElement = document.createElement('div');
|
||||
itemElement.className = 'c-palette__item ' + item;
|
||||
itemElement.setAttribute('data-item', item);
|
||||
|
||||
self.itemElements[item] = itemElement;
|
||||
self.domElement.querySelector('.c-palette__items').appendChild(itemElement);
|
||||
});
|
||||
|
||||
self.domElement.querySelector('.c-menu').style.display = 'none';
|
||||
|
@ -1,35 +1,60 @@
|
||||
define(['./summary-widget.html', '@braintree/sanitize-url'], function (
|
||||
summaryWidgetTemplate,
|
||||
urlSanitizeLib
|
||||
) {
|
||||
const WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';
|
||||
import * as urlSanitizeLib from '@braintree/sanitize-url';
|
||||
|
||||
function SummaryWidgetView(domainObject, openmct) {
|
||||
const WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';
|
||||
|
||||
class SummaryWidgetView {
|
||||
#createSummaryWidgetTemplate() {
|
||||
const anchor = document.createElement('a');
|
||||
anchor.classList.add(
|
||||
't-summary-widget',
|
||||
'c-summary-widget',
|
||||
'js-sw',
|
||||
'u-links',
|
||||
'u-fills-container'
|
||||
);
|
||||
|
||||
const widgetIcon = document.createElement('div');
|
||||
widgetIcon.id = 'widgetIcon';
|
||||
widgetIcon.classList.add('c-sw__icon', 'js-sw__icon');
|
||||
anchor.appendChild(widgetIcon);
|
||||
|
||||
const widgetLabel = document.createElement('div');
|
||||
widgetLabel.id = 'widgetLabel';
|
||||
widgetLabel.classList.add('c-sw__label', 'js-sw__label');
|
||||
widgetLabel.textContent = 'Loading...';
|
||||
anchor.appendChild(widgetLabel);
|
||||
|
||||
return anchor;
|
||||
}
|
||||
|
||||
constructor(domainObject, openmct) {
|
||||
this.openmct = openmct;
|
||||
this.domainObject = domainObject;
|
||||
this.hasUpdated = false;
|
||||
this.render = this.render.bind(this);
|
||||
}
|
||||
|
||||
SummaryWidgetView.prototype.updateState = function (datum) {
|
||||
updateState(datum) {
|
||||
this.hasUpdated = true;
|
||||
this.widget.style.color = datum.textColor;
|
||||
this.widget.style.backgroundColor = datum.backgroundColor;
|
||||
this.widget.style.borderColor = datum.borderColor;
|
||||
this.widget.title = datum.message;
|
||||
this.label.title = datum.message;
|
||||
this.label.innerHTML = datum.ruleLabel;
|
||||
this.label.textContent = datum.ruleLabel;
|
||||
this.icon.className = WIDGET_ICON_CLASS + ' ' + datum.icon;
|
||||
};
|
||||
}
|
||||
|
||||
SummaryWidgetView.prototype.render = function () {
|
||||
render() {
|
||||
if (this.unsubscribe) {
|
||||
this.unsubscribe();
|
||||
}
|
||||
|
||||
this.hasUpdated = false;
|
||||
|
||||
this.container.innerHTML = summaryWidgetTemplate;
|
||||
const anchor = this.#createSummaryWidgetTemplate();
|
||||
this.container.appendChild(anchor);
|
||||
|
||||
this.widget = this.container.querySelector('a');
|
||||
this.icon = this.container.querySelector('#widgetIcon');
|
||||
this.label = this.container.querySelector('.js-sw__label');
|
||||
@ -49,33 +74,32 @@ define(['./summary-widget.html', '@braintree/sanitize-url'], function (
|
||||
|
||||
const renderTracker = {};
|
||||
this.renderTracker = renderTracker;
|
||||
|
||||
this.openmct.telemetry
|
||||
.request(this.domainObject, {
|
||||
strategy: 'latest',
|
||||
size: 1
|
||||
})
|
||||
.then(
|
||||
function (results) {
|
||||
if (
|
||||
this.destroyed ||
|
||||
this.hasUpdated ||
|
||||
this.renderTracker !== renderTracker ||
|
||||
results.length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
.then((results) => {
|
||||
if (
|
||||
this.destroyed ||
|
||||
this.hasUpdated ||
|
||||
this.renderTracker !== renderTracker ||
|
||||
results.length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateState(results[results.length - 1]);
|
||||
}.bind(this)
|
||||
);
|
||||
this.updateState(results[results.length - 1]);
|
||||
});
|
||||
|
||||
this.unsubscribe = this.openmct.telemetry.subscribe(
|
||||
this.domainObject,
|
||||
this.updateState.bind(this)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
SummaryWidgetView.prototype.show = function (container) {
|
||||
show(container) {
|
||||
this.container = container;
|
||||
this.render();
|
||||
this.removeMutationListener = this.openmct.objects.observe(
|
||||
@ -84,14 +108,14 @@ define(['./summary-widget.html', '@braintree/sanitize-url'], function (
|
||||
this.onMutation.bind(this)
|
||||
);
|
||||
this.openmct.time.on('timeSystem', this.render);
|
||||
};
|
||||
}
|
||||
|
||||
SummaryWidgetView.prototype.onMutation = function (domainObject) {
|
||||
onMutation(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.render();
|
||||
};
|
||||
}
|
||||
|
||||
SummaryWidgetView.prototype.destroy = function (container) {
|
||||
destroy() {
|
||||
this.unsubscribe();
|
||||
this.removeMutationListener();
|
||||
this.openmct.time.off('timeSystem', this.render);
|
||||
@ -100,7 +124,7 @@ define(['./summary-widget.html', '@braintree/sanitize-url'], function (
|
||||
delete this.label;
|
||||
delete this.openmct;
|
||||
delete this.domainObject;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return SummaryWidgetView;
|
||||
});
|
||||
export default SummaryWidgetView;
|
||||
|
@ -1,4 +0,0 @@
|
||||
<a class="t-summary-widget c-summary-widget js-sw u-links u-fills-container">
|
||||
<div id="widgetIcon" class="c-sw__icon js-sw__icon"></div>
|
||||
<div id="widgetLabel" class="c-sw__label js-sw__label">Loading...</div>
|
||||
</a>
|
@ -55,6 +55,7 @@ define([
|
||||
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
|
||||
this.telemetryObjects = {};
|
||||
this.subscribedStaleObjects = new Map();
|
||||
this.telemetryCollections = {};
|
||||
this.delayedActions = [];
|
||||
this.outstandingRequests = 0;
|
||||
@ -74,6 +75,8 @@ define([
|
||||
this.filterObserver = undefined;
|
||||
|
||||
this.createTableRowCollections();
|
||||
this.resubscribeToStaleness = this.resubscribeAllObjectsToStaleness.bind(this);
|
||||
this.openmct.time.on('clockChanged', this.resubscribeToStaleness);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,24 +166,7 @@ define([
|
||||
this.telemetryCollections[keyString].on('clear', this.clearData);
|
||||
this.telemetryCollections[keyString].load();
|
||||
|
||||
this.stalenessSubscription[keyString] = {};
|
||||
this.stalenessSubscription[keyString].stalenessUtils = new StalenessUtils.default(
|
||||
this.openmct,
|
||||
telemetryObject
|
||||
);
|
||||
this.openmct.telemetry.isStale(telemetryObject).then((stalenessResponse) => {
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
});
|
||||
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
|
||||
telemetryObject,
|
||||
(stalenessResponse) => {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
);
|
||||
|
||||
this.stalenessSubscription[keyString].unsubscribe = stalenessSubscription;
|
||||
this.subscribeToStaleness(telemetryObject);
|
||||
|
||||
this.telemetryObjects[keyString] = {
|
||||
telemetryObject,
|
||||
@ -193,6 +179,42 @@ define([
|
||||
this.emit('object-added', telemetryObject);
|
||||
}
|
||||
|
||||
resubscribeAllObjectsToStaleness() {
|
||||
if (!this.subscribedStaleObjects || this.subscribedStaleObjects.size < 1) {
|
||||
return;
|
||||
}
|
||||
for (const [, telemetryObject] of this.subscribedStaleObjects) {
|
||||
this.subscribeToStaleness(telemetryObject);
|
||||
}
|
||||
}
|
||||
|
||||
subscribeToStaleness(domainObject) {
|
||||
const keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
if (this.stalenessSubscription?.[keyString]) {
|
||||
this.unsubscribeFromStaleness(domainObject.identifier);
|
||||
}
|
||||
|
||||
this.stalenessSubscription[keyString] = {};
|
||||
this.stalenessSubscription[keyString].stalenessUtils = new StalenessUtils.default(
|
||||
this.openmct,
|
||||
domainObject
|
||||
);
|
||||
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
});
|
||||
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
|
||||
domainObject,
|
||||
(stalenessResponse) => {
|
||||
this.handleStaleness(keyString, stalenessResponse);
|
||||
}
|
||||
);
|
||||
this.subscribedStaleObjects.set(keyString, domainObject);
|
||||
|
||||
this.stalenessSubscription[keyString].unsubscribe = stalenessSubscription;
|
||||
}
|
||||
|
||||
handleStaleness(keyString, stalenessResponse, skipCheck = false) {
|
||||
if (
|
||||
skipCheck ||
|
||||
@ -203,7 +225,7 @@ define([
|
||||
) {
|
||||
this.emit('telemetry-staleness', {
|
||||
keyString,
|
||||
isStale: stalenessResponse.isStale
|
||||
stalenessResponse: stalenessResponse
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -310,7 +332,6 @@ define([
|
||||
|
||||
removeTelemetryObject(objectIdentifier) {
|
||||
const keyString = this.openmct.objects.makeKeyString(objectIdentifier);
|
||||
const SKIP_CHECK = true;
|
||||
|
||||
this.configuration.removeColumnsForObject(objectIdentifier, true);
|
||||
this.tableRows.removeRowsByObject(keyString);
|
||||
@ -320,6 +341,13 @@ define([
|
||||
|
||||
this.emit('object-removed', objectIdentifier);
|
||||
|
||||
this.unsubscribeFromStaleness(objectIdentifier);
|
||||
}
|
||||
|
||||
unsubscribeFromStaleness(objectIdentifier) {
|
||||
const keyString = this.openmct.objects.makeKeyString(objectIdentifier);
|
||||
const SKIP_CHECK = true;
|
||||
|
||||
this.stalenessSubscription[keyString].unsubscribe();
|
||||
this.stalenessSubscription[keyString].stalenessUtils.destroy();
|
||||
this.handleStaleness(keyString, { isStale: false }, SKIP_CHECK);
|
||||
@ -423,6 +451,7 @@ define([
|
||||
this.tableRows.destroy();
|
||||
|
||||
this.tableRows.off('resetRowsFromAllData', this.resetRowsFromAllData);
|
||||
this.openmct.time.off('clockChanged', this.resubscribeToStaleness);
|
||||
|
||||
let keystrings = Object.keys(this.telemetryCollections);
|
||||
keystrings.forEach(this.removeTelemetryCollection);
|
||||
|
@ -275,6 +275,7 @@
|
||||
<script>
|
||||
import _ from 'lodash';
|
||||
import { toRaw } from 'vue';
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
|
||||
import CSVExporter from '../../../exporters/CSVExporter.js';
|
||||
import ProgressBar from '../../../ui/components/ProgressBar.vue';
|
||||
@ -300,6 +301,7 @@ export default {
|
||||
SizingRow,
|
||||
ProgressBar
|
||||
},
|
||||
mixins: [stalenessMixin],
|
||||
inject: ['openmct', 'objectPath', 'table', 'currentView'],
|
||||
props: {
|
||||
isEditing: {
|
||||
@ -370,8 +372,7 @@ export default {
|
||||
enableRegexSearch: {},
|
||||
hideHeaders: configuration.hideHeaders,
|
||||
totalNumberOfRows: 0,
|
||||
rowContext: {},
|
||||
staleObjects: []
|
||||
rowContext: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -414,7 +415,7 @@ export default {
|
||||
classes.push('is-paused');
|
||||
}
|
||||
|
||||
if (this.staleObjects.length !== 0) {
|
||||
if (this.isStale) {
|
||||
classes.push('is-stale');
|
||||
}
|
||||
|
||||
@ -745,17 +746,8 @@ export default {
|
||||
outstandingRequests(loading) {
|
||||
this.loading = loading;
|
||||
},
|
||||
handleStaleness({ keyString, isStale }) {
|
||||
const index = this.staleObjects.indexOf(keyString);
|
||||
if (isStale) {
|
||||
if (index === -1) {
|
||||
this.staleObjects.push(keyString);
|
||||
}
|
||||
} else {
|
||||
if (index !== -1) {
|
||||
this.staleObjects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
handleStaleness({ keyString, stalenessResponse }) {
|
||||
this.addOrRemoveStaleObject(keyString, stalenessResponse);
|
||||
},
|
||||
calculateTableSize() {
|
||||
this.$nextTick().then(this.calculateColumnWidths);
|
||||
|
@ -139,6 +139,10 @@ export default {
|
||||
this.initObjectStyles();
|
||||
this.triggerStalenessSubscribe(this.domainObject);
|
||||
}
|
||||
this.setupClockChangedEvent((domainObject) => {
|
||||
this.triggerUnsubscribeFromStaleness(domainObject);
|
||||
this.subscribeToStaleness(domainObject);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
clear() {
|
||||
@ -172,8 +176,7 @@ export default {
|
||||
this.composition._destroy();
|
||||
}
|
||||
|
||||
this.isStale = false;
|
||||
this.triggerUnsubscribeFromStaleness();
|
||||
this.triggerUnsubscribeFromStaleness(this.domainObject);
|
||||
|
||||
this.openmct.objectViews.off('clearData', this.clearData);
|
||||
this.openmct.objectViews.off('contextAction', this.performContextAction);
|
||||
|
@ -20,52 +20,190 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import { isProxy, toRaw } from 'vue';
|
||||
|
||||
import StalenessUtils from '@/utils/staleness';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isStale: false
|
||||
staleObjects: [],
|
||||
stalenessSubscription: {},
|
||||
compositionObjectMap: new Map(),
|
||||
setupClockChanged: false
|
||||
};
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.triggerUnsubscribeFromStaleness();
|
||||
computed: {
|
||||
isStale() {
|
||||
return this.staleObjects.length !== 0;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
subscribeToStaleness(domainObject, callback) {
|
||||
if (!this.stalenessUtils) {
|
||||
this.stalenessUtils = new StalenessUtils(this.openmct, domainObject);
|
||||
getSubscriptionId(domainObject) {
|
||||
return this.openmct?.objects.makeKeyString(domainObject.identifier);
|
||||
},
|
||||
setupClockChangedEvent(callback) {
|
||||
this.setupClockChanged = true;
|
||||
this.compositionIteratorCallback = this.compositionIterator(callback);
|
||||
this.openmct.time.on('clockChanged', this.compositionIteratorCallback);
|
||||
},
|
||||
addToCompositionMap(id, domainObject) {
|
||||
if (!this.compositionObjectMap.get(id)) {
|
||||
this.compositionObjectMap.set(id, domainObject);
|
||||
}
|
||||
},
|
||||
compositionIterator(callback) {
|
||||
return () => {
|
||||
this.staleObjects = [];
|
||||
for (const [, object] of this.compositionObjectMap) {
|
||||
let domainObject = object;
|
||||
if (isProxy(domainObject)) {
|
||||
domainObject = toRaw(object);
|
||||
}
|
||||
if (callback && typeof callback === 'function') {
|
||||
callback(domainObject);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
subscribeToStaleness(domainObjectList, callback) {
|
||||
if (domainObjectList === null || domainObjectList === undefined) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(domainObjectList)) {
|
||||
domainObjectList = [domainObjectList];
|
||||
}
|
||||
|
||||
this.requestStaleness(domainObject);
|
||||
this.unsubscribeFromStaleness = this.openmct.telemetry.subscribeToStaleness(
|
||||
domainObjectList.forEach((domainObject) => {
|
||||
if (isProxy(domainObject)) {
|
||||
domainObject = toRaw(domainObject);
|
||||
}
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
this.addToCompositionMap(id, domainObject);
|
||||
this.setupStalenessUtils(domainObject);
|
||||
this.requestStaleness(domainObject, callback);
|
||||
this.setupStalenessSubscription(domainObject, callback);
|
||||
});
|
||||
},
|
||||
triggerUnsubscribeFromStaleness(domainObjectList, callback) {
|
||||
if (domainObjectList === null || domainObjectList === undefined) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(domainObjectList)) {
|
||||
domainObjectList = [domainObjectList];
|
||||
}
|
||||
|
||||
domainObjectList.forEach((domainObject) => {
|
||||
if (isProxy(domainObject)) {
|
||||
domainObject = toRaw(domainObject);
|
||||
}
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
if (!this.stalenessSubscription[id]) {
|
||||
return;
|
||||
}
|
||||
if (this.staleObjects.length !== 0) {
|
||||
const SKIP_CHECK = true;
|
||||
this.handleStalenessResponse(id, { isStale: false }, SKIP_CHECK);
|
||||
}
|
||||
this.teardownStalenessSubscription(domainObject);
|
||||
this.teardownStalenessUtils(domainObject);
|
||||
delete this.stalenessSubscription[id];
|
||||
});
|
||||
|
||||
if (callback && typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
setupStalenessUtils(domainObject) {
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
if (this.stalenessSubscription[id]) {
|
||||
return;
|
||||
}
|
||||
this.stalenessSubscription[id] = {};
|
||||
this.stalenessSubscription[id].stalenessUtils = new StalenessUtils(
|
||||
this.openmct,
|
||||
domainObject
|
||||
);
|
||||
},
|
||||
teardownStalenessUtils(domainObject) {
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
const { stalenessUtils } = this.stalenessSubscription[id];
|
||||
if (stalenessUtils) {
|
||||
stalenessUtils.destroy();
|
||||
delete this.stalenessSubscription[id].stalenessUtils;
|
||||
}
|
||||
},
|
||||
setupStalenessSubscription(domainObject, callback) {
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
this.stalenessSubscription[id].unsubscribe = this.openmct.telemetry.subscribeToStaleness(
|
||||
domainObject,
|
||||
(stalenessResponse) => {
|
||||
this.handleStalenessResponse(stalenessResponse, callback);
|
||||
const SKIP_CHECK = false;
|
||||
this.handleStalenessResponse(id, stalenessResponse, SKIP_CHECK, callback);
|
||||
}
|
||||
);
|
||||
},
|
||||
async requestStaleness(domainObject) {
|
||||
const stalenessResponse = await this.openmct.telemetry.isStale(domainObject);
|
||||
if (stalenessResponse !== undefined) {
|
||||
this.handleStalenessResponse(stalenessResponse);
|
||||
teardownStalenessSubscription(domainObject) {
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
const { unsubscribe } = this.stalenessSubscription[id];
|
||||
if (unsubscribe) {
|
||||
unsubscribe();
|
||||
delete this.stalenessSubscription[id].unsubscribe;
|
||||
}
|
||||
},
|
||||
handleStalenessResponse(stalenessResponse, callback) {
|
||||
if (this.stalenessUtils.shouldUpdateStaleness(stalenessResponse)) {
|
||||
if (typeof callback === 'function') {
|
||||
callback(stalenessResponse.isStale);
|
||||
resubscribeToStaleness(domainObject, callback, unsubscribeCallback) {
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
this.stalenessSubscription[id].resubscribe = () => {
|
||||
this.staleObjects = [];
|
||||
this.triggerUnsubscribeFromStaleness(domainObject, unsubscribeCallback);
|
||||
this.setupStalenessSubscription(domainObject, callback);
|
||||
};
|
||||
},
|
||||
async requestStaleness(domainObject, callback) {
|
||||
const id = this.getSubscriptionId(domainObject);
|
||||
const stalenessResponse = await this.openmct.telemetry.isStale(domainObject);
|
||||
if (stalenessResponse !== undefined) {
|
||||
const SKIP_CHECK = false;
|
||||
this.handleStalenessResponse(id, stalenessResponse, SKIP_CHECK, callback);
|
||||
}
|
||||
},
|
||||
handleStalenessResponse(id, stalenessResponse, skipCheck, callback) {
|
||||
if (!id) {
|
||||
id = Object.keys(this.stalenessSubscription)[0];
|
||||
}
|
||||
const shouldUpdateStaleness =
|
||||
this.stalenessSubscription[id].stalenessUtils.shouldUpdateStaleness(stalenessResponse);
|
||||
if (skipCheck || shouldUpdateStaleness) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
callback(stalenessResponse);
|
||||
} else {
|
||||
this.isStale = stalenessResponse.isStale;
|
||||
this.addOrRemoveStaleObject(id, stalenessResponse);
|
||||
}
|
||||
}
|
||||
},
|
||||
triggerUnsubscribeFromStaleness() {
|
||||
if (this.unsubscribeFromStaleness) {
|
||||
this.unsubscribeFromStaleness();
|
||||
delete this.unsubscribeFromStaleness;
|
||||
this.stalenessUtils.destroy();
|
||||
addOrRemoveStaleObject(id, stalenessResponse) {
|
||||
const index = this.staleObjects.indexOf(id);
|
||||
if (stalenessResponse.isStale) {
|
||||
if (index === -1) {
|
||||
this.staleObjects.push(id);
|
||||
}
|
||||
} else {
|
||||
if (index !== -1) {
|
||||
this.staleObjects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
unmounted() {
|
||||
let compositionObjects = [];
|
||||
for (const [, object] of this.compositionObjectMap) {
|
||||
compositionObjects.push(object);
|
||||
}
|
||||
this.triggerUnsubscribeFromStaleness(compositionObjects);
|
||||
|
||||
if (this.setupClockChanged) {
|
||||
this.openmct.time.off('clockChanged', this.compositionIteratorCallback);
|
||||
this.setupClockChanged = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -33,8 +33,10 @@ export default class StalenessUtils {
|
||||
|
||||
shouldUpdateStaleness(stalenessResponse, id) {
|
||||
const stalenessResponseTime = this.parseTime(stalenessResponse);
|
||||
const { start } = this.openmct.time.bounds();
|
||||
const isStalenessInCurrentClock = stalenessResponseTime > start;
|
||||
|
||||
if (stalenessResponseTime > this.lastStalenessResponseTime) {
|
||||
if (stalenessResponseTime > this.lastStalenessResponseTime && isStalenessInCurrentClock) {
|
||||
this.lastStalenessResponseTime = stalenessResponseTime;
|
||||
|
||||
return true;
|
||||
|
@ -1,8 +1,17 @@
|
||||
export function convertTemplateToHTML(templateString) {
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = templateString;
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(templateString, 'text/html');
|
||||
|
||||
return template.content.cloneNode(true).children;
|
||||
// Create a document fragment to hold the parsed content
|
||||
const fragment = document.createDocumentFragment();
|
||||
|
||||
// Append nodes from the parsed content to the fragment
|
||||
while (doc.body.firstChild) {
|
||||
fragment.appendChild(doc.body.firstChild);
|
||||
}
|
||||
|
||||
// Convert children of the fragment to an array and return
|
||||
return Array.from(fragment.children);
|
||||
}
|
||||
|
||||
export function toggleClass(element, className) {
|
||||
|
Reference in New Issue
Block a user