diff --git a/client/.env b/client/.env index a2d09f3b312..2f5d271b1e4 100644 --- a/client/.env +++ b/client/.env @@ -1,3 +1,3 @@ VITE_API_URL=/otp/transmodel/v3 VITE_DEBUG_STYLE_URL=/otp/routers/default/inspector/vectortile/style.json - +VITE_GRAPHIQL_URL=/graphiql?flavor=transmodel diff --git a/client/.env.development b/client/.env.development index 35840c239bd..1cb7d9235e3 100644 --- a/client/.env.development +++ b/client/.env.development @@ -1,2 +1,3 @@ VITE_API_URL=http://localhost:8080/otp/transmodel/v3 -VITE_DEBUG_STYLE_URL=http://localhost:8080/otp/routers/default/inspector/vectortile/style.json \ No newline at end of file +VITE_DEBUG_STYLE_URL=http://localhost:8080/otp/routers/default/inspector/vectortile/style.json +VITE_GRAPHIQL_URL=http://localhost:8080/graphiql?flavor=transmodel \ No newline at end of file diff --git a/client/src/components/ItineraryList/ItineraryGraphiQLAuthorityLink.tsx b/client/src/components/ItineraryList/ItineraryGraphiQLAuthorityLink.tsx new file mode 100644 index 00000000000..8ec3e1353ec --- /dev/null +++ b/client/src/components/ItineraryList/ItineraryGraphiQLAuthorityLink.tsx @@ -0,0 +1,25 @@ +import { authorityQueryAsString } from '../../static/query/authorityQuery.tsx'; +import { Maybe } from '../../gql/graphql.ts'; +const graphiQLUrl = import.meta.env.VITE_GRAPHIQL_URL; + +export function ItineraryGraphiQLAuthorityLink({ + legId, + legName, +}: { + legId: string | undefined; + legName: Maybe | undefined; +}) { + const queryID = { id: legId }; + const formattedQuery = encodeURIComponent(authorityQueryAsString); + const formattedQueryID = encodeURIComponent(JSON.stringify(queryID)); + + return ( + + {legName} + + ); +} diff --git a/client/src/components/ItineraryList/ItineraryGraphiQLLineLink.tsx b/client/src/components/ItineraryList/ItineraryGraphiQLLineLink.tsx new file mode 100644 index 00000000000..f54f61a204b --- /dev/null +++ b/client/src/components/ItineraryList/ItineraryGraphiQLLineLink.tsx @@ -0,0 +1,18 @@ +import { lineQueryAsString } from '../../static/query/lineQuery.tsx'; +const graphiQLUrl = import.meta.env.VITE_GRAPHIQL_URL; + +export function ItineraryGraphiQLLineLink({ legId, legName }: { legId: string; legName: string }) { + const queryID = { id: legId }; + const formattedQuery = encodeURIComponent(lineQueryAsString); + const formattedQueryID = encodeURIComponent(JSON.stringify(queryID)); + + return ( + + {legName} + + ); +} diff --git a/client/src/components/ItineraryList/ItineraryGraphiQLQuayLink.tsx b/client/src/components/ItineraryList/ItineraryGraphiQLQuayLink.tsx new file mode 100644 index 00000000000..795cecd0703 --- /dev/null +++ b/client/src/components/ItineraryList/ItineraryGraphiQLQuayLink.tsx @@ -0,0 +1,25 @@ +import { quayQueryAsString } from '../../static/query/quayQuery.tsx'; +import { Maybe } from '../../gql/graphql.ts'; +const graphiQLUrl = import.meta.env.VITE_GRAPHIQL_URL; + +export function ItineraryGraphiQLQuayLink({ + legId, + legName, +}: { + legId: string | undefined; + legName: Maybe | undefined; +}) { + const queryID = { id: legId }; + const formattedQuery = encodeURIComponent(quayQueryAsString); + const formattedQueryID = encodeURIComponent(JSON.stringify(queryID)); + + return ( + + {legName} + + ); +} diff --git a/client/src/components/ItineraryList/ItineraryLegDetails.tsx b/client/src/components/ItineraryList/ItineraryLegDetails.tsx index e75813a4a45..51f0821b3e4 100644 --- a/client/src/components/ItineraryList/ItineraryLegDetails.tsx +++ b/client/src/components/ItineraryList/ItineraryLegDetails.tsx @@ -3,6 +3,9 @@ import { LegTime } from './LegTime.tsx'; import { formatDistance } from '../../util/formatDistance.ts'; import { formatDuration } from '../../util/formatDuration.ts'; import { InterchangeInfo } from './InterchangeInfo.tsx'; +import { ItineraryGraphiQLLineLink } from './ItineraryGraphiQLLineLink.tsx'; +import { ItineraryGraphiQLQuayLink } from './ItineraryGraphiQLQuayLink.tsx'; +import { ItineraryGraphiQLAuthorityLink } from './ItineraryGraphiQLAuthorityLink.tsx'; export function ItineraryLegDetails({ leg, isLast }: { leg: Leg; isLast: boolean }) { return ( @@ -17,19 +20,20 @@ export function ItineraryLegDetails({ leg, isLast }: { leg: Leg; isLast: boolean {leg.mode}{' '} {leg.line && ( <> - - {leg.line.publicCode} {leg.toEstimatedCall?.destinationDisplay?.frontText} - - , {leg.authority?.name} + + , )}{' '} {leg.mode !== Mode.Foot && ( <>
- {leg.fromPlace.name} →{' '} + →{' '} )}{' '} - {!isLast && {leg.toPlace.name}} + {!isLast && } ); diff --git a/client/src/components/SearchBar/GraphiQLRouteButton.tsx b/client/src/components/SearchBar/GraphiQLRouteButton.tsx new file mode 100644 index 00000000000..550964dd5a8 --- /dev/null +++ b/client/src/components/SearchBar/GraphiQLRouteButton.tsx @@ -0,0 +1,18 @@ +import { Button } from 'react-bootstrap'; +import { TripQueryVariables } from '../../gql/graphql.ts'; +import { queryAsString } from '../../static/query/tripQuery.tsx'; +const graphiQLUrl = import.meta.env.VITE_GRAPHIQL_URL; + +function GraphiQLRouteButton({ tripQueryVariables }: { tripQueryVariables: TripQueryVariables }) { + const formattedVariables = encodeURIComponent(JSON.stringify(tripQueryVariables)); + const formattedQuery = encodeURIComponent(queryAsString); + + return ( +
+ +
+ ); +} +export default GraphiQLRouteButton; diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index dbdb5db29bf..dfcbc6ac36e 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -15,6 +15,7 @@ import Navbar from 'react-bootstrap/Navbar'; import { ServerInfoTooltip } from './ServerInfoTooltip.tsx'; import { useRef, useState } from 'react'; import logo from '../../static/img/otp-logo.svg'; +import GraphiQLRouteButton from './GraphiQLRouteButton.tsx'; type SearchBarProps = { onRoute: () => void; @@ -61,6 +62,7 @@ export function SearchBar({ onRoute, tripQueryVariables, setTripQueryVariables, Route + ); } diff --git a/client/src/hooks/useTripQuery.ts b/client/src/hooks/useTripQuery.ts index e50e7019b66..5ff6fc80a1f 100644 --- a/client/src/hooks/useTripQuery.ts +++ b/client/src/hooks/useTripQuery.ts @@ -1,96 +1,12 @@ import { useCallback, useEffect, useState } from 'react'; -import { graphql } from '../gql'; import { request } from 'graphql-request'; // eslint-disable-line import/no-unresolved import { QueryType, TripQueryVariables } from '../gql/graphql.ts'; import { getApiUrl } from '../util/getApiUrl.ts'; +import { query } from '../static/query/tripQuery.tsx'; /** General purpose trip query document for debugging trip searches - TODO: should live in a separate file, and split into fragments for readability */ -const query = graphql(` - query trip( - $from: Location! - $to: Location! - $arriveBy: Boolean - $dateTime: DateTime - $numTripPatterns: Int - $searchWindow: Int - $modes: Modes - $itineraryFiltersDebug: ItineraryFilterDebugProfile - $pageCursor: String - ) { - trip( - from: $from - to: $to - arriveBy: $arriveBy - dateTime: $dateTime - numTripPatterns: $numTripPatterns - searchWindow: $searchWindow - modes: $modes - itineraryFilters: { debug: $itineraryFiltersDebug } - pageCursor: $pageCursor - ) { - previousPageCursor - nextPageCursor - tripPatterns { - aimedStartTime - aimedEndTime - expectedEndTime - expectedStartTime - duration - distance - legs { - id - mode - aimedStartTime - aimedEndTime - expectedEndTime - expectedStartTime - realtime - distance - duration - fromPlace { - name - quay { - id - } - } - toPlace { - name - quay { - id - } - } - toEstimatedCall { - destinationDisplay { - frontText - } - } - line { - publicCode - name - } - authority { - name - } - pointsOnLink { - points - } - interchangeTo { - staySeated - } - interchangeFrom { - staySeated - } - } - systemNotices { - tag - } - } - } - } -`); type TripQueryHook = ( variables?: TripQueryVariables, @@ -126,6 +42,5 @@ export const useTripQuery: TripQueryHook = (variables) => { } // eslint-disable-next-line react-hooks/exhaustive-deps }, [variables?.from, variables?.to]); - return [data, loading, callback]; }; diff --git a/client/src/static/query/authorityQuery.tsx b/client/src/static/query/authorityQuery.tsx new file mode 100644 index 00000000000..e5ff99b133d --- /dev/null +++ b/client/src/static/query/authorityQuery.tsx @@ -0,0 +1,13 @@ +import { graphql } from '../../gql'; +import { print } from 'graphql/index'; + +export const query = graphql(` + query authority($id: String!) { + authority(id: $id) { + name + id + } + } +`); + +export const authorityQueryAsString = print(query); diff --git a/client/src/static/query/lineQuery.tsx b/client/src/static/query/lineQuery.tsx new file mode 100644 index 00000000000..4a3a9826a39 --- /dev/null +++ b/client/src/static/query/lineQuery.tsx @@ -0,0 +1,13 @@ +import { graphql } from '../../gql'; +import { print } from 'graphql/index'; + +export const query = graphql(` + query line($id: ID!) { + line(id: $id) { + name + publicCode + } + } +`); + +export const lineQueryAsString = print(query); diff --git a/client/src/static/query/quayQuery.tsx b/client/src/static/query/quayQuery.tsx new file mode 100644 index 00000000000..e4ab9af3146 --- /dev/null +++ b/client/src/static/query/quayQuery.tsx @@ -0,0 +1,15 @@ +import { graphql } from '../../gql'; +import { print } from 'graphql/index'; + +export const query = graphql(` + query quay($id: String!) { + quay(id: $id) { + stopPlace { + id + name + } + } + } +`); + +export const quayQueryAsString = print(query); diff --git a/client/src/static/query/tripQuery.tsx b/client/src/static/query/tripQuery.tsx new file mode 100644 index 00000000000..ccb19dc745e --- /dev/null +++ b/client/src/static/query/tripQuery.tsx @@ -0,0 +1,90 @@ +import { graphql } from '../../gql'; +import { print } from 'graphql/index'; + +export const query = graphql(` + query trip( + $from: Location! + $to: Location! + $arriveBy: Boolean + $dateTime: DateTime + $numTripPatterns: Int + $searchWindow: Int + $modes: Modes + $itineraryFiltersDebug: ItineraryFilterDebugProfile + $pageCursor: String + ) { + trip( + from: $from + to: $to + arriveBy: $arriveBy + dateTime: $dateTime + numTripPatterns: $numTripPatterns + searchWindow: $searchWindow + modes: $modes + itineraryFilters: { debug: $itineraryFiltersDebug } + pageCursor: $pageCursor + ) { + previousPageCursor + nextPageCursor + tripPatterns { + aimedStartTime + aimedEndTime + expectedEndTime + expectedStartTime + duration + distance + legs { + id + mode + aimedStartTime + aimedEndTime + expectedEndTime + expectedStartTime + realtime + distance + duration + fromPlace { + name + quay { + id + } + } + toPlace { + name + quay { + id + } + } + toEstimatedCall { + destinationDisplay { + frontText + } + } + line { + publicCode + name + id + } + authority { + name + id + } + pointsOnLink { + points + } + interchangeTo { + staySeated + } + interchangeFrom { + staySeated + } + } + systemNotices { + tag + } + } + } + } +`); + +export const queryAsString = print(query);