persist swimlane height resizing

This commit is contained in:
David Tsay 2025-03-03 16:21:31 -08:00
parent af912db7aa
commit ee6aab2f59
3 changed files with 76 additions and 27 deletions

View File

@ -104,7 +104,6 @@ export default {
SwimLane,
ExtendedLinesOverlay
},
inject: ['openmct', 'domainObject', 'path', 'composition', 'extendedLinesBus'],
props: {
isEditing: {
type: Boolean,
@ -112,10 +111,14 @@ export default {
}
},
setup() {
const openmct = inject('openmct');
const domainObject = inject('domainObject');
const path = inject('path');
const openmct = inject('openmct');
const composition = inject('composition');
const extendedLinesBus = inject('extendedLinesBus');
const items = ref([]);
const loadedComposition = ref(null);
const { alignment: alignmentData, reset: resetAlignment } = useAlignment(
domainObject,
@ -140,7 +143,8 @@ export default {
endContainerResizing
} = useFlexContainers(timelineHolder, {
containerClass: Container,
rowsLayout: true
rowsLayout: true,
callback: mutateContainers
});
function getContainerSize(item) {
@ -151,17 +155,33 @@ export default {
return containerforItem?.size;
}
function mutateContainers() {
if (
loadedComposition?.value?.length &&
loadedComposition?.value?.length === containers?.value?.length
) {
openmct.objects.mutate(domainObject, 'configuration.containers', containers.value);
}
}
return {
openmct,
domainObject,
path,
composition,
extendedLinesBus,
containers,
getContainerSize,
timelineHolder,
loadedComposition,
items,
addContainer,
alignmentData,
resetAlignment,
startContainerResizing,
containerResizing,
endContainerResizing
endContainerResizing,
mutateContainers
};
},
data() {
@ -196,7 +216,7 @@ export default {
this.extendedLinesBus.off('update-extended-hover', this.updateExtendedHover);
this.openmct.selection.off('change', this.checkForLineSelection);
},
mounted() {
async mounted() {
this.items = [];
this.setTimeContext();
@ -208,7 +228,8 @@ export default {
this.composition.on('add', this.addItem);
this.composition.on('remove', this.removeItem);
this.composition.on('reorder', this.reorder);
this.composition.load();
this.loadedComposition = await this.composition.load();
}
this.handleContentResize = _.debounce(this.handleContentResize, 500);
@ -243,7 +264,14 @@ export default {
this.items.push(item);
const container = new Container(domainObject);
const containerSizeFromConfiguration = this.domainObject.configuration?.containers?.find(
(container) =>
this.openmct.objects.areIdsEqual(
container.domainObjectIdentifier,
domainObject.identifier
)
)?.size;
const container = new Container(domainObject, containerSizeFromConfiguration);
this.addContainer(container);
},
removeItem(identifier) {

View File

@ -41,7 +41,8 @@ export default function () {
initialize: function (domainObject) {
domainObject.composition = [];
domainObject.configuration = {
useIndependentTime: false
useIndependentTime: false,
containers: []
};
}
});

View File

@ -1,6 +1,21 @@
import _ from 'lodash';
import { ref } from 'vue';
/**
* @typedef {Object} configuration
* @property {boolean} rowsLayout true if containers arranged as rows, false if columns
* @property {number} minContainerSize minimum size in pixels of a container
* @property {Function} callback function to call when container resize completes
*/
/**
* Provides a means to size a collection of containers to a total size of 100%.
* The containers will resize proportionally to fit the total size on add/remove.
* The containers will initially be sized based on their scale property.
* @param {import('vue').Ref<HTMLElement} element ref to the html total sizing element
* @param {configuration} configuration object with configuration options
* @returns
*/
export function useFlexContainers(element, { rowsLayout, minContainerSize = 5, callback }) {
const containers = ref([]);
const maxMoveSize = ref(null);
@ -37,7 +52,6 @@ export function useFlexContainers(element, { rowsLayout, minContainerSize = 5, c
}
function endContainerResizing() {
// persist the new container sizes
callback?.(containers.value);
}
@ -59,32 +73,38 @@ export function useFlexContainers(element, { rowsLayout, minContainerSize = 5, c
}
}
// Resize items so that newItem fits proportionally (newItem must be an element
// of items). If newItem does not have a size or is sized at 100%, newItem will
// have size set to 1/n * 100, where n is the total number of items.
/**
* Resize items so that newItem fits proportionally (newItem must be an element of items).
* If newItem does not have a size or is sized at 100%,
* newItem will have size set to (1 * newItemScale) / n * 100,
* where n is the total number of items and newItemScale is the scale of newItem.
* All other items will be resized to fit inside the remaining space.
* @param {*} items
* @param {*} newItem
*/
function sizeItems(items, newItem) {
const newItemScale = newItem.scale || 1;
if (items.length === 1) {
if (!newItem.size && items.length === 1) {
newItem.size = 100;
} else {
if (!newItem.size || newItem.size === 100) {
newItem.size = Math.round((100 * newItemScale) / sizingContainers);
// Resize oldItems to fit inside remaining space;
const oldItems = items.filter((item) => !_.isEqual(item, newItem));
const remainingSize = 100 - newItem.size;
oldItems.forEach((item) => {
const itemScale = item.scale || 1;
item.size = Math.round((item.size * itemScale * remainingSize) / 100);
});
// Ensure items add up to 100 in case of rounding error.
let total = items.reduce((t, item) => t + item.size, 0);
let excess = Math.round(100 - total);
oldItems[oldItems.length - 1].size += excess;
}
// Resize oldItems to fit inside remaining space;
const oldItems = items.filter((item) => !_.isEqual(item, newItem));
const remainingSize = 100 - newItem.size;
oldItems.forEach((item) => {
const itemScale = item.scale || 1;
item.size = Math.round((item.size * itemScale * remainingSize) / 100);
});
// Ensure items add up to 100 in case of rounding error.
let total = items.reduce((t, item) => t + item.size, 0);
let excess = Math.round(100 - total);
oldItems[oldItems.length - 1].size += excess;
}
}