Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(next): ssr api view #4721

Merged
merged 5 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { APIView } from '@payloadcms/next/pages/API'
import config from 'payload-config'

export default ({ params, searchParams }) =>
APIView({
collectionSlug: params.collection,
id: params.id,
config,
searchParams,
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { APIView } from '@payloadcms/next/pages/API'
import config from 'payload-config'

export default ({ params, searchParams }) =>
APIView({
globalSlug: params.global,
config,
searchParams,
})
90 changes: 90 additions & 0 deletions packages/next/src/pages/API/RenderJSON/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
@import '../../../scss/queries.scss';

.query-inspector {
&__json-children {
position: relative;

&:before {
content: '';
position: absolute;
top: 0;
left: 8px;
width: 1px;
height: 100%;
border-left: 1px dashed var(--theme-elevation-200);
}
}

&__list-wrap {
position: relative;
}

&__list-toggle {
all: unset;
width: 100%;
text-align: left;
cursor: pointer;
border-radius: 3px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
position: relative;
display: flex;
gap: 10px;
align-items: center;
left: -3px;
width: calc(100% + 3px);

svg {
margin-left: 5px;
}

svg .stroke {
stroke: var(--theme-elevation-400);
}

&:hover {
background-color: var(--theme-elevation-100);
}

&--empty {
cursor: default;
pointer-events: none;
}
}

&__toggle-row-icon {
&--open {
transform: rotate(0deg);
}
&--closed {
transform: rotate(-90deg);
}
}

&__value-type {
&--number {
.query-inspector__value {
color: var(--number-color);
}
}

&--string {
.query-inspector__value {
color: var(--string-color);
}
}
}

&__row-line--nested {
margin-left: 25px;
}

&__bracket {
position: relative;

&--position-end {
left: 5px;
width: calc(100% - 5px);
}
}
}
151 changes: 151 additions & 0 deletions packages/next/src/pages/API/RenderJSON/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
'use client'
import * as React from 'react'

import { Chevron } from '@payloadcms/ui'
import './index.scss'

const chars = {
leftCurlyBracket: '\u007B',
leftSquareBracket: '\u005B',
rightCurlyBracket: '\u007D',
rightSquareBracket: '\u005D',
}

const baseClass = 'query-inspector'

const Bracket = ({
comma = false,
position,
type,
}: {
comma?: boolean
position: 'end' | 'start'
type: 'array' | 'object'
}) => {
const rightBracket = type === 'object' ? chars.rightCurlyBracket : chars.rightSquareBracket
const leftBracket = type === 'object' ? chars.leftCurlyBracket : chars.leftSquareBracket
const bracketToRender = position === 'end' ? rightBracket : leftBracket

return (
<span className={`${baseClass}__bracket ${baseClass}__bracket--position-${position}`}>
{bracketToRender}
{position === 'end' && comma ? ',' : null}
</span>
)
}

type Args = {
isEmpty?: boolean
object: Record<string, any> | any[]
objectKey?: string
parentType?: 'array' | 'object'
trailingComma?: boolean
}

export const RenderJSON = ({
isEmpty = false,
object,
objectKey,
parentType = 'object',
trailingComma = false,
}: Args) => {
const objectKeys = Object.keys(object)
const objectLength = objectKeys.length
const [isOpen, setIsOpen] = React.useState<boolean>(true)

return (
<li>
<button
aria-label="toggle"
className={`${baseClass}__list-toggle ${isEmpty ? `${baseClass}__list-toggle--empty` : ''}`}
onClick={() => setIsOpen(!isOpen)}
type="button"
>
{isEmpty ? null : (
<Chevron
className={`${baseClass}__toggle-row-icon ${baseClass}__toggle-row-icon--${
isOpen ? 'open' : 'closed'
}`}
/>
)}
<span>
{objectKey && `"${objectKey}": `}
<Bracket position="start" type={parentType} />
{isEmpty ? <Bracket comma={trailingComma} position="end" type={parentType} /> : null}
</span>
</button>

<ul className={`${baseClass}__json-children`}>
{isOpen &&
objectKeys.map((key, keyIndex) => {
let value = object[key]
let type = 'string'
const isLastKey = keyIndex === objectLength - 1

if (value === null) {
type = 'null'
} else if (value instanceof Date) {
type = 'date'
value = value.toISOString()
} else if (Array.isArray(value)) {
type = 'array'
} else if (typeof value === 'object') {
type = 'object'
} else if (typeof value === 'number') {
type = 'number'
} else if (typeof value === 'boolean') {
type = 'boolean'
} else {
type = 'string'
}

if (type === 'object' || type === 'array') {
return (
<RenderJSON
isEmpty={value.length === 0 || Object.keys(value).length === 0}
key={`${key}-${keyIndex}`}
object={value}
objectKey={parentType === 'object' ? key : undefined}
parentType={type}
trailingComma={!isLastKey}
/>
)
}

if (
type === 'date' ||
type === 'string' ||
type === 'null' ||
type === 'number' ||
type === 'boolean'
) {
const parentHasKey = Boolean(parentType === 'object' && key)

const rowClasses = [
`${baseClass}__row-line`,
`${baseClass}__value-type--${type}`,
`${baseClass}__row-line--${objectKey ? 'nested' : 'top'}`,
]
.filter(Boolean)
.join(' ')

return (
<li className={rowClasses} key={`${key}-${keyIndex}`}>
{parentHasKey ? <span>{`"${key}": `}</span> : null}

<span className={`${baseClass}__value`}>{JSON.stringify(value)}</span>
{isLastKey ? '' : ','}
</li>
)
}
})}
</ul>

{!isEmpty && (
<span>
<Bracket comma={trailingComma} position="end" type={parentType} />
</span>
)}
</li>
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../../../scss/styles.scss';
@import '../../scss/queries.scss';

.query-inspector {
--string-color: #11b102;
Expand Down Expand Up @@ -26,7 +26,7 @@
}

&__api-url {
margin-bottom: base(1.5);
margin-bottom: calc(var(--base) * 1.5);

a {
display: block;
Expand Down Expand Up @@ -103,93 +103,6 @@
min-height: 100vh;
}

&__json-children {
position: relative;

&:before {
content: '';
position: absolute;
top: 0;
left: 8px;
width: 1px;
height: 100%;
border-left: 1px dashed var(--theme-elevation-200);
}
}

&__list-wrap {
position: relative;
}

&__list-toggle {
all: unset;
width: 100%;
text-align: left;
cursor: pointer;
border-radius: 3px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
position: relative;
display: flex;
gap: 10px;
align-items: center;
left: -3px;
width: calc(100% + 3px);

svg {
margin-left: 5px;
}

svg .stroke {
stroke: var(--theme-elevation-400);
}

&:hover {
background-color: var(--theme-elevation-100);
}

&--empty {
cursor: default;
pointer-events: none;
}
}

&__toggle-row-icon {
&--open {
transform: rotate(0deg);
}
&--closed {
transform: rotate(-90deg);
}
}

&__value-type {
&--number {
.query-inspector__value {
color: var(--number-color);
}
}

&--string {
.query-inspector__value {
color: var(--string-color);
}
}
}

&__row-line--nested {
margin-left: 25px;
}

&__bracket {
position: relative;

&--position-end {
left: 5px;
width: calc(100% - 5px);
}
}

@include mid-break {
flex-direction: column;
padding-left: 0;
Expand Down
Loading
Loading