@stacksjs/defaults 0.70.207 → 0.70.208
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/TODO.md +21 -0
- package/ai/AGENTS.md +79 -0
- package/ai/README.md +45 -0
- package/ai/claude/launch.json +12 -0
- package/ai/skills/stacks-actions/SKILL.md +128 -0
- package/ai/skills/stacks-ai/SKILL.md +276 -0
- package/ai/skills/stacks-alias/SKILL.md +94 -0
- package/ai/skills/stacks-analytics/SKILL.md +91 -0
- package/ai/skills/stacks-api/SKILL.md +738 -0
- package/ai/skills/stacks-arrays/SKILL.md +277 -0
- package/ai/skills/stacks-auth/SKILL.md +422 -0
- package/ai/skills/stacks-auto-imports/SKILL.md +138 -0
- package/ai/skills/stacks-brandkit/SKILL.md +811 -0
- package/ai/skills/stacks-browse/SKILL.md +127 -0
- package/ai/skills/stacks-browse/scripts/browse.ts +492 -0
- package/ai/skills/stacks-browser/SKILL.md +145 -0
- package/ai/skills/stacks-buddy/SKILL.md +676 -0
- package/ai/skills/stacks-build/SKILL.md +163 -0
- package/ai/skills/stacks-cache/SKILL.md +125 -0
- package/ai/skills/stacks-calendar/SKILL.md +113 -0
- package/ai/skills/stacks-chat/SKILL.md +371 -0
- package/ai/skills/stacks-cli/SKILL.md +112 -0
- package/ai/skills/stacks-cloud/SKILL.md +192 -0
- package/ai/skills/stacks-cms/SKILL.md +217 -0
- package/ai/skills/stacks-collections/SKILL.md +82 -0
- package/ai/skills/stacks-commerce/SKILL.md +114 -0
- package/ai/skills/stacks-composables/SKILL.md +161 -0
- package/ai/skills/stacks-config/SKILL.md +144 -0
- package/ai/skills/stacks-configuration/SKILL.md +154 -0
- package/ai/skills/stacks-cron/SKILL.md +123 -0
- package/ai/skills/stacks-crosswind/SKILL.md +190 -0
- package/ai/skills/stacks-dashboard/SKILL.md +173 -0
- package/ai/skills/stacks-database/SKILL.md +286 -0
- package/ai/skills/stacks-datetime/SKILL.md +269 -0
- package/ai/skills/stacks-dependencies/SKILL.md +111 -0
- package/ai/skills/stacks-deploy/SKILL.md +102 -0
- package/ai/skills/stacks-design-brutalist/SKILL.md +110 -0
- package/ai/skills/stacks-design-minimalist/SKILL.md +115 -0
- package/ai/skills/stacks-design-output/SKILL.md +55 -0
- package/ai/skills/stacks-design-soft/SKILL.md +156 -0
- package/ai/skills/stacks-design-taste/SKILL.md +1012 -0
- package/ai/skills/stacks-design-taste-codex/SKILL.md +294 -0
- package/ai/skills/stacks-desktop/SKILL.md +78 -0
- package/ai/skills/stacks-development/SKILL.md +298 -0
- package/ai/skills/stacks-dns/SKILL.md +149 -0
- package/ai/skills/stacks-docs/SKILL.md +109 -0
- package/ai/skills/stacks-email/SKILL.md +236 -0
- package/ai/skills/stacks-enums/SKILL.md +100 -0
- package/ai/skills/stacks-env/SKILL.md +181 -0
- package/ai/skills/stacks-error-handling/SKILL.md +137 -0
- package/ai/skills/stacks-events/SKILL.md +228 -0
- package/ai/skills/stacks-faker/SKILL.md +158 -0
- package/ai/skills/stacks-git/SKILL.md +158 -0
- package/ai/skills/stacks-guard/SKILL.md +98 -0
- package/ai/skills/stacks-health/SKILL.md +75 -0
- package/ai/skills/stacks-http/SKILL.md +316 -0
- package/ai/skills/stacks-i18n/SKILL.md +198 -0
- package/ai/skills/stacks-image-to-code/SKILL.md +629 -0
- package/ai/skills/stacks-imagegen-mobile/SKILL.md +1474 -0
- package/ai/skills/stacks-imagegen-web/SKILL.md +998 -0
- package/ai/skills/stacks-investigate/SKILL.md +119 -0
- package/ai/skills/stacks-jobs/SKILL.md +136 -0
- package/ai/skills/stacks-lint/SKILL.md +184 -0
- package/ai/skills/stacks-listeners/SKILL.md +99 -0
- package/ai/skills/stacks-logging/SKILL.md +78 -0
- package/ai/skills/stacks-mail/SKILL.md +120 -0
- package/ai/skills/stacks-middleware/SKILL.md +249 -0
- package/ai/skills/stacks-migrations/SKILL.md +105 -0
- package/ai/skills/stacks-models/SKILL.md +267 -0
- package/ai/skills/stacks-new-feature/SKILL.md +206 -0
- package/ai/skills/stacks-notifications/SKILL.md +210 -0
- package/ai/skills/stacks-objects/SKILL.md +205 -0
- package/ai/skills/stacks-office-hours/SKILL.md +134 -0
- package/ai/skills/stacks-orm/SKILL.md +342 -0
- package/ai/skills/stacks-path/SKILL.md +118 -0
- package/ai/skills/stacks-payments/SKILL.md +373 -0
- package/ai/skills/stacks-plan-review/SKILL.md +152 -0
- package/ai/skills/stacks-plugins/SKILL.md +149 -0
- package/ai/skills/stacks-push/SKILL.md +376 -0
- package/ai/skills/stacks-query-builder/SKILL.md +128 -0
- package/ai/skills/stacks-queue/SKILL.md +559 -0
- package/ai/skills/stacks-realtime/SKILL.md +442 -0
- package/ai/skills/stacks-redesign/SKILL.md +182 -0
- package/ai/skills/stacks-registry/SKILL.md +58 -0
- package/ai/skills/stacks-repl/SKILL.md +80 -0
- package/ai/skills/stacks-retro/SKILL.md +122 -0
- package/ai/skills/stacks-review/SKILL.md +135 -0
- package/ai/skills/stacks-router/SKILL.md +231 -0
- package/ai/skills/stacks-routes/SKILL.md +105 -0
- package/ai/skills/stacks-scaffolding/SKILL.md +162 -0
- package/ai/skills/stacks-scheduler/SKILL.md +363 -0
- package/ai/skills/stacks-search-engine/SKILL.md +112 -0
- package/ai/skills/stacks-security/SKILL.md +129 -0
- package/ai/skills/stacks-security-audit/SKILL.md +128 -0
- package/ai/skills/stacks-server/SKILL.md +458 -0
- package/ai/skills/stacks-shell/SKILL.md +62 -0
- package/ai/skills/stacks-slug/SKILL.md +87 -0
- package/ai/skills/stacks-sms/SKILL.md +385 -0
- package/ai/skills/stacks-socials/SKILL.md +303 -0
- package/ai/skills/stacks-storage/SKILL.md +576 -0
- package/ai/skills/stacks-strings/SKILL.md +416 -0
- package/ai/skills/stacks-stx/SKILL.md +176 -0
- package/ai/skills/stacks-technical-diagrams/LICENSE +22 -0
- package/ai/skills/stacks-technical-diagrams/SKILL.md +290 -0
- package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +4 -0
- package/ai/skills/stacks-technical-diagrams/assets/template.html +1252 -0
- package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +289 -0
- package/ai/skills/stacks-technical-diagrams/bunfig.toml +1 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +64 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +88 -0
- package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +75 -0
- package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +70 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +41 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +62 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +371 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +82 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +295 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +91 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +384 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +84 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +257 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +42 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +13 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +230 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +88 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +103 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +481 -0
- package/ai/skills/stacks-technical-diagrams/schemas/README.md +68 -0
- package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +121 -0
- package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +43 -0
- package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +221 -0
- package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +241 -0
- package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +186 -0
- package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +332 -0
- package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +297 -0
- package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +28 -0
- package/ai/skills/stacks-testing/SKILL.md +129 -0
- package/ai/skills/stacks-tunnel/SKILL.md +125 -0
- package/ai/skills/stacks-types/SKILL.md +178 -0
- package/ai/skills/stacks-ui/SKILL.md +246 -0
- package/ai/skills/stacks-utils/SKILL.md +444 -0
- package/ai/skills/stacks-validation/SKILL.md +371 -0
- package/ai/skills/stacks-whois/SKILL.md +315 -0
- package/assets/world-map-data.ts +121 -0
- package/bootstrap.ts +114 -0
- package/docs/api-examples.md +46 -0
- package/docs/index.md +24 -0
- package/docs/markdown-examples.md +87 -0
- package/functions/analytics.ts +97 -0
- package/functions/api.ts +143 -0
- package/functions/auth.ts +208 -0
- package/functions/billing/payments.ts +149 -0
- package/functions/blog.ts +120 -0
- package/functions/cms/categorizables.ts +107 -0
- package/functions/cms/pages.ts +108 -0
- package/functions/cms/posts.ts +100 -0
- package/functions/cms/taggables.ts +102 -0
- package/functions/commerce/coupons.ts +128 -0
- package/functions/commerce/customers.ts +128 -0
- package/functions/commerce/gift-cards.ts +119 -0
- package/functions/commerce/orders.ts +112 -0
- package/functions/commerce/payments.ts +119 -0
- package/functions/commerce/products/categories.ts +123 -0
- package/functions/commerce/products/manufacturers.ts +123 -0
- package/functions/commerce/products/products.ts +123 -0
- package/functions/commerce/products/reviews.ts +123 -0
- package/functions/commerce/products/units.ts +123 -0
- package/functions/commerce/products/variants.ts +123 -0
- package/functions/commerce/shippings/delivery-routes.ts +123 -0
- package/functions/commerce/shippings/digital-deliveries.ts +119 -0
- package/functions/commerce/shippings/drivers.ts +123 -0
- package/functions/commerce/shippings/license-keys.ts +123 -0
- package/functions/commerce/shippings/shipping-methods.ts +123 -0
- package/functions/commerce/shippings/shipping-rates.ts +119 -0
- package/functions/commerce/shippings/shipping-zones.ts +119 -0
- package/functions/commerce/taxes.ts +119 -0
- package/functions/commerce/waitlist/products.ts +123 -0
- package/functions/commerce/waitlist/restaurants.ts +123 -0
- package/functions/craft.ts +107 -0
- package/functions/dashboard.ts +153 -0
- package/functions/inbox.ts +95 -0
- package/functions/jobs.ts +86 -0
- package/functions/monitoring/errors.ts +295 -0
- package/functions/queue.ts +111 -0
- package/functions/realtime/websockets.ts +96 -0
- package/functions/realtime.ts +52 -0
- package/functions/releases.ts +49 -0
- package/functions/search.ts +126 -0
- package/functions/toasts.ts +95 -0
- package/functions/uploads.ts +216 -0
- package/ide/.gitignore +4 -0
- package/ide/cursor/rules/auto-imports.mdc +574 -0
- package/ide/cursor/rules/code-style.mdc +12 -0
- package/ide/cursor/rules/documentation.mdc +9 -0
- package/ide/cursor/rules/error-handling-validation.mdc +11 -0
- package/ide/cursor/rules/key-conventions.mdc +11 -0
- package/ide/cursor/rules/project-structure.mdc +169 -0
- package/ide/cursor/rules/readme.mdc +318 -0
- package/ide/cursor/rules/syntax-formatting.mdc +9 -0
- package/ide/cursor/rules/testing.mdc +10 -0
- package/ide/cursor/rules/typescript.mdc +9 -0
- package/ide/cursor/rules/ui-styling.mdc +0 -0
- package/ide/dictionary.txt +397 -0
- package/ide/jetbrains/.fleet/settings.json +4 -0
- package/ide/jetbrains/.idea/.gitignore +5 -0
- package/ide/jetbrains/.idea/.name +1 -0
- package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/ide/jetbrains/.idea/jsLinters/eslint.xml +7 -0
- package/ide/jetbrains/.idea/modules.xml +8 -0
- package/ide/jetbrains/.idea/stacks.iml +22 -0
- package/ide/jetbrains/.idea/vcs.xml +6 -0
- package/ide/jetbrains/.idea/webResources.xml +14 -0
- package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
- package/ide/jetbrains/installed.txt +4 -0
- package/ide/jetbrains/options/github-copilot.xml +5 -0
- package/ide/jetbrains/options/nodejs.xml +7 -0
- package/ide/jetbrains/options/templates.xml +124 -0
- package/ide/jetbrains/templates/JavaScript.xml +6 -0
- package/ide/jetbrains/templates/Stacks.xml +8 -0
- package/ide/vscode/.vscode/README.md +23 -0
- package/ide/vscode/.vscode/extensions.json +5 -0
- package/ide/vscode/.vscode/settings.json +176 -0
- package/ide/vscode/.vscode/stacks.code-snippets +181 -0
- package/ide/vscode/LICENSE.md +21 -0
- package/ide/vscode/README.md +36 -0
- package/ide/vscode/logo.png +0 -0
- package/ide/vscode/package.json +79 -0
- package/ide/zed/.zed/settings.json +139 -0
- package/lang/README.md +28 -0
- package/lang/de.yml +14 -0
- package/lang/en.yml +15 -0
- package/package.json +19 -3
- package/project/bootstrap +161 -0
- package/project/buddy +175 -0
- package/project/storage/framework/tsconfig.app.json +50 -0
- package/project/storage/framework/tsconfig.base.json +58 -0
- package/routes/core.ts +78 -0
- package/routes/dashboard-api.ts +233 -0
- package/routes/dashboard.ts +739 -0
- package/routes/email.ts +129 -0
- package/stores/[name].stx +16 -0
- package/stores/git.ts +71 -0
- package/stores/payment.ts +474 -0
- package/stores/queue.ts +43 -0
- package/stores/user.ts +29 -0
- package/stx-components-plugin.ts +25 -0
- package/styles/design-tokens.css +597 -0
- package/types/dashboard.ts +70 -0
- package/types/defaults.ts +438 -0
- package/vcs/github/CODE_OF_CONDUCT.md +83 -0
- package/vcs/github/CONTRIBUTING.md +187 -0
- package/vcs/github/EXPLANATIONS.md +41 -0
- package/vcs/github/FUNDING.yml +1 -0
- package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +49 -0
- package/vcs/github/ISSUE_TEMPLATE/config.yml +10 -0
- package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +44 -0
- package/vcs/github/SECURITY.md +70 -0
- package/vcs/github/renovate.json +5 -0
- package/vcs/github/stale.yml +14 -0
- package/vcs/github/workflows/README.md +16 -0
- package/vcs/github/workflows/ci.yml +114 -0
- package/vcs/github/workflows/export-size.yml +25 -0
- package/vcs/github/workflows/labeler.yml +13 -0
- package/vcs/github/workflows/release.yml +219 -0
- package/views/[...all].stx +8 -0
- package/views/about.md +3 -0
- package/views/auth/login.stx +1 -0
- package/views/auth/signup.stx +85 -0
- package/views/dashboard/.discovered-models.json +542 -0
- package/views/dashboard/AUDIT.md +904 -0
- package/views/dashboard/[...all].stx +89 -0
- package/views/dashboard/access-tokens/index.stx +177 -0
- package/views/dashboard/actions/index.stx +129 -0
- package/views/dashboard/analytics/blog/index.stx +356 -0
- package/views/dashboard/analytics/browsers/index.stx +263 -0
- package/views/dashboard/analytics/commerce/sales/index.stx +329 -0
- package/views/dashboard/analytics/commerce/web/index.stx +379 -0
- package/views/dashboard/analytics/countries/index.stx +289 -0
- package/views/dashboard/analytics/devices/index.stx +305 -0
- package/views/dashboard/analytics/events/index.stx +536 -0
- package/views/dashboard/analytics/index.stx +88 -0
- package/views/dashboard/analytics/marketing/index.stx +315 -0
- package/views/dashboard/analytics/pages/index.stx +271 -0
- package/views/dashboard/analytics/referrers/index.stx +319 -0
- package/views/dashboard/analytics/web/index.stx +356 -0
- package/views/dashboard/buddy/index.stx +198 -0
- package/views/dashboard/ci/index.stx +462 -0
- package/views/dashboard/cloud/index.stx +452 -0
- package/views/dashboard/commands/index.stx +295 -0
- package/views/dashboard/commerce/categories/index.stx +406 -0
- package/views/dashboard/commerce/coupons/index.stx +485 -0
- package/views/dashboard/commerce/customers/index.stx +410 -0
- package/views/dashboard/commerce/dashboard/index.stx +287 -0
- package/views/dashboard/commerce/delivery/delivery-routes.stx +305 -0
- package/views/dashboard/commerce/delivery/digital-delivery.stx +332 -0
- package/views/dashboard/commerce/delivery/drivers.stx +397 -0
- package/views/dashboard/commerce/delivery/index.stx +18 -0
- package/views/dashboard/commerce/delivery/license-keys.stx +380 -0
- package/views/dashboard/commerce/delivery/shipping-methods.stx +346 -0
- package/views/dashboard/commerce/delivery/shipping-rates.stx +338 -0
- package/views/dashboard/commerce/delivery/shipping-zones.stx +302 -0
- package/views/dashboard/commerce/delivery/tabs.ts +25 -0
- package/views/dashboard/commerce/gift-cards/index.stx +561 -0
- package/views/dashboard/commerce/manufacturers/index.stx +308 -0
- package/views/dashboard/commerce/orders/index.stx +247 -0
- package/views/dashboard/commerce/payments/index.stx +535 -0
- package/views/dashboard/commerce/pos/index.stx +653 -0
- package/views/dashboard/commerce/printers/devices/index.stx +273 -0
- package/views/dashboard/commerce/printers/receipts/index.stx +308 -0
- package/views/dashboard/commerce/products/detail.stx +563 -0
- package/views/dashboard/commerce/products/index.stx +370 -0
- package/views/dashboard/commerce/reviews/index.stx +656 -0
- package/views/dashboard/commerce/reviews/index.ts +0 -0
- package/views/dashboard/commerce/taxes/index.stx +377 -0
- package/views/dashboard/commerce/units/index.stx +317 -0
- package/views/dashboard/commerce/variants/index.stx +319 -0
- package/views/dashboard/commerce/waitlist/products.stx +942 -0
- package/views/dashboard/commerce/waitlist/restaurant.stx +1024 -0
- package/views/dashboard/components/index.stx +330 -0
- package/views/dashboard/composables/index.ts +19 -0
- package/views/dashboard/composables/useChart.ts +77 -0
- package/views/dashboard/composables/useNavigation.ts +99 -0
- package/views/dashboard/composables/useRole.ts +58 -0
- package/views/dashboard/composables/useTheme.ts +74 -0
- package/views/dashboard/content/authors/index.stx +171 -0
- package/views/dashboard/content/blog/index.stx +493 -0
- package/views/dashboard/content/categories/index.stx +169 -0
- package/views/dashboard/content/comments/index.stx +189 -0
- package/views/dashboard/content/dashboard.stx +383 -0
- package/views/dashboard/content/files/index.stx +706 -0
- package/views/dashboard/content/pages/index.stx +174 -0
- package/views/dashboard/content/posts/index.stx +269 -0
- package/views/dashboard/content/seo/index.stx +240 -0
- package/views/dashboard/content/tags/index.stx +167 -0
- package/views/dashboard/data/activity/index.stx +261 -0
- package/views/dashboard/data/dashboard/index.stx +116 -0
- package/views/dashboard/data/subscribers.stx +270 -0
- package/views/dashboard/data/teams.stx +275 -0
- package/views/dashboard/data/users.stx +279 -0
- package/views/dashboard/dependencies/index.stx +178 -0
- package/views/dashboard/deployments/[id].stx +234 -0
- package/views/dashboard/deployments/index.stx +9 -0
- package/views/dashboard/dns/index.stx +163 -0
- package/views/dashboard/environment/index.stx +283 -0
- package/views/dashboard/errors/index.stx +274 -0
- package/views/dashboard/forgot-password.stx +57 -0
- package/views/dashboard/functions/index.stx +159 -0
- package/views/dashboard/health/index.stx +248 -0
- package/views/dashboard/inbox/activity.stx +350 -0
- package/views/dashboard/inbox/index.stx +452 -0
- package/views/dashboard/inbox/settings.stx +290 -0
- package/views/dashboard/index.stx +252 -0
- package/views/dashboard/insights/index.stx +529 -0
- package/views/dashboard/jobs/[id].stx +430 -0
- package/views/dashboard/jobs/history.stx +222 -0
- package/views/dashboard/jobs/index.stx +214 -0
- package/views/dashboard/kanban/[id].stx +899 -0
- package/views/dashboard/kanban/index.stx +260 -0
- package/views/dashboard/layouts/default.stx +565 -0
- package/views/dashboard/layouts/guest.stx +10 -0
- package/views/dashboard/login.stx +48 -0
- package/views/dashboard/logs/index.stx +540 -0
- package/views/dashboard/mailboxes/index.stx +149 -0
- package/views/dashboard/management/permissions/index.stx +490 -0
- package/views/dashboard/marketing/campaigns/index.stx +604 -0
- package/views/dashboard/marketing/lists/index.stx +514 -0
- package/views/dashboard/marketing/reviews/index.stx +475 -0
- package/views/dashboard/marketing/social-posts/index.stx +560 -0
- package/views/dashboard/models/[model].stx +195 -0
- package/views/dashboard/models/index.stx +159 -0
- package/views/dashboard/monitoring/errors/index.stx +415 -0
- package/views/dashboard/notifications/dashboard.stx +383 -0
- package/views/dashboard/notifications/email.stx +336 -0
- package/views/dashboard/notifications/history.stx +373 -0
- package/views/dashboard/notifications/sms.stx +332 -0
- package/views/dashboard/packages/index.stx +195 -0
- package/views/dashboard/queries/[id].stx +381 -0
- package/views/dashboard/queries/history.stx +227 -0
- package/views/dashboard/queries/index.stx +335 -0
- package/views/dashboard/queries/slow.stx +318 -0
- package/views/dashboard/queue/index.stx +427 -0
- package/views/dashboard/realtime/index.stx +429 -0
- package/views/dashboard/register.stx +46 -0
- package/views/dashboard/releases/index.stx +389 -0
- package/views/dashboard/requests/index.stx +462 -0
- package/views/dashboard/serverless/index.stx +475 -0
- package/views/dashboard/servers/[id].stx +299 -0
- package/views/dashboard/servers/index.stx +483 -0
- package/views/dashboard/settings/billing.stx +50 -0
- package/views/dashboard/settings/index.stx +256 -0
- package/views/dashboard/settings/mail.stx +252 -0
- package/views/dashboard/stores/auth.ts +123 -0
- package/views/dashboard/stores/ci.ts +342 -0
- package/views/dashboard/stores/index.ts +129 -0
- package/views/dashboard/stores/kanban.ts +723 -0
- package/views/dashboard/stores/rbac.ts +350 -0
- package/views/dashboard/stx.config.ts +34 -0
- package/views/dashboard/teams/[id].stx +170 -0
- package/views/forum/category.stx +92 -0
- package/views/forum/index.stx +209 -0
- package/views/forum/new-topic.stx +113 -0
- package/views/forum/profile.stx +1 -0
- package/views/forum/topic.stx +143 -0
- package/views/hello-world/[name].stx +47 -0
- package/views/index.stx +21 -0
- package/views/system-tray/index.stx +147 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
@extends('layouts/default')
|
|
2
|
+
|
|
3
|
+
@section('content')
|
|
4
|
+
@title('Dashboard - Queue')
|
|
5
|
+
<div class="py-4 lg:py-8 min-h-screen dark:bg-neutral-800">
|
|
6
|
+
<div class="px-4 sm:px-6 lg:px-8">
|
|
7
|
+
<div class="mb-8">
|
|
8
|
+
<div>
|
|
9
|
+
<h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-neutral-100">Queue Overview</h3>
|
|
10
|
+
|
|
11
|
+
<dl class="grid gap-5 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 mt-5">
|
|
12
|
+
<div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
|
|
13
|
+
<dt>
|
|
14
|
+
<div class="absolute p-3 bg-blue-500 rounded-md">
|
|
15
|
+
<div class="h-6 w-6 text-white i-hugeicons-queue-02"></div>
|
|
16
|
+
</div>
|
|
17
|
+
<p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-300">Total Jobs</p>
|
|
18
|
+
</dt>
|
|
19
|
+
<dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
|
|
20
|
+
<p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">71,897</p>
|
|
21
|
+
<p class="flex items-baseline ml-2 font-semibold text-green-600 text-sm">
|
|
22
|
+
<div class="flex-shrink-0 self-center h-5 w-5 text-green-500 i-hugeicons-arrow-up-02"></div>
|
|
23
|
+
<span class="sr-only">Increased by</span>
|
|
24
|
+
122
|
|
25
|
+
</p>
|
|
26
|
+
</dd>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
|
|
30
|
+
<dt>
|
|
31
|
+
<div class="absolute p-3 bg-blue-500 rounded-md">
|
|
32
|
+
<div class="h-6 w-6 text-white i-hugeicons-clock-01"></div>
|
|
33
|
+
</div>
|
|
34
|
+
<p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-300">Average Processing Time</p>
|
|
35
|
+
</dt>
|
|
36
|
+
<dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
|
|
37
|
+
<p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">2.3s</p>
|
|
38
|
+
<p class="flex items-baseline ml-2 font-semibold text-green-600 text-sm">
|
|
39
|
+
<div class="flex-shrink-0 self-center h-5 w-5 text-green-500 i-hugeicons-arrow-down-02"></div>
|
|
40
|
+
<span class="sr-only">Decreased by</span>
|
|
41
|
+
0.4s
|
|
42
|
+
</p>
|
|
43
|
+
</dd>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
|
|
47
|
+
<dt>
|
|
48
|
+
<div class="absolute p-3 bg-blue-500 rounded-md">
|
|
49
|
+
<div class="h-6 w-6 text-white i-hugeicons-energy"></div>
|
|
50
|
+
</div>
|
|
51
|
+
<p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-300">Jobs Per Minute</p>
|
|
52
|
+
</dt>
|
|
53
|
+
<dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
|
|
54
|
+
<p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">42</p>
|
|
55
|
+
<p class="flex items-baseline ml-2 font-semibold text-red-600 text-sm">
|
|
56
|
+
<div class="flex-shrink-0 self-center h-5 w-5 text-red-500 i-hugeicons-arrow-down-02"></div>
|
|
57
|
+
<span class="sr-only">Decreased by</span>
|
|
58
|
+
8
|
|
59
|
+
</p>
|
|
60
|
+
</dd>
|
|
61
|
+
</div>
|
|
62
|
+
</dl>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div class="mt-8">
|
|
67
|
+
<div class="sm:flex sm:items-center">
|
|
68
|
+
<div class="sm:flex-auto">
|
|
69
|
+
<h3 class="font-medium text-base text-gray-900 dark:text-neutral-100">Queue Statistics</h3>
|
|
70
|
+
<p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Detailed breakdown of jobs by queue and status</p>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div class="grid gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 mt-6">
|
|
75
|
+
<template :for="queue in queueList">
|
|
76
|
+
<div class="p-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
|
|
77
|
+
<div class="flex items-center justify-between mb-4">
|
|
78
|
+
<h4 class="inline-flex items-center px-2.5 py-0.5 font-medium text-gray-800 text-xs dark:text-neutral-200 bg-gray-100 dark:bg-neutral-600 rounded-full">{{ queue.name }}</h4>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class="space-y-4">
|
|
82
|
+
<div class="grid gap-4 grid-cols-3">
|
|
83
|
+
<template :for="entry in queue.entries">
|
|
84
|
+
<div class="text-center">
|
|
85
|
+
<div class="font-mono font-semibold text-2xl {{ statusValueClass(entry.status) }}">{{ entry.value }}</div>
|
|
86
|
+
<div class="capitalize text-gray-500 text-xs dark:text-neutral-400">{{ entry.status }}</div>
|
|
87
|
+
</div>
|
|
88
|
+
</template>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div class="overflow-hidden h-2 bg-gray-100 dark:bg-neutral-600 rounded-full">
|
|
92
|
+
<div class="flex h-full">
|
|
93
|
+
<div class="h-full bg-green-500" style="width: {{ queue.successRate }}%"></div>
|
|
94
|
+
<div class="h-full bg-red-500" style="width: {{ queue.failureRate }}%"></div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
<div class="flex justify-between text-gray-500 text-xs dark:text-neutral-400">
|
|
98
|
+
<span>Success Rate: {{ queue.successRate }}%</span>
|
|
99
|
+
<span>Failure Rate: {{ queue.failureRate }}%</span>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</template>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div class="my-8 bg-white dark:bg-neutral-700 rounded-lg shadow">
|
|
108
|
+
<div class="p-6">
|
|
109
|
+
<div class="flex items-center justify-between mb-6">
|
|
110
|
+
<h4 class="font-medium text-base text-gray-900 dark:text-neutral-100">Queue Statistics</h4>
|
|
111
|
+
<div class="flex gap-4 items-center">
|
|
112
|
+
<select x-model="selectedQueue" class="block px-3 py-1.5 h-9 w-32 text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600">
|
|
113
|
+
<option value="all">All Queues</option>
|
|
114
|
+
<template :for="queueName in queueNames">
|
|
115
|
+
<option value="{{ queueName }}">{{ queueName }}</option>
|
|
116
|
+
</template>
|
|
117
|
+
</select>
|
|
118
|
+
|
|
119
|
+
<select x-model="timeRange" class="block px-3 py-1.5 h-9 text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600">
|
|
120
|
+
<option value="hour">Last Hour</option>
|
|
121
|
+
<option value="day">Last 24 Hours</option>
|
|
122
|
+
<option value="week">Last Week</option>
|
|
123
|
+
</select>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<div class="grid gap-6 grid-cols-1 lg:grid-cols-2">
|
|
128
|
+
<div class="h-80">
|
|
129
|
+
<canvas id="queue_throughput_chart"></canvas>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="h-80">
|
|
132
|
+
<canvas id="queue_wait_chart"></canvas>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="mb-8 bg-white dark:bg-neutral-700 rounded-lg shadow">
|
|
139
|
+
<div class="p-6">
|
|
140
|
+
<div class="flex items-center justify-between mb-6">
|
|
141
|
+
<div>
|
|
142
|
+
<h4 class="font-medium text-base text-gray-900 dark:text-neutral-100">Workers</h4>
|
|
143
|
+
<p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Monitor your queue workers and their performance.</p>
|
|
144
|
+
</div>
|
|
145
|
+
<div class="flex gap-4 items-center">
|
|
146
|
+
<button @click="retryFailedJobs()" class="inline-flex items-center px-3 py-2 font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">
|
|
147
|
+
<div class="mr-1 h-5 w-5 i-hugeicons-arrow-path"></div>
|
|
148
|
+
Retry Failed Jobs
|
|
149
|
+
</button>
|
|
150
|
+
<button @click="clearFailedJobs()" class="inline-flex items-center px-3 py-2 font-semibold text-gray-900 text-sm dark:text-neutral-100 bg-white dark:bg-neutral-600 hover:bg-gray-50 dark:hover:bg-neutral-500 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">
|
|
151
|
+
<div class="mr-1 h-5 w-5 i-hugeicons-trash"></div>
|
|
152
|
+
Clear Failed Jobs
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div class="space-y-6">
|
|
158
|
+
<template :for="worker in workers">
|
|
159
|
+
<div class="relative p-6 border rounded-lg dark:border-neutral-600 hover:border-blue-200 dark:hover:border-blue-500 duration-200 transition-all">
|
|
160
|
+
<div class="grid gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-4">
|
|
161
|
+
<div>
|
|
162
|
+
<h5 class="font-medium text-gray-900 text-lg dark:text-neutral-100">{{ worker.name }}</h5>
|
|
163
|
+
<p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Queue: {{ worker.queue }}</p>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div>
|
|
167
|
+
<div class="flex gap-2 items-center">
|
|
168
|
+
<div class="h-2 w-2 rounded-full {{ workerStatusDot(worker.status) }}"></div>
|
|
169
|
+
<span class="font-medium text-gray-900 text-sm dark:text-neutral-100">{{ worker.status.charAt(0).toUpperCase() + worker.status.slice(1) }}</span>
|
|
170
|
+
</div>
|
|
171
|
+
<div class="flex gap-2 items-center mt-2">
|
|
172
|
+
<button :show="{{ worker.status !== 'running' ? 'true' : 'false' }}" @click="restartWorker('{{ worker.id }}')" class="inline-flex items-center px-2 py-1 font-medium text-green-700 text-xs dark:text-green-300 bg-green-50 dark:bg-green-900/50 hover:bg-green-100 dark:hover:bg-green-900 rounded-md">
|
|
173
|
+
<div class="mr-1 h-4 w-4 i-hugeicons-play"></div>
|
|
174
|
+
Start
|
|
175
|
+
</button>
|
|
176
|
+
<button :show="{{ worker.status === 'running' ? 'true' : 'false' }}" @click="pauseWorker('{{ worker.id }}')" class="inline-flex items-center px-2 py-1 font-medium text-xs text-yellow-700 dark:text-yellow-300 bg-yellow-50 dark:bg-yellow-900/50 hover:bg-yellow-100 dark:hover:bg-yellow-900 rounded-md">
|
|
177
|
+
<div class="mr-1 h-4 w-4 i-hugeicons-pause"></div>
|
|
178
|
+
Pause
|
|
179
|
+
</button>
|
|
180
|
+
<button :show="{{ worker.status === 'running' ? 'true' : 'false' }}" @click="stopWorker('{{ worker.id }}')" class="inline-flex items-center px-2 py-1 font-medium text-red-700 text-xs dark:text-red-300 bg-red-50 dark:bg-red-900/50 hover:bg-red-100 dark:hover:bg-red-900 rounded-md">
|
|
181
|
+
<div class="mr-1 h-4 w-4 i-hugeicons-stop"></div>
|
|
182
|
+
Stop
|
|
183
|
+
</button>
|
|
184
|
+
</div>
|
|
185
|
+
<p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Last heartbeat: {{ worker.last_heartbeat }}</p>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<div>
|
|
189
|
+
<p class="text-gray-500 text-sm dark:text-neutral-400">Jobs Processed</p>
|
|
190
|
+
<p class="mt-1 font-medium text-gray-900 text-lg dark:text-neutral-100">{{ worker.jobs_processed.toLocaleString() }}</p>
|
|
191
|
+
<p class="mt-1 text-red-600 text-sm dark:text-red-400">{{ worker.failed_jobs }} failed</p>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div>
|
|
195
|
+
<div class="space-y-4">
|
|
196
|
+
<div>
|
|
197
|
+
<div class="flex items-center justify-between text-sm">
|
|
198
|
+
<span class="text-gray-500 dark:text-neutral-400">Connection</span>
|
|
199
|
+
<span class="font-medium text-gray-900 dark:text-neutral-100">{{ worker.connection }}</span>
|
|
200
|
+
</div>
|
|
201
|
+
<div class="flex items-center justify-between mt-2 text-sm">
|
|
202
|
+
<span class="text-gray-500 dark:text-neutral-400">Memory Limit</span>
|
|
203
|
+
<span class="font-medium text-gray-900 dark:text-neutral-100">{{ worker.memory_limit }}MB</span>
|
|
204
|
+
</div>
|
|
205
|
+
<div class="flex items-center justify-between mt-2 text-sm">
|
|
206
|
+
<span class="text-gray-500 dark:text-neutral-400">Timeout</span>
|
|
207
|
+
<span class="font-medium text-gray-900 dark:text-neutral-100">{{ worker.timeout }}s</span>
|
|
208
|
+
</div>
|
|
209
|
+
<div class="flex items-center justify-between mt-2 text-sm">
|
|
210
|
+
<span class="text-gray-500 dark:text-neutral-400">Supervisor</span>
|
|
211
|
+
<span class="font-medium text-gray-900 dark:text-neutral-100">{{ worker.supervisor_id }}</span>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div :show="{{ worker.memory_usage / worker.memory_limit > 0.9 ? 'true' : 'false' }}" class="p-3 bg-yellow-50 dark:bg-yellow-900/50 rounded-md">
|
|
216
|
+
<div class="flex">
|
|
217
|
+
<div class="h-5 w-5 text-yellow-400 i-hugeicons-exclamation-triangle"></div>
|
|
218
|
+
<div class="ml-3">
|
|
219
|
+
<h3 class="font-medium text-sm text-yellow-800 dark:text-yellow-300">High Memory Usage</h3>
|
|
220
|
+
<div class="mt-2 text-sm text-yellow-700 dark:text-yellow-200">
|
|
221
|
+
<p>Worker is approaching memory limit. Consider restarting or increasing the limit.</p>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
</template>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
<script client>
|
|
238
|
+
|
|
239
|
+
interface QueueStats {
|
|
240
|
+
queued: number
|
|
241
|
+
processing: number
|
|
242
|
+
processed: number
|
|
243
|
+
released: number
|
|
244
|
+
failed: number
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
interface WorkerStats {
|
|
248
|
+
id: string
|
|
249
|
+
name: string
|
|
250
|
+
status: 'running' | 'paused' | 'stopped'
|
|
251
|
+
jobs_processed: number
|
|
252
|
+
failed_jobs: number
|
|
253
|
+
last_heartbeat: string
|
|
254
|
+
queue: string
|
|
255
|
+
memory_usage: number
|
|
256
|
+
cpu_usage: number
|
|
257
|
+
memory_limit: number
|
|
258
|
+
timeout: number
|
|
259
|
+
supervisor_id: string
|
|
260
|
+
connection: 'redis' | 'database' | 'sqs'
|
|
261
|
+
tries: number
|
|
262
|
+
retry_after: number
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
interface ChartLike { destroy: () => void }
|
|
266
|
+
type ChartCtor = new (canvas: HTMLElement, config: { type: string, data: unknown, options?: unknown }) => ChartLike
|
|
267
|
+
|
|
268
|
+
const queues = state<Record<string, QueueStats>>({
|
|
269
|
+
default: { queued: 70, processing: 15, processed: 250, released: 5, failed: 2 },
|
|
270
|
+
high: { queued: 23, processing: 8, processed: 180, released: 3, failed: 1 },
|
|
271
|
+
low: { queued: 45, processing: 12, processed: 150, released: 4, failed: 3 },
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
const workers = state<WorkerStats[]>([
|
|
275
|
+
{ id: '1', name: 'worker-1', status: 'running', jobs_processed: 1250, failed_jobs: 23, last_heartbeat: '2024-03-14 10:16:32', queue: 'default', memory_usage: 128.5, cpu_usage: 23.4, memory_limit: 128, timeout: 60, supervisor_id: 'supervisor-1', connection: 'redis', tries: 3, retry_after: 90 },
|
|
276
|
+
{ id: '2', name: 'worker-2', status: 'running', jobs_processed: 980, failed_jobs: 15, last_heartbeat: '2024-03-14 10:16:30', queue: 'high', memory_usage: 145.2, cpu_usage: 28.7, memory_limit: 128, timeout: 60, supervisor_id: 'supervisor-2', connection: 'redis', tries: 3, retry_after: 90 },
|
|
277
|
+
{ id: '3', name: 'worker-3', status: 'running', jobs_processed: 850, failed_jobs: 18, last_heartbeat: '2024-03-14 10:16:28', queue: 'low', memory_usage: 112.8, cpu_usage: 19.5, memory_limit: 128, timeout: 60, supervisor_id: 'supervisor-3', connection: 'redis', tries: 3, retry_after: 90 },
|
|
278
|
+
])
|
|
279
|
+
|
|
280
|
+
const timeRange = state('hour')
|
|
281
|
+
const selectedQueue = state('all')
|
|
282
|
+
const isLoading = state(false)
|
|
283
|
+
|
|
284
|
+
let chartHandles: Array<{ destroy: () => void }> = []
|
|
285
|
+
|
|
286
|
+
const chartOptions = {
|
|
287
|
+
responsive: true,
|
|
288
|
+
maintainAspectRatio: false,
|
|
289
|
+
scales: {
|
|
290
|
+
y: { beginAtZero: true, grid: { color: 'rgba(200, 200, 200, 0.1)' }, ticks: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" } } },
|
|
291
|
+
x: { grid: { display: false }, ticks: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" } } },
|
|
292
|
+
},
|
|
293
|
+
plugins: {
|
|
294
|
+
legend: { display: true, position: 'top', align: 'end', labels: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" }, boxWidth: 12, padding: 15 } },
|
|
295
|
+
tooltip: { mode: 'index', intersect: false },
|
|
296
|
+
},
|
|
297
|
+
interaction: { mode: 'index', intersect: false },
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function queueNames(): string[] {
|
|
301
|
+
return Object.keys(queues())
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function queueList(): Array<{ name: string, entries: Array<{ status: string, value: number }>, successRate: string, failureRate: string }> {
|
|
305
|
+
return Object.entries(queues()).map(([name, stats]) => {
|
|
306
|
+
const total = stats.processed + stats.failed
|
|
307
|
+
const successRate = total === 0 ? '0.0' : ((stats.processed / total) * 100).toFixed(1)
|
|
308
|
+
const failureRate = total === 0 ? '0.0' : ((stats.failed / total) * 100).toFixed(1)
|
|
309
|
+
return {
|
|
310
|
+
name,
|
|
311
|
+
entries: [
|
|
312
|
+
{ status: 'queued', value: stats.queued },
|
|
313
|
+
{ status: 'processing', value: stats.processing },
|
|
314
|
+
{ status: 'processed', value: stats.processed },
|
|
315
|
+
{ status: 'released', value: stats.released },
|
|
316
|
+
{ status: 'failed', value: stats.failed },
|
|
317
|
+
],
|
|
318
|
+
successRate,
|
|
319
|
+
failureRate,
|
|
320
|
+
}
|
|
321
|
+
})
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function statusValueClass(status: string): string {
|
|
325
|
+
switch (status) {
|
|
326
|
+
case 'failed': return 'text-red-600 dark:text-red-400'
|
|
327
|
+
case 'processed': return 'text-green-600 dark:text-green-400'
|
|
328
|
+
case 'processing': return 'text-blue-600 dark:text-blue-400'
|
|
329
|
+
case 'queued': return 'text-yellow-600 dark:text-yellow-400'
|
|
330
|
+
case 'released': return 'text-purple-600 dark:text-purple-400'
|
|
331
|
+
default: return ''
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function workerStatusDot(status: string): string {
|
|
336
|
+
if (status === 'running')
|
|
337
|
+
return 'bg-green-500'
|
|
338
|
+
if (status === 'paused')
|
|
339
|
+
return 'bg-yellow-500'
|
|
340
|
+
if (status === 'stopped')
|
|
341
|
+
return 'bg-red-500'
|
|
342
|
+
return 'bg-gray-400'
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function getThroughputData() {
|
|
346
|
+
const labels = Array.from({ length: 24 }, (_, i) => `${i}:00`)
|
|
347
|
+
return {
|
|
348
|
+
labels,
|
|
349
|
+
datasets: [
|
|
350
|
+
{ label: 'Processed', data: Array.from({ length: 24 }, () => Math.floor(Math.random() * 100) + 50), borderColor: 'rgb(16, 185, 129)', backgroundColor: 'rgba(16, 185, 129, 0.1)', fill: true },
|
|
351
|
+
{ label: 'Failed', data: Array.from({ length: 24 }, () => Math.floor(Math.random() * 10)), borderColor: 'rgb(239, 68, 68)', backgroundColor: 'rgba(239, 68, 68, 0.1)', fill: true },
|
|
352
|
+
],
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function getWaitTimeData() {
|
|
357
|
+
const labels = Array.from({ length: 24 }, (_, i) => `${i}:00`)
|
|
358
|
+
return {
|
|
359
|
+
labels,
|
|
360
|
+
datasets: [{
|
|
361
|
+
label: 'Average Wait Time (seconds)',
|
|
362
|
+
data: Array.from({ length: 24 }, () => Math.random() * 5 + 1),
|
|
363
|
+
borderColor: 'rgb(59, 130, 246)',
|
|
364
|
+
backgroundColor: 'rgba(59, 130, 246, 0.1)',
|
|
365
|
+
fill: true,
|
|
366
|
+
}],
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
async function restartWorker(workerId: string): Promise<void> {
|
|
371
|
+
isLoading.set(true)
|
|
372
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
373
|
+
workers.set(workers().map(w => w.id === workerId ? { ...w, status: 'running', last_heartbeat: new Date().toISOString() } : w))
|
|
374
|
+
isLoading.set(false)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async function pauseWorker(workerId: string): Promise<void> {
|
|
378
|
+
isLoading.set(true)
|
|
379
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
380
|
+
workers.set(workers().map(w => w.id === workerId ? { ...w, status: 'paused' } : w))
|
|
381
|
+
isLoading.set(false)
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
async function stopWorker(workerId: string): Promise<void> {
|
|
385
|
+
isLoading.set(true)
|
|
386
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
387
|
+
workers.set(workers().map(w => w.id === workerId ? { ...w, status: 'stopped' } : w))
|
|
388
|
+
isLoading.set(false)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
async function retryFailedJobs(): Promise<void> {
|
|
392
|
+
isLoading.set(true)
|
|
393
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
394
|
+
const next: Record<string, QueueStats> = {}
|
|
395
|
+
for (const [name, stats] of Object.entries(queues()))
|
|
396
|
+
next[name] = { ...stats, queued: stats.queued + stats.failed, failed: 0 }
|
|
397
|
+
queues.set(next)
|
|
398
|
+
isLoading.set(false)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
async function clearFailedJobs(): Promise<void> {
|
|
402
|
+
isLoading.set(true)
|
|
403
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
404
|
+
const next: Record<string, QueueStats> = {}
|
|
405
|
+
for (const [name, stats] of Object.entries(queues()))
|
|
406
|
+
next[name] = { ...stats, failed: 0 }
|
|
407
|
+
queues.set(next)
|
|
408
|
+
isLoading.set(false)
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
onMount(async () => {
|
|
412
|
+
const { Chart, registerables } = await import('@stacksjs/charts')
|
|
413
|
+
Chart.register(...registerables)
|
|
414
|
+
const Ctor = Chart as unknown as ChartCtor
|
|
415
|
+
|
|
416
|
+
const throughput = useChart({ Chart: Ctor, id: 'queue_throughput_chart', type: 'line', data: getThroughputData(), options: chartOptions })
|
|
417
|
+
const wait = useChart({ Chart: Ctor, id: 'queue_wait_chart', type: 'line', data: getWaitTimeData(), options: chartOptions })
|
|
418
|
+
chartHandles = [throughput.instance, wait.instance].filter((c): c is ChartLike => c !== null)
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
onDestroy(() => {
|
|
422
|
+
chartHandles.forEach(c => c.destroy())
|
|
423
|
+
chartHandles = []
|
|
424
|
+
})
|
|
425
|
+
</script>
|
|
426
|
+
|
|
427
|
+
@endsection
|