Compare commits
3 Commits
openspendi
...
feature/an
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8ba5b11f3 | ||
|
|
bedc9a8d33 | ||
|
|
418b4bfe52 |
@@ -49,20 +49,35 @@ export default function DatasetsSearch({
|
|||||||
? dataset.countryCode === watch().country
|
? dataset.countryCode === watch().country
|
||||||
: true
|
: true
|
||||||
)
|
)
|
||||||
// TODO: Does that really makes sense?
|
.filter((dataset) => {
|
||||||
// What if the fiscalPeriod is 2015-2017 and inputs are
|
const filterMinDate = watch().minDate;
|
||||||
// set to 2015-2016. It's going to be filtered out but
|
const filterMaxDate = watch().maxDate;
|
||||||
// it shouldn't.
|
|
||||||
.filter((dataset) =>
|
const datasetMinDate = dataset.fiscalPeriod?.start;
|
||||||
watch().minDate && watch().minDate !== ''
|
const datasetMaxDate = dataset.fiscalPeriod?.end;
|
||||||
? dataset.fiscalPeriod?.start >= watch().minDate
|
|
||||||
: true
|
let datasetStartOverlaps = false;
|
||||||
)
|
if (datasetMinDate) {
|
||||||
.filter((dataset) =>
|
datasetStartOverlaps =
|
||||||
watch().maxDate && watch().maxDate !== ''
|
datasetMinDate >= filterMinDate && datasetMinDate <= filterMaxDate;
|
||||||
? dataset.fiscalPeriod?.end <= watch().maxDate
|
}
|
||||||
: true
|
|
||||||
);
|
let datasetEndOverlaps = false;
|
||||||
|
if (datasetMaxDate) {
|
||||||
|
datasetEndOverlaps =
|
||||||
|
datasetMaxDate >= filterMinDate && datasetMaxDate <= filterMaxDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filterMinDate && filterMaxDate) {
|
||||||
|
return datasetStartOverlaps || datasetEndOverlaps;
|
||||||
|
} else if (filterMinDate) {
|
||||||
|
return datasetMinDate >= filterMinDate;
|
||||||
|
} else if (filterMaxDate) {
|
||||||
|
return datasetMinDate <= filterMaxDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
const paginatedDatasets = filteredDatasets.slice(
|
const paginatedDatasets = filteredDatasets.slice(
|
||||||
(page - 1) * itemsPerPage,
|
(page - 1) * itemsPerPage,
|
||||||
@@ -111,7 +126,9 @@ export default function DatasetsSearch({
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:basis-1/6">
|
<div className="sm:basis-1/6">
|
||||||
<label className="text-sm text-gray-600 font-medium">Min. date</label>
|
<label className="text-sm text-gray-600 font-medium">
|
||||||
|
Fiscal Period Start
|
||||||
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<input
|
<input
|
||||||
aria-label="Min. date"
|
aria-label="Min. date"
|
||||||
@@ -122,7 +139,9 @@ export default function DatasetsSearch({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:basis-1/6">
|
<div className="sm:basis-1/6">
|
||||||
<label className="text-sm text-gray-600 font-medium">Max. date</label>
|
<label className="text-sm text-gray-600 font-medium">
|
||||||
|
Fiscal Period End
|
||||||
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<input
|
<input
|
||||||
aria-label="Max. date"
|
aria-label="Max. date"
|
||||||
@@ -196,9 +215,9 @@ const CloseIcon = () => {
|
|||||||
id="Vector"
|
id="Vector"
|
||||||
d="M18 18L12 12M12 12L6 6M12 12L18 6M12 12L6 18"
|
d="M18 18L12 12M12 12L6 6M12 12L18 6M12 12L6 18"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
strokeWidth="2"
|
||||||
stroke-linecap="round"
|
strokeLinecap="round"
|
||||||
stroke-linejoin="round"
|
strokeLinejoin="round"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ const Spinning = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Table: React.FC<{ url: string }> = ({ url }) => {
|
export const FlatUiTable: React.FC<{ url: string }> = ({ url }) => {
|
||||||
return (
|
return (
|
||||||
// Provide the client to your App
|
// Provide the client to your App
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
@@ -87,7 +87,7 @@ const TableInner: React.FC<{ url: string }> = ({ url }) => {
|
|||||||
</div>;
|
</div>;
|
||||||
if (parsedData)
|
if (parsedData)
|
||||||
return (
|
return (
|
||||||
<div className="h-[500px] overflow-scroll">
|
<div className="h-[500px] w-full">
|
||||||
<Grid data={parsedData.data} />
|
<Grid data={parsedData.data} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -2,7 +2,7 @@ import { Header } from '../Header';
|
|||||||
|
|
||||||
export default function Layout({ children }) {
|
export default function Layout({ children }) {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white min-h-screen">
|
<div className="bg-white min-h-screen pb-32">
|
||||||
<Header />
|
<Header />
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
3107
examples/openspending/package-lock.json
generated
3107
examples/openspending/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@
|
|||||||
"test": "vitest"
|
"test": "vitest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@flowershow/core": "^0.4.13",
|
||||||
"@githubocto/flat-ui": "^0.14.1",
|
"@githubocto/flat-ui": "^0.14.1",
|
||||||
"@heroicons/react": "^2.0.18",
|
"@heroicons/react": "^2.0.18",
|
||||||
"@octokit/plugin-throttling": "^5.2.2",
|
"@octokit/plugin-throttling": "^5.2.2",
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
"eslint": "8.39.0",
|
"eslint": "8.39.0",
|
||||||
"eslint-config-next": "13.3.1",
|
"eslint-config-next": "13.3.1",
|
||||||
"flexsearch": "0.7.21",
|
"flexsearch": "0.7.21",
|
||||||
"next": "13.3.1",
|
"next": "13.3.0",
|
||||||
"next-seo": "^6.0.0",
|
"next-seo": "^6.0.0",
|
||||||
"octokit": "^2.0.14",
|
"octokit": "^2.0.14",
|
||||||
"papaparse": "^5.4.1",
|
"papaparse": "^5.4.1",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import Layout from '../../../components/_shared/Layout';
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Project } from '../../../lib/project.interface';
|
import { Project } from '../../../lib/project.interface';
|
||||||
import ExternalLinkIcon from '../../../components/icons/ExternalLinkIcon';
|
import ExternalLinkIcon from '../../../components/icons/ExternalLinkIcon';
|
||||||
|
import { FlatUiTable } from '@/components/FlatUiTable';
|
||||||
|
|
||||||
export default function ProjectPage({
|
export default function ProjectPage({
|
||||||
project,
|
project,
|
||||||
@@ -21,7 +22,6 @@ export default function ProjectPage({
|
|||||||
project: Project;
|
project: Project;
|
||||||
readme: string;
|
readme: string;
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
// Get description from datapackage or calculate
|
// Get description from datapackage or calculate
|
||||||
// excerpt from README by getting all the content
|
// excerpt from README by getting all the content
|
||||||
// up to the first dot.
|
// up to the first dot.
|
||||||
@@ -98,7 +98,7 @@ export default function ProjectPage({
|
|||||||
<h3 className="mb-1 mt-10">Data files</h3>
|
<h3 className="mb-1 mt-10">Data files</h3>
|
||||||
<p>
|
<p>
|
||||||
This dataset contains {project.files.length} file
|
This dataset contains {project.files.length} file
|
||||||
{project.files.length != 1 ? '' : 's'}
|
{project.files.length == 1 ? '' : 's'}
|
||||||
</p>
|
</p>
|
||||||
<div className="inline-block min-w-full py-2 align-middle">
|
<div className="inline-block min-w-full py-2 align-middle">
|
||||||
<table className="mt-0 min-w-full divide-y divide-gray-300">
|
<table className="mt-0 min-w-full divide-y divide-gray-300">
|
||||||
@@ -137,7 +137,6 @@ export default function ProjectPage({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={file.name}>
|
<tr key={file.name}>
|
||||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||||
@@ -169,6 +168,44 @@ export default function ProjectPage({
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-y-16 ">
|
||||||
|
{project.files?.map((file) => {
|
||||||
|
let size: number | string = file.size;
|
||||||
|
|
||||||
|
if (!size) {
|
||||||
|
if (file.bytes) {
|
||||||
|
if (file.bytes > 1000000) {
|
||||||
|
size = (file.bytes / 1000000).toFixed(2) + ' MB';
|
||||||
|
} else {
|
||||||
|
size = (file.bytes / 1000).toFixed(2) + ' kB';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div key={file.name}>
|
||||||
|
{file.path && (
|
||||||
|
<>
|
||||||
|
<h4>
|
||||||
|
{file.name}
|
||||||
|
{file.format ? `.${file.format}` : ''}
|
||||||
|
</h4>
|
||||||
|
{file.bytes >= 5132288 && (
|
||||||
|
<span>Previewing 5MB out of {size}</span>
|
||||||
|
)}
|
||||||
|
<FlatUiTable
|
||||||
|
url={
|
||||||
|
file.path.startsWith('http')
|
||||||
|
? file.path
|
||||||
|
: `https://raw.githubusercontent.com/${project.owner.name}/${project.repo.name}/main/${file.path}`
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
{readme && (
|
{readme && (
|
||||||
<>
|
<>
|
||||||
<hr />
|
<hr />
|
||||||
@@ -192,7 +229,6 @@ export async function getStaticPaths() {
|
|||||||
github_pat
|
github_pat
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(allProjects)
|
|
||||||
const paths = allProjects.results.map((project) => ({
|
const paths = allProjects.results.map((project) => ({
|
||||||
params: {
|
params: {
|
||||||
// TODO: dynamize the org
|
// TODO: dynamize the org
|
||||||
@@ -223,7 +259,12 @@ export async function getStaticProps({ params }) {
|
|||||||
const project = loadDataPackage(datapackage, repo);
|
const project = loadDataPackage(datapackage, repo);
|
||||||
|
|
||||||
// TODO: should this be moved to the loader?
|
// TODO: should this be moved to the loader?
|
||||||
const readme = await getProjectReadme(orgName, projectName, 'main', github_pat);
|
const readme = await getProjectReadme(
|
||||||
|
orgName,
|
||||||
|
projectName,
|
||||||
|
'main',
|
||||||
|
github_pat
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -2,10 +2,52 @@ import { AppProps } from 'next/app';
|
|||||||
import './styles.css';
|
import './styles.css';
|
||||||
import { NextSeo } from 'next-seo';
|
import { NextSeo } from 'next-seo';
|
||||||
|
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { pageview } from '@flowershow/core';
|
||||||
|
import Script from 'next/script';
|
||||||
|
import Head from 'next/head';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
|
||||||
function CustomApp({ Component, pageProps }: AppProps) {
|
function CustomApp({ Component, pageProps }: AppProps) {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const GA_TOKEN = 'G-GXZF7NRXX6';
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleRouteChange = (url) => {
|
||||||
|
pageview(url);
|
||||||
|
};
|
||||||
|
router.events.on('routeChangeComplete', handleRouteChange);
|
||||||
|
return () => {
|
||||||
|
router.events.off('routeChangeComplete', handleRouteChange);
|
||||||
|
};
|
||||||
|
}, [router.events]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Head>
|
||||||
|
<link rel="shortcut icon" href="/squared_logo.png" />
|
||||||
|
</Head>
|
||||||
<NextSeo title="OpenSpending" />
|
<NextSeo title="OpenSpending" />
|
||||||
|
<Script
|
||||||
|
strategy="afterInteractive"
|
||||||
|
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TOKEN}`}
|
||||||
|
/>
|
||||||
|
<Script
|
||||||
|
id="gtag-init"
|
||||||
|
strategy="afterInteractive"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', ${GA_TOKEN}, {
|
||||||
|
page_path: window.location.pathname,
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<main className="app">
|
<main className="app">
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
BIN
examples/openspending/public/squared_logo.png
Normal file
BIN
examples/openspending/public/squared_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
@@ -13,7 +13,10 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
"incremental": true
|
"incremental": true,
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const config = {
|
|||||||
// { name: "Components", href: "/docs/components" },
|
// { name: "Components", href: "/docs/components" },
|
||||||
{ name: "Blog", href: "/blog" },
|
{ name: "Blog", href: "/blog" },
|
||||||
{ name: "Showcases", href: "/#showcases" },
|
{ name: "Showcases", href: "/#showcases" },
|
||||||
|
{ name: "Howtos", href: "/howto" },
|
||||||
{ name: "Examples", href: "https://github.com/datopian/portaljs/tree/main/examples", target: "_blank" },
|
{ name: "Examples", href: "https://github.com/datopian/portaljs/tree/main/examples", target: "_blank" },
|
||||||
{ name: "Components", href: "https://storybook.portaljs.org", target: "_blank" },
|
{ name: "Components", href: "https://storybook.portaljs.org", target: "_blank" },
|
||||||
// { name: "DL Demo", href: "/data-literate/demo" },
|
// { name: "DL Demo", href: "/data-literate/demo" },
|
||||||
|
|||||||
Reference in New Issue
Block a user