Skip to content

Commit

Permalink
Refactor PointEntryCreator component and add tour
Browse files Browse the repository at this point in the history
feature
  • Loading branch information
jthoward64 committed Nov 27, 2023
1 parent 97d8d84 commit 9dcf118
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { App, Button, Flex, Form, Input, InputNumber } from "antd";
import { useReducer } from "react";
import { QuestionOutlined } from "@ant-design/icons";
import type { InputRef, TourProps } from "antd";
import { App, Button, Flex, Form, Input, InputNumber, Tour } from "antd";
import { useReducer, useRef, useState } from "react";

import { PointEntryOpportunityLookup } from "./PointEntryOpportunityLookup";
import { PointEntryPersonLookup } from "./PointEntryPersonLookup";
Expand All @@ -14,6 +16,59 @@ export function PointEntryCreator({
}) {
const { message } = App.useApp();

const [tourVisible, setTourVisible] = useState(false);

const commentFieldRef = useRef<InputRef>(null);
const pointsFieldRef = useRef<HTMLInputElement>(null);
const nameFieldRef = useRef<HTMLDivElement>(null);
const linkblueFieldRef = useRef<InputRef>(null);
const selectedPersonRef = useRef<HTMLSpanElement>(null);
const clearButtonRef = useRef<HTMLButtonElement>(null);
const submitButtonRef = useRef<HTMLButtonElement>(null);

const steps: TourProps["steps"] = [
{
title: "Comment",
description:
"Enter a comment for the point entry, the comment is not shown anywhere outside of this page and is just for your reference.",
target: commentFieldRef.current?.input ?? null,
},
{
title: "Points",
description: "Enter the number of points to give for the point entry.",
target: pointsFieldRef.current ?? null,
},
{
title: "Name",
description:
"If you know the name of the person that the point entry is for, you can search for them here. If they have signed in before their name will appear in the list. Click on their name to select them.",
target: nameFieldRef.current,
},
{
title: "Linkblue",
description:
"If you know the linkblue of the person that the point entry is for, you can enter it here. Click lookup to check for the person. If they have already been added to the system they will be selected automatically. Otherwise, a create button will appear that will allow you to create a new person with that linkblue.",
target: linkblueFieldRef.current?.input ?? null,
},
{
title: "Clear",
description: "Click the clear button to clear the person selection.",
target: clearButtonRef.current ?? null,
},
{
title: "Selected person",
description:
"Once you have selected a person, their info will appear here.",
target: selectedPersonRef.current ?? null,
},
{
title: "Submit",
description:
"Once you have filled out the form, click the submit button to create the point entry.",
target: submitButtonRef.current ?? null,
},
];

const [personLookupKey, resetLookup] = useReducer(
(prev: number) => prev + 1,
0
Expand All @@ -31,6 +86,13 @@ export function PointEntryCreator({

return (
<formApi.Provider>
<Tour
steps={steps}
placement="top"
mask
open={tourVisible}
onClose={() => setTourVisible(false)}
/>
<Form
onFinish={() => {
formApi.handleSubmit().catch((error) => {
Expand Down Expand Up @@ -63,6 +125,7 @@ export function PointEntryCreator({
value={field.state.value ?? undefined}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
ref={commentFieldRef}
/>
</Form.Item>
)}
Expand Down Expand Up @@ -91,6 +154,7 @@ export function PointEntryCreator({
value={field.state.value}
onBlur={field.handleBlur}
onChange={(num) => field.handleChange(num ?? 0)}
ref={pointsFieldRef}
/>
</Form.Item>
)}
Expand All @@ -101,10 +165,22 @@ export function PointEntryCreator({
formApi={formApi}
teamUuid={teamUuid}
key={personLookupKey}
nameFieldRef={nameFieldRef}
linkblueFieldRef={linkblueFieldRef}
selectedPersonRef={selectedPersonRef}
clearButtonRef={clearButtonRef}
/>
<Button type="primary" htmlType="submit">
Submit
</Button>
<Flex justify="space-between" align="center" wrap="wrap">
<Button type="primary" htmlType="submit" ref={submitButtonRef}>
Submit
</Button>
<Button
icon={<QuestionOutlined />}
onClick={() => setTourVisible(true)}
>
Help
</Button>
</Flex>
</Form>
</formApi.Provider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ClearOutlined, PlusOutlined, SearchOutlined } from "@ant-design/icons";
import { useAskConfirm, useUnknownErrorHandler } from "@hooks/useAntFeedback";
import { useQueryStatusWatcher } from "@hooks/useQueryStatusWatcher";
import { AutoComplete, Button, Descriptions, Flex, Form, Input } from "antd";
import type { LegacyRef } from "react";
import { useEffect, useState } from "react";
import { useMutation, useQuery } from "urql";
import { useDebouncedCallback } from "use-debounce";
Expand All @@ -18,9 +19,17 @@ const generalLinkblueRegex = new RegExp(/^[A-Za-z]{3,4}\d{3}$/);
export function PointEntryPersonLookup({
formApi,
teamUuid,
nameFieldRef,
linkblueFieldRef,
selectedPersonRef,
clearButtonRef,
}: {
formApi: ReturnType<typeof usePointEntryCreatorForm>["formApi"];
teamUuid: string;
nameFieldRef: LegacyRef<HTMLDivElement>;
linkblueFieldRef: Parameters<typeof Input>[0]["ref"];
selectedPersonRef: LegacyRef<HTMLSpanElement>;
clearButtonRef: Parameters<typeof Button>[0]["ref"];
}) {
const { showErrorMessage } = useUnknownErrorHandler();
// Form state (shared with parent)
Expand Down Expand Up @@ -179,30 +188,32 @@ export function PointEntryPersonLookup({
>
<Descriptions column={1}>
<Descriptions.Item label="Name">
{/* Three options to choose a person, autocomplete name, autocomplete linkblue, or manual entry */}
<AutoComplete
placeholder="Search by Name"
value={
(personFromUuid &&
selectedPersonQuery.data?.person.data?.name) ||
searchByNameField
}
onBlur={field.handleBlur}
disabled={!!field.state.value}
onChange={(value) => {
setSearchByNameField(value);
if (value) {
updateAutocomplete(value);
} else {
setNameAutocomplete([]);
<div ref={nameFieldRef} style={{ width: "100%" }}>
{/* Three options to choose a person, autocomplete name, autocomplete linkblue, or manual entry */}
<AutoComplete
placeholder="Search by Name"
value={
(personFromUuid &&
selectedPersonQuery.data?.person.data?.name) ||
searchByNameField
}
}}
onSelect={(value) => {
field.handleChange(value);
updateSelectedPerson();
}}
options={nameAutocomplete}
/>
onBlur={field.handleBlur}
disabled={!!field.state.value}
onChange={(value) => {
setSearchByNameField(value);
if (value) {
updateAutocomplete(value);
} else {
setNameAutocomplete([]);
}
}}
onSelect={(value) => {
field.handleChange(value);
updateSelectedPerson();
}}
options={nameAutocomplete}
/>
</div>
</Descriptions.Item>
<Descriptions.Item label="LinkBlue">
<Input
Expand All @@ -218,6 +229,7 @@ export function PointEntryPersonLookup({
disabled={!!field.state.value}
onBlur={field.handleBlur}
placeholder="Lookup Existing LinkBlue"
ref={linkblueFieldRef}
/>
{!linkblueKnownDoesNotExist ? (
<Button
Expand Down Expand Up @@ -277,21 +289,23 @@ export function PointEntryPersonLookup({
</Descriptions.Item>
</Descriptions>
<Flex justify="space-between" wrap="wrap">
{field.state.value ? (
<span>
Selected Person:{" "}
{selectedPersonQuery.data?.person.data ? (
<i>
{selectedPersonQuery.data.person.data.name ??
selectedPersonQuery.data.person.data.linkblue}
</i>
) : (
"No name or linkblue found"
)}
</span>
) : (
<span>Nobody selected</span>
)}
<span ref={selectedPersonRef}>
{field.state.value ? (
<>
<span>Selected Person:</span>{" "}
{selectedPersonQuery.data?.person.data ? (
<i>
{selectedPersonQuery.data.person.data.name ??
selectedPersonQuery.data.person.data.linkblue}
</i>
) : (
"No name or linkblue found"
)}
</>
) : (
"Nobody selected"
)}
</span>
<Button
color="grey"
onClick={() => {
Expand All @@ -300,6 +314,7 @@ export function PointEntryPersonLookup({
}}
icon={<ClearOutlined />}
disabled={!field.state.value}
ref={clearButtonRef}
>
Clear
</Button>
Expand Down

0 comments on commit 9dcf118

Please sign in to comment.