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

project: Update Local Unit edit, validation, and delete workflow #1593

Merged
merged 2 commits into from
Jan 13, 2025
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
5 changes: 5 additions & 0 deletions .changeset/pink-ties-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"go-web-app": minor
---

Add local unit validation workflow
52 changes: 52 additions & 0 deletions app/src/components/DiffWrapper/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useMemo } from 'react';
import { isNotDefined } from '@togglecorp/fujs';

interface Props<T> {
diffContainerClassName?: string;
value?: T;
oldValue?: T;
children: React.ReactNode;
enabled: boolean;
showOnlyDiff?: boolean;
}

function DiffWrapper<T>(props: Props<T>) {
const {
diffContainerClassName,
oldValue,
value,
children,
enabled = false,
showOnlyDiff,
} = props;

const hasChanged = useMemo(() => {
// NOTE: we consider `null` and `undefined` as same for
// this scenario
if (isNotDefined(oldValue) && isNotDefined(value)) {
return false;
}

return JSON.stringify(oldValue) !== JSON.stringify(value);
}, [oldValue, value]);

if (!enabled) {
return children;
}

if (!hasChanged && showOnlyDiff) {
return null;
}

if (!hasChanged) {
return children;
}

return (
<div className={diffContainerClassName}>
{children}
</div>
);
}

export default DiffWrapper;
47 changes: 47 additions & 0 deletions app/src/components/MultiSelectOutput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useMemo } from 'react';
import { TextOutput } from '@ifrc-go/ui';
import { listToMap } from '@togglecorp/fujs';

interface Props<VALUE, OPTION> {
value: VALUE[] | undefined;
options: OPTION[] | undefined;
keySelector: (datum: OPTION) => VALUE;
labelSelector: (datum: OPTION) => React.ReactNode;
label: React.ReactNode;
}

function MultiSelectOutput<VALUE extends string | number, OPTION>(props: Props<VALUE, OPTION>) {
const {
value,
options,
keySelector,
labelSelector,
label,
} = props;

const valueMap = useMemo(
() => listToMap(value ?? [], (val) => val, () => true),
[value],
);

const selectedOptions = useMemo(() => options?.filter(
(option) => valueMap[keySelector(option)],
), [keySelector, options, valueMap]);

const valueLabel = useMemo(
() => selectedOptions?.map(
(selectedOption) => labelSelector(selectedOption),
).join(', ') ?? '--',
[labelSelector, selectedOptions],
);

return (
<TextOutput
label={label}
value={valueLabel}
strongLabel
/>
);
}

export default MultiSelectOutput;
41 changes: 41 additions & 0 deletions app/src/components/SelectOutput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useMemo } from 'react';
import { TextOutput } from '@ifrc-go/ui';
import { isDefined } from '@togglecorp/fujs';

interface Props<VALUE, OPTION> {
value: VALUE | undefined;
options: OPTION[] | undefined;
keySelector: (datum: OPTION) => VALUE;
labelSelector: (datum: OPTION) => React.ReactNode;
label: React.ReactNode;
}

function SelectOutput<VALUE, OPTION>(props: Props<VALUE, OPTION>) {
const {
value,
options,
keySelector,
labelSelector,
label,
} = props;

const selectedOption = useMemo(() => options?.find(
(option) => keySelector(option) === value,
), [options, keySelector, value]);

const valueLabel = useMemo(() => (
isDefined(selectedOption)
? labelSelector(selectedOption)
: '--'
), [labelSelector, selectedOption]);

return (
<TextOutput
label={label}
value={valueLabel}
strongLabel
/>
);
}

export default SelectOutput;
7 changes: 7 additions & 0 deletions app/src/components/domain/BaseMapPointInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ interface Props<NAME> extends BaseMapProps {
readOnly?: boolean;
required?: boolean;
error?: ObjectError<Value>;
showChanges: boolean;
latitudeInputSectionClassName?: string;
longitudeInputSectionClassName?: string;
}

function BaseMapPointInput<NAME extends string>(props: Props<NAME>) {
Expand All @@ -74,6 +77,8 @@ function BaseMapPointInput<NAME extends string>(props: Props<NAME>) {
country,
required,
error,
latitudeInputSectionClassName,
longitudeInputSectionClassName,
...otherProps
} = props;

Expand Down Expand Up @@ -183,6 +188,7 @@ function BaseMapPointInput<NAME extends string>(props: Props<NAME>) {
<div className={_cs(styles.baseMapPointInput, className)}>
<div className={styles.locationInputs}>
<NumberInput
inputSectionClassName={latitudeInputSectionClassName}
className={styles.input}
name="lat"
label={strings.latitude}
Expand All @@ -193,6 +199,7 @@ function BaseMapPointInput<NAME extends string>(props: Props<NAME>) {
required={required}
/>
<NumberInput
inputSectionClassName={longitudeInputSectionClassName}
className={styles.input}
name="lng"
label={strings.longitude}
Expand Down
6 changes: 6 additions & 0 deletions app/src/components/domain/BaseMapPointInput/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
flex-direction: column;
gap: var(--go-ui-spacing-md);

.diff-container{
.changes {
background-color: var(--go-ui-color-semantic-yellow) !important;
}
}

.location-inputs {
display: flex;
gap: var(--go-ui-spacing-sm);
Expand Down
2 changes: 1 addition & 1 deletion app/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const DREF_TYPE_ASSESSMENT = 1 satisfies TypeOfDrefEnum;
export const DREF_TYPE_RESPONSE = 2 satisfies TypeOfDrefEnum;
export const DREF_TYPE_LOAN = 3 satisfies TypeOfDrefEnum;

type TypeOfOnsetEnum = components<'read'>['schemas']['TypeValidatedEnum'];
type TypeOfOnsetEnum = components<'read'>['schemas']['DrefDrefOnsetTypeEnumKey'];
export const ONSET_SLOW = 1 satisfies TypeOfOnsetEnum;

// Subscriptions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { _cs } from '@togglecorp/fujs';

import styles from './styles.module.css';

interface Props {
className?: string;
children?: React.ReactNode;
}

function FormGrid(props: Props) {
const {
className,
children,
} = props;

return (
<div className={_cs(styles.formGrid, className)}>
{children}
</div>
);
}

export default FormGrid;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* NOTE: this element is portaled */
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--go-ui-spacing-lg);

@media screen and (max-width: 60rem) {
grid-template-columns: 1fr;
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"namespace": "countryNsOverviewContextAndStructure",
"strings": {
"submitLabel": "Submit",
"deleteSuccessMessage": "{localUnitName} has been successfully deleted.",
"deleteFailureMessage": "Unable to delete {localUnitName}. Please try again.",
"chooseDeleteReasonMessage": "Choose the reason to delete local unit.",
"deleteReasonExplanation": "Explain the reason why the local unit is being deleted.",
"deleteLocalUnitHeading": "Are you sure you want to delete \"{localUnitName}\"?"
}
}
Loading
Loading