panda-core 0.2.3 → 0.2.4
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.
- checksums.yaml +4 -4
- data/README.md +185 -0
- data/app/assets/tailwind/application.css +182 -0
- data/app/assets/tailwind/tailwind.config.js +21 -0
- data/app/controllers/panda/core/admin/dashboard_controller.rb +2 -3
- data/app/controllers/panda/core/admin/sessions_controller.rb +20 -2
- data/app/controllers/panda/core/admin_controller.rb +2 -0
- data/app/helpers/panda/core/sessions_helper.rb +21 -0
- data/app/javascript/panda/core/application.js +1 -0
- data/app/views/layouts/panda/core/admin.html.erb +5 -59
- data/app/views/panda/core/admin/dashboard/_default_content.html.erb +73 -0
- data/app/views/panda/core/admin/dashboard/show.html.erb +2 -8
- data/app/views/panda/core/admin/sessions/new.html.erb +8 -7
- data/app/views/panda/core/shared/_footer.html.erb +2 -0
- data/app/views/panda/core/shared/_header.html.erb +11 -0
- data/config/importmap.rb +10 -0
- data/config/initializers/panda_core.rb +37 -1
- data/config/routes.rb +7 -5
- data/lib/generators/panda/core/install_generator.rb +3 -9
- data/lib/generators/panda/core/templates/README +25 -0
- data/lib/generators/panda/core/templates/initializer.rb +28 -0
- data/lib/panda/core/configuration.rb +32 -3
- data/lib/panda/core/engine.rb +40 -3
- data/lib/panda/core/version.rb +1 -1
- data/lib/tasks/assets.rake +58 -392
- data/lib/tasks/panda_core_tasks.rake +16 -0
- metadata +11 -2
data/lib/tasks/assets.rake
CHANGED
|
@@ -1,423 +1,89 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "fileutils"
|
|
4
|
-
require "digest"
|
|
5
|
-
require "json"
|
|
6
|
-
|
|
7
3
|
namespace :panda do
|
|
8
4
|
namespace :core do
|
|
9
5
|
namespace :assets do
|
|
10
|
-
desc "Compile Panda Core assets for
|
|
6
|
+
desc "Compile Panda Core assets for development (overwrites panda-core.css)"
|
|
11
7
|
task :compile do
|
|
12
8
|
puts "🐼 Compiling Panda Core assets..."
|
|
13
|
-
puts "Rails.root: #{Rails.root}"
|
|
14
|
-
puts "Working directory: #{Dir.pwd}"
|
|
15
9
|
|
|
16
10
|
# Create output directory
|
|
17
|
-
output_dir =
|
|
11
|
+
output_dir = Panda::Core::Engine.root.join("public", "panda-core-assets")
|
|
18
12
|
FileUtils.mkdir_p(output_dir)
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
puts "Output directory: #{output_dir}"
|
|
23
|
-
|
|
24
|
-
# Compile JavaScript bundle
|
|
25
|
-
js_bundle = compile_javascript_bundle(version)
|
|
26
|
-
js_file = output_dir.join("panda-core-#{version}.js")
|
|
27
|
-
File.write(js_file, js_bundle)
|
|
28
|
-
puts "✅ JavaScript compiled: #{js_file} (#{File.size(js_file)} bytes)"
|
|
29
|
-
|
|
30
|
-
# Compile CSS bundle (for core UI components)
|
|
31
|
-
css_bundle = compile_css_bundle(version)
|
|
32
|
-
if css_bundle && !css_bundle.strip.empty?
|
|
33
|
-
css_file = output_dir.join("panda-core-#{version}.css")
|
|
34
|
-
File.write(css_file, css_bundle)
|
|
35
|
-
puts "✅ CSS compiled: #{css_file} (#{File.size(css_file)} bytes)"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Create manifest file
|
|
39
|
-
manifest = create_asset_manifest(version)
|
|
40
|
-
manifest_file = output_dir.join("manifest.json")
|
|
41
|
-
File.write(manifest_file, JSON.pretty_generate(manifest))
|
|
42
|
-
puts "✅ Manifest created: #{manifest_file}"
|
|
43
|
-
|
|
44
|
-
# Copy assets to public directory for testing
|
|
45
|
-
test_asset_dir = Rails.root.join("public", "panda-core-assets")
|
|
46
|
-
FileUtils.mkdir_p(test_asset_dir)
|
|
47
|
-
|
|
48
|
-
js_file_name = "panda-core-#{version}.js"
|
|
49
|
-
css_file_name = "panda-core-#{version}.css"
|
|
50
|
-
|
|
51
|
-
# Copy JavaScript file
|
|
52
|
-
if File.exist?(output_dir.join(js_file_name))
|
|
53
|
-
FileUtils.cp(output_dir.join(js_file_name), test_asset_dir.join(js_file_name))
|
|
54
|
-
puts "✅ Copied JavaScript to test location: #{test_asset_dir.join(js_file_name)}"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Copy CSS file
|
|
58
|
-
if File.exist?(output_dir.join(css_file_name))
|
|
59
|
-
FileUtils.cp(output_dir.join(css_file_name), test_asset_dir.join(css_file_name))
|
|
60
|
-
puts "✅ Copied CSS to test location: #{test_asset_dir.join(css_file_name)}"
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Copy manifest
|
|
64
|
-
if File.exist?(output_dir.join("manifest.json"))
|
|
65
|
-
FileUtils.cp(output_dir.join("manifest.json"), test_asset_dir.join("manifest.json"))
|
|
66
|
-
puts "✅ Copied manifest to test location: #{test_asset_dir.join("manifest.json")}"
|
|
67
|
-
end
|
|
14
|
+
# Compile CSS using Tailwind CSS v4
|
|
15
|
+
compile_css_development(output_dir)
|
|
68
16
|
|
|
69
17
|
puts "🎉 Asset compilation complete!"
|
|
70
18
|
puts "📁 Output directory: #{output_dir}"
|
|
71
|
-
puts "
|
|
19
|
+
puts ""
|
|
20
|
+
puts "💡 CSS is served via Rack middleware from Core gem at /panda-core-assets/panda-core.css"
|
|
21
|
+
puts " No need to copy to CMS or other apps - they load it from Core automatically!"
|
|
72
22
|
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
private
|
|
78
|
-
|
|
79
|
-
def compile_javascript_bundle(version)
|
|
80
|
-
puts "Creating Panda Core JavaScript bundle..."
|
|
81
|
-
|
|
82
|
-
bundle = []
|
|
83
|
-
bundle << "// Panda Core JavaScript Bundle v#{version}"
|
|
84
|
-
bundle << "// Compiled: #{Time.now.utc.iso8601}"
|
|
85
|
-
bundle << "// Core UI components and authentication"
|
|
86
|
-
bundle << ""
|
|
87
23
|
|
|
88
|
-
|
|
89
|
-
|
|
24
|
+
desc "Compile and version Panda Core assets for release"
|
|
25
|
+
task :release do
|
|
26
|
+
puts "🐼 Compiling Panda Core assets for release..."
|
|
90
27
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
bundle << compile_core_controllers
|
|
96
|
-
|
|
97
|
-
# Add initialization
|
|
98
|
-
bundle << create_core_init(version)
|
|
28
|
+
# Get version
|
|
29
|
+
require_relative "../panda/core/version"
|
|
30
|
+
version = Panda::Core::VERSION
|
|
31
|
+
puts "Version: #{version}"
|
|
99
32
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
33
|
+
# Create output directory
|
|
34
|
+
output_dir = Panda::Core::Engine.root.join("public", "panda-core-assets")
|
|
35
|
+
FileUtils.mkdir_p(output_dir)
|
|
103
36
|
|
|
104
|
-
|
|
105
|
-
|
|
37
|
+
# Compile CSS with versioning
|
|
38
|
+
compile_css_release(output_dir, version)
|
|
106
39
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
40
|
+
puts "🎉 Release asset compilation complete!"
|
|
41
|
+
puts "📁 Output directory: #{output_dir}"
|
|
42
|
+
puts "📦 Versioned: panda-core-#{version}.css"
|
|
43
|
+
puts "🔗 Symlink: panda-core.css -> panda-core-#{version}.css"
|
|
44
|
+
end
|
|
111
45
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
bundle << ".panda-core-admin {"
|
|
115
|
-
bundle << " font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;"
|
|
116
|
-
bundle << "}"
|
|
117
|
-
bundle << ""
|
|
118
|
-
bundle << ".panda-core-button {"
|
|
119
|
-
bundle << " display: inline-flex;"
|
|
120
|
-
bundle << " align-items: center;"
|
|
121
|
-
bundle << " padding: 0.5rem 1rem;"
|
|
122
|
-
bundle << " border-radius: 0.375rem;"
|
|
123
|
-
bundle << " font-weight: 500;"
|
|
124
|
-
bundle << "}"
|
|
125
|
-
bundle << ""
|
|
126
|
-
bundle << ".panda-core-container {"
|
|
127
|
-
bundle << " padding: 1.5rem;"
|
|
128
|
-
bundle << " background: white;"
|
|
129
|
-
bundle << " border-radius: 0.5rem;"
|
|
130
|
-
bundle << "}"
|
|
131
|
-
bundle << ""
|
|
46
|
+
def compile_css_development(output_dir)
|
|
47
|
+
puts "Compiling Tailwind CSS (development mode)..."
|
|
132
48
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
49
|
+
engine_root = Panda::Core::Engine.root
|
|
50
|
+
input_file = engine_root.join("app/assets/tailwind/application.css")
|
|
51
|
+
output_file = output_dir.join("panda-core.css")
|
|
136
52
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
"// Stimulus setup and polyfill for Panda Core",
|
|
140
|
-
"window.Stimulus = window.Stimulus || {",
|
|
141
|
-
" controllers: new Map(),",
|
|
142
|
-
" register: function(name, controller) {",
|
|
143
|
-
" this.controllers.set(name, controller);",
|
|
144
|
-
" console.log('[Panda Core] Registered controller:', name);",
|
|
145
|
-
" // Simple controller connection simulation",
|
|
146
|
-
" document.addEventListener('DOMContentLoaded', () => {",
|
|
147
|
-
" const elements = document.querySelectorAll(`[data-controller*='${name}']`);",
|
|
148
|
-
" elements.forEach(element => {",
|
|
149
|
-
" if (controller.connect) {",
|
|
150
|
-
" const instance = Object.create(controller);",
|
|
151
|
-
" instance.element = element;",
|
|
152
|
-
" instance.connect();",
|
|
153
|
-
" }",
|
|
154
|
-
" });",
|
|
155
|
-
" });",
|
|
156
|
-
" }",
|
|
157
|
-
"};",
|
|
158
|
-
"window.pandaCoreStimulus = window.Stimulus;",
|
|
159
|
-
""
|
|
160
|
-
].join("\n")
|
|
161
|
-
end
|
|
53
|
+
# Compile directly to unversioned file
|
|
54
|
+
cmd = "bundle exec tailwindcss -i #{input_file} -o #{output_file} --minify"
|
|
162
55
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
" connect() {",
|
|
171
|
-
" console.log('[Panda Core] Alert controller connected');",
|
|
172
|
-
" const dismissAfter = this.dismissAfterValue || 5000;",
|
|
173
|
-
" setTimeout(() => {",
|
|
174
|
-
" if (this.element && this.element.remove) {",
|
|
175
|
-
" this.element.remove();",
|
|
176
|
-
" }",
|
|
177
|
-
" }, dismissAfter);",
|
|
178
|
-
" },",
|
|
179
|
-
" close() {",
|
|
180
|
-
" console.log('[Panda Core] Alert closed manually');",
|
|
181
|
-
" if (this.element && this.element.remove) {",
|
|
182
|
-
" this.element.remove();",
|
|
183
|
-
" }",
|
|
184
|
-
" }",
|
|
185
|
-
"};",
|
|
186
|
-
"",
|
|
187
|
-
"const Dropdown = {",
|
|
188
|
-
" connect() {",
|
|
189
|
-
" console.log('[Panda Core] Dropdown controller connected');",
|
|
190
|
-
" },",
|
|
191
|
-
" toggle() {",
|
|
192
|
-
" console.log('[Panda Core] Dropdown toggled');",
|
|
193
|
-
" }",
|
|
194
|
-
"};",
|
|
195
|
-
"",
|
|
196
|
-
"const Modal = {",
|
|
197
|
-
" connect() {",
|
|
198
|
-
" console.log('[Panda Core] Modal controller connected');",
|
|
199
|
-
" },",
|
|
200
|
-
" open() {",
|
|
201
|
-
" console.log('[Panda Core] Modal opened');",
|
|
202
|
-
" if (this.element && this.element.showModal) {",
|
|
203
|
-
" this.element.showModal();",
|
|
204
|
-
" }",
|
|
205
|
-
" },",
|
|
206
|
-
" close() {",
|
|
207
|
-
" console.log('[Panda Core] Modal closed');",
|
|
208
|
-
" if (this.element && this.element.close) {",
|
|
209
|
-
" this.element.close();",
|
|
210
|
-
" }",
|
|
211
|
-
" }",
|
|
212
|
-
"};",
|
|
213
|
-
"",
|
|
214
|
-
"const Slideover = {",
|
|
215
|
-
" static: {",
|
|
216
|
-
" targets: ['dialog'],",
|
|
217
|
-
" values: { open: Boolean }",
|
|
218
|
-
" },",
|
|
219
|
-
" connect() {",
|
|
220
|
-
" console.log('[Panda Core] Slideover controller connected');",
|
|
221
|
-
" this.dialogTarget = this.element.querySelector('[data-slideover-target=\"dialog\"]') ||",
|
|
222
|
-
" this.element.querySelector('dialog');",
|
|
223
|
-
" if (this.openValue) {",
|
|
224
|
-
" this.open();",
|
|
225
|
-
" }",
|
|
226
|
-
" },",
|
|
227
|
-
" open() {",
|
|
228
|
-
" console.log('[Panda Core] Slideover opening');",
|
|
229
|
-
" if (this.dialogTarget && this.dialogTarget.showModal) {",
|
|
230
|
-
" this.dialogTarget.showModal();",
|
|
231
|
-
" }",
|
|
232
|
-
" },",
|
|
233
|
-
" close() {",
|
|
234
|
-
" console.log('[Panda Core] Slideover closing');",
|
|
235
|
-
" if (this.dialogTarget) {",
|
|
236
|
-
" this.dialogTarget.setAttribute('closing', '');",
|
|
237
|
-
" Promise.all(",
|
|
238
|
-
" this.dialogTarget.getAnimations ? ",
|
|
239
|
-
" this.dialogTarget.getAnimations().map(animation => animation.finished) : []",
|
|
240
|
-
" ).then(() => {",
|
|
241
|
-
" this.dialogTarget.removeAttribute('closing');",
|
|
242
|
-
" if (this.dialogTarget.close) {",
|
|
243
|
-
" this.dialogTarget.close();",
|
|
244
|
-
" }",
|
|
245
|
-
" });",
|
|
246
|
-
" }",
|
|
247
|
-
" },",
|
|
248
|
-
" show() {",
|
|
249
|
-
" this.open();",
|
|
250
|
-
" },",
|
|
251
|
-
" hide() {",
|
|
252
|
-
" this.close();",
|
|
253
|
-
" },",
|
|
254
|
-
" backdropClose(event) {",
|
|
255
|
-
" if (event.target.nodeName === 'DIALOG') {",
|
|
256
|
-
" this.close();",
|
|
257
|
-
" }",
|
|
258
|
-
" }",
|
|
259
|
-
"};",
|
|
260
|
-
"",
|
|
261
|
-
"const Toggle = {",
|
|
262
|
-
" static: {",
|
|
263
|
-
" values: { open: { type: Boolean, default: false } }",
|
|
264
|
-
" },",
|
|
265
|
-
" connect() {",
|
|
266
|
-
" console.log('[Panda Core] Toggle controller connected');",
|
|
267
|
-
" },",
|
|
268
|
-
" toggle() {",
|
|
269
|
-
" this.openValue = !this.openValue;",
|
|
270
|
-
" }",
|
|
271
|
-
"};",
|
|
272
|
-
"",
|
|
273
|
-
"const Tabs = {",
|
|
274
|
-
" connect() {",
|
|
275
|
-
" console.log('[Panda Core] Tabs controller connected');",
|
|
276
|
-
" }",
|
|
277
|
-
"};",
|
|
278
|
-
"",
|
|
279
|
-
"const Popover = {",
|
|
280
|
-
" connect() {",
|
|
281
|
-
" console.log('[Panda Core] Popover controller connected');",
|
|
282
|
-
" }",
|
|
283
|
-
"};",
|
|
284
|
-
"",
|
|
285
|
-
"const Autosave = {",
|
|
286
|
-
" connect() {",
|
|
287
|
-
" console.log('[Panda Core] Autosave controller connected');",
|
|
288
|
-
" }",
|
|
289
|
-
"};",
|
|
290
|
-
"",
|
|
291
|
-
"const ColorPreview = {",
|
|
292
|
-
" connect() {",
|
|
293
|
-
" console.log('[Panda Core] ColorPreview controller connected');",
|
|
294
|
-
" }",
|
|
295
|
-
"};",
|
|
296
|
-
"",
|
|
297
|
-
"// Register TailwindCSS components",
|
|
298
|
-
"Stimulus.register('alert', Alert);",
|
|
299
|
-
"Stimulus.register('dropdown', Dropdown);",
|
|
300
|
-
"Stimulus.register('modal', Modal);",
|
|
301
|
-
"Stimulus.register('slideover', Slideover);",
|
|
302
|
-
"Stimulus.register('toggle', Toggle);",
|
|
303
|
-
"Stimulus.register('tabs', Tabs);",
|
|
304
|
-
"Stimulus.register('popover', Popover);",
|
|
305
|
-
"Stimulus.register('autosave', Autosave);",
|
|
306
|
-
"Stimulus.register('color-preview', ColorPreview);",
|
|
307
|
-
""
|
|
308
|
-
].join("\n")
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
def compile_core_controllers
|
|
312
|
-
puts "Compiling Core controllers..."
|
|
56
|
+
if system(cmd)
|
|
57
|
+
puts "✅ CSS compiled: #{output_file} (#{File.size(output_file)} bytes)"
|
|
58
|
+
else
|
|
59
|
+
puts "❌ CSS compilation failed"
|
|
60
|
+
exit 1
|
|
61
|
+
end
|
|
62
|
+
end
|
|
313
63
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
# Add theme form controller
|
|
318
|
-
bundle << [
|
|
319
|
-
"// Theme Form Controller",
|
|
320
|
-
"const ThemeFormController = {",
|
|
321
|
-
" connect() {",
|
|
322
|
-
" console.log('[Panda Core] Theme form controller connected');",
|
|
323
|
-
" // Ensure submit button is enabled",
|
|
324
|
-
" const submitButton = this.element.querySelector('input[type=\"submit\"], button[type=\"submit\"]');",
|
|
325
|
-
" if (submitButton) submitButton.disabled = false;",
|
|
326
|
-
" },",
|
|
327
|
-
" updateTheme(event) {",
|
|
328
|
-
" const newTheme = event.target.value;",
|
|
329
|
-
" document.documentElement.dataset.theme = newTheme;",
|
|
330
|
-
" console.log('[Panda Core] Theme updated to:', newTheme);",
|
|
331
|
-
" }",
|
|
332
|
-
"};",
|
|
333
|
-
"",
|
|
334
|
-
"Stimulus.register('theme-form', ThemeFormController);",
|
|
335
|
-
""
|
|
336
|
-
].join("\n")
|
|
64
|
+
def compile_css_release(output_dir, version)
|
|
65
|
+
puts "Compiling Tailwind CSS (release mode)..."
|
|
337
66
|
|
|
338
|
-
|
|
339
|
-
|
|
67
|
+
engine_root = Panda::Core::Engine.root
|
|
68
|
+
input_file = engine_root.join("app/assets/tailwind/application.css")
|
|
69
|
+
versioned_file = output_dir.join("panda-core-#{version}.css")
|
|
340
70
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
"// Panda Core Initialization",
|
|
344
|
-
"// Immediate execution marker for CI debugging",
|
|
345
|
-
"window.pandaCoreScriptExecuted = true;",
|
|
346
|
-
"console.log('[Panda Core] Script execution started');",
|
|
347
|
-
"",
|
|
348
|
-
"(function() {",
|
|
349
|
-
" 'use strict';",
|
|
350
|
-
" ",
|
|
351
|
-
" try {",
|
|
352
|
-
" console.log('[Panda Core] Full JavaScript bundle v#{version} loaded');",
|
|
353
|
-
" ",
|
|
354
|
-
" // Mark as loaded immediately",
|
|
355
|
-
" window.pandaCoreVersion = '#{version}';",
|
|
356
|
-
" window.pandaCoreLoaded = true;",
|
|
357
|
-
" window.pandaCoreFullBundle = true;",
|
|
358
|
-
" window.pandaCoreStimulus = window.Stimulus;",
|
|
359
|
-
" ",
|
|
360
|
-
" // Also set on document for iframe context issues",
|
|
361
|
-
" if (window.document) {",
|
|
362
|
-
" window.document.pandaCoreLoaded = true;",
|
|
363
|
-
" }",
|
|
364
|
-
" ",
|
|
365
|
-
" // Initialize on DOM ready",
|
|
366
|
-
" if (document.readyState === 'loading') {",
|
|
367
|
-
" document.addEventListener('DOMContentLoaded', initializePandaCore);",
|
|
368
|
-
" } else {",
|
|
369
|
-
" initializePandaCore();",
|
|
370
|
-
" }",
|
|
371
|
-
" ",
|
|
372
|
-
" function initializePandaCore() {",
|
|
373
|
-
" console.log('[Panda Core] Initializing controllers...');",
|
|
374
|
-
" ",
|
|
375
|
-
" // Trigger controller connections for existing elements",
|
|
376
|
-
" if (window.Stimulus && window.Stimulus.controllers) {",
|
|
377
|
-
" window.Stimulus.controllers.forEach((controller, name) => {",
|
|
378
|
-
" const elements = document.querySelectorAll(`[data-controller*='${name}']`);",
|
|
379
|
-
" console.log(`[Panda Core] Found ${elements.length} elements for controller: ${name}`);",
|
|
380
|
-
" elements.forEach(element => {",
|
|
381
|
-
" if (controller.connect) {",
|
|
382
|
-
" const instance = Object.create(controller);",
|
|
383
|
-
" instance.element = element;",
|
|
384
|
-
" // Add target helpers",
|
|
385
|
-
" instance.targets = instance.targets || {};",
|
|
386
|
-
" controller.connect.call(instance);",
|
|
387
|
-
" }",
|
|
388
|
-
" });",
|
|
389
|
-
" });",
|
|
390
|
-
" }",
|
|
391
|
-
" }",
|
|
392
|
-
" } catch (error) {",
|
|
393
|
-
" console.error('[Panda Core] Error during initialization:', error);",
|
|
394
|
-
" // Still mark as loaded to prevent test failures",
|
|
395
|
-
" window.pandaCoreLoaded = true;",
|
|
396
|
-
" window.pandaCoreError = error.message;",
|
|
397
|
-
" }",
|
|
398
|
-
"})();",
|
|
399
|
-
""
|
|
400
|
-
].join("\n")
|
|
401
|
-
end
|
|
71
|
+
# Compile to versioned file
|
|
72
|
+
cmd = "bundle exec tailwindcss -i #{input_file} -o #{versioned_file} --minify"
|
|
402
73
|
|
|
403
|
-
|
|
404
|
-
|
|
74
|
+
if system(cmd)
|
|
75
|
+
puts "✅ CSS compiled: #{versioned_file} (#{File.size(versioned_file)} bytes)"
|
|
405
76
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
77
|
+
# Create/update unversioned symlink
|
|
78
|
+
symlink = output_dir.join("panda-core.css")
|
|
79
|
+
FileUtils.rm_f(symlink) if File.exist?(symlink)
|
|
80
|
+
FileUtils.ln_sf(File.basename(versioned_file), symlink)
|
|
81
|
+
puts "✅ Created symlink: #{symlink} -> #{File.basename(versioned_file)}"
|
|
82
|
+
else
|
|
83
|
+
puts "❌ CSS compilation failed"
|
|
84
|
+
exit 1
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
412
88
|
end
|
|
413
|
-
|
|
414
|
-
{
|
|
415
|
-
version: version,
|
|
416
|
-
compiled_at: Time.now.utc.iso8601,
|
|
417
|
-
files: files,
|
|
418
|
-
cdn_base_url: "https://github.com/tastybamboo/panda-core/releases/download/v#{version}/",
|
|
419
|
-
integrity: {
|
|
420
|
-
algorithm: "sha256"
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
89
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Provide consistent namespacing for Panda tasks
|
|
4
|
+
# Rails auto-generates panda_core:* tasks from the module name,
|
|
5
|
+
# but we want to use panda:core:* for consistency across all Panda gems
|
|
6
|
+
|
|
7
|
+
namespace :panda do
|
|
8
|
+
namespace :core do
|
|
9
|
+
namespace :install do
|
|
10
|
+
desc "Copy migrations from panda-core to application"
|
|
11
|
+
task :migrations do
|
|
12
|
+
Rake::Task["panda_core:install:migrations"].invoke
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: panda-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tasty Bamboo
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2025-
|
|
12
|
+
date: 2025-10-27 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: importmap-rails
|
|
@@ -372,6 +372,8 @@ files:
|
|
|
372
372
|
- LICENSE
|
|
373
373
|
- README.md
|
|
374
374
|
- Rakefile
|
|
375
|
+
- app/assets/tailwind/application.css
|
|
376
|
+
- app/assets/tailwind/tailwind.config.js
|
|
375
377
|
- app/builders/panda/core/form_builder.rb
|
|
376
378
|
- app/components/panda/core/admin/button_component.rb
|
|
377
379
|
- app/components/panda/core/admin/container_component.html.erb
|
|
@@ -393,6 +395,7 @@ files:
|
|
|
393
395
|
- app/controllers/panda/core/admin_controller.rb
|
|
394
396
|
- app/controllers/panda/core/application_controller.rb
|
|
395
397
|
- app/helpers/panda/core/asset_helper.rb
|
|
398
|
+
- app/helpers/panda/core/sessions_helper.rb
|
|
396
399
|
- app/javascript/panda/core/application.js
|
|
397
400
|
- app/javascript/panda/core/controllers/index.js
|
|
398
401
|
- app/javascript/panda/core/controllers/theme_form_controller.js
|
|
@@ -402,6 +405,7 @@ files:
|
|
|
402
405
|
- app/models/panda/core/current.rb
|
|
403
406
|
- app/models/panda/core/user.rb
|
|
404
407
|
- app/views/layouts/panda/core/admin.html.erb
|
|
408
|
+
- app/views/panda/core/admin/dashboard/_default_content.html.erb
|
|
405
409
|
- app/views/panda/core/admin/dashboard/show.html.erb
|
|
406
410
|
- app/views/panda/core/admin/my_profile/edit.html.erb
|
|
407
411
|
- app/views/panda/core/admin/sessions/new.html.erb
|
|
@@ -409,6 +413,9 @@ files:
|
|
|
409
413
|
- app/views/panda/core/admin/shared/_flash.html.erb
|
|
410
414
|
- app/views/panda/core/admin/shared/_sidebar.html.erb
|
|
411
415
|
- app/views/panda/core/admin/shared/_slideover.html.erb
|
|
416
|
+
- app/views/panda/core/shared/_footer.html.erb
|
|
417
|
+
- app/views/panda/core/shared/_header.html.erb
|
|
418
|
+
- config/importmap.rb
|
|
412
419
|
- config/initializers/panda_core.rb
|
|
413
420
|
- config/routes.rb
|
|
414
421
|
- db/migrate/20250809000001_create_panda_core_users.rb
|
|
@@ -418,6 +425,7 @@ files:
|
|
|
418
425
|
- lib/generators/panda/core/dev_tools/templates/spec_support_panda_core_helpers.rb
|
|
419
426
|
- lib/generators/panda/core/dev_tools_generator.rb
|
|
420
427
|
- lib/generators/panda/core/install_generator.rb
|
|
428
|
+
- lib/generators/panda/core/templates/README
|
|
421
429
|
- lib/generators/panda/core/templates/initializer.rb
|
|
422
430
|
- lib/generators/panda/core/templates_generator.rb
|
|
423
431
|
- lib/panda/core.rb
|
|
@@ -442,6 +450,7 @@ files:
|
|
|
442
450
|
- lib/tasks/assets.rake
|
|
443
451
|
- lib/tasks/panda/core/migrations.rake
|
|
444
452
|
- lib/tasks/panda_core.rake
|
|
453
|
+
- lib/tasks/panda_core_tasks.rake
|
|
445
454
|
homepage: https://github.com/tastybamboo/panda-core
|
|
446
455
|
licenses:
|
|
447
456
|
- BSD-3-Clause
|