diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js b/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js index 1af6573..6e6dfad 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js @@ -215,8 +215,19 @@ function FolderTreePicker({ } /** - * The button-plus-modal pairing every settings pane wants, so none of them - * has to hold `open` state of its own. + * The chosen folders, as a table, plus the button that opens the picker. + * + * Not a `.settings-row`: that class is `display:flex; justify-content: + * space-between`, so a label, a hint and a value laid out inside one end up + * spread across a single line in whatever order they were written — which is + * how the first version of this read as three unrelated fragments per app. + * + * A table rather than a row of chips because these are lists now. Videos and + * Music can hold several folders, Photos routinely does, and a wrapped run of + * chips gives no column to scan and nowhere to put a per-row control. One + * folder per line, removable where it sits, in the same shape as the shared + * directories table above it — the operator is looking at two lists of + * directories on one page and they should read alike. */ function FolderPickerField({ label, hint, roots, dirs, mode = 'single', requireWritable = false, @@ -226,21 +237,52 @@ function FolderPickerField({ const multi = mode === 'multi'; const chosen = multi ? (value || []) : (value ? [value] : []); + const removeAt = (path) => { + if (!multi) { onChange(''); return; } + onChange(chosen.filter((p) => p !== path)); + }; + return html` - <div class="settings-row"> - <label class="settings-label">${label}</label> - ${hint && html`<p class="settings-hint">${hint}</p>`} - <div class="ftp-field"> - <div class="ftp-field-value"> - ${chosen.length - ? chosen.map((p) => html`<code key=${p} class="ftp-chip">${p}</code>`) - : html`<span class="settings-hint">${t('folder_tree.nothing_selected')}</span>`} - </div> + <div class="folder-field"> + <div class="folder-field-head"> + <h4 class="folder-field-label">${label}</h4> + ${hint && html`<p class="settings-hint">${hint}</p>`} + </div> + + ${chosen.length > 0 && html` + <table class="shared-dirs-tbl folder-field-tbl"> + <tbody> + ${chosen.map((path) => html` + <tr key=${path}> + <td class="sdt-col-dir"> + <span class="sdt-dir-name"> + <${Icon} name="folder" /> + ${path} + </span> + </td> + <td class="sdt-col-actions"> + <button class="sdt-action-btn sdt-action-danger" + disabled=${disabled} + title=${t('folder_tree.remove')} + onClick=${() => removeAt(path)}>\u{2715}</button> + </td> + </tr> + `)} + </tbody> + </table> + `} + + <div class="folder-field-actions"> + ${chosen.length === 0 && html` + <span class="settings-hint">${t('folder_tree.nothing_selected')}</span>`} <button class="btn btn-small btn-secondary" disabled=${disabled} onClick=${() => setOpen(true)}> - <${Icon} name="folder" /> ${t('folder_tree.choose')} + <${Icon} name="folder" /> + ${' '}${chosen.length && multi ? t('folder_tree.add') + : t('folder_tree.choose')} </button> </div> + ${open && html` <${FolderTreePicker} roots=${roots} dirs=${dirs} mode=${mode} |