Skip to content

Commit b6b8b4e

Browse files
committed
fix community issues
1 parent 14f4845 commit b6b8b4e

File tree

17 files changed

+1383
-68
lines changed

17 files changed

+1383
-68
lines changed

Cargo.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ members = [
1818
]
1919

2020
[workspace.package]
21-
version = "0.3.47"
21+
version = "0.3.48"
2222
edition = "2021"
2323
license = "Apache-2.0 OR MIT"
2424
repository = "https://github.com/RightNow-AI/openfang"

crates/openfang-api/static/index_body.html

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,9 +2645,9 @@ <h3><span x-text="detailHand.icon"></span> <span x-text="detailHand.name"></span
26452645
<!-- ═══ Step 1: Dependencies ═══ -->
26462646
<div class="hand-wizard-body" x-show="setupStep === 1">
26472647
<template x-for="req in (setupWizard.requirements || [])" :key="req.key">
2648-
<div class="dep-card" :class="req.satisfied ? 'dep-met' : 'dep-missing'">
2648+
<div class="dep-card" :class="(req.satisfied || (req.type === 'ApiKey' && apiKeyInputs[req.key] && apiKeyInputs[req.key].trim() !== '')) ? 'dep-met' : 'dep-missing'">
26492649
<div class="dep-card-header">
2650-
<div class="dep-status-icon" :class="[req.satisfied ? 'met' : 'missing', setupChecking ? 'checking' : '']" x-text="req.satisfied ? '\u2713' : '\u2717'"></div>
2650+
<div class="dep-status-icon" :class="[(req.satisfied || (req.type === 'ApiKey' && apiKeyInputs[req.key] && apiKeyInputs[req.key].trim() !== '')) ? 'met' : 'missing', setupChecking ? 'checking' : '']" x-text="(req.satisfied || (req.type === 'ApiKey' && apiKeyInputs[req.key] && apiKeyInputs[req.key].trim() !== '')) ? '\u2713' : '\u2717'"></div>
26512651
<span class="dep-card-title" x-text="req.label"></span>
26522652
<template x-if="req.install && req.install.estimated_time">
26532653
<span class="dep-time-badge" x-text="req.install.estimated_time"></span>
@@ -2690,24 +2690,32 @@ <h3><span x-text="detailHand.icon"></span> <span x-text="detailHand.name"></span
26902690
</ol>
26912691
</template>
26922692

2693-
<!-- API Key: numbered steps + signup link -->
2693+
<!-- API Key: input field + numbered steps + signup link -->
26942694
<template x-if="req.type === 'ApiKey' && req.install">
26952695
<div>
2696-
<template x-if="req.install.steps && req.install.steps.length">
2697-
<ol class="api-key-steps">
2698-
<template x-for="step in req.install.steps" :key="step">
2699-
<li x-text="step"></li>
2700-
</template>
2701-
</ol>
2702-
</template>
2703-
<template x-if="req.install.env_example">
2704-
<div class="install-block" style="margin-top:8px">
2705-
<div class="install-cmd">
2706-
<code x-text="req.install.env_example"></code>
2707-
<button class="copy-btn" :class="{ copied: clipboardMsg === req.install.env_example }" @click="copyToClipboard(req.install.env_example)" x-text="clipboardMsg === req.install.env_example ? 'Copied!' : 'Copy'"></button>
2696+
<div style="margin-bottom:10px">
2697+
<label class="text-xs text-dim" style="display:block;margin-bottom:4px" x-text="'Paste your ' + req.label + ':'"></label>
2698+
<input type="password" class="form-input" x-model="apiKeyInputs[req.key]" :placeholder="req.label" style="width:100%;font-family:var(--font-mono);font-size:12px">
2699+
<div class="text-xs" style="margin-top:4px;color:var(--green)" x-show="apiKeyInputs[req.key] && apiKeyInputs[req.key].trim() !== ''">&check; Token entered</div>
2700+
</div>
2701+
<details style="margin-bottom:8px">
2702+
<summary class="text-xs text-dim" style="cursor:pointer;user-select:none">Or set as environment variable</summary>
2703+
<template x-if="req.install.steps && req.install.steps.length">
2704+
<ol class="api-key-steps">
2705+
<template x-for="step in req.install.steps" :key="step">
2706+
<li x-text="step"></li>
2707+
</template>
2708+
</ol>
2709+
</template>
2710+
<template x-if="req.install.env_example">
2711+
<div class="install-block" style="margin-top:8px">
2712+
<div class="install-cmd">
2713+
<code x-text="req.install.env_example"></code>
2714+
<button class="copy-btn" :class="{ copied: clipboardMsg === req.install.env_example }" @click="copyToClipboard(req.install.env_example)" x-text="clipboardMsg === req.install.env_example ? 'Copied!' : 'Copy'"></button>
2715+
</div>
27082716
</div>
2709-
</div>
2710-
</template>
2717+
</template>
2718+
</details>
27112719
<div class="flex gap-2 mt-2">
27122720
<template x-if="req.install.signup_url">
27132721
<a :href="req.install.signup_url" target="_blank" rel="noopener" class="btn btn-primary btn-sm">Get API Key &rarr;</a>

