Merge pull request #121 from navi-sa/search-params-for-teams

TP-56198 | add team id in search parms and access a particular team using the url for easy shareability of team
This commit is contained in:
Dhruv Joshi
2024-02-07 12:02:05 +05:30
committed by GitHub
7 changed files with 962 additions and 54 deletions

View File

@@ -1,17 +1,21 @@
import { useEffect, useState, useRef, useReducer } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { SelectPicker } from '@navi/web-ui/lib/components';
import { SelectPickerOptionProps } from '@navi/web-ui/lib/components/SelectPicker/types';
import { Button, Typography } from '@navi/web-ui/lib/primitives';
import { AddIcon } from '@navi/web-ui/lib/icons';
import { Button, Typography } from '@navi/web-ui/lib/primitives';
import PersonIcon from '@src/assets/PersonIcon';
import SelectedPersonIcon from '@src/assets/SelectedPersonIcon';
import CreateTeam from '@src/Pages/TeamRevamp/partials/CreateTeam/CreateTeam';
import { useAuthData } from '@src/services/hooks/useAuth';
import { fetchTeamDetails, setModalOpen } from '@src/slices/team1Slice';
import { AppDispatch, RootState } from '@src/store';
import { useAuthData } from '@src/services/hooks/useAuth';
import CreateTeam from '@src/Pages/TeamRevamp/partials/CreateTeam/CreateTeam';
import useGetTeamDetailsConstants from '@src/Pages/TeamRevamp/util';
import SearchInput from './SearchInput';
import styles from './TeamList.module.scss';
import SelectedPersonIcon from '@src/assets/SelectedPersonIcon';
type Options = {
label: string;
@@ -43,14 +47,43 @@ const CustomTeamOptions = (option: Options): JSX.Element => {
const TeamList: React.FC = () => {
const dispatch = useDispatch<AppDispatch>();
const Role = useAuthData();
const navigate = useNavigate();
const [searchParams, setSearchParams] = useSearchParams();
const [isOpenedUsingUrl, setIsOpenedUsingUrl] = useState(true);
const teamList = useSelector((state: RootState) => state.team1.teams.data);
const defaultTeam = useSelector(
(state: RootState) => state.team1.teams.data[0],
);
const [team, setTeam] = useState<SelectPickerOptionProps>();
const teamRef = useRef(`team_id=${team?.value}`);
const newTeam = useSelector((state: RootState) => state.team1.teams.newTeam);
const [input, setInput] = useState('');
const scroll = useRef<boolean>(false);
const { getTeamNameFromId } = useGetTeamDetailsConstants();
useEffect(() => {
const selectedTeamIdFromParams = searchParams?.get('team_id');
const selectedTeamNameFromParams = getTeamNameFromId(
selectedTeamIdFromParams,
);
if (selectedTeamIdFromParams && selectedTeamNameFromParams) {
handleSetTeam({
label: selectedTeamNameFromParams,
value: parseInt(selectedTeamIdFromParams),
});
if (isOpenedUsingUrl) {
scrollintoView(selectedTeamIdFromParams ?? '');
}
} else {
if (defaultTeam?.id) {
handleSetTeam({
label: defaultTeam?.name,
value: parseInt(defaultTeam?.id),
});
scrollintoView(defaultTeam?.id);
}
}
}, [searchParams, teamList]);
const scrollintoView = (event: string): void => {
if (!event) return;
@@ -112,23 +145,42 @@ const TeamList: React.FC = () => {
dispatch(setModalOpen(true));
};
const handleSetTeam = (team: SelectPickerOptionProps): void => {
setTeam(team);
teamRef.current = `team_id=${team.value}`;
updateURLAndFetchData(teamRef.current);
};
const handleSelectionChange = (
event: SelectPickerOptionProps | SelectPickerOptionProps[],
): void => {
if (!Array.isArray(event)) {
setTeam(event);
dispatch(fetchTeamDetails(event.value.toString()));
handleSetTeam(event);
scroll.current = false;
setIsOpenedUsingUrl(false);
}
};
const returnIsFilteredResultEmpty = (): boolean => {
const filteredResult = options.filter(item =>
item.label.toLowerCase().includes(input.toLowerCase()),
);
return !filteredResult.length;
};
const updateURLAndFetchData = (updatedQuery: string) => {
navigate({
search: updatedQuery,
});
const pairs = updatedQuery?.split('&');
const result = {};
pairs?.forEach(pair => {
const keyValue = pair?.split('=');
if (keyValue.length === 2) {
const [key, value] = keyValue;
result[key] = value;
}
});
dispatch(fetchTeamDetails(result?.['team_id']));
};
return (
<div>
<div className={styles['team-div']}>
@@ -184,7 +236,7 @@ const TeamList: React.FC = () => {
selectedValue={team?.value ?? defaultTeam?.id ?? ''}
/>
</div>
<CreateTeam setTeam={setTeam} />
<CreateTeam handleSetTeam={handleSetTeam} />
</div>
);
};

View File

@@ -19,9 +19,6 @@ import { CLICK_STREAM_EVENT_FACTORY } from '@src/services/clickStream/constants/
const TeamRevamp: FC = () => {
const dispatch = useDispatch<AppDispatch>();
const teamData: TeamState = useSelector(selectSearchTeamData);
const { data, selectedTeam } = teamData;
const selectedTeamId = selectedTeam?.id || '';
const { fireEvent } = useClickStream();
const { EVENT_NAME, SCREEN_NAME } = CLICK_STREAM_EVENT_FACTORY;
@@ -30,17 +27,6 @@ const TeamRevamp: FC = () => {
fetchAllBots();
}, []);
useEffect(() => {
if (data) {
dispatch(setSelectedTeam(data[0]));
}
}, []);
useEffect(() => {
if (selectedTeam && selectedTeamId) {
dispatch(fetchTeamDetails(selectedTeamId.toString()));
}
}, [selectedTeam]);
useEffect(() => {
fireEvent(EVENT_NAME.Houston_Team_Land, {
screen_name: SCREEN_NAME.TEAM_PAGE,

View File

@@ -29,7 +29,7 @@ import styles from './CreateTeam.module.scss';
import useClickStream from '@src/services/clickStream';
import { CLICK_STREAM_EVENT_FACTORY } from '@src/services/clickStream/constants/values';
const CreateTeam: React.FC<CreateTeamProps> = ({ setTeam }) => {
const CreateTeam: React.FC<CreateTeamProps> = ({ handleSetTeam }) => {
const dispatch = useDispatch<AppDispatch>();
const [state, dispatchData] = useReducer(reducer, initialState);
const { fireEvent } = useClickStream();
@@ -90,7 +90,7 @@ const CreateTeam: React.FC<CreateTeamProps> = ({ setTeam }) => {
toast.success(toastMessage);
clearErrors();
dispatch(fetchTeamDetails(createdTeamId.toString()));
setTeam({ label: createdTeamName, value: createdTeamId });
handleSetTeam({ label: createdTeamName, value: createdTeamId });
dispatch(setNewTeam(createdTeamId));
dispatch(fetchTeams());
})

View File

@@ -24,9 +24,7 @@ export interface TeamsData {
expand?: boolean;
}
export interface CreateTeamProps {
setTeam: React.Dispatch<
React.SetStateAction<SelectPickerOptionProps | undefined>
>;
handleSetTeam: (team: SelectPickerOptionProps) => void;
}
export interface BotsData {
id: string;
@@ -72,6 +70,7 @@ export interface Details {
DEFAULT_TEAM_PSEC_ID: string;
DEFAULT_PSEC_ONCALL: string;
webChannelId: string;
getTeamNameFromId: (teamId: string | null) => string;
}
export interface Participant {
name: string;

View File

@@ -1,6 +1,6 @@
import { useSelector } from 'react-redux';
import { TeamState, selectSearchTeamData } from '@src/slices/team1Slice';
import { Details } from './types';
import { Details, TeamsData } from './types';
export const useTeamDetails = (): TeamState => {
return useSelector(selectSearchTeamData);
};
@@ -8,6 +8,7 @@ export const useTeamDetails = (): TeamState => {
export const useGetTeamDetailsConstants = (): Details => {
const userData = JSON.parse(localStorage.getItem('user-data') || '{}');
const teamData = useTeamDetails();
const teamList = teamData?.data;
const teamDetails = teamData.teamDetails;
const teamId = teamDetails?.id;
const userEmail = userData?.emailId || '';
@@ -38,6 +39,12 @@ export const useGetTeamDetailsConstants = (): Details => {
: teamDetails?.webhookSlackChannelId
? teamDetails?.webhookSlackChannelId
: '';
const getTeamNameFromId = (teamId: string | null) => {
if (!teamId) return '';
return Array.isArray(teamList)
? teamList?.find(item => item.id == parseInt(teamId))?.name
: '';
};
return {
teamId,
userEmail,
@@ -51,6 +58,7 @@ export const useGetTeamDetailsConstants = (): Details => {
DEFAULT_TEAM_PSEC_ID,
DEFAULT_PSEC_ONCALL,
webChannelId,
getTeamNameFromId,
};
};

View File

@@ -26,7 +26,7 @@
},
"typeRoots": ["./node_modules/@types", "./src/types"]
},
"include": ["src", "config.js", "setup.template.js"],
"include": ["src", "config.qa.js", "setup.template.js"],
"exclude": ["**/node_modules/*"],
"references": [{ "path": "./tsconfig.node.json" }]
}

911
yarn.lock

File diff suppressed because it is too large Load Diff