Skip to content
This repository has been archived by the owner on Oct 27, 2024. It is now read-only.

Move log app #2

Merged
merged 30 commits into from
Oct 5, 2023
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
97af51c
chore: switch to Github workers
devpanther Aug 19, 2023
595bdf3
chore: deploy before set env
devpanther Aug 19, 2023
5a77e4d
chore: setting up websocket
devpanther Aug 20, 2023
b66c50d
chore: properly type the socket class
devpanther Aug 21, 2023
d38c5a0
chore: websocket works now
devpanther Aug 21, 2023
84bed17
chore: clear toml file
devpanther Aug 21, 2023
d882ffd
chore: switch back to pages for html support
devpanther Aug 21, 2023
c9ffe0b
chore: setting up logger page
devpanther Aug 22, 2023
8ed7dc1
chore: separating ts config
devpanther Aug 22, 2023
835e401
chore: ignore all js files in local directory
devpanther Aug 22, 2023
7375fa2
chore: logger setup done
devpanther Aug 22, 2023
1de015e
chore: use esbuild for frontend scripts
devpanther Aug 22, 2023
8141e4f
chore: json on modal
devpanther Aug 22, 2023
5449f71
chore: overflow long text
devpanther Aug 22, 2023
55b5f38
chore: switch to frontend supabase
devpanther Aug 22, 2023
2abe341
chore: table styling
devpanther Aug 22, 2023
1ac6d9d
chore: scroll last log into view
devpanther Aug 22, 2023
bb33e44
chore: keys to constant
devpanther Aug 22, 2023
1948ba5
chore: scroll overflowing text
devpanther Aug 22, 2023
49d0dc6
Merge remote-tracking branch 'bot/move-log-app' into development
gitcoindev Oct 4, 2023
08cf356
chore: rename from generic to ubiquibot-logging
gitcoindev Oct 4, 2023
4d1764d
chore: merge ts-template dev dependencies
gitcoindev Oct 4, 2023
cdf022d
chore: clean up dependencies, set the same versions
gitcoindev Oct 4, 2023
6e7e329
chore: upgrade packages to latest versions
gitcoindev Oct 4, 2023
e6d80eb
chore: add scripts folder and index.ts to project
gitcoindev Oct 4, 2023
3208dde
chore: yarn prettier the code
gitcoindev Oct 4, 2023
9cb1930
chore: eslint: remove unused channel variable
gitcoindev Oct 4, 2023
c255723
chore: eslint: await promise
gitcoindev Oct 4, 2023
51505c6
chore: update app name in README
gitcoindev Oct 4, 2023
0ab3135
Update package.json
0x4007 Oct 5, 2023
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
4 changes: 2 additions & 2 deletions .commitlintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"extends": ["@commitlint/config-conventional"]
}
"extends": ["@commitlint/config-conventional"]
}
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
# `@ubiquity/ts-template`

This template repository includes support for the following:

- TypeScript
- Environment Variables
- Conventional Commits
- Automatic publishing of pull requests to Cloudflare Pages
# Ubiquibot-logging App
9 changes: 9 additions & 0 deletions _worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Env } from "./types/global";

export default {
async fetch(request: Request, env: Env) {
// Otherwise, serve the static assets.
// Without this, the Worker will error and no assets will be served.
return env.ASSETS.fetch(request);
},
};
44 changes: 44 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Log Viewer</title>
<link rel="stylesheet" href="./styles/index.css" />
</head>

