Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 36 additions & 69 deletions src/api.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,20 @@
import { ApiProxyConnector } from "@elastic/search-ui-elasticsearch-connector";
import { toByteArray } from "base64-js";
import CustomElasticSearchAPIConnector from "./components/caputlog/CustomElasticSearchAPIConnector";
import config from "./config";

const channelFinderURL = import.meta.env.PROD ? import.meta.env.REACT_APP_CF_URL : import.meta.env.REACT_APP_CF_URL_DEV;
const cfMaxResults = parseInt(import.meta.env.REACT_APP_CF_MAX_RESULTS);
const ologURL = import.meta.env.PROD ? import.meta.env.REACT_APP_OLOG_URL : import.meta.env.REACT_APP_OLOG_URL_DEV;
const ologWebURL = import.meta.env.PROD ? import.meta.env.REACT_APP_OLOG_WEB_CLIENT_URL : import.meta.env.REACT_APP_OLOG_WEB_CLIENT_URL_DEV;
const aaViewerURL = import.meta.env.PROD ? import.meta.env.REACT_APP_AA_URL : import.meta.env.REACT_APP_AA_URL_DEV;
const pvwsURL = import.meta.env.PROD ? import.meta.env.REACT_APP_PVWS_URL : import.meta.env.REACT_APP_PVWS_URL_DEV;
const pvwsHTTPURL = import.meta.env.PROD ? import.meta.env.REACT_APP_PVWS_HTTP_URL : import.meta.env.REACT_APP_PVWS_HTTP_URL_DEV;
const serverURL = import.meta.env.PROD ? import.meta.env.REACT_APP_BASE_URL : import.meta.env.REACT_APP_BASE_URL_DEV;
const alarmLogURL = import.meta.env.PROD ? import.meta.env.REACT_APP_AL_URL : import.meta.env.REACT_APP_AL_URL_DEV;
const caputlogURL = import.meta.env.PROD ? import.meta.env.REACT_APP_CAPUTLOG_URL : import.meta.env.REACT_APP_CAPUTLOG_URL_DEV;
const ologStartDays = import.meta.env.REACT_APP_OLOG_START_TIME_DAYS !== '' ?
`&start=${import.meta.env.REACT_APP_OLOG_START_TIME_DAYS}days&end=now`
const cfMaxResults = config.CF_MAX_RESULTS;
const ologStartDays = config.OLOG_START_TIME_DAYS !== null
? `&start=${config.OLOG_START_TIME_DAYS}days&end=now`
: "";
const ologMaxResults = import.meta.env.REACT_APP_OLOG_MAX_RESULTS !== '' ?
`&size=${import.meta.env.REACT_APP_OLOG_MAX_RESULTS}`
const ologMaxResults = config.OLOG_MAX_RESULTS !== null
? `&size=${config.OLOG_MAX_RESULTS}`
: "";
const alarmLogStartDays = import.meta.env.REACT_APP_AL_START_TIME_DAYS !== '' ?
`&start=${import.meta.env.REACT_APP_AL_START_TIME_DAYS}days&end=now`
const alarmLogStartDays = config.AL_START_TIME_DAYS !== null
? `&start=${config.AL_START_TIME_DAYS}days&end=now`
: "";
const alarmLogMaxResults = import.meta.env.REACT_APP_AL_MAX_RESULTS !== '' ?
`&size=${import.meta.env.REACT_APP_AL_MAX_RESULTS}`
const alarmLogMaxResults = config.AL_MAX_RESULTS !== null
? `&size=${config.AL_MAX_RESULTS}`
: "";

const elasticIndexName = import.meta.env.REACT_APP_ELASTICSEARCH_INDEX_NAME;
const elasticApikey = import.meta.env.REACT_APP_ELASTICSEARCH_API_KEY;
// Choice to use Elasticsearch directly or an API Proxy
const useProxy = import.meta.env.REACT_APP_USE_CAPUT_API_PROXY_CONNNECTOR ?? "false";
const caputLogConnector = (useProxy === "true")
? new ApiProxyConnector({
basePath: `${caputlogURL}`
})
: CustomElasticSearchAPIConnector({
host: `${caputlogURL}`,
index: `${elasticIndexName}`,
apiKey: `${elasticApikey}`
});