crates/openfang-api/static/js/pages/hands.js

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ function handsPage() {
3636
_clipboardTimer: null,
3737
detectedPlatform: 'linux',
3838
installPlatforms: {},
39+
apiKeyInputs: {},
3940

4041
async loadData() {
4142
this.loading = true;
@@ -110,11 +111,15 @@ function handsPage() {
110111
} else {
111112
this._detectClientPlatform();
112113
}
113-
// Initialize per-requirement platform selections
114+
// Initialize per-requirement platform selections and API key inputs
114115
this.installPlatforms = {};
116+
this.apiKeyInputs = {};
115117
if (data.requirements) {
116118
for (var j = 0; j < data.requirements.length; j++) {
117119
this.installPlatforms[data.requirements[j].key] = this.detectedPlatform;
120+
if (data.requirements[j].type === 'ApiKey') {
121+
this.apiKeyInputs[data.requirements[j].key] = '';
122+
}
118123
}
119124
}
120125
this.setupWizard = data;
@@ -283,7 +288,10 @@ function handsPage() {
283288
if (!this.setupWizard || !this.setupWizard.requirements) return 0;
284289
var count = 0;
285290
for (var i = 0; i < this.setupWizard.requirements.length; i++) {
286-
if (this.setupWizard.requirements[i].satisfied) count++;
291+
var req = this.setupWizard.requirements[i];
292+
if (req.satisfied) { count++; continue; }
293+
// Count API key reqs as met if user entered a value
294+
if (req.type === 'ApiKey' && this.apiKeyInputs[req.key] && this.apiKeyInputs[req.key].trim() !== '') count++;
287295
}
288296
return count;
289297
},
@@ -294,7 +302,34 @@ function handsPage() {
294302
},
295303

296304
get setupAllReqsMet() {
297-
return this.setupReqsTotal > 0 && this.setupReqsMet === this.setupReqsTotal;
305+
if (!this.setupWizard || !this.setupWizard.requirements) return false;
306+
if (this.setupReqsTotal === 0) return false;
307+
for (var i = 0; i < this.setupWizard.requirements.length; i++) {
308+
var req = this.setupWizard.requirements[i];
309+
if (req.satisfied) continue;
310+
// API key reqs are satisfied if the user entered a value in the input
311+
if (req.type === 'ApiKey' && this.apiKeyInputs[req.key] && this.apiKeyInputs[req.key].trim() !== '') continue;
312+
return false;
313+
}
314+
return true;
315+
},
316+
317+
getSettingKeyForReq(req) {
318+
// Find the matching setting key for an API key requirement.
319+
// Convention: setting key is the lowercase version of the requirement key.
320+
if (!this.setupWizard || !this.setupWizard.settings) return null;
321+
var lowerKey = req.key.toLowerCase();
322+
for (var i = 0; i < this.setupWizard.settings.length; i++) {
323+
if (this.setupWizard.settings[i].key === lowerKey) return lowerKey;
324+
}
325+
// Fallback: try matching by check_value lowercased
326+
if (req.check_value) {
327+
var lowerCheck = req.check_value.toLowerCase();
328+
for (var j = 0; j < this.setupWizard.settings.length; j++) {
329+
if (this.setupWizard.settings[j].key === lowerCheck) return lowerCheck;
330+
}
331+
}
332+
return null;
298333
},
299334

300335
get setupHasReqs() {
@@ -306,6 +341,10 @@ function handsPage() {
306341
},
307342

308343
setupNextStep() {
344+
// When leaving step 1, sync API key inputs into settings values
345+
if (this.setupStep === 1) {
346+
this._syncApiKeysToSettings();
347+
}
309348
if (this.setupStep === 1 && this.setupHasSettings) {
310349
this.setupStep = 2;
311350
} else if (this.setupStep === 1) {
@@ -315,6 +354,19 @@ function handsPage() {
315354
}
316355
},
317356

357+
_syncApiKeysToSettings() {
358+
if (!this.setupWizard || !this.setupWizard.requirements) return;
359+
for (var i = 0; i < this.setupWizard.requirements.length; i++) {
360+
var req = this.setupWizard.requirements[i];
361+
if (req.type === 'ApiKey' && this.apiKeyInputs[req.key] && this.apiKeyInputs[req.key].trim() !== '') {
362+
var settingKey = this.getSettingKeyForReq(req);
363+
if (settingKey) {
364+
this.settingsValues[settingKey] = this.apiKeyInputs[req.key].trim();
365+
}
366+
}
367+
}
368+
},
369+
318370
setupPrevStep() {
319371
if (this.setupStep === 3 && this.setupHasSettings) {
320372
this.setupStep = 2;
@@ -332,11 +384,24 @@ function handsPage() {
332384
this.setupChecking = false;
333385
this.clipboardMsg = null;
334386
this.installPlatforms = {};
387+
this.apiKeyInputs = {};
335388
},
336389

337390
async launchHand() {
338391
if (!this.setupWizard) return;
339392
var handId = this.setupWizard.id;
393+
// Sync API key inputs from step 1 into settings values
394+
if (this.setupWizard.requirements) {
395+
for (var i = 0; i < this.setupWizard.requirements.length; i++) {
396+
var req = this.setupWizard.requirements[i];
397+
if (req.type === 'ApiKey' && this.apiKeyInputs[req.key] && this.apiKeyInputs[req.key].trim() !== '') {
398+
var settingKey = this.getSettingKeyForReq(req);
399+
if (settingKey) {
400+
this.settingsValues[settingKey] = this.apiKeyInputs[req.key].trim();
401+
}
402+
}
403+
}
404+
}
340405
var config = {};
341406
for (var key in this.settingsValues) {
342407
config[key] = this.settingsValues[key];

0 commit comments

Comments
 (0)