diff --git a/.vscode/settings.json b/.vscode/settings.json index d7c9b74391..8045f6e7bd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,4 +22,7 @@ "*.tsx": "$(capture).ts, $(capture).d.ts, $(capture).spec.tsx, $(capture).styles.ts", "package.json": "package-lock.json, .npmrc" }, + "cSpell.words": [ + "fluentui" + ], } diff --git a/package-lock.json b/package-lock.json index 82ec5db5d5..d337ea68cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "eslint-config-react-app": "7.0.1", "eslint-plugin-react": "7.33.2", "eslint-webpack-plugin": "4.1.0", - "express": "4.21.0", + "express": "^4.21.1", "expvariantassignmentsdk": "file:packages/expvariantassignmentsdk-1.0.0.tgz", "file-loader": "6.2.0", "fork-ts-checker-webpack-plugin": "9.0.2", @@ -4449,6 +4449,14 @@ "whatwg-fetch": "^3.0.0" } }, + "node_modules/@ms-ofb/officebrowserfeedbacknpm/node_modules/@ms-ofb/officefloodgatecore": { + "version": "0.0.0", + "extraneous": true, + "inBundle": true, + "dependencies": { + "es6-promise": "4.2.8" + } + }, "node_modules/@ms-ofb/officebrowserfeedbacknpm/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -7438,9 +7446,10 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9684,16 +9693,17 @@ } }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -11115,9 +11125,10 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", diff --git a/package.json b/package.json index b7047aaefb..fc9c2e8e10 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "eslint-config-react-app": "7.0.1", "eslint-plugin-react": "7.33.2", "eslint-webpack-plugin": "4.1.0", - "express": "4.21.0", + "express": "^4.21.1", "expvariantassignmentsdk": "file:packages/expvariantassignmentsdk-1.0.0.tgz", "file-loader": "6.2.0", "fork-ts-checker-webpack-plugin": "9.0.2", diff --git a/src/app/services/context/validation-context/ValidationProvider.tsx b/src/app/services/context/validation-context/ValidationProvider.tsx index a7e568bb02..18d11212f6 100644 --- a/src/app/services/context/validation-context/ValidationProvider.tsx +++ b/src/app/services/context/validation-context/ValidationProvider.tsx @@ -13,7 +13,7 @@ interface ValidationProviderProps { } export const ValidationProvider = ({ children }: ValidationProviderProps) => { - const { resources } = useAppSelector((state) => state); + const resources = useAppSelector((state) => state.resources); const base = Object.keys(resources.data).length > 0 ? resources.data[GRAPH_API_VERSIONS[0]].children! : []; diff --git a/src/app/views/app-sections/StatusMessages.tsx b/src/app/views/app-sections/StatusMessages.tsx index a020466c88..8bd791fae5 100644 --- a/src/app/views/app-sections/StatusMessages.tsx +++ b/src/app/views/app-sections/StatusMessages.tsx @@ -9,8 +9,8 @@ import MessageDisplay from '../common/message-display/MessageDisplay'; const StatusMessages = () => { const dispatch = useAppDispatch(); - const { queryRunnerStatus, sampleQuery } = - useAppSelector((state) => state); + const queryRunnerStatus = useAppSelector((state)=> state.queryRunnerStatus); + const sampleQuery = useAppSelector((state)=> state.sampleQuery); function setQuery(link: string) { const query: IQuery = { ...sampleQuery }; diff --git a/src/app/views/app-sections/TermsOfUseMessage.tsx b/src/app/views/app-sections/TermsOfUseMessage.tsx index 66e0c84465..c1e8c6bce9 100644 --- a/src/app/views/app-sections/TermsOfUseMessage.tsx +++ b/src/app/views/app-sections/TermsOfUseMessage.tsx @@ -9,8 +9,7 @@ import { appStyles } from '../App.styles'; const StyledTermsOfUseMessage = () => { - const { termsOfUse } = - useAppSelector((state) => state); + const termsOfUse = useAppSelector((state) => state.termsOfUse); const dispatch = useAppDispatch(); if (termsOfUse) { diff --git a/src/app/views/authentication/Authentication.tsx b/src/app/views/authentication/Authentication.tsx index 1e8efb1f6b..dd52633e2a 100644 --- a/src/app/views/authentication/Authentication.tsx +++ b/src/app/views/authentication/Authentication.tsx @@ -16,7 +16,7 @@ import { translateMessage } from '../../utils/translate-messages'; const Authentication = (props: any) => { const dispatch: AppDispatch = useAppDispatch(); const [loginInProgress, setLoginInProgress] = useState(false); - const { auth: { authToken } } = useAppSelector((state) => state); + const authToken = useAppSelector((state) => state.auth.authToken); const tokenPresent = !!authToken.token; const logoutInProgress = !!authToken.pending; diff --git a/src/app/views/main-header/FeedbackButton.tsx b/src/app/views/main-header/FeedbackButton.tsx index 691dd5cafb..27413a1b80 100644 --- a/src/app/views/main-header/FeedbackButton.tsx +++ b/src/app/views/main-header/FeedbackButton.tsx @@ -8,7 +8,8 @@ import { useAppSelector } from '../../../store'; export const FeedbackButton = () => { const [enableSurvey, setEnableSurvey] = useState(false); - const { profile: { user } } = useAppSelector((state) => state); + const user = useAppSelector((state) => state.profile.user) + const currentTheme = getTheme(); const feedbackIcon : IIconProps = { iconName : 'Feedback' diff --git a/src/app/views/main-header/Help.tsx b/src/app/views/main-header/Help.tsx index 95b8f2e496..c9cde96a01 100644 --- a/src/app/views/main-header/Help.tsx +++ b/src/app/views/main-header/Help.tsx @@ -17,7 +17,8 @@ import { mainHeaderStyles } from './MainHeader.styles'; import { useAppSelector } from '../../../store'; export const Help = () => { - const { auth: { authToken } } = useAppSelector((state) => state); + const auth = useAppSelector((state)=> state.auth) + const authToken = auth.authToken; const authenticated = authToken.token; const [items, setItems] = useState([]); const currentTheme = getTheme(); diff --git a/src/app/views/main-header/MainHeader.tsx b/src/app/views/main-header/MainHeader.tsx index a8dfe8bee0..8b25e44a36 100644 --- a/src/app/views/main-header/MainHeader.tsx +++ b/src/app/views/main-header/MainHeader.tsx @@ -29,9 +29,10 @@ registerIcons({ } }); export const MainHeader: React.FunctionComponent = (props: MainHeaderProps) => { - const { profile: { user }, graphExplorerMode, sidebarProperties } = useAppSelector( - (state) => state - ); + const profile = useAppSelector((state)=> state.profile) + const user = profile.user; + const graphExplorerMode = useAppSelector((state)=> state.graphExplorerMode) + const sidebarProperties = useAppSelector((state)=> state.sidebarProperties) const mobileScreen = !!sidebarProperties.mobileScreen; const showSidebar = !!sidebarProperties.showSidebar; diff --git a/src/app/views/main-header/settings/Settings.tsx b/src/app/views/main-header/settings/Settings.tsx index dfec3b5317..b751ced56e 100644 --- a/src/app/views/main-header/settings/Settings.tsx +++ b/src/app/views/main-header/settings/Settings.tsx @@ -14,7 +14,8 @@ import { translateMessage } from '../../../utils/translate-messages'; import { mainHeaderStyles } from '../MainHeader.styles'; export const Settings: React.FunctionComponent = () => { - const { auth: { authToken } } = useAppSelector((state) => state); + const auth = useAppSelector((state)=> state.auth) + const authToken = auth.authToken; const authenticated = authToken.token; const [items, setItems] = useState([]); const currentTheme = getTheme(); diff --git a/src/app/views/query-response/QueryResponse.tsx b/src/app/views/query-response/QueryResponse.tsx index 933510f8f1..447e3e57db 100644 --- a/src/app/views/query-response/QueryResponse.tsx +++ b/src/app/views/query-response/QueryResponse.tsx @@ -18,7 +18,9 @@ const QueryResponse = () => { const dispatch = useAppDispatch(); const [showModal, setShowModal] = useState(false); const [responseHeight, setResponseHeight] = useState('610px'); - const { sampleQuery, dimensions, snippets } = useAppSelector((state) => state); + const sampleQuery = useAppSelector((state)=> state.sampleQuery); + const dimensions = useAppSelector((state)=> state.dimensions); + const snippets = useAppSelector((state)=> state.snippets); const [currentTab, setCurrentTab] = useState('response-preview'); const currentTheme: ITheme = getTheme(); const { modalStyles, modalPivotStyles } = queryResponseStyles(currentTheme); diff --git a/src/app/views/query-response/pivot-items/pivot-items.tsx b/src/app/views/query-response/pivot-items/pivot-items.tsx index b5d2dbb6ce..2ad2208a82 100644 --- a/src/app/views/query-response/pivot-items/pivot-items.tsx +++ b/src/app/views/query-response/pivot-items/pivot-items.tsx @@ -17,9 +17,9 @@ import { } from '../../common/lazy-loader/component-registry'; export const GetPivotItems = () => { - - const { graphExplorerMode: mode, sampleQuery, - graphResponse: { response: { body } } } = useAppSelector((state) => state); + const mode = useAppSelector((state)=> state.graphExplorerMode); + const sampleQuery= useAppSelector((state)=> state.sampleQuery); + const body = useAppSelector((state)=> state.graphResponse.response.body); const currentTheme: ITheme = getTheme(); const dotStyle = queryResponseStyles(currentTheme).dot; diff --git a/src/app/views/query-response/queryResponse.styles.ts b/src/app/views/query-response/queryResponse.styles.ts index e4357747ab..97a481bf01 100644 --- a/src/app/views/query-response/queryResponse.styles.ts +++ b/src/app/views/query-response/queryResponse.styles.ts @@ -3,8 +3,9 @@ import { useAppSelector } from '../../../store'; import { convertVhToPx, getResponseHeight } from '../common/dimensions/dimensions-adjustment'; export const queryResponseStyles = (theme: ITheme) => { - const { dimensions: { response }, responseAreaExpanded} = - useAppSelector((state) => state); + const response = useAppSelector((state)=> state.dimensions.response); + const responseAreaExpanded = useAppSelector((state)=> state.responseAreaExpanded); + const height = convertVhToPx(getResponseHeight( response.height, responseAreaExpanded), 220); diff --git a/src/app/views/query-response/response/Response.tsx b/src/app/views/query-response/response/Response.tsx index 00cacc7f3a..c758604cd5 100644 --- a/src/app/views/query-response/response/Response.tsx +++ b/src/app/views/query-response/response/Response.tsx @@ -10,8 +10,10 @@ import ResponseDisplay from './ResponseDisplay'; import { ResponseMessages } from './ResponseMessages'; const Response = () => { - const { dimensions: { response }, graphResponse: { response: { body, headers } }, responseAreaExpanded } = - useAppSelector((state) => state); + const response = useAppSelector((state) => state.dimensions.response); + const body = useAppSelector((state) => state.graphResponse.response.body); + const headers = useAppSelector((state) => state.graphResponse.response.headers); + const responseAreaExpanded = useAppSelector((state) => state.responseAreaExpanded); const defaultHeight = convertVhToPx(getResponseHeight(response.height, responseAreaExpanded), 220); const monacoHeight = getResponseEditorHeight(150); diff --git a/src/app/views/query-response/response/ResponseMessages.tsx b/src/app/views/query-response/response/ResponseMessages.tsx index c81406fd56..0f6dddc3ab 100644 --- a/src/app/views/query-response/response/ResponseMessages.tsx +++ b/src/app/views/query-response/response/ResponseMessages.tsx @@ -34,9 +34,11 @@ function getOdataLinkFromResponseBody(responseBody: any): ODataLink | null { export const ResponseMessages = () => { const dispatch = useAppDispatch(); const messageBars = []; - - const { graphResponse: { response: { body, headers } }, sampleQuery, auth: { authToken }, graphExplorerMode - } = useAppSelector((state) => state); + const body = useAppSelector((state)=> state.graphResponse.response.body); + const headers = useAppSelector((state)=> state.graphResponse.response.headers); + const sampleQuery = useAppSelector((state)=> state.sampleQuery); + const authToken= useAppSelector((state)=> state.auth.authToken); + const graphExplorerMode = useAppSelector((state)=> state.graphExplorerMode); const [displayMessage, setDisplayMessage] = useState(true); const tokenPresent = !!authToken.token; diff --git a/src/app/views/query-runner/QueryRunner.tsx b/src/app/views/query-runner/QueryRunner.tsx index bd08783a5b..13acff72f1 100644 --- a/src/app/views/query-runner/QueryRunner.tsx +++ b/src/app/views/query-runner/QueryRunner.tsx @@ -17,7 +17,7 @@ import Request from './request/Request'; const QueryRunner = (props: any) => { const dispatch = useAppDispatch(); - const { sampleQuery } = useAppSelector((state) => state); + const sampleQuery = useAppSelector((state) => state.sampleQuery); const [sampleBody, setSampleBody] = useState(''); diff --git a/src/app/views/query-runner/query-input/QueryInput.tsx b/src/app/views/query-runner/query-input/QueryInput.tsx index 5e1c05e04a..6adb5f9827 100644 --- a/src/app/views/query-runner/query-input/QueryInput.tsx +++ b/src/app/views/query-runner/query-input/QueryInput.tsx @@ -33,10 +33,11 @@ const QueryInput = (props: IQueryInputProps) => { }) }); - const { sampleQuery, auth: { authToken }, - graphResponse: { isLoadingData }, - sidebarProperties } = useAppSelector((state) => state); + const sampleQuery = useAppSelector((state) => state.sampleQuery); + const authToken = useAppSelector((state) => state.auth.authToken); const authenticated = !!authToken.token; + const isLoadingData = useAppSelector((state) => state.graphResponse.isLoadingData); + const sidebarProperties = useAppSelector((state) => state.sidebarProperties); const { mobileScreen } = sidebarProperties; const showError = !shouldRunQuery({ diff --git a/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx b/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx index 442006b587..9887e7a067 100644 --- a/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx +++ b/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx @@ -29,9 +29,9 @@ const AutoComplete = (props: IAutoCompleteProps) => { let element: HTMLDivElement | null | undefined = null; - const { sampleQuery, autoComplete: { data: autoCompleteOptions, pending: autoCompletePending } } = useAppSelector( - (state) => state - ); + const sampleQuery = useAppSelector((state)=> state.sampleQuery); + const autoCompleteOptions = useAppSelector((state)=> state.autoComplete.data); + const autoCompletePending = useAppSelector((state)=> state.autoComplete.pending); const previousQuery = usePrevious(sampleQuery.sampleUrl); const [isMultiline, setIsMultiline] = useState(false); @@ -290,6 +290,14 @@ const AutoComplete = (props: IAutoCompleteProps) => { validation.validate(queryUrl); return validation.error; } + const [descriptionError, setDescriptionError] = useState(''); + + useEffect(()=>{ + const errorMessage = getErrorMessage(); + if (errorMessage) { + setDescriptionError(errorMessage) + } + }, [getErrorMessage]) return (
@@ -310,7 +318,7 @@ const AutoComplete = (props: IAutoCompleteProps) => { ariaLabel={translateMessage('Query Sample Input')} role='textbox' onRenderDescription={handleRenderDescription} - description={getErrorMessage()} + description={descriptionError} />
{shouldShowSuggestions && queryUrl && suggestions.length > 0 && diff --git a/src/app/views/query-runner/query-input/auto-complete/suffix/SuffixRenderer.tsx b/src/app/views/query-runner/query-input/auto-complete/suffix/SuffixRenderer.tsx index c65755482c..05a5cc2874 100644 --- a/src/app/views/query-runner/query-input/auto-complete/suffix/SuffixRenderer.tsx +++ b/src/app/views/query-runner/query-input/auto-complete/suffix/SuffixRenderer.tsx @@ -13,9 +13,9 @@ import DocumentationService from './documentation'; import { styles } from './suffix.styles'; const SuffixRenderer = () => { - const { sampleQuery, samples, resources } = useAppSelector( - (state) => state - ); + const sampleQuery = useAppSelector((state)=> state.sampleQuery); + const samples = useAppSelector((state)=> state.samples); + const resources = useAppSelector((state)=> state.resources); const buttonId = getId('callout-button'); const calloutProps = { gapSpace: 0 }; diff --git a/src/app/views/query-runner/query-input/auto-complete/use-previous.ts b/src/app/views/query-runner/query-input/auto-complete/use-previous.ts index 80bca8bf8a..b7aa493826 100644 --- a/src/app/views/query-runner/query-input/auto-complete/use-previous.ts +++ b/src/app/views/query-runner/query-input/auto-complete/use-previous.ts @@ -1,7 +1,7 @@ import { useRef, useEffect } from 'react'; const usePrevious = (value: string) => { - const reference = useRef(null); + const reference = useRef(null); useEffect(() => { reference.current = value; }); diff --git a/src/app/views/query-runner/request/Request.tsx b/src/app/views/query-runner/request/Request.tsx index 04f3581ff7..3452398ed8 100644 --- a/src/app/views/query-runner/request/Request.tsx +++ b/src/app/views/query-runner/request/Request.tsx @@ -15,18 +15,27 @@ import { convertPxToVh, convertVhToPx } from '../../common/dimensions/dimensions import { Auth, Permissions, RequestHeaders } from '../../common/lazy-loader/component-registry'; import { RequestBody } from './body'; import './request.scss'; +import { IQuery } from '../../../../types/query-runner'; -const Request = (props: any) => { +interface IRequestProps { + handleOnEditorChange: ()=> void + sampleQuery: IQuery +} + +const Request = (props: IRequestProps) => { const dispatch = useAppDispatch(); const [selectedPivot, setSelectedPivot] = useState('request-body'); - const { graphExplorerMode: mode, dimensions, sidebarProperties } = useAppSelector((state) => state); + const mode = useAppSelector((state)=> state.graphExplorerMode); + const dimensions= useAppSelector((state)=> state.dimensions); + const sidebarProperties = useAppSelector((state)=> state.sidebarProperties); const pivot = selectedPivot.replace('.$', ''); const minHeight = 60; const maxHeight = 800; const { - handleOnEditorChange - }: any = props; + handleOnEditorChange, + sampleQuery + }: IRequestProps = props; useEffect(() => { if(sidebarProperties && sidebarProperties.mobileScreen){ @@ -129,7 +138,6 @@ const Request = (props: any) => { const onPivotItemClick = (item?: PivotItem) => { if (!item) { return; } const tabKey = item.props.itemKey; - const { sampleQuery }: any = props; if (tabKey) { telemetry.trackTabClickEvent(tabKey, sampleQuery); } diff --git a/src/app/views/query-runner/request/body/RequestBody.tsx b/src/app/views/query-runner/request/body/RequestBody.tsx index 6137285730..3d7f1d2fbc 100644 --- a/src/app/views/query-runner/request/body/RequestBody.tsx +++ b/src/app/views/query-runner/request/body/RequestBody.tsx @@ -4,13 +4,18 @@ import { useAppSelector } from '../../../../../store'; import { Monaco } from '../../../common'; import { convertVhToPx } from '../../../common/dimensions/dimensions-adjustment'; -const RequestBody = ({ handleOnEditorChange }: any) => { - const { dimensions: { request: { height } }, sampleQuery } = useAppSelector((state) => state); +interface IRequestBodyProps { + handleOnEditorChange: (v: string | undefined)=> void; +} + +const RequestBody = ({ handleOnEditorChange }: IRequestBodyProps) => { + const height = useAppSelector((state)=> state.dimensions.request.height); + const sampleBody = useAppSelector((state)=> state.sampleQuery.sampleBody); return ( handleOnEditorChange(value)} /> diff --git a/src/app/views/query-runner/request/feedback/FeedbackForm.tsx b/src/app/views/query-runner/request/feedback/FeedbackForm.tsx index 0aea13041c..60ad8ada85 100644 --- a/src/app/views/query-runner/request/feedback/FeedbackForm.tsx +++ b/src/app/views/query-runner/request/feedback/FeedbackForm.tsx @@ -20,7 +20,7 @@ export default function FeedbackForm({ activated, onDismissSurvey, onDisableSurv const [officeBrowserFeedback, setOfficeBrowserFeedback] = useState(undefined); const currentTheme = getTheme(); const { NODE_ENV } = process.env; - const { profile: { user } } = useAppSelector((state) => state); + const user = useAppSelector((state) => state.profile.user); function surveyActivated(launcher: any, surveyItem: any) { return surveyItem; diff --git a/src/app/views/sidebar/sample-queries/SampleQueries.tsx b/src/app/views/sidebar/sample-queries/SampleQueries.tsx index 6ca6493c4b..4df6eb46b4 100644 --- a/src/app/views/sidebar/sample-queries/SampleQueries.tsx +++ b/src/app/views/sidebar/sample-queries/SampleQueries.tsx @@ -30,8 +30,9 @@ import { const UnstyledSampleQueries = (sampleProps?: ISampleQueriesProps): JSX.Element => { const [selectedQuery, setSelectedQuery] = useState(null) - const { auth: { authToken }, profile, samples } = - useAppSelector((state) => state); + const authToken = useAppSelector((state) => state.auth.authToken); + const profile = useAppSelector((state) => state.profile); + const samples = useAppSelector((state) => state.samples); const tokenPresent = authToken.token; const [sampleQueries, setSampleQueries] = useState(samples.queries); const [groups, setGroups] = useState([]);