Repository navigation
feat(agent-settings): one wake table per agent, heartbeat autosave (TASK-689 slices a + b-partial) #3095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(agent-settings): one wake table per agent, heartbeat autosave (TASK-689 slices a + b-partial) #3095
Changes from all commits
6db3844
07e7d73
ffd6c10
5382f38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,8 +87,9 @@ const V2AgentIdentitySection: React.FC<Props> = ({ installation, update }) => { | |
| setSaved(false); | ||
| }, [installation, profile]); | ||
|
|
||
| const save = async (event: React.FormEvent) => { | ||
| event.preventDefault(); | ||
| // Identity autosaves: a quiet pause after the last edit persists it, so there is no Save button. | ||
| const dirty = displayName.trim() !== (installation.displayName || '') || personaChanged; | ||
| const persist = async () => { | ||
| const name = displayName.trim(); | ||
| if (!name || name.length > 80) { | ||
| setError(t('agentSettings.identityNameError')); | ||
|
|
@@ -128,6 +129,14 @@ const V2AgentIdentitySection: React.FC<Props> = ({ installation, update }) => { | |
| } | ||
| }; | ||
|
|
||
| useEffect(() => { | ||
| if (!dirty) return undefined; | ||
| const timer = window.setTimeout(() => { void persist(); }, 600); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preserve edits made during a save. If a user edits again while a PATCH is in flight, its refresh replaces
|
||
| return () => window.clearTimeout(timer); | ||
| // persist reads the current fields; the timer is keyed on the edited values only. | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, [displayName, persona]); | ||
|
|
||
| const entryOwnerId = listing?.publisher?.userId ? String(listing.publisher.userId) : null; | ||
| const ownsListing = Boolean(currentUser?._id) && entryOwnerId === String(currentUser._id); | ||
| const retired = listing?.status === 'unpublished'; | ||
|
|
@@ -149,7 +158,7 @@ const V2AgentIdentitySection: React.FC<Props> = ({ installation, update }) => { | |
| }; | ||
| return <section className="v2-agent-settings__section" aria-labelledby="agent-identity-title"> | ||
| <h2 id="agent-identity-title">{t('agentSettings.identityTitle')}</h2> | ||
| <form className="v2-agent-settings__identity" onSubmit={save}> | ||
| <form className="v2-agent-settings__identity" onSubmit={(event) => { event.preventDefault(); void persist(); }}> | ||
| <label><span>{t('agentSettings.displayName')}</span> | ||
| <input value={displayName} maxLength={80} required onChange={(event) => setDisplayName(event.target.value)} /> | ||
| </label> | ||
|
|
@@ -172,8 +181,7 @@ const V2AgentIdentitySection: React.FC<Props> = ({ installation, update }) => { | |
| </label> | ||
| </fieldset>} | ||
| <div className="v2-agent-settings__actions"> | ||
| <button type="submit" disabled={busy || (!personaChanged && displayName.trim() === installation.displayName)}>{busy ? t('agentSettings.saving') : t('agentSettings.saveIdentity')}</button> | ||
| {saved && <span role="status">{t('agentSettings.identitySaved')}</span>} | ||
| <span role="status">{busy ? t('agentSettings.saving') : saved && !dirty ? t('agentSettings.identitySaved') : ''}</span> | ||
| </div> | ||
| {error && <p role="alert" className="v2-agent-settings__error">{error}</p>} | ||
| </form> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assert the layout change, not the existing heading.
The former layout also had a Wake heading. This assertion passes if the separate Pods section returns. Assert that the separate Pods heading is absent and that the pod table is present. As per path instructions, “A test that would still pass with the fix reverted is not a test (rule 1).”
Source: Path instructions