A failed report dropped its error under the previous repo's rows, the repo list and the report shared one error slot, a remembered repo that the list lacked left the select on all repos, and the report URL did not encode the repo path. Each request now has its own error, a failed report clears the rows, the remembered repo keeps an option, and the path parts are encoded.
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
// Pure helpers for the issue report's repo filter: the report URL and the
|
|
// select's options. Kept out of the page so the cases are unit tested.
|
|
|
|
/** Select value for "every repo". It cannot collide with a real
|
|
* `owner/name`, which always has a slash. */
|
|
export const ALL_REPOS = "";
|
|
|
|
export interface RepoOption {
|
|
value: string;
|
|
label: string;
|
|
}
|
|
|
|
/** The report URL for a repo filter. The path parts are encoded, so a name
|
|
* with `?`, `#` or `%` stays one path segment. A filter without a slash
|
|
* is not a repo, so it reads as all repos. */
|
|
export function reportUrl(repoFilter: string): string {
|
|
const i = repoFilter.indexOf("/");
|
|
if (i < 0) return "/api/issue-report";
|
|
const org = encodeURIComponent(repoFilter.slice(0, i));
|
|
const name = encodeURIComponent(repoFilter.slice(i + 1));
|
|
return `/api/repos/${org}/${name}/issue-report`;
|
|
}
|
|
|
|
/** The select's options. A remembered repo that the list lacks keeps its
|
|
* own option, so the select shows what the table is filtered to. Once the
|
|
* list has loaded, the label says why the repo is not in it. */
|
|
export function repoOptions(
|
|
repos: string[] | null,
|
|
selected: string,
|
|
): RepoOption[] {
|
|
const options: RepoOption[] = [
|
|
{ value: ALL_REPOS, label: "all repos" },
|
|
...(repos ?? []).map((r) => ({ value: r, label: r })),
|
|
];
|
|
if (selected !== ALL_REPOS && !(repos ?? []).includes(selected)) {
|
|
options.push({
|
|
value: selected,
|
|
label: repos === null ? selected : `${selected} (no open issues)`,
|
|
});
|
|
}
|
|
return options;
|
|
}
|