@stacksjs/defaults 0.75.244 → 0.75.246
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/ai/skills/stacks-dashboard/SKILL.md +2 -2
- package/ai/skills/stacks-native/CATALOG.md +7 -7
- package/ai/skills/stacks-path/SKILL.md +19 -1
- package/app/Actions/Dashboard/Models/ModelsIndexAction.ts +2 -1
- package/app/Actions/Dashboard/Search/GlobalSearchAction.ts +2 -1
- package/app/Actions/Dashboard/Source/source-inventory.ts +2 -1
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
- package/project/storage/framework/tsconfig.app.json +8 -0
- package/resources/components/Dashboard/Analytics/WebAnalyticsDashboard.stx +5 -5
- package/resources/components/Dashboard/Ci/CiDashboard.stx +2 -2
- package/resources/components/Dashboard/Ci/CiRunHistoryDrawer.stx +1 -1
- package/resources/components/Dashboard/Content/AuthorsDashboard.stx +59 -20
- package/resources/components/Dashboard/Content/BlogDashboard.stx +2 -2
- package/resources/components/Dashboard/Content/ContentDashboard.stx +2 -2
- package/resources/components/Dashboard/Content/ContentTaxonomyDashboard.stx +50 -18
- package/resources/components/Dashboard/Content/PagesDashboard.stx +54 -10
- package/resources/components/Dashboard/Content/PostsDashboard.stx +91 -20
- package/resources/components/Dashboard/Content/SeoDashboard.stx +61 -59
- package/resources/components/Dashboard/Email/InboxSettingsDashboard.stx +3 -3
- package/resources/components/Dashboard/Environment/EnvironmentDashboard.stx +1 -1
- package/resources/components/Dashboard/Kanban/KanbanBoardDashboard.stx +3 -3
- package/resources/components/Dashboard/Kanban/KanbanBoardsDashboard.stx +2 -2
- package/resources/components/Dashboard/Kanban/KanbanCardDialog.stx +1 -1
- package/resources/components/Dashboard/Library/ComponentsDashboard.stx +47 -81
- package/resources/components/Dashboard/Library/FunctionsDashboard.stx +24 -15
- package/resources/components/Dashboard/Library/PackagesDashboard.stx +68 -13
- package/resources/components/Dashboard/Management/PermissionsDashboard.stx +12 -15
- package/resources/components/Dashboard/Models/ModelRecordsDashboard.stx +3 -3
- package/resources/components/Dashboard/Settings/AppearanceSettingsDashboard.stx +3 -3
- package/resources/components/Dashboard/Settings/SettingsDashboard.stx +1 -1
- package/resources/components/Dashboard/Teams/TeamInvitationDashboard.stx +2 -2
- package/resources/components/Dashboard/UI/Button.stx +29 -3
- package/resources/components/Dashboard/UI/SearchFilter.stx +46 -0
- package/resources/components/Dashboard/UI/Table.stx +43 -20
- package/resources/functions/dashboard/data.ts +27 -4
- package/resources/functions/dashboard/sidebar.ts +3 -2
- package/resources/plugins/preloader.ts +9 -1
- package/views/dashboard/layouts/default.stx +17 -13
- package/views/system-tray/index.stx +1 -1
- package/resources/components/Dashboard/Commerce/Delivery/SearchFilter.stx +0 -24
- package/resources/components/Dashboard/UI/FilterBar.stx +0 -62
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-dashboard
|
|
3
|
-
description: Use when building or customizing the Stacks admin dashboard, including dashboard pages, model management views, analytics widgets, commerce dashboards, content management, settings panels, deployment monitoring, job/queue management, or the
|
|
3
|
+
description: Use when building or customizing the Stacks admin dashboard, including dashboard pages, model management views, analytics widgets, commerce dashboards, content management, settings panels, deployment monitoring, job/queue management, or the 413 built-in dashboard components. Covers the dashboard system at storage/framework/defaults/.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
6
|
allowed-tools: Read Edit Write Bash Grep Glob
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read Edit Write Bash Grep Glob
|
|
|
8
8
|
|
|
9
9
|
# Stacks Dashboard
|
|
10
10
|
|
|
11
|
-
The Stacks admin dashboard provides a full-featured admin panel with 100+ route views,
|
|
11
|
+
The Stacks admin dashboard provides a full-featured admin panel with 100+ route views, 413 components, and a multi-section layout.
|
|
12
12
|
|
|
13
13
|
## Key Paths
|
|
14
14
|
- Dashboard components: `storage/framework/defaults/resources/components/Dashboard/`
|
|
@@ -21,7 +21,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
|
|
|
21
21
|
| `@stacksjs/auth` | [`stacks-auth`](../stacks-auth/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/index.ts) | 119 |
|
|
22
22
|
| `@stacksjs/browser` | [`stacks-browser`](../stacks-browser/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser/src/index.ts) | 8 |
|
|
23
23
|
| `@stacksjs/browser-extension` | [`stacks-browser-extension`](../stacks-browser-extension/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/index.ts) | 7 |
|
|
24
|
-
| `@stacksjs/buddy` | [`stacks-buddy`](../stacks-buddy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/index.ts) |
|
|
24
|
+
| `@stacksjs/buddy` | [`stacks-buddy`](../stacks-buddy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/index.ts) | 153 |
|
|
25
25
|
| `@stacksjs/build` | [`stacks-build`](../stacks-build/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/build/src/index.ts) | 2 |
|
|
26
26
|
| `@stacksjs/cache` | [`stacks-cache`](../stacks-cache/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/src/index.ts) | 11 |
|
|
27
27
|
| `@stacksjs/calendar-api` | [`stacks-calendar`](../stacks-calendar/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/calendar-api/src/index.ts) | 2 |
|
|
@@ -67,7 +67,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
|
|
|
67
67
|
| `@stacksjs/objects` | [`stacks-objects`](../stacks-objects/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/objects/src/index.ts) | 4 |
|
|
68
68
|
| `@stacksjs/orm` | [`stacks-orm`](../stacks-orm/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/index.ts) | 64 |
|
|
69
69
|
| `@stacksjs/pagination` | [`stacks-pagination`](../stacks-pagination/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/pagination/src/index.ts) | 0 |
|
|
70
|
-
| `@stacksjs/path` | [`stacks-path`](../stacks-path/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/src/index.ts) |
|
|
70
|
+
| `@stacksjs/path` | [`stacks-path`](../stacks-path/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/src/index.ts) | 12 |
|
|
71
71
|
| `@stacksjs/payments` | [`stacks-payments`](../stacks-payments/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/index.ts) | 28 |
|
|
72
72
|
| `@stacksjs/push` | [`stacks-push`](../stacks-push/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/push/src/index.ts) | 6 |
|
|
73
73
|
| `@stacksjs/query-builder` | [`stacks-query-builder`](../stacks-query-builder/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/query-builder/src/index.ts) | 6 |
|
|
@@ -88,7 +88,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
|
|
|
88
88
|
| `@stacksjs/socials` | [`stacks-socials`](../stacks-socials/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/socials/src/index.ts) | 17 |
|
|
89
89
|
| `@stacksjs/storage` | [`stacks-storage`](../stacks-storage/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/index.ts) | 42 |
|
|
90
90
|
| `@stacksjs/strings` | [`stacks-strings`](../stacks-strings/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/strings/src/index.ts) | 7 |
|
|
91
|
-
| `@stacksjs/testing` | [`stacks-testing`](../stacks-testing/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/index.ts) |
|
|
91
|
+
| `@stacksjs/testing` | [`stacks-testing`](../stacks-testing/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/index.ts) | 18 |
|
|
92
92
|
| `@stacksjs/tinker` | [`stacks-repl`](../stacks-repl/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tinker/src/index.ts) | 1 |
|
|
93
93
|
| `@stacksjs/tunnel` | [`stacks-tunnel`](../stacks-tunnel/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tunnel/src/index.ts) | 1 |
|
|
94
94
|
| `@stacksjs/types` | [`stacks-types`](../stacks-types/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/types/src/index.ts) | 2 |
|
|
@@ -215,7 +215,7 @@ Read the entrypoint and package export map for re-exported or type-only surfaces
|
|
|
215
215
|
|
|
216
216
|
Local source modules: [src/commands/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/commands/index.ts).
|
|
217
217
|
|
|
218
|
-
Evidence directory: [
|
|
218
|
+
Evidence directory: [153 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
|
|
219
219
|
|
|
220
220
|
### @stacksjs/build
|
|
221
221
|
|
|
@@ -645,11 +645,11 @@ Declared runtime exports: `isCursorPaginator`, `isPaginator`, `isSimplePaginator
|
|
|
645
645
|
|
|
646
646
|
Guidance: [`stacks-path`](../stacks-path/SKILL.md). Source: [storage/framework/core/path/src/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/src/index.ts).
|
|
647
647
|
|
|
648
|
-
Declared runtime exports: `DEFAULTS_SYNC_MARKER`, `actionRunnerPath`, `actionsPath`, `aiPath`, `aliasPath`, `analyticsPath`, `appPath`, `applyRuntimeDirectoryEnv`, `arraysPath`, `assetsPath`, `authPath`, `basename`, `browserPath`, `buddyPath`, `buildEnginePath`, `buildPath`, `builtUserActionsPath`, `cachePath`, `chartsPath`, `chatPath`, `cliPath`, `cloudPath`, `cloudStatePath`, `collectionsPath`, `commandsPath`, `componentsPath`, `configPath`, `coreApiPath`, `coreEnvPath`, `corePath`, `coreStoragePath`, `customElementsDataPath`, `databasePath`, `datetimePath`, `defaultsAppPath`, `defaultsPackagePath`, `defaultsResourcesPath`, `delimiter`, `desktopPath`, `developmentPath`, `dirname`, `dnsPath`, `docsPath`, `emailPath`, `ensureRuntimeDirectories`, `enumsPath`, `errorHandlingPath`, `eslintPluginPath`, `eventsPath`, `examplesPath`, `extname`, `fakerPath`, `featureFlagsPath`, `featuresPath`, `findProjectPath`, `frameworkCloudPath`, `frameworkPath`, `frameworkRuntimePath`, `functionsPath`, `gitPath`, `healthPath`, `homeDir`, `inspectDefaultsProvenance`, `installedDefaultsVersion`, `isAbsolute`, `isCompiledBinary`, `jobsPath`, `join`, `langPath`, `layoutsPath`, `libraryPackagePath`, `libsEntriesPath`, `libsPath`, `lintPath`, `listenersPath`, `loggingPath`, `logsPath`, `mergeDirectoryInto`, `modelMetaPath`, `modelsPath`, `modulesPath`, `newsletterPath`, `normalize`, `notificationsPath`, `objectsPath`, `onboardingPath`, `ormPath`, `paginationPath`, `path`, `pathPath`, `paymentsPath`, `projectConfigPath`, `projectPath`, `publicPath`, `pushPath`, `queryBuilderPath`, `queuePath`, `realtimePath`, `relative`, `relativeActionsPath`, `replPath`, `resolve`, `resolveModulePath`, `resolveUserLibBase`, `resourcesPath`, `routerPath`, `routesPath`, `runtimeDirectoryEnv`, `runtimePath`, `schedulerPath`, `scriptsPath`, `searchEnginePath`, `securityPath`, `sep`, `serverPath`, `serverlessPath`, `settingsPath`, `shellPath`, `siteConfigPath`, `skillsPath`, `slugPath`, `smsPath`, `socialsPath`, `stacksBackupPath`, `stacksLockPath`, `stacksPath`, `storagePath`, `storesPath`, `stringsPath`, `stxPath`, `testingPath`, `testsPath`, `tinkerPath`, `toNamespacedPath`, `typesPath`, `uiPath`, `userActionsPath`, `userComponentsPath`, `userControllersPath`, `userDatabasePath`, `userEmailsPath`, `userEventsPath`, `userFunctionsPath`, `userJobsPath`, `userLibsPath`, `userListenersPath`, `userMailPath`, `userMiddlewarePath`, `userMigrationsPath`, `userModelsPath`, `userNotificationsPath`, `userServerPath`, `userViewsPath`, `utilsPath`, `validationPath`, `viewsPath`.
|
|
648
|
+
Declared runtime exports: `DEFAULTS_SYNC_MARKER`, `actionRunnerPath`, `actionsPath`, `aiPath`, `aliasPath`, `analyticsPath`, `appPath`, `applyRuntimeDirectoryEnv`, `arraysPath`, `assetsPath`, `authPath`, `basename`, `browserPath`, `buddyPath`, `buildEnginePath`, `buildPath`, `builtUserActionsPath`, `cachePath`, `chartsPath`, `chatPath`, `cliPath`, `cloudPath`, `cloudStatePath`, `collectionsPath`, `commandsPath`, `componentsPath`, `configPath`, `coreApiPath`, `coreEnvPath`, `corePath`, `coreStoragePath`, `customElementsDataPath`, `databasePath`, `datetimePath`, `defaultsAppPath`, `defaultsPackagePath`, `defaultsResourcesPath`, `delimiter`, `desktopPath`, `developmentPath`, `dirname`, `dnsPath`, `docsPath`, `emailPath`, `ensureRuntimeDirectories`, `enumsPath`, `errorHandlingPath`, `eslintPluginPath`, `eventsPath`, `examplesPath`, `extname`, `fakerPath`, `featureFlagsPath`, `featuresPath`, `findProjectPath`, `frameworkCloudPath`, `frameworkDefaultsRoot`, `frameworkPath`, `frameworkRuntimePath`, `functionsPath`, `gitPath`, `healthPath`, `homeDir`, `inspectDefaultsProvenance`, `installedDefaultsVersion`, `isAbsolute`, `isCompiledBinary`, `isInstalledDefaultsRoot`, `jobsPath`, `join`, `langPath`, `layoutsPath`, `libraryPackagePath`, `libsEntriesPath`, `libsPath`, `linkPackagedDefaults`, `lintPath`, `listenersPath`, `loggingPath`, `logsPath`, `mergeDirectoryInto`, `modelMetaPath`, `modelsPath`, `modulesPath`, `newsletterPath`, `normalize`, `notificationsPath`, `objectsPath`, `onboardingPath`, `ormPath`, `packagedDefaultsRoot`, `paginationPath`, `path`, `pathPath`, `paymentsPath`, `projectConfigPath`, `projectPath`, `publicPath`, `pushPath`, `queryBuilderPath`, `queuePath`, `realtimePath`, `relative`, `relativeActionsPath`, `replPath`, `resolve`, `resolveModulePath`, `resolveUserLibBase`, `resourcesPath`, `routerPath`, `routesPath`, `runtimeDirectoryEnv`, `runtimePath`, `schedulerPath`, `scriptsPath`, `searchEnginePath`, `securityPath`, `sep`, `serverPath`, `serverlessPath`, `settingsPath`, `shellPath`, `siteConfigPath`, `skillsPath`, `slugPath`, `smsPath`, `socialsPath`, `stacksBackupPath`, `stacksLockPath`, `stacksPath`, `storagePath`, `storesPath`, `stringsPath`, `stxPath`, `testingPath`, `testsPath`, `tinkerPath`, `toNamespacedPath`, `typesPath`, `uiPath`, `userActionsPath`, `userComponentsPath`, `userControllersPath`, `userDatabasePath`, `userEmailsPath`, `userEventsPath`, `userFunctionsPath`, `userJobsPath`, `userLibsPath`, `userListenersPath`, `userMailPath`, `userMiddlewarePath`, `userMigrationsPath`, `userModelsPath`, `userNotificationsPath`, `userServerPath`, `userViewsPath`, `usesVendoredDefaults`, `utilsPath`, `validationPath`, `viewsPath`.
|
|
649
649
|
|
|
650
650
|
Local source modules: [src/module-resolution.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/src/module-resolution.ts), [src/project.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/src/project.ts).
|
|
651
651
|
|
|
652
|
-
Evidence directory: [
|
|
652
|
+
Evidence directory: [12 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
|
|
653
653
|
|
|
654
654
|
### @stacksjs/payments
|
|
655
655
|
|
|
@@ -851,7 +851,7 @@ Read the entrypoint and package export map for re-exported or type-only surfaces
|
|
|
851
851
|
|
|
852
852
|
Local source modules: [src/console.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/console.ts), [src/disposable-database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/disposable-database.ts), [src/events.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/events.ts), [src/feature.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/feature.ts), [src/isolated.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/isolated.ts), [src/mail.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/mail.ts), [src/time.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/time.ts).
|
|
853
853
|
|
|
854
|
-
Evidence directory: [
|
|
854
|
+
Evidence directory: [18 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
|
|
855
855
|
|
|
856
856
|
### @stacksjs/tinker
|
|
857
857
|
|
|
@@ -91,11 +91,29 @@ buildEnginePath()
|
|
|
91
91
|
libsEntriesPath()
|
|
92
92
|
frameworkPath() // ~/storage/framework
|
|
93
93
|
corePath() // ~/storage/framework/core
|
|
94
|
-
frameworkPath('defaults') //
|
|
94
|
+
frameworkPath('defaults') // the defaults tree (see below)
|
|
95
95
|
defaultsAppPath()
|
|
96
96
|
defaultsResourcesPath()
|
|
97
|
+
frameworkDefaultsRoot() // where that tree actually is
|
|
98
|
+
usesVendoredDefaults() // true when it is a real directory
|
|
99
|
+
linkPackagedDefaults() // (re)create the link; boot calls it
|
|
97
100
|
```
|
|
98
101
|
|
|
102
|
+
`storagePath('framework/defaults/...')` and `frameworkPath('defaults/...')`
|
|
103
|
+
resolve to `storage/framework/defaults` only when that is a real, vendored
|
|
104
|
+
directory (the framework checkout, an app made with `--vendor-defaults` or
|
|
105
|
+
`buddy publish:defaults`). Otherwise they resolve to the installed
|
|
106
|
+
`node_modules/@stacksjs/defaults`. A new app keeps a gitignored
|
|
107
|
+
`storage/framework/defaults` link to the package for people and tools, but
|
|
108
|
+
framework code resolves the package itself: a module loaded through a link
|
|
109
|
+
created after the process started fails in Bun.
|
|
110
|
+
|
|
111
|
+
In code and templates, import a default by package name:
|
|
112
|
+
`@stacksjs/defaults/<path>.ts` in TypeScript, `@stacksjs/defaults/<path>` with
|
|
113
|
+
no extension in a `.stx` script (`stx typecheck` rejects `.ts` there). `storage/framework/tsconfig.app.json` maps that
|
|
114
|
+
onto a vendored tree when there is one and falls back to the package, so it
|
|
115
|
+
resolves in every layout; `~/storage/framework/defaults/...` does not.
|
|
116
|
+
|
|
99
117
|
### Relative Path Variants
|
|
100
118
|
Only some helpers have relative modes. Inspect the selected signature rather
|
|
101
119
|
than deriving a function name from another path helper:
|
|
@@ -2,6 +2,7 @@ import { Action } from '@stacksjs/actions/runtime'
|
|
|
2
2
|
import { existsSync, readdirSync } from 'node:fs'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
import process from 'node:process'
|
|
5
|
+
import { frameworkDefaultsRoot } from '@stacksjs/path'
|
|
5
6
|
import { countRows } from '../../../../resources/functions/dashboard/data'
|
|
6
7
|
import { dashboardOperationalError, dashboardOperationalIssue } from '../dashboard-response'
|
|
7
8
|
import { resolveDashboardModel } from '../../../../resources/functions/dashboard/model-access'
|
|
@@ -123,7 +124,7 @@ export default new Action({
|
|
|
123
124
|
async handle() {
|
|
124
125
|
const cwd = process.cwd()
|
|
125
126
|
const userlandDir = join(cwd, 'app', 'Models')
|
|
126
|
-
const defaultsDir = join(
|
|
127
|
+
const defaultsDir = join(frameworkDefaultsRoot(), 'app/Models')
|
|
127
128
|
|
|
128
129
|
let userland: Array<Omit<DiscoveredModel, 'source'>>
|
|
129
130
|
let defaults: Array<Omit<DiscoveredModel, 'source'>>
|
|
@@ -4,6 +4,7 @@ import { env } from '@stacksjs/env'
|
|
|
4
4
|
import { readdirSync } from 'node:fs'
|
|
5
5
|
import { basename, extname, join } from 'node:path'
|
|
6
6
|
import process from 'node:process'
|
|
7
|
+
import { frameworkDefaultsRoot } from '@stacksjs/path'
|
|
7
8
|
import { resolveDashboardModel } from '../../../../resources/functions/dashboard/model-access'
|
|
8
9
|
import { dashboardOperationalError } from '../dashboard-response'
|
|
9
10
|
|
|
@@ -114,7 +115,7 @@ function iconForModel(name: string): string {
|
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
async function loadSearchableModels(): Promise<SearchableModel[]> {
|
|
117
|
-
const defaultsRoot = join(
|
|
118
|
+
const defaultsRoot = join(frameworkDefaultsRoot(), 'app/Models')
|
|
118
119
|
const userRoot = join(process.cwd(), 'app/Models')
|
|
119
120
|
const merged = new Map<string, string>()
|
|
120
121
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, statSync } from 'node:fs'
|
|
2
2
|
import { basename, join, relative } from 'node:path'
|
|
3
|
+
import { frameworkDefaultsRoot } from '@stacksjs/path'
|
|
3
4
|
|
|
4
5
|
export interface SourceInventoryItem {
|
|
5
6
|
name: string
|
|
@@ -71,7 +72,7 @@ export function parseCommandSource(
|
|
|
71
72
|
export async function discoverActionSources(projectRoot: string): Promise<SourceInventoryItem[]> {
|
|
72
73
|
const roots: SourceRoot[] = [
|
|
73
74
|
{
|
|
74
|
-
directory: join(projectRoot, '
|
|
75
|
+
directory: join(frameworkDefaultsRoot(projectRoot), 'app/Actions'),
|
|
75
76
|
origin: 'Framework',
|
|
76
77
|
},
|
|
77
78
|
{
|
package/ide/vscode/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"publisher": "Stacks",
|
|
3
3
|
"name": "vscode-stacks",
|
|
4
4
|
"displayName": "Stacks",
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.246",
|
|
6
6
|
"description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.246",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@iconify-json/f7": "^1.2.2",
|
|
46
46
|
"@iconify-json/hugeicons": "^1.2.35",
|
|
47
|
-
"@stacksjs/mobile": "0.75.
|
|
47
|
+
"@stacksjs/mobile": "0.75.246",
|
|
48
48
|
"@stacksjs/sanitizer": "^0.2.534",
|
|
49
49
|
"@xterm/addon-fit": "^0.11.0",
|
|
50
50
|
"@xterm/xterm": "^6.0.0",
|
|
@@ -17,6 +17,14 @@
|
|
|
17
17
|
"Middleware/*": ["../../app/Middleware/*"],
|
|
18
18
|
"Models/*": ["../../app/Models/*"],
|
|
19
19
|
"Notifications/*": ["../../app/Notifications/*"],
|
|
20
|
+
// The framework defaults by package name. Lands on this project's
|
|
21
|
+
// `storage/framework/defaults` when there is one (a framework checkout, a
|
|
22
|
+
// vendored app, or the link to node_modules), and falls back to the
|
|
23
|
+
// installed `@stacksjs/defaults` when the mapped file does not exist -
|
|
24
|
+
// Bun and tsc both try the package after a `paths` miss. So one
|
|
25
|
+
// specifier resolves in every layout, which `~/storage/framework/
|
|
26
|
+
// defaults/...` does not.
|
|
27
|
+
"@stacksjs/defaults/*": ["./defaults/*"],
|
|
20
28
|
"~/*": ["../../*"],
|
|
21
29
|
"@/*": ["../../resources/*"]
|
|
22
30
|
}
|
|
@@ -208,11 +208,11 @@ import type {
|
|
|
208
208
|
PageData,
|
|
209
209
|
ReferrerData,
|
|
210
210
|
TrafficDataPoint,
|
|
211
|
-
} from '
|
|
212
|
-
import { fetchWebAnalytics } from '
|
|
213
|
-
import { pushToast } from '
|
|
214
|
-
import type { ChartCtor, ChartLike } from '
|
|
215
|
-
import { useChart } from '
|
|
211
|
+
} from '@stacksjs/defaults/functions/analytics'
|
|
212
|
+
import { fetchWebAnalytics } from '@stacksjs/defaults/functions/analytics'
|
|
213
|
+
import { pushToast } from '@stacksjs/defaults/functions/toasts'
|
|
214
|
+
import type { ChartCtor, ChartLike } from '@stacksjs/defaults/views/dashboard/composables/useChart'
|
|
215
|
+
import { useChart } from '@stacksjs/defaults/views/dashboard/composables/useChart'
|
|
216
216
|
|
|
217
217
|
const analyticsOverview = state<AnalyticsOverview>({
|
|
218
218
|
realtimeVisitors: 0,
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
//
|
|
8
8
|
// No <script server>, no window./document. reads - per #1838 the page
|
|
9
9
|
// is pure presentation against the store.
|
|
10
|
-
import { useRole } from '
|
|
11
|
-
import { ciStore } from '
|
|
10
|
+
import { useRole } from '@stacksjs/defaults/views/dashboard/composables/useRole'
|
|
11
|
+
import { ciStore } from '@stacksjs/defaults/views/dashboard/stores/ci'
|
|
12
12
|
|
|
13
13
|
// Import the store definition directly so its typed setup and persistence
|
|
14
14
|
// are part of this page's client bundle. A name-only useStore('ci') lookup
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import('../UI/Table')
|
|
2
|
+
|
|
1
3
|
<script client>
|
|
2
4
|
import { dashboardApi } from '../../../../functions/dashboard-api'
|
|
3
5
|
import { pushToast } from '../../../../functions/toasts'
|
|
@@ -23,7 +25,6 @@ const authors = state<AuthorRecord[]>([])
|
|
|
23
25
|
const assignedPostCount = state(0)
|
|
24
26
|
const loading = state(true)
|
|
25
27
|
const loadError = state('')
|
|
26
|
-
const search = state('')
|
|
27
28
|
const formOpen = state(false)
|
|
28
29
|
const editingAuthor = state<AuthorRecord | null>(null)
|
|
29
30
|
const saving = state(false)
|
|
@@ -44,10 +45,33 @@ function normalize(record: any): AuthorRecord {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const COLUMNS = [
|
|
49
|
+
// Slotted: the cell is an avatar, or the author's initials when there is no
|
|
50
|
+
// image, with the name and email beside it.
|
|
51
|
+
{ key: 'name', label: 'Author', sortable: true, slotted: true },
|
|
52
|
+
{ key: 'postCount', label: 'Posts', type: 'number' as const, sortable: true, class: 'text-gray-500 dark:text-neutral-400' },
|
|
53
|
+
{ key: 'createdAt', label: 'Created', type: 'date' as const, sortable: true, emptyText: 'Unknown', class: 'text-gray-500 dark:text-neutral-400' },
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
const ROW_ACTIONS = [
|
|
57
|
+
{ action: 'edit', label: 'Edit author', icon: 'i-hugeicons-edit-02' },
|
|
58
|
+
{ action: 'delete', label: 'Delete author', icon: 'i-hugeicons-delete-02', class: 'text-red-500' },
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* `UI/Table` owns the search. `initialsLabel` is computed per row rather than
|
|
63
|
+
* called from the slot, because a slot body reads the row through attribute
|
|
64
|
+
* bindings and keeping the derivation here is one less thing to depend on.
|
|
65
|
+
*/
|
|
66
|
+
function visibleAuthors(): Array<AuthorRecord & { initialsLabel: string }> {
|
|
67
|
+
return authors().map(author => ({ ...author, initialsLabel: initials(author.name) }))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function handleRowAction(payload: { action: string, row: AuthorRecord }): void {
|
|
71
|
+
if (payload.action === 'edit')
|
|
72
|
+
openEdit(payload.row)
|
|
73
|
+
else
|
|
74
|
+
openDelete(payload.row)
|
|
51
75
|
}
|
|
52
76
|
|
|
53
77
|
function initials(value: string): string {
|
|
@@ -55,15 +79,6 @@ function initials(value: string): string {
|
|
|
55
79
|
.map(part => part[0]?.toUpperCase() || '').join('') || '?'
|
|
56
80
|
}
|
|
57
81
|
|
|
58
|
-
function formatDate(value: string): string {
|
|
59
|
-
if (!value)
|
|
60
|
-
return 'Unknown'
|
|
61
|
-
const date = new Date(value)
|
|
62
|
-
return Number.isNaN(date.getTime())
|
|
63
|
-
? value
|
|
64
|
-
: new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric', year: 'numeric' }).format(date)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
82
|
async function loadAuthors(): Promise<void> {
|
|
68
83
|
loading.set(true)
|
|
69
84
|
loadError.set('')
|
|
@@ -185,12 +200,36 @@ onMount(() => {
|
|
|
185
200
|
</section>
|
|
186
201
|
|
|
187
202
|
<section class="overflow-hidden bg-white dark:bg-neutral-800 border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
203
|
+
{{-- Slot bodies read the row through `x-text` and `:attr`; an
|
|
204
|
+
interpolation in slot content is preserved but not evaluated on the
|
|
205
|
+
installed stx. See stacksjs/stx#2095. --}}
|
|
206
|
+
<Table
|
|
207
|
+
:columns="COLUMNS"
|
|
208
|
+
:data="visibleAuthors()"
|
|
209
|
+
:loading="loading()"
|
|
210
|
+
:row-actions="ROW_ACTIONS"
|
|
211
|
+
action-label-key="name"
|
|
212
|
+
searchable
|
|
213
|
+
search-placeholder="Search authors"
|
|
214
|
+
paginated
|
|
215
|
+
:page-size="25"
|
|
216
|
+
empty-title="No authors found"
|
|
217
|
+
empty-description="Adjust the search or create an author."
|
|
218
|
+
@row-action="handleRowAction"
|
|
219
|
+
>
|
|
220
|
+
<template #cell="{ row }">
|
|
221
|
+
<div class="flex gap-3 items-center">
|
|
222
|
+
<div class="flex overflow-hidden flex-shrink-0 items-center justify-center h-9 w-9 font-semibold text-blue-700 text-xs dark:text-blue-300 bg-blue-50 dark:bg-blue-950/50 rounded-full">
|
|
223
|
+
<img :if="row.avatar" :src="row.avatar" :alt="row.name" class="object-cover h-full w-full" />
|
|
224
|
+
<span :else x-text="row.initialsLabel"></span>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="min-w-0">
|
|
227
|
+
<p class="font-medium text-gray-900 text-sm truncate dark:text-white" x-text="row.name"></p>
|
|
228
|
+
<p class="text-gray-500 text-xs truncate dark:text-neutral-400" x-text="row.email"></p>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
</template>
|
|
232
|
+
</Table>
|
|
194
233
|
</section>
|
|
195
234
|
</div>
|
|
196
235
|
|
|
@@ -202,8 +202,8 @@ defineClientPayload({ blogUrl })
|
|
|
202
202
|
<script client>
|
|
203
203
|
// Plain async transport for /api/dashboard/blog, which reads and writes the
|
|
204
204
|
// markdown files in content/blog. It owns no state; the signals below do.
|
|
205
|
-
import type { BlogPost, BlogPostDraft } from '
|
|
206
|
-
import { deleteBlogPost, fetchBlogPost, fetchBlogPosts, saveBlogPost } from '
|
|
205
|
+
import type { BlogPost, BlogPostDraft } from '@stacksjs/defaults/functions/blog'
|
|
206
|
+
import { deleteBlogPost, fetchBlogPost, fetchBlogPosts, saveBlogPost } from '@stacksjs/defaults/functions/blog'
|
|
207
207
|
|
|
208
208
|
const publicBlogBaseUrl = {{ blogUrl }}
|
|
209
209
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script client>
|
|
2
2
|
import { dashboardApi } from '../../../../functions/dashboard-api'
|
|
3
3
|
import { pushToast } from '../../../../functions/toasts'
|
|
4
|
-
import type { ChartCtor, ChartDataset, ChartLike, ChartOptions } from '
|
|
5
|
-
import { useChart } from '
|
|
4
|
+
import type { ChartCtor, ChartDataset, ChartLike, ChartOptions } from '@stacksjs/defaults/views/dashboard/composables/useChart'
|
|
5
|
+
import { useChart } from '@stacksjs/defaults/views/dashboard/composables/useChart'
|
|
6
6
|
|
|
7
7
|
interface ContentPostSummary {
|
|
8
8
|
id: number
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import('../UI/Table')
|
|
2
|
+
|
|
1
3
|
<script client>
|
|
2
4
|
import { dashboardApi } from '../../../../functions/dashboard-api'
|
|
3
5
|
import { pushToast } from '../../../../functions/toasts'
|
|
@@ -23,7 +25,6 @@ const description = useReactiveProp('description', '')
|
|
|
23
25
|
const records = state<TaxonomyRecord[]>([])
|
|
24
26
|
const loading = state(true)
|
|
25
27
|
const loadError = state('')
|
|
26
|
-
const search = state('')
|
|
27
28
|
const dialogOpen = state(false)
|
|
28
29
|
const saving = state(false)
|
|
29
30
|
const saveError = state('')
|
|
@@ -46,13 +47,41 @@ function normalize(record: any): TaxonomyRecord {
|
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Derived rather than constant: this component serves both categories and
|
|
52
|
+
* tags, and the fourth column is the post count for tags and the active state
|
|
53
|
+
* for categories - a different heading and a different value.
|
|
54
|
+
*/
|
|
55
|
+
function columns() {
|
|
56
|
+
return [
|
|
57
|
+
{ key: 'name', label: 'Name', sortable: true, class: 'font-medium text-gray-900 dark:text-white' },
|
|
58
|
+
{ key: 'slug', label: 'Slug', sortable: true, class: 'font-mono text-gray-500 dark:text-neutral-400' },
|
|
59
|
+
{ key: 'description', label: 'Description', emptyText: 'No description', class: 'max-w-md truncate text-gray-500 dark:text-neutral-400' },
|
|
60
|
+
{
|
|
61
|
+
key: 'stateLabel',
|
|
62
|
+
label: resource() === 'tags' ? 'Posts' : 'Status',
|
|
63
|
+
sortable: true,
|
|
64
|
+
class: 'text-gray-500 dark:text-neutral-400',
|
|
65
|
+
},
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const ROW_ACTIONS = [
|
|
70
|
+
{ action: 'delete', label: 'Delete', icon: 'i-hugeicons-delete-02', class: 'text-red-500' },
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
/** `UI/Table` owns the search; the fourth cell is derived onto the row. */
|
|
49
74
|
function visibleRecords(): TaxonomyRecord[] {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
75
|
+
return records().map(record => ({
|
|
76
|
+
...record,
|
|
77
|
+
stateLabel: resource() === 'tags'
|
|
78
|
+
? String(record.postCount)
|
|
79
|
+
: record.active ? 'Active' : 'Inactive',
|
|
80
|
+
})) as TaxonomyRecord[]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function handleRowAction(payload: { action: string, row: TaxonomyRecord }): void {
|
|
84
|
+
openDelete(payload.row)
|
|
56
85
|
}
|
|
57
86
|
|
|
58
87
|
function secondaryMetricLabel(): string {
|
|
@@ -184,17 +213,20 @@ onMount(() => {
|
|
|
184
213
|
</section>
|
|
185
214
|
|
|
186
215
|
<section class="overflow-hidden max-w-full min-w-0 bg-white dark:bg-neutral-800 border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
216
|
+
<Table
|
|
217
|
+
:columns="columns()"
|
|
218
|
+
:data="visibleRecords()"
|
|
219
|
+
:loading="loading()"
|
|
220
|
+
:row-actions="ROW_ACTIONS"
|
|
221
|
+
action-label-key="name"
|
|
222
|
+
searchable
|
|
223
|
+
:search-placeholder="'Search ' + resource()"
|
|
224
|
+
paginated
|
|
225
|
+
:page-size="25"
|
|
226
|
+
:empty-title="'No ' + resource() + ' found'"
|
|
227
|
+
:empty-description="'Adjust the search or create a ' + singular() + '.'"
|
|
228
|
+
@row-action="handleRowAction"
|
|
229
|
+
/>
|
|
198
230
|
</section>
|
|
199
231
|
</div>
|
|
200
232
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import('../UI/Table')
|
|
2
|
+
|
|
1
3
|
<script client>
|
|
2
4
|
import { dashboardApi } from '../../../../functions/dashboard-api'
|
|
3
5
|
import { pushToast } from '../../../../functions/toasts'
|
|
@@ -20,7 +22,6 @@ interface PageDraft {
|
|
|
20
22
|
const pages = state<PageRecord[]>([])
|
|
21
23
|
const loading = state(true)
|
|
22
24
|
const loadError = state('')
|
|
23
|
-
const search = state('')
|
|
24
25
|
const formOpen = state(false)
|
|
25
26
|
const editingPage = state<PageRecord | null>(null)
|
|
26
27
|
const saving = state(false)
|
|
@@ -40,10 +41,45 @@ function normalize(record: any): PageRecord {
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
const COLUMNS = [
|
|
45
|
+
{ key: 'title', label: 'Page', sortable: true, subtitleKey: 'template', class: 'font-medium text-gray-900 dark:text-white' },
|
|
46
|
+
{ key: 'viewsLabel', label: 'Traffic', subtitleKey: 'conversionsLabel', class: 'text-gray-500 dark:text-neutral-400' },
|
|
47
|
+
{
|
|
48
|
+
key: 'publishState',
|
|
49
|
+
label: 'Publishing',
|
|
50
|
+
type: 'badge' as const,
|
|
51
|
+
sortable: true,
|
|
52
|
+
// Coloured by state, labelled with the date it happened - which is why
|
|
53
|
+
// `badgeLabels` cannot express it.
|
|
54
|
+
badgeLabelKey: 'publishedLabel',
|
|
55
|
+
badgeClasses: {
|
|
56
|
+
published: 'text-green-700 dark:text-green-300 bg-green-50 dark:bg-green-950/40',
|
|
57
|
+
draft: 'text-gray-600 dark:text-neutral-300 bg-gray-100 dark:bg-neutral-700',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
const ROW_ACTIONS = [
|
|
63
|
+
{ action: 'edit', label: 'Edit page', icon: 'i-hugeicons-edit-02' },
|
|
64
|
+
{ action: 'delete', label: 'Delete page', icon: 'i-hugeicons-delete-02', class: 'text-red-500' },
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
/** `UI/Table` owns the search; the cells each read a field, so derive them. */
|
|
43
68
|
function visiblePages(): PageRecord[] {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
69
|
+
return pages().map(page => ({
|
|
70
|
+
...page,
|
|
71
|
+
viewsLabel: `${formatNumber(page.views)} views`,
|
|
72
|
+
conversionsLabel: `${formatNumber(page.conversions)} conversions`,
|
|
73
|
+
publishState: page.publishedAt ? 'published' : 'draft',
|
|
74
|
+
publishedLabel: formatDate(page.publishedAt),
|
|
75
|
+
})) as PageRecord[]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function handleRowAction(payload: { action: string, row: PageRecord }): void {
|
|
79
|
+
if (payload.action === 'edit')
|
|
80
|
+
openEdit(payload.row)
|
|
81
|
+
else
|
|
82
|
+
openDelete(payload.row)
|
|
47
83
|
}
|
|
48
84
|
|
|
49
85
|
function totalViews(): number {
|
|
@@ -179,12 +215,20 @@ onMount(() => {
|
|
|
179
215
|
</section>
|
|
180
216
|
|
|
181
217
|
<section class="overflow-hidden bg-white dark:bg-neutral-800 border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
218
|
+
<Table
|
|
219
|
+
:columns="COLUMNS"
|
|
220
|
+
:data="visiblePages()"
|
|
221
|
+
:loading="loading()"
|
|
222
|
+
:row-actions="ROW_ACTIONS"
|
|
223
|
+
action-label-key="title"
|
|
224
|
+
searchable
|
|
225
|
+
search-placeholder="Search pages"
|
|
226
|
+
paginated
|
|
227
|
+
:page-size="25"
|
|
228
|
+
empty-title="No pages found"
|
|
229
|
+
empty-description="Adjust the search or create a page."
|
|
230
|
+
@row-action="handleRowAction"
|
|
231
|
+
/>
|
|
188
232
|
</section>
|
|
189
233
|
</div>
|
|
190
234
|
|