Skip to content

Commit

Permalink
docs(demo): IssueDetail no longer takes time to navigate to
Browse files Browse the repository at this point in the history
  • Loading branch information
ntucker committed Sep 27, 2024
1 parent 1f7b191 commit 198ac44
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 157 deletions.
16 changes: 8 additions & 8 deletions examples/github-app/src/pages/IssueList.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { useSuspense } from '@data-client/react';
import { List } from 'antd';
import parseLink from 'parse-link-header';
import { memo } from 'react';
import { Issue, IssueResource } from 'resources/Issue';

import IssueListItem from './IssueListItem';
import NextPage from './NextPage';

export default function IssueList({ owner, repo, q }: Props) {
function IssueList({ owner, repo, query = '' }: Props) {
const q = `${query} repo:${owner}/${repo}`;
const {
results: { items: issues },
link,
} = useSuspense(IssueResource.search, { owner, repo, q });
} = useSuspense(IssueResource.search, { q });
const nextPage = parseLink(link)?.next?.page;

return (
Expand All @@ -19,16 +21,14 @@ export default function IssueList({ owner, repo, q }: Props) {
itemLayout="horizontal"
dataSource={issues}
renderItem={(issue) => <IssueListItem key={issue.pk()} issue={issue} />}
loadMore={
nextPage ? (
<NextPage owner={owner} repo={repo} q={q} page={nextPage} />
) : null
}
loadMore={nextPage ? <NextPage q={q} page={nextPage} /> : null}
/>
</>
);
}

type Props = { owner: string; repo: string; q: string } & {
export default memo(IssueList);

type Props = { owner: string; repo: string; query?: string } & {
state?: Issue['state'];
};
4 changes: 3 additions & 1 deletion examples/github-app/src/pages/IssueListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Link } from '@anansi/router';
import { List, Avatar, Skeleton } from 'antd';
import { humanTime } from 'components/human';
import Labels from 'components/Labels';
import { memo } from 'react';
import { Issue } from 'resources/Issue';

export default function IssueListItem({ issue }: { issue: Issue }) {
function IssueListItem({ issue }: { issue: Issue }) {
const actions = [];
if (issue.comments) {
actions.push(
Expand Down Expand Up @@ -54,3 +55,4 @@ export default function IssueListItem({ issue }: { issue: Issue }) {
</List.Item>
);
}
export default memo(IssueListItem);
16 changes: 5 additions & 11 deletions examples/github-app/src/pages/IssuesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import IssueList from './IssueList';

export default function IssuePage({ owner, repo }: Props) {
const search = useLocationSearch();
const q = search?.get('q') || 'is:issue is:open';
const query = `${search?.get('query') || 'is:open'} is:issue`;

return (
<>
{' '}
<Breadcrumb
itemRender={(route, params, routes, paths) =>
route.href ? <Link name="Home">{route.title}</Link> : route.title
Expand Down Expand Up @@ -40,15 +39,10 @@ export default function IssuePage({ owner, repo }: Props) {
},
]}
/>
<IssueList owner={owner} repo={repo} q={q} />
<IssueList owner={owner} repo={repo} query={query} />
</>
);
}
type Props = { owner: string; repo: string } & (
| {
page: number;
}
| {
state?: Issue['state'];
}
);
type Props = { owner: string; repo: string } & {
state?: Issue['state'];
};
6 changes: 1 addition & 5 deletions examples/github-app/src/pages/NextPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { useController, useLoading } from '@data-client/react';
import { Button } from 'antd';
import { IssueResource } from 'resources/Issue';

export default function NextPage({ repo, owner, q, page }: Props) {
export default function NextPage({ q, page }: Props) {
const ctrl = useController();
const [loadMore, loading] = useLoading(() =>
ctrl.fetch(IssueResource.search.getPage, {
page,
repo,
owner,
q,
}),
);
Expand All @@ -20,8 +18,6 @@ export default function NextPage({ repo, owner, q, page }: Props) {
}

export interface Props {
repo: string;
owner: string;
q: string;
page: string;
}
15 changes: 5 additions & 10 deletions examples/github-app/src/pages/PullsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@ import IssueList from './IssueList';

export default function PullsPage({ owner, repo }: Props) {
const search = useLocationSearch();
const q = search?.get('q') || 'is:pr is:open';
const query = `${search?.get('query') || 'is:open'} is:pr`;

return <IssueList owner={owner} repo={repo} q={q} />;
return <IssueList owner={owner} repo={repo} query={query} />;
}
type Props = { owner: string; repo: string } & (
| {
page: number;
}
| {
state?: Issue['state'];
}
);
type Props = { owner: string; repo: string } & {
state?: Issue['state'];
};
3 changes: 2 additions & 1 deletion examples/github-app/src/resources/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { getAuth } from './Auth';
const HOST = 'https://api.github.com';

export class GithubEntity extends Entity {
readonly id: number = -1;
// -1 is not valid, so this indicates it was not initialized
id = -1;
}

export const GithubGqlEndpoint = new GQLEndpoint(
Expand Down
14 changes: 7 additions & 7 deletions examples/github-app/src/resources/Comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { GithubEntity, githubResource } from './Base';
import { User } from './User';

export class Comment extends GithubEntity {
readonly issueUrl: string = '';
readonly htmlUrl: string = '';
readonly body: string = '';
readonly user: User = User.fromJS();
readonly createdAt = Temporal.Instant.fromEpochSeconds(0);
readonly updatedAt = Temporal.Instant.fromEpochSeconds(0);
readonly authorAssociation: string = 'NONE';
issueUrl = '';
htmlUrl = '';
body = '';
user = User.fromJS();
createdAt = Temporal.Instant.fromEpochSeconds(0);
updatedAt = Temporal.Instant.fromEpochSeconds(0);
authorAssociation = 'NONE';

get owner() {
const pieces = this.issueUrl.split('/issues')[0].split('/');
Expand Down
16 changes: 8 additions & 8 deletions examples/github-app/src/resources/Event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ import { Push } from './Push';
import { Review } from './Review';

export class Event extends GithubEntity {
readonly type: EventType = 'WatchEvent';
readonly actor: Record<string, any> = {};
readonly repo: { id: number; name: string; url: string } = {} as any;
readonly payload: Record<string, any> = {};
readonly public: boolean = true;
readonly createdAt = Temporal.Instant.fromEpochSeconds(0);
type: EventType = 'WatchEvent';
actor: Record<string, any> = {};
repo: { id: number; name: string; url: string } = {} as any;
payload: Record<string, unknown> = {};
public = true;
createdAt = Temporal.Instant.fromEpochSeconds(0);

get icon() {
return typeToIcon[this.type];
Expand All @@ -34,7 +34,7 @@ export class Event extends GithubEntity {
export class PullRequestEvent extends Event {
readonly type = 'PullRequestEvent';

declare readonly payload: {
declare payload: {
action: 'closed' | 'opened';
number: number;
pullRequest: Pull;
Expand All @@ -47,7 +47,7 @@ export class PullRequestEvent extends Event {
}
export class PullRequestReviewEvent extends Event {
readonly type = 'PullRequestReviewEvent';
declare readonly payload: {
declare payload: {
action: 'created';
pullRequest: Pull;
review: Review;
Expand Down
72 changes: 43 additions & 29 deletions examples/github-app/src/resources/Issue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,30 @@ import { stateToIcon } from './stateToIcon';
import { User } from './User';

export class Issue extends GithubEntity {
readonly number: number = 0;
readonly repositoryUrl: string = '';
readonly labelsUrl: string = '';
readonly htmlUrl: string = '';
readonly body: string = '';
readonly title: string = '';
readonly user: User = User.fromJS({});
readonly state: 'open' | 'closed' = 'open';
readonly locked: boolean = false;
readonly comments: number = 0;
readonly createdAt = Temporal.Instant.fromEpochSeconds(0);
readonly updatedAt = Temporal.Instant.fromEpochSeconds(0);
readonly closedAt: Date | null = null;
readonly labels: Label[] = [];
readonly authorAssociation: string = 'NONE';
readonly pullRequest: Record<string, any> | null = null;
readonly draft?: boolean;
number = 0;
owner = '';
repo = '';
repositoryUrl = '';
labelsUrl = '';
htmlUrl = '';
body = '';
title = '';
user = User.fromJS({});
state: 'open' | 'closed' = 'open';
locked = false;
comments = 0;
createdAt = Temporal.Instant.fromEpochSeconds(0);
updatedAt = Temporal.Instant.fromEpochSeconds(0);
closedAt: Date | null = null;
labels: Label[] = [];
authorAssociation = 'NONE';
pullRequest: Record<string, any> | null = null;
draft?: boolean;

get stateIcon() {
return stateToIcon[this.state];
}

get owner() {
const pieces = this.repositoryUrl.split('/');
return pieces[pieces.length - 2];
}

get repo() {
const pieces = this.repositoryUrl.split('/');
return pieces[pieces.length - 1];
}

static schema = {
user: User,
createdAt: Temporal.Instant.from,
Expand All @@ -47,18 +39,40 @@ export class Issue extends GithubEntity {
};

pk() {
return [this.repositoryUrl, this.number].join(',');
if (!this.owner) {
const { owner, repo } = splitRepoUrl(this.repositoryUrl);
return `${owner}/${repo}/${this.number}`;
}
return `${this.owner}/${this.repo}/${this.number}`;
}

static process(
input: any,
parent: any,
key: string | undefined,
args: any[],
) {
const { owner, repo } = splitRepoUrl(input.repositoryUrl);
return { owner, repo, ...input };
}
}

function splitRepoUrl(url: string) {
const [a, b, c, d, owner, repo] = url.split('/');
return { owner, repo };
}

export const IssueResource = githubResource({
path: '/repos/:owner/:repo/issues/:number',
schema: Issue,
dataExpiryLength: 60000,
pollFrequency: 60000,
searchParams: {} as IssueFilters | undefined,
paginationField: 'page',
}).extend((Base) => ({
search: Base.getList.extend({
path: '/search/issues\\?q=:q?%20repo\\::owner/:repo&page=:page?',
path: '/search/issues',
searchParams: {} as IssueFilters & { q: string },
schema: {
results: {
incompleteResults: false,
Expand Down
10 changes: 5 additions & 5 deletions examples/github-app/src/resources/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { GithubEntity, githubResource } from './Base';
import PreviewEndpoint from './PreviewEndpoint';

export class Label extends GithubEntity {
readonly nodeId: string = '';
readonly name: string = '';
readonly description: string = '';
readonly color: string = '000000';
readonly default: boolean = false;
nodeId = '';
name = '';
description = '';
color = '000000';
default = false;
}
export const LabelResource = githubResource({
path: '/repos/:owner/:repo/labels/:name',
Expand Down
57 changes: 28 additions & 29 deletions examples/github-app/src/resources/Repository.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,34 @@ import { Temporal } from '@js-temporal/polyfill';
import { GithubEntity, githubResource, GithubGqlEndpoint } from './Base';

export class Repository extends GithubEntity {
readonly name: string = '';
readonly fullName: string = '';
readonly private: boolean = false;
readonly description: string = '';
readonly fork: boolean = false;
readonly homepage: string = '';
readonly language: string | null = null;
readonly forksCount: number = 0;
readonly stargazersCount: number = 0;
readonly watchersCount: number = 0;
readonly size: number = 0;
readonly defaultBranch: string = 'master';
readonly openIssuesCount: number = 0;
readonly isTemplate: boolean = false;
readonly topics: string[] = [];
readonly hasIssues: boolean = false;
readonly hasProjects: boolean = false;
readonly hasWiki: boolean = false;
readonly hasPages: boolean = false;
readonly hasDownloads: boolean = false;
readonly archived: boolean = false;
readonly disabled: boolean = false;
readonly visibility: 'public' | 'private' = 'public';
readonly pushedAt = Temporal.Instant.fromEpochSeconds(0);
readonly createdAt = Temporal.Instant.fromEpochSeconds(0);
readonly updatedAt = Temporal.Instant.fromEpochSeconds(0);
readonly templateRepository: null = null;
readonly owner: { login: string } = { login: '' };
name = '';
fullName = '';
private = false;
description = '';
fork = false;
homepage = '';
language: string | null = null;
forksCount = 0;
stargazersCount = 0;
watchersCount = 0;
size = 0;
defaultBranch = 'master';
openIssuesCount = 0;
isTemplate = false;
topics: string[] = [];
hasIssues = false;
hasProjects = false;
hasWiki = false;
hasPages = false;
hasDownloads = false;
archived = false;
disabled = false;
visibility: 'public' | 'private' = 'public';
pushedAt = Temporal.Instant.fromEpochSeconds(0);
createdAt = Temporal.Instant.fromEpochSeconds(0);
updatedAt = Temporal.Instant.fromEpochSeconds(0);
templateRepository = null;
owner = { login: '' };

static schema = {
pushedAt: Temporal.Instant.from,
Expand All @@ -42,7 +42,6 @@ export class Repository extends GithubEntity {
return [this.owner.login, this.name].join(',');
}

// for the inheritance
static key = 'Repository';
}

Expand Down
Loading

0 comments on commit 198ac44

Please sign in to comment.