@le-space/ui 0.2.0 → 0.3.2

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.
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import { onDestroy, onMount } from 'svelte'
3
3
 
4
- import { createSponsorRelayController, formatDateTime, formatNumber, joinMappedPorts, joinRequiredPortForwards, shortHash } from '../shared/index'
4
+ import { createSponsorRelayController, formatDateTime, formatNumber, formatTierSpecLabel, joinMappedPorts, joinRequiredPortForwards, shortHash } from '../shared/index'
5
5
  import AccordionSection from './components/AccordionSection.svelte'
6
6
  import CopyButton from './components/CopyButton.svelte'
7
7
  import LauncherButton from './components/LauncherButton.svelte'
@@ -104,10 +104,6 @@ export let apiHost = undefined
104
104
  <p class="status-text">{state.statusText}</p>
105
105
 
106
106
  <div class="grid">
107
- <label class="field">
108
- <span>Manifest URL</span>
109
- <input value={state.manifestUrl} on:input={(event) => controller.setManifestUrl(event.currentTarget.value)} />
110
- </label>
111
107
  <label class="field">
112
108
  <span>Instance Name</span>
113
109
  <input value={state.instanceName} on:input={(event) => controller.setInstanceName(event.currentTarget.value)} />
@@ -116,22 +112,39 @@ export let apiHost = undefined
116
112
  <span>Tier</span>
117
113
  <select value={state.pricingSummary.tier?.id ?? state.tierId} on:change={(event) => controller.setTierId(event.currentTarget.value)}>
118
114
  {#each state.pricingSummary.pricing?.tiers ?? [] as tier}
119
- <option value={tier.id}>{tier.id}</option>
115
+ <option value={tier.id}>
116
+ {tier.id} {formatTierSpecLabel(
117
+ state.pricingSummary.pricing ? state.pricingSummary.pricing.compute_unit.vcpus * tier.compute_units : null,
118
+ state.pricingSummary.pricing ? state.pricingSummary.pricing.compute_unit.memory_mib * tier.compute_units : null,
119
+ state.pricingSummary.pricing ? state.pricingSummary.pricing.compute_unit.disk_mib * tier.compute_units : null
120
+ )}
121
+ </option>
120
122
  {/each}
121
123
  </select>
122
- </label>
123
- <label class="field wide">
124
- <span>SSH Public Key</span>
125
- <textarea rows="3" on:input={(event) => controller.setSshPublicKey(event.currentTarget.value)}>{state.sshPublicKey}</textarea>
124
+ <small>{formatTierSpecLabel(state.pricingSummary.vcpus, state.pricingSummary.memoryMiB, state.pricingSummary.diskMiB)}</small>
126
125
  </label>
127
126
  </div>
128
127
 
129
- <AccordionSection title="Paste Manifest" open={state.showPasteManifest}>
130
- <label class="field wide">
131
- <span>Pasted rootfs manifest JSON</span>
132
- <textarea rows="7" on:input={(event) => controller.setManifestJson(event.currentTarget.value)}>{state.manifestJson}</textarea>
133
- </label>
134
- </AccordionSection>
128
+ <details class="accordion" open={state.showAdvanced} on:toggle={(event) => controller.setShowAdvanced(event.currentTarget.open)}>
129
+ <summary>Advanced</summary>
130
+ <div class="accordion-body advanced-grid">
131
+ <label class="field wide">
132
+ <span>Manifest URL</span>
133
+ <input value={state.manifestUrl} on:input={(event) => controller.setManifestUrl(event.currentTarget.value)} />
134
+ </label>
135
+ <label class="field wide">
136
+ <span>SSH Public Key</span>
137
+ <textarea rows="3" on:input={(event) => controller.setSshPublicKey(event.currentTarget.value)}>{state.sshPublicKey}</textarea>
138
+ </label>
139
+
140
+ <AccordionSection title="Paste Manifest" open={state.showPasteManifest}>
141
+ <label class="field wide">
142
+ <span>Pasted rootfs manifest JSON</span>
143
+ <textarea rows="7" on:input={(event) => controller.setManifestJson(event.currentTarget.value)}>{state.manifestJson}</textarea>
144
+ </label>
145
+ </AccordionSection>
146
+ </div>
147
+ </details>
135
148
 
136
149
  <div class="metrics">
137
150
  <div class="metric-card">
@@ -404,10 +417,46 @@ export let apiHost = undefined
404
417
  gap: 0.4rem;
405
418
  }
406
419
 
420
+ .field small {
421
+ color: var(--relay-muted);
422
+ font-size: 0.72rem;
423
+ line-height: 1.35;
424
+ }
425
+
407
426
  .field.wide {
408
427
  grid-column: 1 / -1;
409
428
  }
410
429
 
430
+ .accordion {
431
+ margin-top: 0.9rem;
432
+ border: 1px solid var(--relay-panel-border);
433
+ border-radius: 1rem;
434
+ background: rgba(255, 255, 255, 0.035);
435
+ }
436
+
437
+ .accordion summary {
438
+ cursor: pointer;
439
+ list-style: none;
440
+ padding: 0.8rem 0.95rem;
441
+ color: var(--relay-text);
442
+ font: 700 0.8rem/1.1 var(--relay-font-heading);
443
+ text-transform: uppercase;
444
+ letter-spacing: 0.08em;
445
+ }
446
+
447
+ .accordion summary::-webkit-details-marker {
448
+ display: none;
449
+ }
450
+
451
+ .accordion-body {
452
+ padding: 0 0.95rem 0.95rem;
453
+ }
454
+
455
+ .advanced-grid {
456
+ display: grid;
457
+ gap: 0.75rem;
458
+ }
459
+
411
460
  input,
412
461
  select,
413
462
  textarea {