function handleParams(params) {
let urlParams = { "pvName": "*", "params": "" };
if ("pvName" in params && params.pvName !== "") {
Expand All @@ -64,11 +40,11 @@ function handleParams(params) {

function standardParse(params) {
let noWildcard = new Set(["pvStatus", "recordType"]);
if (import.meta.env.REACT_APP_EXTRA_PROP && import.meta.env.REACT_APP_EXTRA_PROP_DROPDOWN_LABELS) {
noWildcard.add(import.meta.env.REACT_APP_EXTRA_PROP);
if (config.EXTRA_PROP && config.EXTRA_PROP_DROPDOWN_LABELS) {
noWildcard.add(config.EXTRA_PROP);
}
if (import.meta.env.REACT_APP_SECOND_EXTRA_PROP && import.meta.env.REACT_APP_SECOND_EXTRA_PROP_DROPDOWN_LABELS) {
noWildcard.add(import.meta.env.REACT_APP_SECOND_EXTRA_PROP);
if (config.SECOND_EXTRA_PROP && config.SECOND_EXTRA_PROP_DROPDOWN_LABELS) {
noWildcard.add(config.SECOND_EXTRA_PROP);
}

let addOn = "";
Expand Down Expand Up @@ -111,11 +87,10 @@ function freeformParse(params) {
async function queryChannelFinder(params) {
let urlParams = handleParams(params);
let maxResults = cfMaxResults ? `&~size=${cfMaxResults}` : "";
let requestURI = `${channelFinderURL}/resources/channels?~name=${urlParams.pvName}${urlParams.params}${maxResults}`;
let options = {};
options = { method: 'GET' }
if (import.meta.env.REACT_APP_SEND_CREDENTIALS === "true") {
if (import.meta.env.PROD) {
let requestURI = `${config.CF_URL}/resources/channels?~name=${urlParams.pvName}${urlParams.params}${maxResults}`;
let options = { method: 'GET' }
if (config.SEND_CREDENTIALS) {
if (config.IS_PROD) {
// credentials header would help if CF, AA, etc are behind a SSO
options['credentials'] = 'include';
}
Expand All @@ -130,9 +105,9 @@ async function queryLog(logType, pvName, extraParams) {

let requestURI = ""
if (logType === logEnum.ONLINE_LOG) {
requestURI = encodeURI(`${ologURL}/logs/search?text=${pvName}${ologStartDays}${ologMaxResults}`);
requestURI = encodeURI(`${config.OLOG_URL}/logs/search?text=${pvName}${ologStartDays}${ologMaxResults}`);
} else if (logType === logEnum.ALARM_LOG) {
requestURI = encodeURI(`${alarmLogURL}/search/alarm?pv=${pvName}${alarmLogStartDays}${alarmLogMaxResults}${extraParams}`);
requestURI = encodeURI(`${config.AL_URL}/search/alarm?pv=${pvName}${alarmLogStartDays}${alarmLogMaxResults}${extraParams}`);
} else {
return new Promise((resolve, reject) => {
reject();
Expand All @@ -145,9 +120,9 @@ async function getQueryHelpers(helperType) {
let requestURI = ""

if (helperType === queryHelperEnum.PROPERTIES) {
requestURI = `${channelFinderURL}/resources/properties`
requestURI = `${config.CF_URL}/resources/properties`
} else if (helperType === queryHelperEnum.TAGS) {
requestURI = `${channelFinderURL}/resources/tags`
requestURI = `${config.CF_URL}/resources/tags`
} else {
return new Promise((resolve, reject) => {
reject();
Expand All @@ -167,34 +142,34 @@ async function getQueryHelpers(helperType) {

async function getCount(params = {}) {
let urlParams = handleParams(params)
let requestURI = `${channelFinderURL}/resources/channels/count?~name=${urlParams.pvName}${urlParams.params}`;
let requestURI = `${config.CF_URL}/resources/channels/count?~name=${urlParams.pvName}${urlParams.params}`;

return await standardQuery(requestURI);
}

async function getCFInfo() {
return await standardQuery(channelFinderURL);
return await standardQuery(config.CF_URL);
}

async function getALInfo() {
const requestURI = alarmLogURL + "/"
const requestURI = config.AL_URL + "/"
return await standardQuery(requestURI);
}

async function getOLOGInfo() {
return await standardQuery(ologURL);
return await standardQuery(config.OLOG_URL);
}

async function getCaputLogInfo() {
return await standardQuery(caputlogURL);
return await standardQuery(config.CAPUTLOG_URL);
}

async function getPVWSInfo(path) {
if (pvwsHTTPURL === "") return;
if (pvwsHTTPURL.slice(-1) !== "/") {
if (config.PVWS_HTTP_URL === "") return;
if (config.PVWS_HTTP_URL.slice(-1) !== "/") {
path = "/" + path;
}
const requestURI = pvwsHTTPURL + path;
const requestURI = config.PVWS_HTTP_URL + path;
return await standardQuery(requestURI);
}

Expand All @@ -203,8 +178,8 @@ async function standardQuery(requestURI, options = null, handleData = null) {
let error = "";
let errorFlag = false;

if (import.meta.env.REACT_APP_SEND_CREDENTIALS === "true") {
if (import.meta.env.PROD) {
if (config.SEND_CREDENTIALS) {
if (config.IS_PROD) {
if (options === null) options = {};
// credentials header would help if CF, AA, etc are behind a SSO
options['credentials'] = 'include';
Expand Down Expand Up @@ -291,16 +266,16 @@ function parseWebSocketMessage(jsonMessage, fixedPrecision = null) {
pvData.pv_value = Array.prototype.slice.call(value_array);
} else if ("b64byt" in pvData) {
let bytes = toByteArray(pvData.b64byt);
if (import.meta.env.REACT_APP_PVWS_TREAT_BYTE_ARRAY_AS_STRING === "false") {
let value_array = new Uint8Array(bytes.buffer);
pvData.pv_value = Array.prototype.slice.call(value_array);
} else {
if (config.PVWS_TREAT_BYTE_ARRAY_AS_STRING) {
try {
const decoder = new TextDecoder('utf-8');
pvData.pv_value = decoder.decode(bytes);
} catch (error) {
console.log("Error decoding byte array: ", error.message);
}
} else {
let value_array = new Uint8Array(bytes.buffer);
pvData.pv_value = Array.prototype.slice.call(value_array);
}
} else if ("b64flt" in pvData) {
let bytes = toByteArray(pvData.b64flt);
Expand Down Expand Up @@ -359,16 +334,8 @@ const api = {
OLI_QUERY: getOLOGInfo,
CAPUTLOG_QUERY: getCaputLogInfo,
PVWSI_QUERY: getPVWSInfo,
CF_URL: channelFinderURL,
OLOG_URL: ologURL,
OLOG_WEB_URL: ologWebURL,
AA_VIEWER: aaViewerURL,
PVWS_URL: pvwsURL,
SERVER_URL: serverURL,
LOG_ENUM: logEnum,
HELPERS_ENUM: queryHelperEnum,
CAPUTLOG_URL: caputlogURL,
CAPUTLOG_CONNECTOR: caputLogConnector,
PARSE_WEBSOCKET_MSG: parseWebSocketMessage,
}

Expand Down
5 changes: 3 additions & 2 deletions src/app/App.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import './App.css';
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { Grid, Snackbar, Alert } from '@mui/material';
import React, { useState } from "react";
import { useState } from "react";

import config from "../config";
import Home from '../components/home';
import PV from '../components/pv';
import IOC from '../components/ioc';
Expand Down Expand Up @@ -39,7 +40,7 @@ function App() {
<Route path="/plot" exact={true} element={<Plot />} />
<Route path="/services" exact={true} element={<Services />} />
{
import.meta.env.REACT_APP_USE_CAPUTLOG === "true" ? <Route path="/caputlog" exact={true} element={<CaputLogPage />} /> : null
config.USE_CAPUTLOG ? <Route path="/caputlog" exact={true} element={<CaputLogPage />} /> : null
}
<Route path="/help" exact={true} element={<Help />} />
<Route path="/" exact={true} element={<Home handleOpenErrorAlert={setOpenErrorAlert} handleErrorMessage={setErrorMessage} handleSeverity={setSeverity} />} />
Expand Down
18 changes: 12 additions & 6 deletions src/colors.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
const okCol = "#" + import.meta.env.REACT_APP_OK_SEVERITY_COLOR;
const minorCol = "#" + import.meta.env.REACT_APP_MINOR_SEVERITY_COLOR;
const majorCol = "#" + import.meta.env.REACT_APP_MAJOR_SEVERITY_COLOR;
const invalidCol = "#" + import.meta.env.REACT_APP_INVALID_SEVERITY_COLOR;
const undefinedCol = "#" + import.meta.env.REACT_APP_UNDEFINED_SEVERITY_COLOR;
import config from "./config";

const handleColor = (value) => {
if (!value) return null;
return value.startsWith("#") ? value : `#${value}`;
};

const okCol = handleColor(config.OK_SEVERITY_COLOR);
const minorCol = handleColor(config.MINOR_SEVERITY_COLOR);
const majorCol = handleColor(config.MAJOR_SEVERITY_COLOR);
const invalidCol = handleColor(config.INVALID_SEVERITY_COLOR);
const undefinedCol = handleColor(config.UNDEFINED_SEVERITY_COLOR);

// modBrightness function sourced from https://natclark.com/tutorials/javascript-lighten-darken-hex-color/
const modBrightness = (hexColor, magnitude) => {
Expand Down Expand Up @@ -39,6 +45,6 @@ const severityColors = {

const colors = {
SEV_COLORS: severityColors,
}
};

export default colors;
4 changes: 2 additions & 2 deletions src/components/caputlog/caputlogSearchConfig.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import api from "../../api";
import config from "../../config";

export function getCaputLogSearchConfig({ filters = [], search_fields = {}, facets = {}, initialState = {} } = {}) {
return {
alwaysSearchOnInitialLoad: true,
apiConnector: api.CAPUTLOG_CONNECTOR,
apiConnector: config.CAPUTLOG_CONNECTOR,
hasA11yNotifications: true,
trackUrlState: false,
searchQuery: {
Expand Down
8 changes: 5 additions & 3 deletions src/components/header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import InfoIcon from '@mui/icons-material/Info'
import MenuIcon from '@mui/icons-material/Menu';
import { makeStyles } from 'tss-react/mui';

import config from '../../config';

const useStyles = makeStyles()((theme) => ({
root: {
flexGrow: 1,
Expand Down Expand Up @@ -68,7 +70,7 @@ function Header() {
</ListItemIcon>
<ListItemText primary="Plotting" />
</ListItemButton>
{(import.meta.env.REACT_APP_USE_CAPUTLOG || "").toLowerCase() === "true" &&
{config.USE_CAPUTLOG &&
<ListItemButton key="CaputLog" component={NavLink} to="/caputlog" onClick={handleMenuToggle} divider color="primary">
<ListItemIcon>
<InfoIcon color="primary" />
Expand Down Expand Up @@ -101,12 +103,12 @@ function Header() {
<NavLink to="/ioc" style={{ textDecoration: "none", color: 'inherit', paddingRight: 40 }}>
<Typography variant="h5">IOCs</Typography>
</NavLink>
{(import.meta.env.REACT_APP_USE_AA || "").toLowerCase() === "true" &&
{config.USE_AA &&
<NavLink to="/plot" style={{ textDecoration: "none", color: 'inherit', paddingRight: 40 }}>
<Typography variant="h5">Plotting</Typography>
</NavLink>
}
{(import.meta.env.REACT_APP_USE_CAPUTLOG || "").toLowerCase() === "true" &&
{config.USE_CAPUTLOG &&
<NavLink to="/caputlog" style={{ textDecoration: "none", color: 'inherit', paddingRight: 40 }}>
<Typography variant="h5">Caput Log</Typography>
</NavLink>
Expand Down
18 changes: 9 additions & 9 deletions src/components/help/Help.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Fragment } from "react";
import { Typography, Grid, Link } from "@mui/material";
import { Link as RouterLink } from "react-router-dom";
import archivePlotOptions from "../../assets/archive-options.png";

import config from "../../config";

function Help() {

Expand All @@ -18,7 +18,7 @@ function Help() {
<Typography variant='body1' paragraph={true}>
Process Variable (PV) is the name applied to the Real-Time Database Records that contain control system information.
Like most Database records it has a set of fields. Unlike conventional database records, Process Variables are 'connected' to the 'real world',
so they reflect or control values in the control system. For example, here is a PV at our facility: <Link component={RouterLink} to={"/pv/" + import.meta.env.REACT_APP_HELP_EXAMPLE_PV} underline="always">{import.meta.env.REACT_APP_HELP_EXAMPLE_PV}</Link>
so they reflect or control values in the control system. For example, here is a PV at our facility: <Link component={RouterLink} to={"/pv/" + config.HELP_EXAMPLE_PV} underline="always">{config.HELP_EXAMPLE_PV}</Link>
</Typography>
<Typography variant='body1' paragraph={true}>
The Control System is based on the Experimental Physics and Industrial Control System
Expand Down Expand Up @@ -88,7 +88,7 @@ function Help() {

<li>
Current status of this PV. Either Active or Inactive. Inactive means the PV is not synchronized with the recsync server and indicates a problem with the IOC or recsync.
{ import.meta.env.REACT_APP_PVWS_IGNORE_CF_PVSTATUS !== "true" &&
{ !config.PVWS_IGNORE_CF_PVSTATUS &&
<li>If the PV is inactive then the PV value monitor checkbox will be disabled.</li>
}
</li>
Expand All @@ -105,22 +105,22 @@ function Help() {
PVs can have alias names. You can click on the alias name to open the details page for the alias (will have the same information as the real PV name).
</li>
</ul>
{import.meta.env.REACT_APP_EXTRA_PROP.length > 0 &&
{config.EXTRA_PROP && config.EXTRA_PROP.length > 0 &&
<div>
<li><strong>{import.meta.env.REACT_APP_EXTRA_PROP_LABEL}</strong></li>
<li><strong>{config.EXTRA_PROP_LABEL}</strong></li>
<ul>
<li>
{import.meta.env.REACT_APP_EXTRA_PROP_HELP_TEXT}
{config.EXTRA_PROP_HELP_TEXT}
</li>
</ul>
</div>
}
{import.meta.env.REACT_APP_SECOND_EXTRA_PROP.length > 0 &&
{config.SECOND_EXTRA_PROP && config.SECOND_EXTRA_PROP.length > 0 &&
<div>
<li><strong>{import.meta.env.REACT_APP_SECOND_EXTRA_PROP_LABEL}</strong></li>
<li><strong>{config.SECOND_EXTRA_PROP_LABEL}</strong></li>
<ul>
<li>
{import.meta.env.REACT_APP_SECOND_EXTRA_PROP_HELP_TEXT}
{config.SECOND_EXTRA_PROP_HELP_TEXT}
</li>
</ul>
</div>
Expand Down
Loading