<body>
<div class="log-container">
<select id="filter">
<option value="all">All</option>
<option value="error">Error</option>
<option value="warn">Warning</option>
<option value="info">Info</option>
<option value="verbose">Verbose</option>
<option value="debug">Debug</option>
</select>
<button id="clear">Clear</button>
</div>
<table id="log-table">
<thead>
<tr>
<th>Message</th>
<th>Level</th>
<th>Timestamp</th>
<th>Comment URL</th>
</tr>
</thead>
<tbody id="log-body"></tbody>
</table>
<div id="json-modal" class="modal">
<div class="modal-content">
<span id="close-modal" class="close">&times;</span>
<pre id="json-content" class="json-content"></pre>
</div>
</div>
<script>
var exports = {};
</script>
<script type="application/javascript" src="./scripts/index.js"></script>
</body>
</html>
29 changes: 14 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
{
"name": "ts-template",
"name": "ubiquibot-logging",
"version": "1.0.0",
"description": "Template repository with TypeScript support.",
"description": "UbiquiBot Public Log Viewer",
"main": "index.ts",
"author": "Ubiquity DAO",
"license": "MIT",
"engines": {
"node": ">=v20.3.0"
"node": ">=v20.3.2"
},
"scripts": {
"format": "run-s format:prettier format:lint",
"format:lint": "eslint --fix .",
"format:prettier": "prettier --write ."
},
"keywords": [
"typescript",
"template",
"dao",
"ubiquity",
"open-source"
],
"dependencies": {
"dotenv": "^16.3.1"
},
"devDependencies": {
"@cloudflare/workers-types": "^3.2.0",
"@commitlint/cli": "^17.6.6",
"@commitlint/config-conventional": "^17.6.6",
"@supabase/supabase-js": "^2.32.0",
"@types/node": "^20.3.2",
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"esbuild": "^0.19.2",
"eslint": "^8.43.0",
"husky": "^8.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.8",
"tsx": "^3.12.7",
"typescript": "^5.1.0"
}
}
},
"keywords": [
"typescript",
"dao",
"ubiquity",
"open-source"
]
}
3 changes: 3 additions & 0 deletions scripts/constants/index.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume these are public anon keys.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const SUPABASE_URL = "https://qzfjblxdroqrmlheoajw.supabase.co";
export const SUPABASE_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InF6ZmpibHhkcm9xcm1saGVvYWp3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2ODA4NTMwMzMsImV4cCI6MTk5NjQyOTAzM30.BM_qkpX-egNdiMc0PDO_34bIaXHB7ewnr2k4U2hGFMM";
19 changes: 19 additions & 0 deletions scripts/esbuild-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import esbuild from "esbuild";
const typescriptEntries = ["scripts/helpers/utils.ts", "scripts/index.ts", "scripts/constants/index.ts"];
export const entries = [...typescriptEntries];

export const esBuildContext = {
sourcemap: false,
entryPoints: entries,
bundle: true,
minify: false,
loader: {
".png": "dataurl",
".woff": "dataurl",
".woff2": "dataurl",
".eot": "dataurl",
".ttf": "dataurl",
".svg": "dataurl",
},
outdir: "scripts",
} as esbuild.BuildOptions;
3 changes: 3 additions & 0 deletions scripts/esbuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import esbuild from "esbuild";
import { esBuildContext } from "./esbuild-config";
await esbuild.build(esBuildContext);
66 changes: 66 additions & 0 deletions scripts/helpers/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
export enum Level {
ERROR = "error",
WARN = "warn",
INFO = "info",
HTTP = "http",
VERBOSE = "verbose",
DEBUG = "debug",
SILLY = "silly",
}

export const createGitHubCommentURL = (orgName: string, repoName: string, issueNumber: number, commentId: number) => {
return `https://github.com/${orgName}/${repoName}/issues/${issueNumber}#issuecomment-${commentId}`;
};

export const isValidJson = (jsonString) => {
try {
JSON.parse(jsonString);
return true;
} catch (error) {
return false;
}
};

export const generateRandomId = (length) => {
return [...Array(length)].map(() => Math.random().toString(36)[2]).join("");
};

export const containsValidJson = (message: string): [boolean, string, string] => {
const jsonMatches = message.match(/\{.*\}/g); // Find JSON-like substrings
if (!jsonMatches) {
return [false, "", ""];
}

for (const match of jsonMatches) {
if (isValidJson(match)) {
const braceIndex = message.indexOf("{");
if (braceIndex !== -1) {
return [true, match, message.substring(0, braceIndex)];
}
return [true, match, ""];
}
}

return [false, "", ""];
};

