summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/helloworld-app-settings.js
blob: be26fbc26bffc38473625fa25128ab44a2b7c00d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import { html, useState, useEffect } from './vendor/htm-preact.js';
import { t } from './i18n.js';
import { useSaver } from './settings-ui.js';
import { FolderPickerField } from './folder-tree.js';

/**
 * HelloWorld's settings: one folder, and nothing else.
 *
 * This is the whole server-side surface an application needs — no op, no MNP
 * message, no route, no roster accessor. `saveDirectories` is bound to this
 * app's registry key by the page, and `ops.set_app_directories` stores the row
 * under that name without knowing what it is.
 *
 * It takes the shared props and no others (`docs/MESHBAY_DESIGN.md` §9.2),
 * which is what `test_app_settings_plugin.py` checks of every pane — including
 * this one, so the reference implementation is held to the contract it
 * demonstrates.
 */
function HelloWorldSettings({ roots, dirs, settings, saveDirectories }) {
  const { busy, msg, run } = useSaver();
  const [directories, setDirectories] = useState(
    settings.helloworldDirectories || []);

  useEffect(() => {
    setDirectories(settings.helloworldDirectories || []);
  }, [settings.helloworldDirectories]);

  const current = settings.helloworldDirectories || [];
  const dirty = directories.length !== current.length
    || directories.some((d, i) => d !== current[i]);

  return html`
    <div class="app-settings">
      <${FolderPickerField}
        label=${t('settings_app.helloworld_directory_label')}
        hint=${t('settings_app.helloworld_directory_hint')}
        roots=${roots} dirs=${dirs} mode="single"
        value=${directories[0] || ''} disabled=${busy}
        onChange=${(path) => setDirectories(path ? [path] : [])} />

      <button class="btn btn-small btn-secondary" style="margin-top:4px"
        disabled=${busy || !dirty}
        onClick=${() => run(() => saveDirectories(directories))}>
        ${busy ? t('settings_app.saving') : t('settings_app.save')}
      </button>
      ${msg && html`<p class="settings-hint">${msg}</p>`}
    </div>
  `;
}

export { HelloWorldSettings };