Skip to content

Commit

Permalink
[add] KaiYuanShe GitHub modules
Browse files Browse the repository at this point in the history
[fix] Repository names in Project files
  • Loading branch information
TechQuery committed Mar 2, 2024
1 parent f279e47 commit 51f1507
Show file tree
Hide file tree
Showing 17 changed files with 365 additions and 103 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ on:
- v*
env:
ARTIFACT_PATH: /tmp/artifact.tar
BOX_NAME: next-bootstrap-ts
BOX_URL: idea2app/next-bootstrap-ts
BOX_NAME: oss-toolbox
BOX_URL: kaiyuanshe/oss-toolbox

jobs:
deploy_docker_image:
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Next-Bootstrap.ts
# Open Source treasure box

[React][1] project scaffold based on [TypeScript][2], [Next.js][3], [Bootstrap][4] & [Workbox][5]. And this project bootstrapped with [`create-next-app`][6].

[![CI & CD](https://github.com/idea2app/Next-Bootstrap-ts/actions/workflows/main.yml/badge.svg)][7]
[![CI & CD](https://github.com/kaiyuanshe/OSS-toolbox/actions/workflows/main.yml/badge.svg)][7]

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)][8]
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][9]
Expand Down Expand Up @@ -96,9 +96,9 @@ pnpm container
[4]: https://getbootstrap.com/
[5]: https://developers.google.com/web/tools/workbox
[6]: https://github.com/vercel/next.js/tree/canary/packages/create-next-app
[7]: https://github.com/idea2app/Next-Bootstrap-ts/actions/workflows/main.yml
[8]: https://codespaces.new/idea2app/Next-Bootstrap-ts
[9]: https://gitpod.io/?autostart=true#https://github.com/idea2app/Next-Bootstrap-ts
[7]: https://github.com/kaiyuanshe/OSS-toolbox/actions/workflows/main.yml
[8]: https://codespaces.new/kaiyuanshe/OSS-toolbox
[9]: https://gitpod.io/?autostart=true#https://github.com/kaiyuanshe/OSS-toolbox
[10]: https://www.typescriptlang.org/
[11]: https://mdxjs.com/
[12]: https://nextjs.org/
Expand All @@ -110,12 +110,12 @@ pnpm container
[18]: https://sentry.io/
[19]: https://github.com/apps/settings
[20]: https://github.com/new?template_name=Next-Bootstrap-ts&template_owner=idea2app
[21]: https://codespaces.new/idea2app/Next-Bootstrap-ts
[21]: https://codespaces.new/kaiyuanshe/OSS-toolbox
[22]: https://github.com/idea2app/Next-Bootstrap-ts/blob/80967ed49045af9dbcf4d3695a2c39d53a6f71f1/.github/workflows/pull-request.yml#L9-L11
[23]: https://github.com/idea2app/Next-Bootstrap-ts/settings/secrets/actions
[23]: https://github.com/kaiyuanshe/OSS-toolbox/settings/secrets/actions
[24]: https://github.com/kaiyuanshe/kaiyuanshe.github.io/blob/bb4675a56bf1d6b207231313da5ed0af7cf0ebd6/.github/workflows/pull-request.yml#L32-L56
[25]: https://github.com/idea2app/Next-Bootstrap-ts/issues/new/choose
[26]: https://github.com/idea2app/Next-Bootstrap-ts/projects
[25]: https://github.com/kaiyuanshe/OSS-toolbox/issues/new/choose
[26]: https://github.com/kaiyuanshe/OSS-toolbox/projects
[27]: https://nextjs.org/docs/api-routes/introduction
[28]: https://nextjs.org/docs/api-routes/introduction
[29]: https://nextjs.org/docs
Expand Down
75 changes: 75 additions & 0 deletions components/Git/Issue/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Icon, Nameplate, text2color } from 'idea-react';
import { marked } from 'marked';
import { FC } from 'react';
import { Badge, Card, CardProps, Stack } from 'react-bootstrap';

import { Issue } from '../../../models/Repository';

export type IssueCardProps = Issue & Omit<CardProps, 'id' | 'body'>;

