From 43b8ff68fb4b81fd6b16187b16adaaa43acf1ac5 Mon Sep 17 00:00:00 2001 From: Jakub Jankowski Date: Fri, 15 Dec 2023 23:11:28 +0800 Subject: [PATCH] feat: callbacks (#2480) * feat: callbacks * fix: import * chore: release --- demo/package.json | 2 +- packages/elements-core/package.json | 2 +- .../src/__fixtures__/operations/put-todos.ts | 103 +++++++++++++++++- .../components/Docs/HttpOperation/Body.tsx | 4 +- .../Docs/HttpOperation/Callbacks.tsx | 86 +++++++++++++++ .../Docs/HttpOperation/HttpOperation.spec.tsx | 37 ++++++- .../Docs/HttpOperation/HttpOperation.tsx | 9 +- .../components/Docs/HttpOperation/Request.tsx | 2 +- .../Docs/HttpOperation/Responses.tsx | 10 +- packages/elements-dev-portal/package.json | 4 +- packages/elements/package.json | 4 +- 11 files changed, 244 insertions(+), 19 deletions(-) create mode 100644 packages/elements-core/src/components/Docs/HttpOperation/Callbacks.tsx diff --git a/demo/package.json b/demo/package.json index 19d2ac384..eb6542992 100644 --- a/demo/package.json +++ b/demo/package.json @@ -10,7 +10,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@stoplight/elements": "^7.15.3", + "@stoplight/elements": "^7.16.0", "@stoplight/mosaic": "^1.46.1", "history": "^5.0.0", "react": "16.14.0", diff --git a/packages/elements-core/package.json b/packages/elements-core/package.json index 0061a1b50..cbe4e3186 100644 --- a/packages/elements-core/package.json +++ b/packages/elements-core/package.json @@ -1,6 +1,6 @@ { "name": "@stoplight/elements-core", - "version": "7.15.2", + "version": "7.16.0", "sideEffects": [ "web-components.min.js", "src/web-components/**", diff --git a/packages/elements-core/src/__fixtures__/operations/put-todos.ts b/packages/elements-core/src/__fixtures__/operations/put-todos.ts index c98335f06..4ea0cd7bc 100644 --- a/packages/elements-core/src/__fixtures__/operations/put-todos.ts +++ b/packages/elements-core/src/__fixtures__/operations/put-todos.ts @@ -1,4 +1,4 @@ -import { HttpParamStyles, IHttpOperation } from '@stoplight/types'; +import { HttpOperationSecurityDeclarationTypes, HttpParamStyles, IHttpOperation } from '@stoplight/types'; export const httpOperation: IHttpOperation = { id: '?http-operation-id?', @@ -522,6 +522,107 @@ export const httpOperation: IHttpOperation = { }, ], }, + callbacks: [ + { + key: 'newPet', + extensions: {}, + id: '3245690b6a7fc', + method: 'post', + path: '{$request.body#/newPetAvailableUrl}', + request: { + body: { + description: 'Callback body description', + contents: [ + { + encodings: [], + examples: [], + id: 'abc', + mediaType: 'application/json', + schema: { + $schema: 'http://json-schema.org/draft-07/schema#', + properties: { + message: { + examples: ['A new pet has arrived'], + type: 'string', + }, + }, + required: ['message'], + type: 'object', + }, + }, + ], + id: 'abc', + required: true, + }, + cookie: [], + headers: [], + path: [], + query: [], + }, + responses: [ + { + code: '200', + contents: [], + description: 'Your server returns this code if it accepts the callback', + headers: [], + id: 'abc', + }, + ], + security: [], + securityDeclarationType: HttpOperationSecurityDeclarationTypes.InheritedFromService, + servers: [], + tags: [], + }, + { + key: 'returnedPet', + extensions: {}, + id: '07041d5723f4a', + method: 'post', + path: '{$request.body#/returnedPetAvailableUrl}', + request: { + body: { + contents: [ + { + encodings: [], + examples: [], + id: 'abc', + mediaType: 'application/json', + schema: { + $schema: 'http://json-schema.org/draft-07/schema#', + properties: { + message: { + examples: ['A pet has been returned'], + type: 'string', + }, + }, + required: ['message'], + type: 'object', + }, + }, + ], + id: 'abc', + required: true, + }, + cookie: [], + headers: [], + path: [], + query: [], + }, + responses: [ + { + code: '200', + contents: [], + description: 'Your server returns this code if it accepts the callback', + headers: [], + id: 'abc', + }, + ], + security: [], + securityDeclarationType: HttpOperationSecurityDeclarationTypes.InheritedFromService, + servers: [], + tags: [], + }, + ], tags: [ { id: '?http-tags-todos?', diff --git a/packages/elements-core/src/components/Docs/HttpOperation/Body.tsx b/packages/elements-core/src/components/Docs/HttpOperation/Body.tsx index 34ec4c41f..89f12cd46 100644 --- a/packages/elements-core/src/components/Docs/HttpOperation/Body.tsx +++ b/packages/elements-core/src/components/Docs/HttpOperation/Body.tsx @@ -12,7 +12,7 @@ import { SectionSubtitle } from '../Sections'; export interface BodyProps { body: IHttpOperationRequestBody; - onChange: (requestBodyIndex: number) => void; + onChange?: (requestBodyIndex: number) => void; } export const isBodyEmpty = (body?: BodyProps['body']) => { @@ -29,7 +29,7 @@ export const Body = ({ body, onChange }: BodyProps) => { const { nodeHasChanged } = useOptionsCtx(); React.useEffect(() => { - onChange(chosenContent); + onChange?.(chosenContent); // disabling because we don't want to react on `onChange` change // eslint-disable-next-line react-hooks/exhaustive-deps }, [chosenContent]); diff --git a/packages/elements-core/src/components/Docs/HttpOperation/Callbacks.tsx b/packages/elements-core/src/components/Docs/HttpOperation/Callbacks.tsx new file mode 100644 index 000000000..06fc20ef3 --- /dev/null +++ b/packages/elements-core/src/components/Docs/HttpOperation/Callbacks.tsx @@ -0,0 +1,86 @@ +import { Box, Flex, NodeAnnotation, Select, VStack } from '@stoplight/mosaic'; +import { IHttpCallbackOperation } from '@stoplight/types'; +import * as React from 'react'; + +import { useOptionsCtx } from '../../../context/Options'; +import { MarkdownViewer } from '../../MarkdownViewer'; +import { SectionSubtitle, SectionTitle } from '../Sections'; +import { OperationHeader } from './HttpOperation'; +import { Request } from './Request'; +import { Responses } from './Responses'; + +export interface CallbacksProps { + callbacks: IHttpCallbackOperation[]; + isCompact?: boolean; +} + +export interface CallbackProps { + data: IHttpCallbackOperation; + isCompact?: boolean; +} + +export const Callbacks = ({ callbacks, isCompact }: CallbacksProps) => { + const [selectedCallbackIndex, setSelectedCallbackIndex] = React.useState(0); + + const callback = React.useMemo(() => callbacks[selectedCallbackIndex], [callbacks, selectedCallbackIndex]); + + return ( + + + {callbacks.length > 0 && ( + +