From f6c0d13a8b2c9ba4cebb3aa718816178ef1d7d44 Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Fri, 13 Mar 2026 13:39:12 +0000 Subject: [PATCH] feat(docs): Implement config example/structure guidance --- .gitignore | 1 + .../docs/configuration/clients/rocksky.mdx | 2 +- .../configuration/sources/rocksky-source.mdx | 2 +- docsite/src/components/Button.tsx | 86 +++++++++++++ docsite/src/components/ButtonGroup.tsx | 82 +++++++++++++ docsite/src/components/FileConfigExample.tsx | 74 +++++++++++ docsite/src/components/FileExample.tsx | 79 +++++++++--- .../src/components/GenericConfiguration.mdx | 56 ++++++++- docsite/src/components/PlaygroundInner.tsx | 27 +++- .../src/components/Schema/SchemaEditor.tsx | 83 +++++++------ .../components/Schema/SchemaEditorFetch.tsx | 83 +++++++------ .../src/components/snippets/_aio-config.mdx | 1 - .../src/components/snippets/_env-config.mdx | 4 +- .../src/components/snippets/_file-config.mdx | 2 - docsite/src/components/useLocalStorage.ts | 116 ++++++++++++++++++ docsite/src/theme/MDXComponents.js | 6 +- docsite/static/aio.json | 1 - docsite/static/client.json | 1 - docsite/static/schemas/.gitkeep | 0 .../static/schemas/PlexApiSourceConfig.json | 1 - docsite/static/source.json | 1 - .../infrastructure/config/client/clients.ts | 26 +++- .../infrastructure/config/source/plex.ts | 2 - .../infrastructure/config/source/sources.ts | 52 +++++++- src/backend/common/schema/aio-client.json | 1 - src/backend/common/schema/aio-source.json | 1 - src/backend/common/schema/aio.json | 1 - src/backend/common/schema/client.json | 1 - src/backend/common/schema/source.json | 1 - src/backend/sources/ScrobbleSources.ts | 4 +- src/backend/utils/SchemaDocsStaticUtils.ts | 30 ++--- 31 files changed, 684 insertions(+), 143 deletions(-) create mode 100644 docsite/src/components/Button.tsx create mode 100644 docsite/src/components/ButtonGroup.tsx create mode 100644 docsite/src/components/FileConfigExample.tsx create mode 100644 docsite/src/components/useLocalStorage.ts delete mode 100644 docsite/static/aio.json delete mode 100644 docsite/static/client.json create mode 100644 docsite/static/schemas/.gitkeep delete mode 100644 docsite/static/schemas/PlexApiSourceConfig.json delete mode 100644 docsite/static/source.json delete mode 100644 src/backend/common/schema/aio-client.json delete mode 100644 src/backend/common/schema/aio-source.json delete mode 100644 src/backend/common/schema/aio.json delete mode 100644 src/backend/common/schema/client.json delete mode 100644 src/backend/common/schema/source.json diff --git a/.gitignore b/.gitignore index 1d09367d..a73d25d9 100644 --- a/.gitignore +++ b/.gitignore @@ -134,6 +134,7 @@ src/backend/common/schema/*.json !src/backend/common/schema/aio.json !src/backend/common/schema/client.json !src/backend/common/schema/source.json +docsite/static/schemas/*.json *.bak diff --git a/docsite/docs/configuration/clients/rocksky.mdx b/docsite/docs/configuration/clients/rocksky.mdx index 535accb1..1986ff2a 100644 --- a/docsite/docs/configuration/clients/rocksky.mdx +++ b/docsite/docs/configuration/clients/rocksky.mdx @@ -64,7 +64,7 @@ The handle used with multi-scrobbler should be your **full** ATProto handle, inc If you do not include a TLD then multi-scrobbler will automatically append `.bsky.social` to your handle value. - + | Environmental Variable | Required? | Default | Description | | :--------------------- | --------- | ------- | ----------------------------------------------------------------------------------- | | `ROCKSKY_HANDLE` | Yes | | Your **full** ATProto handle. For Bluesky account this is like `myUser.bsky.social` | diff --git a/docsite/docs/configuration/sources/rocksky-source.mdx b/docsite/docs/configuration/sources/rocksky-source.mdx index 578cb071..5849c785 100644 --- a/docsite/docs/configuration/sources/rocksky-source.mdx +++ b/docsite/docs/configuration/sources/rocksky-source.mdx @@ -31,7 +31,7 @@ See the [Rocksky (Client)](/configuration/clients/rocksky#setup) configuration f * [File/AIO config](/configuration?configType=file#configuration-types) must include `"configureAs": "source"` - + | Environmental Variable | Required? | Default | Description | | :---------------------- | --------- | ------- | ----------------------------------------------------------------------------------- | | `SOURCE_ROCKSKY_HANDLE` | Yes | | Your **full** ATProto handle. For Bluesky account this is like `myUser.bsky.social` | diff --git a/docsite/src/components/Button.tsx b/docsite/src/components/Button.tsx new file mode 100644 index 00000000..c1074f58 --- /dev/null +++ b/docsite/src/components/Button.tsx @@ -0,0 +1,86 @@ +import React, { ReactNode, CSSProperties } from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; + +// Define the Button type to control the props that can be passed to the Button component. +export type ButtonProps = { + // The size prop can be one of the following values: 'sm', 'lg', 'small', 'medium', 'large', or null. + // We'll convert 'small' to 'sm' and 'large' to 'lg' in the component. 'medium' will be considered null. + size?: 'sm' | 'lg' | 'small' | 'medium' | 'large' | null; + // The outline prop is a boolean that determines if the button should be an outline button. + outline?: boolean; + // The variant prop is a string that determines the color of the button. + // It can be one of the following values: 'primary', 'secondary', 'danger', 'warning', 'success', 'info', 'link', or any other string. + // The default value is 'primary'. + variant: 'primary' | 'secondary' | 'danger' | 'warning' | 'success' | 'info' | 'link' | string; + // The block prop is a boolean that determines if the button should be a block-level button. + block?: boolean; + // The disabled prop is a boolean that determines if the button should be disabled. + disabled?: boolean; + // The className prop is a string that allows you to add custom classes to the button. + className?: string; + // The style prop is an object that allows you to add custom styles to the button. + style?: CSSProperties; + // The link prop is a string that determines the URL the button should link to. + link: string; + // The label prop is a string that determines the text of the button. + label: string; + onClick?: () => any +} + +// Button component that accepts the specified props. +export default function Button ({ + size = null, + outline = false, + variant = 'primary', + block = false, + disabled = false, + className, + style = {}, + link, + label, + onClick = () => null, + ...rest +}: ButtonProps) { + // Map the size prop values to corresponding CSS classes. + const sizeMap = { + sm: 'sm', + small: 'sm', + lg: 'lg', + large: 'lg', + medium: null, + }; + const buttonSize = size ? sizeMap[size] : ''; + const sizeClass = buttonSize ? `button--${buttonSize}` : ''; + const outlineClass = outline ? 'button--outline' : ''; + const variantClass = variant ? `button--${variant}` : ''; + const blockClass = block ? 'button--block' : ''; + const disabledClass = disabled ? 'disabled' : ''; + // If the button is disabled, set the destination to null. + const destination = disabled ? null : link; + return ( + + + + ); +} \ No newline at end of file diff --git a/docsite/src/components/ButtonGroup.tsx b/docsite/src/components/ButtonGroup.tsx new file mode 100644 index 00000000..e1e9d8dd --- /dev/null +++ b/docsite/src/components/ButtonGroup.tsx @@ -0,0 +1,82 @@ +import React, { ReactNode, CSSProperties } from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import Button, { ButtonProps } from './Button'; + +const leftButton = { + borderRadius: 'var(--ifm-button-border-radius) 0 0 var(--ifm-button-border-radius)' +} + +const rightButton = { + borderRadius: '0 var(--ifm-button-border-radius) var(--ifm-button-border-radius) 0' +} + +const middleButton = { + borderRadius: '0' +} + +// Define the Button type to control the props that can be passed to the Button component. +type ButtonGroup = { + options: [string, string][] + value?: string + defaultValue?: string + // The size prop can be one of the following values: 'sm', 'lg', 'small', 'medium', 'large', or null. + // We'll convert 'small' to 'sm' and 'large' to 'lg' in the component. 'medium' will be considered null. + size?: 'sm' | 'lg' | 'small' | 'medium' | 'large' | null; + + variant: 'primary' | 'secondary' | 'danger' | 'warning' | 'success' | 'info' | 'link' | string; + // The block prop is a boolean that determines if the button should be a block-level button. + block?: boolean; + // The disabled prop is a boolean that determines if the button should be disabled. + disabled?: boolean; + // The className prop is a string that allows you to add custom classes to the button. + className?: string; + // The style prop is an object that allows you to add custom styles to the button. + style?: CSSProperties; + onChange?: (val: string) => any +} + +// Button component that accepts the specified props. +export default function ButtonGroup ({ + size = null, + variant = 'primary', + block = false, + disabled = false, + className, + style, + options, + value, + defaultValue, + onChange = () => null +}: ButtonGroup) { + + if(options === undefined || options.length === 0) { + return null; + } + + const buttons = options.map((opt, index) => { + const props: ButtonProps = { + style: middleButton, + outline: true, + size, + variant, + label: opt[1], + link: '#', + onClick: () => onChange(opt[0]) + }; + if(index === 0) { + props.style = leftButton; + } else if(index === options.length - 1) { + props.style = rightButton; + } + + if((value ?? defaultValue) === opt[0]) { + props.outline = false; + } + + return