Skip to content

Commit

Permalink
Archetype form add stakeholders and stakeholder groups
Browse files Browse the repository at this point in the history
Signed-off-by: Scott J Dickerson <[email protected]>
  • Loading branch information
sjd78 committed Sep 11, 2023
1 parent 1683427 commit 50812df
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import {
Form,
} from "@patternfly/react-core";

import type { Archetype, Tag } from "@app/api/models";
import type {
Archetype,
Stakeholder,
StakeholderGroup,
Tag,
} from "@app/api/models";
import {
HookFormPFTextArea,
HookFormPFTextInput,
Expand All @@ -27,20 +32,24 @@ import {
import { duplicateNameCheck, getAxiosErrorMessage } from "@app/utils/utils";
import { useFetchTagCategories } from "@app/queries/tags";

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

export interface ArchetypeFormValues {
name: string;
description?: string;
comments?: string;
criteriaTags: string[]; // TODO: string[] only works if tags are uniquely named globally
tags: string[]; // TODO: string[] only works if tags are uniquely named globally
stakeholders?: object[];
stakeholderGroups?: object[];

// TODO: a string[] only works here with `Autocomplete` if the entities have globally unique names
criteriaTags: string[];
tags: string[];
stakeholders?: string[];
stakeholderGroups?: string[];
}

export interface ArchetypeFormProps {
toEdit: Archetype | null;
toEdit?: Archetype | null;
onClose: () => void;
}

Expand All @@ -55,6 +64,8 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
archetype, // TODO: Use this or just rely on `toEdit`?
existingArchetypes,
tags,
stakeholders,
stakeholderGroups,
createArchetype,
updateArchetype,
} = useArchetypeFormData({
Expand Down Expand Up @@ -100,8 +111,9 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
.min(1)
.required(t("validation.required")),

// TODO: add stakeholders (optional)
// TODO: add stakeholderGroups (optional)
stakeholders: yup.array().of(yup.string()),

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

const {
Expand All @@ -117,8 +129,9 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
criteriaTags: toEdit?.criteriaTags?.map((tag) => tag.name).sort() ?? [],
tags: toEdit?.archetypeTags?.map((tag) => tag.name).sort() ?? [],

// TODO: add stakeholders
// TODO: add stakeholderGroups
stakeholders: toEdit?.stakeholders?.map((sh) => sh.name).sort() ?? [],
stakeholderGroups:
toEdit?.stakeholderGroups?.map((sg) => sg.name).sort() ?? [],
},
resolver: yupResolver(validationSchema),
mode: "all",
Expand All @@ -139,8 +152,19 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
.map((tagName) => tags.find((tag) => tag.name === tagName))
.filter(Boolean) as Tag[],

stakeholders: undefined, // TODO: add stakeholders
stakeholderGroups: undefined, // TODO: add stakeholderGroups
stakeholders:
values.stakeholders === undefined
? undefined
: (values.stakeholders
.map((name) => stakeholders.find((s) => s.name === name))
.filter(Boolean) as Stakeholder[]),

stakeholderGroups:
values.stakeholderGroups === undefined
? undefined
: (values.stakeholderGroups
.map((name) => stakeholderGroups.find((s) => s.name === name))
.filter(Boolean) as StakeholderGroup[]),
};

if (isCreate) {
Expand All @@ -167,8 +191,8 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
fieldId="description"
/>

<TagsSelect
tags={tags}
<ItemsSelect
items={tags}
control={control}
name="criteriaTags"
label="Criteria Tags" // TODO: l10n
Expand All @@ -181,8 +205,8 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
searchInputAriaLabel="criteria-tags-select-toggle"
/>

<TagsSelect
tags={tags}
<ItemsSelect
items={tags}
control={control}
name="tags"
label="Archetype Tags" // TODO: l10n
Expand All @@ -195,8 +219,31 @@ export const ArchetypeForm: React.FC<ArchetypeFormProps> = ({
searchInputAriaLabel="archetype-tags-select-toggle"
/>

{/* TODO: add stakeholders */}
{/* TODO: add stakeholderGroups */}
<ItemsSelect
items={stakeholders}
control={control}
name="stakeholders"
label="Stakeholder(s)" // TODO: l10n
fieldId="stakeholders"
noResultsMessage={t("message.noResultsFoundTitle")}
placeholderText={t("composed.selectMany", {
what: t("terms.stakeholder(s)").toLowerCase(),
})}
searchInputAriaLabel="stakeholder-select-toggle"
/>

<ItemsSelect
items={stakeholderGroups}
control={control}
name="stakeholderGroups"
label="Stakeholder Group(s)" // TODO: l10n
fieldId="stakeholderGroups"
noResultsMessage={t("message.noResultsFoundTitle")}
placeholderText={t("composed.selectMany", {
what: t("terms.stakeholderGroup(s)").toLowerCase(),
})}
searchInputAriaLabel="stakeholder-groups-select-toggle"
/>

<HookFormPFTextArea
control={control}
Expand Down Expand Up @@ -254,6 +301,9 @@ const useArchetypeFormData = ({
[tagCategories]
);

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

const onCreateSuccess = (archetype: Archetype) => {
pushNotification({
title: t("toastr.success.createWhat", {
Expand Down Expand Up @@ -300,5 +350,7 @@ const useArchetypeFormData = ({
updateArchetype,
tagCategories,
tags,
stakeholders,
stakeholderGroups,
};
};
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import React from "react";
import { Control, Path } from "react-hook-form";
import type { Tag } from "@app/api/models";
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 tags names are globally unique)
// TODO: Does not support select menu grouping by tag category
// 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 tag labels with tag category color
// TODO: Does not support rendering tag labels in tag category groups
const TagsSelect = ({
tags,
// 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 }>({
items = [],
control,
name,
label,
Expand All @@ -21,16 +20,21 @@ const TagsSelect = ({
searchInputAriaLabel,
isRequired = false,
}: {
tags: Tag[];
items: ItemType[];
control: Control<ArchetypeFormValues>;
name: Path<ArchetypeFormValues>;
label: string;
fieldId: string;
noResultsMessage: string;
placeholderText: string;
searchInputAriaLabel: string;
isRequired: boolean;
isRequired?: boolean;
}) => {
const itemsToName = () => items.map((item) => item.name).sort();

const normalizeSelections = (values: string | string[] | undefined) =>
(Array.isArray(values) ? values : [values]).filter(Boolean) as string[];

return (
<HookFormPFGroupController
isRequired={isRequired}
Expand All @@ -44,13 +48,13 @@ const TagsSelect = ({
noResultsMessage={noResultsMessage}
placeholderText={placeholderText}
searchInputAriaLabel={searchInputAriaLabel}
options={tags.map((tag) => tag.name).sort()}
selections={Array.isArray(value) ? value : [value]}
options={itemsToName()}
selections={normalizeSelections(value)}
onChange={onChange}
/>
)}
/>
);
};

export default TagsSelect;
export default ItemsSelect;

0 comments on commit 50812df

Please sign in to comment.