OperationPanel
Domain · API DocTabbed panel showing all details of an API operation — parameters, request body, responses, and code samples.
Returns a paginated list of products.
Products
BearerAuth
Parameters 3
<%- include('modules/domain/api-doc/OperationPanel', {
operation: {
operationId: 'list-products',
operationKey: 'list-products',
method: 'GET',
tags: ['Products'],
description: 'Returns a paginated list of products.',
security: [{ BearerAuth: [] }],
parameters: [
{ parameterId: 'p1', name: 'page', in: 'query', schema: { type: 'integer' } },
{ parameterId: 'p2', name: 'pageSize', in: 'query', schema: { type: 'integer' } },
{ parameterId: 'p3', name: 'category', in: 'query', schema: { type: 'string' } },
],
responses: [
{ responseId: 'r1', statusCode: '200', description: 'OK' },
],
}
}) %>
<%
var _operation = locals.operation || {};
var _params = _operation.parameters || [];
var _responses = _operation.responses || [];
var _tags = _operation.tags || [];
var _samples = _operation.codeSamples || [];
var _security = _operation.security || [];
var _reqBody = _operation.requestBody || null;
var _externalDocs = _operation.externalDocs || null;
var pathParams = _params.filter(function(p) { return p.in === 'path'; });
var queryParams = _params.filter(function(p) { return p.in === 'query'; });
var headerParams = _params.filter(function(p) { return p.in === 'header'; });
var cookieParams = _params.filter(function(p) { return p.in === 'cookie'; });
var reqBodyContent = _reqBody && _reqBody.content ? Object.entries(_reqBody.content) : [];
var hasSamples = _samples.length > 0;
%>
<% if (_operation.deprecated) { %>
This operation is deprecated.
<% } %>
<% if (_operation.description) { %>
<%= _operation.description %>
<% } %>
<% _tags.forEach(function(tag) { %>
<%- include('../../ui/Badge', { variant: 'neutral', size: 'sm', children: tag }) %>
<% }); %>
<% _security.forEach(function(scheme) {
var schemeName = Object.keys(scheme)[0] || '';
%>
<%- include('./SecuritySchemeBadge', { type: 'http', name: schemeName, size: 'sm' }) %>
<% }); %>
<% if (_externalDocs) { %>
External docs
<% } %>
<%
// Build tab content as HTML strings so we can pass them to TabGroup.
function renderParamsTab() {
var html = '';
if (!_params.length) {
html += 'No parameters.
';
}
['path','query','header','cookie'].forEach(function(group) {
var list = group === 'path' ? pathParams
: group === 'query' ? queryParams
: group === 'header' ? headerParams
: cookieParams;
if (!list.length) return;
var label = group.charAt(0).toUpperCase() + group.slice(1);
if (group === 'cookie') label = 'Cookies';
if (group === 'header') label = 'Headers';
html += '';
html += '' + label + '
';
html += include('./ParameterTable', { parameters: list });
html += ' ';
});
html += '';
return html;
}
function renderBodyTab() {
var html = '';
if (!_reqBody) {
html += 'No request body.
';
} else {
if (_reqBody.required) {
html += '' + include('../../ui/Badge', { variant: 'error', size: 'sm', children: 'required' }) + '';
}
if (_reqBody.description) {
html += '' + _reqBody.description + '
';
}
reqBodyContent.forEach(function(entry) {
var mime = entry[0], obj = entry[1];
html += '';
html += '' + mime + '
';
if (obj.schema) html += include('./SchemaViewer', { schema: obj.schema });
html += '';
});
}
html += '';
return html;
}
function renderResponsesTab() {
var html = '';
if (!_responses.length) {
html += 'No responses defined.
';
} else {
_responses.forEach(function(res) {
html += include('./ResponseCard', { response: res, defaultOpen: res.statusCode && String(res.statusCode).startsWith('2') });
});
}
html += '';
return html;
}
function renderSamplesTab() {
return '' + include('./CodeSamplePanel', { samples: _samples }) + '';
}
var _tabs = [
{
id: 'params',
label: 'Parameters',
badge: _params.length ? include('../../ui/Badge', { variant: 'neutral', size: 'sm', children: String(_params.length) }) : null,
content: renderParamsTab(),
},
{
id: 'body',
label: 'Request Body',
badge: _reqBody ? include('../../ui/Badge', { variant: 'primary', size: 'sm', children: '1' }) : null,
content: renderBodyTab(),
},
{
id: 'responses',
label: 'Responses',
badge: _responses.length ? include('../../ui/Badge', { variant: 'neutral', size: 'sm', children: String(_responses.length) }) : null,
content: renderResponsesTab(),
},
];
if (hasSamples) {
_tabs.push({ id: 'samples', label: 'Code Samples', content: renderSamplesTab() });
}
%>
<%- include('../../ui/TabGroup', { tabs: _tabs, label: 'Operation details' }) %>