[LAD Table/Table Sets] Configurable hidden columns (#6386)

* adding lad table configuration, specifically column visibility

* making sure units column checkbox is updated when lad tables are removed from lad table sets

* fixes based on PR feedback, copyright, consts, code, oh my!

* added a test for column hiding

* remove .only

* add a notification for inspector view that must be editing, move selection logic to vue component as it was not being triggered after navigating away in the inspector tabs
This commit is contained in:
Jamie V 2023-03-11 04:01:33 -08:00 committed by GitHub
parent 39cff51db0
commit b5002e166a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 556 additions and 17 deletions

View File

@ -23,6 +23,88 @@
const { test, expect } = require('../../../../pluginFixtures');
const { createDomainObjectWithDefaults, setStartOffset, setFixedTimeMode, setRealTimeMode } = require('../../../../appActions');
test.describe('Testing LAD table configuration', () => {
test.beforeEach(async ({ page }) => {
await page.goto('./', { waitUntil: 'networkidle' });
// Create Sine Wave Generator
await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator',
name: "Test Sine Wave Generator"
});
// Create LAD table
await createDomainObjectWithDefaults(page, {
type: 'LAD Table',
name: "Test LAD Table"
});
});
test('in edit mode, LAD Tables provide ability to hide columns', async ({ page }) => {
// Edit LAD table
await page.locator('[title="Edit"]').click();
// Expand the 'My Items' folder in the left tree
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
// Add the Sine Wave Generator to the LAD table and save changes
await page.dragAndDrop('role=treeitem[name=/Test Sine Wave Generator/]', '.c-lad-table-wrapper');
// select configuration tab in inspector
await page.getByRole('tab', { name: 'LAD Table Configuration' }).getByText('LAD Table Configuration').click();
// make sure headers are visible initially
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
// hide timestamp column
await page.getByLabel('Timestamp').uncheck();
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
// hide units column
await page.getByLabel('Units').uncheck();
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
// save and reload and verify they columns are still hidden
await page.locator('button[title="Save"]').click();
await page.locator('text=Save and Finish Editing').click();
await page.reload();
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
// Edit LAD table
await page.locator('[title="Edit"]').click();
await page.getByRole('tab', { name: 'LAD Table Configuration' }).getByText('LAD Table Configuration').click();
// show timestamp column
await page.getByLabel('Timestamp').check();
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
// save and reload and make sure only timestamp is still visible
await page.locator('button[title="Save"]').click();
await page.locator('text=Save and Finish Editing').click();
await page.reload();
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
// Edit LAD table
await page.locator('[title="Edit"]').click();
await page.getByRole('tab', { name: 'LAD Table Configuration' }).getByText('LAD Table Configuration').click();
// show units column
await page.getByLabel('Units').check();
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
// save and reload and make sure both columns are still visible
await page.locator('button[title="Save"]').click();
await page.locator('text=Save and Finish Editing').click();
await page.reload();
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
});
});
test.describe('Testing LAD table @unstable', () => {
let sineWaveObject;
test.beforeEach(async ({ page }) => {

View File

@ -0,0 +1,56 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2023, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import EventEmitter from 'EventEmitter';
export default class LADTableConfiguration extends EventEmitter {
constructor(domainObject, openmct) {
super();
this.domainObject = domainObject;
this.openmct = openmct;
this.objectMutated = this.objectMutated.bind(this);
this.unlistenFromMutation = openmct.objects.observe(domainObject, 'configuration', this.objectMutated);
}
getConfiguration() {
const configuration = this.domainObject.configuration || {};
configuration.hiddenColumns = configuration.hiddenColumns || {};
return configuration;
}
updateConfiguration(configuration) {
this.openmct.objects.mutate(this.domainObject, 'configuration', configuration);
}
objectMutated(configuration) {
if (configuration !== undefined) {
this.emit('change', configuration);
}
}
destroy() {
this.unlistenFromMutation();
}
}

View File

@ -0,0 +1,67 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2023, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import LADTableConfigurationComponent from './components/LADTableConfiguration.vue';
import Vue from 'vue';
export default function LADTableConfigurationViewProvider(openmct) {
return {
key: 'lad-table-configuration',
name: 'LAD Table Configuration',
canView(selection) {
if (selection.length !== 1 || selection[0].length === 0) {
return false;
}
const object = selection[0][0].context.item;
return object?.type === 'LadTable' || object?.type === 'LadTableSet';
},
view(selection) {
let component;
return {
show(element) {
component = new Vue({
el: element,
components: {
LADTableConfiguration: LADTableConfigurationComponent
},
provide: {
openmct
},
template: '<LADTableConfiguration />'
});
},
destroy() {
if (component) {
component.$destroy();
component = undefined;
}
}
};
},
priority() {
return 1;
}
};
}

View File

@ -1,5 +1,27 @@
import LadTable from './components/LADTable.vue';
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2023, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import LadTable from './components/LADTable.vue';
import LADTableConfiguration from './LADTableConfiguration';
import Vue from 'vue';
export default class LADTableView {
@ -11,6 +33,8 @@ export default class LADTableView {
}
show(element) {
let ladTableConfiguration = new LADTableConfiguration(this.domainObject, this.openmct);
this.component = new Vue({
el: element,
components: {
@ -18,7 +42,8 @@ export default class LADTableView {
},
provide: {
openmct: this.openmct,
currentView: this
currentView: this,
ladTableConfiguration
},
data: () => {
return {

View File

@ -1,5 +1,27 @@
import LadTableSet from './components/LadTableSet.vue';
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2023, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import LadTableSet from './components/LadTableSet.vue';
import LADTableConfiguration from './LADTableConfiguration';
import Vue from 'vue';
export default class LadTableSetView {
@ -11,6 +33,8 @@ export default class LadTableSetView {
}
show(element) {
let ladTableConfiguration = new LADTableConfiguration(this.domainObject, this.openmct);
this.component = new Vue({
el: element,
components: {
@ -19,7 +43,8 @@ export default class LadTableSetView {
provide: {
openmct: this.openmct,
objectPath: this.objectPath,
currentView: this
currentView: this,
ladTableConfiguration
},
data: () => {
return {

View File

@ -26,7 +26,10 @@
@contextmenu.prevent="showContextMenu"
>
<td class="js-first-data">{{ domainObject.name }}</td>
<td class="js-second-data">{{ formattedTimestamp }}</td>
<td
v-if="showTimestamp"
class="js-second-data"
>{{ formattedTimestamp }}</td>
<td
class="js-third-data"
:class="valueClasses"
@ -69,6 +72,10 @@ export default {
default() {
return false;
}
},
configuration: {
type: Object,
required: true
}
},
data() {
@ -121,6 +128,9 @@ export default {
},
objectPath() {
return [this.domainObject, ...this.pathToTable];
},
showTimestamp() {
return !this.configuration?.hiddenColumns?.timestamp;
}
},
mounted() {

View File

@ -29,9 +29,9 @@
<thead>
<tr>
<th>Name</th>
<th>Timestamp</th>
<th v-if="showTimestamp">Timestamp</th>
<th>Value</th>
<th v-if="hasUnits">Unit</th>
<th v-if="hasUnits">Units</th>
</tr>
</thead>
<tbody>
@ -42,6 +42,7 @@
:path-to-table="objectPath"
:has-units="hasUnits"
:is-stale="staleObjects.includes(ladRow.key)"
:configuration="configuration"
@rowContextClick="updateViewContext"
/>
</tbody>
@ -58,7 +59,7 @@ export default {
components: {
LadRow
},
inject: ['openmct', 'currentView'],
inject: ['openmct', 'currentView', 'ladTableConfiguration'],
props: {
domainObject: {
type: Object,
@ -73,7 +74,8 @@ export default {
return {
items: [],
viewContext: {},
staleObjects: []
staleObjects: [],
configuration: this.ladTableConfiguration.getConfiguration()
};
},
computed: {
@ -86,7 +88,10 @@ export default {
});
return itemsWithUnits.length !== 0;
return itemsWithUnits.length !== 0 && !this.configuration?.hiddenColumns?.units;
},
showTimestamp() {
return !this.configuration?.hiddenColumns?.timestamp;
},
staleClass() {
if (this.staleObjects.length !== 0) {
@ -97,6 +102,7 @@ export default {
}
},
mounted() {
this.ladTableConfiguration.on('change', this.handleConfigurationChange);
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addItem);
this.composition.on('remove', this.removeItem);
@ -105,6 +111,8 @@ export default {
this.stalenessSubscription = {};
},
destroyed() {
this.ladTableConfiguration.off('change', this.handleConfigurationChange);
this.composition.off('add', this.addItem);
this.composition.off('remove', this.removeItem);
this.composition.off('reorder', this.reorder);
@ -156,6 +164,9 @@ export default {
return metadataWithUnits.length > 0;
},
handleConfigurationChange(configuration) {
this.configuration = configuration;
},
handleStaleness(id, stalenessResponse, skipCheck = false) {
if (skipCheck || this.stalenessSubscription[id].stalenessUtils.shouldUpdateStaleness(stalenessResponse)) {
const index = this.staleObjects.indexOf(id);

View File

@ -0,0 +1,249 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2023, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div class="c-inspect-properties">
<template v-if="isEditing">
<div class="c-inspect-properties__header">
Table Column Visibility
</div>
<ul class="c-inspect-properties__section">
<li
v-for="(title, key) in headers"
:key="key"
class="c-inspect-properties__row"
>
<div
class="c-inspect-properties__label"
title="Show or hide column"
>
<label :for="key + 'ColumnControl'">{{ title }}</label>
</div>
<div class="c-inspect-properties__value">
<input
:id="key + 'ColumnControl'"
type="checkbox"
:checked="configuration.hiddenColumns[key] !== true"
@change="toggleColumn(key)"
>
</div>
</li>
</ul>
</template>
<template v-else>
<div class="c-inspect-properties__header">
LAD Table Configuration
</div>
<div class="c-inspect-properties__row--span-all">
Only available in edit mode.
</div>
</template>
</div>
</template>
<script>
import LADTableConfiguration from '../LADTableConfiguration';
export default {
inject: ['openmct'],
data() {
const selection = this.openmct.selection.get();
const domainObject = selection[0][0].context.item;
const ladTableConfiguration = new LADTableConfiguration(domainObject, this.openmct);
return {
headers: {
timestamp: 'Timestamp',
units: 'Units'
},
ladTableConfiguration,
isEditing: this.openmct.editor.isEditing(),
configuration: ladTableConfiguration.getConfiguration(),
items: [],
ladTableObjects: [],
ladTelemetryObjects: {}
};
},
mounted() {
this.openmct.editor.on('isEditing', this.toggleEdit);
this.composition = this.openmct.composition.get(this.ladTableConfiguration.domainObject);
this.shouldShowUnitsCheckbox();
if (this.ladTableConfiguration.domainObject.type === 'LadTable') {
this.composition.on('add', this.addItem);
this.composition.on('remove', this.removeItem);
} else {
this.compositions = [];
this.composition.on('add', this.addLadTable);
this.composition.on('remove', this.removeLadTable);
}
this.composition.load();
},
destroyed() {
this.ladTableConfiguration.destroy();
this.openmct.editor.off('isEditing', this.toggleEdit);
if (this.ladTableConfiguration.domainObject.type === 'LadTable') {
this.composition.off('add', this.addItem);
this.composition.off('remove', this.removeItem);
} else {
this.composition.off('add', this.addLadTable);
this.composition.off('remove', this.removeLadTable);
this.compositions.forEach(c => {
c.composition.off('add', c.addCallback);
c.composition.off('remove', c.removeCallback);
});
}
},
methods: {
addItem(domainObject) {
const item = {};
item.domainObject = domainObject;
item.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.items.push(item);
this.shouldShowUnitsCheckbox();
},
removeItem(identifier) {
const keystring = this.openmct.objects.makeKeyString(identifier);
const index = this.items.findIndex(item => keystring === item.key);
this.items.splice(index, 1);
this.shouldShowUnitsCheckbox();
},
addLadTable(domainObject) {
let ladTable = {};
ladTable.domainObject = domainObject;
ladTable.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.$set(this.ladTelemetryObjects, ladTable.key, []);
this.ladTableObjects.push(ladTable);
const composition = this.openmct.composition.get(ladTable.domainObject);
const addCallback = this.addTelemetryObject(ladTable);
const removeCallback = this.removeTelemetryObject(ladTable);
composition.on('add', addCallback);
composition.on('remove', removeCallback);
composition.load();
this.compositions.push({
composition,
addCallback,
removeCallback
});
this.shouldShowUnitsCheckbox();
},
removeLadTable(identifier) {
const index = this.ladTableObjects.findIndex(ladTable => this.openmct.objects.makeKeyString(identifier) === ladTable.key);
const ladTable = this.ladTableObjects[index];
this.$delete(this.ladTelemetryObjects, ladTable.key);
this.ladTableObjects.splice(index, 1);
this.shouldShowUnitsCheckbox();
},
addTelemetryObject(ladTable) {
return (domainObject) => {
const telemetryObject = {};
telemetryObject.key = this.openmct.objects.makeKeyString(domainObject.identifier);
telemetryObject.domainObject = domainObject;
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
telemetryObjects.push(telemetryObject);
this.$set(this.ladTelemetryObjects, ladTable.key, telemetryObjects);
this.shouldShowUnitsCheckbox();
};
},
removeTelemetryObject(ladTable) {
return (identifier) => {
const keystring = this.openmct.objects.makeKeyString(identifier);
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
const index = telemetryObjects.findIndex(telemetryObject => keystring === telemetryObject.key);
telemetryObjects.splice(index, 1);
this.$set(this.ladTelemetryObjects, ladTable.key, telemetryObjects);
this.shouldShowUnitsCheckbox();
};
},
combineKeys(ladKey, telemetryObjectKey) {
return `${ladKey}-${telemetryObjectKey}`;
},
toggleColumn(key) {
const isHidden = this.configuration.hiddenColumns[key] === true;
this.configuration.hiddenColumns[key] = !isHidden;
this.ladTableConfiguration.updateConfiguration(this.configuration);
},
toggleEdit(isEditing) {
this.isEditing = isEditing;
},
shouldShowUnitsCheckbox() {
let showUnitsCheckbox = false;
if (this.ladTableConfiguration?.domainObject) {
if (this.ladTableConfiguration.domainObject.type === 'LadTable') {
const itemsWithUnits = this.items.filter((item) => {
return this.metadataHasUnits(item.domainObject);
});
showUnitsCheckbox = itemsWithUnits.length !== 0;
} else {
const ladTables = Object.values(this.ladTelemetryObjects);
for (const ladTable of ladTables) {
for (const telemetryObject of ladTable) {
if (this.metadataHasUnits(telemetryObject.domainObject)) {
showUnitsCheckbox = true;
}
}
}
}
}
if (showUnitsCheckbox && this.headers.units === undefined) {
this.$set(this.headers, 'units', 'Units');
}
if (!showUnitsCheckbox && this.headers?.units) {
this.$delete(this.headers, 'units');
}
},
metadataHasUnits(domainObject) {
const metadata = this.openmct.telemetry.getMetadata(domainObject);
const valueMetadatas = metadata ? metadata.valueMetadatas : [];
const metadataWithUnits = valueMetadatas.filter(metadatum => metadatum.unit);
return metadataWithUnits.length > 0;
}
}
};
</script>

View File

@ -29,9 +29,9 @@
<thead>
<tr>
<th>Name</th>
<th>Timestamp</th>
<th v-if="showTimestamp">Timestamp</th>
<th>Value</th>
<th v-if="hasUnits">Unit</th>
<th v-if="hasUnits">Units</th>
</tr>
</thead>
<tbody>
@ -53,6 +53,7 @@
:path-to-table="ladTable.objectPath"
:has-units="hasUnits"
:is-stale="staleObjects.includes(combineKeys(ladTable.key, ladRow.key))"
:configuration="configuration"
@rowContextClick="updateViewContext"
/>
</template>
@ -70,7 +71,7 @@ export default {
components: {
LadRow
},
inject: ['openmct', 'objectPath', 'currentView'],
inject: ['openmct', 'objectPath', 'currentView', 'ladTableConfiguration'],
props: {
domainObject: {
type: Object,
@ -83,12 +84,15 @@ export default {
ladTelemetryObjects: {},
compositions: [],
viewContext: {},
staleObjects: []
staleObjects: [],
configuration: this.ladTableConfiguration.getConfiguration()
};
},
computed: {
hasUnits() {
let ladTables = Object.values(this.ladTelemetryObjects);
const ladTables = Object.values(this.ladTelemetryObjects);
let showUnits = false;
for (let ladTable of ladTables) {
for (let telemetryObject of ladTable) {
let metadata = this.openmct.telemetry.getMetadata(telemetryObject.domainObject);
@ -96,14 +100,17 @@ export default {
if (metadata) {
for (let metadatum of metadata.valueMetadatas) {
if (metadatum.unit) {
return true;
showUnits = true;
}
}
}
}
}
return false;
return showUnits && !this.configuration?.hiddenColumns?.units;
},
showTimestamp() {
return !this.configuration?.hiddenColumns?.timestamp;
},
staleClass() {
if (this.staleObjects.length !== 0) {
@ -114,6 +121,7 @@ export default {
}
},
mounted() {
this.ladTableConfiguration.on('change', this.handleConfigurationChange);
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addLadTable);
this.composition.on('remove', this.removeLadTable);
@ -123,6 +131,7 @@ export default {
this.stalenessSubscription = {};
},
destroyed() {
this.ladTableConfiguration.off('change', this.handleConfigurationChange);
this.composition.off('add', this.addLadTable);
this.composition.off('remove', this.removeLadTable);
this.composition.off('reorder', this.reorderLadTables);
@ -230,6 +239,9 @@ export default {
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);

View File

@ -22,12 +22,14 @@
import LADTableViewProvider from './LADTableViewProvider';
import LADTableSetViewProvider from './LADTableSetViewProvider';
import ladTableCompositionPolicy from './LADTableCompositionPolicy';
import LADTableConfigurationViewProvider from './LADTableConfigurationViewProvider';
export default function plugin() {
return function install(openmct) {
openmct.objectViews.addProvider(new LADTableViewProvider(openmct));
openmct.objectViews.addProvider(new LADTableSetViewProvider(openmct));
openmct.inspectorViews.addProvider(new LADTableConfigurationViewProvider(openmct));
openmct.types.addType('LadTable', {
name: "LAD Table",