Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ui/src/names.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ describe('unnamed', () => {
const sonarr = { ...radarr, name: 'sonarr' };
expect(unnamed([radarr, db, self, sonarr], ready).map((t) => t.key)).toEqual(['sonarr']);
});
// tailscale, adopted and stopped: the provider cannot reach it, so Add name
// failed and the prompt came back for it every time.
it('leaves out a stopped app until it runs', () => {
const stopped = { ...radarr, name: 'tailscale', status: { state: 'stopped' } };
const partial = { ...radarr, name: 'sonarr', status: { state: 'partial' } };
expect(unnamed([stopped, partial], ready).map((t) => t.key)).toEqual(['sonarr']);
expect(unnamed([{ ...stopped, status: { state: 'running' } }], ready).map((t) => t.key)).toEqual(['tailscale']);
});
});

describe('trustPage', () => {
Expand Down
14 changes: 11 additions & 3 deletions ui/src/names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ export async function checkTrust(trustName: string): Promise<DeviceTrust> {
return t;
}

type NamedStack = AppUrlStack & { name: string; services?: { name: string; address?: string }[] };
type NamedStack = AppUrlStack & {
name: string;
services?: { name: string; address?: string }[];
status?: AppUrlStack['status'] & { state?: string };
};

/** One app a name can point at. A stack of several apps (crafting-apps) has
* one per app, keyed "<stack>/<service>" and named after the service; any
Expand Down Expand Up @@ -259,9 +263,13 @@ export function nameLabel(s: string): string {
.replace(/^-+|-+$/g, '');
}

/** Apps that could have a name and have none yet (not the provider itself). */
/** Apps that could have a name and have none yet (not the provider itself).
* A stopped stack is left out: the provider probes an app before naming it,
* so naming one that is not running always failed, and the prompt offered
* it again on every visit. It is offered once it runs. */
export function unnamed(stacks: NamedStack[], p: NamesState): NameTarget[] {
return stacks.filter((s) => s.name !== p.provider).flatMap((s) => nameTargets(s).filter((t) => !p.names?.[t.key]));
const stopped = (s: NamedStack) => !!s.status?.state && s.status.state !== 'running' && s.status.state !== 'partial';
return stacks.filter((s) => s.name !== p.provider && !stopped(s)).flatMap((s) => nameTargets(s).filter((t) => !p.names?.[t.key]));
}

export type NameResult = { stack: string; host?: AppName; error?: string };
Expand Down
Loading