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

[TM-1402] Wire up the new tree species BE systems with the updated tree species input. #739

Merged
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
1 change: 0 additions & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: pull-request
on:
pull_request:
branches: [main, staging, release/**]
jobs:
test:
runs-on: ubuntu-latest
Expand Down
20 changes: 14 additions & 6 deletions openapi-codegen.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,34 @@ type EnvironmentName = (typeof ENVIRONMENT_NAMES)[number];
type Environment = {
apiBaseUrl: string;
userServiceUrl: string;
entityServiceUrl: string;
};

const ENVIRONMENTS: { [Property in EnvironmentName]: Environment } = {
local: {
apiBaseUrl: "http://localhost:8080",
userServiceUrl: "http://localhost:4010"
userServiceUrl: "http://localhost:4010",
entityServiceUrl: "http://localhost:4050"
},
dev: {
apiBaseUrl: "https://api-dev.terramatch.org",
userServiceUrl: "https://api-dev.terramatch.org"
userServiceUrl: "https://api-dev.terramatch.org",
entityServiceUrl: "https://api-dev.terramatch.org"
},
test: {
apiBaseUrl: "https://api-test.terramatch.org",
userServiceUrl: "https://api-test.terramatch.org"
userServiceUrl: "https://api-test.terramatch.org",
entityServiceUrl: "https://api-test.terramatch.org"
},
staging: {
apiBaseUrl: "https://api-staging.terramatch.org",
userServiceUrl: "https://api-staging.terramatch.org"
userServiceUrl: "https://api-staging.terramatch.org",
entityServiceUrl: "https://api-staging.terramatch.org"
},
prod: {
apiBaseUrl: "https://api.terramatch.org",
userServiceUrl: "https://api.terramatch.org"
userServiceUrl: "https://api.terramatch.org",
entityServiceUrl: "https://api.terramatch.org"
}
};

Expand All @@ -60,13 +66,15 @@ if (!ENVIRONMENT_NAMES.includes(declaredEnv as EnvironmentName)) {
const DEFAULTS = ENVIRONMENTS[declaredEnv];
const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL ?? DEFAULTS.apiBaseUrl;
const userServiceUrl = process.env.NEXT_PUBLIC_USER_SERVICE_URL ?? DEFAULTS.userServiceUrl;
const entityServiceUrl = process.env.NEXT_PUBLIC_ENTITY_SERVICE_URL ?? DEFAULTS.entityServiceUrl;

// The services defined in the v3 Node BE codebase. Although the URL path for APIs in the v3 space
// are namespaced by feature set rather than service (a service may contain multiple namespaces), we
// isolate the generated API integration by service to make it easier for a developer to find where
// the associated BE code is for a given FE API integration.
const SERVICES = {
"user-service": userServiceUrl
"user-service": userServiceUrl,
"entity-service": entityServiceUrl
};

const config: Record<string, Config> = {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"build-storybook": "storybook build",
"generate:api": "openapi-codegen gen api",
"generate:userService": "openapi-codegen gen userService",
"generate:services": "npm run generate:userService",
"generate:entityService": "openapi-codegen gen entityService",
"generate:services": "yarn generate:userService && yarn generate:entityService",
"tx:push": "eval $(grep '^TRANSIFEX_TOKEN' .env) && eval $(grep '^TRANSIFEX_SECRET' .env) && txjs-cli push --key-generator=hash src/ --token=$TRANSIFEX_TOKEN --secret=$TRANSIFEX_SECRET",
"tx:pull": "eval $(grep '^TRANSIFEX_TOKEN' .env) && eval $(grep '^TRANSIFEX_SECRET' .env) && txjs-cli pull --token=$TRANSIFEX_TOKEN --secret=$TRANSIFEX_SECRET"
},
Expand Down
53 changes: 28 additions & 25 deletions src/admin/components/EntityEdit/EntityEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useNavigate, useParams } from "react-router-dom";
import modules from "@/admin/modules";
import WizardForm from "@/components/extensive/WizardForm";
import LoadingContainer from "@/components/generic/Loading/LoadingContainer";
import EntityProvider from "@/context/entity.provider";
import FrameworkProvider, { Framework } from "@/context/framework.provider";
import {
GetV2FormsENTITYUUIDResponse,
Expand Down Expand Up @@ -73,31 +74,33 @@ export const EntityEdit = () => {
<div className="mx-auto w-full max-w-7xl">
<LoadingContainer loading={isLoading}>
<FrameworkProvider frameworkKey={framework}>
<WizardForm
steps={formSteps!}
errors={error}
onBackFirstStep={() => navigate("..")}
onChange={data =>
updateEntity({
pathParams: { uuid: entityUUID, entity: entityName },
body: { answers: normalizedFormData(data, formSteps!) }
})
}
formStatus={isSuccess ? "saved" : isUpdating ? "saving" : undefined}
onSubmit={() => navigate(createPath({ resource, id, type: "show" }))}
defaultValues={defaultValues}
title={title}
tabOptions={{
markDone: true,
disableFutureTabs: true
}}
summaryOptions={{
title: "Review Details",
downloadButtonText: "Download"
}}
roundedCorners
hideSaveAndCloseButton
/>
<EntityProvider entityUuid={entityUUID} entityName={entityName}>
<WizardForm
steps={formSteps!}
errors={error}
onBackFirstStep={() => navigate("..")}
onChange={data =>
updateEntity({
pathParams: { uuid: entityUUID, entity: entityName },
body: { answers: normalizedFormData(data, formSteps!) }
})
}
formStatus={isSuccess ? "saved" : isUpdating ? "saving" : undefined}
onSubmit={() => navigate(createPath({ resource, id, type: "show" }))}
defaultValues={defaultValues}
title={title}
tabOptions={{
markDone: true,
disableFutureTabs: true
}}
summaryOptions={{
title: "Review Details",
downloadButtonText: "Download"
}}
roundedCorners
hideSaveAndCloseButton
/>
</EntityProvider>
</FrameworkProvider>
</LoadingContainer>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ChangeEvent, forwardRef, Fragment, Ref, useState } from "react";
import { Else, If, Then } from "react-if";

import { useDebounce } from "@/hooks/useDebounce";
import { useValueChanged } from "@/hooks/useValueChanged";

import Text from "../../Text/Text";
import Input, { InputProps } from "../Input/Input";
Expand All @@ -13,17 +14,18 @@ export interface AutoCompleteInputProps extends InputProps {
onSearch: (query: string) => Promise<string[]>;
disableAutoComplete?: boolean;
classNameMenu?: string;
onSelected?: (item: string) => void;
}

const SEARCH_RESET = { list: [], query: "" };

//TODO: Bugfix: Users can enter space in this input
const AutoCompleteInput = forwardRef(
(
{ onSearch, disableAutoComplete, classNameMenu, onSelected, ...inputProps }: AutoCompleteInputProps,
{ onSearch, disableAutoComplete, classNameMenu, ...inputProps }: AutoCompleteInputProps,
ref?: Ref<HTMLInputElement>
) => {
const t = useT();
const [list, setList] = useState<string[]>([]);
const [searchResult, setSearchResult] = useState<{ list: string[]; query: string }>(SEARCH_RESET);
const [loading, setLoading] = useState(false);

const onSelect = (item: string) => {
Expand All @@ -33,37 +35,34 @@ const AutoCompleteInput = forwardRef(
inputProps.onChange?.({ target: { name: inputProps.name, value: item } } as ChangeEvent<HTMLInputElement>);
}

onSelected?.(item);

setList([]);
// Avoid showing the search result list unless the name changes again.
setSearchResult({ list: [], query: item });
};

const search = useDebounce(async (query: string) => {
if (query === searchResult.query) return;

setLoading(true);

onSearch(query)
.then(resp => {
setList(resp);
setLoading(false);
})
.catch(() => {
setList([]);
setLoading(false);
});
try {
setSearchResult({ list: await onSearch(query), query });
setLoading(false);
} catch {
setSearchResult(SEARCH_RESET);
setLoading(false);
}
});

useValueChanged(inputProps.value, () => search(String(inputProps.value ?? "")));

return (
<Popover as="div" className="w-full">
<Popover.Button as={Fragment}>
<Input
{...inputProps}
ref={ref}
onChangeCapture={e => !disableAutoComplete && search(e.currentTarget.value)}
/>
<Input {...inputProps} ref={ref} />
</Popover.Button>

<Transition
show={list.length > 0 || !!loading}
show={searchResult.list.length > 0 || !!loading}
enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100"
Expand All @@ -82,7 +81,7 @@ const AutoCompleteInput = forwardRef(
</Text>
</Then>
<Else>
{list.map(item => (
{searchResult.list.map(item => (
<Text
key={item}
variant="text-body-600"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ exports[`Storyshots Components/Elements/Inputs/AutoComplete Default 1`] = `
className="w-full outline-none transition-all duration-300 ease-in-out focus:ring-transparent px-3 py-[9px] rounded-lg focus:border-primary-500 border border-neutral-200"
data-headlessui-state=""
id=":r9:"
onChangeCapture={[Function]}
onClick={[Function]}
onKeyUp={[Function]}
onMouseDown={[Function]}
Expand Down
Loading
Loading