diff --git a/src/firefly/js/Firefly.js b/src/firefly/js/Firefly.js index eaf2b4f14c..b701035872 100644 --- a/src/firefly/js/Firefly.js +++ b/src/firefly/js/Firefly.js @@ -434,58 +434,53 @@ export const firefly = { * @param {AppProps} props - application properties * @param {FireflyOptions} clientAppSpecificOptions - firefly options specific to this client * @param {Array.} webApiCommands - * @returns {Promise.} + * @returns {Promise.} */ -function bootstrap(props, clientAppSpecificOptions, webApiCommands) { +async function bootstrap(props, clientAppSpecificOptions, webApiCommands) { - if (window?.firefly?.initialized) return Promise.resolve(); // if initialized, don't run it again. + if (window?.firefly?.initialized) return; // if initialized, don't run it again. set(window, 'firefly.initialized', true); - return new Promise(async (resolve) => { - const processDecor= (process) => (rawAction) => { - getOrCreateWsConn().catch(() => { - if (!getConnectionStatus()?.lost) { // set lost status only when it's not already set, to avoid circular dispatches - dispatchConnectionStatus({lost: true, reason: 'You are no longer connected to the server'}); - } - }); - process(rawAction); - recordHistory(rawAction); - }; - - bootstrapRedux( getBootstrapRegistry(), processDecor); - flux.process( {type : APP_LOAD} ); // setup initial store/state + const processDecor= (process) => (rawAction) => { + getOrCreateWsConn().catch(() => { + if (!getConnectionStatus()?.lost) { // set lost status only when it's not already set, to avoid circular dispatches + dispatchConnectionStatus({lost: true, reason: 'You are no longer connected to the server'}); + } + }); + process(rawAction); + recordHistory(rawAction); + }; - let srvAppSpecificOptions={}; - try { - srvAppSpecificOptions= await getJsonProperty('FIREFLY_OPTIONS'); - } - catch (err) { - logger.error('could not retrieve valid server options'); - } - // const appSpecificOptions = mergeObjectOnly(clientAppSpecificOptions, srvAppSpecificOptions); - const appSpecificOptions = mergeAppOptions(clientAppSpecificOptions, srvAppSpecificOptions); + bootstrapRedux( getBootstrapRegistry(), processDecor); + flux.process( {type : APP_LOAD} ); // setup initial store/state - const client= await getOrCreateWsConn(); // establish websocket connection first before doing anything else. + let srvAppSpecificOptions={}; + try { + srvAppSpecificOptions= await getJsonProperty('FIREFLY_OPTIONS'); + } + catch (err) { + logger.error('could not retrieve valid server options'); + } + // const appSpecificOptions = mergeObjectOnly(clientAppSpecificOptions, srvAppSpecificOptions); + const appSpecificOptions = mergeAppOptions(clientAppSpecificOptions, srvAppSpecificOptions); - fireflyInit(props, appSpecificOptions, webApiCommands); + const client= await getOrCreateWsConn(); // establish websocket connection first before doing anything else. - client.addListener(ActionEventHandler); - window.firefly.wsClient = client; - notifyServerAppInit({spaName:`${props.appTitle||''}--${props.template?props.template:'api'}`}); - loadAllJobs(); - resolve?.(); + fireflyInit(props, appSpecificOptions, webApiCommands); + client.addListener(ActionEventHandler); + window.firefly.wsClient = client; + notifyServerAppInit({spaName:`${props.appTitle||''}--${props.template?props.template:'api'}`}); + loadAllJobs(); - }).then(() => { - // when all is done, mark app as 'ready' - defer(() => { - setTimeout(() => { - dispatchUpdateAppData({isReady: true}); - },3); - }); - initWorkerContext(); + // when all is done, mark app as 'ready' + defer(() => { + setTimeout(() => { + dispatchUpdateAppData({isReady: true}); + },3); }); + initWorkerContext(); } /** diff --git a/src/firefly/js/charts/ChartUtil.js b/src/firefly/js/charts/ChartUtil.js index 18499c04df..28a25485f4 100644 --- a/src/firefly/js/charts/ChartUtil.js +++ b/src/firefly/js/charts/ChartUtil.js @@ -1195,7 +1195,7 @@ export function formatColExpr({colOrExpr, quoted, colNames}) { // quote columns, assuming column names are alpha-numeric expr.getParsedVariables().forEach((v) => { if (!v.startsWith('"')) { - const re = new RegExp('([^A-Za-z\d_"]|^)(' + v + ')([^A-Za-z\d_"]|$)', 'g'); + const re = new RegExp('([^A-Za-z0-9_"]|^)(' + v + ')([^A-Za-z0-9_"]|$)', 'g'); while (colOrExpr.match(re)) { // while is needed to handle cases like v*v colOrExpr = colOrExpr.replace(re, '$1"$2"$3'); // add quotes } diff --git a/src/firefly/js/charts/__tests__/ChartUtil-test.js b/src/firefly/js/charts/__tests__/ChartUtil-test.js new file mode 100644 index 0000000000..344f414dda --- /dev/null +++ b/src/firefly/js/charts/__tests__/ChartUtil-test.js @@ -0,0 +1,14 @@ +/*eslint-env node, jest */ +import {formatColExpr} from 'firefly/charts/ChartUtil.js'; + + +describe('ChartUtil', () => { + test('formatColExpr does not treat a digit as the edge of a column name', () => { + const colNames = ['val', 'val2']; + expect(formatColExpr({colOrExpr: 'val + val2', quoted: true, colNames})).toBe('"val"+"val2"'); + expect(formatColExpr({colOrExpr: 'val2 + val', quoted: true, colNames})).toBe('"val2"+"val"'); + + // the digits around e belong to the number 1e5 + expect(formatColExpr({colOrExpr: '1e5*e', quoted: true, colNames: ['e']})).toBe('1e5*"e"'); + }); +}); diff --git a/src/firefly/js/charts/ui/CombineChart.jsx b/src/firefly/js/charts/ui/CombineChart.jsx index dca2f24789..4ecdb74984 100644 --- a/src/firefly/js/charts/ui/CombineChart.jsx +++ b/src/firefly/js/charts/ui/CombineChart.jsx @@ -114,12 +114,12 @@ CombineChart.propTypes = { * @constructor */ export const CombinePinnedCharts = ({viewerId, slotProps}) => { - if (viewerId !== PINNED_CHART_VIEWER_ID) return null; - const {chartIds, selectedChartId} = useStoreConnector(() => ({ chartIds: getViewerItemIds(getMultiViewRoot(), viewerId), selectedChartId: getActiveViewerItemId(viewerId, true) }), [viewerId]); + + if (viewerId !== PINNED_CHART_VIEWER_ID) return null; return ; }; diff --git a/src/firefly/js/tables/HpxIndexCntlr.js b/src/firefly/js/tables/HpxIndexCntlr.js index a236dd54cf..facbd31434 100644 --- a/src/firefly/js/tables/HpxIndexCntlr.js +++ b/src/firefly/js/tables/HpxIndexCntlr.js @@ -798,7 +798,7 @@ export function getPixelCount(orderData,norder) { export function getValuesForOrder(orderData,norder) { if (!orderData) return []; - if (norder<11) return [...orderData[norder]?.tiles[0]?.values()]; + if (norder<11) return [...(orderData[norder]?.tiles[0]?.values() ?? [])]; const joinAry= []; for(let i=0; (i { + const orderData = {5: {norder: 5, tiles: [new Map([[1, 'a'], [2, 'b']])]}}; + + test('getValuesForOrder and getKeysForOrder return the tile entries of an order', () => { + expect(getValuesForOrder(orderData, 5)).toEqual(['a', 'b']); + expect(getKeysForOrder(orderData, 5)).toEqual([1, 2]); + }); + + test('getValuesForOrder and getKeysForOrder return an empty array for a missing order', () => { + expect(getValuesForOrder(orderData, 1)).toEqual([]); + expect(getKeysForOrder(orderData, 1)).toEqual([]); + }); + + test('getKeysForOrder returns an empty array without orderData', () => { + expect(getKeysForOrder(undefined, 4)).toEqual([]); + }); +}); diff --git a/src/firefly/js/util/ObsCoreSRegionParser.js b/src/firefly/js/util/ObsCoreSRegionParser.js index 117be050e6..640b6be114 100644 --- a/src/firefly/js/util/ObsCoreSRegionParser.js +++ b/src/firefly/js/util/ObsCoreSRegionParser.js @@ -200,9 +200,9 @@ export function parseObsCoreRegion(sRegionVal, unit='deg', isCorners=false) { break; case regionShape.box.key: - if (sAry.length = height + 1) { - const w = getDim(sAry[width], coordSys, unit, 'arcsec'); - const h = getDim(sAry[height], coordSys, unit, 'arcsec'); + if (sAry.length === height + 1) { + const w = getDim(sAry[width], coordSys, unit, ShapeDataObj.UnitType.ARCSEC); + const h = getDim(sAry[height], coordSys, unit, ShapeDataObj.UnitType.ARCSEC); pairCoord = getPairCoord(sAry, [coord1, coord2]); if (pairCoord.length === 2 && w !== null && h !== null) { diff --git a/src/firefly/js/util/__tests__/Expression-test.js b/src/firefly/js/util/__tests__/Expression-test.js index 773da21ec8..f2add2d7c6 100644 --- a/src/firefly/js/util/__tests__/Expression-test.js +++ b/src/firefly/js/util/__tests__/Expression-test.js @@ -105,6 +105,20 @@ describe('A test suite for expr/Expression.js', function () { // expect(expressionGood.getValue()).toBe(2^x); }); + it('nvl2', function () { + const expr = new Expression('nvl2(x, 1, 2)', ['x']); + expect(expr.isValid()).toBeTruthy(); + expr.setVariableValue('x', 5); + expect(expr.getValue()).toBe(1); + expr.setVariableValue('x', NaN); + expect(expr.getValue()).toBe(2); + + // all-constant arguments are evaluated while parsing + const constExpr = new Expression('nvl2(1, 2, 3)', []); + expect(constExpr.isValid()).toBeTruthy(); + expect(constExpr.getValue()).toBe(2); + }); + it('invalid expression', function () { const expressionBad = new Expression('2*sin(x)+y/z', ['x','y']); expect(expressionBad.isValid()).toBeFalsy(); diff --git a/src/firefly/js/util/expr/Expr.js b/src/firefly/js/util/expr/Expr.js index 75aaf5c51c..e65d54069a 100644 --- a/src/firefly/js/util/expr/Expr.js +++ b/src/firefly/js/util/expr/Expr.js @@ -230,7 +230,7 @@ class TernaryExpr { const arg1 = this.rand1.value(); const arg2 = this.rand2.value(); switch (this.rator) { - case NVL2: Number.isFinite(arg0) ? arg1 : arg2; + case NVL2: return Number.isFinite(arg0) ? arg1 : arg2; default: throw 'BUG: bad rator: '+this.rator; } } diff --git a/src/firefly/js/visualize/WebPlot.js b/src/firefly/js/visualize/WebPlot.js index bd4ce4892c..bd490e32d5 100644 --- a/src/firefly/js/visualize/WebPlot.js +++ b/src/firefly/js/visualize/WebPlot.js @@ -461,7 +461,7 @@ export const WebPlot= { const relatedData = cubeCtx ? cubeCtx.relatedData : wpInit.relatedData; const plotState= PlotState.makePlotStateWithJson(wpInit.plotState,request0, rv0); if (!request0) request0= plotState.getWebPlotRequest(); - const colorTableId= request0?.getInitialColorTable()+'' ?? '0'; + const colorTableId= String(request0?.getInitialColorTable() ?? '0'); const {processHeader, wlData, wlDataAry, headerAry, header, zeroHeader, allWCSMap, allWlMap}= getAllHeaderAndWlInfo(cubeCtx,wpInit,plotState); diff --git a/src/firefly/js/visualize/draw/SelectBox.js b/src/firefly/js/visualize/draw/SelectBox.js index 82d124cff9..6567e74c4f 100644 --- a/src/firefly/js/visualize/draw/SelectBox.js +++ b/src/firefly/js/visualize/draw/SelectBox.js @@ -198,7 +198,7 @@ function drawBox(ctx, pt0, pt2, drawParams,renderOptions) { DrawUtil.drawInnerRecWithHandles(ctx, innerBoxColor, 2, pt0.x, pt0.y, pt2.x, pt2.y, lineWidth); } else if (selectedShape === SelectedShape.circle.key) { DrawUtil.drawCircleWithHandles(ctx, innerBoxColor, 2, pt0.x, pt0.y, pt2.x, pt2.y, lineWidth); - } else if (selectedShape === SelectedShape.circle.key) { + } else if (selectedShape === SelectedShape.ellipse.key) { DrawUtil.drawEclipseWithHandles(ctx, innerBoxColor, 2, pt0.x, pt0.y, pt2.x, pt2.y, lineWidth); }