Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(client): key order #318

Merged
merged 3 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions terracotta/client/app/src/common/data/getData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { FeatureDataset } from "../../map/types"

export type KeyItem = {
key: string,
original: string,
description?: string
}

Expand Down Expand Up @@ -38,16 +39,16 @@ export type ResponseMetadata404 = {

export type ResponseMetadata = ResponseMetadata200 | ResponseMetadata404

const getData = async (url: string): Promise< ResponseKeys | ResponseDatasets | ResponseMetadata | undefined> => {
const getData = async (url: string): Promise<ResponseKeys | ResponseDatasets | ResponseMetadata | undefined> => {

try{
try {

const data = await fetch(url);
const json = await data.json();

return json

}catch(err){
} catch (err) {

console.error(err)
return undefined
Expand Down
32 changes: 17 additions & 15 deletions terracotta/client/app/src/sidebar-datasets/DatasetPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { FC } from 'react'
import { Box, TableRow, TableCell, Grid, Collapse, Typography, Link } from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles'
import { ResponseMetadata200 } from "../common/data/getData"
import { KeyItem, ResponseMetadata200 } from "../common/data/getData"
import CopyToClipboard from "../common/components/CopyToClipboard"

const useStyles = makeStyles(() => ({
Expand All @@ -10,9 +10,9 @@ const useStyles = makeStyles(() => ({
width: 'auto'
},
codeContainer: {
backgroundColor: '#F8F8F8',
overflowX: 'auto',
width: 'fit-content',
backgroundColor: '#F8F8F8',
overflowX: 'auto',
width: 'fit-content',
maxWidth: '100%'
},
codeContainerText: {
Expand All @@ -32,6 +32,7 @@ const useStyles = makeStyles(() => ({
}))

interface Props {
keys: KeyItem[],
host: string,
page: number,
limit: number,
Expand All @@ -41,6 +42,7 @@ interface Props {
datasetUrl?: string
}
const DatasetPreview: FC<Props> = ({
keys,
host,
page,
limit,
Expand All @@ -53,7 +55,7 @@ const DatasetPreview: FC<Props> = ({
const classes = useStyles()

const returnJson = (dataset: ResponseMetadata200) => Object.keys(dataset).reduce(
(acc: string[], keyItem: string, j: number) =>
(acc: string[], keyItem: string, j: number) =>
{
const neededKeys = ['mean', 'range', 'stdev', 'valid_percentage'];
if(neededKeys.includes(keyItem)){
Expand All @@ -64,7 +66,7 @@ const DatasetPreview: FC<Props> = ({
const buildStr = ` ${keyItem}: ${dataset[keyItem]},\n`
acc = [...acc, buildStr]
}

}

return acc
Expand Down Expand Up @@ -101,34 +103,34 @@ const DatasetPreview: FC<Props> = ({
<Typography className={classes.codeContainerText}>
<code>
{'Metadata'}

</code>
</Typography>
<code style={{ whiteSpace: 'pre' }}>
{'{\n'}
{returnJson(dataset)}
{'}\n'}
</code>
<Link
target={'_blank'}
href={`${host}/metadata${Object.keys(dataset.keys).map((keyItem: string) => `/${dataset.keys[keyItem]}`).join('')}`}
<Link
target={'_blank'}
href={`${host}/metadata${keys.map((key) => `/${dataset.keys[key.original]}`).join('')}`}
className={classes.metadataLink}
>
{'View full metadata\n'}
</Link>
</Box>

</Grid>
<Grid
item
xs={6}
<Grid
item
xs={6}
container
justify={'center'}
alignItems={'center'}
>
<Box p={1}>
<img
src={`${host}/singleband/${Object.keys(dataset.keys).map((datasetKey: string) => `${dataset.keys[datasetKey]}/`).join('')}preview.png?tile_size=[128,128]`}
src={`${host}/singleband/${keys.map((key) => `${dataset.keys[key.original]}/`).join('')}preview.png?tile_size=[128,128]`}
alt={'TC-preview'}
className={classes.imagePreview}
loading={'eager'}
Expand Down
31 changes: 18 additions & 13 deletions terracotta/client/app/src/sidebar-datasets/SidebarDatasets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const SidebarDatasetsItem: FC<Props> = ({
const [ queryFields, setQueryFields ] = useState<string | undefined>(undefined)
const [ isLoading, setIsLoading ] = useState<boolean>(true)

const getDatasets = async (host: string, pageRef: number, limitRef: number, queryString: string = '') => {
const getDatasets = async (host: string, pageRef: number, limitRef: number, queryString: string = '', fetchedKeys: KeyItem[]) => {

const response = await getData(`${host}/datasets?limit=${limitRef}&page=${pageRef}${queryString}`)
const datasetsResponse = response as ResponseDatasets | undefined
Expand All @@ -102,7 +102,7 @@ const SidebarDatasetsItem: FC<Props> = ({

const metadataResponsesPreFetch: unknown = datasetsResponse.datasets.map(
async (dataset: DatasetItem) => {
const buildMetadataUrl = Object.keys(dataset).map((keyItem: string) => `/${dataset[keyItem]}`).join('')
const buildMetadataUrl = fetchedKeys.map((keyItem) => `/${dataset[keyItem.original]}`).join('')
const preFetchData = await fetch(`${host}/metadata${buildMetadataUrl}`)
return preFetchData.json()
})
Expand All @@ -129,12 +129,12 @@ const SidebarDatasetsItem: FC<Props> = ({

if(keysReponse && keysReponse.hasOwnProperty('keys') && Array.isArray(keysReponse.keys)){

keysReponse.keys = keysReponse.keys.map((item: KeyItem) => ({ ...item, key: item.key[0].toUpperCase() + item.key.substring(1, item.key.length ) }))
keysReponse.keys = keysReponse.keys.map((item: KeyItem) => ({ ...item, key: item.key[0].toUpperCase() + item.key.substring(1, item.key.length ), original: item.key }))
setKeys(keysReponse.keys)

}


return keysReponse
}

const onHandleRow = (index: number) => {
Expand Down Expand Up @@ -174,13 +174,16 @@ const SidebarDatasetsItem: FC<Props> = ({
useEffect(() => {

setIsLoading(true)
void getKeys(host)
void getDatasets(host, page, limit, queryFields)
getKeys(host).then(res => {
if (res) {
void getDatasets(host, page, limit, queryFields, res.keys)
}
})

}, [host, page, limit, queryFields]) // eslint-disable-line react-hooks/exhaustive-deps

const onGetRGBBands = async (dataset: ResponseMetadata200) => {
const noBandKeysURL = `${host}/datasets?` + Object.keys(dataset.keys).map((item: string) => item !== 'band' ? `${item}=${dataset.keys[item]}&` : '' ).join('')
const noBandKeysURL = `${host}/datasets?` + keys?.map((key) => key.original.toLowerCase() !== 'band' ? `${key.original}=${dataset.keys[key.original]}&` : '' ).join('')
const response = await getData(noBandKeysURL) as ResponseDatasets

if(response?.datasets && activeRGB){
Expand Down Expand Up @@ -212,7 +215,7 @@ const SidebarDatasetsItem: FC<Props> = ({

setSelectedDatasetRasterUrl(undefined)
const dataset = datasets[activeDataset - page * limit]
const keysRasterUrl = Object.keys(dataset.keys).map((keyItem: string) => `/${dataset.keys[keyItem]}`).join('') + '/{z}/{x}/{y}.png'
const keysRasterUrl = keys?.map((key) => `/${dataset.keys[key.original]}`).join('') + '/{z}/{x}/{y}.png'

if(activeEndpoint === 'singleband'){

Expand All @@ -239,8 +242,8 @@ const SidebarDatasetsItem: FC<Props> = ({

if(hasValueForBand && hasValueForRange && dataset !== undefined){

const lastKey = Object.keys(dataset.keys)[Object.keys(dataset.keys).length - 1]
const keysRasterUrl = Object.keys(dataset.keys).map((keyItem: string) => keyItem !== lastKey ? `/${dataset.keys[keyItem]}` : '').join('') + '/{z}/{x}/{y}.png'
const lastKey = keys?.[keys.length - 1].original
const keysRasterUrl = keys?.map((key) => key.original !== lastKey ? `/${dataset.keys[key.original]}` : '').join('') + '/{z}/{x}/{y}.png'
const rgbParams = Object.keys(activeRGB).map((keyItem: string) => `${keyItem.toLowerCase()}=${activeRGB[keyItem].band}&${keyItem.toLowerCase()}_range=[${activeRGB[keyItem].range}]&`).join('')
const buildRasterUrl = `${host}/${activeEndpoint}${keysRasterUrl}?${rgbParams}`
setSelectedDatasetRasterUrl(buildRasterUrl)
Expand Down Expand Up @@ -274,8 +277,8 @@ const SidebarDatasetsItem: FC<Props> = ({
<MuiTableRow>
<TableCell className={classes.tableCell} />
{keys && (
keys.map((datasetKey: KeyItem, i: number) => (
<TableCell className={classes.tableCell} key={`dataset-key-head-${i}`}>
keys.map((datasetKey: KeyItem) => (
<TableCell className={classes.tableCell} key={`dataset-key-head-${datasetKey.original}`}>
<Typography color={'primary'} className={classes.tableHeadTypography} variant={'body2'}>
{datasetKey.key}
</Typography>
Expand All @@ -286,16 +289,18 @@ const SidebarDatasetsItem: FC<Props> = ({
</TableHead>
<TableBody>
{
datasets && datasets.map((dataset: ResponseMetadata200, i: number) => (
datasets && keys && datasets.map((dataset: ResponseMetadata200, i: number) => (
<Fragment key={`dataset-${i}`}>
<TableRow
keys={keys}
dataset={dataset.keys}
keyVal={`dataset-${i}`}
checked={page * limit + i === activeDataset}
onClick={() => onHandleRow(i)}
onMouseEnter={() => setHoveredDataset(dataset.convex_hull)}
/>
<DatasetPreview
keys={keys}
activeDataset={activeDataset}
dataset={dataset}
host={host}
Expand Down
30 changes: 16 additions & 14 deletions terracotta/client/app/src/sidebar-datasets/TableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { FC } from 'react'
import { TableRow as MuiTableRow, TableCell, Box, IconButton } from '@material-ui/core'
import { makeStyles } from "@material-ui/core/styles"
import { DatasetItem } from "../common/data/getData"
import { DatasetItem, KeyItem } from "../common/data/getData"
import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';
import CheckCircleIcon from '@material-ui/icons/CheckCircle';

Expand All @@ -26,6 +26,7 @@ const useStyles = makeStyles(() => ({
}))

interface Props {
keys: KeyItem[],
dataset: DatasetItem,
keyVal: string,
checked: boolean,
Expand All @@ -34,42 +35,43 @@ interface Props {
onMouseLeave?: () => void
}

const TableRow: FC<Props> = ({
dataset,
keyVal,
checked,
const TableRow: FC<Props> = ({
keys,
dataset,
keyVal,
checked,
onClick,
onMouseEnter,
onMouseLeave
onMouseLeave
}) => {

const classes = useStyles()

return (
<MuiTableRow
hover
onClick={onClick}
<MuiTableRow
hover
onClick={onClick}
className={classes.tableRow}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<TableCell className={classes.tableCell} >
<Box display={'flex'} alignItems={'center'}>
{
checked ?
checked ?
<IconButton classes={{root: classes.noPadding}}>
<CheckCircleIcon className={`${classes.iconChecked} ${classes.icon}`}/>
</IconButton> :
</IconButton> :
<IconButton classes={{root: classes.noPadding}}>
<RadioButtonUncheckedIcon className={classes.icon}/>
</IconButton>
}
</Box>
</TableCell>
{
Object.keys(dataset).map((item: string, i: number) => (
keys.map((key, i: number) => (
<TableCell className={classes.tableCell} key={`${keyVal}-cell-${i}`}>
{dataset[item]}
{dataset[key.original]}
</TableCell>
))
}
Expand Down
6 changes: 3 additions & 3 deletions terracotta/client/static/react/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"files": {
"main.js": "/static/react/static/js/main.edc7f98e.chunk.js",
"main.js.map": "/static/react/static/js/main.edc7f98e.chunk.js.map",
"main.js": "/static/react/static/js/main.2c168de3.chunk.js",
"main.js.map": "/static/react/static/js/main.2c168de3.chunk.js.map",
"runtime-main.js": "/static/react/static/js/runtime-main.b2f07bb0.js",
"runtime-main.js.map": "/static/react/static/js/runtime-main.b2f07bb0.js.map",
"static/css/2.19072978.chunk.css": "/static/react/static/css/2.19072978.chunk.css",
Expand All @@ -16,6 +16,6 @@
"static/js/runtime-main.b2f07bb0.js",
"static/css/2.19072978.chunk.css",
"static/js/2.83c1f4db.chunk.js",
"static/js/main.edc7f98e.chunk.js"
"static/js/main.2c168de3.chunk.js"
]
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion terracotta/client/templates/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/static/react/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/static/react/logo192.png"/><link rel="manifest" href="/static/react/manifest.json"/><style>body{margin:0;padding:0}::-webkit-scrollbar{width:5px!important;height:5px!important}::-webkit-scrollbar-track{background:#f2f5f7}::-webkit-scrollbar-thumb{background:#cfdbe2}#hostname-id{display:none}</style><title>Terracotta Preview</title><link href="/static/react/static/css/2.19072978.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><p id="hostname-id">{{ hostname }}</p><script>!function(e){function t(t){for(var n,a,p=t[0],l=t[1],i=t[2],c=0,s=[];c<p.length;c++)a=p[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(f&&f(t);s.length;)s.shift()();return u.push.apply(u,i||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,p=1;p<r.length;p++){var l=r[p];0!==o[l]&&(n=!1)}n&&(u.splice(t--,1),e=a(a.s=r[0]))}return e}var n={},o={1:0},u=[];function a(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,a),r.l=!0,r.exports}a.m=e,a.c=n,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)a.d(r,n,function(t){return e[t]}.bind(null,n));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="/static/react/";var p=this.webpackJsonpapp=this.webpackJsonpapp||[],l=p.push.bind(p);p.push=t,p=p.slice();for(var i=0;i<p.length;i++)t(p[i]);var f=l;r()}([])</script><script src="/static/react/static/js/2.83c1f4db.chunk.js"></script><script src="/static/react/static/js/main.edc7f98e.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/static/react/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/static/react/logo192.png"/><link rel="manifest" href="/static/react/manifest.json"/><style>body{margin:0;padding:0}::-webkit-scrollbar{width:5px!important;height:5px!important}::-webkit-scrollbar-track{background:#f2f5f7}::-webkit-scrollbar-thumb{background:#cfdbe2}#hostname-id{display:none}</style><title>Terracotta Preview</title><link href="/static/react/static/css/2.19072978.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><p id="hostname-id">{{ hostname }}</p><script>!function(e){function t(t){for(var n,a,p=t[0],l=t[1],i=t[2],c=0,s=[];c<p.length;c++)a=p[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(f&&f(t);s.length;)s.shift()();return u.push.apply(u,i||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,p=1;p<r.length;p++){var l=r[p];0!==o[l]&&(n=!1)}n&&(u.splice(t--,1),e=a(a.s=r[0]))}return e}var n={},o={1:0},u=[];function a(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,a),r.l=!0,r.exports}a.m=e,a.c=n,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)a.d(r,n,function(t){return e[t]}.bind(null,n));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="/static/react/";var p=this.webpackJsonpapp=this.webpackJsonpapp||[],l=p.push.bind(p);p.push=t,p=p.slice();for(var i=0;i<p.length;i++)t(p[i]);var f=l;r()}([])</script><script src="/static/react/static/js/2.83c1f4db.chunk.js"></script><script src="/static/react/static/js/main.2c168de3.chunk.js"></script></body></html>