Skip to content

Commit

Permalink
chore: ui improvments
Browse files Browse the repository at this point in the history
  • Loading branch information
onmax committed Mar 26, 2024
1 parent 49fd61e commit 0f855f4
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 139 deletions.
90 changes: 45 additions & 45 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default async () => {
const autogenerated = [generateRpcDocs, generateWebClientDocs]
await Promise.all(autogenerated.map(fn => fn()))

return withPwa(defineConfig({
return defineConfig({
base: baseUrl,
title: pkg.title,
srcExclude: ['**/README.md'],
Expand Down Expand Up @@ -128,53 +128,53 @@ export default async () => {
['meta', { name: 'twitter:creator', content: '@nimiq' }],
['meta', { name: 'twitter:title', content: pkg.title }],
],
pwa: {
mode: env.DEPLOYMENT_ENV !== 'production' ? 'development' : 'production',
disable: env.DEPLOYMENT_ENV === 'development',
scope: baseUrl,
registerType: 'autoUpdate',
injectRegister: 'script-defer',
includeAssets: [`${baseUrl}favicons/favicon.svg`],
manifest: {
name: pkg.title,
short_name: pkg.title,
theme_color: '#ffffff',
icons: [
{
src: `${baseUrl}favicons/nimiq-hexagon-192.png`,
sizes: '192x192',
type: 'image/png',
},
{
src: `${baseUrl}favicons/nimiq-hexagon-512.png`,
sizes: '512x512',
type: 'image/png',
},
{
src: `${baseUrl}favicons/nimiq-hexagon-512.png`,
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
workbox: {
globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'],
},
experimental: {
includeAllowlist: true,
},
devOptions: {
enabled: env.DEPLOYMENT_ENV === 'production',
type: 'module',
suppressWarnings: true,
navigateFallback: '/',
},
},
// pwa: {
// mode: env.DEPLOYMENT_ENV !== 'production' ? 'development' : 'production',
// disable: env.DEPLOYMENT_ENV !== 'production',
// scope: baseUrl,
// registerType: 'autoUpdate',
// injectRegister: 'script-defer',
// includeAssets: [`${baseUrl}favicons/favicon.svg`],
// manifest: {
// name: pkg.title,
// short_name: pkg.title,
// theme_color: '#ffffff',
// icons: [
// {
// src: `${baseUrl}favicons/nimiq-hexagon-192.png`,
// sizes: '192x192',
// type: 'image/png',
// },
// {
// src: `${baseUrl}favicons/nimiq-hexagon-512.png`,
// sizes: '512x512',
// type: 'image/png',
// },
// {
// src: `${baseUrl}favicons/nimiq-hexagon-512.png`,
// sizes: '512x512',
// type: 'image/png',
// purpose: 'any maskable',
// },
// ],
// },
// workbox: {
// globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'],
// },
// experimental: {
// includeAllowlist: true,
// },
// devOptions: {
// enabled: env.DEPLOYMENT_ENV === 'production',
// type: 'module',
// suppressWarnings: true,
// navigateFallback: '/',
// },
// },

sitemap: {
hostname: 'https://onmax.github.io',
},

}))
})
}
229 changes: 156 additions & 73 deletions .vitepress/scripts/rpc-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ export async function generateRpcDocs() {
// Build folder
const buildFolder = join(__dirname, '../../build/rpc-docs')
// Read package version of generated docs, if already built
const versionFile = join(buildFolder, '/_version')
const methodFile = join(buildFolder, '/method.md')

if (existsSync(versionFile)) {
const generatedVersion = readFileSync(versionFile, 'utf-8')

// Skip build if package version and generated version match
if (existsSync(methodFile)) {
const re = /## Version: (\.*)/
const content = readFileSync(methodFile, 'utf-8')
const generatedVersion = re.exec(content)?.[1]
consola.info(`RPC specification docs ${packageVersion} already generated`)
if (packageVersion === generatedVersion) {
consola.info(`RPC specification docs ${packageVersion} already generated`)
return
Expand All @@ -56,91 +57,173 @@ export async function generateRpcDocs() {
methodsMd.push(addHeader('h2', `Version: ${spec.info.version}`))
methodsMd.push(`[Download RPC definition](https://github.com/nimiq/core-rs-albatross/releases/latest)`)

// - <span font-mono>passphrase</span>*: `String`
// Returns: [ReturnAccount](#returnaccount)
const template = `
<div grid="~ gap-32 cols-1 lg:cols-[2fr_3fr]">
<div w-full>
### {{ methodName }}
Parameters{.label .text-12 .text-neutral-800}
{{ parameters }}
Returns{.label .text-12 .text-neutral-800}
{{ returns }}
</div>
<div w-full>
::: code-group
\`\`\`JavaScript
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: '{"jsonrpc":"2.0","method":"{{ methodName }}","params":[{{ parametersValues }}],"id":1}'
};
fetch('http://127.0.0.1:8648', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
\`\`\`
\`\`\`Shell
curl --request POST \n
--url http://127.0.0.1:8648 \n
--header 'Content-Type: application/json' \n
--data '{
"jsonrpc": "2.0",
"method": "{{ methodName }}",
"params": [{{ parametersValues }}],
"id": 1
}'
\`\`\`
:::
</div>
</div>
`.trim()

function paramToValue(param: any) {
switch (param.schema.type) {
case 'string': return `"${param.name}"`
case 'number': return '0'
case 'boolean': return 'false'
default: return '""'
}
}

methodsMd.push(addHeader('h2', 'Methods'))
for (const method of spec.methods) {
methodsMd.push(addHeader('h3', method.name))

// Method parameters
methodsMd.push(addParagraph('Parameters:'))
if (method.params.length === 0)
methodsMd.push(addParagraph('*None*'))
else
methodsMd.push(methodParamsToTable(method))

// Method result
if ('$ref' in method.result.schema) {
const ref = method.result.schema.$ref.split('/').pop()
methodsMd.push(addParagraph(`Returns: [${ref}](#${ref.toLowerCase()})`))
const parameters = method.params.map(param => `- <span font-mono>${param.name}</span>${param.required ? '*' : ''}: \`${param.schema.type}\``).join('\n')

const parametersValues = method.params.map(paramToValue).join(', ')

let resultProperties = ''
const returnsObject = '$ref' in method.result.schema
if (returnsObject) {
const { /* title, description, */ required, properties } = spec.components.schemas[method.result.schema.$ref.split('/').at(-1)]
resultProperties = Object.values(properties).map(({ title, type }) => `- <span font-mono>${title}</span>${required.includes(title) ? '*' : ''}: \`${type}\``).join('\n')
}
else {
if (method.result.schema.type !== 'array') {
methodsMd.push(addParagraph(`Returns: ${firstCharToUpper(method.result.schema.type)}`))
}
else {
if ('$ref' in method.result.schema.items) {
const ref = method.result.schema.items.$ref.split('/').pop()
methodsMd.push(addParagraph(`Returns: Array< [${ref}](#${ref.toLowerCase()}) >`))
}
else {
methodsMd.push(addParagraph(`Returns: Array< ${firstCharToUpper(method.result.schema.items.type)} >`))
}
}
resultProperties = `- \`${method.result.schema.type}\``
}
const tmp = template
.replaceAll('{{ methodName }}', method.name)
.replaceAll('{{ parameters }}', parameters)
.replaceAll('{{ parametersValues }}', parametersValues)
.replaceAll('{{ returns }}', resultProperties)

methodsMd.push(tmp)
}

// Method parameters
// methodsMd.push(addParagraph('Parameters{.subline .text-neutral-800 .text-12}'))
// if (method.params.length === 0)
// methodsMd.push(addParagraph('*None*'))
// else
// methodsMd.push(methodParamsToTable(method))

// Method result
// if ('$ref' in method.result.schema) {
// const ref = method.result.schema.$ref.split('/').pop()
// methodsMd.push(addParagraph(`Returns: [${ref}](#${ref.toLowerCase()})`))
// }
// else {
// if (method.result.schema.type !== 'array') {
// methodsMd.push(addParagraph(`Returns: ${firstCharToUpper(method.result.schema.type)} `))
// }
// else {
// if ('$ref' in method.result.schema.items) {
// const ref = method.result.schema.items.$ref.split('/').pop()
// methodsMd.push(addParagraph(`Returns: Array < [${ref}](#${ref.toLowerCase()}) > `))
// }
// else {
// methodsMd.push(addParagraph(`Returns: Array < ${firstCharToUpper(method.result.schema.items.type)} > `))
// }
// }
// }

// Schemas section
const schemasMd = []
schemasMd.push(addHeader('h2', 'Schemas'))
for (const schema of Object.values(spec.components.schemas)) {
schemasMd.push(addHeader('h3', (schema as any).title))
schemasMd.push(schemaPropertiesToTable(schema))
}
// const schemasMd = []
// schemasMd.push(addHeader('h2', 'Schemas'))
// for (const schema of Object.values(spec.components.schemas)) {
// schemasMd.push(addHeader('h3', (schema as any).title))
// schemasMd.push(schemaPropertiesToTable(schema))
// }

// Verify that destination folder exists
if (!existsSync(buildFolder))
mkdirSync(buildFolder)

writeFileSync(join(__dirname, '../../build/rpc-docs/methods.md'), json2md(methodsMd))
writeFileSync(join(__dirname, '../../build/rpc-docs/schemas.md'), json2md(schemasMd))
// writeFileSync(join(__dirname, '../../build/rpc-docs/schemas.md'), json2md(schemasMd))
}

function addHeader(size: string, text: string) {
return { [size]: text }
}

function addParagraph(text: string) {
return { p: text }
}

function firstCharToUpper(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}

function schemaPropertiesToTable(schema: any) {
const table = { table: { headers: ['Name', 'Type', 'Required'], rows: [] } }
const requiredProps = Object.entries(schema.required).map(prop => prop[1])

Object.entries(schema.properties)
.map(obj => obj[1])
.forEach((prop: any) => {
// Check if we are dealing with a type or a reference to a schema
let type: string
if (!prop.type && prop.$ref) {
const ref = prop.$ref.split('/').pop()
type = `[${ref}](#${ref.toLowerCase()})`
}
else { type = prop.type }

const isPropRequired = requiredProps.find(reqProp => reqProp === prop.title)
table.table.rows.push([prop.title, firstCharToUpper(type), isPropRequired ? 'Yes' : 'No'])
})
return table
}

function methodParamsToTable(method: any) {
const table = { table: { headers: ['Name', 'Type', 'Required'], rows: [] } }
method.params.forEach((param: any) => {
table.table.rows.push([param.name, firstCharToUpper(param.schema.type), param.required ? 'Yes' : 'No'])
})
return table
}
// function addParagraph(text: string) {
// return { p: text }
// }

// function firstCharToUpper(string: string) {
// return string.charAt(0).toUpperCase() + string.slice(1)
// }

// function schemaPropertiesToTable(schema: any) {
// const table = { table: { headers: ['Name', 'Type', 'Required'], rows: [] } }
// const requiredProps = Object.entries(schema.required).map(prop => prop[1])

// Object.entries(schema.properties)
// .map(obj => obj[1])
// .forEach((prop: any) => {
// // Check if we are dealing with a type or a reference to a schema
// let type: string
// if (!prop.type && prop.$ref) {
// const ref = prop.$ref.split('/').pop()
// type = `[${ref}](#${ref.toLowerCase()})`
// }
// else { type = prop.type }

// const isPropRequired = requiredProps.find(reqProp => reqProp === prop.title)
// table.table.rows.push([prop.title, firstCharToUpper(type), isPropRequired ? 'Yes' : 'No'])
// })
// return table
// }

// function methodParamsToTable(method: any) {
// const table = { table: { headers: ['Name', 'Type', 'Required'], rows: [] } }
// method.params.forEach((param: any) => {
// table.table.rows.push([param.name, firstCharToUpper(param.schema.type), param.required ? 'Yes' : 'No'])
// })
// return table
// }
4 changes: 2 additions & 2 deletions .vitepress/theme/MainLayout.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script setup lang="ts">
import DefaultTheme from 'vitepress/theme'
import RegisterSw from './components/RegisterSW.vue'
// import RegisterSw from './components/RegisterSW.vue'
</script>

<template>
<RegisterSW />
<!-- <RegisterSW /> -->
<DefaultTheme.Layout bg-neutral-0 class="vp-raw">
<template #not-found>
<main px-32>
Expand Down
6 changes: 3 additions & 3 deletions .vitepress/theme/components/header/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ const { copy, isSupported } = useClipboard({ copiedDuring: 3000 })
<template v-else>
<SearchBox v-if="showSearch" @close="showSearch = false" />
<button ml-96 text-14 py-6 px-12 input-text min-w-192 group flex="~ gap-8 items-center" rounded-full class="group" @click="showSearch = true">
<div i-nimiq:magnifying-glass text-neutral-700 text-12 />
<span text="neutral-800 group-hocus:blue">Search</span>
<div flex="~ items-baseline gap-4" pointer-events-none mr--3 mb--1 py-2 lh="11" select-none rounded-full ring="1 neutral/10 group-hocus:blue-600" ml-auto font-sans font-medium text="11 neutral/80 group-hocus:blue" px-6 bg="neutral-200 group-hocus:blue-400" font-mono>
<div i-nimiq:magnifying-glass text="12 neutral-700 group-hocus:blue/80 transition" />
<span text="neutral-800 group-hocus:blue transition">Search</span>
<div flex="~ items-baseline gap-4" pointer-events-none mr--3 mb--1 py-2 lh="11" select-none rounded-full ring="1 neutral/10 group-hocus:blue-600" ml-auto font-sans font-medium text="11 neutral/80 group-hocus:blue" px-6 bg="neutral-200 group-hocus:blue-400" transition font-mono>
<kbd>Ctrl</kbd>
<kbd>K</kbd>
</div>
Expand Down
Loading

0 comments on commit 0f855f4

Please sign in to comment.