UNPKG

model-navigator-standalone

Version:

Standalone MDF graph model visualizer

302 lines (298 loc) 12.9 kB
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } import "core-js/modules/es.array.includes.js"; import "core-js/modules/es.object.assign.js"; import "core-js/modules/esnext.iterator.constructor.js"; import "core-js/modules/esnext.iterator.filter.js"; import "core-js/modules/esnext.iterator.find.js"; import "core-js/modules/esnext.iterator.for-each.js"; import "core-js/modules/esnext.iterator.map.js"; /* eslint-disable no-plusplus */ import React from 'react'; import { List, ListItem, createTheme, ThemeProvider, StyledEngineProvider } from '@mui/material'; const getType = prop => { if (['value_set', 'list'].includes(prop.type)) { return prop.valueSet(); } else { return prop.type || 'UNDEFINED'; } }; const theme = { components: { MuiList: { styleOverrides: { padding: { paddingTop: '2px' } } }, MuiListItem: { styleOverrides: { root: { paddingLeft: '0px', paddingTop: '2px', marginTop: '-10px', paddingBottom: '0', alignItems: 'inherit', fontWeight: '300', wordBreak: 'break-all' }, gutters: { paddingLeft: '0px !important', paddingRight: '0px', wordBreak: 'break-all' } } }, MuiListItemText: { styleOverrides: { root: { padding: '4px', marginTop: '0px', marginBottom: '0px' } } } } }; const escapeReturnChar = (str, newlineClassName) => { if (!str) return str; const pieces = str.split('\\n'); if (pieces.length <= 1) return str; return pieces.map((piece, i) => /*#__PURE__*/React.createElement("span", { key: "span-".concat(i), className: i === 0 || i === pieces.length ? '' : newlineClassName }, piece)); }; const displayKeyPropsDescription = description => { const lines = description.split('<br>'); if (lines.length > 1) { return lines.map(line => /*#__PURE__*/React.createElement("span", null, line)); } return description; }; export const addHighlightingSpans = (str, indices, spanClassName) => { if (!str) { return /*#__PURE__*/React.createElement(React.Fragment, null); } let cursor = 0; let currentIndices = 0; const resultFragments = []; const highlightSpanClassName = "".concat(spanClassName, "--highlight"); const newlineClassName = "".concat(spanClassName, "--new-line"); while (currentIndices < indices.length) { if (cursor < indices[currentIndices][0]) { resultFragments.push(/*#__PURE__*/React.createElement("div", { key: cursor, className: spanClassName }, escapeReturnChar(str.substring(cursor, indices[currentIndices][0]), newlineClassName))); } resultFragments.push(/*#__PURE__*/React.createElement("div", { key: indices[currentIndices][0], className: "".concat(spanClassName, " ").concat(highlightSpanClassName) }, escapeReturnChar(str.substring(indices[currentIndices][0], indices[currentIndices][1] + 1), newlineClassName))); cursor = indices[currentIndices][1] + 1; currentIndices += 1; } if (cursor < str.length) { resultFragments.push(/*#__PURE__*/React.createElement("div", { key: cursor, className: spanClassName }, displayKeyPropsDescription(escapeReturnChar(str.substring(cursor), newlineClassName)))); } return resultFragments; }; export const getPropertyNameFragment = (prop, matchedItem, spanClassName) => { const propertyNameFragment = addHighlightingSpans(prop.handle, matchedItem ? matchedItem.indices : [], spanClassName); return propertyNameFragment; }; export const getPropertyTypeFragment = (prop, typeMatchList, spanClassName) => { const type = getType(prop); let propertyTypeFragment; if (typeof type === 'string') { propertyTypeFragment = /*#__PURE__*/React.createElement(React.Fragment, null, addHighlightingSpans(type, typeMatchList && typeMatchList[0] ? typeMatchList[0].indices : [], spanClassName)); } if (Array.isArray(type)) { propertyTypeFragment = type.map((t, i) => { const matchedTypeItem = typeMatchList && typeMatchList.find(matchItem => matchItem.value === t); if (matchedTypeItem) { return /*#__PURE__*/React.createElement(StyledEngineProvider, { injectFirst: true }, /*#__PURE__*/React.createElement(ThemeProvider, { theme: createTheme(theme) }, /*#__PURE__*/React.createElement(List, null, /*#__PURE__*/React.createElement(ListItem, { key: i }, addHighlightingSpans(t, matchedTypeItem.indices, spanClassName))))); } return /*#__PURE__*/React.createElement(StyledEngineProvider, { injectFirst: true }, /*#__PURE__*/React.createElement(ThemeProvider, { theme: createTheme(theme) }, /*#__PURE__*/React.createElement(List, null, /*#__PURE__*/React.createElement(ListItem, { key: i }, addHighlightingSpans(t, [], spanClassName))))); }); } return propertyTypeFragment; }; export const getPropertyDescriptionFragment = (prop, matchedItem, spanClassName) => { let descriptionStr = prop === null || prop === void 0 ? void 0 : prop.desc; if (!descriptionStr) descriptionStr = 'No Description'; const propertyDescriptionFragment = addHighlightingSpans(descriptionStr, matchedItem ? matchedItem.indices : [], spanClassName); return propertyDescriptionFragment; }; export const getNodeTitleFragment = (allMatches, title, spanClassName) => { const matchedItem = allMatches.find(item => item.key === 'title'); const nodeTitleFragment = addHighlightingSpans(title, matchedItem ? matchedItem.indices : [], spanClassName); return nodeTitleFragment; }; export const getNodeDescriptionFragment = (allMatches, description, spanClassName) => { const matchedItem = allMatches.find(item => item.key === 'description'); const nodeDescriptionFragment = addHighlightingSpans(description, matchedItem ? matchedItem.indices : [], spanClassName); return nodeDescriptionFragment; }; // assume property = model property object export const getMatchInsideProperty = (propertyIndex, propertyKey, prop, allMatches) => { let nameMatch = null; let descriptionMatch = null; const typeMatchList = []; if (allMatches) { allMatches.forEach(item => { if (item.key === 'properties.name' && item.value === propertyKey) { nameMatch = item; } else if (item.key === 'properties.description') { const descriptionStr = prop.desc && prop.desc.toLowerCase(); const splitText = descriptionStr ? descriptionStr.split('<br>')[0] : descriptionStr; if (item.value === splitText) { descriptionMatch = item; } } else if (item.key === 'properties.type') { const type = getType(prop); if (typeof type === 'string') { if (type === item.value) { typeMatchList.push(item); } } else if (Array.isArray(type)) { for (let a = 0; a < type.length; a++) { if (type[a] === item.value) { // TODO: WAS ++ typeMatchList.push(item); } } } } }); } return { nameMatch, descriptionMatch, typeMatchList }; }; export const getMatchesSummaryForProperties = (allProperties, allMatches) => { const matchedPropertiesSummary = []; allProperties.forEach((prop, propertyIndex) => { const { nameMatch, descriptionMatch, typeMatchList } = getMatchInsideProperty(propertyIndex, prop.handle, prop, allMatches); const summaryItem = { prop_handle: prop.handle, prop, nameMatch, descriptionMatch, typeMatchList }; if (nameMatch || descriptionMatch || typeMatchList.length > 0) { matchedPropertiesSummary.push(summaryItem); } }); return matchedPropertiesSummary; }; export const getNodeTitleSVGFragment = (nodeNames, matchedNodeNameIndices, fontSize, textPadding, textLineGap) => { const nodeTitleFragment = []; let currentRowIndex = 0; let rowStartIndex = 0; let rowEndIndex; const nodeNameRows = nodeNames; let currentHighlightIndex = 0; const textAttrBase = { x: 0, textAnchor: 'middle', alignmentBaseline: 'baseline', fontSize, className: 'graph-node__text' }; const tspanAttrBase = { textAnchor: 'middle', alignmentBaseline: 'baseline', fontSize }; const tspanAttr = _objectSpread(_objectSpread({}, tspanAttrBase), {}, { className: 'graph-node__tspan' }); const tspanHighlightAttr = _objectSpread(_objectSpread({}, tspanAttrBase), {}, { className: 'graph-node__tspan graph-node__tspan--highlight' }); while (currentRowIndex < nodeNameRows.length) { // for each row const currentRowStr = nodeNameRows[currentRowIndex]; rowEndIndex = rowStartIndex + currentRowStr.length; const textY = textPadding + currentRowIndex * (fontSize + textLineGap); const textAttr = _objectSpread(_objectSpread({}, textAttrBase), {}, { key: currentRowIndex, y: textY + 10 }); let cursorInRow = 0; const currentRowFragment = []; // Go over all highlighted text in current row while (currentHighlightIndex < matchedNodeNameIndices.length) { const highlightStartIndex = matchedNodeNameIndices[currentHighlightIndex][0]; const highlightEndIndex = matchedNodeNameIndices[currentHighlightIndex][1] + 1; if (highlightStartIndex > rowEndIndex) { currentRowFragment.push(/*#__PURE__*/React.createElement("tspan", _extends({ key: cursorInRow }, tspanAttr), currentRowStr.substring(cursorInRow))); cursorInRow = currentRowStr.length; break; } const highlightStartIndexInRow = highlightStartIndex - rowStartIndex; const highlightEndIndexInRow = highlightEndIndex; if (cursorInRow < highlightStartIndexInRow) { currentRowFragment.push(/*#__PURE__*/React.createElement("tspan", _extends({ key: cursorInRow }, tspanAttr), currentRowStr.substring(cursorInRow, highlightStartIndexInRow))); cursorInRow = highlightStartIndexInRow; } if (highlightEndIndex <= rowEndIndex) { currentRowFragment.push(/*#__PURE__*/React.createElement("tspan", _extends({ key: cursorInRow }, tspanHighlightAttr), currentRowStr.substring(cursorInRow, highlightEndIndexInRow))); cursorInRow = highlightEndIndexInRow; currentHighlightIndex += 1; } else { currentRowFragment.push(/*#__PURE__*/React.createElement("tspan", _extends({ key: cursorInRow }, tspanHighlightAttr), currentRowStr.substring(cursorInRow))); cursorInRow = currentRowStr.lenght; break; } } // Check text in the current row are all added to the list if (cursorInRow < currentRowStr.length) { currentRowFragment.push(/*#__PURE__*/React.createElement("tspan", _extends({ key: cursorInRow }, tspanAttr), currentRowStr.substring(cursorInRow))); } // Add all fragment of current line to the node title fragment list nodeTitleFragment.push(/*#__PURE__*/React.createElement("text", textAttr, currentRowFragment)); currentRowIndex += 1; rowStartIndex += currentRowStr.length + 1; } // end of while, go to the next row return nodeTitleFragment; };