From f2bea2d46b46ff2f235f2471a9e502d83fa70be2 Mon Sep 17 00:00:00 2001 From: Omar Ibrahim <18043@stemegypt.edu.eg> Date: Tue, 13 Jan 2026 13:31:31 -0600 Subject: [PATCH 01/21] ci(docs): add fully headless script mode --- .github/workflows/deploy-docs.yml | 10 +++-- apps/docs/package.json | 4 +- .../public/_index/extensions/view2.5d.txt | 24 ++++++++++++ apps/docs/scripts/.helpers | 17 +++++++- apps/docs/scripts/deploy.sh | 8 ++-- apps/docs/scripts/generate.sh | 39 +++++++++++-------- scripts/check-repo.sh | 7 ++++ scripts/initialize.sh | 1 + 8 files changed, 85 insertions(+), 25 deletions(-) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 615f84f3..cfcbffca 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -20,13 +20,17 @@ jobs: - name: Install dependencies shell: bash + env: + HELIO_SKIP_CHECKS: 1 + NEXT_TELEMETRY_DISABLED: 1 run: NEXT_TELEMETRY_DISABLED=1 yarn run init - name: Build and deploy working-directory: apps/docs shell: bash env: - PRINT_DEBUG: 1 + HELIO_HEADLESS: 1 + HELIO_SKIP_CHECKS: 1 + NEXT_TELEMETRY_DISABLED: 1 GITHUB_TOKEN: ${{ secrets.NETLOGO_HELIO_CI_TOKEN }} - run: | - yes | yarn run docs:deploy + run: yarn run docs:deploy diff --git a/apps/docs/package.json b/apps/docs/package.json index 49aef439..9fe3753d 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -8,8 +8,8 @@ }, "scripts": { "init": "nuxt prepare", - "docs:build": "NODE_OPTIONS=--max-old-space-size=8192 ./scripts/generate.sh", - "docs:deploy": "NODE_OPTIONS=--max-old-space-size=8192 bash ./scripts/deploy.sh", + "docs:build": "./scripts/generate.sh", + "docs:deploy": "bash ./scripts/deploy.sh", "docs:preview": "bash ./scripts/preview.sh", "docs:clean-up": "bash ./scripts/clean-up.sh", "docs:generate-manual": "bash ./scripts/generate-manual/run.sh", diff --git a/apps/docs/public/_index/extensions/view2.5d.txt b/apps/docs/public/_index/extensions/view2.5d.txt index e69de29b..7a88396c 100644 --- a/apps/docs/public/_index/extensions/view2.5d.txt +++ b/apps/docs/public/_index/extensions/view2.5d.txt @@ -0,0 +1,24 @@ +view2.5d:patch-view patch-view.html +view2.5d:decorate-patch-view decorate-patch-view.html +view2.5d:undecorate-patch-view undecorate-patch-view.html +view2.5d:turtle-view turtle-view.html +view2.5d:update-all-patch-views update-all-patch-views.html +view2.5d:update-patch-view update-patch-view.html +view2.5d:update-turtle-view update-turtle-view.html +view2.5d:get-z-scale get-z-scale.html +view2.5d:set-z-scale set-z-scale.html +view2.5d:set-turtle-stem-thickness set-turtle-stem-thickness.html +view2.5d:set-turtle-stem-color set-turtle-stem-color.html +view2.5d:show-links-xy-plane show-links-xy-plane.html +view2.5d:show-links-xyz show-links-xyz.html +view2.5d:get-observer-angles get-observer-angles.html +view2.5d:set-observer-angles set-observer-angles.html +view2.5d:get-observer-xy-focus get-observer-xy-focus.html +view2.5d:set-observer-xy-focus set-observer-xy-focus.html +view2.5d:get-observer-distance get-observer-distance.html +view2.5d:set-observer-distance set-observer-distance.html +view2.5d:remove-patch-view remove-patch-view.html +view2.5d:remove-turtle-view remove-turtle-view.html +view2.5d:remove-all-patch-views remove-all-patch-views.html +view2.5d:remove-all-turtle-views remove-all-turtle-views.html +view2.5d:count-windows count-windows.html \ No newline at end of file diff --git a/apps/docs/scripts/.helpers b/apps/docs/scripts/.helpers index 6554089e..d8e8e6c2 100644 --- a/apps/docs/scripts/.helpers +++ b/apps/docs/scripts/.helpers @@ -1,5 +1,11 @@ #!/bin/bash +HELIO_HEADLESS="${HELIO_HEADLESS:-0}" + +if [ "$HELIO_HEADLESS" = "1" ]; then + echo "๐Ÿ’ก Running in headless mode." +fi + function echo() { command echo "[$(date +'%H:%M')] $*" } @@ -47,7 +53,7 @@ function unroll() { } function confirmUnlessHeadless() { - if [ "$HEADLESS" != "true" ]; then + if [ "$HELIO_HEADLESS" != "1" ]; then read -p "โš ๏ธ $1 (y/n): " response if [ "$response" != "y" ]; then echo "๐Ÿ’ก Operation cancelled by user." @@ -55,3 +61,12 @@ function confirmUnlessHeadless() { fi fi } + +_read() { + if [ "$HELIO_HEADLESS" = "1" ]; then + echo $2 + else + read -p "$1" response + echo "$response" + fi +} diff --git a/apps/docs/scripts/deploy.sh b/apps/docs/scripts/deploy.sh index 52e68d0f..0854c86b 100755 --- a/apps/docs/scripts/deploy.sh +++ b/apps/docs/scripts/deploy.sh @@ -39,10 +39,11 @@ fi echo "=== Step 1: Build documentation site ===" if [ -d .build ]; then - read -p "โš ๏ธ Do you want to use the existing build? (y/n): " use_existing + use_existing=$(_read "โš ๏ธ Do you want to use the existing build? (y/n): " "y") if [ "$use_existing" != "y" ]; then echo "๐Ÿ’ก (Re)building documentation site..." yarn run docs:build + echo "๐Ÿ’ก Generating the PDF Manual" yarn run docs:generate-manual else echo "๐Ÿ’ก Using existing .build directory." @@ -50,13 +51,14 @@ if [ -d .build ]; then else echo "๐Ÿ’ก Building documentation site..." yarn run docs:build + echo "๐Ÿ’ก Generating the PDF Manual" yarn run docs:generate-manual fi echo "" echo "=== Step 2: Clone documentation repository ===" if [ "$(ls -A .repo)" ]; then - read -p "โš ๏ธ .repo directory already exists and is not empty. Do you want to use it? (y/n): " use_repo + use_repo=$(_read "โš ๏ธ .repo directory already exists and is not empty. Do you want to use it? (y/n): " "y") if [ "$use_repo" != "y" ]; then echo "๐Ÿ’ก Removing existing .repo directory..." rm -rf .repo @@ -106,7 +108,7 @@ fi echo "" echo "=== Step 5: Commit and push changes ===" -read -p "โš ๏ธ Are you sure you want to commit and push changes to the $BUILD_BRANCH branch? (y/n): " confirm_push +confirm_push=$(_read "โš ๏ธ Are you sure you want to commit and push changes to the $BUILD_BRANCH branch? (y/n): " "y") if [ "$confirm_push" != "y" ]; then echo "๐Ÿ’ก Deployment aborted by user." exit 0 diff --git a/apps/docs/scripts/generate.sh b/apps/docs/scripts/generate.sh index 13aae0c8..9256daf1 100755 --- a/apps/docs/scripts/generate.sh +++ b/apps/docs/scripts/generate.sh @@ -8,21 +8,22 @@ set -euo pipefail # Strict error handling echo "โš™๏ธ Starting generation of static files..." echo "๐Ÿ’ก You can check .stdout.log and .stderr.log for progress and errors." -processes_to_kill=(node yarn npm) -echo "โš ๏ธ This script will kill all ${processes_to_kill[*]} processes." -for process in "${processes_to_kill[@]}"; do - pgrep $process | xargs -r kill -9 >/dev/null 2>/dev/null || true -done -echo "โœ… Killed specified processes." - -if [ "${BUILD_LATEST:-false}" = "true" ]; then - echo "๐Ÿ’ก Building latest version in addition to ${PRODUCT_VERSION}" -else - echo "๐Ÿ’ก Building only version ${PRODUCT_VERSION}" +if [ "$HELIO_HEADLESS" != "1" ]; then + processes_to_kill=(node yarn npm) + echo "โš ๏ธ This script will kill all ${processes_to_kill[*]} processes." + for process in "${processes_to_kill[@]}"; do + pgrep $process | xargs -r kill -9 >/dev/null 2>/dev/null || true + done + echo "โœ… Killed specified processes." + + if [ "${BUILD_LATEST:-false}" = "true" ]; then + echo "๐Ÿ’ก Building latest version in addition to ${PRODUCT_VERSION}" + else + echo "๐Ÿ’ก Building only version ${PRODUCT_VERSION}" + fi fi TARGET_DIR="$(pwd)/.build" # Define target directory for generated files -PRINT_DEBUG="${PRINT_DEBUG:-0}" rm .stdout.log 2>/dev/null || true # Clear previous logs rm .stderr.log 2>/dev/null || true @@ -32,8 +33,14 @@ mkdir -p "$TARGET_DIR" echo "๐Ÿงน Emptied target directory: $TARGET_DIR" echo "๐Ÿ’ก Preparing Nuxt for generation..." -npx nuxi cleanup >> .stdout.log 2>> .stderr.log -BASE_PATH="/" yarn run nuxt:prepare >> .stdout.log 2>> .stderr.log +if [ "$HELIO_HEADLESS" -eq 1 ]; then + npx nuxi cleanup + BASE_PATH="/" yarn run nuxt:prepare +else + npx nuxi cleanup >> .stdout.log 2>> .stderr.log + BASE_PATH="/" yarn run nuxt:prepare >> .stdout.log 2>> .stderr.log +fi + echo "==== end of prepare step ====" >> .stdout.log echo "" >> .stdout.log echo "โœ… Nuxt prepared." @@ -42,7 +49,7 @@ if [ "$BUILD_LATEST" = "true" ]; then echo "๐Ÿ’ก Building no-prefix version" # 1) Generate for base path "/" - if [ "$PRINT_DEBUG" -eq 1 ]; then + if [ "$HELIO_HEADLESS" -eq 1 ]; then BASE_PATH="/" yarn run nuxt:generate else BASE_PATH="/" yarn run nuxt:generate >> .stdout.log 2>> .stderr.log @@ -61,7 +68,7 @@ fi echo "๐Ÿ’ก Building version ${PRODUCT_VERSION}" # 3) Generate for versioned path "//" -if [ "$PRINT_DEBUG" -eq 1 ]; then +if [ "$HELIO_HEADLESS" -eq 1 ]; then BASE_PATH="/$PRODUCT_VERSION/" yarn run nuxt:generate else BASE_PATH="/$PRODUCT_VERSION/" yarn run nuxt:generate >> .stdout.log 2>> .stderr.log diff --git a/scripts/check-repo.sh b/scripts/check-repo.sh index 9df822bd..f61c9128 100644 --- a/scripts/check-repo.sh +++ b/scripts/check-repo.sh @@ -1,6 +1,13 @@ #!/bin/sh set -e +HELIO_SKIP_CHECKS=${HELIO_SKIP_CHECKS:-0} + +if [ "$HELIO_SKIP_CHECKS" = "1" ]; then + echo "Skipping repository checks (HELIO_SKIP_CHECKS=1)" + exit 0 +fi + yarn turbo run build yarn turbo run lint yarn turbo run check-types diff --git a/scripts/initialize.sh b/scripts/initialize.sh index 6caf16d4..2966890e 100644 --- a/scripts/initialize.sh +++ b/scripts/initialize.sh @@ -12,6 +12,7 @@ set -e NUXT_TELEMETRY_DISABLED=1 +HELIO_SKIP_CHECKS=1 REPO_HOME=$(pwd) if [ "$(basename $REPO_HOME)" = "scripts" ]; then From 377e86f3b9e7c71ce3d2d8a80b6610f0a2f6f7f5 Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Thu, 15 Jan 2026 14:43:16 -0600 Subject: [PATCH 02/21] repo: windows support --- .vscode/settings.json | 32 ++++++------- apps/docs/package.json | 4 +- apps/learn/package.json | 4 +- apps/netlogo/package.json | 4 +- apps/nettango/package.json | 4 +- package.json | 5 ++- packages/markdown/package.json | 3 +- packages/nuxt-content-assets/package.json | 4 +- .../playground/package.json | 2 +- packages/nuxt-core/package.json | 4 +- turbo.json | 45 ++++++------------- 11 files changed, 46 insertions(+), 65 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 376d53e1..0e655eb2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -48,22 +48,22 @@ "editor.formatOnSave": false }, - "files.exclude": { - "**/.next": true, - "**/.nuxt": true, - "**/node_modules": true, - "**/.out": true, - "**/.turbo": true, - "external/": true, - ".git*": true, - ".npmrc": true, - "**/out": true, - "**/dist": true, - "**/coverage": true, - "**/test-dist": true, - "**/.output": true, - "**/.data": true - }, + // "files.exclude": { + // "**/.next": true, + // "**/.nuxt": true, + // "**/node_modules": true, + // "**/.out": true, + // "**/.turbo": true, + // "external/": true, + // ".git*": true, + // ".npmrc": true, + // "**/out": true, + // "**/dist": true, + // "**/coverage": true, + // "**/test-dist": true, + // "**/.output": true, + // "**/.data": true + // }, "cSpell.words": ["autogen", "iconify", "netlogo", "Nuxt", "Pathnames", "reka", "vueuse"] } diff --git a/apps/docs/package.json b/apps/docs/package.json index 9fe3753d..18eed8f7 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -29,7 +29,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "node-version": "node -v && npm -v", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "@nuxt/content": "^3.7.1", @@ -98,4 +98,4 @@ "typescript": "^5.4.0", "zod": "^4.1.12" } -} \ No newline at end of file +} diff --git a/apps/learn/package.json b/apps/learn/package.json index c2bbec10..d52d70bd 100644 --- a/apps/learn/package.json +++ b/apps/learn/package.json @@ -21,7 +21,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "node-version": "node -v && npm -v", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "@nuxt/content": "^3.7.1", @@ -97,4 +97,4 @@ "typescript": "^5.4.0", "zod": "^4.1.12" } -} \ No newline at end of file +} diff --git a/apps/netlogo/package.json b/apps/netlogo/package.json index 7812e083..36b659f1 100644 --- a/apps/netlogo/package.json +++ b/apps/netlogo/package.json @@ -22,7 +22,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "node-version": "node -v && npm -v", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "nuxt": "^4.1.2", @@ -65,4 +65,4 @@ "sass": "^1.93.3", "eslint": "^9.31.0" } -} \ No newline at end of file +} diff --git a/apps/nettango/package.json b/apps/nettango/package.json index 05b425ae..88f16029 100644 --- a/apps/nettango/package.json +++ b/apps/nettango/package.json @@ -17,7 +17,7 @@ "check-types": "nuxi typecheck", "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", - "postinstall": "nuxt prepare", + "turbo:postinstall": "nuxt prepare", "node-version": "node -v && npm -v" }, "dependencies": { @@ -68,4 +68,4 @@ "typescript": "^5.4.0", "zod": "^4.1.12" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index b4bc3a78..4cdaabe7 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "test": "turbo run test", "check-types": "turbo run check-types", "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "pre-push": "sh ./scripts/check-repo.sh" + "pre-push": "sh ./scripts/check-repo.sh", + "postinstall": "yarn run turbo postinstall" }, "devDependencies": { "prettier": "^3.6.2", @@ -70,4 +71,4 @@ "typescript-eslint": "8.45.0", "@vueuse/core": "^14.1.0" } -} \ No newline at end of file +} diff --git a/packages/markdown/package.json b/packages/markdown/package.json index 1a4b9f5f..e22882b9 100644 --- a/packages/markdown/package.json +++ b/packages/markdown/package.json @@ -24,8 +24,7 @@ "scripts": { "build": "npm run build:styles && npm run build:components", "build:styles": "tailwindcss -i ./src/styles.scss -o ./dist/index.scss", - "build:components": "tsc && tsc-alias && npm run copy:scss", - "copy:scss": "find src -name '*.scss' -not -name 'styles.scss' | while read file; do mkdir -p \"dist/$(dirname \"${file#src/}\")\"; cp \"$file\" \"dist/${file#src/}\"; done", + "build:components": "tsc && tsc-alias", "check-types": "tsc --noEmit", "dev": "npm run dev:components & npm run dev:styles & npm run dev:scss", "dev:styles": "tailwindcss -i ./src/styles.scss -o ./dist/index.scss --watch", diff --git a/packages/nuxt-content-assets/package.json b/packages/nuxt-content-assets/package.json index 4ea52093..cd4ed339 100644 --- a/packages/nuxt-content-assets/package.json +++ b/packages/nuxt-content-assets/package.json @@ -21,7 +21,7 @@ "scripts": { "build": "nuxt-module-build build", "lint": "eslint .", - "postinstall": "cd ./playground && yarn run postinstall" + "turbo:postinstall": "cd ./playground && yarn run turbo:postinstall" }, "dependencies": { "@nuxt/kit": "^4.2.1", @@ -54,4 +54,4 @@ "engines": { "node": "^22.0.0" } -} \ No newline at end of file +} diff --git a/packages/nuxt-content-assets/playground/package.json b/packages/nuxt-content-assets/playground/package.json index 636c75b4..adf02aaa 100644 --- a/packages/nuxt-content-assets/playground/package.json +++ b/packages/nuxt-content-assets/playground/package.json @@ -7,7 +7,7 @@ "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "@nuxt/content": "^3.7.1", diff --git a/packages/nuxt-core/package.json b/packages/nuxt-core/package.json index 0556291d..81a75462 100644 --- a/packages/nuxt-core/package.json +++ b/packages/nuxt-core/package.json @@ -8,7 +8,7 @@ "./nuxt/tsconfig.json": "./.nuxt/tsconfig.json" }, "scripts": { - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "nuxt": "^4.1.2", @@ -50,4 +50,4 @@ "sass": "^1.93.3", "eslint": "^9.31.0" } -} \ No newline at end of file +} diff --git a/turbo.json b/turbo.json index 189cac63..93b68373 100644 --- a/turbo.json +++ b/turbo.json @@ -2,51 +2,32 @@ "$schema": "https://turborepo.com/schema.json", "ui": "tui", "concurrency": "15", - "globalDependencies": [ - ".env", - ".env.local", - "tsconfig.json" - ], + "globalDependencies": [".env", ".env.local", "tsconfig.json"], "tasks": { + "postinstall": { + "dependsOn": ["^turbo:postinstall"] + }, + "turbo:postinstall": {}, "build": { - "dependsOn": [ - "^build" - ], - "inputs": [ - "$TURBO_DEFAULT$", - ".env*" - ], - "outputs": [ - "dist/**", - ".next/**", - "!.next/cache/**" - ] + "dependsOn": ["^build"], + "inputs": ["$TURBO_DEFAULT$", ".env*"], + "outputs": ["dist/**", ".next/**", "!.next/cache/**"] }, "init": { - "dependsOn": [ - "^build", - "^init" - ] + "dependsOn": ["^build", "^init"] }, "lint": { - "dependsOn": [ - "^lint" - ] + "dependsOn": ["^lint"] }, "test": { - "dependsOn": [ - "^build", - "^test" - ] + "dependsOn": ["^build", "^test"] }, "check-types": { - "dependsOn": [ - "^check-types" - ] + "dependsOn": ["^check-types"] }, "dev": { "cache": false, "persistent": true } } -} \ No newline at end of file +} From 96d777a8f55e705e0ead8bf7d5f3dcac413b30f6 Mon Sep 17 00:00:00 2001 From: Omar Ibrahim <18043@stemegypt.edu.eg> Date: Tue, 13 Jan 2026 13:31:31 -0600 Subject: [PATCH 03/21] ci(docs): add fully headless script mode --- .github/workflows/deploy-docs.yml | 12 ++-- apps/docs/package.json | 4 +- .../public/_index/extensions/view2.5d.txt | 24 +++++++ apps/docs/scripts/.helpers | 17 ++++- apps/docs/scripts/deploy.sh | 8 ++- .../scripts/generate-manual/env-options.cjs | 70 +++++++++++++++++++ .../scripts/generate-manual/env-options.ts | 12 ++++ apps/docs/scripts/generate-manual/index.cjs | 9 ++- apps/docs/scripts/generate-manual/run.sh | 2 +- apps/docs/scripts/generate.sh | 39 ++++++----- scripts/check-repo.sh | 7 ++ scripts/initialize.sh | 1 + 12 files changed, 176 insertions(+), 29 deletions(-) create mode 100644 apps/docs/scripts/generate-manual/env-options.cjs create mode 100644 apps/docs/scripts/generate-manual/env-options.ts diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 615f84f3..d6b713ac 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -20,13 +20,17 @@ jobs: - name: Install dependencies shell: bash - run: NEXT_TELEMETRY_DISABLED=1 yarn run init + env: + HELIO_SKIP_CHECKS: 1 + NUXT_TELEMETRY_DISABLED: 1 + run: NUXT_TELEMETRY_DISABLED=1 yarn run init - name: Build and deploy working-directory: apps/docs shell: bash env: - PRINT_DEBUG: 1 + HELIO_HEADLESS: 1 + HELIO_SKIP_CHECKS: 1 + NUXT_TELEMETRY_DISABLED: 1 GITHUB_TOKEN: ${{ secrets.NETLOGO_HELIO_CI_TOKEN }} - run: | - yes | yarn run docs:deploy + run: yarn run docs:deploy diff --git a/apps/docs/package.json b/apps/docs/package.json index 49aef439..9fe3753d 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -8,8 +8,8 @@ }, "scripts": { "init": "nuxt prepare", - "docs:build": "NODE_OPTIONS=--max-old-space-size=8192 ./scripts/generate.sh", - "docs:deploy": "NODE_OPTIONS=--max-old-space-size=8192 bash ./scripts/deploy.sh", + "docs:build": "./scripts/generate.sh", + "docs:deploy": "bash ./scripts/deploy.sh", "docs:preview": "bash ./scripts/preview.sh", "docs:clean-up": "bash ./scripts/clean-up.sh", "docs:generate-manual": "bash ./scripts/generate-manual/run.sh", diff --git a/apps/docs/public/_index/extensions/view2.5d.txt b/apps/docs/public/_index/extensions/view2.5d.txt index e69de29b..7a88396c 100644 --- a/apps/docs/public/_index/extensions/view2.5d.txt +++ b/apps/docs/public/_index/extensions/view2.5d.txt @@ -0,0 +1,24 @@ +view2.5d:patch-view patch-view.html +view2.5d:decorate-patch-view decorate-patch-view.html +view2.5d:undecorate-patch-view undecorate-patch-view.html +view2.5d:turtle-view turtle-view.html +view2.5d:update-all-patch-views update-all-patch-views.html +view2.5d:update-patch-view update-patch-view.html +view2.5d:update-turtle-view update-turtle-view.html +view2.5d:get-z-scale get-z-scale.html +view2.5d:set-z-scale set-z-scale.html +view2.5d:set-turtle-stem-thickness set-turtle-stem-thickness.html +view2.5d:set-turtle-stem-color set-turtle-stem-color.html +view2.5d:show-links-xy-plane show-links-xy-plane.html +view2.5d:show-links-xyz show-links-xyz.html +view2.5d:get-observer-angles get-observer-angles.html +view2.5d:set-observer-angles set-observer-angles.html +view2.5d:get-observer-xy-focus get-observer-xy-focus.html +view2.5d:set-observer-xy-focus set-observer-xy-focus.html +view2.5d:get-observer-distance get-observer-distance.html +view2.5d:set-observer-distance set-observer-distance.html +view2.5d:remove-patch-view remove-patch-view.html +view2.5d:remove-turtle-view remove-turtle-view.html +view2.5d:remove-all-patch-views remove-all-patch-views.html +view2.5d:remove-all-turtle-views remove-all-turtle-views.html +view2.5d:count-windows count-windows.html \ No newline at end of file diff --git a/apps/docs/scripts/.helpers b/apps/docs/scripts/.helpers index 6554089e..a9c04b99 100644 --- a/apps/docs/scripts/.helpers +++ b/apps/docs/scripts/.helpers @@ -1,5 +1,11 @@ #!/bin/bash +HELIO_HEADLESS="${HELIO_HEADLESS:-0}" + +if [ "$HELIO_HEADLESS" = "1" ]; then + echo "๐Ÿ’ก Running in headless mode." +fi + function echo() { command echo "[$(date +'%H:%M')] $*" } @@ -47,7 +53,7 @@ function unroll() { } function confirmUnlessHeadless() { - if [ "$HEADLESS" != "true" ]; then + if [ "$HELIO_HEADLESS" != "1" ]; then read -p "โš ๏ธ $1 (y/n): " response if [ "$response" != "y" ]; then echo "๐Ÿ’ก Operation cancelled by user." @@ -55,3 +61,12 @@ function confirmUnlessHeadless() { fi fi } + +_read() { + if [ "$HELIO_HEADLESS" = "1" ]; then + realEcho $2 + else + read -p "$1" response + realEcho "$response" + fi +} diff --git a/apps/docs/scripts/deploy.sh b/apps/docs/scripts/deploy.sh index 52e68d0f..0854c86b 100755 --- a/apps/docs/scripts/deploy.sh +++ b/apps/docs/scripts/deploy.sh @@ -39,10 +39,11 @@ fi echo "=== Step 1: Build documentation site ===" if [ -d .build ]; then - read -p "โš ๏ธ Do you want to use the existing build? (y/n): " use_existing + use_existing=$(_read "โš ๏ธ Do you want to use the existing build? (y/n): " "y") if [ "$use_existing" != "y" ]; then echo "๐Ÿ’ก (Re)building documentation site..." yarn run docs:build + echo "๐Ÿ’ก Generating the PDF Manual" yarn run docs:generate-manual else echo "๐Ÿ’ก Using existing .build directory." @@ -50,13 +51,14 @@ if [ -d .build ]; then else echo "๐Ÿ’ก Building documentation site..." yarn run docs:build + echo "๐Ÿ’ก Generating the PDF Manual" yarn run docs:generate-manual fi echo "" echo "=== Step 2: Clone documentation repository ===" if [ "$(ls -A .repo)" ]; then - read -p "โš ๏ธ .repo directory already exists and is not empty. Do you want to use it? (y/n): " use_repo + use_repo=$(_read "โš ๏ธ .repo directory already exists and is not empty. Do you want to use it? (y/n): " "y") if [ "$use_repo" != "y" ]; then echo "๐Ÿ’ก Removing existing .repo directory..." rm -rf .repo @@ -106,7 +108,7 @@ fi echo "" echo "=== Step 5: Commit and push changes ===" -read -p "โš ๏ธ Are you sure you want to commit and push changes to the $BUILD_BRANCH branch? (y/n): " confirm_push +confirm_push=$(_read "โš ๏ธ Are you sure you want to commit and push changes to the $BUILD_BRANCH branch? (y/n): " "y") if [ "$confirm_push" != "y" ]; then echo "๐Ÿ’ก Deployment aborted by user." exit 0 diff --git a/apps/docs/scripts/generate-manual/env-options.cjs b/apps/docs/scripts/generate-manual/env-options.cjs new file mode 100644 index 00000000..ba4089d7 --- /dev/null +++ b/apps/docs/scripts/generate-manual/env-options.cjs @@ -0,0 +1,70 @@ +/** + * @type {Array} + */ +module.exports = [ + { + environmentName: 'github-actions', + launch: { + args: [ + '--disable-features=IsolateOrigins', + '--disable-site-isolation-trials', + '--autoplay-policy=user-gesture-required', + '--disable-background-networking', + '--disable-background-timer-throttling', + '--disable-backgrounding-occluded-windows', + '--disable-breakpad', + '--disable-client-side-phishing-detection', + '--disable-component-update', + '--disable-default-apps', + '--disable-dev-shm-usage', + '--disable-domain-reliability', + '--disable-extensions', + '--disable-features=AudioServiceOutOfProcess', + '--disable-hang-monitor', + '--disable-ipc-flooding-protection', + '--disable-notifications', + '--disable-offer-store-unmasked-wallet-cards', + '--disable-popup-blocking', + '--disable-print-preview', + '--disable-prompt-on-repost', + '--disable-renderer-backgrounding', + '--disable-setuid-sandbox', + '--disable-speech-api', + '--disable-sync', + '--disable-gpu', + '--hide-scrollbars', + '--ignore-gpu-blacklist', + '--metrics-recording-only', + '--mute-audio', + '--no-default-browser-check', + '--no-first-run', + '--no-pings', + '--no-sandbox', + '--no-zygote', + '--password-store=basic', + '--use-gl=swiftshader', + '--use-mock-keychain', + '--unlimited-storage', + '--enable-logging', + '--v=2', + ], + headless: false, + }, + test: () => process.env.CI === 'true', + beforeAll: async () => { + const { install } = await import('@puppeteer/browsers'); + await install('chromium', 'latest'); + }, + timeout: 200000, + }, + { + environmentName: 'default', + launch: { + headless: 'new', + args: ['--no-sandbox'], + }, + test: () => true, + beforeAll: async () => {}, + timeout: 120000, + }, +]; diff --git a/apps/docs/scripts/generate-manual/env-options.ts b/apps/docs/scripts/generate-manual/env-options.ts new file mode 100644 index 00000000..5275ce8c --- /dev/null +++ b/apps/docs/scripts/generate-manual/env-options.ts @@ -0,0 +1,12 @@ +import type { LaunchOptions } from 'puppeteer'; + +type EnvironmentName = 'github-actions' | 'default'; +type EnvironmentOptions = { + environmentName: EnvironmentName; + launch: LaunchOptions; + test: () => boolean; + beforeAll: () => Promise; + timeout: number; +}; + +export type { EnvironmentName, EnvironmentOptions }; diff --git a/apps/docs/scripts/generate-manual/index.cjs b/apps/docs/scripts/generate-manual/index.cjs index b2851373..9b5db264 100644 --- a/apps/docs/scripts/generate-manual/index.cjs +++ b/apps/docs/scripts/generate-manual/index.cjs @@ -41,6 +41,10 @@ async function main() { // Import the required modules const puppeteer = require('puppeteer'); const fs = require('fs-extra'); + const environments = require('./env-options.cjs'); + + // Check the environment + const environmentOptions = environments.find((env) => env.test()); // Parse command line arguments const args = process.argv.slice(2); @@ -57,11 +61,12 @@ async function main() { let htmlFiles = args.slice(3); // middle args are the HTML files // Run puppeteer in headless mode - const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox'] }); + await environmentOptions.beforeAll(); + const browser = await puppeteer.launch(environmentOptions.launch); const page = await browser.newPage(); // Increase timeout - page.setDefaultTimeout(120000); // 120 seconds + page.setDefaultTimeout(environmentOptions.timeout); // 120 seconds /** * @typedef {Object} TocEntry diff --git a/apps/docs/scripts/generate-manual/run.sh b/apps/docs/scripts/generate-manual/run.sh index 2840cfd9..0322f520 100755 --- a/apps/docs/scripts/generate-manual/run.sh +++ b/apps/docs/scripts/generate-manual/run.sh @@ -81,7 +81,7 @@ EOF ) echo "๐Ÿ’ก Generating title page." -echo "$title" > "$fileDirectory/title.html" +realEcho "$title" > "$fileDirectory/title.html" files=( "title" diff --git a/apps/docs/scripts/generate.sh b/apps/docs/scripts/generate.sh index 13aae0c8..9256daf1 100755 --- a/apps/docs/scripts/generate.sh +++ b/apps/docs/scripts/generate.sh @@ -8,21 +8,22 @@ set -euo pipefail # Strict error handling echo "โš™๏ธ Starting generation of static files..." echo "๐Ÿ’ก You can check .stdout.log and .stderr.log for progress and errors." -processes_to_kill=(node yarn npm) -echo "โš ๏ธ This script will kill all ${processes_to_kill[*]} processes." -for process in "${processes_to_kill[@]}"; do - pgrep $process | xargs -r kill -9 >/dev/null 2>/dev/null || true -done -echo "โœ… Killed specified processes." - -if [ "${BUILD_LATEST:-false}" = "true" ]; then - echo "๐Ÿ’ก Building latest version in addition to ${PRODUCT_VERSION}" -else - echo "๐Ÿ’ก Building only version ${PRODUCT_VERSION}" +if [ "$HELIO_HEADLESS" != "1" ]; then + processes_to_kill=(node yarn npm) + echo "โš ๏ธ This script will kill all ${processes_to_kill[*]} processes." + for process in "${processes_to_kill[@]}"; do + pgrep $process | xargs -r kill -9 >/dev/null 2>/dev/null || true + done + echo "โœ… Killed specified processes." + + if [ "${BUILD_LATEST:-false}" = "true" ]; then + echo "๐Ÿ’ก Building latest version in addition to ${PRODUCT_VERSION}" + else + echo "๐Ÿ’ก Building only version ${PRODUCT_VERSION}" + fi fi TARGET_DIR="$(pwd)/.build" # Define target directory for generated files -PRINT_DEBUG="${PRINT_DEBUG:-0}" rm .stdout.log 2>/dev/null || true # Clear previous logs rm .stderr.log 2>/dev/null || true @@ -32,8 +33,14 @@ mkdir -p "$TARGET_DIR" echo "๐Ÿงน Emptied target directory: $TARGET_DIR" echo "๐Ÿ’ก Preparing Nuxt for generation..." -npx nuxi cleanup >> .stdout.log 2>> .stderr.log -BASE_PATH="/" yarn run nuxt:prepare >> .stdout.log 2>> .stderr.log +if [ "$HELIO_HEADLESS" -eq 1 ]; then + npx nuxi cleanup + BASE_PATH="/" yarn run nuxt:prepare +else + npx nuxi cleanup >> .stdout.log 2>> .stderr.log + BASE_PATH="/" yarn run nuxt:prepare >> .stdout.log 2>> .stderr.log +fi + echo "==== end of prepare step ====" >> .stdout.log echo "" >> .stdout.log echo "โœ… Nuxt prepared." @@ -42,7 +49,7 @@ if [ "$BUILD_LATEST" = "true" ]; then echo "๐Ÿ’ก Building no-prefix version" # 1) Generate for base path "/" - if [ "$PRINT_DEBUG" -eq 1 ]; then + if [ "$HELIO_HEADLESS" -eq 1 ]; then BASE_PATH="/" yarn run nuxt:generate else BASE_PATH="/" yarn run nuxt:generate >> .stdout.log 2>> .stderr.log @@ -61,7 +68,7 @@ fi echo "๐Ÿ’ก Building version ${PRODUCT_VERSION}" # 3) Generate for versioned path "//" -if [ "$PRINT_DEBUG" -eq 1 ]; then +if [ "$HELIO_HEADLESS" -eq 1 ]; then BASE_PATH="/$PRODUCT_VERSION/" yarn run nuxt:generate else BASE_PATH="/$PRODUCT_VERSION/" yarn run nuxt:generate >> .stdout.log 2>> .stderr.log diff --git a/scripts/check-repo.sh b/scripts/check-repo.sh index 9df822bd..f61c9128 100644 --- a/scripts/check-repo.sh +++ b/scripts/check-repo.sh @@ -1,6 +1,13 @@ #!/bin/sh set -e +HELIO_SKIP_CHECKS=${HELIO_SKIP_CHECKS:-0} + +if [ "$HELIO_SKIP_CHECKS" = "1" ]; then + echo "Skipping repository checks (HELIO_SKIP_CHECKS=1)" + exit 0 +fi + yarn turbo run build yarn turbo run lint yarn turbo run check-types diff --git a/scripts/initialize.sh b/scripts/initialize.sh index 6caf16d4..2966890e 100644 --- a/scripts/initialize.sh +++ b/scripts/initialize.sh @@ -12,6 +12,7 @@ set -e NUXT_TELEMETRY_DISABLED=1 +HELIO_SKIP_CHECKS=1 REPO_HOME=$(pwd) if [ "$(basename $REPO_HOME)" = "scripts" ]; then From cbcac52ec9edf881a120adfc99ad42bfbf7eaf34 Mon Sep 17 00:00:00 2001 From: Omar Ibrahim <18043@stemegypt.edu.eg> Date: Fri, 16 Jan 2026 12:10:28 -0600 Subject: [PATCH 04/21] fixup pdf --- apps/docs/scripts/generate-manual/env-options.cjs | 9 +++------ apps/docs/scripts/generate-manual/index.cjs | 8 +++++--- apps/docs/scripts/generate-manual/run.sh | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/apps/docs/scripts/generate-manual/env-options.cjs b/apps/docs/scripts/generate-manual/env-options.cjs index ba4089d7..f2e59986 100644 --- a/apps/docs/scripts/generate-manual/env-options.cjs +++ b/apps/docs/scripts/generate-manual/env-options.cjs @@ -50,12 +50,9 @@ module.exports = [ ], headless: false, }, - test: () => process.env.CI === 'true', - beforeAll: async () => { - const { install } = await import('@puppeteer/browsers'); - await install('chromium', 'latest'); - }, - timeout: 200000, + test: () => typeof process.env.CI !== 'undefined', + beforeAll: async () => {}, + timeout: 800000, }, { environmentName: 'default', diff --git a/apps/docs/scripts/generate-manual/index.cjs b/apps/docs/scripts/generate-manual/index.cjs index 9b5db264..5dd377fe 100644 --- a/apps/docs/scripts/generate-manual/index.cjs +++ b/apps/docs/scripts/generate-manual/index.cjs @@ -45,6 +45,7 @@ async function main() { // Check the environment const environmentOptions = environments.find((env) => env.test()); + console.info('Using Options:', JSON.stringify(environmentOptions, null, 2)); // Parse command line arguments const args = process.argv.slice(2); @@ -66,7 +67,7 @@ async function main() { const page = await browser.newPage(); // Increase timeout - page.setDefaultTimeout(environmentOptions.timeout); // 120 seconds + page.setDefaultTimeout(environmentOptions.timeout); /** * @typedef {Object} TocEntry @@ -236,7 +237,7 @@ async function main() { const fileBaseName = path.basename(file); const fileUrl = 'http://' + serverHost + ':' + serverPort + '/' + urlPrefix + fileBaseName; console.log(`Handling: ${fileBaseName} (=> ${fileUrl})`); - await myPage.goto(fileUrl, { waitUntil: 'networkidle0' }); + await myPage.goto(fileUrl, { waitUntil: 'domcontentloaded', timeout: 120000 }); /** * Extract the table of contents entries from the page. @@ -441,7 +442,8 @@ ${combinedHtml.filter(Boolean).join('')} const tempHtmlUrl = 'http://' + serverHost + ':' + serverPort + '/' + urlPrefix + 'tmp.html'; await page.setJavaScriptEnabled(false); - await page.goto(tempHtmlUrl, { waitUntil: 'networkidle0' }); + await page.emulateMediaType('print'); + await page.goto(tempHtmlUrl, { waitUntil: 'domcontentloaded', timeout: environmentOptions.timeout }); const pdfBuffer = await page.pdf({ format: 'A4', printBackground: true, diff --git a/apps/docs/scripts/generate-manual/run.sh b/apps/docs/scripts/generate-manual/run.sh index 0322f520..d3f689ff 100755 --- a/apps/docs/scripts/generate-manual/run.sh +++ b/apps/docs/scripts/generate-manual/run.sh @@ -17,7 +17,7 @@ if [ ! -d ".build/latest" ] && [ ! -d ".build/${PRODUCT_VERSION}" ]; then exit 1 fi -(yarn run docs:preview --port $PORT) & +(yarn run docs:preview --port $PORT > /dev/null 2>&1) & PREVIEW_PID=$! echo "๐Ÿš€ Started preview server (PID $PREVIEW_PID)" From 58309c9a121050085e475289aaf40bbaf0e2d8b1 Mon Sep 17 00:00:00 2001 From: Omar Ibrahim <18043@stemegypt.edu.eg> Date: Fri, 16 Jan 2026 11:12:55 -0600 Subject: [PATCH 05/21] dev: add utility to clean dirty file watchers left by node --- package.json | 5 ++-- packages/markdown/package.json | 5 ++-- scripts/clean-file-watchers.sh | 49 ++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) create mode 100755 scripts/clean-file-watchers.sh diff --git a/package.json b/package.json index b4bc3a78..59c15eb2 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "test": "turbo run test", "check-types": "turbo run check-types", "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "pre-push": "sh ./scripts/check-repo.sh" + "pre-push": "sh ./scripts/check-repo.sh", + "clean-up": "sh ./scripts/clean-file-watchers.sh" }, "devDependencies": { "prettier": "^3.6.2", @@ -70,4 +71,4 @@ "typescript-eslint": "8.45.0", "@vueuse/core": "^14.1.0" } -} \ No newline at end of file +} diff --git a/packages/markdown/package.json b/packages/markdown/package.json index 1a4b9f5f..5fdd5c51 100644 --- a/packages/markdown/package.json +++ b/packages/markdown/package.json @@ -24,8 +24,7 @@ "scripts": { "build": "npm run build:styles && npm run build:components", "build:styles": "tailwindcss -i ./src/styles.scss -o ./dist/index.scss", - "build:components": "tsc && tsc-alias && npm run copy:scss", - "copy:scss": "find src -name '*.scss' -not -name 'styles.scss' | while read file; do mkdir -p \"dist/$(dirname \"${file#src/}\")\"; cp \"$file\" \"dist/${file#src/}\"; done", + "build:components": "tsc && tsc-alias", "check-types": "tsc --noEmit", "dev": "npm run dev:components & npm run dev:styles & npm run dev:scss", "dev:styles": "tailwindcss -i ./src/styles.scss -o ./dist/index.scss --watch", @@ -73,4 +72,4 @@ "unist-builder": "^4.0.0", "unist-util-visit": "^5.0.0" } -} +} \ No newline at end of file diff --git a/scripts/clean-file-watchers.sh b/scripts/clean-file-watchers.sh new file mode 100755 index 00000000..17c9b310 --- /dev/null +++ b/scripts/clean-file-watchers.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +REPO_PATH=$(dirname "$(dirname "$(realpath "$0")")") + +echo "โ„น๏ธ Process PID: $$" +echo "โ„น๏ธ Parent PID: $PPID" + +function count_os_wide_watchers() { + echo $(lsof "/" | wc -l) +} + +echo "โ„น๏ธ Current OS-wide file watchers: $(count_os_wide_watchers)" + +echo "โณ Finding Node processes holding files in $REPO_PATH..." + +PIDS=$(lsof +D "$REPO_PATH" | grep -E "node|npm" | awk '{print $2}' | sort -u) + +if [ -z "$PIDS" ]; then + echo "โŒ No Node processes found holding files in the repo." + exit 0 +fi + +echo "โ„น๏ธ Found PIDs: $(echo "$PIDS" | wc -l)" + +function send_sig() { + for PID in $PIDS; do + if echo "$PID" | grep -E "^($$|$PPID)$" >/dev/null; then + echo "โš ๏ธ Skipping PID $PID (self or parent)..." + continue + fi + if kill -0 "$PID" 2>/dev/null; then + echo "โ„น๏ธ Sending $2 to PID $PID..." + kill "$1" "$PID" + fi + done +} + +echo "โ„น๏ธ Attempt graceful termination..." +send_sig -15 "SIGTERM" + +echo "โณ Waiting 5 seconds for processes to terminate..." +sleep 5 + +echo "โ„น๏ธ Forcefully killing remaining processes..." +send_sig -9 "SIGKILL" + +echo "โœ”๏ธ Done! Current OS-wide file watchers: $(count_os_wide_watchers)" From 3d20d95cc3cd97a498e012a14642da072bb5f1c7 Mon Sep 17 00:00:00 2001 From: Omar Ibrahim <18043@stemegypt.edu.eg> Date: Fri, 16 Jan 2026 12:15:02 -0600 Subject: [PATCH 06/21] hotfix(repo): workaround for yarn bug on windows (yarnpkg/yarn/issues/4564) --- apps/docs/package.json | 4 ++-- apps/learn/package.json | 4 ++-- apps/netlogo/package.json | 4 ++-- apps/nettango/package.json | 4 ++-- package.json | 3 ++- packages/nuxt-content-assets/package.json | 4 ++-- packages/nuxt-content-assets/playground/package.json | 2 +- packages/nuxt-core/package.json | 4 ++-- packages/nuxt-core/package.template.json | 4 ++-- scripts/initialize.sh | 2 +- turbo.json | 11 ++++++++++- 11 files changed, 28 insertions(+), 18 deletions(-) diff --git a/apps/docs/package.json b/apps/docs/package.json index 9fe3753d..18eed8f7 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -29,7 +29,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "node-version": "node -v && npm -v", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "@nuxt/content": "^3.7.1", @@ -98,4 +98,4 @@ "typescript": "^5.4.0", "zod": "^4.1.12" } -} \ No newline at end of file +} diff --git a/apps/learn/package.json b/apps/learn/package.json index c2bbec10..d52d70bd 100644 --- a/apps/learn/package.json +++ b/apps/learn/package.json @@ -21,7 +21,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "node-version": "node -v && npm -v", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "@nuxt/content": "^3.7.1", @@ -97,4 +97,4 @@ "typescript": "^5.4.0", "zod": "^4.1.12" } -} \ No newline at end of file +} diff --git a/apps/netlogo/package.json b/apps/netlogo/package.json index 7812e083..36b659f1 100644 --- a/apps/netlogo/package.json +++ b/apps/netlogo/package.json @@ -22,7 +22,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "node-version": "node -v && npm -v", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "nuxt": "^4.1.2", @@ -65,4 +65,4 @@ "sass": "^1.93.3", "eslint": "^9.31.0" } -} \ No newline at end of file +} diff --git a/apps/nettango/package.json b/apps/nettango/package.json index 05b425ae..88f16029 100644 --- a/apps/nettango/package.json +++ b/apps/nettango/package.json @@ -17,7 +17,7 @@ "check-types": "nuxi typecheck", "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", - "postinstall": "nuxt prepare", + "turbo:postinstall": "nuxt prepare", "node-version": "node -v && npm -v" }, "dependencies": { @@ -68,4 +68,4 @@ "typescript": "^5.4.0", "zod": "^4.1.12" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 59c15eb2..e85adb05 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "check-types": "turbo run check-types", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "pre-push": "sh ./scripts/check-repo.sh", - "clean-up": "sh ./scripts/clean-file-watchers.sh" + "clean-up": "sh ./scripts/clean-file-watchers.sh", + "postinstall": "turbo run turbo:postinstall" }, "devDependencies": { "prettier": "^3.6.2", diff --git a/packages/nuxt-content-assets/package.json b/packages/nuxt-content-assets/package.json index 4ea52093..1df0c03d 100644 --- a/packages/nuxt-content-assets/package.json +++ b/packages/nuxt-content-assets/package.json @@ -21,7 +21,7 @@ "scripts": { "build": "nuxt-module-build build", "lint": "eslint .", - "postinstall": "cd ./playground && yarn run postinstall" + "turbo:postinstall": "cd ./playground && nuxt prepare" }, "dependencies": { "@nuxt/kit": "^4.2.1", @@ -54,4 +54,4 @@ "engines": { "node": "^22.0.0" } -} \ No newline at end of file +} diff --git a/packages/nuxt-content-assets/playground/package.json b/packages/nuxt-content-assets/playground/package.json index 636c75b4..adf02aaa 100644 --- a/packages/nuxt-content-assets/playground/package.json +++ b/packages/nuxt-content-assets/playground/package.json @@ -7,7 +7,7 @@ "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "@nuxt/content": "^3.7.1", diff --git a/packages/nuxt-core/package.json b/packages/nuxt-core/package.json index 0556291d..81a75462 100644 --- a/packages/nuxt-core/package.json +++ b/packages/nuxt-core/package.json @@ -8,7 +8,7 @@ "./nuxt/tsconfig.json": "./.nuxt/tsconfig.json" }, "scripts": { - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "nuxt": "^4.1.2", @@ -50,4 +50,4 @@ "sass": "^1.93.3", "eslint": "^9.31.0" } -} \ No newline at end of file +} diff --git a/packages/nuxt-core/package.template.json b/packages/nuxt-core/package.template.json index 4ab8982a..96966c91 100644 --- a/packages/nuxt-core/package.template.json +++ b/packages/nuxt-core/package.template.json @@ -22,7 +22,7 @@ "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "node-version": "node -v && npm -v", - "postinstall": "nuxt prepare" + "turbo:postinstall": "nuxt prepare" }, "dependencies": { "nuxt": "^4.1.2", @@ -65,4 +65,4 @@ "sass": "^1.93.3", "eslint": "^9.31.0" } -} \ No newline at end of file +} diff --git a/scripts/initialize.sh b/scripts/initialize.sh index 2966890e..f2d6f372 100644 --- a/scripts/initialize.sh +++ b/scripts/initialize.sh @@ -22,5 +22,5 @@ fi git submodule update --init --recursive yarn install --ignore-scripts --frozen-lockfile yarn turbo run build -yarn install --force +yarn install --force --frozen-lockfile NUXT_TELEMETRY_DISABLED=1 yarn turbo run init diff --git a/turbo.json b/turbo.json index 189cac63..69c2d3e6 100644 --- a/turbo.json +++ b/turbo.json @@ -8,6 +8,15 @@ "tsconfig.json" ], "tasks": { + "turbo:postinstall": { + "cache": false, + "outputs": [ + ".nuxt/**", + ".output/**", + "node_modules/.cache/**", + "content/**" + ] + }, "build": { "dependsOn": [ "^build" @@ -49,4 +58,4 @@ "persistent": true } } -} \ No newline at end of file +} From d1a1238f394c62c2a62ce912f582ddbf148d8826 Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Fri, 16 Jan 2026 17:10:20 -0600 Subject: [PATCH 07/21] Edit tab icons and navbar logo --- apps/netlogo/app/assets/website-logo.ts | 2 +- apps/netlogo/app/assets/website-meta.json | 4 ++-- apps/netlogo/app/pages/index.vue | 2 +- apps/netlogo/public/favicon.ico | Bin 4286 -> 15086 bytes .../vue-ui/assets/brands/NetLogoOrgLogo.svg | 10 ++++++++++ 5 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 packages/vue-ui/assets/brands/NetLogoOrgLogo.svg diff --git a/apps/netlogo/app/assets/website-logo.ts b/apps/netlogo/app/assets/website-logo.ts index 70d3afe6..b71e8540 100644 --- a/apps/netlogo/app/assets/website-logo.ts +++ b/apps/netlogo/app/assets/website-logo.ts @@ -1,3 +1,3 @@ -import WebsiteLogo from "@repo/vue-ui/assets/brands/NetLogoLearnGuide.svg"; +import WebsiteLogo from "@repo/vue-ui/assets/brands/NetLogoOrgLogo.svg"; export { WebsiteLogo }; diff --git a/apps/netlogo/app/assets/website-meta.json b/apps/netlogo/app/assets/website-meta.json index 06de3676..f6f0fef9 100644 --- a/apps/netlogo/app/assets/website-meta.json +++ b/apps/netlogo/app/assets/website-meta.json @@ -1,5 +1,5 @@ { - "name": "NetLogo", + "name": "NetLogo Home", "fullName": "NetLogo: Agent-Based Modeling Environment", "description": "Agent-Based Modeling Environment for Simulating Natural and Social Phenomena.", "longDescription": "NetLogo is a multi-agent programmable modeling environment used for simulating natural and social phenomena. It is widely used in education, research, and industry to create complex models with ease. Explore NetLogo's features, download the software, and access extensive documentation and resources to get started with agent-based modeling.", @@ -18,4 +18,4 @@ "Programming", "Agent-based Modeling" ] -} \ No newline at end of file +} diff --git a/apps/netlogo/app/pages/index.vue b/apps/netlogo/app/pages/index.vue index 3b5c9974..007c6332 100644 --- a/apps/netlogo/app/pages/index.vue +++ b/apps/netlogo/app/pages/index.vue @@ -1,6 +1,6 @@ diff --git a/apps/netlogo/public/favicon.ico b/apps/netlogo/public/favicon.ico index 18993ad91cfd43e03b074dd0b5cc3f37ab38e49c..2fc954256b4393bfd1482958d13da0b1c0fb1270 100644 GIT binary patch literal 15086 zcmd5@du$xXdH;r__KWS~u*qzz!?@kg5=vC|}Vi`Yn8 zr;QsoRNAI38l(xD0CiHdKnfHo(iUkQB!wGAJn|$_wq?3<-I;H`84?Mqr~B_G;KTH9cM`pohz=ii^D&|<%3{D= z|9At@UxDB*(13*=1#o#SkC4RpbrQ9(?w|H`)a8lt5|z#J$h<^3`r8tO7xMn(%OXce&db+fiD%Y0Mmn+fbcxf+Dj;q%4>IFtp>VtHmn)BySrf4*!QrZ&*Q4|jo+u=2LCqtFDK>~%y}}d8TS{Lg85palEY+fy!2b4g zk5kJ_e@}F(MX#wj4U=9kt0Hwr%D3yN`@)}6(~CPqLjxq9Zv(GmMkIZt&#~9mhVGN3}|0>b&Z;*%{2cKDQpkG=(6{2sO>!a3} z-$(S_`T&pLz(8?y2JerV`yR#47e(DL>>sqz2H^A*(XluE`t5JO&IHhoLc|%zY(o(Ah(hYsw}ry%q26P3YW& zu6KspP+pd90LHE-HzHC~MXEocYVY* z9FC)}g5%)pDJO8Ek$Pq(gpswVaYVD9$AaIdA$H&+KoKIkQ1Mu)pOD+l%*~?RG#&oVkVkKNEewRi8bSl>K4M zJ-xFZr1*tf?!3V|dG7cDaPRG9!uFookK)~V4PcSEU{P$|qNZ~eiBl{K?cgy`FwF1h zQOv7oLzxF%6xB-+g&-SjK>vT4l9L4?zdO}unO*4l4B-}zX{m}^i2k1J^Wb`SQ|>75>+J>P67Je9BU&p`+4Zz zC1bHj9kUiSyn=pXee%8KclN7jW7sEy66iK^zYAC=^R*%wI~JuZOBe;#v zEYWhwqWTvh+iS;b81LVf{pVU(t>q3m^!Ltup3G|-WNt&(ElZ^G7A4j({@3vhj!9jD zGFxcFALCnaeF4^jG3%N6G?{ZNWURq<*lbvUqLjn-vn-Kv+aTMqVNrb9qV}96>QB4l zF}w)bj|At6Dq4}6Xs4blUm$a7PmXs=>BYD!ok{46E!grst~-r)HuL*}Fvq-kvWd(q zPg2hU#tiM2cEfflgWG}khx?!VLdxR4VZd0V@J=x#*U*j`iw>}_acUCp={stgSB)D3 zWNh6ev$#v91v`L^TY%kN=-h)ov}+srtzAlP>{9H;F11Zv#h846%z~}22`$uXx^<`(zyk9xG%yMaI z|L5Qz7pQ^PH};j%yheY+Ti?9)dWmwv+;Y1f{qdjZk33|3$yw_wuy|sCc;Cp6*9OaET!WB=Ioi&;dwCZNSzt{8ZqLWwc`% z?O3A5vwwrWK{NDA;bbKQZ=f*S`nm{fXz>+dLkk`v&?Bdo8CO zSl=?wdTT@cW+(M-+)d{0&%^HqFxFuMc?X1xDZcS@)H(I$+s&!oo5TAPW9|{`39k!d z2V>0pDvNPZq>4P|fLldM?E>vhXKVR3&?rWL4T6 zB7^W+<=09d(pZ`e*-)!|onB8zDk?1ul~j;Wp(-TA%kF~(yw!76PwALcJ$?0*USrE8 zLZU+1a$KSEQm)dH3M{uJ4)G%Ev3Loc#xJzx1COF+oCgQ<~ydjMwaZ zJ>yk7FC-qwgO_OLh>QDIX@K+nGjs$v-IS(&;G@{dbuq?iRueEk^%2<4A93sfUO~N` z@3PqoX7%hH`?%gt%e=7D16)pa`iR5>>3(3CL0!Nz^iu@gcADC8{fg|PE+%T=Je(rg z4mg$)L%E~BM$GrL4g($nRDDm&A3kt}AK{O^tn%~BrnBnluoTXR>%)1;;}&{#ULs0j zxD3S3e_d3NC`z8j6C_qSX7bzZG(;1mC1ss1Pu8gdm(WGJbd|1zLu^`ymef=d{}upwmrZb z$hZvJSaL~#B#(_;rn#7C z8~qw$4!`JEy8@IPRl#Fx%)Eo*7nj^~Z0sY`3)ug?&3P{!!Z4d}kP@WfzWF3|j1Q3* zJ^>r<&gaFMUKMoGkk$wE`Wa67IoHI4R}Udhd70`tZaak7!q7iCF@fN@ zsyKvuS3SAMuy@AZ9A|(r#6u1su0z}pCqOJ?TqiLW$w1@73UwQtv%1exa(0uNC)B<= zk60J>^r!uA>(G@JoaKIk%&V)|L%Zj29GAg)TWrydEg()QWMBN3W4~hs|CX4*1u|wg z|0iTFZ(zR+S=-M3UdDJ{+@!jbe<K_mr=q_sk>o=A@Lgv;v?Af!}^8)gKZNPe#x)-z5a_OvSdgWo9MIyenK92ZG zR)H`S{f^7Cl|^4Tys;ZuYMmTM{0no#aeUkQO&#koc6_^(mZiJz5J zx2txIB}>9LaM`@Ck789F@5ImpJ#pT$1MbEae#*WV?ON%zgrME#}2E z=9eLcJ;c^=??eB#Trq3}1INfx)8BBO)iE%!IGX#0(OUB;? z&v8SzAHwHaKY~o3+e`H=B%%K}weUHBjN9Vu=j0awILiw@9*7bZ91EPP>>yT=P3*tQ6#3jrLi@_;BAyoLYr`oIl}Sj#Ln# znHME~_}+>!`w{B7c0-se?p(WLi8#`2(@GxOu!OPwq~m`u-*rQni~owdDm$3d^6q_w zJmRK#>bR1prm?G3cLw)4)V-RJ4V*Qur-yw5x0kL<)D*d|~h+|svenkRy$omy? z?U_d(ydVBcBPCbgg4pNh5Knv>e1Kbk9TzsAro{5oxF_*3%!$q1%#e0xJxDD+O2+y$ z~ITHgF|aLj9G4&in01j+CzqQ$|Q!C8bWLrvtL0GKv`3O{$V8>WXC= zqn515vcJl(bS|2LMMH?5|q3{nudn3ov~VOh>^)&oo)|w)z6a1P*P*Dxxf_ zh`5BGyC5J2I1CW-7m0EY<|b*j|05~Y$}hNH)|KxKN3=`i>fxL(LuP^kBmsUrHYefy z!nbKTeF%5S(F`n2$^cik!=xB-HsK~E;vb%8+sD2@2TtPe0gjp8T@{w2XeEX(({lEg zan6)dqGd7PY3iJK7VG>X)}}uoF&g8xIR6wSu)sZ#uJeCJ^+Vql;(vUfn)e-v$>*qH z1nV^KCDWK2<=-WM$2EY(V1Gu5><_5!^g4;mSJ)>OowMEW#gB^Q${OyU!T&ywd&Q@& zVSRe9cOC{2Qi`$sx47@ONb$8L>X@6NhOF344WyrGF}wFeRXU{BAms`6VImdm!)j1M@p%Rs(fj{8juN$`X8{b0pF@ z3mvq|0AbEwLIsRjAQvNxhcSipwE!YB{FMP{53Hte@x* Zpq;(BCIGBsn7IOY3~w;9M_o{S{|BJ4?Oy-@ literal 4286 zcmeHLOKuuL5PjK%MHWVi6lD zOGiREbCw`xmFozJ^aNatJY>w+g ze6a2@u~m#^BZm@8wco9#Crlli0uLb^3E$t2-WIc^#(?t)*@`UpuofJ(Uyh@F>b3Ph z$D^m8Xq~pTkGJ4Q`Q2)te3mgkWYZ^Ijq|hkiP^9`De={bQQ%heZC$QU2UpP(-tbl8 zPWD2abEew;oat@w`uP3J^YpsgT%~jT(Dk%oU}sa$7|n6hBjDj`+I;RX(>)%lm_7N{+B7Mu%H?422lE%MBJH!!YTN2oT7xr>>N-8OF$C&qU^ z>vLsa{$0X%q1fjOe3P1mCv#lN{xQ4_*HCSAZjTb1`}mlc+9rl8$B3OP%VT@mch_~G z7Y+4b{r>9e=M+7vSI;BgB?ryZDY4m>&wcHSn81VH1N~`0gvwH{ z8dv#hG|OK`>1;j7tM#B)Z7zDN?{6=dUal}$e + + + + + + + + + From 6a498e9bb8f32426b42882bc0602ce118cbdec52 Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Sat, 17 Jan 2026 13:24:59 -0600 Subject: [PATCH 08/21] Implement Directus navigations on to navbar --- apps/netlogo/.env | 2 + apps/netlogo/.env.development | 2 + apps/netlogo/app/components/ClientNavbar.vue | 37 +- apps/netlogo/app/composables/useNavigation.ts | 91 ++++ apps/netlogo/app/utils/api.ts | 369 +++++++++++++++ apps/netlogo/app/utils/queries.ts | 299 +++++++++++++ apps/netlogo/nuxt.config.ts | 5 + apps/netlogo/package.json | 34 +- yarn.lock | 421 +++++++++++++++--- 9 files changed, 1177 insertions(+), 83 deletions(-) create mode 100644 apps/netlogo/app/composables/useNavigation.ts create mode 100644 apps/netlogo/app/utils/api.ts create mode 100644 apps/netlogo/app/utils/queries.ts diff --git a/apps/netlogo/.env b/apps/netlogo/.env index b7a62211..1cd8400f 100644 --- a/apps/netlogo/.env +++ b/apps/netlogo/.env @@ -3,6 +3,8 @@ PROJECT_ROOT="." PRODUCT_NAME="NetLogo" PRODUCT_WEBSITE="https://www.netlogo.org" +PUBLIC_BACKEND_URL="https://backend.netlogo.org" + REPO_ROOT=../.. EXTENSIONS_DIR="$REPO_ROOT/external/extensions" diff --git a/apps/netlogo/.env.development b/apps/netlogo/.env.development index e26ed85f..a8202e21 100644 --- a/apps/netlogo/.env.development +++ b/apps/netlogo/.env.development @@ -7,5 +7,7 @@ PROJECT_ROOT="." PRODUCT_NAME="NetLogo" PRODUCT_WEBSITE="https://learn.netlogo.org" +PUBLIC_BACKEND_URL="https://backend.netlogo.org" + REPO_ROOT=../.. EXTENSIONS_DIR="$REPO_ROOT/external/extensions" diff --git a/apps/netlogo/app/components/ClientNavbar.vue b/apps/netlogo/app/components/ClientNavbar.vue index 3be3e596..d969e3e2 100644 --- a/apps/netlogo/app/components/ClientNavbar.vue +++ b/apps/netlogo/app/components/ClientNavbar.vue @@ -38,14 +38,7 @@ import type { Navbar as _Navbar } from "@repo/vue-ui/components/navbar/index"; import { useMediaQuery } from "@vueuse/core"; import { onMounted, ref, watch } from "vue"; import { WebsiteLogo } from "~/assets/website-logo"; - -interface NavbarLink { - title: string; - href: string; - columns?: number; - children?: Array>; - active?: boolean; -} +import { useNavigation, type NavbarLink } from "~/composables/useNavigation"; const route = useRoute(); @@ -72,13 +65,19 @@ const handleMediaQueryChange = (): void => { } }; -const navbarLinks = ref>([ +// Use the navigation composable to fetch from Directus +const { navbarLinks: apiNavbarLinks, fetchNavigation, isLoading } = useNavigation(); + +// Default fallback navigation (shown while loading or on error) +const defaultNavbarLinks: NavbarLink[] = [ { title: "Home", href: "/", - columns: 2, }, -]); +]; + +// Reactive navbar links that update once API data is loaded +const navbarLinks = ref(defaultNavbarLinks); const updateActiveStates = () => { navbarRef.value?.blur(); @@ -120,10 +119,22 @@ const isLinkParentActive = (link: NavbarLink, currentPath: string): boolean => { ); }; -updateActiveStates(); +// Watch for API data to load and update navbarLinks +watch( + apiNavbarLinks, + (newLinks) => { + if (newLinks.length > 0) { + navbarLinks.value = newLinks; + updateActiveStates(); + } + }, + { immediate: true }, +); -onMounted(() => { +onMounted(async () => { if (import.meta.client) { + // Fetch navigation data from Directus + await fetchNavigation(); updateActiveStates(); handleMediaQueryChange(); } diff --git a/apps/netlogo/app/composables/useNavigation.ts b/apps/netlogo/app/composables/useNavigation.ts new file mode 100644 index 00000000..ab671647 --- /dev/null +++ b/apps/netlogo/app/composables/useNavigation.ts @@ -0,0 +1,91 @@ +import { computed, ref } from "vue"; +import NetLogoAPI, { type NavigationSection } from "~/utils/api"; + +export interface NavbarLink { + title: string; + href: string; + columns?: number; + children?: Array>; + active?: boolean; +} + +/** + * Composable to fetch and manage navigation data from the Directus backend + */ +export function useNavigation() { + const config = useRuntimeConfig(); + const navigationSections = ref([]); + const isLoading = ref(true); + const error = ref(null); + + /** + * Transform API navigation sections into NavbarLink format + */ + const navbarLinks = computed(() => { + return navigationSections.value.map((section) => { + const children = section.items + .filter((item) => item.url !== section.items[0]?.url) // Exclude first item if it's the parent link + .map((item) => ({ + title: item.display_title, + href: item.url, + active: false, + })); + + return { + title: section.name, + href: section.items[0]?.url || "/", + columns: children.length > 6 ? 2 : undefined, + children: children.length > 0 ? children : undefined, + active: false, + }; + }); + }); + + /** + * Get footer navigation items (items with in_footer = true) + */ + const footerLinks = computed(() => { + const links: Array<{ title: string; href: string }> = []; + navigationSections.value.forEach((section) => { + section.items + .filter((item) => item.in_footer) + .forEach((item) => { + links.push({ + title: item.display_title, + href: item.url, + }); + }); + }); + return links; + }); + + /** + * Fetch navigation data from the Directus backend + */ + async function fetchNavigation() { + isLoading.value = true; + error.value = null; + + try { + const api = new NetLogoAPI(config.public.backendUrl as string); + const data = await api.getNavigationData(); + navigationSections.value = data.navigation_sections; + } catch (e) { + console.error("Failed to fetch navigation data:", e); + error.value = e instanceof Error ? e : new Error("Unknown error"); + // Fallback to default navigation + navigationSections.value = []; + } finally { + isLoading.value = false; + } + } + + return { + navigationSections, + navbarLinks, + footerLinks, + isLoading, + error, + fetchNavigation, + }; +} diff --git a/apps/netlogo/app/utils/api.ts b/apps/netlogo/app/utils/api.ts new file mode 100644 index 00000000..6ce3519b --- /dev/null +++ b/apps/netlogo/app/utils/api.ts @@ -0,0 +1,369 @@ +import { GraphQLClient } from "graphql-request"; +// import { type FormData } from "../components/download/download-form"; +// import { type AnnouncementObj } from "../components/layout/announcement"; +import queries from "./queries"; + +// Types for the API responses +interface ApiResponse { + data: T; +} + +interface Image { + id: string; +} + +export interface Introduction { + id: string; + title: string; + description: string; +} + +export interface IntroSplashEntry { + id: string; + title: string; + description: string; + demo_image: Image; + learn_more_link: string; + featured_items: FeaturedItem[]; +} + +export interface FeaturedItem { + id: string; + type: number; + image: Image; + image_description: string; + word_column_title: string; + column_words: ColumnWord[]; + image_column_title: string; + column_images: ColumnImage[]; +} + +export interface ColumnWord { + word: string; + url: string; +} + +export interface ColumnImage { + image: Image; + word: string; +} + +export interface WhyNetLogoEntry { + title: string; + content: string; + icon: Image; + order: number; +} + +export interface GetNetLogoEntry { + id: string; + title: string; + content: string; + icon: Image; + link: string; + order: number; + button_text: string; +} + +export interface CommunityEntry { + id: string; + title: string; + description: string; + icon: Image; + link: string; + order: number; + bordered: boolean; +} + +export interface PartnerEntry { + id: string; + partner_name: string; + partner_image: Image; +} + +export interface NavigationSection { + name: string; + items: NavigationItem[]; +} + +export interface NavigationItem { + display_title: string; + url: string; + in_footer: boolean; +} + +export interface ContactItem { + heading: string; + body: string; +} + +export interface AnnouncementEntry { + id: number; + title: string; + date: string; + content: string; +} + +export interface NewsEntry { + id: number; + title: string; + date: string; + body: string; +} + +export interface AboutEntry { + body: string; +} + +export interface EducatorsEntry { + body: string; +} + +export interface CampaignEntry { + body: string; +} + +export interface NetlogoCon2026Entry { + body: string; +} + +export interface ReferenceEntry { + year: number; + reference: string; + is_ccl: boolean; + //in_press: boolean; +} + +export interface GroupedReference { + year: number; + references: string[]; +} + +export interface AllData { + introduction: Introduction; + intro_splash: IntroSplashEntry[]; + why_netlogo: WhyNetLogoEntry[]; + get_netlogo: GetNetLogoEntry[]; + community: CommunityEntry[]; + featured_partners: PartnerEntry[]; + // announcement: AnnouncementObj; +} + +export interface PlatformIcon { + icon: Image; +} + +export interface DownloadLink { + platform: string; + download_url: string; + primary: boolean; + subplatform: string; + platform_icon: PlatformIcon; +} + +export interface NetLogoVersion { + version: string; + download_links: DownloadLink[]; +} + +export interface DonationData { + title: string; + text: string; + image: Image; + url: string; +} + +export interface DownloadPageData { + netlogo_versions: NetLogoVersion[]; + donation_data: DonationData[]; +} + +export interface PageEntry { + section_title: string; + section_content: string; +} + +class NetLogoAPI { + private readonly baseUrl: string; + private client: GraphQLClient; + + constructor(baseUrl: string = import.meta.env.PUBLIC_BACKEND_URL) { + this.baseUrl = baseUrl; + this.client = new GraphQLClient(this.baseUrl + "/graphql"); + } + + async fetchData(endpoint: string): Promise { + try { + const url = `${this.baseUrl}${endpoint}`; + const response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data: ApiResponse = await response.json(); + return data.data; + } catch (error) { + console.error(`Error fetching ${endpoint}:`, error); + throw error; + } + } + + async graphqlFetchData(query: string): Promise { + try { + const data = await this.client.request(query); + return data; + } catch (error) { + console.error("GraphQL query error:", error); + throw error; + } + } + + async getMainPageData() { + return await this.graphqlFetchData(queries.mainPageData); + } + + async getDownloadPageData() { + return await this.graphqlFetchData(queries.downloadPageData); + } + + async getDonationData() { + const donationData = await this.graphqlFetchData<{ + donation_data: DonationData[]; + }>(queries.donationData); + + return donationData.donation_data; + } + + async getNetLogoVersions() { + return await this.graphqlFetchData(queries.netLogoVersions); + } + + async getContact() { + const dict = await this.graphqlFetchData<{ contact_data: ContactItem[] }>(queries.contacts); + return dict.contact_data; + } + + async getAnnouncements() { + const result = await this.graphqlFetchData<{ announcements: AnnouncementEntry[] }>( + queries.mainAnnouncements, + ); + return result.announcements; + } + + async getNews() { + const result = await this.graphqlFetchData<{ official_news: NewsEntry[] }>( + queries.officialNews, + ); + return result.official_news; + } + + async getAboutContent() { + const dict = await this.graphqlFetchData<{ about: AboutEntry }>(queries.aboutContent); + return dict.about; + } + + async getEducatorsContent() { + const dict = await this.graphqlFetchData<{ educators: EducatorsEntry }>( + queries.educatorsContent, + ); + return dict.educators; + } + + async getCampaignContent() { + const dict = await this.graphqlFetchData<{ campaign: CampaignEntry }>(queries.campaignContent); + return dict.campaign; + } + + async getNetLogoCon2026Content() { + const dict = await this.graphqlFetchData<{ netlogo_con_2026: NetlogoCon2026Entry }>( + queries.netlogoCon2026Content, + ); + return dict.netlogo_con_2026; + } + + async getReferences() { + const references: { References: ReferenceEntry[] } = await this.graphqlFetchData<{ + References: ReferenceEntry[]; + }>(queries.referenceData); + + // ***new fix stores is ccl and the refrence not jsut ref + let groupedReferences: Map = new Map(); + + //let groupedReferences: Map = new Map(); + + // Loop through the references and group them by year + references["References"].forEach((item) => { + const year = item.year; // Convert year to string for the key + + // Check if the year already exists in the map + if (!groupedReferences.has(year)) { + // If not, create a new entry with an empty array + groupedReferences.set(year, []); + } + //data is not consistent + //indexing data that i cant work with it + //how did i organize data from directus + //The issue is inconsistent data indexing or formatting when calling the getReferences() method and attempting to process or display the data. The line: + //suggests that your grouped data may not be properly returned, consumed, or structured. + + // add some console log stmts in the api and make sure it get the data how you expect the go to typesript file + + // Push the reference into the array for that year + //groupedReferences.get(year)?.push(item.reference); + + //***new fix 2: ensure that each reference is stored with the text and the is_ccl field proper rendering + + groupedReferences.get(year)?.push({ + reference: item.reference, + is_ccl: item.is_ccl, + }); + }); + // *** new fix 3: return in coreect strucure + //console.log('Grouped References:', groupedReferences); + //return groupedReferences; + + // *** new fix 4: make sure the data is formatted into the array shape your frontend expects + const groupedArray = Array.from(groupedReferences.entries()).map(([year, refs]) => ({ + year, + references: refs, + })); + + //console.log('Grouped References:', groupedArray); + + // sort the array by year in descending order + groupedArray.sort((a, b) => b.year - a.year); + + return groupedArray; + + //return references['References'] + } + + async getNavigationData() { + return await this.graphqlFetchData<{ + navigation_sections: NavigationSection[]; + }>(queries.navigationData); + } + + async getResourcesData() { + const resourcesData = await this.graphqlFetchData<{ + resources: PageEntry[]; + }>(queries.resourcesData); + + return resourcesData.resources; + } + + // async sendDownloadForm(formData: FormData) { + // const url = this.baseUrl + "/items/download_responses"; + + // const response = await fetch(url, { + // method: "POST", + // headers: { + // "Content-Type": "application/json", + // }, + // body: JSON.stringify(formData), + // }); + + // return response; + // } +} + +export default NetLogoAPI; diff --git a/apps/netlogo/app/utils/queries.ts b/apps/netlogo/app/utils/queries.ts new file mode 100644 index 00000000..1ea9d869 --- /dev/null +++ b/apps/netlogo/app/utils/queries.ts @@ -0,0 +1,299 @@ +import { gql } from "graphql-request"; + +const queries = { + introduction: gql` + query { + introduction { + title + description + } + } + `, + + introSplash: gql` + query GetIntroSplash { + intro_splash { + title + description + learn_more_link + demo_image { + id + } + featured_items { + id + image { + id + } + type + image_description + column_title + column_words { + word + url + } + } + } + } + `, + + whyNetLogo: gql` + query GetWhyNetLogo { + why_netlogo { + id + title + content + icon + order + } + } + `, + + getNetLogo: gql` + query GetGetNetLogo { + get_netlogo { + id + title + content + icon + link + order + } + } + `, + + community: gql` + query GetCommunity { + community { + id + Title + Description + Icon + Link + order + Bordered + } + } + `, + + partners: gql` + query GetPartners { + featured_partners { + id + partner_name + partner_image + } + } + `, + + contacts: gql` + query getContacts { + contact_data { + heading + body + } + } + `, + + mainAnnouncements: gql` + query getAnnouncements { + announcements(sort: ["-date"]) { + title + date + content + } + } + `, + + officialNews: gql` + query getNews { + official_news(sort: ["-date"]) { + id + title + date + body + } + } + `, + + referenceData: gql` + query getReferences { + References(limit: -1) { + year + reference + is_ccl + } + } + `, + + navigationData: gql` + query GetNavigation { + navigation_sections { + name + items { + display_title + url + in_footer + } + } + } + `, + + aboutContent: gql` + query getAbout { + about { + body + } + } + `, + + educatorsContent: gql` + query getEducators { + educators { + body + } + } + `, + + campaignContent: gql` + query getCampaign { + campaign { + body + } + } + `, + + netlogoCon2026Content: gql` + query getNetlogoCon2026 { + netlogo_con_2026 { + body + } + } + `, + + netLogoVersions: gql` + query GetNetLogoVersions { + netlogo_versions { + version + download_links { + platform + download_url + } + } + } + `, + + resourcesData: gql` + query GetResources { + resources { + section_title + section_content + } + } + `, + + mainPageData: gql` + query GetAllData { + introduction { + title + description + } + intro_splash { + title + + description + learn_more_link + featured_items { + id + type + image { + id + } + image_description + word_column_title + column_words { + word + url + } + image_column_title + column_images { + image { + id + } + word + } + } + } + why_netlogo { + title + content + icon { + id + } + } + get_netlogo { + title + content + icon { + id + } + link + button_text + } + community { + title + description + icon { + id + } + link + } + featured_partners { + partner_name + partner_image { + id + } + } + } + `, + + downloadPageData: gql` + query GetDownloadPageData { + netlogo_versions { + version + download_links { + platform + download_url + primary + subplatform + platform_icon { + icon { + id + } + } + } + } + donation_data { + title + text + image { + id + } + url + } + } + `, + donationData: gql` + query GetDonationData { + donation_data { + title + text + image { + id + } + url + } + } + `, +}; + +export default queries; diff --git a/apps/netlogo/nuxt.config.ts b/apps/netlogo/nuxt.config.ts index ad60b465..cd69a855 100644 --- a/apps/netlogo/nuxt.config.ts +++ b/apps/netlogo/nuxt.config.ts @@ -7,5 +7,10 @@ export default defineNuxtConfig( enabled: true, }, ssr: true, + runtimeConfig: { + public: { + backendUrl: process.env.PUBLIC_BACKEND_URL || "https://backend.netlogo.org", + }, + }, }), ); diff --git a/apps/netlogo/package.json b/apps/netlogo/package.json index 36b659f1..3e17cb7d 100644 --- a/apps/netlogo/package.json +++ b/apps/netlogo/package.json @@ -25,18 +25,6 @@ "turbo:postinstall": "nuxt prepare" }, "dependencies": { - "nuxt": "^4.1.2", - "nuxt-gtag": "4.1.0", - "nuxt-link-checker": "4.3.6", - "nuxt-og-image": "^5.1.12", - "nuxt-svgo": "4.2.6", - "radix-vue": "1.9.17", - "reka-ui": "^2.6.0", - "tailwind-merge": "^3.3.1", - "tailwindcss": "^4.1.18", - "tw-animate-css": "^1.4.0", - "vue": "^3.5.24", - "vue-router": "^4.6.3", "@nuxt/content": "^3.7.1", "@nuxt/eslint": "1.10.0", "@nuxt/fonts": "0.12.1", @@ -49,20 +37,34 @@ "@repo/markdown": "0.0.0", "@repo/netlogo-docs": "0.0.0", "@repo/nuxt-content-assets": "1.5.0", + "@repo/nuxt-core": "0.0.0", "@repo/tailwind-config": "0.0.0", "@repo/template": "0.0.0", "@repo/typescript-config": "0.0.0", "@repo/utils": "0.0.0", "@repo/vue-ui": "1.0.0", - "@repo/nuxt-core": "0.0.0" + "graphql": "^16.10.0", + "graphql-request": "^7.1.2", + "nuxt": "^4.1.2", + "nuxt-gtag": "4.1.0", + "nuxt-link-checker": "4.3.6", + "nuxt-og-image": "^5.1.12", + "nuxt-svgo": "4.2.6", + "radix-vue": "1.9.17", + "reka-ui": "^2.6.0", + "tailwind-merge": "^3.3.1", + "tailwindcss": "^4.1.18", + "tw-animate-css": "^1.4.0", + "vue": "^3.5.24", + "vue-router": "^4.6.3" }, "devDependencies": { "@nuxt/kit": "^4.2.1", "@repo/nuxt-content-assets": "1.5.0", + "eslint": "^9.31.0", + "sass": "^1.93.3", "turbo-meta-utilities": "^1.0.1", "typescript": "^5.4.0", - "zod": "^4.1.12", - "sass": "^1.93.3", - "eslint": "^9.31.0" + "zod": "^4.1.12" } } diff --git a/yarn.lock b/yarn.lock index 243adb48..30092aa6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1167,11 +1167,23 @@ dependencies: eslint-visitor-keys "^3.4.3" +"@eslint-community/eslint-utils@^4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" + integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== + dependencies: + eslint-visitor-keys "^3.4.3" + "@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.11.0", "@eslint-community/regexpp@^4.12.1", "@eslint-community/regexpp@^4.8.0": version "4.12.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== +"@eslint-community/regexpp@^4.12.2", "@eslint-community/regexpp@^4.5.1": + version "4.12.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== + "@eslint/compat@^1.2.5": version "1.4.0" resolved "https://registry.yarnpkg.com/@eslint/compat/-/compat-1.4.0.tgz#6d6b2f198ddfecda3d4cbd5a6e9324fca54f2dfb" @@ -1330,6 +1342,11 @@ "@floating-ui/utils" "^0.2.10" vue-demi ">=0.13.0" +"@graphql-typed-document-node/core@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" + integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== + "@humanfs/core@^0.19.1": version "0.19.1" resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" @@ -2209,7 +2226,7 @@ ufo "^1.6.1" youch "^4.1.0-beta.11" -"@nuxt/content@3.7.1", "@nuxt/content@^3.7.1": +"@nuxt/content@^3.7.1": version "3.7.1" resolved "https://registry.yarnpkg.com/@nuxt/content/-/content-3.7.1.tgz#0b1e61a5ffb37c24033f7ab257811d3d5c8c7062" integrity sha512-QjUyxvC3IhLca9gZuGGZslL+L2PkxFwiPD/fbXN1X0EuUfbe17H/AMt53ZRezWrxs6MOaLbyWLHzcllcjEB/jQ== @@ -4759,7 +4776,7 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/json-schema@^7.0.15": +"@types/json-schema@^7.0.12", "@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -4847,6 +4864,11 @@ resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== +"@types/semver@^7.5.0": + version "7.7.1" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.1.tgz#3ce3af1a5524ef327d2da9e4fd8b6d95c8d70528" + integrity sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA== + "@types/stack-utils@^2.0.0": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" @@ -4867,6 +4889,11 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4" integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== +"@types/web-bluetooth@^0.0.20": + version "0.0.20" + resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597" + integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow== + "@types/web-bluetooth@^0.0.21": version "0.0.21" resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz#525433c784aed9b457aaa0ee3d92aeb71f346b63" @@ -4898,7 +4925,38 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@8.45.0", "@typescript-eslint/eslint-plugin@^6.5.0", "@typescript-eslint/eslint-plugin@^8.45.0", "@typescript-eslint/eslint-plugin@^8.46.2": +"@typescript-eslint/eslint-plugin@8.53.0", "@typescript-eslint/eslint-plugin@^8.46.2": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.0.tgz#afb966c66a2fdc6158cf81118204a971a36d0fc5" + integrity sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg== + dependencies: + "@eslint-community/regexpp" "^4.12.2" + "@typescript-eslint/scope-manager" "8.53.0" + "@typescript-eslint/type-utils" "8.53.0" + "@typescript-eslint/utils" "8.53.0" + "@typescript-eslint/visitor-keys" "8.53.0" + ignore "^7.0.5" + natural-compare "^1.4.0" + ts-api-utils "^2.4.0" + +"@typescript-eslint/eslint-plugin@^6.5.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" + integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/type-utils" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/eslint-plugin@^8.45.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.45.0.tgz#9f251d4e85ec5089e7cccb09257ce93dbf0d7744" integrity sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg== @@ -4913,15 +4971,26 @@ natural-compare "^1.4.0" ts-api-utils "^2.1.0" -"@typescript-eslint/parser@8.45.0", "@typescript-eslint/parser@^6.5.0", "@typescript-eslint/parser@^8.46.2": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.45.0.tgz#571660c98824aefb4a6ec3b3766655d1348520a4" - integrity sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ== +"@typescript-eslint/parser@8.53.0", "@typescript-eslint/parser@^8.46.2": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.53.0.tgz#d8bed6f12dc74e03751e5f947510ff2b165990c6" + integrity sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg== dependencies: - "@typescript-eslint/scope-manager" "8.45.0" - "@typescript-eslint/types" "8.45.0" - "@typescript-eslint/typescript-estree" "8.45.0" - "@typescript-eslint/visitor-keys" "8.45.0" + "@typescript-eslint/scope-manager" "8.53.0" + "@typescript-eslint/types" "8.53.0" + "@typescript-eslint/typescript-estree" "8.53.0" + "@typescript-eslint/visitor-keys" "8.53.0" + debug "^4.4.3" + +"@typescript-eslint/parser@^6.5.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" + integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== + dependencies: + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" "@typescript-eslint/project-service@8.45.0": @@ -4933,6 +5002,23 @@ "@typescript-eslint/types" "^8.45.0" debug "^4.3.4" +"@typescript-eslint/project-service@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.53.0.tgz#327c67c61c16a1c8b12a440b0779b41eb77cc7df" + integrity sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg== + dependencies: + "@typescript-eslint/tsconfig-utils" "^8.53.0" + "@typescript-eslint/types" "^8.53.0" + debug "^4.4.3" + +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/scope-manager@8.45.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz#59615ba506a9e3479d1efb0d09d6ab52f2a19142" @@ -4941,16 +5027,39 @@ "@typescript-eslint/types" "8.45.0" "@typescript-eslint/visitor-keys" "8.45.0" +"@typescript-eslint/scope-manager@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.53.0.tgz#f922fcbf0d42e72f065297af31779ccf19de9a97" + integrity sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g== + dependencies: + "@typescript-eslint/types" "8.53.0" + "@typescript-eslint/visitor-keys" "8.53.0" + "@typescript-eslint/tsconfig-utils@8.45.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz#63d38282790a2566c571bad423e7c1cad1f3d64c" integrity sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w== +"@typescript-eslint/tsconfig-utils@8.53.0", "@typescript-eslint/tsconfig-utils@^8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.0.tgz#105279d7969a7abdc8345cc9c57cff83cf910f8f" + integrity sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA== + "@typescript-eslint/tsconfig-utils@^8.45.0": version "8.50.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.1.tgz#ee4894bec14ef13db305d0323b14b109d996f116" integrity sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw== +"@typescript-eslint/type-utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" + integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== + dependencies: + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/type-utils@8.45.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.45.0.tgz#04004bdf2598844faa29fb936fb6b0ee10d6d3f3" @@ -4962,11 +5071,46 @@ debug "^4.3.4" ts-api-utils "^2.1.0" -"@typescript-eslint/types@8.45.0", "@typescript-eslint/types@^8.34.0", "@typescript-eslint/types@^8.35.0", "@typescript-eslint/types@^8.38.0", "@typescript-eslint/types@^8.45.0", "@typescript-eslint/types@^8.46.0", "@typescript-eslint/types@^8.46.2", "@typescript-eslint/types@^8.47.0": +"@typescript-eslint/type-utils@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.53.0.tgz#81a0de5c01fc68f6df0591d03cd8226bda01c91f" + integrity sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw== + dependencies: + "@typescript-eslint/types" "8.53.0" + "@typescript-eslint/typescript-estree" "8.53.0" + "@typescript-eslint/utils" "8.53.0" + debug "^4.4.3" + ts-api-utils "^2.4.0" + +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== + +"@typescript-eslint/types@8.45.0", "@typescript-eslint/types@^8.34.0", "@typescript-eslint/types@^8.35.0", "@typescript-eslint/types@^8.38.0", "@typescript-eslint/types@^8.45.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.45.0.tgz#fc01cd2a4690b9713b02f895e82fb43f7d960684" integrity sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA== +"@typescript-eslint/types@8.53.0", "@typescript-eslint/types@^8.46.0", "@typescript-eslint/types@^8.46.2", "@typescript-eslint/types@^8.47.0", "@typescript-eslint/types@^8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.53.0.tgz#1adcad3fa32bc2c4cbf3785ba07a5e3151819efb" + integrity sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ== + +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/typescript-estree@8.45.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz#3498500f109a89b104d2770497c707e56dfe062d" @@ -4983,7 +5127,35 @@ semver "^7.6.0" ts-api-utils "^2.1.0" -"@typescript-eslint/utils@8.45.0", "@typescript-eslint/utils@^8.38.0", "@typescript-eslint/utils@^8.46.2": +"@typescript-eslint/typescript-estree@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.0.tgz#7805b46b7a8ce97e91b7bb56fc8b1ba26ca8ef52" + integrity sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw== + dependencies: + "@typescript-eslint/project-service" "8.53.0" + "@typescript-eslint/tsconfig-utils" "8.53.0" + "@typescript-eslint/types" "8.53.0" + "@typescript-eslint/visitor-keys" "8.53.0" + debug "^4.4.3" + minimatch "^9.0.5" + semver "^7.7.3" + tinyglobby "^0.2.15" + ts-api-utils "^2.4.0" + +"@typescript-eslint/utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" + integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + semver "^7.5.4" + +"@typescript-eslint/utils@8.45.0", "@typescript-eslint/utils@^8.38.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.45.0.tgz#6e68e92d99019fdf56018d0e6664c76a70470c95" integrity sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg== @@ -4993,6 +5165,24 @@ "@typescript-eslint/types" "8.45.0" "@typescript-eslint/typescript-estree" "8.45.0" +"@typescript-eslint/utils@8.53.0", "@typescript-eslint/utils@^8.46.2": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.53.0.tgz#bf0a4e2edaf1afc9abce209fc02f8cab0b74af13" + integrity sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA== + dependencies: + "@eslint-community/eslint-utils" "^4.9.1" + "@typescript-eslint/scope-manager" "8.53.0" + "@typescript-eslint/types" "8.53.0" + "@typescript-eslint/typescript-estree" "8.53.0" + +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== + dependencies: + "@typescript-eslint/types" "6.21.0" + eslint-visitor-keys "^3.4.1" + "@typescript-eslint/visitor-keys@8.45.0": version "8.45.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz#4e3bcc55da64ac61069ebfe62ca240567ac7d784" @@ -5001,6 +5191,14 @@ "@typescript-eslint/types" "8.45.0" eslint-visitor-keys "^4.2.1" +"@typescript-eslint/visitor-keys@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.0.tgz#9a785664ddae7e3f7e570ad8166e48dbc9c6cf02" + integrity sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw== + dependencies: + "@typescript-eslint/types" "8.53.0" + eslint-visitor-keys "^4.2.1" + "@ungap/structured-clone@^1.0.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" @@ -5608,12 +5806,31 @@ "@vue/compiler-ssr" "3.5.24" "@vue/shared" "3.5.24" -"@vue/shared@3.5.22", "@vue/shared@3.5.24", "@vue/shared@3.5.26", "@vue/shared@^3.5.0", "@vue/shared@^3.5.18", "@vue/shared@^3.5.21", "@vue/shared@^3.5.23", "@vue/shared@^3.5.25": +"@vue/shared@3.5.22": + version "3.5.22" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.22.tgz#9d56a1644a3becb8af1e34655928b0e288d827f8" + integrity sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w== + +"@vue/shared@3.5.24", "@vue/shared@^3.5.0", "@vue/shared@^3.5.18", "@vue/shared@^3.5.21", "@vue/shared@^3.5.23": version "3.5.24" resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.24.tgz#45ea9e6e037e53cfb8141ffa6bcad75b8be11e9c" integrity sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A== -"@vueuse/core@13.9.0", "@vueuse/core@14.1.0", "@vueuse/core@^10.11.0", "@vueuse/core@^10.8.0", "@vueuse/core@^12.5.0", "@vueuse/core@^13.9.0", "@vueuse/core@^14.1.0": +"@vue/shared@3.5.26", "@vue/shared@^3.5.25": + version "3.5.26" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.26.tgz#1e02ef2d64aced818cd31d81ce5175711dc90a9f" + integrity sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A== + +"@vueuse/core@13.9.0", "@vueuse/core@^13.9.0": + version "13.9.0" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-13.9.0.tgz#051aeff47a259e9e4d7d0cc3e54879817b0cbcad" + integrity sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA== + dependencies: + "@types/web-bluetooth" "^0.0.21" + "@vueuse/metadata" "13.9.0" + "@vueuse/shared" "13.9.0" + +"@vueuse/core@14.1.0", "@vueuse/core@^14.1.0": version "14.1.0" resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-14.1.0.tgz#274e98e591a505333b7dfb2bcaf7b4530a10b9c9" integrity sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw== @@ -5622,6 +5839,26 @@ "@vueuse/metadata" "14.1.0" "@vueuse/shared" "14.1.0" +"@vueuse/core@^10.11.0", "@vueuse/core@^10.8.0": + version "10.11.1" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.11.1.tgz#15d2c0b6448d2212235b23a7ba29c27173e0c2c6" + integrity sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww== + dependencies: + "@types/web-bluetooth" "^0.0.20" + "@vueuse/metadata" "10.11.1" + "@vueuse/shared" "10.11.1" + vue-demi ">=0.14.8" + +"@vueuse/core@^12.5.0": + version "12.8.2" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-12.8.2.tgz#007c6dd29a7d1f6933e916e7a2f8ef3c3f968eaa" + integrity sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ== + dependencies: + "@types/web-bluetooth" "^0.0.21" + "@vueuse/metadata" "12.8.2" + "@vueuse/shared" "12.8.2" + vue "^3.5.13" + "@vueuse/integrations@^13.9.0": version "13.9.0" resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-13.9.0.tgz#1bd1d77093a327321cca00e2bbf5da7b18aa6b43" @@ -5638,35 +5875,50 @@ "@vueuse/core" "14.1.0" "@vueuse/shared" "14.1.0" -"@vueuse/metadata@14.1.0": - version "14.1.0" - resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-14.1.0.tgz#70fc2e94775e4a07369f11f86f6f0a465b04a381" - integrity sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA== +"@vueuse/metadata@10.11.1": + version "10.11.1" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.11.1.tgz#209db7bb5915aa172a87510b6de2ca01cadbd2a7" + integrity sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw== -"@vueuse/shared@13.9.0": +"@vueuse/metadata@12.8.2": + version "12.8.2" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-12.8.2.tgz#6cb3a4e97cdcf528329eebc1bda73cd7f64318d3" + integrity sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A== + +"@vueuse/metadata@13.9.0": version "13.9.0" - resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-13.9.0.tgz#7168b4ed647e625b05eb4e7e80fe8aabd00e3923" - integrity sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g== + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-13.9.0.tgz#57c738d99661c33347080c0bc4cd11160e0d0881" + integrity sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg== -"@vueuse/shared@14.1.0": +"@vueuse/metadata@14.1.0": version "14.1.0" - resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-14.1.0.tgz#49b2face86a9c0c52e20eaf4c732a0223276c11f" - integrity sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw== + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-14.1.0.tgz#70fc2e94775e4a07369f11f86f6f0a465b04a381" + integrity sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA== -"@vueuse/shared@^10.11.0": +"@vueuse/shared@10.11.1", "@vueuse/shared@^10.11.0": version "10.11.1" resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.11.1.tgz#62b84e3118ae6e1f3ff38f4fbe71b0c5d0f10938" integrity sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA== dependencies: vue-demi ">=0.14.8" -"@vueuse/shared@^12.5.0": +"@vueuse/shared@12.8.2", "@vueuse/shared@^12.5.0": version "12.8.2" resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-12.8.2.tgz#b9e4611d0603629c8e151f982459da394e22f930" integrity sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w== dependencies: vue "^3.5.13" +"@vueuse/shared@13.9.0": + version "13.9.0" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-13.9.0.tgz#7168b4ed647e625b05eb4e7e80fe8aabd00e3923" + integrity sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g== + +"@vueuse/shared@14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-14.1.0.tgz#49b2face86a9c0c52e20eaf4c732a0223276c11f" + integrity sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw== + "@webcontainer/env@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@webcontainer/env/-/env-1.1.1.tgz#23021b2bb24befeeef53dba8996d1886b7016515" @@ -6206,7 +6458,7 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -better-sqlite3@12.4.1, better-sqlite3@^12.4.1: +better-sqlite3@^12.4.1: version "12.4.1" resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.4.1.tgz#f78df6c80530d1a0b750b538033e6199b7d30d26" integrity sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ== @@ -9219,7 +9471,7 @@ globalthis@^1.0.4: define-properties "^1.2.1" gopd "^1.0.1" -globby@^11.0.4: +globby@^11.0.4, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -9296,6 +9548,18 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +graphql-request@^7.1.2: + version "7.4.0" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-7.4.0.tgz#97a1fc871e79f682d816963446ac6b7f99c963f9" + integrity sha512-xfr+zFb/QYbs4l4ty0dltqiXIp07U6sl+tOKAb0t50/EnQek6CVVBLjETXi+FghElytvgaAWtIOt3EV7zLzIAQ== + dependencies: + "@graphql-typed-document-node/core" "^3.2.0" + +graphql@^16.10.0: + version "16.12.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.12.0.tgz#28cc2462435b1ac3fdc6976d030cef83a0c13ac7" + integrity sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ== + gzip-size@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-7.0.0.tgz#9f9644251f15bc78460fccef4055ae5a5562ac60" @@ -10853,16 +11117,11 @@ jsdom@^25.0.0: ws "^8.18.0" xml-name-validator "^5.0.0" -jsesc@^3.0.2, jsesc@^3.1.0: +jsesc@^3.0.2, jsesc@^3.1.0, jsesc@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== -jsesc@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" - integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== - json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -12087,6 +12346,13 @@ minimark@^0.2.0: resolved "https://registry.yarnpkg.com/minimark/-/minimark-0.2.0.tgz#bb18fb25cfaf1c9cceccf1633c07852c17b427f9" integrity sha512-AmtWU9pO0C2/3AM2pikaVhJ//8E5rOpJ7+ioFQfjIq+wCsBeuZoxPd97hBFZ9qrI7DMHZudwGH3r8A7BMnsIew== +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimatch@^10.0.1, minimatch@^10.0.3, "minimatch@^9.0.3 || ^10.0.1": version "10.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" @@ -12115,7 +12381,7 @@ minimatch@^5.0.1, minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.3, minimatch@^9.0.4: +minimatch@^9.0.3, minimatch@^9.0.4, minimatch@^9.0.5: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== @@ -12768,7 +13034,7 @@ nuxt-svgo@4.2.6: mini-svg-data-uri "^1.4.4" svgo "3.0.2" -nuxt@4.1.2, nuxt@^4.1.2: +nuxt@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-4.1.2.tgz#0d3b57a0a6a672ab21b7e3f3f2a0481d50d5902e" integrity sha512-g5mwszCZT4ZeGJm83nxoZvtvZoAEaY65VDdn7p7UgznePbRaEJJ1KS1OIld4FPVkoDZ8TEVuDNqI9gUn12Exvg== @@ -13867,7 +14133,7 @@ prettier-plugin-tailwindcss@^0.6.11: resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.14.tgz#06701a580f7104c034ae3b699dbd17a80d67f0cd" integrity sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg== -prettier@3.6.2, prettier@^3.2.5, prettier@^3.6.2: +prettier@^3.2.5, prettier@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== @@ -14441,12 +14707,12 @@ regexp.prototype.flags@^1.5.3, regexp.prototype.flags@^1.5.4: gopd "^1.2.0" set-function-name "^2.0.2" -regjsparser@^0.12.0, regjsparser@^0.13.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.12.0.tgz#0e846df6c6530586429377de56e0475583b088dc" - integrity sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ== +regjsparser@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.13.0.tgz#01f8351335cf7898d43686bc74d2dd71c847ecc0" + integrity sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q== dependencies: - jsesc "~3.0.2" + jsesc "~3.1.0" rehype-autolink-headings@^7.1.0: version "7.1.0" @@ -14528,7 +14794,39 @@ rehype-sort-attributes@^5.0.1: "@types/hast" "^3.0.0" unist-util-visit "^5.0.0" -reka-ui@2.6.0, reka-ui@2.6.1, reka-ui@^2.0.0, reka-ui@^2.6.0: +reka-ui@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/reka-ui/-/reka-ui-2.6.0.tgz#3b96712744decb9da8f4b1af79d16a499c84b826" + integrity sha512-NrGMKrABD97l890mFS3TNUzB0BLUfbL3hh0NjcJRIUSUljb288bx3Mzo31nOyUcdiiW0HqFGXJwyCBh9cWgb0w== + dependencies: + "@floating-ui/dom" "^1.6.13" + "@floating-ui/vue" "^1.1.6" + "@internationalized/date" "^3.5.0" + "@internationalized/number" "^3.5.0" + "@tanstack/vue-virtual" "^3.12.0" + "@vueuse/core" "^12.5.0" + "@vueuse/shared" "^12.5.0" + aria-hidden "^1.2.4" + defu "^6.1.4" + ohash "^2.0.11" + +reka-ui@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/reka-ui/-/reka-ui-2.6.1.tgz#08f6b8a8ee774887b6bcde3d8ea54b608acfe82c" + integrity sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww== + dependencies: + "@floating-ui/dom" "^1.6.13" + "@floating-ui/vue" "^1.1.6" + "@internationalized/date" "^3.5.0" + "@internationalized/number" "^3.5.0" + "@tanstack/vue-virtual" "^3.12.0" + "@vueuse/core" "^12.5.0" + "@vueuse/shared" "^12.5.0" + aria-hidden "^1.2.4" + defu "^6.1.4" + ohash "^2.0.11" + +reka-ui@^2.0.0, reka-ui@^2.6.0: version "2.7.0" resolved "https://registry.yarnpkg.com/reka-ui/-/reka-ui-2.7.0.tgz#906697e744e9a9682f89372a46ef384d4500eae7" integrity sha512-m+XmxQN2xtFzBP3OAdIafKq7C8OETo2fqfxcIIxYmNN2Ch3r5oAf6yEYCIJg5tL/yJU2mHqF70dCCekUkrAnXA== @@ -15971,7 +16269,12 @@ tailwindcss-animate@^1.0.7: resolved "https://registry.yarnpkg.com/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz#318b692c4c42676cc9e67b19b78775742388bef4" integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA== -tailwindcss@4.1.13, tailwindcss@4.1.18, tailwindcss@^4.1.17, tailwindcss@^4.1.18: +tailwindcss@4.1.13: + version "4.1.13" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.1.13.tgz#ade3471fdfd0a2a86da3a679bfc10c623e645b09" + integrity sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w== + +tailwindcss@4.1.18, tailwindcss@^4.1.17, tailwindcss@^4.1.18: version "4.1.18" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.1.18.tgz#f488ba47853abdb5354daf9679d3e7791fc4f4e3" integrity sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw== @@ -16230,11 +16533,21 @@ trough@^2.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== +ts-api-utils@^1.0.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" + integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== + ts-api-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== +ts-api-utils@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz#2690579f96d2790253bdcf1ca35d569ad78f9ad8" + integrity sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA== + ts-jest@^29.1.2: version "29.4.4" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.4.4.tgz#fc6fefe28652ed81b8e1381ef8391901d9f81417" @@ -16453,15 +16766,15 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript-eslint@8.45.0, typescript-eslint@^8.46.2: - version "8.45.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.45.0.tgz#98ab164234dc04c112747ec0a4ae29a94efe123b" - integrity sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg== +typescript-eslint@^8.46.2: + version "8.53.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.53.0.tgz#c35ca6403cd381753aee325f67e10d6101d55f04" + integrity sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw== dependencies: - "@typescript-eslint/eslint-plugin" "8.45.0" - "@typescript-eslint/parser" "8.45.0" - "@typescript-eslint/typescript-estree" "8.45.0" - "@typescript-eslint/utils" "8.45.0" + "@typescript-eslint/eslint-plugin" "8.53.0" + "@typescript-eslint/parser" "8.53.0" + "@typescript-eslint/typescript-estree" "8.53.0" + "@typescript-eslint/utils" "8.53.0" typescript@^5.2.2, typescript@^5.4.0, typescript@^5.9.3: version "5.9.3" @@ -17167,7 +17480,7 @@ vitest-environment-nuxt@^1.0.1: dependencies: "@nuxt/test-utils" ">=3.13.1" -vitest@^4.0.0, vitest@^4.0.16: +vitest@^4.0.16: version "4.0.16" resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.0.16.tgz#7ceaecd4612fa6351923e842a0723c48cdfb6719" integrity sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q== From 828e66a9bc40af5db454163d63c6a6d1536fdd83 Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Sat, 17 Jan 2026 14:38:30 -0600 Subject: [PATCH 09/21] Change footer with Directus footer navigations --- apps/netlogo/app/components/ClientFooter.vue | 46 +++++++++++++++++-- apps/netlogo/app/composables/useNavigation.ts | 33 +++++++------ 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/apps/netlogo/app/components/ClientFooter.vue b/apps/netlogo/app/components/ClientFooter.vue index 4ba93372..d28a47c1 100644 --- a/apps/netlogo/app/components/ClientFooter.vue +++ b/apps/netlogo/app/components/ClientFooter.vue @@ -5,10 +5,20 @@ :brand="WebsiteLogo" brand-href="/" :href-aria-label="hrefAriaLabel" - class="w-fit mx-auto" + :span="2" + class="w-fit" > - + + + +

{{ meta.longDescription }}

@@ -17,6 +27,7 @@ + + diff --git a/apps/netlogo/app/composables/useNavigation.ts b/apps/netlogo/app/composables/useNavigation.ts index ab671647..2682fa6f 100644 --- a/apps/netlogo/app/composables/useNavigation.ts +++ b/apps/netlogo/app/composables/useNavigation.ts @@ -41,22 +41,25 @@ export function useNavigation() { }); }); - /** - * Get footer navigation items (items with in_footer = true) - */ - const footerLinks = computed(() => { - const links: Array<{ title: string; href: string }> = []; - navigationSections.value.forEach((section) => { - section.items - .filter((item) => item.in_footer) - .forEach((item) => { - links.push({ + const footerSections = computed(() => { + return navigationSections.value + .map((section) => { + const links = section.items + .filter((item) => item.in_footer) + .map((item) => ({ title: item.display_title, href: item.url, - }); - }); - }); - return links; + external: false, + })); + + return links.length > 0 + ? { + title: section.name, + links, + } + : null; + }) + .filter((section) => section !== null); }); /** @@ -83,7 +86,7 @@ export function useNavigation() { return { navigationSections, navbarLinks, - footerLinks, + footerSections, isLoading, error, fetchNavigation, From 74c23326479a87c6ac4938acd582fb434b00e922 Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Fri, 23 Jan 2026 09:55:27 -0600 Subject: [PATCH 10/21] Add intro section onto index page --- apps/netlogo/app/components/Intro.vue | 82 +++++++++++++++++++++++++++ apps/netlogo/app/pages/index.vue | 18 +++++- 2 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 apps/netlogo/app/components/Intro.vue diff --git a/apps/netlogo/app/components/Intro.vue b/apps/netlogo/app/components/Intro.vue new file mode 100644 index 00000000..318347e7 --- /dev/null +++ b/apps/netlogo/app/components/Intro.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/apps/netlogo/app/pages/index.vue b/apps/netlogo/app/pages/index.vue index 007c6332..2a480670 100644 --- a/apps/netlogo/app/pages/index.vue +++ b/apps/netlogo/app/pages/index.vue @@ -1,11 +1,25 @@ From f1b4c00c97f03acb1f8b753d928438eb9b811e8e Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Thu, 29 Jan 2026 00:49:43 -0600 Subject: [PATCH 11/21] Add News and Social Media section on main page --- apps/netlogo/app/app.config.ts | 2 +- apps/netlogo/app/assets/styles/main.scss | 18 ++- apps/netlogo/app/components/ClientFooter.vue | 2 - apps/netlogo/app/components/Intro.vue | 19 ++- apps/netlogo/app/components/Newsfeed.vue | 144 +++++++++++++++++++ apps/netlogo/app/pages/index.vue | 18 ++- apps/netlogo/nuxt.config.ts | 15 ++ 7 files changed, 194 insertions(+), 24 deletions(-) create mode 100644 apps/netlogo/app/components/Newsfeed.vue diff --git a/apps/netlogo/app/app.config.ts b/apps/netlogo/app/app.config.ts index dc0faedf..6ff6ae89 100644 --- a/apps/netlogo/app/app.config.ts +++ b/apps/netlogo/app/app.config.ts @@ -6,7 +6,7 @@ export default defineAppConfig({ }, container: { - base: "max-w-[110ch] mx-auto px-0 mx-auto px-[var(--space-xl)] lg:px-0", + base: "max-w-[150ch] mx-auto px-0 mx-auto px-[var(--space-xl)] lg:px-0", }, breadcrumb: { diff --git a/apps/netlogo/app/assets/styles/main.scss b/apps/netlogo/app/assets/styles/main.scss index c68670f2..462b17e5 100644 --- a/apps/netlogo/app/assets/styles/main.scss +++ b/apps/netlogo/app/assets/styles/main.scss @@ -1,14 +1,22 @@ -@use 'sass:meta'; +@use "sass:meta"; @layer theme, base, components, website, utilities; @layer utilities { - @include meta.load-css('@repo/tailwind-config/scss/utilities.scss'); + @include meta.load-css("@repo/tailwind-config/scss/utilities.scss"); } @layer website { - @include meta.load-css('@repo/tailwind-config/scss/normalize.scss'); - @include meta.load-css('@repo/tailwind-config/scss/docs-theme.scss'); + @include meta.load-css("@repo/tailwind-config/scss/normalize.scss"); + + h1, + h2, + h3, + h4, + h5 { + margin-bottom: 0; + } + // @include meta.load-css('@repo/tailwind-config/scss/docs-theme.scss'); } -@include meta.load-css('@repo/vue-ui/styles.scss'); +@include meta.load-css("@repo/vue-ui/styles.scss"); diff --git a/apps/netlogo/app/components/ClientFooter.vue b/apps/netlogo/app/components/ClientFooter.vue index d28a47c1..7826575b 100644 --- a/apps/netlogo/app/components/ClientFooter.vue +++ b/apps/netlogo/app/components/ClientFooter.vue @@ -35,10 +35,8 @@ const currentYear = ref(new Date().getFullYear()); const hrefAriaLabel = computed(() => `Navigate to the homepage of ${meta.value.name}`); -// Fetch footer navigation from Directus const { footerSections, fetchNavigation } = useNavigation(); -// Calculate span based on number of sections (remaining space after brand section) const calculateSpan = (sectionCount: number) => { if (sectionCount === 0) return 10; return Math.floor(10 / sectionCount); diff --git a/apps/netlogo/app/components/Intro.vue b/apps/netlogo/app/components/Intro.vue index 318347e7..80ae92eb 100644 --- a/apps/netlogo/app/components/Intro.vue +++ b/apps/netlogo/app/components/Intro.vue @@ -20,23 +20,21 @@

- + --> + 100% Free
- +
@@ -47,6 +45,7 @@ + + diff --git a/apps/netlogo/app/pages/index.vue b/apps/netlogo/app/pages/index.vue index 2a480670..5065bb02 100644 --- a/apps/netlogo/app/pages/index.vue +++ b/apps/netlogo/app/pages/index.vue @@ -1,25 +1,31 @@ diff --git a/apps/netlogo/nuxt.config.ts b/apps/netlogo/nuxt.config.ts index cd69a855..573d539a 100644 --- a/apps/netlogo/nuxt.config.ts +++ b/apps/netlogo/nuxt.config.ts @@ -12,5 +12,20 @@ export default defineNuxtConfig( backendUrl: process.env.PUBLIC_BACKEND_URL || "https://backend.netlogo.org", }, }, + app: { + head: { + script: [ + { + src: "https://unpkg.com/bsky-embed/dist/bsky-embed.es.js", + type: "module", + }, + ], + }, + }, + vue: { + compilerOptions: { + isCustomElement: (tag: string) => tag === "bsky-embed", + }, + }, }), ); From c25775cf53973c5f479d8e561986fbfed1600720 Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Thu, 29 Jan 2026 01:56:22 -0600 Subject: [PATCH 12/21] Fix initial Directus loading issue with async functions --- apps/netlogo/app/components/ClientFooter.vue | 5 +-- apps/netlogo/app/components/ClientNavbar.vue | 20 ++-------- apps/netlogo/app/composables/useNavigation.ts | 40 +++++-------------- apps/netlogo/app/pages/index.vue | 26 +++++------- 4 files changed, 27 insertions(+), 64 deletions(-) diff --git a/apps/netlogo/app/components/ClientFooter.vue b/apps/netlogo/app/components/ClientFooter.vue index 7826575b..597207d5 100644 --- a/apps/netlogo/app/components/ClientFooter.vue +++ b/apps/netlogo/app/components/ClientFooter.vue @@ -35,16 +35,15 @@ const currentYear = ref(new Date().getFullYear()); const hrefAriaLabel = computed(() => `Navigate to the homepage of ${meta.value.name}`); -const { footerSections, fetchNavigation } = useNavigation(); +const { footerSections } = await useNavigation(); const calculateSpan = (sectionCount: number) => { if (sectionCount === 0) return 10; return Math.floor(10 / sectionCount); }; -onMounted(async () => { +onMounted(() => { currentYear.value = new Date().getFullYear(); - await fetchNavigation(); }); diff --git a/apps/netlogo/app/components/ClientNavbar.vue b/apps/netlogo/app/components/ClientNavbar.vue index d969e3e2..358ab5c8 100644 --- a/apps/netlogo/app/components/ClientNavbar.vue +++ b/apps/netlogo/app/components/ClientNavbar.vue @@ -65,19 +65,10 @@ const handleMediaQueryChange = (): void => { } }; -// Use the navigation composable to fetch from Directus -const { navbarLinks: apiNavbarLinks, fetchNavigation, isLoading } = useNavigation(); - -// Default fallback navigation (shown while loading or on error) -const defaultNavbarLinks: NavbarLink[] = [ - { - title: "Home", - href: "/", - }, -]; +const { navbarLinks: apiNavbarLinks } = await useNavigation(); -// Reactive navbar links that update once API data is loaded -const navbarLinks = ref(defaultNavbarLinks); +// Reactive navbar links with active states +const navbarLinks = ref(apiNavbarLinks.value); const updateActiveStates = () => { navbarRef.value?.blur(); @@ -119,7 +110,6 @@ const isLinkParentActive = (link: NavbarLink, currentPath: string): boolean => { ); }; -// Watch for API data to load and update navbarLinks watch( apiNavbarLinks, (newLinks) => { @@ -131,10 +121,8 @@ watch( { immediate: true }, ); -onMounted(async () => { +onMounted(() => { if (import.meta.client) { - // Fetch navigation data from Directus - await fetchNavigation(); updateActiveStates(); handleMediaQueryChange(); } diff --git a/apps/netlogo/app/composables/useNavigation.ts b/apps/netlogo/app/composables/useNavigation.ts index 2682fa6f..3e1104de 100644 --- a/apps/netlogo/app/composables/useNavigation.ts +++ b/apps/netlogo/app/composables/useNavigation.ts @@ -9,14 +9,18 @@ export interface NavbarLink { active?: boolean; } -/** - * Composable to fetch and manage navigation data from the Directus backend - */ -export function useNavigation() { +export async function useNavigation() { const config = useRuntimeConfig(); const navigationSections = ref([]); - const isLoading = ref(true); - const error = ref(null); + + const { data } = await useAsyncData("nav-data", async () => { + const api = new NetLogoAPI(config.public.backendUrl as string); + return await api.getNavigationData(); + }); + + if (data.value) { + navigationSections.value = data.value.navigation_sections; + } /** * Transform API navigation sections into NavbarLink format @@ -62,33 +66,9 @@ export function useNavigation() { .filter((section) => section !== null); }); - /** - * Fetch navigation data from the Directus backend - */ - async function fetchNavigation() { - isLoading.value = true; - error.value = null; - - try { - const api = new NetLogoAPI(config.public.backendUrl as string); - const data = await api.getNavigationData(); - navigationSections.value = data.navigation_sections; - } catch (e) { - console.error("Failed to fetch navigation data:", e); - error.value = e instanceof Error ? e : new Error("Unknown error"); - // Fallback to default navigation - navigationSections.value = []; - } finally { - isLoading.value = false; - } - } - return { navigationSections, navbarLinks, footerSections, - isLoading, - error, - fetchNavigation, }; } diff --git a/apps/netlogo/app/pages/index.vue b/apps/netlogo/app/pages/index.vue index 5065bb02..2ea6f29c 100644 --- a/apps/netlogo/app/pages/index.vue +++ b/apps/netlogo/app/pages/index.vue @@ -7,25 +7,21 @@ From b889a68fbc49f6e373e04a7765ddb435764af2fa Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Fri, 30 Jan 2026 11:46:27 -0600 Subject: [PATCH 13/21] Add in Get NetLogo and Community sections on home page --- apps/netlogo/app/app.config.ts | 33 +----- apps/netlogo/app/app.vue | 4 +- apps/netlogo/app/components/Community.vue | 79 +++++++++++++ apps/netlogo/app/components/GetNetLogo.vue | 78 +++++++++++++ apps/netlogo/app/components/Intro.vue | 74 ++++++------ apps/netlogo/app/components/Newsfeed.vue | 130 +++++++++++---------- apps/netlogo/app/pages/index.vue | 12 +- 7 files changed, 276 insertions(+), 134 deletions(-) create mode 100644 apps/netlogo/app/components/Community.vue create mode 100644 apps/netlogo/app/components/GetNetLogo.vue diff --git a/apps/netlogo/app/app.config.ts b/apps/netlogo/app/app.config.ts index 6ff6ae89..2fb4f73a 100644 --- a/apps/netlogo/app/app.config.ts +++ b/apps/netlogo/app/app.config.ts @@ -6,38 +6,7 @@ export default defineAppConfig({ }, container: { - base: "max-w-[150ch] mx-auto px-0 mx-auto px-[var(--space-xl)] lg:px-0", - }, - - breadcrumb: { - slots: { - list: "[&_li]:m-0! p-0", - }, - }, - - contentNavigation: { - slots: { - list: "mx-0 px-2 lg:mt-[var(--block-top)]", - listWithChildren: "px-0", - }, - }, - contentToc: { - slots: { - root: "px-0! w-full -mx-0", - trailing: "hidden", - title: - "w-full px-[var(--space-lg)] py-2 bg-[var(--secondary-heading-background-color)] text-[var(--secondary-heading-text-color)] w-full", - }, - }, - pageAside: { - slots: { - root: "pt-0", - }, - }, - blogPost: { - slots: { - footer: "p-4 sm:p-6", - }, + base: "max-w-[150ch] px-4 lg:px-12 mx-auto", }, }, }); diff --git a/apps/netlogo/app/app.vue b/apps/netlogo/app/app.vue index 81018a76..c90826e6 100644 --- a/apps/netlogo/app/app.vue +++ b/apps/netlogo/app/app.vue @@ -3,7 +3,9 @@ - + + + diff --git a/apps/netlogo/app/components/Community.vue b/apps/netlogo/app/components/Community.vue new file mode 100644 index 00000000..f9516bf5 --- /dev/null +++ b/apps/netlogo/app/components/Community.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/apps/netlogo/app/components/GetNetLogo.vue b/apps/netlogo/app/components/GetNetLogo.vue new file mode 100644 index 00000000..3cab1988 --- /dev/null +++ b/apps/netlogo/app/components/GetNetLogo.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/apps/netlogo/app/components/Intro.vue b/apps/netlogo/app/components/Intro.vue index 80ae92eb..82199cd4 100644 --- a/apps/netlogo/app/components/Intro.vue +++ b/apps/netlogo/app/components/Intro.vue @@ -1,46 +1,50 @@ From 8f5046d7ddb43934844d3dffe44b2ea6b04e6277 Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Tue, 3 Feb 2026 23:19:02 -0600 Subject: [PATCH 14/21] Fix Intro section with appropriate turtles and NetLogo Icon --- apps/netlogo/app/components/Intro.vue | 44 +++++++++++-------- .../vue-ui/assets/brands/intro-turtles.svg | 26 +++++++++++ packages/vue-ui/assets/brands/logo-text.svg | 4 ++ 3 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 packages/vue-ui/assets/brands/intro-turtles.svg create mode 100644 packages/vue-ui/assets/brands/logo-text.svg diff --git a/apps/netlogo/app/components/Intro.vue b/apps/netlogo/app/components/Intro.vue index 82199cd4..645fd296 100644 --- a/apps/netlogo/app/components/Intro.vue +++ b/apps/netlogo/app/components/Intro.vue @@ -2,40 +2,47 @@
-
+
-
- -
- NetLogo - - Simulate, Explore, Understand - +
+ +
+
-
-

+

+

{{ description }}

-
-
+
+
- - 100% Free + 100% Free
-
@@ -48,7 +55,8 @@ + + diff --git a/apps/netlogo/app/pages/index.vue b/apps/netlogo/app/pages/index.vue index 388c5045..ce319ed5 100644 --- a/apps/netlogo/app/pages/index.vue +++ b/apps/netlogo/app/pages/index.vue @@ -1,5 +1,5 @@
diff --git a/apps/netlogo/app/components/GetNetLogo.vue b/apps/netlogo/app/components/GetNetLogo.vue index 1187154b..d9833c76 100644 --- a/apps/netlogo/app/components/GetNetLogo.vue +++ b/apps/netlogo/app/components/GetNetLogo.vue @@ -37,15 +37,15 @@
From 2a1b930f2bcb53df45124e8ea691c5efbd4d8a3c Mon Sep 17 00:00:00 2001 From: danielwong0115 Date: Fri, 13 Feb 2026 18:36:19 -0600 Subject: [PATCH 21/21] Temporary link styling changes --- apps/netlogo/app/assets/styles/main.scss | 8 ++++++++ packages/tailwind-config/scss/docs-theme.scss | 2 ++ 2 files changed, 10 insertions(+) diff --git a/apps/netlogo/app/assets/styles/main.scss b/apps/netlogo/app/assets/styles/main.scss index 462b17e5..a695ebda 100644 --- a/apps/netlogo/app/assets/styles/main.scss +++ b/apps/netlogo/app/assets/styles/main.scss @@ -16,6 +16,14 @@ h5 { margin-bottom: 0; } + + a { + color: var(--color-link); + } + + a:hover { + color: var(--color-link-hover); + } // @include meta.load-css('@repo/tailwind-config/scss/docs-theme.scss'); } diff --git a/packages/tailwind-config/scss/docs-theme.scss b/packages/tailwind-config/scss/docs-theme.scss index 2bb7eb4d..57a819c1 100644 --- a/packages/tailwind-config/scss/docs-theme.scss +++ b/packages/tailwind-config/scss/docs-theme.scss @@ -473,6 +473,7 @@ span.external-link { // Links +a, .landing a, a:has(code):not(h3 > a), code a, @@ -484,6 +485,7 @@ a:not(h1 a):not(h2 a):not(h3 a):not(h4 a):not(h5 a):not(h6 a) { font-weight: 600; } +a:hover, .landing a:hover, a:has(code:hover), code a:hover,