Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
andresgnlez committed Dec 11, 2023
1 parent 2f17338 commit 0de3769
Show file tree
Hide file tree
Showing 17 changed files with 1,511 additions and 76 deletions.
1 change: 0 additions & 1 deletion app/components/features/selected-item/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ export const Item: React.FC<ItemProps> = ({
) : (
<HiEyeOff className="h-4 w-4" />
)}
{/* <Icon className="h-4 w-4" icon={isShown ? SHOW_SVG : HIDE_SVG} /> */}
</button>
</Tooltip>

Expand Down
75 changes: 48 additions & 27 deletions app/hooks/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export function useSelectedFeatures(
queryOptions = {}
) {
const { data: session } = useSession();
const { search } = filters;
const { search, sort, tag } = filters;

const queryClient = useQueryClient();

Expand Down Expand Up @@ -271,6 +271,7 @@ export function useSelectedFeatures(
id: featureId,
name: alias || featureClassName,
type: tag,
// type: Math.random() < 0.5 ? 'test' : 'andres',
description,
amountRange: {
min: amountMin,
Expand All @@ -291,12 +292,12 @@ export function useSelectedFeatures(
};
});

// Filter
if (search) {
const fuse = new Fuse(parsedData, {
keys: ['name'],
threshold: 0.25,
});

parsedData = fuse.search(search).map((f) => {
return f.item;
});
Expand All @@ -314,7 +315,7 @@ export function useTargetedFeatures(
queryOptions = {}
) {
const { data: session } = useSession();
const { search } = filters;
const { search, sort } = filters;

const fetchFeatures = () =>
SCENARIOS.request({
Expand All @@ -325,10 +326,16 @@ export function useTargetedFeatures(
},
params: {
disablePagination: true,
...(search && {
q: search,
}),
...(sort && {
sort,
}),
},
}).then(({ data }) => data);

return useQuery(['targeted-features', sid], fetchFeatures, {
return useQuery(['targeted-features', sid, filters], fetchFeatures, {
...queryOptions,
retry: false,
enabled: !!sid,
Expand Down Expand Up @@ -405,6 +412,11 @@ export function useTargetedFeatures(
name: alias || featureClassName,
type: tag,
description,
// todo: missing scenarioUsageCount from API
scenarios: d.scenarioUsageCount,
// todo: missing tag from API
tag: d.tag,
isCustom: d.metadata?.isCustom,

// SPLIT
splitOptions,
Expand All @@ -429,7 +441,16 @@ export function useTargetedFeatures(
}

// Sort
parsedData = orderBy(parsedData, ['name'], ['desc']);
if (sort) {
parsedData.sort((a, b) => {
if (sort.startsWith('-')) {
const _sort = sort.substring(1);
return b[_sort].localeCompare(a[_sort]);
}

return a[sort].localeCompare(b[sort]);
});
}

parsedData = flatten(
parsedData.map((s) => {
Expand All @@ -439,25 +460,27 @@ export function useTargetedFeatures(

// Generate splitted features to target
if (isSplitted) {
return splitFeaturesSelected
.sort((a, b) => a.name.localeCompare(b.name))
.map((sf) => {
const { id: sfId, name: sfName, marxanSettings: sfMarxanSettings } = sf;

return {
...sf,
id: `${id}-${sfId}`,
parentId: id,
name: `${name} / ${sfName}`,
splitted: true,
splitSelected,
splitFeaturesSelected,
...(!!sfMarxanSettings && {
target: sfMarxanSettings.prop * 100,
fpf: sfMarxanSettings.fpf,
}),
};
});
return (
splitFeaturesSelected
// .sort((a, b) => a.name.localeCompare(b.name))
.map((sf) => {
const { id: sfId, name: sfName, marxanSettings: sfMarxanSettings } = sf;

return {
...sf,
id: `${id}-${sfId}`,
parentId: id,
name: `${name} / ${sfName}`,
splitted: true,
splitSelected,
splitFeaturesSelected,
...(!!sfMarxanSettings && {
target: sfMarxanSettings.prop * 100,
fpf: sfMarxanSettings.fpf,
}),
};
})
);
}

// if (isIntersected) {
Expand Down Expand Up @@ -518,11 +541,9 @@ export function useSaveSelectedFeatures({
};

return useMutation(saveFeature, {
onSuccess: (data, variables, context) => {
onSuccess: (data, variables) => {
const { id } = variables;
queryClient.setQueryData(['selected-features', id], { data: data?.data });

console.info('Succces', data, variables, context);
},
onError: (error, variables, context) => {
// An error happened!
Expand Down
2 changes: 2 additions & 0 deletions app/hooks/features/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { AxiosRequestConfig } from 'axios';

export interface UseFeaturesFiltersProps {
search?: string;
sort?: string;
tag?: string;
}

export interface UseSaveSelectedFeaturesProps {
Expand Down
2 changes: 1 addition & 1 deletion app/layout/project/sidebar/project/header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const InventoryProjectHeader = (): JSX.Element => {
);

return (
<div className="mb-6 flex items-start justify-between">
<div className="flex items-start justify-between">
<UnderModeration />
<Title title={name} description={description} onEditTitle={onEditProjectName} />
<div className="mt-4 flex items-center space-x-5">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ export const ScenariosFeaturesAdd = (): JSX.Element => {
},
},
{
onSuccess: () => {
onSuccess: async () => {
setOpen(false);
queryClient.invalidateQueries(['selected-features', sid]);
await queryClient.invalidateQueries(['selected-features', sid]);
await queryClient.invalidateQueries(['targeted-features', sid]);
},
onSettled: () => {
setSubmitting(false);
Expand Down
46 changes: 2 additions & 44 deletions app/layout/project/sidebar/scenario/grid-setup/features/index.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,7 @@
import { useRouter } from 'next/router';

import { TABS } from 'layout/project/navigation/constants';
import StepManager from 'layout/step-manager';

import GridSetupFeaturesAdd from './add';
import GridSetupFeaturesTargets from './targets';
import GridSetupFeaturesTargets from './target-spf';

export const GridSetupFeatures = (): JSX.Element => {
const { replace, query } = useRouter();
const { pid, sid, tab } = query as { pid: string; sid: string; tab: string };

return (
<StepManager defaultStep={tab === TABS['scenario-features-targets-spf'] ? 1 : 0}>
{({ currentStep, onChangeStep }) => (
<>
{currentStep === 0 && (
<GridSetupFeaturesAdd
onContinue={() => {
onChangeStep(1);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
replace(
`/projects/${pid}/scenarios/${sid}/edit?tab=${TABS['scenario-features-targets-spf']}`,
null,
{ shallow: true }
);
}}
/>
)}
{currentStep === 1 && (
<GridSetupFeaturesTargets
onGoBack={() => {
onChangeStep(0);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
replace(
`/projects/${pid}/scenarios/${sid}/edit?tab=${TABS['scenario-features']}`,
null,
{ shallow: true }
);
}}
/>
)}
</>
)}
</StepManager>
);
return <GridSetupFeaturesTargets />;
};

export default GridSetupFeatures;
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { useState } from 'react';

import Input from 'components/forms/input';

const DEFAULT_INPUT_VALUES = {
target: 50,
spf: 1,
};

const INPUT_CLASSES =
'w-[55px] rounded-md border-solid border-gray-600 bg-gray-900 bg-opacity-100 px-0 py-1 text-center leading-tight';

const AllTargetsSelector = ({
onChangeAllTargets,
onChangeAllSPF,
}: {
onChangeAllTargets: (target: number) => void;
onChangeAllSPF: (spf: number) => void;
}): JSX.Element => {
const [values, setValues] = useState(DEFAULT_INPUT_VALUES);

return (
<div className="flex justify-between rounded-lg bg-gray-700 px-[10px] py-[5px] text-sm">
<span className="flex max-w-[115px] text-xs text-white">
Set target and SPF in all features:
</span>
<div className="flex space-x-2">
<div className="flex items-center space-x-2">
<span>Target</span>
<Input
className={INPUT_CLASSES}
theme="dark"
mode="dashed"
type="number"
min={0}
max={100}
defaultValue={values.target}
value={values.target}
// disabled={!editable}
onChange={({ target: { value: inputValue } }) => {
setValues((prevValues) => ({
...prevValues,
target: Number(inputValue),
}));
}}
onKeyDownCapture={(event) => {
if (event.key === 'Enter') {
onChangeAllTargets(Number(values.target));
}
}}
onBlur={() => {
// If user leaves the input empty, we'll revert to the original targetValue
console.log(values);
if (!values.target) {
return setValues((prevValues) => ({
...prevValues,
target: DEFAULT_INPUT_VALUES.target,
}));
}

setValues((prevValues) => ({
...prevValues,
target: values.target,
}));

onChangeAllTargets(Number(values.target));
}}
/>
<span className="text-xs">%</span>
</div>
<div className="flex items-center space-x-2">
<span>SPF</span>
<Input
className={INPUT_CLASSES}
theme="dark"
mode="dashed"
type="number"
defaultValue={values.spf}
// value={inputFPFValue}
// disabled={!editable}
onChange={({ target: { value: inputValue } }) => {
setValues((prevValues) => ({
...prevValues,
spf: Number(inputValue),
}));
}}
onKeyDownCapture={(event) => {
if (event.key === 'Enter') {
onChangeAllSPF(Number(values.spf));
}
}}
onBlur={() => {
if (!values.spf) {
return setValues((prevValues) => ({
...prevValues,
target: DEFAULT_INPUT_VALUES.spf,
}));
}

setValues((prevValues) => ({
...prevValues,
spf: values.spf,
}));

onChangeAllSPF(Number(values.spf));
}}
/>
</div>
</div>
</div>
);
};

export default AllTargetsSelector;
Loading

0 comments on commit 0de3769

Please sign in to comment.