@nextsparkjs/core 0.1.0-beta.45 → 0.1.0-beta.46
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/dist/styles/classes.json +1 -1
- package/dist/templates/contents/themes/starter/config/permissions.config.ts +28 -0
- package/dist/types/api-presets.d.ts +4 -0
- package/dist/types/api-presets.d.ts.map +1 -1
- package/package.json +23 -2
- package/scripts/build/registry/config.mjs +28 -6
- package/scripts/build/theme.mjs +72 -3
- package/styles/docs.css +82 -0
- package/styles/utilities.css +37 -0
- package/templates/contents/themes/starter/config/permissions.config.ts +28 -0
package/dist/styles/classes.json
CHANGED
|
@@ -58,6 +58,34 @@ export const PERMISSIONS_CONFIG_OVERRIDES: ThemePermissionsConfig = {
|
|
|
58
58
|
{ action: 'delete', label: 'Delete tasks', description: 'Can delete tasks', roles: ['owner', 'admin'], dangerous: true },
|
|
59
59
|
{ action: 'assign', label: 'Assign tasks', description: 'Can assign tasks to team members', roles: ['owner', 'admin'] },
|
|
60
60
|
],
|
|
61
|
+
|
|
62
|
+
// ------------------------------------------
|
|
63
|
+
// PAGES ENTITY (uncommented by CLI if pages feature enabled)
|
|
64
|
+
// ------------------------------------------
|
|
65
|
+
// __PAGES_PERMISSIONS_START__
|
|
66
|
+
// pages: [
|
|
67
|
+
// { action: 'create', label: 'Create Pages', description: 'Can create new pages', roles: ['owner', 'admin'] },
|
|
68
|
+
// { action: 'read', label: 'View Pages', description: 'Can view page details', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
69
|
+
// { action: 'list', label: 'List Pages', description: 'Can see the pages list', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
70
|
+
// { action: 'update', label: 'Edit Pages', description: 'Can modify page content', roles: ['owner', 'admin'] },
|
|
71
|
+
// { action: 'delete', label: 'Delete Pages', description: 'Can delete pages', roles: ['owner', 'admin'], dangerous: true },
|
|
72
|
+
// { action: 'publish', label: 'Publish Pages', description: 'Can publish pages to make them public', roles: ['owner', 'admin'] },
|
|
73
|
+
// ],
|
|
74
|
+
// __PAGES_PERMISSIONS_END__
|
|
75
|
+
|
|
76
|
+
// ------------------------------------------
|
|
77
|
+
// POSTS ENTITY (uncommented by CLI if blog feature enabled)
|
|
78
|
+
// ------------------------------------------
|
|
79
|
+
// __POSTS_PERMISSIONS_START__
|
|
80
|
+
// posts: [
|
|
81
|
+
// { action: 'create', label: 'Create Posts', description: 'Can create new blog posts', roles: ['owner', 'admin', 'member'] },
|
|
82
|
+
// { action: 'read', label: 'View Posts', description: 'Can view post details', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
83
|
+
// { action: 'list', label: 'List Posts', description: 'Can see the posts list', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
84
|
+
// { action: 'update', label: 'Edit Posts', description: 'Can modify post content', roles: ['owner', 'admin', 'member'] },
|
|
85
|
+
// { action: 'delete', label: 'Delete Posts', description: 'Can delete posts', roles: ['owner', 'admin'], dangerous: true },
|
|
86
|
+
// { action: 'publish', label: 'Publish Posts', description: 'Can publish posts to make them public', roles: ['owner', 'admin'] },
|
|
87
|
+
// ],
|
|
88
|
+
// __POSTS_PERMISSIONS_END__
|
|
61
89
|
},
|
|
62
90
|
}
|
|
63
91
|
|
|
@@ -37,10 +37,14 @@ export interface ApiPreset {
|
|
|
37
37
|
description?: string;
|
|
38
38
|
/** HTTP method for this preset */
|
|
39
39
|
method: HttpMethod;
|
|
40
|
+
/** Path suffix for sub-routes (e.g., '/{id}', '/{id}/child/{childType}') */
|
|
41
|
+
path?: string;
|
|
40
42
|
/** Path parameters (for dynamic segments like [id]) */
|
|
41
43
|
pathParams?: Record<string, string>;
|
|
42
44
|
/** Query parameters */
|
|
43
45
|
params?: Record<string, string | number | boolean>;
|
|
46
|
+
/** Query parameters (alias for params) */
|
|
47
|
+
queryParams?: Record<string, string | number | boolean>;
|
|
44
48
|
/** Custom headers */
|
|
45
49
|
headers?: Record<string, string>;
|
|
46
50
|
/** Request body (for POST/PATCH/PUT) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-presets.d.ts","sourceRoot":"","sources":["../../src/types/api-presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAA;AAEnF;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yBAAyB;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kCAAkC;IAClC,MAAM,EAAE,UAAU,CAAA;IAClB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;IAClD,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,iCAAiC;IACjC,aAAa,CAAC,EAAE,mBAAmB,CAAA;IACnC,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,wEAAwE;AACxE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;AAEzD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yCAAyC;IACzC,OAAO,EAAE,SAAS,EAAE,CAAA;IACpB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,MAAM,CAAC,EAAE,eAAe,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC7C,eAAe;IACf,IAAI,EAAE;QACJ,cAAc,EAAE,MAAM,CAAA;QACtB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAA;IACb,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,MAAM,CAAC,EAAE,eAAe,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACjC,eAAe;IACf,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAC,GAC7C,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAExC"}
|
|
1
|
+
{"version":3,"file":"api-presets.d.ts","sourceRoot":"","sources":["../../src/types/api-presets.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextsparkjs/core",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.46",
|
|
4
4
|
"description": "NextSpark - The complete SaaS framework for Next.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "NextSpark <hello@nextspark.dev>",
|
|
@@ -96,6 +96,22 @@
|
|
|
96
96
|
"types": "./dist/lib/scheduled-actions/index.d.ts",
|
|
97
97
|
"import": "./dist/lib/scheduled-actions/index.js"
|
|
98
98
|
},
|
|
99
|
+
"./lib/permissions": {
|
|
100
|
+
"types": "./dist/lib/permissions/index.d.ts",
|
|
101
|
+
"import": "./dist/lib/permissions/index.js"
|
|
102
|
+
},
|
|
103
|
+
"./lib/permissions/system": {
|
|
104
|
+
"types": "./dist/lib/permissions/system.d.ts",
|
|
105
|
+
"import": "./dist/lib/permissions/system.js"
|
|
106
|
+
},
|
|
107
|
+
"./lib/permissions/types": {
|
|
108
|
+
"types": "./dist/lib/permissions/types.d.ts",
|
|
109
|
+
"import": "./dist/lib/permissions/types.js"
|
|
110
|
+
},
|
|
111
|
+
"./lib/config/config-sync": {
|
|
112
|
+
"types": "./dist/lib/config/config-sync.d.ts",
|
|
113
|
+
"import": "./dist/lib/config/config-sync.js"
|
|
114
|
+
},
|
|
99
115
|
"./lib/*": {
|
|
100
116
|
"types": "./dist/lib/*.d.ts",
|
|
101
117
|
"import": "./dist/lib/*.js"
|
|
@@ -104,6 +120,10 @@
|
|
|
104
120
|
"types": "./dist/hooks/index.d.ts",
|
|
105
121
|
"import": "./dist/hooks/index.js"
|
|
106
122
|
},
|
|
123
|
+
"./hooks/teams": {
|
|
124
|
+
"types": "./dist/hooks/teams/index.d.ts",
|
|
125
|
+
"import": "./dist/hooks/teams/index.js"
|
|
126
|
+
},
|
|
107
127
|
"./hooks/*": {
|
|
108
128
|
"types": "./dist/hooks/*.d.ts",
|
|
109
129
|
"import": "./dist/hooks/*.js"
|
|
@@ -219,6 +239,7 @@
|
|
|
219
239
|
},
|
|
220
240
|
"files": [
|
|
221
241
|
"dist",
|
|
242
|
+
"styles",
|
|
222
243
|
"templates",
|
|
223
244
|
"migrations",
|
|
224
245
|
"tests/cypress/support",
|
|
@@ -320,7 +341,7 @@
|
|
|
320
341
|
"tailwind-merge": "^3.3.1",
|
|
321
342
|
"uuid": "^13.0.0",
|
|
322
343
|
"zod": "^4.1.5",
|
|
323
|
-
"@nextsparkjs/testing": "0.1.0-beta.
|
|
344
|
+
"@nextsparkjs/testing": "0.1.0-beta.46"
|
|
324
345
|
},
|
|
325
346
|
"scripts": {
|
|
326
347
|
"build": "tsup && pnpm build:dts && pnpm build:ui-css",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { join, dirname } from 'path'
|
|
16
16
|
import { fileURLToPath } from 'url'
|
|
17
|
-
import { existsSync, lstatSync } from 'fs'
|
|
17
|
+
import { existsSync, lstatSync, readlinkSync } from 'fs'
|
|
18
18
|
import dotenv from 'dotenv'
|
|
19
19
|
import { loadNextSparkConfigSync } from '../config-loader.mjs'
|
|
20
20
|
|
|
@@ -86,9 +86,15 @@ export function detectProjectRoot() {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
|
-
* Check if NextSpark is installed as a package (
|
|
89
|
+
* Check if NextSpark is installed as a package (from npm registry)
|
|
90
|
+
*
|
|
91
|
+
* This handles both traditional npm/yarn AND pnpm:
|
|
92
|
+
* - npm/yarn: packages are copied to node_modules (not symlinks)
|
|
93
|
+
* - pnpm: ALL packages are symlinks, but npm packages point to .pnpm/ store
|
|
94
|
+
* - pnpm workspace: local packages symlink to the actual package path
|
|
95
|
+
*
|
|
90
96
|
* @param {string} root - Project root path
|
|
91
|
-
* @returns {boolean} True if installed
|
|
97
|
+
* @returns {boolean} True if installed from npm registry
|
|
92
98
|
*/
|
|
93
99
|
export function isInstalledAsPackage(root) {
|
|
94
100
|
const corePath = join(root, 'node_modules/@nextsparkjs/core')
|
|
@@ -96,11 +102,27 @@ export function isInstalledAsPackage(root) {
|
|
|
96
102
|
return false
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
// In monorepo mode with pnpm workspaces, packages are symlinked
|
|
100
|
-
// A real npm installation is not a symlink
|
|
101
105
|
try {
|
|
102
106
|
const stat = lstatSync(corePath)
|
|
103
|
-
|
|
107
|
+
|
|
108
|
+
// If not a symlink, it's a traditional npm/yarn install
|
|
109
|
+
if (!stat.isSymbolicLink()) {
|
|
110
|
+
return true
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// For symlinks (pnpm), check WHERE it points to:
|
|
114
|
+
// - npm install: points to .pnpm/@nextsparkjs+core@version.../node_modules/@nextsparkjs/core
|
|
115
|
+
// - workspace: points to ../../packages/core or similar
|
|
116
|
+
const linkTarget = readlinkSync(corePath)
|
|
117
|
+
|
|
118
|
+
// If symlink points to .pnpm/ directory, it's a real npm installation via pnpm
|
|
119
|
+
// The .pnpm directory is pnpm's content-addressable store
|
|
120
|
+
if (linkTarget.includes('.pnpm/') || linkTarget.includes('.pnpm\\')) {
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Otherwise it's a workspace symlink (monorepo development)
|
|
125
|
+
return false
|
|
104
126
|
} catch {
|
|
105
127
|
return false
|
|
106
128
|
}
|
package/scripts/build/theme.mjs
CHANGED
|
@@ -32,6 +32,75 @@ function getActiveTheme() {
|
|
|
32
32
|
return process.env.NEXT_PUBLIC_ACTIVE_THEME
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Sync app/globals.css to import from the active theme
|
|
37
|
+
*
|
|
38
|
+
* This ensures the import path in app/globals.css always matches
|
|
39
|
+
* NEXT_PUBLIC_ACTIVE_THEME, handling both npm and monorepo modes.
|
|
40
|
+
*
|
|
41
|
+
* @param {object} config - Configuration from getConfig()
|
|
42
|
+
* @param {string} activeTheme - Active theme name
|
|
43
|
+
* @returns {boolean} - True if file was updated, false if already correct
|
|
44
|
+
*/
|
|
45
|
+
function syncAppGlobalsCss(config, activeTheme) {
|
|
46
|
+
const appGlobalsCssPath = path.join(config.projectRoot, 'app', 'globals.css')
|
|
47
|
+
|
|
48
|
+
// Calculate the correct relative path from app/ to theme globals.css
|
|
49
|
+
const appDir = path.join(config.projectRoot, 'app')
|
|
50
|
+
const themeGlobalsPath = path.join(config.themesDir, activeTheme, 'styles', 'globals.css')
|
|
51
|
+
const relativePath = path.relative(appDir, themeGlobalsPath)
|
|
52
|
+
|
|
53
|
+
// Expected import statement
|
|
54
|
+
const expectedImport = `@import "${relativePath}";`
|
|
55
|
+
|
|
56
|
+
// Template for app/globals.css
|
|
57
|
+
const template = `/* =============================================
|
|
58
|
+
GLOBAL STYLES - Import from Active Theme
|
|
59
|
+
|
|
60
|
+
This file imports styles from the active theme.
|
|
61
|
+
DO NOT edit directly - all styles are in:
|
|
62
|
+
contents/themes/{theme}/styles/globals.css
|
|
63
|
+
|
|
64
|
+
To customize colors, typography and tokens, edit
|
|
65
|
+
the globals.css file in your active theme.
|
|
66
|
+
============================================= */
|
|
67
|
+
|
|
68
|
+
${expectedImport}
|
|
69
|
+
`
|
|
70
|
+
|
|
71
|
+
// Check if file exists and has correct import
|
|
72
|
+
if (fs.existsSync(appGlobalsCssPath)) {
|
|
73
|
+
const currentContent = fs.readFileSync(appGlobalsCssPath, 'utf8')
|
|
74
|
+
|
|
75
|
+
// Extract current import (handle various formats)
|
|
76
|
+
const importMatch = currentContent.match(/@import\s+["']([^"']+)["'];?/)
|
|
77
|
+
|
|
78
|
+
if (importMatch) {
|
|
79
|
+
const currentImportPath = importMatch[1]
|
|
80
|
+
|
|
81
|
+
// Check if it's already pointing to the correct theme
|
|
82
|
+
if (currentImportPath === relativePath) {
|
|
83
|
+
return false // Already correct, no update needed
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Update only the import line, preserving any custom comments
|
|
87
|
+
const updatedContent = currentContent.replace(
|
|
88
|
+
/@import\s+["'][^"']+["'];?/,
|
|
89
|
+
expectedImport
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
fs.writeFileSync(appGlobalsCssPath, updatedContent)
|
|
93
|
+
console.log(` 🔄 Updated app/globals.css import: ${relativePath}`)
|
|
94
|
+
return true
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// File doesn't exist or has no import - write full template
|
|
99
|
+
fs.writeFileSync(appGlobalsCssPath, template)
|
|
100
|
+
console.log(` ✅ Created app/globals.css with import: ${relativePath}`)
|
|
101
|
+
return true
|
|
102
|
+
}
|
|
103
|
+
|
|
35
104
|
/**
|
|
36
105
|
* Recursively copy directory contents
|
|
37
106
|
*/
|
|
@@ -217,9 +286,9 @@ export async function buildTheme(projectRoot = null) {
|
|
|
217
286
|
fs.mkdirSync(outputDir, { recursive: true })
|
|
218
287
|
}
|
|
219
288
|
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
|
|
289
|
+
// Sync app/globals.css to import from the active theme
|
|
290
|
+
// This handles path differences between npm and monorepo modes
|
|
291
|
+
syncAppGlobalsCss(config, activeTheme)
|
|
223
292
|
|
|
224
293
|
// Copy theme public assets (for all themes, including default)
|
|
225
294
|
if (fs.existsSync(themePath)) {
|
package/styles/docs.css
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* =============================================
|
|
2
|
+
DOCUMENTATION - Markdown Styles
|
|
3
|
+
Styles for rendered markdown content in docs pages.
|
|
4
|
+
These styles USE theme variables (--foreground, --muted, etc.)
|
|
5
|
+
Include this file in your theme's globals.css
|
|
6
|
+
============================================= */
|
|
7
|
+
|
|
8
|
+
.docs-content {
|
|
9
|
+
@apply space-y-4;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.docs-content h2 {
|
|
13
|
+
@apply text-2xl font-bold mt-8 mb-4 border-b pb-2 border-border;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.docs-content h3 {
|
|
17
|
+
@apply text-xl font-semibold mt-6 mb-3;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.docs-content h4 {
|
|
21
|
+
@apply text-lg font-semibold mt-4 mb-2;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.docs-content p {
|
|
25
|
+
@apply leading-7 text-foreground;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.docs-content code {
|
|
29
|
+
@apply bg-muted px-1.5 py-0.5 rounded text-sm font-mono text-foreground;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.docs-content pre {
|
|
33
|
+
@apply bg-muted p-4 rounded-lg overflow-x-auto my-4 border border-border;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.docs-content pre code {
|
|
37
|
+
@apply bg-transparent p-0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.docs-content ul {
|
|
41
|
+
@apply list-disc list-inside space-y-2 text-foreground;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.docs-content ol {
|
|
45
|
+
@apply list-decimal list-inside space-y-2 text-foreground;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.docs-content li {
|
|
49
|
+
@apply leading-7;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.docs-content a {
|
|
53
|
+
@apply text-primary underline-offset-4 hover:underline transition-colors;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.docs-content blockquote {
|
|
57
|
+
@apply border-l-4 border-primary pl-4 italic text-muted-foreground my-4;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.docs-content table {
|
|
61
|
+
@apply w-full border-collapse my-4;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.docs-content thead {
|
|
65
|
+
@apply border-b-2 border-border;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.docs-content th {
|
|
69
|
+
@apply text-left p-2 font-semibold bg-muted;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.docs-content td {
|
|
73
|
+
@apply p-2 border-b border-border;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.docs-content img {
|
|
77
|
+
@apply rounded-lg my-4 max-w-full h-auto;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.docs-content hr {
|
|
81
|
+
@apply my-8 border-border;
|
|
82
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/* =============================================
|
|
2
|
+
CORE UTILITIES - Keyframes and Animations
|
|
3
|
+
These utilities USE theme variables but don't define them.
|
|
4
|
+
Include this file in your theme's globals.css
|
|
5
|
+
============================================= */
|
|
6
|
+
|
|
7
|
+
/* Accordion animations for Radix UI */
|
|
8
|
+
@keyframes accordion-down {
|
|
9
|
+
from {
|
|
10
|
+
height: 0;
|
|
11
|
+
}
|
|
12
|
+
to {
|
|
13
|
+
height: var(--radix-accordion-content-height);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@keyframes accordion-up {
|
|
18
|
+
from {
|
|
19
|
+
height: var(--radix-accordion-content-height);
|
|
20
|
+
}
|
|
21
|
+
to {
|
|
22
|
+
height: 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Wiggle animation for icons and interactive elements */
|
|
27
|
+
@keyframes wiggle {
|
|
28
|
+
0%, 100% {
|
|
29
|
+
transform: rotate(0deg);
|
|
30
|
+
}
|
|
31
|
+
25% {
|
|
32
|
+
transform: rotate(-15deg);
|
|
33
|
+
}
|
|
34
|
+
75% {
|
|
35
|
+
transform: rotate(15deg);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -58,6 +58,34 @@ export const PERMISSIONS_CONFIG_OVERRIDES: ThemePermissionsConfig = {
|
|
|
58
58
|
{ action: 'delete', label: 'Delete tasks', description: 'Can delete tasks', roles: ['owner', 'admin'], dangerous: true },
|
|
59
59
|
{ action: 'assign', label: 'Assign tasks', description: 'Can assign tasks to team members', roles: ['owner', 'admin'] },
|
|
60
60
|
],
|
|
61
|
+
|
|
62
|
+
// ------------------------------------------
|
|
63
|
+
// PAGES ENTITY (uncommented by CLI if pages feature enabled)
|
|
64
|
+
// ------------------------------------------
|
|
65
|
+
// __PAGES_PERMISSIONS_START__
|
|
66
|
+
// pages: [
|
|
67
|
+
// { action: 'create', label: 'Create Pages', description: 'Can create new pages', roles: ['owner', 'admin'] },
|
|
68
|
+
// { action: 'read', label: 'View Pages', description: 'Can view page details', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
69
|
+
// { action: 'list', label: 'List Pages', description: 'Can see the pages list', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
70
|
+
// { action: 'update', label: 'Edit Pages', description: 'Can modify page content', roles: ['owner', 'admin'] },
|
|
71
|
+
// { action: 'delete', label: 'Delete Pages', description: 'Can delete pages', roles: ['owner', 'admin'], dangerous: true },
|
|
72
|
+
// { action: 'publish', label: 'Publish Pages', description: 'Can publish pages to make them public', roles: ['owner', 'admin'] },
|
|
73
|
+
// ],
|
|
74
|
+
// __PAGES_PERMISSIONS_END__
|
|
75
|
+
|
|
76
|
+
// ------------------------------------------
|
|
77
|
+
// POSTS ENTITY (uncommented by CLI if blog feature enabled)
|
|
78
|
+
// ------------------------------------------
|
|
79
|
+
// __POSTS_PERMISSIONS_START__
|
|
80
|
+
// posts: [
|
|
81
|
+
// { action: 'create', label: 'Create Posts', description: 'Can create new blog posts', roles: ['owner', 'admin', 'member'] },
|
|
82
|
+
// { action: 'read', label: 'View Posts', description: 'Can view post details', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
83
|
+
// { action: 'list', label: 'List Posts', description: 'Can see the posts list', roles: ['owner', 'admin', 'member', 'viewer'] },
|
|
84
|
+
// { action: 'update', label: 'Edit Posts', description: 'Can modify post content', roles: ['owner', 'admin', 'member'] },
|
|
85
|
+
// { action: 'delete', label: 'Delete Posts', description: 'Can delete posts', roles: ['owner', 'admin'], dangerous: true },
|
|
86
|
+
// { action: 'publish', label: 'Publish Posts', description: 'Can publish posts to make them public', roles: ['owner', 'admin'] },
|
|
87
|
+
// ],
|
|
88
|
+
// __POSTS_PERMISSIONS_END__
|
|
61
89
|
},
|
|
62
90
|
}
|
|
63
91
|
|