Compare commits
12 Commits
fix_id_res
...
@portaljs/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68fbf2cda6 | ||
|
|
83fd7727ba | ||
|
|
083d3178cd | ||
|
|
3200dc5ade | ||
|
|
32dce434eb | ||
|
|
37ef29d9a2 | ||
|
|
98d62532c5 | ||
|
|
50122cd0cb | ||
|
|
0156e72dd3 | ||
|
|
91217f3256 | ||
|
|
11f9253709 | ||
|
|
3efba6578d |
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'@portaljs/ckan': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
remove optional from id in resource interface
|
|
||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -46942,7 +46942,7 @@
|
|||||||
},
|
},
|
||||||
"packages/ckan": {
|
"packages/ckan": {
|
||||||
"name": "@portaljs/ckan",
|
"name": "@portaljs/ckan",
|
||||||
"version": "0.0.3",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"swr": "^2.1.5",
|
"swr": "^2.1.5",
|
||||||
@@ -47347,7 +47347,7 @@
|
|||||||
},
|
},
|
||||||
"packages/components": {
|
"packages/components": {
|
||||||
"name": "@portaljs/components",
|
"name": "@portaljs/components",
|
||||||
"version": "0.3.1",
|
"version": "0.3.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@githubocto/flat-ui": "^0.14.1",
|
"@githubocto/flat-ui": "^0.14.1",
|
||||||
"@heroicons/react": "^2.0.17",
|
"@heroicons/react": "^2.0.17",
|
||||||
@@ -47828,7 +47828,7 @@
|
|||||||
},
|
},
|
||||||
"packages/remark-wiki-link": {
|
"packages/remark-wiki-link": {
|
||||||
"name": "@portaljs/remark-wiki-link",
|
"name": "@portaljs/remark-wiki-link",
|
||||||
"version": "1.0.4",
|
"version": "1.1.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mdast-util-to-markdown": "^1.5.0",
|
"mdast-util-to-markdown": "^1.5.0",
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
# @portaljs/ckan
|
# @portaljs/ckan
|
||||||
|
|
||||||
|
## 0.1.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- [#1018](https://github.com/datopian/portaljs/pull/1018) [`50122cd0`](https://github.com/datopian/portaljs/commit/50122cd0cbbf68bdadc641341279b30b22538cfd) Thanks [@demenech](https://github.com/demenech)! - package_search method now supports custom headers and include_private parameter
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- [#1016](https://github.com/datopian/portaljs/pull/1016) [`91217f32`](https://github.com/datopian/portaljs/commit/91217f325657e2f298b0e632793ae9bb8b08e870) Thanks [@luccasmmg](https://github.com/luccasmmg)! - remove optional from id in resource interface
|
||||||
|
|
||||||
## 0.0.5
|
## 0.0.5
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@portaljs/ckan",
|
"name": "@portaljs/ckan",
|
||||||
"version": "0.0.5",
|
"version": "0.1.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "https://portaljs.org",
|
"description": "https://portaljs.org",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export interface PackageSearchOptions {
|
|||||||
query?: string;
|
query?: string;
|
||||||
resFormat?: Array<string>;
|
resFormat?: Array<string>;
|
||||||
sort?: string;
|
sort?: string;
|
||||||
|
include_private?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Tag {
|
export interface Tag {
|
||||||
|
|||||||
@@ -31,11 +31,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getDatasetsListWithDetails(options: DatasetListQueryOptions) {
|
async getDatasetsListWithDetails(options: DatasetListQueryOptions) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/current_package_list_with_resources?offset=${options.offset}&limit=${options.limit}`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/current_package_list_with_resources?offset=${
|
|
||||||
options.offset
|
|
||||||
}&limit=${options.limit}`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -44,7 +40,8 @@ export default class CKAN {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async packageSearch(
|
async packageSearch(
|
||||||
options: PackageSearchOptions
|
options: PackageSearchOptions,
|
||||||
|
reqOptions: Partial<RequestInit> = {}
|
||||||
): Promise<{ datasets: Dataset[]; count: number }> {
|
): Promise<{ datasets: Dataset[]; count: number }> {
|
||||||
function buildGroupsQuery(groups: Array<string>) {
|
function buildGroupsQuery(groups: Array<string>) {
|
||||||
if (groups.length > 0) {
|
if (groups.length > 0) {
|
||||||
@@ -99,16 +96,18 @@ export default class CKAN {
|
|||||||
options.groups,
|
options.groups,
|
||||||
options?.resFormat
|
options?.resFormat
|
||||||
);
|
);
|
||||||
const response = await fetchRetry(
|
|
||||||
`${
|
let url = `${this.DMS}/api/3/action/package_search?`;
|
||||||
this.DMS
|
url += `start=${options.offset}`;
|
||||||
}/api/3/action/package_search?start=${options.offset}&rows=${
|
url += `&rows=${options.limit}`;
|
||||||
options.limit
|
url += fq ? fq : '';
|
||||||
}${fq ? fq : ''}${options.query ? '&q=' + options.query : ''}${
|
url += options.query ? '&q=' + options.query : '';
|
||||||
options.sort ? '&sort=' + options.sort : ''
|
url += options.sort ? '&sort=' + options.sort : '';
|
||||||
}`,
|
url += options.include_private
|
||||||
3
|
? '&include_private=' + options.include_private
|
||||||
);
|
: '';
|
||||||
|
|
||||||
|
const response = await fetchRetry(url, 3, reqOptions);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
const datasets: Array<Dataset> = responseData.result.results;
|
const datasets: Array<Dataset> = responseData.result.results;
|
||||||
return { datasets, count: responseData.result.count };
|
return { datasets, count: responseData.result.count };
|
||||||
@@ -116,9 +115,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getDatasetDetails(datasetName: string) {
|
async getDatasetDetails(datasetName: string) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/package_show?id=${datasetName}`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/package_show?id=${datasetName}`,
|
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -131,9 +128,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getDatasetActivityStream(datasetName: string) {
|
async getDatasetActivityStream(datasetName: string) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/package_activity_list?id=${datasetName}`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/package_activity_list?id=${datasetName}`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -151,9 +146,7 @@ export default class CKAN {
|
|||||||
async getUser(userId: string) {
|
async getUser(userId: string) {
|
||||||
try {
|
try {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/user_show?id=${userId}`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/user_show?id=${userId}`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -166,10 +159,7 @@ export default class CKAN {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getGroupList() {
|
async getGroupList() {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(`${this.DMS}/api/3/action/group_list`, 3);
|
||||||
`${this.DMS}/api/3/action/group_list`,
|
|
||||||
3
|
|
||||||
);
|
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
const groups: Array<string> = responseData.result;
|
const groups: Array<string> = responseData.result;
|
||||||
return groups;
|
return groups;
|
||||||
@@ -177,9 +167,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getGroupsWithDetails() {
|
async getGroupsWithDetails() {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/group_list?all_fields=True`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/group_list?all_fields=True`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -189,9 +177,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getGroupDetails(groupName: string) {
|
async getGroupDetails(groupName: string) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/group_show?id=${groupName}&include_datasets=True`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/group_show?id=${groupName}&include_datasets=True`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -201,9 +187,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getGroupActivityStream(groupName: string) {
|
async getGroupActivityStream(groupName: string) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/group_activity_list?id=${groupName}`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/group_activity_list?id=${groupName}`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -230,9 +214,7 @@ export default class CKAN {
|
|||||||
async getOrgsWithDetails(accrossPages?: boolean) {
|
async getOrgsWithDetails(accrossPages?: boolean) {
|
||||||
if (!accrossPages) {
|
if (!accrossPages) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/organization_list?all_fields=True`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/organization_list?all_fields=True`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -251,9 +233,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
for (let i = 0; i < pages; i++) {
|
for (let i = 0; i < pages; i++) {
|
||||||
let allOrgListResponse = await fetchRetry(
|
let allOrgListResponse = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/organization_list?all_fields=True&offset=${
|
||||||
this.DMS
|
|
||||||
}/api/3/action/organization_list?all_fields=True&offset=${
|
|
||||||
i * 25
|
i * 25
|
||||||
}&limit=25`,
|
}&limit=25`,
|
||||||
3
|
3
|
||||||
@@ -267,9 +247,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getOrgDetails(orgName: string) {
|
async getOrgDetails(orgName: string) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/organization_show?id=${orgName}&include_datasets=True`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/organization_show?id=${orgName}&include_datasets=True`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -279,9 +257,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getOrgActivityStream(orgName: string) {
|
async getOrgActivityStream(orgName: string) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/organization_activity_list?id=${orgName}`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/organization_activity_list?id=${orgName}`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -297,9 +273,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getAllTags() {
|
async getAllTags() {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/tag_list?all_fields=True`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/tag_list?all_fields=True`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -308,49 +282,41 @@ export default class CKAN {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getResourcesWithAliasList() {
|
async getResourcesWithAliasList() {
|
||||||
const response = await fetch(
|
const response = await fetch(`${this.DMS}/api/3/action/datastore_search`, {
|
||||||
`${this.DMS}/api/3/action/datastore_search`,
|
method: 'POST',
|
||||||
{
|
headers: {
|
||||||
method: 'POST',
|
Accept: 'application/json',
|
||||||
headers: {
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
},
|
||||||
'Content-Type': 'application/json',
|
body: JSON.stringify({
|
||||||
},
|
id: '_table_metadata',
|
||||||
body: JSON.stringify({
|
limit: '32000',
|
||||||
id: '_table_metadata',
|
}),
|
||||||
limit: '32000',
|
});
|
||||||
}),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
const tableMetadata: Array<TableMetadata> = responseData.result.records;
|
const tableMetadata: Array<TableMetadata> = responseData.result.records;
|
||||||
return tableMetadata.filter((item) => item.alias_of);
|
return tableMetadata.filter((item) => item.alias_of);
|
||||||
}
|
}
|
||||||
|
|
||||||
async datastoreSearch(resourceId: string) {
|
async datastoreSearch(resourceId: string) {
|
||||||
const response = await fetch(
|
const response = await fetch(`${this.DMS}/api/3/action/datastore_search`, {
|
||||||
`${this.DMS}/api/3/action/datastore_search`,
|
method: 'POST',
|
||||||
{
|
headers: {
|
||||||
method: 'POST',
|
Accept: 'application/json',
|
||||||
headers: {
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
},
|
||||||
'Content-Type': 'application/json',
|
body: JSON.stringify({
|
||||||
},
|
id: resourceId,
|
||||||
body: JSON.stringify({
|
limit: '32000',
|
||||||
id: resourceId,
|
}),
|
||||||
limit: '32000',
|
});
|
||||||
}),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
return responseData.result.records;
|
return responseData.result.records;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getResourceMetadata(resourceId: string) {
|
async getResourceMetadata(resourceId: string) {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/resource_show?id=${resourceId}`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/resource_show?id=${resourceId}`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
@@ -359,17 +325,14 @@ export default class CKAN {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getResourceInfo(resourceId: string) {
|
async getResourceInfo(resourceId: string) {
|
||||||
const response = await fetch(
|
const response = await fetch(`${this.DMS}/api/3/action/datastore_info`, {
|
||||||
`${this.DMS}/api/3/action/datastore_info`,
|
method: 'POST',
|
||||||
{
|
headers: {
|
||||||
method: 'POST',
|
Accept: 'application/json',
|
||||||
headers: {
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
},
|
||||||
'Content-Type': 'application/json',
|
body: JSON.stringify({ resource_id: resourceId }),
|
||||||
},
|
});
|
||||||
body: JSON.stringify({ resource_id: resourceId }),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
const resourceInfo: Array<ResourceInfo> = responseData.result;
|
const resourceInfo: Array<ResourceInfo> = responseData.result;
|
||||||
return resourceInfo;
|
return resourceInfo;
|
||||||
@@ -377,9 +340,7 @@ export default class CKAN {
|
|||||||
|
|
||||||
async getFacetFields(field: 'res_format' | 'tags') {
|
async getFacetFields(field: 'res_format' | 'tags') {
|
||||||
const response = await fetchRetry(
|
const response = await fetchRetry(
|
||||||
`${
|
`${this.DMS}/api/3/action/package_search?facet.field=["${field}"]&rows=0`,
|
||||||
this.DMS
|
|
||||||
}/api/3/action/package_search?facet.field=["${field}"]&rows=0`,
|
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
|
|||||||
@@ -9,10 +9,14 @@ export function getDaysAgo(date: string) {
|
|||||||
return (+today - +createdOn) / msInDay;
|
return (+today - +createdOn) / msInDay;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function fetchRetry(url: string, n: number): Promise<any> {
|
export default async function fetchRetry(
|
||||||
|
url: string,
|
||||||
|
n: number,
|
||||||
|
opts: Partial<RequestInit> = {}
|
||||||
|
): Promise<any> {
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const id = setTimeout(() => abortController.abort(), 30000);
|
const id = setTimeout(() => abortController.abort(), 30000);
|
||||||
const res = await fetch(url, { signal: abortController.signal });
|
const res = await fetch(url, { signal: abortController.signal, ...opts });
|
||||||
clearTimeout(id);
|
clearTimeout(id);
|
||||||
if (!res.ok && n && n > 0) {
|
if (!res.ok && n && n > 0) {
|
||||||
return await fetchRetry(url, n - 1);
|
return await fetchRetry(url, n - 1);
|
||||||
@@ -21,13 +25,13 @@ export default async function fetchRetry(url: string, n: number): Promise<any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function removeTag(tag?: string) {
|
export function removeTag(tag?: string) {
|
||||||
if (tag === "{{description}}" || !tag) {
|
if (tag === '{{description}}' || !tag) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== 'undefined') {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement('div');
|
||||||
div.innerHTML = tag;
|
div.innerHTML = tag;
|
||||||
return div.textContent || div.innerText || "";
|
return div.textContent || div.innerText || '';
|
||||||
}
|
}
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
@@ -38,10 +42,10 @@ export function convertFieldSchema(
|
|||||||
) {
|
) {
|
||||||
function convertToGraphqlString(fieldName: string) {
|
function convertToGraphqlString(fieldName: string) {
|
||||||
return fieldName
|
return fieldName
|
||||||
.replaceAll(" ", "_")
|
.replaceAll(' ', '_')
|
||||||
.replaceAll("(", "_")
|
.replaceAll('(', '_')
|
||||||
.replaceAll(")", "_")
|
.replaceAll(')', '_')
|
||||||
.replace(/[^\w\s]|(_)\1/gi, "_");
|
.replace(/[^\w\s]|(_)\1/gi, '_');
|
||||||
}
|
}
|
||||||
const entries = Object.entries(schema);
|
const entries = Object.entries(schema);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @portaljs/components
|
# @portaljs/components
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- [#1022](https://github.com/datopian/portaljs/pull/1022) [`83fd7727`](https://github.com/datopian/portaljs/commit/83fd7727bafb4902218777597e9848a3e3a71d87) Thanks [@luccasmmg](https://github.com/luccasmmg)! - FlatUiTables now accepts a bytes param and a parsingConfig param for CSV links
|
||||||
|
|
||||||
## 0.3.2
|
## 0.3.2
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@portaljs/components",
|
"name": "@portaljs/components",
|
||||||
"version": "0.3.2",
|
"version": "0.4.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "https://portaljs.org",
|
"description": "https://portaljs.org",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -5,22 +5,20 @@ import LoadingSpinner from './LoadingSpinner';
|
|||||||
|
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
export async function getCsv(url: string, corsProxy?: string) {
|
export async function getCsv(url: string, bytes) {
|
||||||
if (corsProxy) {
|
|
||||||
url = corsProxy + url;
|
|
||||||
}
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
Range: 'bytes=0-5132288',
|
Range: `bytes=0-${bytes}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const data = await response.text();
|
const data = await response.text();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseCsv(file: string): Promise<any> {
|
export async function parseCsv(file: string, parsingConfig): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Papa.parse(file, {
|
Papa.parse(file, {
|
||||||
|
...parsingConfig,
|
||||||
header: true,
|
header: true,
|
||||||
dynamicTyping: true,
|
dynamicTyping: true,
|
||||||
skipEmptyLines: true,
|
skipEmptyLines: true,
|
||||||
@@ -41,25 +39,28 @@ export interface FlatUiTableProps {
|
|||||||
url?: string;
|
url?: string;
|
||||||
data?: { [key: string]: number | string }[];
|
data?: { [key: string]: number | string }[];
|
||||||
rawCsv?: string;
|
rawCsv?: string;
|
||||||
corsProxy?: string;
|
|
||||||
randomId?: number;
|
randomId?: number;
|
||||||
|
bytes: number;
|
||||||
|
parsingConfig: any;
|
||||||
}
|
}
|
||||||
export const FlatUiTable: React.FC<FlatUiTableProps> = ({
|
export const FlatUiTable: React.FC<FlatUiTableProps> = ({
|
||||||
url,
|
url,
|
||||||
data,
|
data,
|
||||||
rawCsv,
|
rawCsv,
|
||||||
corsProxy,
|
bytes = 5132288,
|
||||||
|
parsingConfig = {},
|
||||||
}) => {
|
}) => {
|
||||||
const randomId = Math.random();
|
const randomId = Math.random();
|
||||||
return (
|
return (
|
||||||
// Provide the client to your App
|
// Provide the client to your App
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<TableInner
|
<TableInner
|
||||||
corsProxy={corsProxy}
|
bytes={bytes}
|
||||||
url={url}
|
url={url}
|
||||||
data={data}
|
data={data}
|
||||||
rawCsv={rawCsv}
|
rawCsv={rawCsv}
|
||||||
randomId={randomId}
|
randomId={randomId}
|
||||||
|
parsingConfig={parsingConfig}
|
||||||
/>
|
/>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
@@ -69,8 +70,9 @@ const TableInner: React.FC<FlatUiTableProps> = ({
|
|||||||
url,
|
url,
|
||||||
data,
|
data,
|
||||||
rawCsv,
|
rawCsv,
|
||||||
corsProxy,
|
|
||||||
randomId,
|
randomId,
|
||||||
|
bytes,
|
||||||
|
parsingConfig,
|
||||||
}) => {
|
}) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
return (
|
return (
|
||||||
@@ -81,12 +83,16 @@ const TableInner: React.FC<FlatUiTableProps> = ({
|
|||||||
}
|
}
|
||||||
const { data: csvString, isLoading: isDownloadingCSV } = useQuery(
|
const { data: csvString, isLoading: isDownloadingCSV } = useQuery(
|
||||||
['dataCsv', url, randomId],
|
['dataCsv', url, randomId],
|
||||||
() => getCsv(url as string, corsProxy),
|
() => getCsv(url as string, bytes),
|
||||||
{ enabled: !!url }
|
{ enabled: !!url }
|
||||||
);
|
);
|
||||||
const { data: parsedData, isLoading: isParsing } = useQuery(
|
const { data: parsedData, isLoading: isParsing } = useQuery(
|
||||||
['dataPreview', csvString, randomId],
|
['dataPreview', csvString, randomId],
|
||||||
() => parseCsv(rawCsv ? (rawCsv as string) : (csvString as string)),
|
() =>
|
||||||
|
parseCsv(
|
||||||
|
rawCsv ? (rawCsv as string) : (csvString as string),
|
||||||
|
parsingConfig
|
||||||
|
),
|
||||||
{ enabled: rawCsv ? true : !!csvString }
|
{ enabled: rawCsv ? true : !!csvString }
|
||||||
);
|
);
|
||||||
if (isParsing || isDownloadingCSV)
|
if (isParsing || isDownloadingCSV)
|
||||||
|
|||||||
@@ -9,17 +9,24 @@ const meta: Meta = {
|
|||||||
tags: ['autodocs'],
|
tags: ['autodocs'],
|
||||||
argTypes: {
|
argTypes: {
|
||||||
data: {
|
data: {
|
||||||
description: "Data to be displayed in the table, must be setup as an array of key value pairs"
|
description:
|
||||||
|
'Data to be displayed in the table, must be setup as an array of key value pairs',
|
||||||
},
|
},
|
||||||
csv: {
|
csv: {
|
||||||
description: "CSV data as string.",
|
description: 'CSV data as string.',
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
description: "Fetch the data from a CSV file remotely. only the first 5MB of data will be displayed"
|
description:
|
||||||
|
'Fetch the data from a CSV file remotely. only the first 5MB of data will be displayed',
|
||||||
|
},
|
||||||
|
bytes: {
|
||||||
|
description:
|
||||||
|
'Fetch the data from a CSV file remotely. only the first <bytes> of data will be displayed',
|
||||||
|
},
|
||||||
|
parsingConfig: {
|
||||||
|
description:
|
||||||
|
'Configuration for parsing the CSV data. See https://www.papaparse.com/docs#config for more details',
|
||||||
},
|
},
|
||||||
corsProxy: {
|
|
||||||
description: "Optionally you cant set a CORS Proxy to which all your requests you be redirected"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,7 +36,7 @@ type Story = StoryObj<FlatUiTableProps>;
|
|||||||
|
|
||||||
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
|
||||||
export const FromColumnsAndData: Story = {
|
export const FromColumnsAndData: Story = {
|
||||||
name: "Table data",
|
name: 'Table data',
|
||||||
args: {
|
args: {
|
||||||
data: [
|
data: [
|
||||||
{ id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 },
|
{ id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 },
|
||||||
@@ -44,20 +51,19 @@ export const FromColumnsAndData: Story = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const FromRawCSV: Story = {
|
export const FromRawCSV: Story = {
|
||||||
name: "Table from raw CSV",
|
name: 'Table from raw CSV',
|
||||||
args: {
|
args: {
|
||||||
rawCsv: `
|
rawCsv: `
|
||||||
Year,Temp Anomaly
|
Year,Temp Anomaly
|
||||||
1850,-0.418
|
1850,-0.418
|
||||||
2020,0.923
|
2020,0.923
|
||||||
`
|
`,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FromURL: Story = {
|
export const FromURL: Story = {
|
||||||
name: "Table from URL",
|
name: 'Table from URL',
|
||||||
args: {
|
args: {
|
||||||
url: "https://raw.githubusercontent.com/datasets/finance-vix/main/data/vix-daily.csv"
|
url: 'https://ckan-dev.sse.datopian.com/datastore/dump/601c9cf0-595e-46d8-88fc-d1ab2904e2db',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ function fromMarkdown(opts: FromMarkdownOptions = {}) {
|
|||||||
data: { isEmbed, target, alias },
|
data: { isEmbed, target, alias },
|
||||||
} = wikiLink;
|
} = wikiLink;
|
||||||
// eslint-disable-next-line no-useless-escape
|
// eslint-disable-next-line no-useless-escape
|
||||||
const wikiLinkWithHeadingPattern = /([\w\s\/\.-]*)(#.*)?/;
|
const wikiLinkWithHeadingPattern = /([\p{Letter}\d\s\/\.-_]*)(#.*)?/u;
|
||||||
const [, path, heading = ""] = target.match(wikiLinkWithHeadingPattern);
|
const [, path, heading = ""] = target.match(wikiLinkWithHeadingPattern);
|
||||||
|
|
||||||
const possibleWikiLinkPermalinks = wikiLinkResolver(path);
|
const possibleWikiLinkPermalinks = wikiLinkResolver(path);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ List of available datasets:
|
|||||||
<Catalog datasets={datasets} facets={['group']}/>
|
<Catalog datasets={datasets} facets={['group']}/>
|
||||||
```
|
```
|
||||||
|
|
||||||
You now have a filter in your page with all possible values automatically added to it.
|
Rerun `npm run mddb`. You now have a filter in your page with all possible values automatically added to it.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user