diff --git a/next/components/atoms/ObservationLevelTable.js b/next/components/atoms/ObservationLevelTable.js
index f1f04f21..8d2bda79 100644
--- a/next/components/atoms/ObservationLevelTable.js
+++ b/next/components/atoms/ObservationLevelTable.js
@@ -18,16 +18,25 @@ export default function ObservationLevel({ resource }) {
const headers = [t('observationLevelTable.entityHeader'), t('observationLevelTable.columnsHeader')];
- let array = []
- const keys = Object.keys(resource?.observationLevels)
+ function sortElements(a, b) {
+ if (a.order < b.order) {
+ return -1;
+ }
+ if (a.order > b.order) {
+ return 1;
+ }
+ return 0;
+ }
- keys.forEach((elm) => {
- const value = resource?.observationLevels[elm]
+ let array = [];
+ const keys = Object.keys(resource?.observationLevels);
+ const sortedLevels = Object.values(resource?.observationLevels).sort(sortElements);
+ sortedLevels.forEach((value) => {
const valueEntity = () => {
- if(value.entity[`name${capitalize(locale)}`]) return value.entity[`name${capitalize(locale)}`]
- if(value.entity.name) return value.entity.name
- return t('observationLevelTable.notProvided')
+ if(value.entity[`name${capitalize(locale)}`]) return value.entity[`name${capitalize(locale)}`];
+ if(value.entity.name) return value.entity.name;
+ return t('observationLevelTable.notProvided');
}
const valueColumns = () => {
diff --git a/next/components/molecules/DataInformationQuery.js b/next/components/molecules/DataInformationQuery.js
index 84ac9326..67ed4ffe 100644
--- a/next/components/molecules/DataInformationQuery.js
+++ b/next/components/molecules/DataInformationQuery.js
@@ -46,6 +46,7 @@ import CheckIcon from "../../public/img/icons/checkIcon";
import Link from "../atoms/Link";
export function CodeHighlight({ language, children }) {
+ const { t } = useTranslation('dataset');
const textRef = useRef(null)
const [isOverflowing, setIsOverflowing] = useState(false)
const [isExpanded, setIsExpanded] = useState(true)
@@ -117,17 +118,17 @@ export function CodeHighlight({ language, children }) {
color:"#9D9FA3",
}}
>
- {hasCopied ? "Copiado" : "Copiar"}
+ {hasCopied ? t('table.copied') : t('table.copy')}
{hasCopied ?
:
- {isExpanded ? "Recolher" : "Expandir"}
+ {isExpanded ? t('table.collapse') : t('table.expand')}
)}
diff --git a/next/components/molecules/Footer.js b/next/components/molecules/Footer.js
index 97957372..e04142d4 100644
--- a/next/components/molecules/Footer.js
+++ b/next/components/molecules/Footer.js
@@ -93,25 +93,24 @@ export default function Footer({ template, ocult = false }) {
if(template === "simple") return (
diff --git a/next/components/molecules/TableColumns.js b/next/components/molecules/TableColumns.js
index cc522e2e..89ff0d71 100644
--- a/next/components/molecules/TableColumns.js
+++ b/next/components/molecules/TableColumns.js
@@ -668,8 +668,8 @@ export default function TableColumns({
- {elm?.node?.coverage?.start && elm?.node?.coverage?.end ?
- elm.node.coverage.start +" - "+ elm.node.coverage.end
+ {elm?.node?.temporalCoverage?.start && elm?.node?.temporalCoverage?.end ?
+ elm.node.temporalCoverage.start +" - "+ elm.node.temporalCoverage.end
:
t('column.notProvided')
}
diff --git a/next/components/molecules/ThemeCatalog.js b/next/components/molecules/ThemeCatalog.js
index d5830062..42165eec 100644
--- a/next/components/molecules/ThemeCatalog.js
+++ b/next/components/molecules/ThemeCatalog.js
@@ -18,7 +18,7 @@ import { triggerGAEvent } from "../../utils";
import Carousel from "../atoms/Carousel";
import SectionText from "../atoms/SectionText";
-import DatasetCard from "../organisms/DatasetCard";
+import DatasetThemeCatalogCard from "../organisms/DatasetThemeCatalogCard";
import RemoveIcon from "../../public/img/icons/removeIcon";
import styles from "../../styles/themeCatalog.module.css";
@@ -249,11 +249,11 @@ function CardThemes ({ responsive, datasetsCards = [], loading, locale }) {
))
:
datasetsCards.map((elm, i) => (
- {
@@ -55,7 +55,6 @@ export default function DatasetResource({
}
useEffect(() => {
-
let dataset_tables = dataset?.tables?.edges.map((elm) => elm.node)
.filter((elm) => elm?.status?.slug !== "under_review")
.filter((elm) => elm?.slug !== "dicionario")
@@ -194,10 +193,24 @@ export default function DatasetResource({
)
}
- function SelectResource() {
- const [widthScreen, setWidthScreen] = useState(0)
+ function SelectResource ({ selectedResource }) {
+ const { t } = useTranslation('dataset');
+ const [widthScreen, setWidthScreen] = useState(0);
+ const [value, setValue] = useState("")
+ const {table, raw_data_source, information_request} = selectedResource;
+
+ const findResourceName = (source, id) => {
+ const resource = source.find(item => item._id === id);
+ return resource ? resource[`name${capitalize(locale)}`] || resource.name : "";
+ };
useEffect(() => {
+ setValue(
+ table ? findResourceName(tables, table) :
+ raw_data_source ? findResourceName(rawDataSources, raw_data_source) :
+ information_request ? findResourceName(informationRequests, information_request) : ""
+ );
+
const updateWidthScreen = () => {
setWidthScreen(window.innerWidth - 48)
}
@@ -209,35 +222,49 @@ export default function DatasetResource({
return () => {
window.removeEventListener('resize', updateWidthScreen)
}
- }, [])
+ }, [table, raw_data_source, information_request]);
return (
:
-
+
}
diff --git a/next/components/organisms/Dataset.js b/next/components/organisms/DatasetSearchCard.js
similarity index 84%
rename from next/components/organisms/Dataset.js
rename to next/components/organisms/DatasetSearchCard.js
index e84fd8c6..7acd9796 100644
--- a/next/components/organisms/Dataset.js
+++ b/next/components/organisms/DatasetSearchCard.js
@@ -15,12 +15,15 @@ import Link from '../atoms/Link';
import LinkIcon from "../../public/img/icons/linkIcon";
import InfoArrowIcon from "../../public/img/icons/infoArrowIcon";
import { DataBaseSolidIcon } from "../../public/img/icons/databaseIcon";
+import axios from "axios";
+import { useState, useEffect } from "react";
export default function Dataset({
id,
name,
+ organizations,
temporalCoverageText,
- organization,
+ spatialCoverage,
tables,
rawDataSources,
informationRequests,
@@ -28,7 +31,7 @@ export default function Dataset({
locale
}) {
const { t } = useTranslation('dataset');
- const router = useRouter();
+ const allowedURLs = ["https://basedosdados.org", "https://staging.basedosdados.org"]
const Tables = () => {
let tablesNumber = tables.number
@@ -155,8 +158,10 @@ export default function Dataset({
_hover={{ opacity: 0.9 }}
>
- {organization[`name${capitalize(locale)}`] || organization?.name}
+ {organizations[0]?.[`name${capitalize(locale)}`] || organizations[0]?.name}
@@ -261,10 +266,36 @@ export default function Dataset({
lineHeight="20px"
color="#71757A"
>
- {temporalCoverageText ? temporalCoverageText : t('noCoverage')}
+ {temporalCoverageText ? temporalCoverageText : t('notProvided')}
+ {!allowedURLs.includes(process.env.NEXT_PUBLIC_BASE_URL_FRONTEND) &&
+
+
+ {t('spatialCoverage')}:
+
+
+ {spatialCoverage ? spatialCoverage : t('notProvided')}
+
+
+ }
+
-
+
- {organization[`name${capitalize(locale)}`] || organization.name || organization.slug}
+ {organizations?.[0]?.[`name${capitalize(locale)}`] || organizations?.[0]?.name || organizations?.[0]?.slug}
diff --git a/next/components/organisms/TablePage.js b/next/components/organisms/TablePage.js
index 82895657..642898ed 100644
--- a/next/components/organisms/TablePage.js
+++ b/next/components/organisms/TablePage.js
@@ -36,16 +36,17 @@ export default function TablePage({ id }) {
const [resource, setResource] = useState({})
const [isError, setIsError] = useState(false)
+ const allowedURLs = ["https://basedosdados.org", "https://staging.basedosdados.org"]
+
useEffect(() => {
const fetchData = async () => {
- setIsLoading(true)
try {
const response = await fetch(`/api/tables/getTable?id=${id}&locale=${locale}`, { method: "GET" })
const result = await response.json()
if (result.success) {
- setResource(result.resource)
- setIsError(false)
+ setResource(result.resource);
+ setIsError(false);
} else {
console.error(result.error)
setIsError(true)
@@ -58,7 +59,8 @@ export default function TablePage({ id }) {
}
}
- fetchData()
+ setIsLoading(true);
+ fetchData();
}, [id, locale])
const TooltipText = ({ text, info, ...props }) => {
@@ -144,38 +146,49 @@ export default function TablePage({ id }) {
}
const PublishedOrDataCleanedBy = ({ resource }) => {
+ if (!resource || typeof resource !== 'object' || Object.keys(resource).length === 0) {
+ return (
+
+ {t('table.notProvided')}
+
+ );
+ }
+
+ const people = Object.values(resource);
+
return (
-
- {resource?.firstName && resource?.lastName ?
-
- {`${resource.firstName} ${resource.lastName}`}
-
- :
-
- {t('table.notProvided')}
-
- }
- {resource?.email && }
- {resource?.github && }
- {resource?.website && }
- {resource?.twitter && }
-
- )
- }
+
+ {people.map((person, index) => (
+
+
+ {person?.firstName && person?.lastName
+ ? `${person.firstName} ${person.lastName}`
+ : t('table.notProvided')
+ }
+
+ {person?.email && }
+ {person?.github && }
+ {person?.website && }
+ {person?.twitter && }
+
+ ))}
+
+ );
+ };
const StackSkeleton = ({ children, ...props }) => {
return (
@@ -232,8 +245,8 @@ export default function TablePage({ id }) {
return formats[value] ? formats[value] : t('table.updateNotDefined')
}
- if(isError) return
-
+ if (isError) return ;
+
return (
-
+
+ {!allowedURLs.includes(process.env.NEXT_PUBLIC_BASE_URL_FRONTEND) &&
+
+
+
+ {t('table.spatialCoverage')}
+
+
+
+
+
+ {resource?.[`spatialCoverageName${capitalize(locale)}`]
+ ? Object.values(resource[`spatialCoverageName${capitalize(locale)}`])
+ .sort((a, b) => a.localeCompare(b, locale))
+ .join(', ')
+ : t('table.notProvided')}
+
+
+
+ }
+
{resource?.rawDataSource?.[0]?.updates?.[0]?.latest ?
- `${formatDate(resource.rawDataSource[0].updates[0].latest)}:`
+ `${formatDate(resource.rawDataSource[0].updates[0].latest)}`
:
t('table.notProvided')
}: {t('table.lastUpdateRawDataSource')}
@@ -471,7 +519,7 @@ export default function TablePage({ id }) {
color="#464A51"
>
{resource?.rawDataSource?.[0]?.polls?.[0]?.latest ?
- `${formatDate(resource.rawDataSource[0].polls[0].latest)}:`
+ `${formatDate(resource.rawDataSource[0].polls[0].latest)}`
:
t('table.notProvided')
}: {t('table.lastCheckRawDataSource')}
diff --git a/next/pages/api/areas/getArea.js b/next/pages/api/areas/getArea.js
new file mode 100644
index 00000000..05874a93
--- /dev/null
+++ b/next/pages/api/areas/getArea.js
@@ -0,0 +1,45 @@
+import axios from "axios";
+import { capitalize } from 'lodash';
+
+const API_URL = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/graphql`;
+
+async function getArea(slug, locale) {
+ try {
+ const res = await axios({
+ url: API_URL,
+ method: "POST",
+ data: {
+ query: `
+ query {
+ allArea (slug: "${slug}") {
+ edges {
+ node {
+ _id
+ slug
+ name
+ name${capitalize(locale)}
+ }
+ }
+ }
+ }
+ `,
+ variables: null
+ }
+ });
+ const data = res?.data?.data?.allArea?.edges;
+ return data;
+ } catch (error) {
+ console.error(error);
+ return null;
+ }
+}
+
+export default async function handler(req, res) {
+ const { slug, locale = 'pt' } = req.query;
+ const result = await getArea(slug, locale);
+
+ if(result.errors) return res.status(500).json({error: result.errors, success: false})
+ if(result === "err") return res.status(500).json({error: "err", success: false})
+
+ return res.status(200).json({resource: result, success: true})
+}
\ No newline at end of file
diff --git a/next/pages/api/areas/getAreas.js b/next/pages/api/areas/getAreas.js
new file mode 100644
index 00000000..0e7ddfea
--- /dev/null
+++ b/next/pages/api/areas/getAreas.js
@@ -0,0 +1,45 @@
+import axios from "axios";
+import { capitalize } from 'lodash';
+
+const API_URL = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/graphql`;
+
+async function getAreas(locale = 'pt') {
+ try {
+ const res = await axios({
+ url: API_URL,
+ method: "POST",
+ data: {
+ query: `
+ query {
+ allArea {
+ edges {
+ node {
+ _id
+ slug
+ name
+ name${capitalize(locale)}
+ }
+ }
+ }
+ }
+ `,
+ variables: null
+ }
+ });
+ const data = res?.data?.data?.allArea?.edges;
+ return data;
+ } catch (error) {
+ console.error(error);
+ return null;
+ }
+}
+
+export default async function handler(req, res) {
+ const { locale } = req.query;
+ const result = await getAreas(locale);
+
+ if(result.errors) return res.status(500).json({error: result.errors, success: false})
+ if(result === "err") return res.status(500).json({error: "err", success: false})
+
+ return res.status(200).json({resource: result, success: true})
+}
\ No newline at end of file
diff --git a/next/pages/api/areas/getCountries.js b/next/pages/api/areas/getCountries.js
new file mode 100644
index 00000000..22b38ea3
--- /dev/null
+++ b/next/pages/api/areas/getCountries.js
@@ -0,0 +1,46 @@
+import axios from "axios";
+import { capitalize } from 'lodash';
+
+const API_URL = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/graphql`;
+
+async function getAreas(locale = 'pt') {
+ try {
+ const res = await axios({
+ url: API_URL,
+ method: "POST",
+ data: {
+ query: `
+ query {
+ allArea (administrativeLevel: A_0) {
+ edges {
+ node {
+ _id
+ slug
+ name
+ name${capitalize(locale)}
+ }
+ }
+ }
+ }
+ `,
+ variables: null
+ }
+ });
+ const data = res?.data?.data?.allArea?.edges;
+
+ return data;
+ } catch (error) {
+ console.error(error);
+ return null;
+ }
+}
+
+export default async function handler(req, res) {
+ const { locale } = req.query;
+ const result = await getAreas(locale);
+
+ if(result.errors) return res.status(500).json({error: result.errors, success: false})
+ if(result === "err") return res.status(500).json({error: "err", success: false})
+
+ return res.status(200).json({resource: result, success: true})
+}
\ No newline at end of file
diff --git a/next/pages/api/datasets/getDataset.js b/next/pages/api/datasets/getDataset.js
index 60e73e92..482ca97a 100644
--- a/next/pages/api/datasets/getDataset.js
+++ b/next/pages/api/datasets/getDataset.js
@@ -20,7 +20,9 @@ export default async function getDataset(id, locale = 'pt') {
name${capitalize(locale)}
description
description${capitalize(locale)}
- coverage
+ temporalCoverage
+ spatialCoverage
+ spatialCoverageName${capitalize(locale)}
themes {
edges {
node {
@@ -39,13 +41,17 @@ export default async function getDataset(id, locale = 'pt') {
}
}
}
- organization {
- _id
- slug
- name
- name${capitalize(locale)}
- website
- picture
+ organizations {
+ edges {
+ node {
+ _id
+ slug
+ name
+ name${capitalize(locale)}
+ website
+ picture
+ }
+ }
}
informationRequests {
edges {
diff --git a/next/pages/api/rawDataSources/getRawDataSource.js b/next/pages/api/rawDataSources/getRawDataSource.js
index cadc8bdb..4b9fc868 100644
--- a/next/pages/api/rawDataSources/getRawDataSource.js
+++ b/next/pages/api/rawDataSources/getRawDataSource.js
@@ -61,6 +61,7 @@ async function getRawDataSource(id, locale = 'pt') {
edges {
node {
_id
+ order
columns {
edges {
node {
diff --git a/next/pages/api/tables/getTable.js b/next/pages/api/tables/getTable.js
index a921390d..e012a7a1 100644
--- a/next/pages/api/tables/getTable.js
+++ b/next/pages/api/tables/getTable.js
@@ -25,14 +25,14 @@ async function getTable(id, locale='pt') {
dataset {
_id
slug
- organization {
- _id
- slug
- name
- name${capitalize(locale)}
- area {
- _id
- slug
+ organizations {
+ edges {
+ node {
+ _id
+ slug
+ name
+ name${capitalize(locale)}
+ }
}
}
}
@@ -46,7 +46,15 @@ async function getTable(id, locale='pt') {
}
}
version
- fullCoverage
+ status {
+ _id
+ slug
+ }
+ isDeprecated
+ temporalCoverage
+ spatialCoverage
+ spatialCoverageName${capitalize(locale)}
+ fullTemporalCoverage
rawDataSource {
edges {
node {
@@ -105,6 +113,7 @@ async function getTable(id, locale='pt') {
edges {
node {
_id
+ order
columns {
edges {
node {
diff --git a/next/pages/api/tables/getTableColumns.js b/next/pages/api/tables/getTableColumns.js
index 1c3f83fb..39b076b5 100644
--- a/next/pages/api/tables/getTableColumns.js
+++ b/next/pages/api/tables/getTableColumns.js
@@ -55,7 +55,9 @@ async function getTableColumns(id, locale = 'pt') {
bigqueryType {
name
}
- coverage
+ temporalCoverage
+ spatialCoverage
+ spatialCoverageName${capitalize(locale)}
measurementUnit
containsSensitiveData
observations
diff --git a/next/pages/dataset/[dataset].js b/next/pages/dataset/[dataset].js
index f1019d18..223dffa5 100644
--- a/next/pages/dataset/[dataset].js
+++ b/next/pages/dataset/[dataset].js
@@ -15,6 +15,7 @@ import Head from "next/head";
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { capitalize } from 'lodash';
+import axios from "axios";
import BigTitle from "../../components/atoms/BigTitle";
import GreenTab from "../../components/atoms/GreenTab";
@@ -35,17 +36,21 @@ import {
export async function getStaticProps(context) {
const { locale, params } = context;
let dataset = null;
+
try {
dataset = await getDataset(params.dataset, locale || 'pt');
+
} catch (error) {
console.error("Fetch error:", error.message);
}
+ const props = {
+ ...(await serverSideTranslations(locale, ['dataset', 'common', 'menu', 'prices'])),
+ dataset,
+ };
+
return {
- props: {
- ...(await serverSideTranslations(locale, ['dataset', 'common', 'menu', 'prices'])),
- dataset,
- },
+ props,
revalidate: 30,
};
}
@@ -68,12 +73,10 @@ export default function DatasetPage ({ dataset }) {
const { query } = router
const [tabIndex, setTabIndex] = useState(0)
- const isDatasetEmpty = dataset === null || Object.keys(dataset).length === 0
+ const allowedURLs = ["https://basedosdados.org", "https://staging.basedosdados.org"]
+
- useEffect(() => {
- if (router.query?.dataset === "mundo-kaggle-olimpiadas") return window.open(`${process.env.NEXT_PUBLIC_BASE_URL_FRONTEND}/dataset/62f8cb83-ac37-48be-874b-b94dd92d3e2b`, "_self")
- if (isDatasetEmpty) return router.push(`${process.env.NEXT_PUBLIC_API_URL}/dataset_redirect?dataset=${query.dataset}`)
- }, [])
+ const isDatasetEmpty = dataset === null || Object.keys(dataset).length === 0
if(isDatasetEmpty) return
@@ -117,7 +120,7 @@ export default function DatasetPage ({ dataset }) {
spacing={0}
>
-
+
-
+
{dataset[`description${capitalize(locale)}`] || dataset.description || t('noDescription')}
-
+
- {t('temporalCoverage')}
+ {t('organization')}
-
- {dataset.coverage || t('noCoverage')}
-
+
+ {dataset.organizations?.edges?.[0]?.node?.[`name${capitalize(locale)}`] || dataset.organizations?.edges?.[0]?.node?.name || t('noOrganization')}
+
+
-
+
- {t('organization')}
+ {t('temporalCoverage')}
-
+ {dataset.temporalCoverage || t('notProvided')}
+
+
+
+ {!allowedURLs.includes(process.env.NEXT_PUBLIC_BASE_URL_FRONTEND) &&
+
+
+ {t('spatialCoverage')}
+
- {dataset.organization?.[`name${capitalize(locale)}`] || dataset.organization?.name || t('noOrganization')}
+ {dataset?.[`spatialCoverageName${capitalize(locale)}`]
+ ? Object.values(dataset[`spatialCoverageName${capitalize(locale)}`])
+ .sort((a, b) => a.localeCompare(b, locale))
+ .join(', ')
+ : t('notProvided')}
-
-
+
+ }
diff --git a/next/pages/search.js b/next/pages/search.js
index 034bc1b5..1ea95799 100644
--- a/next/pages/search.js
+++ b/next/pages/search.js
@@ -27,7 +27,7 @@ import {
import { CheckboxFilterAccordion } from "../components/atoms/FilterAccordion";
import Checkbox from "../components/atoms/Checkbox";
import { TagFilter } from "../components/atoms/Tag";
-import Dataset from "../components/organisms/Dataset";
+import DatasetSearchCard from "../components/organisms/DatasetSearchCard";
import { MainPageTemplate } from "../components/templates/main";
import FilterIcon from "../public/img/icons/filterIcon";
@@ -43,6 +43,7 @@ export async function getStaticProps({ locale }) {
export default function SearchDatasetPage() {
const { t } = useTranslation('dataset')
+ const { locale } = useRouter()
const router = useRouter()
const query = router.query
@@ -55,8 +56,9 @@ export default function SearchDatasetPage() {
const [pageInfo, setPageInfo] = useState({page: 0, count: 0})
const [isLoading, setIsLoading] = useState(true)
+ const allowedURLs = ["https://basedosdados.org", "https://staging.basedosdados.org"]
+
async function getDatasets({q, filters, page}) {
- const { locale } = router
const res = await getSearchDatasets({q, filter: filters, page, locale: locale || 'pt'})
if(res === undefined) return router.push({pathname:"500"})
if(res?.count === 0) setShowEmptyState(true)
@@ -292,12 +294,16 @@ export default function SearchDatasetPage() {
function DatasetCard({ data }) {
return (
- coverage.name)
+ .sort((a, b) => a.localeCompare(b, locale))
+ .join(', ')}
+ organizations={data.organizations}
tables={{
id: data?.first_table_id,
number: data?.n_tables
@@ -314,6 +320,7 @@ export default function SearchDatasetPage() {
free: data?.contains_open_data,
pro: data?.contains_closed_data
}}
+ locale={locale}
/>
)
}
@@ -660,6 +667,25 @@ export default function SearchDatasetPage() {
+ {!allowedURLs.includes(process.env.NEXT_PUBLIC_BASE_URL_FRONTEND) ?
+ <>
+ handleSelectFilter(["spatial_coverage",`${value}`])}
+ isLoading={!isLoading}
+ />
+
+ >
+ :
+ <>>
+ }
+