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:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
})
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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" }]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user