Skip to content

Commit f1bc250

Browse files
committed
fix: switch to code when executing actions
1 parent 759e04f commit f1bc250

File tree

5 files changed

+110
-3
lines changed

5 files changed

+110
-3
lines changed

web/landing/assets/controllers/playground_controller.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Controller } from "@hotwired/stimulus"
22

33
export default class extends Controller {
4-
static outlets = ["wasm", "code-editor", "turnstile", "playground-output"]
4+
static outlets = ["wasm", "code-editor", "turnstile", "playground-output", "playground-tabs"]
55
static targets = ["loadingMessage", "loadingBar", "loadingPercent", "navigation", "editor", "outputContainer", "storageIndicator", "actionSpinner"]
66
static values = {
77
packageIcon: String,
@@ -20,6 +20,9 @@ export default class extends Controller {
2020
}
2121

2222
onActionStarted() {
23+
if (this.hasPlaygroundTabsOutlet) {
24+
this.playgroundTabsOutlet.switchToCode()
25+
}
2326
document.querySelectorAll('#action-run, #action-format, #action-share, #action-upload').forEach(btn => btn.disabled = true)
2427
const resetLink = document.getElementById('action-reset')
2528
if (resetLink) {

web/landing/assets/controllers/playground_tabs_controller.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ export default class extends Controller {
6060
return
6161
}
6262

63+
if (filePath === '/code.php') {
64+
this.switchToCode()
65+
return
66+
}
67+
6368
if (!this.hasWasmOutlet) {
6469
this.#log('WASM outlet not found')
6570
return
@@ -102,6 +107,17 @@ export default class extends Controller {
102107
this.#updateTabUI()
103108
}
104109

110+
openFileFromDropdown(event) {
111+
const filePath = event.target.value
112+
if (!filePath) {
113+
return
114+
}
115+
116+
event.target.value = ''
117+
118+
this.openFile({ currentTarget: { dataset: { filePath } } })
119+
}
120+
105121
downloadPreviewFile(event) {
106122
if (event) {
107123
event.preventDefault()

web/landing/assets/controllers/playground_workspace_controller.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Controller } from "@hotwired/stimulus"
22

33
export default class extends Controller {
44
static outlets = ["wasm", "code-editor", "playground"]
5-
static targets = ["tree", "emptyState"]
5+
static targets = ["tree", "dropdown", "emptyState"]
66
static values = {
77
rootPath: { type: String, default: '/workspace' },
88
folderIcon: String,
@@ -104,6 +104,7 @@ export default class extends Controller {
104104
}
105105

106106
this.treeTarget.innerHTML = this.#renderFileTree(tree)
107+
this.#populateDropdown(tree)
107108
this.#treeRendered = true
108109

109110
if (this.hasEmptyStateTarget) {
@@ -239,4 +240,42 @@ export default class extends Controller {
239240

240241
return count
241242
}
243+
244+
#populateDropdown(tree) {
245+
if (!this.hasDropdownTarget) {
246+
return
247+
}
248+
249+
const files = this.#collectFiles(tree)
250+
251+
this.dropdownTarget.innerHTML = '<option value="">Select a file...</option>'
252+
this.dropdownTarget.innerHTML += '<option value="/code.php">code.php</option>'
253+
254+
for (const file of files) {
255+
const option = document.createElement('option')
256+
option.value = file.path
257+
option.textContent = file.path
258+
this.dropdownTarget.appendChild(option)
259+
}
260+
}
261+
262+
#collectFiles(tree, prefix = '') {
263+
const files = []
264+
265+
const entries = Object.values(tree).sort((a, b) => {
266+
if (a.type === 'directory' && b.type !== 'directory') return -1
267+
if (a.type !== 'directory' && b.type === 'directory') return 1
268+
return a.name.localeCompare(b.name)
269+
})
270+
271+
for (const entry of entries) {
272+
if (entry.type === 'directory' && entry.children) {
273+
files.push(...this.#collectFiles(entry.children, `${prefix}/${entry.name}`))
274+
} else if (entry.type === 'file') {
275+
files.push({ path: entry.path, name: entry.name })
276+
}
277+
}
278+
279+
return files
280+
}
242281
}

web/landing/assets/styles/app.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,39 @@ code {
349349
@apply grid gap-6 grid-cols-1 lg:grid-cols-12 mb-6;
350350
display: none; /* Hidden by default, shown by Stimulus */
351351

352+
div.file-browser-mobile {
353+
@apply grid grid-cols-[auto_1fr] items-center gap-4;
354+
355+
@screen lg {
356+
display: none;
357+
}
358+
359+
.file-browser-label {
360+
@apply text-sm font-bold text-stone-400 uppercase whitespace-nowrap;
361+
362+
.help-trigger-workspace {
363+
@apply cursor-pointer border-0 bg-transparent p-0 ml-2 transition-opacity hover:opacity-70 inline-block align-middle;
364+
}
365+
}
366+
367+
.file-select {
368+
@apply bg-stone-800 text-white border border-gray rounded px-3 py-2 text-base
369+
focus:outline-none focus:ring-2 focus:ring-cyan-400 focus:border-transparent;
370+
371+
option {
372+
@apply text-base py-2;
373+
}
374+
}
375+
}
376+
352377
div.file-browser {
353378
@apply rounded p-4 overflow-auto shadow-2xl shadow-gray border-gray border-2
354379
lg:col-span-2 bg-transparent;
380+
display: none;
381+
382+
@screen lg {
383+
display: block;
384+
}
355385

356386
.file-browser-header {
357387
@apply text-sm font-bold mb-3 text-stone-400 uppercase;

web/landing/templates/playground/index.html.twig

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
data-playground-storage-code-editor-outlet="#code-editor"
6363
data-playground-storage-wasm-outlet="#playground"
6464
data-playground-reset-playground-storage-outlet="#playground"
65+
data-playground-playground-tabs-outlet="#playground-editor"
6566
data-action="wasm:initialized->playground#onWasmInitialized
6667
wasm:initialized->playground-workspace#refreshTree
6768
wasm:initialized->playground-share#onWasmResourcesLoaded
@@ -241,10 +242,28 @@
241242
</a>
242243
</div>
243244
</div>
244-
<div class="editor" data-playground-target="editor"
245+
<div id="playground-editor" class="editor" data-playground-target="editor"
245246
data-controller="playground-tabs"
246247
data-playground-tabs-wasm-outlet="#playground"
247248
data-playground-tabs-code-editor-outlet="#code-editor">
249+
<div class="file-browser-mobile">
250+
<label for="file-select" class="file-browser-label">
251+
Workspace
252+
<button
253+
data-action="click->playground-help#showTopic"
254+
data-help-topic="help-workspace"
255+
class="help-trigger-workspace"
256+
aria-label="What is the Workspace?">
257+
<img src="{{ asset('images/icons/help.svg') }}" alt="Help" width="14" height="14">
258+
</button>
259+
</label>
260+
<select id="file-select"
261+
class="file-select"
262+
data-playground-workspace-target="dropdown"
263+
data-action="change->playground-tabs#openFileFromDropdown">
264+
<option value="">Select a file...</option>
265+
</select>
266+
</div>
248267
<div class="file-browser">
249268
<div class="file-browser-header">
250269
Workspace

0 commit comments

Comments
 (0)