export const getLevelString = (level: number) => {
switch (level) {
case 0:
return Level.ERROR;
case 1:
return Level.WARN;
case 2:
return Level.INFO;
case 3:
return Level.HTTP;
case 4:
return Level.VERBOSE;
case 5:
return Level.DEBUG;
case 6:
return Level.SILLY;
default:
return -1; // Invalid level
}
};
99 changes: 99 additions & 0 deletions scripts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { containsValidJson, createGitHubCommentURL, generateRandomId, getLevelString } from "./helpers/utils";
import { Logs } from "./types/log";
import { createClient } from "@supabase/supabase-js";
import { SUPABASE_URL, SUPABASE_KEY } from "./constants/index";

const filterSelect = document.getElementById("filter") as unknown as HTMLSelectElement;
const clearButton = document.getElementById("clear") as HTMLButtonElement;
const logBody = document.getElementById("log-body") as HTMLDivElement;

const jsonModal = document.getElementById("json-modal") as HTMLDivElement;
const closeModalButton = document.getElementById("close-modal") as HTMLButtonElement;
const jsonContent = document.getElementById("json-content") as HTMLDivElement;

const openJsonModal = (validJson) => {
jsonContent.textContent = validJson;

jsonModal.style.display = "flex";
};

const updateLogTable = () => {
const selectedFilter = filterSelect.value;
const filteredLogs = selectedFilter === "all" ? logs : logs.filter((log) => getLevelString(log.level) === selectedFilter);

logBody.innerHTML = "";
filteredLogs.forEach((log) => {
const classId = generateRandomId(10);
const commentUrl = createGitHubCommentURL(log.org_name, log.repo_name, log.issue_number, log.comment_id);
const row = document.createElement("tr");
const [validJson, match, beforeText] = containsValidJson(log.log_message);
row.innerHTML = `
${
validJson
? `<td class="log-cell">${beforeText} - <button id="button_${classId}">Show JSON</button></td>`
: `<td class="log-cell">${log.log_message}</td>`
}
<td>${getLevelString(log.level)}</td>
<td>${log.timestamp}</td>
<td><a href="${commentUrl}">Comment - ${log.comment_id}</a></td>
`;
logBody.appendChild(row);
const logCell = document.getElementsByClassName("log-cell");
if (validJson) {
// show modal button for valid json row
const showMoreButton = document.getElementById(`button_${classId}`) as HTMLButtonElement;
showMoreButton.addEventListener("click", () => {
if (validJson) {
openJsonModal(JSON.stringify(JSON.parse(match), null, 2)); // properly formatted json
}
});
}
// scroll to last added data
logCell[logCell.length - 1].scrollIntoView();
});
};

let logs: Logs[] = [];

const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY);

supabaseClient
.channel("table-db-changes")
.on(
"postgres_changes",
{
event: "INSERT",
schema: "public",
table: "logs",
},
(payload) => handlePayload(payload)
)
.subscribe();

const handlePayload = (logEntry) => {
if (logEntry?.eventType !== "INSERT") return;
logs.push(logEntry.new);
updateLogTable();
};

filterSelect.addEventListener("change", () => {
updateLogTable();
});

clearButton.addEventListener("click", () => {
logs = [];
updateLogTable();
});

closeModalButton.addEventListener("click", () => {
jsonModal.style.display = "none";
});

window.addEventListener("click", (event) => {
if (event.target === jsonModal) {
jsonModal.style.display = "none";
}
});

// Initial update
updateLogTable();
15 changes: 15 additions & 0 deletions scripts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"useDefineForClassFields": true,
"allowJs": false,
"esModuleInterop": true,
"module": "CommonJS",
"allowSyntheticDefaultImports": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"lib": ["esnext", "dom", "dom.iterable"] /* Specify a set of bundled library declaration files that describe the target runtime environment. */
},
"include": ["./helpers", "./constants", "./index.ts"],
"exclude": ["./esbuild.ts", "./esbuild-config.ts"]
}
9 changes: 9 additions & 0 deletions scripts/types/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type Logs = {
timestamp: string;
log_message: string;
level: number;
repo_name: string;
org_name: string;
comment_id: number;
issue_number: number;
};
Loading