Skip to content

Commit

Permalink
✨ Add stakeholders and stakeholder group fields to assessment wizard (k…
Browse files Browse the repository at this point in the history
…onveyor#1349)

- Uses new Autocomplete field wrapper in the assessment wizard. 
- Moves the ItemsSelect component to the root level of the app for code
sharing

Signed-off-by: ibolton336 <[email protected]>
  • Loading branch information
ibolton336 authored Sep 12, 2023
1 parent 85d738b commit c44218d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 110 deletions.
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
import React from "react";
import { Control, Path } from "react-hook-form";
import { Control, FieldValues, Path } from "react-hook-form";
import { HookFormPFGroupController } from "@app/components/HookFormPFFields";
import { Autocomplete } from "@app/components/Autocomplete";
import type { ArchetypeFormValues } from "./archetype-form";

// TODO: Currently only supports working with tag names (which only work if item names are globally unique)
// TODO: Does not support select menu grouping by category
// TODO: Does not support select menu selection checkboxes
// TODO: Does not support rendering item labels with item category color
// TODO: Does not support rendering item labels in item category groups
const ItemsSelect = <ItemType extends { name: string }>({

const ItemsSelect = <
ItemType extends { name: string },
FormValues extends FieldValues,
>({
items = [],
control,
name,
label,
fieldId,
name,
control,
noResultsMessage,
placeholderText,
searchInputAriaLabel,
isRequired = false,
}: {
items: ItemType[];
control: Control<ArchetypeFormValues>;
name: Path<ArchetypeFormValues>;
name: Path<FormValues>;
control: Control<FormValues>;
label: string;
fieldId: string;
noResultsMessage: string;
Expand Down Expand Up @@ -50,7 +53,9 @@ const ItemsSelect = <ItemType extends { name: string }>({
searchInputAriaLabel={searchInputAriaLabel}
options={itemsToName()}
selections={normalizeSelections(value)}
onChange={onChange}
onChange={() => {
onChange(value);
}}
/>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as yup from "yup";
import React, { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
Expand All @@ -18,10 +19,7 @@ import { NotificationsContext } from "@app/components/NotificationsContext";
import { WizardStepNavDescription } from "../wizard-step-nav-description";
import { QuestionnaireForm } from "../questionnaire-form";
import { ConfirmDialog } from "@app/components/ConfirmDialog";
import {
QuestionnairesQueryKey,
useFetchQuestionnaires,
} from "@app/queries/questionnaires";
import { useFetchQuestionnaires } from "@app/queries/questionnaires";
import {
COMMENTS_KEY,
QUESTIONS_KEY,
Expand All @@ -30,15 +28,13 @@ import {
} from "../../form-utils";
import { AxiosError } from "axios";
import {
assessmentQueryKey,
assessmentsByAppIdQueryKey,
assessmentsQueryKey,
useUpdateAssessmentMutation,
} from "@app/queries/assessments";
import { useQueryClient } from "@tanstack/react-query";
import { ApplicationAssessmentStatus } from "@app/pages/applications/components/application-assessment-status";
import { formatPath, getAxiosErrorMessage } from "@app/utils/utils";
import { Paths } from "@app/Paths";
import { yupResolver } from "@hookform/resolvers/yup";

export const SAVE_ACTION_KEY = "saveAction";

Expand All @@ -49,8 +45,8 @@ export enum SAVE_ACTION_VALUE {
}

export interface ApplicationAssessmentWizardValues {
stakeholders: number[];
stakeholderGroups: number[];
stakeholders: string[];
stakeholderGroups: string[];
[COMMENTS_KEY]: {
[key: string]: string; // <categoryId, commentValue>
};
Expand Down Expand Up @@ -140,6 +136,12 @@ export const ApplicationAssessmentWizard: React.FC<
});
}, [initialQuestions]);

const validationSchema = yup.object().shape({
stakeholders: yup.array().of(yup.string()),

stakeholderGroups: yup.array().of(yup.string()),
});

const methods = useForm<ApplicationAssessmentWizardValues>({
defaultValues: useMemo(() => {
return {
Expand All @@ -150,6 +152,7 @@ export const ApplicationAssessmentWizard: React.FC<
[SAVE_ACTION_KEY]: SAVE_ACTION_VALUE.SAVE_AS_DRAFT,
};
}, [assessment]),
resolver: yupResolver(validationSchema),
mode: "all",
});
const values = methods.getValues();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,15 @@ import { ApplicationAssessmentWizardValues } from "../application-assessment-wiz
import { HookFormPFGroupController } from "@app/components/HookFormPFFields";
import { OptionWithValue, SimpleSelect } from "@app/components/SimpleSelect";
import { Stakeholder, StakeholderGroup } from "@app/api/models";

const stakeholderGroupToOption = (
value: StakeholderGroup
): OptionWithValue<StakeholderGroup> => ({
value,
toString: () => value.name,
});

const stakeholderToOption = (
value: Stakeholder
): OptionWithValue<Stakeholder> => ({
value,
toString: () => value.name,
props: {
description: value.email,
},
});
import ItemsSelect from "@app/components/items-select/items-select";

export const AssessmentStakeholdersForm: React.FC = () => {
const { t } = useTranslation();
const { setValue, control, formState } =
useFormContext<ApplicationAssessmentWizardValues>();

// const { stakeholders } = useFetchStakeholders();

// const { stakeholderGroups } = useFetchStakeholderGroups();
const { stakeholders } = useFetchStakeholders();
const { stakeholderGroups } = useFetchStakeholderGroups();

return (
<div className="pf-v5-c-form">
Expand All @@ -59,79 +42,30 @@ export const AssessmentStakeholdersForm: React.FC = () => {
<Grid className="pf-v5-c-form__section">
<GridItem md={6} className="pf-v5-c-form">
<FormSection>
<HookFormPFGroupController
<ItemsSelect
items={stakeholders}
control={control}
name="stakeholders"
label={t("terms.stakeholders")}
label="Stakeholder(s)"
fieldId="stakeholders"
renderInput={({ field: { value, name, onChange } }) => (
<SimpleSelect
id="stakeholders-select"
variant="typeaheadmulti"
toggleId="stakeholders-select-toggle"
toggleAriaLabel="Stakeholders dropdown toggle"
aria-label={name}
// value={value
// .map((id) => stakeholders.find((f) => id === f.id))
// .map((e) => (e ? stakeholderToOption(e) : undefined))
// .filter((e) => e !== undefined)}
// options={stakeholders.map(stakeholderToOption)}
value={value}
options={[]}
onChange={(selection) => {
const selectionWithValue =
selection as OptionWithValue<Stakeholder>;
const selectionId: number = selectionWithValue.value.id!;

const currentValue = value || [];
const e = currentValue.find((f) => f === selectionId);
if (e) {
onChange(currentValue.filter((f) => f !== selectionId));
} else {
onChange([...currentValue, selectionId]);
}
}}
onClear={() => onChange([])}
noResultsFoundText={t("message.noResultsFoundTitle")}
/>
)}
noResultsMessage={t("message.noResultsFoundTitle")}
placeholderText={t("composed.selectMany", {
what: t("terms.stakeholder(s)").toLowerCase(),
})}
searchInputAriaLabel="stakeholder-select-toggle"
/>
<HookFormPFGroupController

<ItemsSelect
items={stakeholderGroups}
control={control}
name="stakeholderGroups"
label={t("terms.stakeholderGroups")}
fieldId="stakeholder-groups"
renderInput={({ field: { value, name, onChange } }) => (
<SimpleSelect
variant="typeaheadmulti"
id="stakeholder-groups-select"
toggleId="stakeholder-groups-select-toggle"
toggleAriaLabel="Stakeholder groups dropdown toggle"
aria-label={name}
value={value}
options={[]}
// value={value
// .map((id) => stakeholderGroups.find((f) => id === f.id))
// .map((e) => (e ? stakeholderGroupToOption(e) : undefined))
// .filter((e) => e !== undefined)}
// options={stakeholderGroups.map(stakeholderGroupToOption)}
onChange={(selection) => {
const selectionWithValue =
selection as OptionWithValue<StakeholderGroup>;
const selectionId: number = selectionWithValue.value.id!;

const currentValue = value || [];
const e = currentValue.find((f) => f === selectionId);
if (e) {
onChange(currentValue.filter((f) => f !== selectionId));
} else {
onChange([...currentValue, selectionId]);
}
}}
onClear={() => onChange([])}
noResultsFoundText={t("message.noResultsFoundTitle")}
/>
)}
label="Stakeholder Group(s)"
fieldId="stakeholderGroups"
noResultsMessage={t("message.noResultsFoundTitle")}
placeholderText={t("composed.selectMany", {
what: t("terms.stakeholderGroup(s)").toLowerCase(),
})}
searchInputAriaLabel="stakeholder-groups-select-toggle"
/>
</FormSection>
</GridItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ import {
import { duplicateNameCheck, getAxiosErrorMessage } from "@app/utils/utils";
import { useFetchTagCategories } from "@app/queries/tags";

import ItemsSelect from "../items-select";
import { useFetchStakeholderGroups } from "@app/queries/stakeholdergoups";
import { useFetchStakeholders } from "@app/queries/stakeholders";
import ItemsSelect from "@app/components/items-select/items-select";

export interface ArchetypeFormValues {
name: string;
Expand Down Expand Up @@ -74,7 +74,6 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
});

const validationSchema = yup.object().shape({
// for text input fields
name: yup
.string()
.trim()
Expand Down Expand Up @@ -191,7 +190,7 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
fieldId="description"
/>

<ItemsSelect
<ItemsSelect<Tag, ArchetypeFormValues>
items={tags}
control={control}
name="criteriaTags"
Expand All @@ -205,7 +204,7 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
searchInputAriaLabel="criteria-tags-select-toggle"
/>

<ItemsSelect
<ItemsSelect<Tag, ArchetypeFormValues>
items={tags}
control={control}
name="tags"
Expand All @@ -219,7 +218,7 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
searchInputAriaLabel="archetype-tags-select-toggle"
/>

<ItemsSelect
<ItemsSelect<Stakeholder, ArchetypeFormValues>
items={stakeholders}
control={control}
name="stakeholders"
Expand All @@ -232,7 +231,7 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
searchInputAriaLabel="stakeholder-select-toggle"
/>

<ItemsSelect
<ItemsSelect<StakeholderGroup, ArchetypeFormValues>
items={stakeholderGroups}
control={control}
name="stakeholderGroups"
Expand Down

0 comments on commit c44218d

Please sign in to comment.