export const IssueCard: FC<IssueCardProps> = ({
bg = 'light',
text = 'dark',
id,
number,
title,
labels,
body,
html_url,
user,
comments,
created_at,
...props
}) => (
<Card {...{ ...props, bg, text }}>
<Card.Header
as="h4"
className="d-flex justify-content-between align-items-center gap-3"
>
<a
className="text-decoration-none text-secondary text-truncate"
title={title}
href={html_url}
target="_blank"
rel="noreferrer"
>
#{number} {title}
</a>
<Stack direction="horizontal" gap={2}>
{labels.map(
label =>
typeof label === 'object' && (
<Badge
key={label.name}
className="fs-6"
{...(label.color
? {
bg: '',
style: { background: `#${label.color}` },
}
: {
bg: text2color(label.name || '', ['light']),
})}
>
{label.name}
</Badge>
),
)}
</Stack>
</Card.Header>
<Card.Body
as="article"
dangerouslySetInnerHTML={{ __html: marked(body || '') }}
/>
<Card.Footer className="d-flex justify-content-between align-items-center">
{user && <Nameplate name={user.name || ''} avatar={user.avatar_url} />}

<Stack direction="horizontal" gap={2}>
<Icon name="chat-left-text" />
{comments}
</Stack>

<time dateTime={created_at}>{new Date(created_at).toLocaleString()}</time>
</Card.Footer>
</Card>
);
53 changes: 53 additions & 0 deletions components/Git/Issue/IssueModule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Icon, text2color } from 'idea-react';
import { FC, useState } from 'react';
import { Badge, Card, Col, Collapse, Row } from 'react-bootstrap';

import type { GitRepository } from '../../../models/Repository';
import { IssueCard } from './Card';

export const IssueModule: FC<GitRepository> = ({ name, language, issues }) => {
const [isExpand, setIsExpand] = useState(false);

return (
<Card className="p-0" bg="light" text="dark">
<Card.Header
className="cursor-pointer"
onClick={() => setIsExpand(!isExpand)}
>
<Row className="align-items-center gx-3">
<Col xs={4} sm={2}>
{language && (
<Badge className="fs-6" bg={text2color(language, ['light'])}>
{language}
</Badge>
)}
</Col>
<Col xs={6} sm={8} as="h3" className="m-0 text-truncate">
{name}
</Col>
<Col xs={1} className="text-end">
<Badge className="fs-6" pill bg="info">
{issues.length}
</Badge>
</Col>
<Col xs={1} className="text-end">
<Icon
size={1.5}
name={isExpand ? 'arrows-collapse' : 'arrows-expand'}
/>
</Col>
</Row>
</Card.Header>

<Collapse in={isExpand}>
<Card.Body as={Row} xs={1} sm={2} xl={2} className="g-3">
{issues.map(issue => (
<Col key={issue.title}>
<IssueCard className="h-100" {...issue} />
</Col>
))}
</Card.Body>
</Collapse>
</Card>
);
};
4 changes: 4 additions & 0 deletions components/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export interface Link {
}

