From 8a93e6c897c37f857d1bc86cb04cfe3ac9c2bf16 Mon Sep 17 00:00:00 2001 From: Elena Shorohova Date: Wed, 30 Apr 2025 14:15:18 +0300 Subject: [PATCH 1/4] Unified components --- .../list-of-apis/react/runtime/ApisCards.tsx | 34 +------- .../react/runtime/OperationDetails.tsx | 24 +++--- .../react/runtime/OperationDetailsGql.tsx | 23 +++--- .../runtime/OperationDetailsWebsocket.tsx | 79 ++++++++++--------- .../react/runtime/OperationRepresentation.tsx | 20 +++-- .../react/runtime/TypeDefinitions.tsx | 12 +-- .../react/runtime/TypeDefinitionsGql.tsx | 10 +-- .../react/runtime/OperationList.tsx | 75 +++--------------- .../widgets/fui/apis-products-lists.scss | 1 - .../styles/widgets/fui/operation-details.scss | 15 +++- .../website/styles/widgets/widgets.scss | 2 + 11 files changed, 111 insertions(+), 184 deletions(-) diff --git a/src/components/apis/list-of-apis/react/runtime/ApisCards.tsx b/src/components/apis/list-of-apis/react/runtime/ApisCards.tsx index 10227bda3..b5b928f0d 100644 --- a/src/components/apis/list-of-apis/react/runtime/ApisCards.tsx +++ b/src/components/apis/list-of-apis/react/runtime/ApisCards.tsx @@ -1,10 +1,8 @@ import * as React from "react"; import { useState } from "react"; -import { Stack } from "@fluentui/react"; +import { ApiCard } from "@microsoft/api-docs-ui"; import { Api } from "../../../../../models/api"; import { TagGroup } from "../../../../../models/tagGroup"; -import { MarkdownProcessor } from "../../../../utils/react/MarkdownProcessor"; -import { markdownMaxCharsMap } from "../../../../../constants"; import { isApisGrouped, toggleValueInSet, TagGroupToggleBtn, TApisData } from "./utils"; type Props = { @@ -13,36 +11,6 @@ type Props = { detailsPageTarget: string; }; -const ApiCard = ({ api, getReferenceUrl, showApiType, detailsPageTarget }: Props & { api: Api }) => { - return ( -
-
- {showApiType && ( -
- API - {api.typeName} -
- )} -

{api.displayName}

- - -
- - - - Go to API - - -
- ); -}; - const ApisCardsContainer = ({ apis, ...props }: Props & { apis: Api[] }) => ( <> {apis?.length > 0 diff --git a/src/components/operations/operation-details/react/runtime/OperationDetails.tsx b/src/components/operations/operation-details/react/runtime/OperationDetails.tsx index caa8841c6..ffe73f352 100644 --- a/src/components/operations/operation-details/react/runtime/OperationDetails.tsx +++ b/src/components/operations/operation-details/react/runtime/OperationDetails.tsx @@ -17,6 +17,7 @@ import { Tooltip, } from "@fluentui/react-components"; import { Copy16Regular } from "@fluentui/react-icons"; +import { InfoPanel } from "@microsoft/api-docs-ui"; import { RouteHelper } from "../../../../../routing/routeHelper"; import { ApiService } from "../../../../../services/apiService"; import { UsersService } from "../../../../../services/usersService"; @@ -369,10 +370,9 @@ export const OperationDetails = ({ sessionManager={sessionManager} httpClient={httpClient} /> -
-
- Endpoint: - {tags.length > 0 && ( + 0 && ( ))} - )} -
-
-
- + ) + } + children={ +
+ {operation.method} @@ -421,8 +419,8 @@ export const OperationDetails = ({ />
-
-
+ } + /> {enableConsole && (
diff --git a/src/components/operations/operation-details/react/runtime/OperationDetailsWebsocket.tsx b/src/components/operations/operation-details/react/runtime/OperationDetailsWebsocket.tsx index e337761b7..0de6de370 100644 --- a/src/components/operations/operation-details/react/runtime/OperationDetailsWebsocket.tsx +++ b/src/components/operations/operation-details/react/runtime/OperationDetailsWebsocket.tsx @@ -6,6 +6,7 @@ import { HttpClient } from "@paperbits/common/http/httpClient"; import { Stack } from "@fluentui/react"; import { Badge, Button, Spinner, Tooltip } from "@fluentui/react-components"; import { Copy16Regular } from "@fluentui/react-icons"; +import { InfoPanel } from "@microsoft/api-docs-ui"; import { Operation } from "../../../../../models/operation"; import { Api } from "../../../../../models/api"; import { Tag } from "../../../../../models/tag"; @@ -119,6 +120,16 @@ export const OperationDetailsWebsocket = ({ : !operation ? No operation selected. :
+

+ {operation.displayName} +

+ {operation.description && ( +
+ +
+ )} -
-
-
{operation.displayName}
- {operation.description && -
- -
- } - {tags.length > 0 && + 0 && Tags: {tags.map(tag => {tag.name})} - } -
-
-
- Socket URL - {requestUrl} - -
- {api.protocols && + } + children={ + <>
- Protocol - {api.protocols.join(", ")} + Socket URL + {requestUrl} + +
- } -
-
+ {api.protocols && +
+ Protocol + {api.protocols.join(", ")} +
+ } + + } + /> {enableConsole && }
} diff --git a/src/components/operations/operation-details/react/runtime/OperationRepresentation.tsx b/src/components/operations/operation-details/react/runtime/OperationRepresentation.tsx index 80d1cbac4..56b866743 100644 --- a/src/components/operations/operation-details/react/runtime/OperationRepresentation.tsx +++ b/src/components/operations/operation-details/react/runtime/OperationRepresentation.tsx @@ -2,13 +2,13 @@ import * as React from "react"; import { useEffect, useState } from "react"; import { Stack } from "@fluentui/react"; import { Dropdown, Option, Tab, TabList } from "@fluentui/react-components"; +import { RawSchema } from "@microsoft/api-docs-ui"; import { KnownMimeTypes } from "../../../../../models/knownMimeTypes"; import { Representation } from "../../../../../models/representation"; import { TypeDefinition } from "../../../../../models/typeDefinition"; import { RepresentationExample } from "../../../../../models/representationExample"; import { Utils } from "../../../../../utils"; import { OperationDetailsTable } from "./utils"; -import { CodeSnippet } from "../../../../utils/react/CodeSnippet"; import { TypeDefinitionForRepresentation } from "./TypeDefinitions"; type OperationRepresentationProps = { @@ -67,7 +67,7 @@ export const OperationRepresentation = ({ definitions, representations, showExam selectedOptions={[selectedRepresentation.contentType]} size="small" className={"operation-content-type-dropdown"} - onOptionSelect={(e, data) => { + onOptionSelect={(_, data) => { const newSelectedRepresentation = representations.find(x => x.contentType === data.optionValue); setSelectedRepresentation(newSelectedRepresentation); newSelectedRepresentation.contentType === KnownMimeTypes.FormData && setSchemaView(TSchemaView.table); @@ -88,10 +88,10 @@ export const OperationRepresentation = ({ definitions, representations, showExam /> : selectedRepresentationDefinition && (schemaView === TSchemaView.schema - ? : + onTabSelect={(_, data: { value: string }) => setSelectedRepresentationExample(selectedRepresentation.examples.find(x => x.title === data.value)) }> {selectedRepresentation.examples.map(example => ( @@ -113,7 +113,11 @@ export const OperationRepresentation = ({ definitions, representations, showExam ))} - + } diff --git a/src/components/operations/operation-details/react/runtime/TypeDefinitions.tsx b/src/components/operations/operation-details/react/runtime/TypeDefinitions.tsx index b72d22302..a447852f8 100644 --- a/src/components/operations/operation-details/react/runtime/TypeDefinitions.tsx +++ b/src/components/operations/operation-details/react/runtime/TypeDefinitions.tsx @@ -2,10 +2,10 @@ import * as React from "react"; import { useState } from "react"; import { Stack } from "@fluentui/react"; import { Tab, TabList, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TableRow } from "@fluentui/react-components"; +import { RawSchema } from "@microsoft/api-docs-ui"; import { TypeDefinition, TypeDefinitionPropertyTypeCombination } from "../../../../../models/typeDefinition"; import { MarkdownProcessor } from "../../../../utils/react/MarkdownProcessor"; import { ScrollableTableContainer } from "../../../../utils/react/ScrollableTableContainer"; -import { CodeSnippet } from "../../../../utils/react/CodeSnippet"; import { TSchemaView } from "./OperationRepresentation"; type TypeDefinitionProps = { @@ -46,11 +46,11 @@ export const TypeDefinitionInList = ({ definition, showExamples, getReferenceUrl {schemaView === TSchemaView.schema - ? + ? : {schemaView === TSchemaView.schema - ? : ( - selectOperation(operation)} - onKeyDown={e => e.key === "Enter" && selectOperation(operation)} - tabIndex={0} - > - {operation.name === selectedOperationName - ? <> - - {operation.method} - - - {showUrlPath ? operation.urlTemplate : operation.displayName} - - - : <> - - {operation.method} - - - {showUrlPath ? operation.urlTemplate : operation.displayName} - - - } - - ) - return (
@@ -329,37 +295,14 @@ export const OperationList = ({ {working ? : <> - {groupByTag - ? <> - {(!operationsByTags || operationsByTags.length === 0) - ? No operations found. - : - {operationsByTags.map((tag, index) => ( - - {tag.tag} - - {tag.items.map(operation => - renderOperation(operation) - )} - - - ))} - - } - - : <> - {(!operations || operations.length <= 0) - ? No operations found. - : operations.map(operation => - renderOperation(operation) - ) - } - - } + {hasNextPage && setPageNumber(prev => prev + 1)}>Show more} } diff --git a/src/themes/website/styles/widgets/fui/apis-products-lists.scss b/src/themes/website/styles/widgets/fui/apis-products-lists.scss index 3a090660b..f290219a8 100644 --- a/src/themes/website/styles/widgets/fui/apis-products-lists.scss +++ b/src/themes/website/styles/widgets/fui/apis-products-lists.scss @@ -17,7 +17,6 @@ .fui-list-cards-container { display: grid; - width: 1100px; /* TODO */ grid-template-columns: 1fr 1fr 1fr; gap: 1.5rem; margin-top: 1.5rem; diff --git a/src/themes/website/styles/widgets/fui/operation-details.scss b/src/themes/website/styles/widgets/fui/operation-details.scss index 68c54aef6..e0c06b612 100644 --- a/src/themes/website/styles/widgets/fui/operation-details.scss +++ b/src/themes/website/styles/widgets/fui/operation-details.scss @@ -10,6 +10,16 @@ fui-operation-details { .operation-details-content { max-width: 800px; + + .ws-info-panel { + > div { + padding: 0; + } + + .operation-table-body-row { + padding: 1rem; + } + } } .operation-description { @@ -21,7 +31,7 @@ fui-operation-details { } .operation-tags { - padding-top: 1rem; + padding: 1rem 0; > * { margin-right: .5rem; @@ -119,8 +129,7 @@ fui-operation-details { } } -.operation-table-body-row { - padding: 1rem; +.operation-table-body-row { display: flex; align-items: center; diff --git a/src/themes/website/styles/widgets/widgets.scss b/src/themes/website/styles/widgets/widgets.scss index 301ff28b5..0ce1c499a 100644 --- a/src/themes/website/styles/widgets/widgets.scss +++ b/src/themes/website/styles/widgets/widgets.scss @@ -18,3 +18,5 @@ @import "fui/operation-details.scss"; @import "fui/apis-products-lists.scss"; @import "fui/reports.scss"; + +@import '@microsoft/api-docs-ui/dist/index.css'; \ No newline at end of file From d25028aa8a4cdc0f27134f6b5e45749a20c64d1a Mon Sep 17 00:00:00 2001 From: Elena Shorohova Date: Thu, 1 May 2025 19:47:57 +0300 Subject: [PATCH 2/4] Unified components - tables --- .../react/runtime/ApiHistory.tsx | 39 ++-- .../list-of-apis/react/runtime/ApisTable.tsx | 62 ++---- .../react/runtime/OperationDetails.tsx | 110 ++++------ .../react/runtime/OperationDetailsGql.tsx | 172 ++++++--------- .../react/runtime/TypeDefinitions.tsx | 142 ++++++------- .../react/runtime/TypeDefinitionsGql.tsx | 85 ++++---- .../ConsoleRequestResponse.tsx | 35 +--- .../operation-console/ConsoleWsLogItems.tsx | 66 +++--- .../operation-details/react/runtime/utils.tsx | 70 ++----- .../react/runtime/ProductsTable.tsx | 42 ++-- .../runtime/ProductSubscriptionsTable.tsx | 45 ++-- .../profile/react/runtime/ProfileTable.tsx | 196 ++++++++---------- .../react/runtime/SubscriptionsTable.tsx | 85 ++------ .../website/styles/widgets/fui/fluentui.scss | 5 + 14 files changed, 406 insertions(+), 748 deletions(-) diff --git a/src/components/apis/history-of-api/react/runtime/ApiHistory.tsx b/src/components/apis/history-of-api/react/runtime/ApiHistory.tsx index 60d655009..47ed1e230 100644 --- a/src/components/apis/history-of-api/react/runtime/ApiHistory.tsx +++ b/src/components/apis/history-of-api/react/runtime/ApiHistory.tsx @@ -3,15 +3,14 @@ import { useEffect, useState } from "react"; import { Resolve } from "@paperbits/react/decorators"; import { Router } from "@paperbits/common/routing"; import { Stack } from "@fluentui/react"; -import { FluentProvider, Spinner, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TableRow } from "@fluentui/react-components"; +import { FluentProvider, Spinner, TableCell, TableRow } from "@fluentui/react-components"; +import { InfoTable } from "@microsoft/api-docs-ui"; import { Api } from "../../../../../models/api"; import { Page } from "../../../../../models/page"; import { ChangeLogContract } from "../../../../../contracts/apiChangeLog"; import { ApiService } from "../../../../../services/apiService"; import { RouteHelper } from "../../../../../routing/routeHelper"; import { Pagination } from "../../../../utils/react/Pagination"; -import { NoRecordsRow } from "../../../../utils/react/NoRecordsRow"; -import { ScrollableTableContainer } from "../../../../utils/react/ScrollableTableContainer"; import { defaultPageSize, fuiTheme } from "../../../../../constants"; import { Utils } from "../../../../../utils"; @@ -91,27 +90,19 @@ const ApiHistoryFC = ({ Go back to the API reference page } - - - - - Release date - Notes - - - - {currentChangelogPage?.value?.length > 0 - ? currentChangelogPage.value.map((changelog, index) => ( - - {Utils.formatDateTime(changelog.createdDateTime)} - {changelog.notes} - - )) - : - } - -
-
+ 0 + && currentChangelogPage.value.map((changelog, index) => ( + + {Utils.formatDateTime(changelog.createdDateTime)} + {changelog.notes} + + )) + } + noDataMessage="No records to show" + /> {currentChangelogPage?.count > 1 &&
diff --git a/src/components/apis/list-of-apis/react/runtime/ApisTable.tsx b/src/components/apis/list-of-apis/react/runtime/ApisTable.tsx index 9fd76d4e0..dda66f924 100644 --- a/src/components/apis/list-of-apis/react/runtime/ApisTable.tsx +++ b/src/components/apis/list-of-apis/react/runtime/ApisTable.tsx @@ -1,19 +1,12 @@ import * as React from "react"; import { useState } from "react"; -import { - Table, - TableBody, - TableCell, - TableHeader, - TableHeaderCell, - TableRow, -} from "@fluentui/react-components"; +import { TableCell, TableRow } from "@fluentui/react-components"; +import { InfoTable } from "@microsoft/api-docs-ui"; import { Api } from "../../../../../models/api"; import { Page } from "../../../../../models/page"; import { TagGroup } from "../../../../../models/tagGroup"; import { MarkdownProcessor } from "../../../../utils/react/MarkdownProcessor"; import { NoRecordsRow } from "../../../../utils/react/NoRecordsRow"; -import { ScrollableTableContainer } from "../../../../utils/react/ScrollableTableContainer"; import { markdownMaxCharsMap } from "../../../../../constants"; import { isApisGrouped, @@ -88,38 +81,23 @@ const TableBodyTags = ({ tags, ...props }: Props & { tags: Page> } ); }; -export const ApisTable = ({ apis, ...props }: Props & { apis: TApisData }) => ( - - - - - - Name - - - Description - - {props.showApiType && ( - - Type - - )} - - +export const ApisTable = ({ apis, ...props }: Props & { apis: TApisData }) => { + const tableColumns = ["Name", "Description"]; + props.showApiType && tableColumns.push("Type"); - - {isApisGrouped(apis) ? ( - + return ( + ) : ( - - )} - -
-
-); + + ) + } + noDataMessage="No APIs to display" + /> + ); +} diff --git a/src/components/operations/operation-details/react/runtime/OperationDetails.tsx b/src/components/operations/operation-details/react/runtime/OperationDetails.tsx index ffe73f352..63e3dcd12 100644 --- a/src/components/operations/operation-details/react/runtime/OperationDetails.tsx +++ b/src/components/operations/operation-details/react/runtime/OperationDetails.tsx @@ -4,20 +4,9 @@ import { ISettingsProvider } from "@paperbits/common/configuration"; import { SessionManager } from "@paperbits/common/persistence/sessionManager"; import { HttpClient } from "@paperbits/common/http/httpClient"; import { Stack } from "@fluentui/react"; -import { - Badge, - Button, - Spinner, - Table, - TableBody, - TableCell, - TableHeader, - TableHeaderCell, - TableRow, - Tooltip, -} from "@fluentui/react-components"; +import { Badge, Button, Spinner, TableCell, TableRow, Tooltip } from "@fluentui/react-components"; import { Copy16Regular } from "@fluentui/react-icons"; -import { InfoPanel } from "@microsoft/api-docs-ui"; +import { InfoPanel, InfoTable } from "@microsoft/api-docs-ui"; import { RouteHelper } from "../../../../../routing/routeHelper"; import { ApiService } from "../../../../../services/apiService"; import { UsersService } from "../../../../../services/usersService"; @@ -38,7 +27,6 @@ import { TypeDefinitionPropertyTypeReference, } from "../../../../../models/typeDefinition"; import { MarkdownProcessor } from "../../../../utils/react/MarkdownProcessor"; -import { ScrollableTableContainer } from "../../../../utils/react/ScrollableTableContainer"; import { OperationDetailsRuntimeProps } from "./OperationDetailsRuntime"; import { OperationRepresentation, @@ -464,7 +452,6 @@ export const OperationDetails = ({ tableContent={request.headers} showExamples={showExamples} showIn={false} - isHeaders={true} /> )} @@ -542,66 +529,47 @@ export const OperationDetails = ({

Definitions

- - - + ( - - - Name - - - - - Description - - - - - - {definitions.map((definition) => ( - - - - {definition.name} - - - - + + {definition.name} + + + + + - - - - - ))} - -
-
+ maxChars={250} + truncate={true} + /> + + + + )) + } + /> {definitions.map((definition) => (
{schemaView === TSchemaView.table ? ( - - - - - - - Name - - - - - Type - - - - - Description - - - - - - {graph.args.map((arg) => ( - ( + + + {arg.name} + + + {getGraphType(arg.type)} + + +
- - {arg.name} - - - {getGraphType(arg.type)} - - -
- -
-
- - ))} - -
-
+ +
+ + + ))} + /> ) : ( Types - - - + ( - - - Name - - - - - Description - - - - - - {references.map((reference) => ( - - - {getGraphType(reference)} - - -
+ {getGraphType(reference)} + + +
+ - -
-
- - ))} - -
-
+ maxChars={250} + truncate={true} + /> +
+ + + )) + } + /> {references.map((reference) => (
{ const enumValues = definition.enum.join(", "); return ( - - - - - Type - Values - - - - - {definition.type["name"]} - {enumValues} - - -
-
+ + + {enumValues} + + } + /> ); } @@ -131,67 +124,60 @@ const TypeDefinitionEnum = ({ definition }: TypeDefinitionProps) => { const TypeDefinitionObject = ({ definition, showExamples, getReferenceUrl }: TypeDefinitionProps) => { if (!definition.properties || definition.properties.length === 0) return; + /** This is needed to ensure the right order of columns */ + const columnLabels = ["Name", "Required", "Type", "Description"]; + if (definition.readOnly) columnLabels.splice(2, 0, "Read-only"); + if (showExamples) columnLabels.push("Example"); + return ( - - - - - Name - Required - {definition.readOnly && Read-only} - Type - Description - {showExamples && Example} - - - - {definition.properties.map(property => { - let type: JSX.Element; - const typeName = property.type["name"]; - - if (property.type.displayAs === TPropertyDisplayAs.combination) { - let children = [
{property.type["combinationType"]}:
]; - - property.type["combination"].map(combinationProperty => { - const combinationName = combinationProperty["name"]; - - if (combinationProperty["displayAs"] === TPropertyDisplayAs.reference) { - children.push( - - ); - } else { - children.push(
{combinationName}
); - } - }); - - type = <>{children}; - } else if (property.type.displayAs === TPropertyDisplayAs.reference || property.type.displayAs === TPropertyDisplayAs.arrayOfReference) { - type = {typeName + (property.type.displayAs === TPropertyDisplayAs.arrayOfReference ? "[]" : "")}; + { + let type: JSX.Element; + const typeName = property.type["name"]; + + if (property.type.displayAs === TPropertyDisplayAs.combination) { + let children = [
{property.type["combinationType"]}:
]; + + property.type["combination"].map(combinationProperty => { + const combinationName = combinationProperty["name"]; + + if (combinationProperty["displayAs"] === TPropertyDisplayAs.reference) { + children.push( + + ); } else { - type = {typeName + (property.type.displayAs === TPropertyDisplayAs.arrayOfPrimitive ? "[]" : "")}; + children.push(
{combinationName}
); + } + }); + + type = <>{children}; + } else if (property.type.displayAs === TPropertyDisplayAs.reference || property.type.displayAs === TPropertyDisplayAs.arrayOfReference) { + type = {typeName + (property.type.displayAs === TPropertyDisplayAs.arrayOfReference ? "[]" : "")}; + } else { + type = {typeName + (property.type.displayAs === TPropertyDisplayAs.arrayOfPrimitive ? "[]" : "")}; + } + + return ( + + {property.name} + + {definition.readOnly && {property.readOnly}} + +
+ +
+ {showExamples && + + {!!property.example && {property.example}} + } - - return ( - - {property.name} - {property.required ? "true" : "false"} - {definition.readOnly && {property.readOnly}} - {type} -
- -
- {showExamples && - - {!!property.example && {property.example}} - - } -
- ); - })} -
-
-
+ + ); + })} + /> ); } diff --git a/src/components/operations/operation-details/react/runtime/TypeDefinitionsGql.tsx b/src/components/operations/operation-details/react/runtime/TypeDefinitionsGql.tsx index 36f003175..8dc4ae454 100644 --- a/src/components/operations/operation-details/react/runtime/TypeDefinitionsGql.tsx +++ b/src/components/operations/operation-details/react/runtime/TypeDefinitionsGql.tsx @@ -2,10 +2,9 @@ import * as React from "react"; import { useState } from "react"; import { GraphQLCompositeType, GraphQLEnumValue, GraphQLField, GraphQLInputType, GraphQLObjectType, GraphQLOutputType, isEnumType, isUnionType } from "graphql"; import { Stack } from "@fluentui/react"; -import { Tab, TabList, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TableRow } from "@fluentui/react-components"; -import { RawSchema } from "@microsoft/api-docs-ui"; +import { Tab, TabList, TableCell, TableRow } from "@fluentui/react-components"; +import { InfoTable, RawSchema } from "@microsoft/api-docs-ui"; import { MarkdownProcessor } from "../../../../utils/react/MarkdownProcessor"; -import { ScrollableTableContainer } from "../../../../utils/react/ScrollableTableContainer"; import { GraphqlFieldTypes } from "../../../../../constants"; import { TSchemaView } from "./OperationRepresentation"; @@ -57,51 +56,37 @@ const renderDescription = (description: string) => (
) -const GQLTypeDefinitionForRepresentation = ({ graph, getGraphType }: GQLTypeDefinitionProps) => ( - <> -
{graph.name}
- {graph.description && } - - - - - {isEnumType(graph) - ? Value - : isUnionType(graph) - ? Possible types - : <> - Fields - Type - - } - Description - - - - {isEnumType(graph) - ? graph[GraphqlFieldTypes.values].map((value: GraphQLEnumValue) => ( - - {value.name} - {renderDescription(value.description)} +const GQLTypeDefinitionForRepresentation = ({ graph, getGraphType }: GQLTypeDefinitionProps) => { + const columnLabels = isEnumType(graph) ? ["Value", "Description"] : isUnionType(graph) ? ["Possible types", "Description"] : ["Fields", "Type", "Description"]; + return ( + <> +
{graph.name}
+ {graph.description && } + ( + + {value.name} + {renderDescription(value.description)} + + )) + : isUnionType(graph) + ? graph[GraphqlFieldTypes.types].map((type: GraphQLObjectType) => ( + + {getGraphType(type)} + {renderDescription(type.description)} + + )) + : Object.values(graph[GraphqlFieldTypes.fields]).map((field: GraphQLField) => ( + + {field.name} + {getGraphType(field.type)} + {renderDescription(field.description)} - )) - : isUnionType(graph) - ? graph[GraphqlFieldTypes.types].map((type: GraphQLObjectType) => ( - - {getGraphType(type)} - {renderDescription(type.description)} - - )) - : Object.values(graph[GraphqlFieldTypes.fields]).map((field: GraphQLField) => ( - - {field.name} - {getGraphType(field.type)} - {renderDescription(field.description)} - - )) - } -
-
-
- -); + ))} + /> + + ); +} diff --git a/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx b/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx index be6d6576f..afc4b179e 100644 --- a/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx +++ b/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx @@ -16,16 +16,10 @@ import { Option, Radio, RadioGroup, - Table, - TableBody, - TableCell, - TableHeader, - TableHeaderCell, - TableRow, Textarea, Tooltip } from "@fluentui/react-components"; -import { ArrowDownFilled, ArrowUpFilled, ChevronUp20Regular, Copy16Regular, EyeOffRegular, EyeRegular } from "@fluentui/react-icons"; +import { ChevronUp20Regular, Copy16Regular } from "@fluentui/react-icons"; import { Api } from "../../../../../../models/api"; import { KnownMimeTypes } from "../../../../../../models/knownMimeTypes"; import { KnownHttpHeaders } from "../../../../../../models/knownHttpHeaders"; @@ -37,12 +31,12 @@ import { HttpResponse } from "../../../../../../contracts/httpResponse"; import { TemplatingService } from "../../../../../../services/templatingService"; import { Utils } from "../../../../../../utils"; import { MarkdownProcessor } from "../../../../../utils/react/MarkdownProcessor"; -import { ScrollableTableContainer } from "../../../../../utils/react/ScrollableTableContainer"; import { RequestBodyType, TypeOfApi, downloadableTypes } from "../../../../../../constants"; import { LogItem, WebsocketClient } from "./ws-utilities/websocketClient"; import { templates } from "./templates/templates"; import { BinaryField } from "./BinaryField"; import { RevealSecretButton } from "./consoleUtils"; +import { ConsoleWsLogItems } from "./ConsoleWsLogItems"; type ConsoleRequestResponseProps = { api: Api; @@ -511,30 +505,7 @@ ${responseBodyFormatted}`; Output {wsLogItems.length === 0 ? Sent and received messages will appear here. Send a payload to begin. - : - - - - Time - - Data - - - - {wsLogItems.map((item, index) => ( - - {item.logTime} - { - item.logType === "SendData" - ? - : item.logType === "GetData" && - } - {item.logData} - - ))} - -
-
+ : }
-
-
- -
-
- - ) -} \ No newline at end of file diff --git a/src/components/utils/react/MarkdownProcessor.tsx b/src/components/utils/react/MarkdownProcessor.tsx deleted file mode 100644 index 562cb602f..000000000 --- a/src/components/utils/react/MarkdownProcessor.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from "react"; -import remarkGfm from "remark-gfm"; -import rehypeRaw from "rehype-raw"; -import rehypeTruncate from "rehype-truncate"; -import ReactMarkdown from "react-markdown"; // TODO: upgrade this package and all related ones when https://github.com/hashicorp/next-mdx-remote/issues/403 fixed - -type TMarkdownProcessorProps = { - markdownToDisplay: string; - maxChars?: number; - truncate?: boolean; -} - -export const MarkdownProcessor = ({ markdownToDisplay, maxChars, truncate = false }: TMarkdownProcessorProps) => ( - - {markdownToDisplay} - -); From 53abe5d79833e9111f5b4a7612b48d7577ca9caf Mon Sep 17 00:00:00 2001 From: Elena Shorohova Date: Thu, 1 May 2025 20:23:15 +0300 Subject: [PATCH 4/4] Unified components - syntax highlighter --- .../react/runtime/OperationConsoleGql.tsx | 6 ++---- .../runtime/operation-console/ConsoleRequestResponse.tsx | 8 +++----- .../react/runtime/operation-console/ConsoleWsLogItems.tsx | 8 ++------ 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/components/operations/operation-details/react/runtime/OperationConsoleGql.tsx b/src/components/operations/operation-details/react/runtime/OperationConsoleGql.tsx index ca729860c..5e6e873b3 100644 --- a/src/components/operations/operation-details/react/runtime/OperationConsoleGql.tsx +++ b/src/components/operations/operation-details/react/runtime/OperationConsoleGql.tsx @@ -1,7 +1,5 @@ import * as React from "react"; import { useCallback, useEffect, useState } from "react"; -import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; -import { a11yLight } from "react-syntax-highlighter/dist/esm/styles/hljs"; import Editor, { Monaco } from '@monaco-editor/react'; import { ISettingsProvider } from "@paperbits/common/configuration"; import { SessionManager } from "@paperbits/common/persistence/sessionManager"; @@ -36,7 +34,7 @@ import { truncateBreadcrumbLongName } from "@fluentui/react-components"; import { DismissRegular, SearchRegular } from "@fluentui/react-icons"; -import { MarkdownRenderer } from "@microsoft/api-docs-ui"; +import { MarkdownRenderer, SyntaxHighlighter } from "@microsoft/api-docs-ui"; import { RouteHelper } from "../../../../../routing/routeHelper"; import { Api } from "../../../../../models/api"; import { ConsoleHeader } from "../../../../../models/console/consoleHeader"; @@ -703,7 +701,7 @@ export const OperationConsoleGql = ({ {selectedTab === ConsoleTab.response && (requestError ? - : response && + : response && ) } {selectedTab === ConsoleTab.wsconsole && diff --git a/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx b/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx index 2d1280652..0374404f7 100644 --- a/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx +++ b/src/components/operations/operation-details/react/runtime/operation-console/ConsoleRequestResponse.tsx @@ -3,8 +3,6 @@ import * as ko from "knockout"; import { useEffect, useState } from "react"; import { saveAs } from "file-saver"; import { getExtension } from "mime"; -import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; -import { a11yLight } from "react-syntax-highlighter/dist/esm/styles/hljs"; import { HttpClient, HttpHeader, HttpMethod, HttpRequest } from "@paperbits/common/http"; import { Stack } from "@fluentui/react"; import { @@ -20,7 +18,7 @@ import { Tooltip } from "@fluentui/react-components"; import { ChevronUp20Regular, Copy16Regular } from "@fluentui/react-icons"; -import { MarkdownRenderer } from "@microsoft/api-docs-ui"; +import { MarkdownRenderer, SyntaxHighlighter } from "@microsoft/api-docs-ui"; import { Api } from "../../../../../../models/api"; import { KnownMimeTypes } from "../../../../../../models/knownMimeTypes"; import { KnownHttpHeaders } from "../../../../../../models/knownHttpHeaders"; @@ -459,7 +457,7 @@ ${responseBodyFormatted}`; setIsSecretsRevealed(!isSecretsRevealed)} > - + {api.type === TypeOfApi.webSocket && <> {isWsConnected && @@ -535,7 +533,7 @@ ${responseBodyFormatted}`;
{requestError ? - : formattedResponse && {formattedResponse} + : formattedResponse && }
diff --git a/src/components/operations/operation-details/react/runtime/operation-console/ConsoleWsLogItems.tsx b/src/components/operations/operation-details/react/runtime/operation-console/ConsoleWsLogItems.tsx index 0396fd5bc..9e08e83bd 100644 --- a/src/components/operations/operation-details/react/runtime/operation-console/ConsoleWsLogItems.tsx +++ b/src/components/operations/operation-details/react/runtime/operation-console/ConsoleWsLogItems.tsx @@ -1,9 +1,7 @@ import * as React from "react"; -import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; -import { a11yLight } from "react-syntax-highlighter/dist/esm/styles/hljs"; import { Body1, TableCell, TableRow } from "@fluentui/react-components"; import { ArrowDownFilled, ArrowUpFilled } from "@fluentui/react-icons"; -import { InfoTable } from "@microsoft/api-docs-ui"; +import { InfoTable, SyntaxHighlighter } from "@microsoft/api-docs-ui"; import { LogItem } from "./ws-utilities/websocketClient"; export const ConsoleWsLogItems = ({ wsLogItems }: { wsLogItems: LogItem[] }) => ( @@ -25,9 +23,7 @@ export const ConsoleWsLogItems = ({ wsLogItems }: { wsLogItems: LogItem[] }) => } { item.logType === "SendData" || item.logType === "GetData" - ? - {item.logData} - + ? : item.logData }