Skip to content

Commit

Permalink
Created the status page, showing basic information of when was the la…
Browse files Browse the repository at this point in the history
…st time the events were ingested
  • Loading branch information
Marc-Antoine Hinse committed Nov 13, 2024
1 parent 3de70fe commit 8f1a1f6
Show file tree
Hide file tree
Showing 23 changed files with 991 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/flare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"devDependencies": {
"@babel/core": "^7.2.0",
"@splunk/configuration-screen": "^0.0.1",
"@splunk/status-screen": "^0.0.1",
"@splunk/babel-preset": "^4.0.0",
"@splunk/eslint-config": "^4.0.0",
"@splunk/react-page": "^7.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<html class="no-js" lang="">

<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>
Status
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
</head>

<body>
<script src="${make_url('/config?autoload=1')}" crossorigin="use-credentials"></script>
<script src="${make_url('/static/js/i18n.js')}"></script>
<script src="${make_url('/i18ncatalog?autoload=1')}"></script>
<script>
__splunkd_partials__ = ${json_decode(splunkd)};
</script>

<%
page_path = "/static/app/flare/pages/" + page + ".js"
%>

<script src="${make_url(page_path)}"></script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<nav search_view="search" color="#272735">
<view name="search" default='true' />
<view name="configuration" />
<view name="status" />
<a href="https://docs.flare.io/splunk-app-integration" target="_blank">Documentation</a>
<a href="https://app.flare.io/" target="_blank">Flare Platform</a>
</nav>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<view template="flare:/templates/status.html" type="html">
<label>Status</label>
</view>
17 changes: 17 additions & 0 deletions packages/flare/src/main/webapp/pages/status/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

import layout from '@splunk/react-page';
import StatusScreen from '@splunk/status-screen';
import { getUserTheme } from '@splunk/splunk-utils/themes';

getUserTheme()
.then((theme) => {
layout(<StatusScreen theme={theme} />, {
theme,
});
})
.catch((e) => {
const errorEl = document.createElement('span');
errorEl.innerHTML = e;
document.body.appendChild(errorEl);
});
3 changes: 3 additions & 0 deletions packages/status-screen/.babelrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ['@splunk/babel-preset'],
};
1 change: 1 addition & 0 deletions packages/status-screen/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/vendor/**
22 changes: 22 additions & 0 deletions packages/status-screen/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: '@splunk/eslint-config/browser-prettier',
rules: {
'react/jsx-filename-extension': [2, { 'extensions': ['.js', '.jsx', '.ts', '.tsx'] }],
'no-restricted-syntax': 'off',
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['warn'],
'@typescript-eslint/no-unused-vars': ['warn'],
'no-unused-vars': ['warn'],
'camelcase': 'off',
'no-underscore-dangle': 'off',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
'react/jsx-no-target-blank': 'off',
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/no-static-element-interactions': 'off',
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/label-has-associated-control': 'off',
},
};
6 changes: 6 additions & 0 deletions packages/status-screen/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*.js
!/.babelrc.js
!/.eslintrc.js
!/jest.config.js
!/*.config.js
!/build.js
35 changes: 35 additions & 0 deletions packages/status-screen/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Source code
/src/

# Tools
/.babelrc*
.eslintrc.*
.eslintignore
/stylelint.config.js
.stylelintignore
/webpack.config.js

# Testing
/coverage_report/
/functional.settings.js
/functional.*.conf.js
/functional-temp
/splunktional.settings.js
/splunktional.*.conf.js
/splunktional-temp
/test-reports/
/karma.conf.js
/jest.config.js
/webpack.test.config.js
/*hooks.js
/test-app

# Misc
/docs.manifest.json
/docs
/docs.gen*
/.npmignore
npm-debug.log
yarn-error.log
/licenses.json
/*.tgz
37 changes: 37 additions & 0 deletions packages/status-screen/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable */

const shell = require('shelljs');
const OS = require('os').platform().toLocaleLowerCase();

const arg = process.argv[2];
const commands = ['build', 'link'];

if (!arg) {
shell.echo(
`No command received, please supply a command to run. \nCommands: ${commands.join(', ')}`
);
shell.exit(1);
}

if (!commands.includes(arg)) {
shell.echo(`Please supply one of the following command to run: ${commands.join(', ')}`);
shell.exit(1);
}

// prettier-ignore
const runCommands = {
win32: {
build: () => shell.exec('set NODE_ENV=production&&.\\node_modules\\.bin\\webpack --mode=production'),
},
nix: {
build: () => shell.exec('export NODE_ENV=production && ./node_modules/.bin/webpack --mode=production'),
},
};

