[go: nahoru, domu]

Skip to content

Commit

Permalink
feat: analytics site
Browse files Browse the repository at this point in the history
  • Loading branch information
drew-harris committed Jun 26, 2024
1 parent eaef023 commit 024de97
Show file tree
Hide file tree
Showing 60 changed files with 1,966 additions and 47 deletions.
2 changes: 2 additions & 0 deletions .env.analytics
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# .env.analytics
VITE_API_HOST=http://localhost:8090/api
35 changes: 35 additions & 0 deletions .github/workflows/analytics-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: analytics test suite

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true

on:
pull_request:
paths:
- 'analytics/**'
- 'shared/**'

jobs:
build-test:
runs-on: blacksmith-2vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: yarn --cwd analytics-site
- name: Running lint
run: yarn --cwd analytics-site build
eslint:
runs-on: blacksmith-2vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: yarn --cwd analytics-site
- name: Running lint
run: yarn --cwd analytics-site lint:CI
- name: Annotate Code Linting Results
uses: ataylorme/eslint-annotate-action@1.0.4
if: always()
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
report-json: './analytics-site/eslint_report.json'
39 changes: 39 additions & 0 deletions analytics-site/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"env": {
"browser": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/strict",
"plugin:solid/typescript",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": [
"./tsconfig.json"
]
},
"plugins": [
"@typescript-eslint",
"solid"
],
"rules": {
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
},
"overrides": [],
"ignorePatterns": [
"node_modules",
"dist",
"tailwind.config.cjs",
"prettier.config.cjs",
"postcss.config.cjs"
]
}
24 changes: 24 additions & 0 deletions analytics-site/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
3 changes: 3 additions & 0 deletions analytics-site/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignore artifacts:
build
coverage
44 changes: 44 additions & 0 deletions analytics-site/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM node:18 as build

WORKDIR /app

COPY package*.json ./

COPY . .

RUN yarn install
RUN yarn run build --filter analytics-site

FROM nginx:1.25.4-alpine-slim

WORKDIR /usr/share/nginx/html

COPY --from=build /app/analytics-site/dist /usr/share/nginx/html

COPY <<'EOF' /etc/nginx/conf.d/default.conf
server {
listen 80;

root /usr/share/nginx/html;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}
}
EOF

COPY <<'EOF' /docker-entrypoint.d/01-insert-window-variable.sh
#!/bin/sh

set -eu

cp /usr/share/nginx/html/index.html /usr/share/nginx/html/index.html.template
envsubst < /usr/share/nginx/html/index.html.template > /usr/share/nginx/html/index.html
rm /usr/share/nginx/html/index.html.template

EOF

RUN chmod +x /docker-entrypoint.d/01-insert-window-variable.sh

EXPOSE 80
25 changes: 25 additions & 0 deletions analytics-site/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!doctype html>
<html lang="en">
<head>
<script defer data-domain="dashboard.trieve.ai" src="https://plausible.trieve.ai/js/script.js"></script>
<meta charset="UTF-8" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Maven+Pro:wght@400..900&amp;display=swap" rel="stylesheet">
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.trieve.ai/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.trieve.ai/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="https://cdn.trieve.ai/favicon-16x16.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Trieve">
<meta property="og:site_name" content="advanced relevance semantic search and RAG API">
<meta property="og:url" content="https://search.trieve.ai">
<meta property="og:description" content="Build better, faster, and more relevant search and RAG with our open source API. Date recency biasing, re-ranker models, dense vector search, sub-sentence highlighting, and more all on one endpoint that you can host yourself." >
<meta property="og:type" content="">
<meta property="og:image" content="https://cdn.trieve.ai/trieve-og.png">
<title>Trieve Analytics</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
46 changes: 46 additions & 0 deletions analytics-site/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "analytics-site",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --port 5176",
"build": "tsc -b && vite build",
"preview": "vite preview",
"lint": "prettier --write \"**/*.{js,jsx,ts,tsx,md,mdx,}\" && eslint --fix \"src/**/*.{js,ts,jsx,tsx,astro}\"",
"lint:only": "eslint --fix \"src/**/*.{js,ts,jsx,tsx,}\"",
"lint:CI": "eslint --fix --output-file eslint_report.json --format json \"src/**/*.{js,ts,jsx,tsx,}\""
},
"dependencies": {
"@solidjs/router": "^0.13.6",
"@tanstack/solid-query": "^5.48.0",
"@types/matter-js": "^0.19.6",
"chart.js": "^4.4.3",
"date-fns": "^3.6.0",
"matter-js": "^0.20.0",
"shared": "*",
"solid-js": "^1.8.17",
"tailwind-gradient-mask-image": "^1.2.0",
"tailwind-scrollbar": "^3.1.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "7.14.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.13.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-semistandard": "^17.0.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.0.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-solid": "0.14.1",
"postcss": "^8.4.38",
"prettier-plugin-tailwindcss": "^0.5.11",
"tailwindcss": "^3.4.4",
"typescript": "^5.2.2",
"vite": "^5.3.1",
"vite-plugin-solid": "^2.10.2"
}
}
6 changes: 6 additions & 0 deletions analytics-site/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
6 changes: 6 additions & 0 deletions analytics-site/prettier.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: [import("prettier-plugin-tailwindcss")],
overrides: [],
tabWidth: 2,
trailingComma: "all",
};
48 changes: 48 additions & 0 deletions analytics-site/src/api/analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { AnalyticsParams, LatencyDatapoint, RpsDatapoint } from "shared/types";
import { apiHost } from "../utils/apiHost";
import { transformParams } from "../utils/formatDate";

