@ai-ecoverse/slicc-spectrum 1.7.0 → 1.8.0

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.
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  DummySettings,
6
6
  clock
7
- } from "./chunk-YWO2TNED.js";
7
+ } from "./chunk-43NIJXWH.js";
8
8
  import {
9
9
  Emitter
10
10
  } from "./chunk-T5NHW4KC.js";
package/dist/slicc-ui.js CHANGED
@@ -10104,10 +10104,17 @@ var accountStatus = {
10104
10104
  disconnected: ["neutral", "Not connected"]
10105
10105
  };
10106
10106
  var SliccSettings = class extends ModelElement {
10107
- static properties = { ...ModelElement.properties, pending: { state: true } };
10107
+ static properties = {
10108
+ ...ModelElement.properties,
10109
+ pending: { state: true },
10110
+ entering: { state: true },
10111
+ failure: { state: true }
10112
+ };
10108
10113
  constructor() {
10109
10114
  super();
10110
10115
  this.pending = /* @__PURE__ */ new Set();
10116
+ this.entering = null;
10117
+ this.failure = null;
10111
10118
  }
10112
10119
  static styles = [
10113
10120
  shared,
@@ -10171,6 +10178,21 @@ var SliccSettings = class extends ModelElement {
10171
10178
  .state .dot[data-variant='positive'] {
10172
10179
  background: var(--spectrum-positive-visual-color);
10173
10180
  }
10181
+ .key {
10182
+ display: flex;
10183
+ align-items: center;
10184
+ gap: 8px;
10185
+ padding: 8px 0 12px;
10186
+ border-bottom: 1px solid var(--spectrum-gray-200);
10187
+ }
10188
+ .key sp-textfield {
10189
+ flex: 1;
10190
+ }
10191
+ .failure {
10192
+ color: var(--spectrum-negative-content-color-default);
10193
+ font-size: var(--spectrum-font-size-75);
10194
+ padding: 4px 0;
10195
+ }
10174
10196
  `
10175
10197
  ];
10176
10198
  subscribe(model) {
@@ -10189,20 +10211,61 @@ var SliccSettings = class extends ModelElement {
10189
10211
  #checked(event) {
10190
10212
  return event.target.checked;
10191
10213
  }
10192
- async connect(id) {
10214
+ async connect(id, secret) {
10193
10215
  this.pending = /* @__PURE__ */ new Set([...this.pending, id]);
10216
+ this.failure = null;
10194
10217
  try {
10195
- await this.model?.settings.connect(id);
10218
+ await this.model?.settings.connect(id, secret);
10219
+ if (this.entering === id) this.entering = null;
10220
+ } catch (error) {
10221
+ this.failure = { id, message: error.message };
10196
10222
  } finally {
10197
10223
  this.pending = new Set([...this.pending].filter((candidate) => candidate !== id));
10198
10224
  }
10199
10225
  }
10226
+ #start(account) {
10227
+ if (account.auth !== "api-key") {
10228
+ void this.connect(account.id);
10229
+ return;
10230
+ }
10231
+ this.failure = null;
10232
+ this.entering = account.id;
10233
+ void this.updateComplete.then(() => this.focusOn(".key sp-textfield"));
10234
+ }
10235
+ #submit(event, id) {
10236
+ event.preventDefault();
10237
+ const field = event.currentTarget.querySelector(
10238
+ "sp-textfield"
10239
+ );
10240
+ const secret = field.value.trim();
10241
+ field.value = "";
10242
+ if (secret) void this.connect(id, secret);
10243
+ }
10244
+ #send(event) {
10245
+ event.currentTarget.closest("form")?.requestSubmit();
10246
+ }
10247
+ #enter(event) {
10248
+ if (event.key === "Enter") this.#send(event);
10249
+ }
10250
+ #cancel() {
10251
+ this.entering = null;
10252
+ this.failure = null;
10253
+ }
10254
+ #key(account) {
10255
+ if (this.entering !== account.id) return A;
10256
+ const busy = this.pending.has(account.id);
10257
+ return b`<form class="key" data-id=${account.id} @submit=${(event) => this.#submit(event, account.id)}>
10258
+ <sp-textfield size="m" type="password" autocomplete="off" label=${`${account.provider} API key`} placeholder="Paste the API key" @keydown=${(event) => this.#enter(event)}></sp-textfield>
10259
+ <sp-button size="s" variant="accent" ?pending=${busy} @click=${(event) => this.#send(event)}>Save</sp-button>
10260
+ <sp-button size="s" variant="secondary" treatment="outline" @click=${() => this.#cancel()}>Cancel</sp-button>
10261
+ </form>`;
10262
+ }
10200
10263
  #account(account) {
10201
10264
  const [variant, label] = accountStatus[account.status];
10202
10265
  const busy = this.pending.has(account.id);
10203
10266
  const action = account.status === "connected" ? b`<sp-button size="s" variant="secondary" treatment="outline" @click=${() => this.model?.settings.disconnect(account.id)}
10204
10267
  >Disconnect</sp-button
10205
- >` : b`<sp-button size="s" variant="secondary" ?pending=${busy} @click=${() => this.connect(account.id)}
10268
+ >` : b`<sp-button size="s" variant="secondary" ?pending=${busy} ?disabled=${this.entering === account.id} @click=${() => this.#start(account)}
10206
10269
  >${account.status === "expired" ? "Reconnect" : "Connect"}</sp-button
10207
10270
  >`;
10208
10271
  return b`<div class="account" data-id=${account.id}>
@@ -10210,7 +10273,9 @@ var SliccSettings = class extends ModelElement {
10210
10273
  <span class="identity">${account.identity || "\u2014"}</span>
10211
10274
  <span class="state"><span class="dot" data-variant=${variant}></span>${label}</span>
10212
10275
  ${action}
10213
- </div>`;
10276
+ </div>
10277
+ ${this.#key(account)}
10278
+ ${this.failure?.id === account.id ? b`<div class="failure" role="alert">${this.failure.message}</div>` : A}`;
10214
10279
  }
10215
10280
  render() {
10216
10281
  const settings = this.model?.settings;