[simple-example][lg] - multiple datasets per repo are now possible
This commit is contained in:
122
examples/simple-example/pages/@org/[org]/[...path].tsx
Normal file
122
examples/simple-example/pages/@org/[org]/[...path].tsx
Normal file
@@ -0,0 +1,122 @@
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
import { NextSeo } from 'next-seo';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
import getConfig from 'next/config';
|
||||
import { getProject, GithubProject } from '../../../lib/octokit';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function ProjectPage({ project }) {
|
||||
return (
|
||||
<>
|
||||
<NextSeo title={`PortalJS - @${project.repo_config.owner}/${project.repo_config.repo}${project.base_path !== '/' ? '/' + project.base_path : ''}`} />
|
||||
<main className="prose mx-auto my-8">
|
||||
<Link href='/'>Back to homepage</Link>
|
||||
<h1 className="mb-0">Data</h1>
|
||||
<div className="inline-block min-w-full py-2 align-middle">
|
||||
<table className="min-w-full divide-y divide-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
|
||||
>
|
||||
Size
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200">
|
||||
{project.files.map((file) => (
|
||||
<tr key={file.download_url}>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
<a href={file.download_url}>{file.name}</a>
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
{file.size} Bytes
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h1>Readme</h1>
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]}>
|
||||
{project.readmeContent}
|
||||
</ReactMarkdown>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// Generates `/posts/1` and `/posts/2`
|
||||
export async function getStaticPaths() {
|
||||
const project_name = getConfig().serverRuntimeConfig.project_name;
|
||||
const jsonDirectory = path.join(
|
||||
process.cwd(),
|
||||
`/examples/${project_name}/datasets.json`
|
||||
);
|
||||
const repos = await fs.readFile(jsonDirectory, 'utf8');
|
||||
|
||||
return {
|
||||
paths: JSON.parse(repos).map((repo) => {
|
||||
const projectPath =
|
||||
repo.readme.split('/').length > 1
|
||||
? repo.readme.split('/').slice(0, -1)
|
||||
: null;
|
||||
let path = [repo.repo];
|
||||
if (projectPath) {
|
||||
projectPath.forEach((element) => {
|
||||
path.push(element);
|
||||
});
|
||||
}
|
||||
return {
|
||||
params: { org: repo.owner, path },
|
||||
};
|
||||
}),
|
||||
fallback: false, // can also be true or 'blocking'
|
||||
};
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const project_name = getConfig().serverRuntimeConfig.project_name;
|
||||
const jsonDirectory = path.join(
|
||||
process.cwd(),
|
||||
`/examples/${project_name}/datasets.json`
|
||||
);
|
||||
const reposFile = await fs.readFile(jsonDirectory, 'utf8');
|
||||
const repos: GithubProject[] = JSON.parse(reposFile);
|
||||
const repo = repos.find((_repo) => {
|
||||
const projectPath =
|
||||
_repo.readme.split('/').length > 1
|
||||
? _repo.readme.split('/').slice(0, -1)
|
||||
: null;
|
||||
let path = [_repo.repo];
|
||||
if (projectPath) {
|
||||
projectPath.forEach((element) => {
|
||||
path.push(element);
|
||||
});
|
||||
}
|
||||
return (
|
||||
_repo.owner == params.org &&
|
||||
JSON.stringify(path) === JSON.stringify(params.path)
|
||||
);
|
||||
});
|
||||
const github_pat = getConfig().serverRuntimeConfig.github_pat;
|
||||
const project = await getProject(repo, github_pat);
|
||||
return {
|
||||
props: {
|
||||
project: { ...project, repo_config: repo },
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
import DRD from '../../../../components/drd/DRD';
|
||||
import parse from '../../../../lib/markdown';
|
||||
import Project from '../../../../lib/project';
|
||||
import { NextSeo } from 'next-seo';
|
||||
import MDLayout from 'examples/simple-example/components/MDLayout';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
function CollectionsLayout({ children, ...frontMatter }) {
|
||||
const { title, date, description } = frontMatter;
|
||||
|
||||
return (
|
||||
<article className="docs prose text-primary dark:text-primary-dark dark:prose-invert prose-headings:font-headings prose-a:break-words mx-auto p-6">
|
||||
<header>
|
||||
<div className="mb-6">
|
||||
{date && (
|
||||
<p className="text-sm text-zinc-400 dark:text-zinc-500">
|
||||
<time dateTime={date}>{date}</time>
|
||||
</p>
|
||||
)}
|
||||
{title && <h1 className="mb-2">{title}</h1>}
|
||||
{description && <p className="text-xl mt-0">{description}</p>}
|
||||
</div>
|
||||
</header>
|
||||
<section>{children}</section>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ProjectPage({
|
||||
mdxSource,
|
||||
frontMatter,
|
||||
excerpt,
|
||||
project,
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextSeo title={`PortalJS - @${project.owner}/${project.name}`} />
|
||||
<Head>
|
||||
{/*
|
||||
On index files, add trailling slash to the base path
|
||||
see notes: https://github.com/datopian/datahub-next/issues/69
|
||||
*/}
|
||||
<base href={router.asPath.split('#')[0] + '/'} />
|
||||
</Head>
|
||||
<main>
|
||||
<MDLayout
|
||||
layout={frontMatter.layout}
|
||||
excerpt={excerpt}
|
||||
project={project}
|
||||
{...frontMatter}
|
||||
>
|
||||
<DRD
|
||||
source={mdxSource}
|
||||
frictionless={{
|
||||
views: project.metadata?.views,
|
||||
resources: project.metadata?.resources,
|
||||
}}
|
||||
/>
|
||||
</MDLayout>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// Generates `/posts/1` and `/posts/2`
|
||||
export async function getStaticPaths() {
|
||||
const jsonDirectory = path.join(process.cwd(), '/examples/simple-example/datasets.json');
|
||||
const repos = await fs.readFile(jsonDirectory, 'utf8');
|
||||
|
||||
return {
|
||||
paths: JSON.parse(repos).map(repo => ({ params: { org: repo.owner, project: repo.repo}})),
|
||||
fallback: false, // can also be true or 'blocking'
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const { org: orgName, project: projectName } = params;
|
||||
|
||||
const project = await Project.getFromGitHub(orgName, projectName);
|
||||
|
||||
// Defaults to README
|
||||
let content = project.readme;
|
||||
|
||||
if (content === null) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
let { mdxSource, frontMatter, excerpt } = await parse(content, '.mdx');
|
||||
|
||||
if (project.metadata?.resources) {
|
||||
frontMatter.layout = 'datapackage';
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
mdxSource,
|
||||
frontMatter,
|
||||
excerpt,
|
||||
project: project.serialize(),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import './styles.css';
|
||||
import "../styles/global.css";
|
||||
|
||||
function CustomApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import axios from "axios";
|
||||
|
||||
export default function handler(req, res) {
|
||||
if (!req.query.url) {
|
||||
res.status(200).send({
|
||||
error: true,
|
||||
info: "No url to proxy in query string i.e. ?url=...",
|
||||
});
|
||||
return;
|
||||
}
|
||||
axios({
|
||||
method: "get",
|
||||
url: req.query.url,
|
||||
responseType: "stream",
|
||||
})
|
||||
.then((resp) => {
|
||||
resp.data.pipe(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
res.status(400).send({
|
||||
error: true,
|
||||
info: err.message,
|
||||
detailed: err,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,35 +1,21 @@
|
||||
import parse from '../lib/markdown';
|
||||
import Project from '../lib/project';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
import Link from 'next/link';
|
||||
import { getProject } from '../lib/octokit';
|
||||
import getConfig from 'next/config';
|
||||
|
||||
export async function getStaticProps() {
|
||||
const project_name = getConfig().serverRuntimeConfig.project_name;
|
||||
const jsonDirectory = path.join(
|
||||
process.cwd(),
|
||||
'/examples/simple-example/datasets.json'
|
||||
`/examples/${project_name}/datasets.json`
|
||||
);
|
||||
const repos = await fs.readFile(jsonDirectory, 'utf8');
|
||||
const github_pat = getConfig().serverRuntimeConfig.github_pat;
|
||||
|
||||
const projects = await Promise.all(
|
||||
JSON.parse(repos).map(async (repo) => {
|
||||
const project = await Project.getFromGitHub(repo.owner, repo.repo);
|
||||
|
||||
// Defaults to README
|
||||
const content = project.readme ? project.readme : '';
|
||||
|
||||
let { mdxSource, frontMatter, excerpt } = await parse(content, '.mdx');
|
||||
|
||||
if (project.metadata?.resources) {
|
||||
frontMatter.layout = 'datapackage';
|
||||
}
|
||||
|
||||
return {
|
||||
mdxSource,
|
||||
frontMatter,
|
||||
excerpt,
|
||||
project: project.serialize(),
|
||||
};
|
||||
(JSON.parse(repos)).map(async (repo) => {
|
||||
const project = await getProject(repo, github_pat);
|
||||
return { ...project, repo_config: repo };
|
||||
})
|
||||
);
|
||||
return {
|
||||
@@ -53,37 +39,13 @@ export function Datasets({ projects }) {
|
||||
return (
|
||||
<div className="bg-white">
|
||||
<div className="mx-auto max-w-7xl px-6 py-16 sm:py-24 lg:px-8">
|
||||
<h2 className="text-2xl font-bold leading-10 tracking-tight text-indigo-500">
|
||||
<h2 className="text-2xl font-bold leading-10 tracking-tight">
|
||||
My Datasets
|
||||
</h2>
|
||||
<p className="mt-6 max-w-2xl text-base leading-7 text-gray-600">
|
||||
Here is a list of all my datasets for easy access and sharing
|
||||
</p>
|
||||
<div className="mt-20">
|
||||
{/*
|
||||
<dl className="space-y-16 sm:grid sm:grid-cols-2 sm:gap-x-6 sm:gap-y-16 sm:space-y-0 lg:grid-cols-3 lg:gap-x-10">
|
||||
{projects.map((project) => (
|
||||
<div>
|
||||
<dt className="text-base font-semibold leading-7 text-gray-900">
|
||||
<Link
|
||||
href={`@${project.project.owner}/${project.project.name}`}
|
||||
>
|
||||
{project.project.owner}/{project.project.name}
|
||||
</Link>
|
||||
</dt>
|
||||
<dt className="text-base font-semibold leading-7 text-indigo-600">
|
||||
<a
|
||||
href={`https://github.com/${project.project.owner}/${project.project.name}`}
|
||||
>
|
||||
Github repo
|
||||
</a>
|
||||
</dt>
|
||||
<dd className="mt-2 text-base leading-7 text-gray-600">
|
||||
{project.excerpt !== '' ? project.excerpt : 'No description'}
|
||||
</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl> */}
|
||||
<div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
|
||||
<table className="min-w-full divide-y divide-gray-300">
|
||||
@@ -93,7 +55,13 @@ export function Datasets({ projects }) {
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
|
||||
>
|
||||
Dataset name
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
|
||||
>
|
||||
Repo
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
@@ -117,22 +85,24 @@ export function Datasets({ projects }) {
|
||||
{projects.map((project) => (
|
||||
<tr>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
<a href={project.project.repo_metadata.html_url}>
|
||||
{project.project.owner}/{project.project.name}
|
||||
</a>
|
||||
</td>
|
||||
<td className="px-3 py-4 text-sm text-gray-500">
|
||||
{project.project.repo_metadata.description}
|
||||
{project.repo_config.name
|
||||
? project.repo_config.name
|
||||
: project.full_name + (project.base_path === '/' ? '' : '/' + project.base_path)}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
{formatter.format(
|
||||
new Date(project.project.repo_metadata.updated_at)
|
||||
)}
|
||||
<a href={project.html_url}>{project.full_name}</a>
|
||||
</td>
|
||||
<td className="px-3 py-4 text-sm text-gray-500">
|
||||
{project.repo_config.description
|
||||
? project.repo_config.description
|
||||
: project.description}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
{formatter.format(new Date(project.last_updated))}
|
||||
</td>
|
||||
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
|
||||
<a
|
||||
href={`/@${project.project.owner}/${project.project.name}`}
|
||||
className="text-indigo-600 hover:text-indigo-900"
|
||||
href={`/@${project.repo_config.owner}/${project.repo_config.repo}/${project.base_path === '/' ? '' : project.base_path}`}
|
||||
>
|
||||
More info
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user