export const getLatency = async (
filters: AnalyticsParams,
datasetId: string,
): Promise<LatencyDatapoint[]> => {
const response = await fetch(`${apiHost}/analytics/${datasetId}/latency`, {
credentials: "include",
method: "POST",
body: JSON.stringify(transformParams(filters)),
headers: {
"TR-Dataset": datasetId,
"Content-Type": "application/json",
},
});

if (!response.ok) {
throw new Error(`Failed to fetch trends bubbles: ${response.statusText}`);
}

const data = (await response.json()) as unknown as LatencyDatapoint[];
return data;
};

export const getRps = async (
filters: AnalyticsParams,
datasetId: string,
): Promise<RpsDatapoint[]> => {
const response = await fetch(`${apiHost}/analytics/${datasetId}/rps`, {
credentials: "include",
method: "POST",
body: JSON.stringify(transformParams(filters)),
headers: {
"TR-Dataset": datasetId,
"Content-Type": "application/json",
},
});

if (!response.ok) {
throw new Error(`Failed to fetch trends bubbles: ${response.statusText}`);
}

const data = (await response.json()) as unknown as RpsDatapoint[];
console.log(data);
return data;
};
21 changes: 21 additions & 0 deletions analytics-site/src/api/trends.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { SearchClusterTopics } from "shared/types";
import { apiHost } from "../utils/apiHost";

export const getTrendsBubbles = async (
datasetId: string,
): Promise<SearchClusterTopics[]> => {
const response = await fetch(`${apiHost}/analytics/${datasetId}/topics`, {
credentials: "include",
headers: {
"TR-Dataset": datasetId,
"Content-Type": "application/json",
},
});

if (!response.ok) {
throw new Error(`Failed to fetch trends bubbles: ${response.statusText}`);
}

const data = (await response.json()) as unknown as SearchClusterTopics[];
return data;
};
75 changes: 75 additions & 0 deletions analytics-site/src/components/FilterBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { AnalyticsFilter, AnalyticsParams } from "shared/types";
import { Select } from "./shared/Select";

Check failure on line 2 in analytics-site/src/components/FilterBar.tsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

analytics-site/src/components/FilterBar.tsx#L2

[@typescript-eslint/no-unused-vars] 'Select' is defined but never used.
import { SetStoreFunction } from "solid-js/store";
import { For } from "solid-js";

const ALL_SEARCH_METHODS: AnalyticsFilter["search_method"][] = [
"fulltext",
"hybrid",
"semantic",
];

const ALL_SEARCH_TYPES: AnalyticsFilter["search_type"][] = [
"search",
"search_over_groups",
"search_within_groups",
"autocomplete",
];

interface FilterBarProps {
filters: AnalyticsParams;
setFilters: SetStoreFunction<AnalyticsParams>;
}

export const FilterBar = (props: FilterBarProps) => {
return (
<div class="flex justify-between border-b border-neutral-300 bg-neutral-100 px-3 py-2">
<div class="flex gap-2">
<select
value={props.filters.filter.search_method}
onChange={(e) =>
props.setFilters("filter", {
...props.filters.filter,
search_method: e.currentTarget
.value as AnalyticsFilter["search_method"],
})
}
>
<For each={ALL_SEARCH_METHODS}>
{(method) => <option value={method}>{method}</option>}
</For>
</select>

<select
value={props.filters.filter.search_type}
onChange={(e) =>
props.setFilters("filter", {
...props.filters.filter,
search_type: e.currentTarget
.value as AnalyticsFilter["search_type"],
})
}
>
<For each={ALL_SEARCH_TYPES}>
{(type) => <option value={type}>{type}</option>}
</For>
</select>
</div>

<select
value={props.filters.granularity}
onChange={(e) =>
props.setFilters(
"granularity",
e.currentTarget.value as AnalyticsParams["granularity"],
)
}
>
<option value="second">Second</option>
<option value="minute">Minute</option>
<option value="hour">Hour</option>
<option value="day">Day</option>
</select>
</div>
);
};
Loading

0 comments on commit 024de97

Please sign in to comment.