Skip to content
Closed
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
340 changes: 177 additions & 163 deletions frontend/bun.lock

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions frontend/eslint.config.js → frontend/eslint.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import eslintJs from "@eslint/js";
import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss";
import eslintPluginJsxA11y from "eslint-plugin-jsx-a11y";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import eslintPluginReactHooks from "eslint-plugin-react-hooks";
import js from "@eslint/js";
import tailwind from "eslint-plugin-better-tailwindcss";
import a11y from "eslint-plugin-jsx-a11y";
import prettier from "eslint-plugin-prettier/recommended";
import reactHooks from "eslint-plugin-react-hooks";
import { defineConfig, globalIgnores } from "eslint/config";
import globals from "globals";
import typescriptEslint from "typescript-eslint";
import tslint from "typescript-eslint";

export default defineConfig([
globalIgnores(["dist", "public"]),
eslintJs.configs.recommended,
typescriptEslint.configs.recommended,
eslintPluginPrettierRecommended,
eslintPluginReactHooks.configs.flat.recommended,
eslintPluginJsxA11y.flatConfigs.recommended,
js.configs.recommended,
tslint.configs.recommended,
prettier,
reactHooks.configs.flat.recommended,
a11y.flatConfigs.recommended,
{
plugins: {
"better-tailwindcss": eslintPluginBetterTailwindcss,
"better-tailwindcss": tailwind,
},
languageOptions: {
ecmaVersion: 2020,
Expand Down Expand Up @@ -45,7 +45,7 @@ export default defineConfig([

/** FORMATTING */
"prettier/prettier": "warn",
...eslintPluginBetterTailwindcss.configs["recommended-warn"].rules,
...tailwind.configs["recommended-warn"].rules,
/** https://github.com/schoero/eslint-plugin-better-tailwindcss/issues/302 */
"better-tailwindcss/enforce-consistent-line-wrapping": [
"warn",
Expand Down
66 changes: 33 additions & 33 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,56 +13,56 @@
"clean": "rm -rf node_modules dist bun.lock && bun pm cache rm"
},
"dependencies": {
"@base-ui/react": "^1.1.0",
"@base-ui/react": "^1.4.1",
"@fontsource-variable/outfit": "^5.2.8",
"@fontsource-variable/sometype-mono": "^5.2.7",
"@reactuses/core": "^6.1.11",
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-query": "^5.90.19",
"@reactuses/core": "^6.3.1",
"@tailwindcss/vite": "^4.3.0",
"@tanstack/react-query": "^5.100.10",
"@tanstack/react-table": "^8.21.3",
"clsx": "^2.1.1",
"gsap": "^3.14.2",
"highlight.js": "^11.11.1",
"javascript-time-ago": "^2.5.12",
"jotai": "^2.16.2",
"lodash": "^4.17.21",
"lucide-react": "^0.562.0",
"react": "^19.2.3",
"gsap": "^3.15.0",
"javascript-time-ago": "^2.6.4",
"jotai": "^2.20.0",
"lodash": "^4.18.1",
"lucide-react": "^1.16.0",
"react": "^19.2.6",
"react-children-utilities": "^2.10.0",
"react-dom": "^19.2.3",
"react-dom": "^19.2.6",
"react-ga4": "^3.0.1",
"react-highlight-words": "^0.21.0",
"react-router": "^7.12.0",
"react-time-ago": "^7.3.5",
"react-router": "^7.15.1",
"react-time-ago": "^7.4.4",
"seedrandom": "^3.0.5",
"tailwindcss": "^4.1.18",
"zod": "^4.3.6"
"tailwindcss": "^4.3.0",
"zod": "^4.4.3"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
"@types/lodash": "^4.17.23",
"@types/react": "^19.2.9",
"@eslint/js": "^10.0.1",
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
"@types/eslint-plugin-jsx-a11y": "^6.10.1",
"@types/lodash": "^4.17.24",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/react-highlight-words": "^0.20.1",
"@types/seedrandom": "^3.0.8",
"@vitejs/plugin-react": "^5.1.2",
"eslint": "^9.39.2",
"@vitejs/plugin-react": "^6.0.1",
"eslint": "^10.3.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-better-tailwindcss": "^4.0.1",
"eslint-plugin-better-tailwindcss": "^4.5.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^17.0.0",
"msw": "^2.12.7",
"prettier": "^3.8.0",
"eslint-plugin-react-hooks": "^7.1.1",
"globals": "^17.6.0",
"msw": "^2.14.6",
"prettier": "^3.8.3",
"prettier-plugin-jsdoc": "^1.8.0",
"prettier-plugin-tailwindcss": "^0.7.2",
"type-fest": "^5.4.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.1",
"vite": "^7.3.1",
"vite-plugin-svgr": "^4.5.0"
"prettier-plugin-tailwindcss": "^0.8.0",
"type-fest": "^5.6.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.3",
"vite": "^8.0.13",
"vite-plugin-svgr": "^5.2.0"
},
"msw": {
"workerDirectory": [
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/mockServiceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* - Please do NOT modify this file.
*/

const PACKAGE_VERSION = '2.13.6'
const PACKAGE_VERSION = '2.14.6'
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set()
Expand Down
27 changes: 2 additions & 25 deletions frontend/src/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type { Cart, Feedback } from "@/api/types";
import type { LocalCart, ShareCart } from "@/state/cart";
import type { Feedback } from "@/api/types";
import type { ShareCart } from "@/state/cart";
import analytics from "react-ga4";
import z from "zod";
import { api, request } from "@/api";
import { cart, ontologies, samples, studies } from "@/api/types";
import { dbLink, getDb } from "@/components/Database";
import { downloadBlob } from "@/util/download";

/** type to color map */
Expand Down Expand Up @@ -142,25 +141,3 @@ export const downloadCart = async (
if (type === "json") downloadBlob(data, filename, "json");
analytics.event("download_cart", { ids, filename, type });
};

/** get download bash script */
export const getCartScript = (cart: Cart | LocalCart, database: string) =>
[
`#!/bin/bash`,
`# Meta2Onto data cart download script`,
`# Generated: ${new Date().toISOString()}`,
"id" in cart ? `# ID: ${cart.id}` : "",
"name" in cart ? `# Name: ${cart.name}` : "",
`# Studies: ${cart.studies.length}`,
...cart.studies.map(({ id }) => [
`# Download ${id} from ${database}`,
`wget "${dbLink(getDb(database).link, id)}" -O ${id}_${database}.zip`,
]),
`# Extract`,
`for file in *.zip; do unzip "$file"; done`,
`echo "Download complete"`,
]
.flat()
.map((line) => line.trimEnd())
.filter(Boolean)
.join("\n");
37 changes: 37 additions & 0 deletions frontend/src/api/refine.bio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import analytics from "react-ga4";
import * as z from "zod";
import { request } from "@/api";

const api = `https://api.refine.bio/v1`;

export const dataset = z.object({
id: z.string().optional(),
data: z.unknown().optional(),
success: z.boolean().optional(),
failure_reason: z.string().optional(),
});

/** export cart of studies to refine.bio dataset */
export const makeDataset = async (ids: string[], email = "") => {
const url = new URL(`${api}/dataset/`);
const options = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: {
data: Object.fromEntries(ids.map((id) => [id, ["ALL"]])),
aggregate_by: "ALL",
scale_by: "NONE",
email_address: email,
email_ccdl_ok: !!email,
notify_me: !!email,
start: true,
quantile_normalize: true,
quant_sf_only: true,
svd_algorithm: "NONE",
},
} as const;
const data = await request(url, dataset, options);
analytics.event("refine.bio_make_dataset", { ids, data });
if (!data.success) throw Error(data.failure_reason ?? "Unknown error");
return data;
};
2 changes: 1 addition & 1 deletion frontend/src/components/Textbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function Textbox({
);
return multi ? (
<textarea
className={clsx("min-h-[calc(3lh+--spacing(4))]", _class)}
className={clsx("min-h-[calc(3lh+(--spacing(4)))]", _class)}
onChange={(event) => onChange?.(event.currentTarget.value)}
{...(props as ComponentPropsWithRef<"textarea">)}
/>
Expand Down
Loading