Skip to content

Instantly share code, notes, and snippets.

@joepie91
Created June 10, 2020 15:34
Show Gist options
  • Save joepie91/3d6f1df5dacfee258a71405c79fd1ae4 to your computer and use it in GitHub Desktop.
Save joepie91/3d6f1df5dacfee258a71405c79fd1ae4 to your computer and use it in GitHub Desktop.
app.engine("jsx", expressAsyncReact.createEngine({
prepare: (template, locals) => {
return Promise.try(() => {
if (template.query != null) {
let queryArguments = (template.queryArguments != null)
? template.queryArguments(locals)
: {};
return apiQuery(template.query, queryArguments);
}
}).then((result) => {
if (result == null) {
return {};
} else {
if (result.errors != null && result.errors.length > 0) {
throw result.errors[0];
} else {
return {
data: result.data
};
}
}
});
}
}));
app.set("view engine", "jsx");
app.set("views", projectPath("src/views"));
"use strict";
const React = require("react");
const classnames = require("classnames");
const gql = require("../../../packages/graphql-interface/tag");
const treecutter = require("../../../packages/treecutter");
const Layout = require("../layout");
function Indented({ depth, children }) {
return (
<div style={{ paddingLeft: depth * 10 }}>
{children}
</div>
);
}
function MountEntry({ mount }) {
return <div className="mountpoint">{mount.mountpoint}</div>;
}
function PartitionEntry({partition, isLast}) {
function PartitionIndent({ children }) {
return (
<Indented depth={partition._treecutterDepth}>
{children}
</Indented>
);
}
return (
<tr className={classnames("partition", {last: isLast})}>
<td>
<PartitionIndent>
{partition.name}
</PartitionIndent>
</td>
<td>
<PartitionIndent>
{partition.size.toString()}
</PartitionIndent>
</td>
<td colSpan={5}>
<PartitionIndent>
{(partition.mounts.length > 0)
? partition.mounts.map((mount) => <MountEntry mount={mount} />)
: <span className="notMounted">(not mounted)</span>
}
</PartitionIndent>
</td>
</tr>
);
}
function DriveEntry({drive}) {
let hasPartitions = (drive.partitions.length > 0);
return (<>
<tr className={classnames({hasPartitions})}>
<td className={classnames("smart", drive.smartHealth)} rowSpan={1 + drive.partitions.length} />
<td>{drive.path}</td>
<td>{drive.size.toDisplay(2).toString()}</td>
<td>
{(drive.rpm != null)
? `${drive.rpm} RPM`
: null
}
</td>
<td>{drive.serialNumber}</td>
<td>{drive.model}</td>
<td>{drive.modelFamily}</td>
<td>{drive.firmwareVersion}</td>
</tr>
{drive.partitions.map((partition, i) => {
let isLast = (i === drive.partitions.length - 1);
return <PartitionEntry partition={partition} isLast={isLast} />;
})}
</>);
}
module.exports = {
query: gql`
query {
hardware {
drives {
path
smartHealth
size
rpm
serialNumber
model
modelFamily
firmwareVersion
blockDevice {
name
}
partitions: allBlockDevices {
_treecutterDepth
_treecutterSequenceNumber
name
size
mounts {
mountpoint
}
}
}
}
}
`,
template: function StorageDeviceList({data}) {
return (
<Layout title="Storage Devices">
<table className="drives">
<tr>
<th>SMART</th>
<th>Device</th>
<th>Total size</th>
<th>RPM</th>
<th>Serial number</th>
<th>Model</th>
<th>Family</th>
<th>Firmware version</th>
</tr>
{data.hardware.drives.map((drive) => <DriveEntry drive={drive} />)}
</table>
</Layout>
);
}
};
"use strict";
const Promise = require("bluebird");
const React = require("react");
const ReactDOMServer = require("react-dom/server");
const defaultValue = require("default-value");
const dotty = require("dotty");
const registerBabel = require("./register-babel");
const clearRequireCache = require("./clear-require-cache");
/* FILEBUG: Express does not copy symbol-keyed properties from app.locals, but it probably should? */
// let ExpressReact = Symbol("ExpressReact");
let ExpressReact = "__EXPRESS_REACT_SETTINGS";
let LocalsContext = React.createContext({});
function componentAtPath(moduleRoot, componentPath) {
if (componentPath == null) {
return moduleRoot;
} else {
return dotty.get(moduleRoot, componentPath);
}
}
function renderComponent(component, locals, doctype = "<!DOCTYPE html>") {
let tree = React.createElement(LocalsContext.Provider, {value: locals},
React.createElement(component, locals)
);
try {
/* TODO: Expose internals? Like koa-react */
return doctype + ReactDOMServer.renderToStaticMarkup(tree);
} catch (err) {
if (/Element type is invalid:/.test(err.message)) {
throw new Error(`Expected a React component, but got '${component}' - maybe you forgot to specify a componentPath?`);
} else {
throw err;
}
}
}
module.exports = {
Settings: ExpressReact,
LocalsContext: LocalsContext,
createEngine: function createEngine({ prepare } = {}) {
let babelRegistered = false;
return function asyncRender(filename, options, callback) {
return Promise.try(() => {
let viewPaths = options.settings.views;
if (!babelRegistered) {
registerBabel(viewPaths);
babelRegistered = true;
}
let {componentPath} = defaultValue(options[ExpressReact], {});
return Promise.try(() => {
let templateFile = require(filename);
let moduleRoot = defaultValue(templateFile.exports, templateFile);
return Promise.try(() => {
if (prepare != null) {
return prepare(moduleRoot, options);
}
}).then((result) => {
console.log("QUERY RESULT:", require("util").inspect(result, { colors: true, depth: null }));
let mergedOptions = Object.assign({}, options, result);
return renderComponent(componentAtPath(moduleRoot, componentPath), mergedOptions);
});
}).finally(() => {
if (options.settings.env === "development") {
clearRequireCache(viewPaths);
}
});
}).asCallback(callback);
};
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment