Skip to content
Draft
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
95 changes: 95 additions & 0 deletions app/components/domain/ConflationOptionSelectInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
isDefined,
listToMap,
} from '@togglecorp/fujs';

import InlineLayout from '#components/InlineLayout';
import SelectInput from '#components/SelectInput';
import { SearchSelectInputProps } from '#components/SelectInput/SearchSelectInput';
import {
conflationTileOptions,
labelSelector,
OPACITY_TILE_SELECTED,
TileSelectOption,
valueSelector,
} from '#utils/common';

interface ColorPreviewProps {
value: string | undefined | null;
}

function ColorPreview(props: ColorPreviewProps) {
const {
value,
} = props;

return (
<div
style={{
backgroundColor: value ?? undefined,
height: '1rem',
width: '1rem',
opacity: OPACITY_TILE_SELECTED,
}}
/>
);
}

function iconOptionLabelSelector(option: TileSelectOption) {
return (
<InlineLayout
start={<ColorPreview value={option.color} />}
>
{option.label}
</InlineLayout>
);
}

type Def = { containerClassName?: string };

type Props<NAME> = SearchSelectInputProps<
number,
NAME,
TileSelectOption,
Def,
'onSearchValueChange'
| 'searchOptions'
| 'onShowDropdownChange'
| 'totalOptionsCount'
| 'value'
| 'options'
| 'keySelector'
| 'labelSelector'
| 'optionLabelSelector'
| 'icons'
> & { value: number | undefined | null};

function TileOptionSelectInput<const NAME>(props: Props<NAME>) {
const {
value,
...otherProps
} = props;

const optionToColorMapping = listToMap(
conflationTileOptions,
(option) => option.value,
(option) => option.color,
);

return (
<SelectInput
// eslint-disable-next-line react/jsx-props-no-spreading
{...otherProps}
value={value}
options={conflationTileOptions}
keySelector={valueSelector}
labelSelector={labelSelector}
optionLabelSelector={iconOptionLabelSelector}
icons={isDefined(value) && (
<ColorPreview value={optionToColorMapping[value]} />
)}
/>
);
}

export default TileOptionSelectInput;
29 changes: 29 additions & 0 deletions app/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export const COLOR_TILE_OPTION_YES = 'green';
export const COLOR_TILE_OPTION_MAYBE = 'orange';
export const COLOR_TILE_OPTION_BAD_IMAGERY = 'red';

export const COLOR_CONFLATION_OPTION_NO = 'red';
export const COLOR_CONFLATION_OPTION_YES = 'green';
export const COLOR_CONFLATION_OPTION_NOT_SURE = 'grey';
export const COLOR_CONFLATION_OPTION_SKIP = 'orange';

export const VALUE_TILE_OPTION_NO = 0;
export const VALUE_TILE_OPTION_YES = 1;
export const VALUE_TILE_OPTION_MAYBE = 2;
Expand Down Expand Up @@ -56,6 +61,29 @@ export const defaultTileOptions: TileSelectOption[] = [
},
];

export const conflationTileOptions: TileSelectOption[] = [
{
value: VALUE_TILE_OPTION_NO,
label: 'No | OSM',
color: COLOR_CONFLATION_OPTION_NO,
},
{
value: VALUE_TILE_OPTION_YES,
label: 'Yes | fAIr',
color: COLOR_CONFLATION_OPTION_YES,
},
{
value: VALUE_TILE_OPTION_MAYBE,
label: 'Not sure | Neither',
color: COLOR_CONFLATION_OPTION_NOT_SURE,
},
{
value: VALUE_TILE_OPTION_BAD_IMAGERY,
label: 'Skip',
color: COLOR_CONFLATION_OPTION_SKIP,
},
];

