From c487147a63758e97c06e80531dee6b9ffc7907fd Mon Sep 17 00:00:00 2001 From: Arik Chakma Date: Tue, 25 Jul 2023 02:54:40 +0600 Subject: [PATCH] wip: roadmap selector modal --- src/components/CreateTeam/RoadmapSelector.tsx | 82 +++++++----- .../CreateTeam/SelectRoadmapModal.tsx | 118 ++++++++++++++++++ src/components/CreateTeam/Step2.tsx | 4 +- src/icons/plus-white.svg | 1 + 4 files changed, 173 insertions(+), 32 deletions(-) create mode 100644 src/components/CreateTeam/SelectRoadmapModal.tsx create mode 100644 src/icons/plus-white.svg diff --git a/src/components/CreateTeam/RoadmapSelector.tsx b/src/components/CreateTeam/RoadmapSelector.tsx index bec08ff38..ac4a8c9fa 100644 --- a/src/components/CreateTeam/RoadmapSelector.tsx +++ b/src/components/CreateTeam/RoadmapSelector.tsx @@ -3,9 +3,12 @@ import { SearchSelector } from '../SearchSelector'; import { httpGet, httpPut } from '../../lib/http'; import type { PageType } from '../CommandMenu/CommandMenu'; import SearchIcon from '../../icons/search.svg'; +import PlusIcon from '../../icons/plus.svg'; +import PlusWhiteIcon from '../../icons/plus-white.svg'; import { pageProgressMessage } from '../../stores/page'; import type { TeamDocument } from './CreateTeamForm'; import { UpdateTeamResourceModal } from './UpdateTeamResourceModal'; +import { SelectRoadmapModal } from './SelectRoadmapModal'; export type TeamResourceConfig = { resourceId: string; @@ -22,6 +25,7 @@ type RoadmapSelectorProps = { export function RoadmapSelector(props: RoadmapSelectorProps) { const { team, teamResourceConfig = [], setTeamResourceConfig } = props; + const [showSelectRoadmapModal, setShowSelectRoadmapModal] = useState(false); const [allRoadmaps, setAllRoadmaps] = useState([]); const [changingRoadmapId, setChangingRoadmapId] = useState(''); const [error, setError] = useState(''); @@ -56,8 +60,7 @@ export function RoadmapSelector(props: RoadmapSelectorProps) { pageProgressMessage.set(`Deleting resource`); const { error, response } = await httpPut( - `${import.meta.env.PUBLIC_API_URL}/v1-delete-team-resource-config/${ - team._id + `${import.meta.env.PUBLIC_API_URL}/v1-delete-team-resource-config/${team._id }`, { resourceId: roadmapId, @@ -88,8 +91,7 @@ export function RoadmapSelector(props: RoadmapSelectorProps) { pageProgressMessage.set(`Adding roadmap to team`); const { error, response } = await httpPut( - `${import.meta.env.PUBLIC_API_URL}/v1-update-team-resource-config/${ - team._id + `${import.meta.env.PUBLIC_API_URL}/v1-update-team-resource-config/${team._id }`, { teamId: team._id, @@ -126,42 +128,47 @@ export function RoadmapSelector(props: RoadmapSelectorProps) { } /> )} - - { - const roadmapId = option.value; - addTeamResource(roadmapId).finally(() => { - pageProgressMessage.set(''); - }); - }} - options={allRoadmaps - .filter((roadmap) => { - return !teamResourceConfig - .map((c) => c.resourceId) - .includes(roadmap.id); - }) - .map((roadmap) => ({ - value: roadmap.id, - label: roadmap.title, - }))} - searchInputId={'roadmap-input'} - inputClassName="mt-2 block w-full rounded-md border px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1" - /> + {showSelectRoadmapModal && ( + setShowSelectRoadmapModal(false)} + teamResourceConfig={teamResourceConfig} + allRoadmaps={allRoadmaps} + teamId={team?._id!} + onRoadmapAdd={(roadmapId) => { + addTeamResource(roadmapId).finally(() => { + pageProgressMessage.set(''); + }); + }} + onRoadmapRemove={(roadmapId) => { + onRemove(roadmapId).finally(() => { + }); + }} + /> + )} {!teamResourceConfig.length && (
- {'search'} No roadmaps selected.

Please search and add roadmaps from above

+
+ +
)} @@ -214,6 +221,19 @@ export function RoadmapSelector(props: RoadmapSelectorProps) { ); })} + )} diff --git a/src/components/CreateTeam/SelectRoadmapModal.tsx b/src/components/CreateTeam/SelectRoadmapModal.tsx new file mode 100644 index 000000000..347552fd8 --- /dev/null +++ b/src/components/CreateTeam/SelectRoadmapModal.tsx @@ -0,0 +1,118 @@ +import { useEffect, useRef, useState } from 'preact/hooks'; +import { useKeydown } from '../../hooks/use-keydown'; +import { useOutsideClick } from '../../hooks/use-outside-click'; +import type { PageType } from '../CommandMenu/CommandMenu'; +import { httpGet } from '../../lib/http'; +import { useToast } from '../../hooks/use-toast'; +import type { TeamResourceConfig } from './RoadmapSelector'; + +export type SelectRoadmapModalProps = { + teamId: string; + allRoadmaps: PageType[]; + onClose: () => void; + teamResourceConfig: TeamResourceConfig + onRoadmapAdd: (roadmapId: string) => void; + onRoadmapRemove: (roadmapId: string) => void; +}; + +export function SelectRoadmapModal(props: SelectRoadmapModalProps) { + const { onClose, allRoadmaps, onRoadmapAdd, onRoadmapRemove, teamResourceConfig } = props; + const toast = useToast(); + const popupBodyEl = useRef(null); + + const [searchResults, setSearchResults] = useState(allRoadmaps); + const [searchText, setSearchText] = useState(''); + + useKeydown('Escape', () => { + onClose(); + }); + + useOutsideClick(popupBodyEl, () => { + onClose(); + }); + + useEffect(() => { + if (searchText.length === 0) { + setSearchResults(allRoadmaps); + return; + } + + const searchResults = allRoadmaps.filter(roadmap => { + return roadmap.title.toLowerCase().includes(searchText.toLowerCase()) || + roadmap.id.toLowerCase().includes(searchText.toLowerCase()); + }); + setSearchResults(searchResults); + }, [searchText, allRoadmaps]) + + return ( +
+
+ +
+
+ ); +} diff --git a/src/components/CreateTeam/Step2.tsx b/src/components/CreateTeam/Step2.tsx index 723456cd8..119d79c71 100644 --- a/src/components/CreateTeam/Step2.tsx +++ b/src/components/CreateTeam/Step2.tsx @@ -1,5 +1,6 @@ -import { RoadmapSelector, TeamResourceConfig } from './RoadmapSelector'; +import {RoadmapSelector, TeamResourceConfig } from './RoadmapSelector'; import type { TeamDocument } from './CreateTeamForm'; +import { useState } from 'preact/hooks'; type Step2Props = { team: TeamDocument; @@ -12,6 +13,7 @@ type Step2Props = { export function Step2(props: Step2Props) { const { team, onBack, onNext, teamResourceConfig, setTeamResourceConfig } = props; + const [showSelectRoadmapModal, setShowSelectRoadmapModal] = useState(false); return ( <> diff --git a/src/icons/plus-white.svg b/src/icons/plus-white.svg new file mode 100644 index 000000000..4986ebc4b --- /dev/null +++ b/src/icons/plus-white.svg @@ -0,0 +1 @@ +