export const MainRoutes: () => Link[] = () => [
{
title: 'GitHub issues',
path: '/issue',
},
{ title: t('license_tool'), path: '/tool/license-filter' },
{
title: `${t('Web_polyfill_CDN')} v1`,
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ networks:
idea2app:

services:
next-bootstrap-ts:
image: idea2app/next-bootstrap-ts
oss-toolbox:
image: kaiyuanshe/oss-toolbox
networks:
- idea2app
healthcheck:
Expand Down Expand Up @@ -34,11 +34,11 @@ services:

caddy:
depends_on:
- next-bootstrap-ts
- oss-toolbox
image: caddy
ports:
- 80:80
- 443:443
networks:
- idea2app
command: caddy reverse-proxy --from your.domain.com --to next-bootstrap-ts:3000
command: caddy reverse-proxy --from your.domain.com --to oss-toolbox:3000
2 changes: 1 addition & 1 deletion models/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const ownClient = new HTTPClient({
});

export const githubClient = new HTTPClient({
baseURI: isServer() ? 'https://api.github.com/' : `${API_Host}/api/github/`,
baseURI: isServer() ? 'https://api.github.com/' : `${API_Host}/api/GitHub/`,
responseType: 'json',
}).use(({ request }, next) => {
if (GithubToken)
Expand Down
87 changes: 65 additions & 22 deletions models/Repository.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,91 @@
import { components } from '@octokit/openapi-types';
import { memoize } from 'lodash';
import { ListModel, toggle } from 'mobx-restful';
import { Filter, ListModel, toggle } from 'mobx-restful';
import { averageOf, buildURLData } from 'web-utility';

import { githubClient } from './Base';

type Repository = components['schemas']['minimal-repository'];
export type Organization = components['schemas']['organization-full'];
export type Issue = components['schemas']['issue'];

export interface GitRepository extends Repository {
issues: Issue[];
languages?: string[];
}
export type Organization = components['schemas']['organization-full'];

const getGitLanguages = memoize(async (URI: string) => {
const { body: languageCount } = await githubClient.get<
Record<string, number>
>(`repos/${URI}/languages`);

const languageAverage = averageOf(...Object.values(languageCount!));

const languageList = Object.entries(languageCount!)
.filter(([_, score]) => score >= languageAverage)
.sort(([_, a], [__, b]) => b - a);
export interface RepositoryFilter extends Filter<GitRepository> {
relation: (keyof RepositoryModel['relation'])[];
}

return languageList.map(([name]) => name);
});
type ReturnMap<T> = {
[K in keyof T]: T[K] extends (...data: any[]) => Promise<any>
? Awaited<ReturnType<T[K]>>
: T[K] extends (...data: any[]) => any
? ReturnType<T[K]>
: never;
};

export class RepositoryModel extends ListModel<GitRepository> {
export class RepositoryModel extends ListModel<
GitRepository,
RepositoryFilter
> {
client = githubClient;
baseURI = 'orgs/idea2app/repos';
baseURI = 'orgs/kaiyuanshe/repos';
indexKey = 'full_name' as const;

relation = {
issues: memoize(async (URI: string) => {
const { body: issuesList } = await this.client.get<Issue[]>(
`repos/${URI}/issues?per_page=100`,
);
return issuesList!.filter(({ pull_request }) => !pull_request);
}),
languages: memoize(async (URI: string) => {
const { body: languageCount } = await this.client.get<
Record<string, number>
>(`repos/${URI}/languages`);

const languageAverage = averageOf(...Object.values(languageCount!));

const languageList = Object.entries(languageCount!)
.filter(([_, score]) => score >= languageAverage)
.sort(([_, a], [__, b]) => b - a);

return languageList.map(([name]) => name);
}),
};

async getOneRelation(
URI: string,
relation: RepositoryFilter['relation'] = [],
) {
const relationData = await Promise.all(
relation.map(async key => {
const value = await this.relation[key](URI);
return [key, value];
}),
);
return Object.fromEntries(relationData) as ReturnMap<
RepositoryModel['relation']
>;
}

@toggle('downloading')
async getOne(URI: string) {
async getOne(URI: string, relation: RepositoryFilter['relation'] = []) {
const { body } = await this.client.get<Repository>(`repos/${URI}`);

return (this.currentOne = {
...body!,
languages: await getGitLanguages(URI),
...(await this.getOneRelation(URI, relation)),
});
}

async loadPage(page: number, per_page: number) {
async loadPage(
page: number,
per_page: number,
{ relation }: RepositoryFilter,
) {
const { body: list } = await this.client.get<Repository[]>(
`${this.baseURI}?${buildURLData({
type: 'public',
Expand All @@ -51,10 +95,9 @@ export class RepositoryModel extends ListModel<GitRepository> {
})}`,
);
const pageData = await Promise.all(
list!.map(async ({ full_name, ...item }) => ({
list!.map(async item => ({
...item,
full_name,
languages: await getGitLanguages(full_name),
...(await this.getOneRelation(item.full_name, relation)),
})),
);
const [_, organization] = this.baseURI.split('/');
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@idea2app/next-bootstrap-ts",
"name": "@kaiyuanshe/oss-toolbox",
"version": "1.6.0",
"description": "React project scaffold based on TypeScript, Next.js, Bootstrap & Workbox.",
"private": true,
Expand Down Expand Up @@ -27,6 +27,7 @@
"less-loader": "^12.2.0",
"license-filter": "^0.2.4",
"lodash": "^4.17.21",
"marked": "^12.0.0",
"mobx": "^6.12.0",
"mobx-i18n": "^0.5.0",
"mobx-react": "^9.1.0",
Expand Down Expand Up @@ -82,7 +83,7 @@
"start": "next start",
"lint": "next lint",
"test": "lint-staged && npm run lint",
"pack-image": "docker build -t idea2app/next-bootstrap-ts:latest .",
"container": "docker rm -f next-bootstrap-ts && docker run --name next-bootstrap-ts -p 3000:3000 -d idea2app/next-bootstrap-ts:latest"
"pack-image": "docker build -t kaiyuanshe/oss-toolbox:latest .",
"container": "docker rm -f oss-toolbox && docker run --name oss-toolbox -p 3000:3000 -d kaiyuanshe/oss-toolbox:latest"
}
}
3 changes: 3 additions & 0 deletions pages/api/GitHub/[...slug].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { proxyGithub } from './core';

export default proxyGithub();
Loading

1 comment on commit 51f1507

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for oss-toolbox ready!

✅ Preview
https://oss-toolbox-1b90vcwa8-techquery.vercel.app

Built with commit 51f1507.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.