export const defaultMarkdownPreviewOptions: MarkdownViewProps['options'] = {
simpleLineBreaks: true,
headerLevelStart: 3,
Expand Down Expand Up @@ -156,6 +184,7 @@ export const projectTypeToKeyMap: Record<ProjectTypeEnum, keyof(ProjectTypeSpeci
[ProjectTypeEnum.Validate]: 'validate',
[ProjectTypeEnum.ValidateImage]: 'validateImage',
[ProjectTypeEnum.Street]: 'street',
[ProjectTypeEnum.Conflation]: 'conflation',
};

interface NumericValueOption {
Expand Down
11 changes: 10 additions & 1 deletion app/utils/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fragment VectorTileServerPropertyFields on ProjectVectorTileServerConfig {
export const PROJECT_TYPE_SPECIFIC_FRAGMENT = gql`
${TILE_SERVER_PROPERTY_FRAGMENT}
${VECTOR_TILE_SERVER_PROPERTY_FRAGMENT}
fragment ProjectTypeSpecificFields on CompareProjectPropertyTypeFindProjectPropertyTypeValidateProjectPropertyTypeValidateImageProjectPropertyTypeCompletenessProjectPropertyTypeStreetProjectPropertyType {
fragment ProjectTypeSpecificFields on CompareProjectPropertyTypeFindProjectPropertyTypeValidateProjectPropertyTypeValidateImageProjectPropertyTypeCompletenessProjectPropertyTypeStreetProjectPropertyTypeConflationProjectPropertyType {
... on CompareProjectPropertyType {
__typename
aoiGeometry
Expand Down Expand Up @@ -146,6 +146,15 @@ fragment ProjectTypeSpecificFields on CompareProjectPropertyTypeFindProjectPrope
startTime
}
}
... on ConflationProjectPropertyType {
__typename
objectSource {
objectGeojsonUrl
}
tileServerProperty {
...RasterTileServerPropertyFields
}
}
}
`;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
EntriesAsList,
getErrorObject,
LeafError,
ObjectError,
} from '@togglecorp/toggle-form';

import Container from '#components/Container';
import TextInput from '#components/TextInput';

import { PartialConflationObjectSourceInputFields } from './schema';

interface Props {
value: PartialConflationObjectSourceInputFields | undefined,
error: LeafError | ObjectError<PartialConflationObjectSourceInputFields>,
setFieldValue: (...entries: EntriesAsList<PartialConflationObjectSourceInputFields>) => void;
}

function ObjectSourceInput(props: Props) {
const {
value,
error: formError,
setFieldValue,
} = props;

const error = getErrorObject(formError);

return (
<Container
heading="Conflation Object Source"
headingLevel={4}
>
<TextInput
label="URL for geojson"
name="objectGeojsonUrl"
value={value?.objectGeojsonUrl}
error={error?.objectGeojsonUrl}
onChange={setFieldValue}
hint="Provide a direct link to a GeoJSON file containing your building footprint geometries."
/>
</Container>
);
}

export default ObjectSourceInput;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
ObjectSchema,
PartialForm,
} from '@togglecorp/toggle-form';

import {
ConflationObjectSourceConfig,
ConflationObjectSourceConfigInput,
} from '#generated/types/graphql';
import { DeepNonNullable } from '#utils/types';

export type ConflationSourceConfigKeys = Exclude<keyof ConflationObjectSourceConfig, 'sourceType'>;

export type PartialConflationObjectSourceInputFields = PartialForm<
DeepNonNullable<ConflationObjectSourceConfigInput>
>;
type ConflationSourceFormSchema = ObjectSchema<PartialConflationObjectSourceInputFields>;
type ConflationSourceInputFields = ReturnType<ConflationSourceFormSchema['fields']>;

export const defaultObjectSourceInputFormValue: PartialConflationObjectSourceInputFields = {
objectGeojsonUrl: '',
};

const objectSourceFormSchema: ConflationSourceFormSchema = {
fields: (): ConflationSourceInputFields => {
const schema: ConflationSourceInputFields = {
objectGeojsonUrl: { required: true },
};

return schema;
},
};

export default objectSourceFormSchema;
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
EntriesAsList,
getErrorObject,
LeafError,
ObjectError,
useFormObject,
} from '@togglecorp/toggle-form';

import RasterTileServerInput from '#components/domain/RasterTileServerInput';
import {
defaultRasterTileServerInputValue,
type PartialRasterTileServerInputFields,
} from '#components/domain/RasterTileServerInput/schema';

import {
defaultObjectSourceInputFormValue,
PartialConflationObjectSourceInputFields,
} from './ObjectSourceInput/schema';
import ObjectSourceInput from './ObjectSourceInput';
import { type PartialConflationSpecificFields } from './schema';

interface Props {
value: PartialConflationSpecificFields | undefined | null;
error: LeafError | ObjectError<PartialConflationSpecificFields>;
setFieldValue: (...entries: EntriesAsList<PartialConflationSpecificFields>) => void;
disabled?: boolean;
}

function ConflationProjectSpecifics(props: Props) {
const {
value,
error: formError,
setFieldValue,
disabled,
} = props;

const error = getErrorObject(formError);

const setTileServerInputFieldValue = useFormObject<'tileServerProperty', PartialRasterTileServerInputFields>(
'tileServerProperty' as const,
setFieldValue,
defaultRasterTileServerInputValue,
);

const setObjectSourceInputFieldValue = useFormObject<'objectSource', PartialConflationObjectSourceInputFields>(
'objectSource' as const,
setFieldValue,
defaultObjectSourceInputFormValue,
);

return (
<>
<ObjectSourceInput
value={value?.objectSource}
setFieldValue={setObjectSourceInputFieldValue}
error={error?.objectSource}
/>
<RasterTileServerInput
value={value?.tileServerProperty}
error={error?.tileServerProperty}
setFieldValue={setTileServerInputFieldValue}
disabled={disabled}
zoomLevel={undefined}
/>
</>
);
}

export default ConflationProjectSpecifics;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
ObjectSchema,
PartialForm,
} from '@togglecorp/toggle-form';

import rasterTileServerFormSchema, { defaultRasterTileServerInputValue } from '#components/domain/RasterTileServerInput/schema';
import { ConflationProjectPropertyInput } from '#generated/types/graphql';
import { DeepNonNullable } from '#utils/types';

import {
type PartialProjectUpdateInput,
type UpdateProjectContext,
} from '../schema';
import objectSourceFormSchema, { defaultObjectSourceInputFormValue } from './ObjectSourceInput/schema';

export type PartialConflationSpecificFields = PartialForm<
DeepNonNullable<ConflationProjectPropertyInput>,
'clientId'
>;
type ConflationSpecificFormSchema = ObjectSchema<
PartialConflationSpecificFields,
PartialProjectUpdateInput,
UpdateProjectContext
>;

export const defaultConflationSpecificFormValue: PartialConflationSpecificFields = {
objectSource: defaultObjectSourceInputFormValue,
tileServerProperty: defaultRasterTileServerInputValue,
};

const conflationSpecificFormSchema: ConflationSpecificFormSchema = {
fields: (): ReturnType<ConflationSpecificFormSchema['fields']> => ({
objectSource: objectSourceFormSchema,
tileServerProperty: rasterTileServerFormSchema,
}),
};

export default conflationSpecificFormSchema;
Loading
Loading