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

Enable mosaic creation #70

Merged
merged 24 commits into from
Jan 24, 2024
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
3 changes: 2 additions & 1 deletion app/assets/scripts/components/common/card-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ Card.propTypes = {

const CardListContainer = styled.ol`
display: grid;
height: min-content;
grid-template-columns: ${({ numColumns }) => {
if (numColumns) {
return css`repeat(${numColumns}, 1fr)`;
Expand All @@ -185,7 +186,7 @@ const CardListScroll = styled(ShadowScrollbar)`
flex: 1;
`;
const CardListWrapper = styled(PanelBlockBody)`
height: 100%;
height: min-content;
${({ nonScrolling }) =>
nonScrolling &&
css`
Expand Down
2 changes: 2 additions & 0 deletions app/assets/scripts/components/common/map/constants.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const BOUNDS_PADDING = [25, 25];

export const MOSAIC_LAYER_OPACITY = 0.8;
12 changes: 7 additions & 5 deletions app/assets/scripts/components/common/tabbed-block-body.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ const TabbedBlockHeader = styled(PanelBlockHeader)`
${listReset}
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
padding: 0 ${glsp(1.5)};
justify-content: ${({ leftAligned }) =>
leftAligned ? 'flex-start' : 'space-between'};
gap: ${glsp()};
padding: ${({ leftAligned }) => (leftAligned ? '0' : '0 1.5rem')};
box-shadow: inset 0 -1px 0 0 ${themeVal('color.baseAlphaB')};
}
/* PanelBlockHeader sets z-index. This causes
Expand All @@ -108,11 +110,11 @@ const PanelBlockScroll = styled(ScrollableBody)`
`;

function TabbedBlock(props) {
const { children, activeTab } = props;
const { children, activeTab, leftAligned } = props;

return (
<>
<TabbedBlockHeader as='nav' role='navigation'>
<TabbedBlockHeader as='nav' role='navigation' leftAligned={leftAligned}>
<ul>
{Children.map(children, (child, ind) => {
const { name, icon, tabId, disabled, tabTooltip } = child.props;
Expand Down Expand Up @@ -153,7 +155,6 @@ function TabbedBlock(props) {
<>
{React.cloneElement(child, {
active: active,
//style: active ? {} : { display: 'none' },
className: active ? className : `${className} inactive-panel`,
})}
</>
Expand All @@ -167,5 +168,6 @@ function TabbedBlock(props) {
TabbedBlock.propTypes = {
children: T.node.isRequired,
activeTab: T.number.isRequired,
leftAligned: T.bool,
};
export default TabbedBlock;
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function MosaicSelectorModal({
<ModalHeader>
<Headline>
{' '}
<Heading>Select an base mosaic</Heading>
<Heading>Select a base mosaic</Heading>
<Button
hideText
variation='base-plain'
Expand Down
6 changes: 4 additions & 2 deletions app/assets/scripts/components/project/map/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ import { RETRAIN_MAP_MODES } from '../../../fsm/project/constants';
import FreehandDrawControl from './freehand-draw-control';
import PolygonDrawControl from './polygon-draw-control';
import selectors from '../../../fsm/project/selectors';
import { BOUNDS_PADDING } from '../../common/map/constants';
import {
BOUNDS_PADDING,
MOSAIC_LAYER_OPACITY,
} from '../../common/map/constants';

const center = [19.22819, -99.995841];
const zoom = 12;

const DEFAULT_PREDICTION_LAYER_OPACITY = 0.7;
const MOSAIC_LAYER_OPACITY = 0.8;

const Container = styled.div`
height: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function ImagerySourceSelectorModal({ showModal, setShowModal }) {
<ModalContent>
<HeadingWrapper>
<Heading size='small' as='h4'>
Available mosaics for the AOI
Imagery sources available for the selected AOI
</Heading>
</HeadingWrapper>
<CardList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function MosaicSelector() {
/>
<HeadOption>
<HeadOptionHeadline usePadding>
<Subheading>Base Mosaic</Subheading>
<Subheading>Imagery Mosaic Date Range</Subheading>
</HeadOptionHeadline>
<SubheadingStrong
data-cy='mosaic-selector-label'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import React from 'react';
import React, { useMemo } from 'react';
import T from 'prop-types';
import styled from 'styled-components';
import { Modal } from '@devseed-ui/modal';
import { glsp } from '@devseed-ui/theme-provider';
import { Button } from '@devseed-ui/button';
import { Heading } from '@devseed-ui/typography';
import CardList, { Card } from '../../../../../common/card-list';
import { ExistingMosaicsSection } from './sections/list-mosaics';
import { CreateMosaicSection } from './sections/create-mosaic';
import TabbedBlock from '../../../../../common/tabbed-block-body';
import { ProjectMachineContext } from '../../../../../../fsm/project';
import selectors from '../../../../../../fsm/project/selectors';
import { formatDateTime } from '../../../../../../utils/format';

const ModalHeader = styled.header`
padding: ${glsp(2)} ${glsp(2)} 0;
`;

const ModalContent = styled.div`
display: block;
display: flex;
flex-flow: column;
height: 60vh;
`;

const Headline = styled.div`
Expand All @@ -34,26 +36,19 @@ const Headline = styled.div`
}
`;

const HeadingWrapper = styled.div`
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: baseline;
`;
export function MosaicSelectorModal({ showModal, setShowModal }) {
const [activeTab, setActiveTab] = React.useState(0);

export function MosaicSelectorModal({ showModal, setShowModal, isProjectNew }) {
const actorRef = ProjectMachineContext.useActorRef();
const mosaicsList = ProjectMachineContext.useSelector(selectors.mosaicsList);
const currentMosaic = ProjectMachineContext.useSelector(
selectors.currentMosaic
);
const currentImagerySource = ProjectMachineContext.useSelector(
selectors.currentImagerySource
const mapRef = ProjectMachineContext.useSelector(
({ context }) => context.mapRef
);

const selectableMosaics = mosaicsList.filter(
(mosaic) => mosaic.imagery_source_id === currentImagerySource?.id
);
// Get the current map zoom and center on modal open
const [mapZoom, mapCenter] = useMemo(() => {
if (!showModal || !mapRef) return [null, null];
const { lng, lat } = mapRef.getCenter();
return [mapRef.getZoom(), [lat, lng]];
}, [mapRef, showModal]);

return (
<Modal
Expand All @@ -66,8 +61,7 @@ export function MosaicSelectorModal({ showModal, setShowModal, isProjectNew }) {
renderHeader={() => (
<ModalHeader>
<Headline>
{' '}
<Heading>Select an base mosaic</Heading>
<Heading>Set Mosaic Date Range</Heading>
<Button
hideText
variation='base-plain'
Expand All @@ -84,62 +78,34 @@ export function MosaicSelectorModal({ showModal, setShowModal, isProjectNew }) {
)}
content={
<ModalContent>
<HeadingWrapper>
<Heading size='small' as='h4'>
Available mosaics for the AOI
</Heading>
</HeadingWrapper>
<CardList
nonScrolling
numColumns={2}
data={selectableMosaics}
renderCard={(mosaic) => {
const { name, mosaic_ts_end, mosaic_ts_start } = mosaic;

return (
<Card
data-cy={`select-mosaic-${mosaic.id}-card`}
key={mosaic.id}
title={mosaic.name}
details={{
name,
'Mosaic Start Date': mosaic_ts_start
? formatDateTime(mosaic_ts_start)
: 'N/A',
'Mosaic End Date': mosaic_ts_end
? formatDateTime(mosaic_ts_end)
: 'N/A',
}}
borderlessMedia
selected={currentMosaic && currentMosaic.id === mosaic.id}
onClick={() => {
if (isProjectNew) {
if (!currentMosaic || currentMosaic.id !== mosaic.id) {
actorRef.send({
type: 'Mosaic was selected',
data: { mosaic },
});
}
} else if (currentMosaic?.id !== mosaic.id) {
actorRef.send({
type: 'Mosaic was selected',
data: { mosaic },
});
}
setShowModal(false);
}}
/>
);
}}
/>
<TabbedBlock activeTab={activeTab} leftAligned={true}>
<ExistingMosaicsSection
name='Select Preset'
className='select-preset-mosaic'
tabId='select-preset-mosaic-tab-trigger'
onTabClick={() => setActiveTab(0)}
setShowModal={setShowModal}
/>
<CreateMosaicSection
name='Create Mosaic'
className='create-mosaic'
tabId='create-mosaic-tab-trigger'
initialMapZoom={mapZoom}
initialMapCenter={mapCenter}
onTabClick={() => setActiveTab(1)}
onMosaicCreated={() => {
setActiveTab(0);
setShowModal(false);
}}
/>
</TabbedBlock>
</ModalContent>
}
/>
);
}

MosaicSelectorModal.propTypes = {
isProjectNew: T.bool,
showModal: T.bool,
setShowModal: T.func.isRequired,
};
Loading
Loading