mirror of
https://github.com/nasa/openmct.git
synced 2024-12-24 07:16:39 +00:00
Merge branch 'activity-state-display' of https://github.com/nasa/openmct into activity-states-and-compact-view
This commit is contained in:
commit
9e880a5020
@ -108,6 +108,7 @@
|
||||
|
||||
openmct.install(openmct.plugins.Espresso());
|
||||
openmct.install(openmct.plugins.MyItems());
|
||||
openmct.install(openmct.plugins.ActivityStates());
|
||||
openmct.install(
|
||||
openmct.plugins.PlanLayout({
|
||||
creatable: true
|
||||
|
@ -99,7 +99,13 @@ export default class ObjectAPI {
|
||||
this.cache = {};
|
||||
this.interceptorRegistry = new InterceptorRegistry();
|
||||
|
||||
this.SYNCHRONIZED_OBJECT_TYPES = ['notebook', 'restricted-notebook', 'plan', 'annotation'];
|
||||
this.SYNCHRONIZED_OBJECT_TYPES = [
|
||||
'notebook',
|
||||
'restricted-notebook',
|
||||
'plan',
|
||||
'annotation',
|
||||
'activity-states'
|
||||
];
|
||||
|
||||
this.errors = {
|
||||
Conflict: ConflictError
|
||||
|
51
src/plugins/activityStates/activityStatesInterceptor.js
Normal file
51
src/plugins/activityStates/activityStatesInterceptor.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*****************************************************************************
|
||||
* 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 { ACTIVITYSTATES_KEY, ACTIVITYSTATES_TYPE } from './createActivityStatesIdentifier.js';
|
||||
|
||||
function activityStatesInterceptor(openmct, identifierObject, name) {
|
||||
const activityStatesModel = {
|
||||
identifier: identifierObject,
|
||||
name,
|
||||
type: ACTIVITYSTATES_TYPE,
|
||||
activities: {},
|
||||
location: null
|
||||
};
|
||||
|
||||
return {
|
||||
appliesTo: (identifier) => {
|
||||
return identifier.key === ACTIVITYSTATES_KEY;
|
||||
},
|
||||
invoke: (identifier, object) => {
|
||||
if (!object || openmct.objects.isMissing(object)) {
|
||||
openmct.objects.save(activityStatesModel);
|
||||
|
||||
return activityStatesModel;
|
||||
}
|
||||
|
||||
return object;
|
||||
},
|
||||
priority: openmct.priority.HIGH
|
||||
};
|
||||
}
|
||||
|
||||
export default activityStatesInterceptor;
|
@ -0,0 +1,9 @@
|
||||
export const ACTIVITYSTATES_KEY = 'activity-states';
|
||||
export const ACTIVITYSTATES_TYPE = 'activity-states';
|
||||
|
||||
export function createActivityStatesIdentifier(namespace = '') {
|
||||
return {
|
||||
key: ACTIVITYSTATES_KEY,
|
||||
namespace
|
||||
};
|
||||
}
|
42
src/plugins/activityStates/plugin.js
Normal file
42
src/plugins/activityStates/plugin.js
Normal file
@ -0,0 +1,42 @@
|
||||
/*****************************************************************************
|
||||
* 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 activityStatesInterceptor from './activityStatesInterceptor.js';
|
||||
import { createActivityStatesIdentifier } from './createActivityStatesIdentifier.js';
|
||||
|
||||
const ACTIVITYSTATES_DEFAULT_NAME = 'Activity States';
|
||||
|
||||
export default function ActivityStatesPlugin(
|
||||
name = ACTIVITYSTATES_DEFAULT_NAME,
|
||||
namespace = '',
|
||||
priority = undefined
|
||||
) {
|
||||
return function install(openmct) {
|
||||
const identifier = createActivityStatesIdentifier(namespace);
|
||||
|
||||
if (priority === undefined) {
|
||||
priority = openmct.priority.LOW;
|
||||
}
|
||||
|
||||
openmct.objects.addGetInterceptor(activityStatesInterceptor(openmct, identifier, name));
|
||||
};
|
||||
}
|
89
src/plugins/activityStates/pluginSpec.js
Normal file
89
src/plugins/activityStates/pluginSpec.js
Normal file
@ -0,0 +1,89 @@
|
||||
/*****************************************************************************
|
||||
* 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 { createOpenMct, resetApplicationState } from 'utils/testing';
|
||||
|
||||
import {
|
||||
ACTIVITYSTATES_KEY,
|
||||
createActivityStatesIdentifier
|
||||
} from './createActivityStatesIdentifier.js';
|
||||
|
||||
const MISSING_NAME = `Missing: ${ACTIVITYSTATES_KEY}`;
|
||||
const DEFAULT_NAME = 'Activity States';
|
||||
const activityStatesIdentifier = createActivityStatesIdentifier();
|
||||
|
||||
describe('the plugin', () => {
|
||||
let openmct;
|
||||
let missingObj = {
|
||||
identifier: activityStatesIdentifier,
|
||||
type: 'unknown',
|
||||
name: MISSING_NAME
|
||||
};
|
||||
|
||||
describe('with no arguments passed in', () => {
|
||||
beforeEach((done) => {
|
||||
openmct = createOpenMct();
|
||||
openmct.install(openmct.plugins.ActivityStates());
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.startHeadless();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
return resetApplicationState(openmct);
|
||||
});
|
||||
|
||||
it('when installed, adds "Activity States"', async () => {
|
||||
const activityStatesObject = await openmct.objects.get(activityStatesIdentifier);
|
||||
expect(activityStatesObject.name).toBe(DEFAULT_NAME);
|
||||
expect(activityStatesObject).toBeDefined();
|
||||
});
|
||||
|
||||
describe('adds an interceptor that returns a "Activity States" model for', () => {
|
||||
let activityStatesObject;
|
||||
let mockNotFoundProvider;
|
||||
let activeProvider;
|
||||
|
||||
beforeEach(async () => {
|
||||
mockNotFoundProvider = {
|
||||
get: () => Promise.reject(new Error('Not found')),
|
||||
create: () => Promise.resolve(missingObj),
|
||||
update: () => Promise.resolve(missingObj)
|
||||
};
|
||||
|
||||
activeProvider = mockNotFoundProvider;
|
||||
spyOn(openmct.objects, 'getProvider').and.returnValue(activeProvider);
|
||||
activityStatesObject = await openmct.objects.get(activityStatesIdentifier);
|
||||
});
|
||||
|
||||
it('missing objects', () => {
|
||||
let idsMatch = openmct.objects.areIdsEqual(
|
||||
activityStatesObject.identifier,
|
||||
activityStatesIdentifier
|
||||
);
|
||||
|
||||
expect(activityStatesObject).toBeDefined();
|
||||
expect(idsMatch).toBeTrue();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -488,6 +488,7 @@ export default {
|
||||
},
|
||||
start: rawActivity.start,
|
||||
end: rawActivity.end,
|
||||
description: rawActivity.description,
|
||||
row: currentRow,
|
||||
textLines: textLines,
|
||||
textStart: textStart,
|
||||
@ -496,7 +497,8 @@ export default {
|
||||
rectStart: rectX1,
|
||||
rectEnd: showTextInsideRect ? rectX2 : textStart + textWidth,
|
||||
rectWidth: rectWidth,
|
||||
clipPathId: this.getClipPathId(groupName, rawActivity, currentRow)
|
||||
clipPathId: this.getClipPathId(groupName, rawActivity, currentRow),
|
||||
id: rawActivity.id
|
||||
};
|
||||
activitiesByRow[currentRow].push(activity);
|
||||
});
|
||||
|
@ -20,21 +20,39 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<div class="c-inspector__properties c-inspect-properties">
|
||||
<plan-activity-view
|
||||
<div>
|
||||
<plan-activity-time-view
|
||||
v-for="activity in activities"
|
||||
:key="activity.id"
|
||||
:key="activity.key"
|
||||
class="c-inspector__properties c-inspect-properties"
|
||||
:activity="activity"
|
||||
:heading="heading"
|
||||
/>
|
||||
<plan-activity-properties-view
|
||||
v-for="activity in activities"
|
||||
:key="activity.key"
|
||||
:heading="'Properties'"
|
||||
class="c-inspector__properties c-inspect-properties"
|
||||
:activity="activity"
|
||||
></plan-activity-properties-view>
|
||||
<plan-activity-status-view
|
||||
v-if="canPersistState"
|
||||
:key="activities[0].key"
|
||||
class="c-inspector__properties c-inspect-properties"
|
||||
:activity="activities[0]"
|
||||
:execution-state="persistedActivityStates[activities[0].id]"
|
||||
:heading="'Activity Status'"
|
||||
@update-activity-state="persistedActivityState"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPreciseDuration } from 'utils/duration';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import PlanActivityView from './PlanActivityView.vue';
|
||||
import PlanActivityPropertiesView from './PlanActivityPropertiesView.vue';
|
||||
import PlanActivityStatusView from './PlanActivityStatusView.vue';
|
||||
import PlanActivityTimeView from './PlanActivityTimeView.vue';
|
||||
|
||||
const propertyLabels = {
|
||||
start: 'Start DateTime',
|
||||
@ -44,23 +62,34 @@ const propertyLabels = {
|
||||
latestEnd: 'Latest End',
|
||||
gap: 'Gap',
|
||||
overlap: 'Overlap',
|
||||
totalTime: 'Total Time'
|
||||
totalTime: 'Total Time',
|
||||
description: 'Description'
|
||||
};
|
||||
export default {
|
||||
components: {
|
||||
PlanActivityView
|
||||
PlanActivityTimeView,
|
||||
PlanActivityPropertiesView,
|
||||
PlanActivityStatusView
|
||||
},
|
||||
inject: ['openmct', 'selection'],
|
||||
data() {
|
||||
return {
|
||||
name: '',
|
||||
activities: [],
|
||||
selectedActivities: [],
|
||||
persistedActivityStates: {},
|
||||
heading: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
canPersistState() {
|
||||
return this.selectedActivities.length === 1 && this.activities[0].id;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setFormatters();
|
||||
this.getPlanData(this.selection);
|
||||
this.getActivityStates();
|
||||
this.getActivities();
|
||||
this.openmct.selection.on('change', this.updateSelection);
|
||||
this.openmct.time.on('timeSystem', this.setFormatters);
|
||||
@ -68,8 +97,23 @@ export default {
|
||||
beforeUnmount() {
|
||||
this.openmct.selection.off('change', this.updateSelection);
|
||||
this.openmct.time.off('timeSystem', this.setFormatters);
|
||||
if (this.stopObservingActivityStatesObject) {
|
||||
this.stopObservingActivityStatesObject();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getActivityStates() {
|
||||
this.activityStatesObject = await this.openmct.objects.get('activity-states');
|
||||
this.setActivityStates();
|
||||
this.stopObservingActivityStatesObject = this.openmct.objects.observe(
|
||||
this.activityStatesObject,
|
||||
'*',
|
||||
this.setActivityStates
|
||||
);
|
||||
},
|
||||
setActivityStates() {
|
||||
this.persistedActivityStates = { ...this.activityStatesObject.activities };
|
||||
},
|
||||
setFormatters() {
|
||||
let timeSystem = this.openmct.time.timeSystem();
|
||||
this.timeFormatter = this.openmct.telemetry.getValueFormatter({
|
||||
@ -86,6 +130,7 @@ export default {
|
||||
if (selectionItem[0].context.type === 'activity') {
|
||||
const activity = selectionItem[0].context.activity;
|
||||
if (activity) {
|
||||
activity.key = activity.id ?? activity.name;
|
||||
this.selectedActivities.push(activity);
|
||||
}
|
||||
}
|
||||
@ -104,20 +149,31 @@ export default {
|
||||
this.activities.splice(0);
|
||||
this.selectedActivities.forEach((selectedActivity, index) => {
|
||||
const activity = {
|
||||
id: uuid(),
|
||||
start: {
|
||||
label: propertyLabels.start,
|
||||
value: this.formatTime(selectedActivity.start)
|
||||
},
|
||||
end: {
|
||||
label: propertyLabels.end,
|
||||
value: this.formatTime(selectedActivity.end)
|
||||
},
|
||||
duration: {
|
||||
label: propertyLabels.duration,
|
||||
value: this.formatDuration(selectedActivity.end - selectedActivity.start)
|
||||
id: selectedActivity.id,
|
||||
key: selectedActivity.key,
|
||||
timeProperties: {
|
||||
start: {
|
||||
label: propertyLabels.start,
|
||||
value: this.formatTime(selectedActivity.start)
|
||||
},
|
||||
end: {
|
||||
label: propertyLabels.end,
|
||||
value: this.formatTime(selectedActivity.end)
|
||||
},
|
||||
duration: {
|
||||
label: propertyLabels.duration,
|
||||
value: this.formatDuration(selectedActivity.end - selectedActivity.start)
|
||||
}
|
||||
}
|
||||
};
|
||||
if (selectedActivity.description) {
|
||||
activity.metadata = {
|
||||
description: {
|
||||
label: propertyLabels.description,
|
||||
value: selectedActivity.description
|
||||
}
|
||||
};
|
||||
}
|
||||
this.activities[index] = activity;
|
||||
});
|
||||
},
|
||||
@ -141,6 +197,8 @@ export default {
|
||||
let latestEnd;
|
||||
let gap;
|
||||
let overlap;
|
||||
let id;
|
||||
let key;
|
||||
|
||||
//Sort by start time
|
||||
let selectedActivities = this.selectedActivities.sort(this.sortFn);
|
||||
@ -159,6 +217,8 @@ export default {
|
||||
earliestStart = Math.min(earliestStart, selectedActivity.start);
|
||||
latestEnd = Math.max(latestEnd, selectedActivity.end);
|
||||
} else {
|
||||
id = selectedActivity.id;
|
||||
key = selectedActivity.id ?? selectedActivity.name;
|
||||
earliestStart = selectedActivity.start;
|
||||
latestEnd = selectedActivity.end;
|
||||
}
|
||||
@ -166,30 +226,33 @@ export default {
|
||||
let totalTime = latestEnd - earliestStart;
|
||||
|
||||
const activity = {
|
||||
id: uuid(),
|
||||
earliestStart: {
|
||||
label: propertyLabels.earliestStart,
|
||||
value: this.formatTime(earliestStart)
|
||||
},
|
||||
latestEnd: {
|
||||
label: propertyLabels.latestEnd,
|
||||
value: this.formatTime(latestEnd)
|
||||
id,
|
||||
key,
|
||||
timeProperties: {
|
||||
earliestStart: {
|
||||
label: propertyLabels.earliestStart,
|
||||
value: this.formatTime(earliestStart)
|
||||
},
|
||||
latestEnd: {
|
||||
label: propertyLabels.latestEnd,
|
||||
value: this.formatTime(latestEnd)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (gap) {
|
||||
activity.gap = {
|
||||
activity.timeProperties.gap = {
|
||||
label: propertyLabels.gap,
|
||||
value: this.formatDuration(gap)
|
||||
};
|
||||
} else if (overlap) {
|
||||
activity.overlap = {
|
||||
activity.timeProperties.overlap = {
|
||||
label: propertyLabels.overlap,
|
||||
value: this.formatDuration(overlap)
|
||||
};
|
||||
}
|
||||
|
||||
activity.totalTime = {
|
||||
activity.timeProperties.totalTime = {
|
||||
label: propertyLabels.totalTime,
|
||||
value: this.formatDuration(totalTime)
|
||||
};
|
||||
@ -201,6 +264,11 @@ export default {
|
||||
},
|
||||
formatTime(time) {
|
||||
return this.timeFormatter.format(time);
|
||||
},
|
||||
persistedActivityState(data) {
|
||||
const { key, executionState } = data;
|
||||
const activitiesPath = `activities.${key}`;
|
||||
this.openmct.objects.mutate(this.activityStatesObject, activitiesPath, executionState);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -0,0 +1,82 @@
|
||||
<!--
|
||||
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>
|
||||
<div v-if="properties.length" class="u-contents">
|
||||
<div class="c-inspect-properties__header">{{ heading }}</div>
|
||||
<ul v-for="property in properties" :key="property.id" class="c-inspect-properties__section">
|
||||
<activity-property :label="property.label" :value="property.value" />
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ActivityProperty from './ActivityProperty.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ActivityProperty
|
||||
},
|
||||
props: {
|
||||
activity: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
heading: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
properties: []
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.setProperties();
|
||||
},
|
||||
methods: {
|
||||
setProperties() {
|
||||
if (!this.activity.metadata) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.keys(this.activity.metadata).forEach((key) => {
|
||||
if (this.activity.metadata[key].label) {
|
||||
const label = this.activity.metadata[key].label;
|
||||
const value = String(this.activity.metadata[key].value);
|
||||
const id = this.activity.id;
|
||||
|
||||
this.properties[this.properties.length] = {
|
||||
id,
|
||||
label,
|
||||
value
|
||||
};
|
||||
}
|
||||
});
|
||||
console.log(this.activity.metadata, this.properties);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
114
src/plugins/plan/inspector/components/PlanActivityStatusView.vue
Normal file
114
src/plugins/plan/inspector/components/PlanActivityStatusView.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<!--
|
||||
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>
|
||||
<div class="u-contents">
|
||||
<div class="c-inspect-properties__header">{{ heading }}</div>
|
||||
<form name="activityStatus">
|
||||
<select v-model="currentStatusKey" name="setActivityStatus" @change="changeActivityStatus">
|
||||
<option v-for="status in activityStates" :key="status.key" :value="status.label">
|
||||
{{ status.label }}
|
||||
</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const activityStates = [
|
||||
{
|
||||
key: '',
|
||||
label: '- Select Activity Status -'
|
||||
},
|
||||
{
|
||||
key: 'active',
|
||||
label: 'In progress'
|
||||
},
|
||||
{
|
||||
key: 'completed',
|
||||
label: 'Completed'
|
||||
},
|
||||
{
|
||||
key: 'aborted',
|
||||
label: 'Aborted'
|
||||
},
|
||||
{
|
||||
key: 'cancelled',
|
||||
label: 'Cancelled'
|
||||
},
|
||||
{
|
||||
key: 'notStarted',
|
||||
label: 'Not started'
|
||||
}
|
||||
];
|
||||
|
||||
export default {
|
||||
props: {
|
||||
activity: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
executionState: {
|
||||
type: String,
|
||||
default() {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
heading: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: ['updateActivityState'],
|
||||
data() {
|
||||
return {
|
||||
activityStates: activityStates,
|
||||
currentStatusKey: activityStates[0].key
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
executionState() {
|
||||
this.setActivityStatus();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setActivityStatus();
|
||||
},
|
||||
methods: {
|
||||
setActivityStatus() {
|
||||
this.currentStatusKey = this.executionState;
|
||||
},
|
||||
changeActivityStatus() {
|
||||
if (this.currentStatusKey === '') {
|
||||
return;
|
||||
}
|
||||
this.activity.executionState = this.currentStatusKey;
|
||||
this.$emit('updateActivityState', {
|
||||
key: this.activity.id,
|
||||
executionState: this.currentStatusKey
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -21,23 +21,23 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div v-if="timeProperties.length" class="u-contents">
|
||||
<div class="c-inspect-properties__header">
|
||||
{{ heading }}
|
||||
<div>
|
||||
<div v-if="timeProperties.length" class="u-contents">
|
||||
<div class="c-inspect-properties__header">
|
||||
{{ heading }}
|
||||
</div>
|
||||
<ul
|
||||
v-for="timeProperty in timeProperties"
|
||||
:key="timeProperty.id"
|
||||
class="c-inspect-properties__section"
|
||||
>
|
||||
<activity-property :label="timeProperty.label" :value="timeProperty.value" />
|
||||
</ul>
|
||||
</div>
|
||||
<ul
|
||||
v-for="timeProperty in timeProperties"
|
||||
:key="timeProperty.id"
|
||||
class="c-inspect-properties__section"
|
||||
>
|
||||
<activity-property :label="timeProperty.label" :value="timeProperty.value" />
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import ActivityProperty from './ActivityProperty.vue';
|
||||
|
||||
export default {
|
||||
@ -64,13 +64,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
setProperties() {
|
||||
Object.keys(this.activity).forEach((key) => {
|
||||
if (this.activity[key].label) {
|
||||
const label = this.activity[key].label;
|
||||
const value = String(this.activity[key].value);
|
||||
Object.keys(this.activity.timeProperties).forEach((key) => {
|
||||
if (this.activity.timeProperties[key].label) {
|
||||
const label = this.activity.timeProperties[key].label;
|
||||
const value = String(this.activity.timeProperties[key].value);
|
||||
const id = this.activity.id;
|
||||
|
||||
this.timeProperties[this.timeProperties.length] = {
|
||||
id: uuid(),
|
||||
id,
|
||||
label,
|
||||
value
|
||||
};
|
@ -45,6 +45,10 @@ export function getValidatedData(domainObject) {
|
||||
groupActivity.end = activity[sourceMap.end];
|
||||
}
|
||||
|
||||
if (sourceMap.id) {
|
||||
groupActivity.id = activity[sourceMap.id];
|
||||
}
|
||||
|
||||
if (!mappedJson[groupIdKey]) {
|
||||
mappedJson[groupIdKey] = [];
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import ExampleUser from '../../example/exampleUser/plugin.js';
|
||||
import ExampleFaultSource from '../../example/faultManagement/exampleFaultSource.js';
|
||||
import GeneratorPlugin from '../../example/generator/plugin.js';
|
||||
import ExampleImagery from '../../example/imagery/plugin.js';
|
||||
import ActivityStatesPlugin from './activityStates/plugin.js';
|
||||
import AutoflowPlugin from './autoflow/AutoflowTabularPlugin.js';
|
||||
import BarChartPlugin from './charts/bar/plugin.js';
|
||||
import ScatterPlotPlugin from './charts/scatter/plugin.js';
|
||||
@ -101,6 +102,7 @@ plugins.LocalTimeSystem = LocalTimeSystem;
|
||||
plugins.RemoteClock = RemoteClock;
|
||||
|
||||
plugins.MyItems = MyItems;
|
||||
plugins.ActivityStates = ActivityStatesPlugin;
|
||||
|
||||
plugins.StaticRootPlugin = StaticRootPlugin;
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
:header-items="headerItems"
|
||||
:default-sort="defaultSort"
|
||||
class="sticky"
|
||||
@item-selection-changed="setSelectionForActivity"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -548,6 +549,29 @@ export default {
|
||||
setEditState(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
this.setViewFromConfig(this.domainObject.configuration);
|
||||
},
|
||||
setSelectionForActivity(activity, element) {
|
||||
const multiSelect = false;
|
||||
|
||||
this.openmct.selection.select(
|
||||
[
|
||||
{
|
||||
element: element,
|
||||
context: {
|
||||
type: 'activity',
|
||||
activity: activity
|
||||
}
|
||||
},
|
||||
{
|
||||
element: this.openmct.layout.$refs.browseObject.$el,
|
||||
context: {
|
||||
item: this.domainObject,
|
||||
supportsMultiSelect: false
|
||||
}
|
||||
}
|
||||
],
|
||||
multiSelect
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -43,6 +43,7 @@
|
||||
:key="item.key"
|
||||
:item="item"
|
||||
:item-properties="itemProperties"
|
||||
@click="itemSelected(item, $event)"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -86,6 +87,7 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
emits: ['itemSelectionChanged'],
|
||||
data() {
|
||||
let sortBy = this.defaultSort.property;
|
||||
let ascending = this.defaultSort.defaultDirection;
|
||||
@ -156,6 +158,10 @@ export default {
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
itemSelected(item, event) {
|
||||
event.stopPropagation();
|
||||
this.$emit('itemSelectionChanged', item, event.currentTarget);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user