try {
const isWindows = OS === 'win32' || OS === 'win64';
const os = isWindows ? 'win32' : 'nix';
runCommands[os][arg]();
} catch (error) {
shell.echo('Something went wrong');
}
62 changes: 62 additions & 0 deletions packages/status-screen/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "@splunk/status-screen",
"version": "0.0.1",
"license": "UNLICENSED",
"scripts": {
"build": "node build.js build",
"eslint": "eslint src --ext \".js,.tsx,.ts\"",
"eslint:fix": "eslint src --ext \".js,.tsx,.ts\" --fix",
"lint": "yarn run eslint && yarn run stylelint",
"lint:ci": "yarn run eslint:ci && yarn run stylelint",
"start": "webpack --watch",
"stylelint": "stylelint \"src/**/*.{js,jsx}\" --config stylelint.config.js"
},
"main": "StatusScreen.js",
"dependencies": {
"@splunk/react-ui": "^4.30.0",
"@splunk/themes": "^0.18.0"
},
"devDependencies": {
"@babel/core": "^7.2.0",
"@splunk/babel-preset": "^4.0.0",
"@splunk/eslint-config": "^4.0.0",
"@splunk/splunk-utils": "^3.0.1",
"@splunk/stylelint-config": "^4.0.0",
"@splunk/webpack-configs": "^7.0.2",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12",
"@typescript-eslint/eslint-plugin": "^4.0.0",
"@typescript-eslint/parser": "^4.0.0",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.3.0",
"css-loader": "^7.1.2",
"eslint": "^7.14.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^6.15.0",
"eslint-import-resolver-webpack": "^0.13.4",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"html-webpack-plugin": "^5.5.3",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-test-renderer": "^16.12.0",
"shelljs": "^0.8.5",
"style-loader": "^4.0.0",
"styled-components": "^5.3.10",
"stylelint": "^13.0.0",
"typescript": "^4.3.0",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^16.8",
"styled-components": "^5.3.10"
},
"engines": {
"node": ">=14"
}
}
55 changes: 55 additions & 0 deletions packages/status-screen/src/StatusScreen.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#container {
display: flex;
flex-direction: column;
width: 100%;
height: auto;
background-color: var(--bg-color);
color: var(--text-color);
text-align: center;
gap: 2rem;
}

.content {
display: flex;
flex-direction: column;
flex: content;
height: auto;
width: 800px;
align-self: center;
align-items: flex-start;
}

#experimental {
align-self: center;
text-align: left;
width: 800px;
font-style: italic;
margin-top: 2rem;
}

#status-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
flex: content;
}

.status-item {
text-align: start;
overflow-wrap: anywhere;
display: flex;
flex-direction: column;
gap: 0.125rem;
background-color: var(--secondary-bg-color);
border-radius: 10px;
padding: 1rem;
}

.status-item-name {
font-weight: bold;
color: var(--text-color);
}

.status-item-value {
color: var(--secondary-text-color);
}
83 changes: 83 additions & 0 deletions packages/status-screen/src/StatusScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { useEffect, FC, useState } from 'react';
import './global.css';
import './StatusScreen.css';
import { findCollection, retrieveTenantId } from './utils/setupConfiguration';
import { CollectionKeys, SplunkCollectionItem } from './models/splunk';


const StatusScreen: FC<{ theme: string }> = ({ theme }) => {
const [statusItems, setStatusItem] = useState<SplunkCollectionItem[]>([]);

useEffect(() => {
retrieveTenantId().then((id) => {
findCollection().then((items: SplunkCollectionItem[]) => {
setStatusItem(items.filter((p) => {
if (p.key.startsWith(CollectionKeys.NEXT_TOKEN)) {
const parsedTenantId = parseInt(p.key.substring(CollectionKeys.NEXT_TOKEN.length));
return parsedTenantId == id;
}
return true;
}).reverse());
});
});
}, []);

useEffect(() => {
const container = document.getElementById('container') as HTMLDivElement;
const parentContainer = container.parentElement?.parentElement ?? undefined;
if (parentContainer) {
parentContainer.className = `parent-container ${theme === 'dark' ? 'dark' : ''}`;
}
}, [theme]);

function getCollectionName(key: string) : string {
if (key.startsWith(CollectionKeys.NEXT_TOKEN)) {
const parsedTenantId = parseInt(key.substring(CollectionKeys.NEXT_TOKEN.length));
return `Next token for Tenant ID ${parsedTenantId}`;
}

if (key === CollectionKeys.START_DATE) {
return "Date of the first time events were ingested"
}

if (key === CollectionKeys.LAST_FETCHED) {
return "Last moment the events were ingested"
}

return "Unknown Status Item";
}

function formatValue(item: SplunkCollectionItem) : string {
if (item.key === CollectionKeys.START_DATE || item.key === CollectionKeys.LAST_FETCHED) {
const date = new Date(item.value);
return date.toLocaleString();
}

return item.value;
}

return (
<div id="container" className={theme === 'dark' ? 'dark' : ''}>
<div id="experimental">This is an experimental release</div>
<div className="content">
<h2>Status</h2>
<div id="status-list">
{statusItems.map((item) => {
return (
<span className="status-item" key={item.key}>
<span className="status-item-name">
{getCollectionName(item.key)}
</span>
<span className='status-item-value'>
{formatValue(item)}
</span>
</span>
);
})}
</div>
</div>
</div>
);
};

export default StatusScreen;
Loading

0 comments on commit 8f1a1f6

Please sign in to comment.