Files
openmct/src/plugins/notebook/utils/notebook-entries.js
Tristan F fce98a1c47 refactor: migrate to ESM (#7331)
* refactor: move package.json to type: module

this is where the fun begins

* chore: move webpack common and prod to esm

* chore: move webpack to esm, eslint to explicit cjs

* refactor: migrate all files to esm

* style: lint

* refactor: begin moving karma to cjs, use dynamic esm import

* refactor: move index-test to cjs

* refactor: begin moving e2e to ESM

this was manual. I'm committing this because I'm about to try the `cjstoesm` tool

* refactor: move all to esm

* fix: make all e2e tests use .js imports

* refactor: begin moving exports to esm

* refactor: use URL transforms instead of __dirname

* fix: use libraryExport: default to properly handle openmct

* fix: export all playwright configs as modules

* refactor: move all instances of __dirname to import.meta.url

* refactor: lint, drop unnecessary URL call

* fix: use correct URL path on helper/addNoneditableObject.js

* fix: more incorrect URL resolve issues

* fix: parse json after reading it
2024-01-02 07:24:22 -08:00

319 lines
7.9 KiB
JavaScript

import { v4 as uuid } from 'uuid';
import objectLink from '../../../ui/mixins/object-link.js';
import {
createNotebookImageDomainObject,
getThumbnailURLFromImageUrl,
saveNotebookImageDomainObject
} from './notebook-image.js';
async function getUsername(openmct) {
let username = null;
if (openmct.user.hasProvider()) {
const user = await openmct.user.getCurrentUser();
username = user.getName();
}
return username;
}
async function getActiveRole(openmct) {
let role = null;
if (openmct.user.hasProvider()) {
role = await openmct.user.getActiveRole?.();
}
return role;
}
export const DEFAULT_CLASS = 'notebook-default';
const TIME_BOUNDS = {
START_BOUND: 'tc.startBound',
END_BOUND: 'tc.endBound',
START_DELTA: 'tc.startDelta',
END_DELTA: 'tc.endDelta'
};
export function addEntryIntoPage(notebookStorage, entries, entry) {
const defaultSectionId = notebookStorage.defaultSectionId;
const defaultPageId = notebookStorage.defaultPageId;
if (!defaultSectionId || !defaultPageId) {
return;
}
const newEntries = JSON.parse(JSON.stringify(entries));
let section = newEntries[defaultSectionId];
if (!section) {
newEntries[defaultSectionId] = {};
}
let page = newEntries[defaultSectionId][defaultPageId];
if (!page) {
newEntries[defaultSectionId][defaultPageId] = [];
}
newEntries[defaultSectionId][defaultPageId].push(entry);
return newEntries;
}
export function selectEntry({
element,
entryId,
domainObject,
openmct,
onAnnotationChange,
notebookAnnotations
}) {
const keyString = openmct.objects.makeKeyString(domainObject.identifier);
const targetDetails = [
{
entryId,
keyString
}
];
const targetDomainObjects = [domainObject];
openmct.selection.select(
[
{
element,
context: {
type: 'notebook-entry-selection',
item: domainObject,
targetDetails,
targetDomainObjects,
annotations: notebookAnnotations,
annotationType: openmct.annotation.ANNOTATION_TYPES.NOTEBOOK,
onAnnotationChange
}
}
],
false
);
}
export function getHistoricLinkInFixedMode(openmct, bounds, historicLink) {
if (historicLink.includes('tc.mode=fixed')) {
return historicLink;
}
openmct.time.getAllClocks().forEach((clock) => {
if (historicLink.includes(`tc.mode=${clock.key}`)) {
historicLink.replace(`tc.mode=${clock.key}`, 'tc.mode=fixed');
return;
}
});
const params = historicLink.split('&').map((param) => {
if (param.includes(TIME_BOUNDS.START_BOUND) || param.includes(TIME_BOUNDS.START_DELTA)) {
param = `${TIME_BOUNDS.START_BOUND}=${bounds.start}`;
}
if (param.includes(TIME_BOUNDS.END_BOUND) || param.includes(TIME_BOUNDS.END_DELTA)) {
param = `${TIME_BOUNDS.END_BOUND}=${bounds.end}`;
}
return param;
});
return params.join('&');
}
export function createNewImageEmbed(image, openmct, imageName = '') {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = async () => {
try {
const base64Data = reader.result;
const blobUrl = URL.createObjectURL(image);
const imageDomainObject = createNotebookImageDomainObject(base64Data);
await saveNotebookImageDomainObject(openmct, imageDomainObject);
const imageThumbnailURL = await getThumbnailURLFromImageUrl(blobUrl);
const snapshot = {
fullSizeImageObjectIdentifier: imageDomainObject.identifier,
thumbnailImage: {
src: imageThumbnailURL
}
};
const embedMetaData = {
bounds: openmct.time.bounds(),
link: null,
objectPath: null,
openmct,
userImage: true,
imageName
};
const createdEmbed = await createNewEmbed(embedMetaData, snapshot);
resolve(createdEmbed);
} catch (error) {
console.error(`${error.message} - unable to embed image ${imageName}`, error);
openmct.notifications.error(`${error.message} -- unable to embed image ${imageName}`);
}
};
reader.readAsDataURL(image);
});
}
export async function createNewEmbed(snapshotMeta, snapshot = '') {
const { bounds, link, objectPath, openmct, userImage } = snapshotMeta;
let name = null;
let type = null;
let cssClass = 'icon-object-unknown';
let domainObject = null;
let historicLink = null;
if (objectPath?.length > 0) {
domainObject = objectPath[0];
const domainObjectType = openmct.types.get(domainObject.type);
cssClass = domainObjectType?.definition
? domainObjectType.definition.cssClass
: 'icon-object-unknown';
name = domainObject.name;
type = domainObject.identifier.key;
historicLink = link
? getHistoricLinkInFixedMode(openmct, bounds, link)
: objectLink.computed.objectLink.call({
objectPath,
openmct
});
} else if (userImage) {
cssClass = 'icon-image';
name = snapshotMeta.imageName;
}
const date = openmct.time.now();
const createdBy = await getUsername(openmct);
return {
bounds,
createdOn: date,
createdBy,
cssClass,
domainObject,
historicLink,
id: 'embed-' + date,
name,
snapshot,
type
};
}
export async function addNotebookEntry(
openmct,
domainObject,
notebookStorage,
passedEmbeds = [],
entryText = ''
) {
if (!openmct || !domainObject || !notebookStorage) {
return;
}
const date = openmct.time.now();
const configuration = domainObject.configuration;
const entries = configuration.entries || {};
// if embeds isn't an array, make it one
const embedsNormalized =
passedEmbeds && !Array.isArray(passedEmbeds) ? [passedEmbeds] : passedEmbeds;
const id = `entry-${uuid()}`;
const [createdBy, createdByRole] = await Promise.all([
getUsername(openmct),
getActiveRole(openmct)
]);
const entry = {
id,
createdOn: date,
createdBy,
createdByRole,
text: entryText,
embeds: embedsNormalized
};
const newEntries = addEntryIntoPage(notebookStorage, entries, entry);
addDefaultClass(domainObject, openmct);
mutateObject(openmct, domainObject, 'configuration.entries', newEntries);
return id;
}
export function getNotebookEntries(domainObject, selectedSection, selectedPage) {
if (!domainObject || !selectedSection || !selectedPage || !domainObject.configuration) {
return;
}
const configuration = domainObject.configuration;
const entries = configuration.entries || {};
let section = entries[selectedSection.id];
if (!section) {
return;
}
let page = entries[selectedSection.id][selectedPage.id];
if (!page) {
return;
}
const specificEntries = entries[selectedSection.id][selectedPage.id];
return specificEntries;
}
export function getEntryPosById(entryId, domainObject, selectedSection, selectedPage) {
if (!domainObject || !selectedSection || !selectedPage) {
return;
}
const entries = getNotebookEntries(domainObject, selectedSection, selectedPage);
let foundId = -1;
entries.forEach((element, index) => {
if (element.id === entryId) {
foundId = index;
return;
}
});
return foundId;
}
export function deleteNotebookEntries(openmct, domainObject, selectedSection, selectedPage) {
if (!domainObject || !selectedSection) {
return;
}
const configuration = domainObject.configuration;
const entries = configuration.entries || {};
// Delete entire section
if (!selectedPage) {
delete entries[selectedSection.id];
return;
}
let section = entries[selectedSection.id];
if (!section) {
return;
}
delete entries[selectedSection.id][selectedPage.id];
mutateObject(openmct, domainObject, 'configuration.entries', entries);
}
export function mutateObject(openmct, object, key, value) {
openmct.objects.mutate(object, key, value);
}
function addDefaultClass(domainObject, openmct) {
openmct.status.set(domainObject.identifier, DEFAULT_CLASS);
}