test: type fixes (#6331)
This commit is contained in:
@@ -1,33 +0,0 @@
|
|||||||
@import '../../../../../../../packages/payload/src/admin/scss/styles.scss';
|
|
||||||
|
|
||||||
.button-rich-text-button {
|
|
||||||
.btn {
|
|
||||||
margin-right: base(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__modal {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
&.payload__modal-item--enterDone {
|
|
||||||
@include blur-bg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: $baseline;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: base(1.5);
|
|
||||||
height: base(1.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
import facelessUIImport from '@faceless-ui/modal'
|
|
||||||
|
|
||||||
const { Modal, useModal } = facelessUIImport
|
|
||||||
import React, { Fragment, useCallback } from 'react'
|
|
||||||
import { Transforms } from 'slate'
|
|
||||||
import { ReactEditor, useSlate } from 'slate-react'
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
import Button from '../../../../../../../packages/payload/src/admin/components/elements/Button'
|
|
||||||
import Form from '../../../../../../../packages/payload/src/admin/components/forms/Form'
|
|
||||||
import reduceFieldsToValues from '../../../../../../../packages/payload/src/admin/components/forms/Form/reduceFieldsToValues'
|
|
||||||
import Submit from '../../../../../../../packages/payload/src/admin/components/forms/Submit'
|
|
||||||
import Checkbox from '../../../../../../../packages/payload/src/admin/components/forms/field-types/Checkbox'
|
|
||||||
import ElementButton from '../../../../../../../packages/payload/src/admin/components/forms/field-types/RichText/elements/Button'
|
|
||||||
import Select from '../../../../../../../packages/payload/src/admin/components/forms/field-types/Select'
|
|
||||||
import Text from '../../../../../../../packages/payload/src/admin/components/forms/field-types/Text'
|
|
||||||
import X from '../../../../../../../packages/payload/src/admin/components/icons/X'
|
|
||||||
import MinimalTemplate from '../../../../../../../packages/payload/src/admin/components/templates/Minimal'
|
|
||||||
import './index.scss'
|
|
||||||
|
|
||||||
const baseClass = 'button-rich-text-button'
|
|
||||||
|
|
||||||
const initialFormData = {
|
|
||||||
style: 'primary',
|
|
||||||
}
|
|
||||||
|
|
||||||
const insertButton = (editor, { href, label, newTab = false, style }: any) => {
|
|
||||||
const text = { text: ' ' }
|
|
||||||
const button = {
|
|
||||||
type: 'button',
|
|
||||||
children: [text],
|
|
||||||
href,
|
|
||||||
label,
|
|
||||||
newTab,
|
|
||||||
style,
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodes = [button, { children: [{ text: '' }] }]
|
|
||||||
|
|
||||||
if (editor.blurSelection) {
|
|
||||||
Transforms.select(editor, editor.blurSelection)
|
|
||||||
}
|
|
||||||
|
|
||||||
Transforms.insertNodes(editor, nodes)
|
|
||||||
|
|
||||||
const currentPath = editor.selection.anchor.path[0]
|
|
||||||
const newSelection = {
|
|
||||||
anchor: { offset: 0, path: [currentPath + 1, 0] },
|
|
||||||
focus: { offset: 0, path: [currentPath + 1, 0] },
|
|
||||||
}
|
|
||||||
|
|
||||||
Transforms.select(editor, newSelection)
|
|
||||||
ReactEditor.focus(editor)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ToolbarButton: React.FC<{ path: string }> = ({ path }) => {
|
|
||||||
const { closeAll, open } = useModal()
|
|
||||||
const editor = useSlate()
|
|
||||||
|
|
||||||
const handleAddButton = useCallback(
|
|
||||||
(fields) => {
|
|
||||||
const data = reduceFieldsToValues(fields)
|
|
||||||
insertButton(editor, data)
|
|
||||||
closeAll()
|
|
||||||
},
|
|
||||||
[editor, closeAll],
|
|
||||||
)
|
|
||||||
|
|
||||||
const modalSlug = `${path}-add-button`
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<ElementButton className={baseClass} format="button" onClick={() => open(modalSlug)}>
|
|
||||||
Button
|
|
||||||
</ElementButton>
|
|
||||||
<Modal className={`${baseClass}__modal`} slug={modalSlug}>
|
|
||||||
<MinimalTemplate>
|
|
||||||
<header className={`${baseClass}__header`}>
|
|
||||||
<h3>Add button</h3>
|
|
||||||
<Button buttonStyle="none" onClick={closeAll}>
|
|
||||||
<X />
|
|
||||||
</Button>
|
|
||||||
</header>
|
|
||||||
<Form initialData={initialFormData} onSubmit={handleAddButton}>
|
|
||||||
<Text label="Label" name="label" required />
|
|
||||||
<Text label="URL" name="href" required />
|
|
||||||
<Select
|
|
||||||
label="Style"
|
|
||||||
name="style"
|
|
||||||
options={[
|
|
||||||
{
|
|
||||||
label: 'Primary',
|
|
||||||
value: 'primary',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Secondary',
|
|
||||||
value: 'secondary',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<Checkbox label="Open in new tab" name="newTab" />
|
|
||||||
<Submit>Add button</Submit>
|
|
||||||
</Form>
|
|
||||||
</MinimalTemplate>
|
|
||||||
</Modal>
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
@import '../../../../../../../packages/payload/src/admin/scss/styles.scss';
|
|
||||||
|
|
||||||
.rich-text-button {
|
|
||||||
margin: $baseline 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rich-text-button__button {
|
|
||||||
padding: base(0.5) base(1.5);
|
|
||||||
border-radius: $style-radius-s;
|
|
||||||
|
|
||||||
&--primary {
|
|
||||||
background-color: $color-dark-gray;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--secondary {
|
|
||||||
background-color: $color-light-gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
|
|
||||||
import './index.scss'
|
|
||||||
|
|
||||||
const baseClass = 'rich-text-button'
|
|
||||||
|
|
||||||
export const ButtonElement: React.FC = ({ attributes, children, element }) => {
|
|
||||||
const { label, style = 'primary' } = element
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={baseClass} contentEditable={false}>
|
|
||||||
<span
|
|
||||||
{...attributes}
|
|
||||||
className={[`${baseClass}__button`, `${baseClass}__button--${style}`].join(' ')}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import type { RichTextCustomElement } from '../../../../../../packages/richtext-slate/src/types.js'
|
|
||||||
|
|
||||||
import { ToolbarButton } from './Button/index.js'
|
|
||||||
import { ButtonElement } from './Element/index.js'
|
|
||||||
import { withButton } from './plugin.js'
|
|
||||||
|
|
||||||
export const button: RichTextCustomElement = {
|
|
||||||
name: 'button',
|
|
||||||
Button: ToolbarButton,
|
|
||||||
Element: ButtonElement,
|
|
||||||
plugins: [withButton],
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import type { Editor } from 'slate'
|
|
||||||
|
|
||||||
export const withButton = (incomingEditor: Editor): Editor => {
|
|
||||||
const editor = incomingEditor
|
|
||||||
const { isVoid } = editor
|
|
||||||
|
|
||||||
editor.isVoid = (element) => (element.type === 'button' ? true : isVoid(element))
|
|
||||||
|
|
||||||
return editor
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
|
|
||||||
import LeafButton from '../../../../../../../packages/payload/src/admin/components/forms/field-types/RichText/leaves/Button'
|
|
||||||
|
|
||||||
const Button = () => <LeafButton format="purple-background">Purple Background</LeafButton>
|
|
||||||
|
|
||||||
export default Button
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
|
|
||||||
const PurpleBackground: React.FC<any> = ({ attributes, children }) => (
|
|
||||||
<span {...attributes} style={{ backgroundColor: 'purple' }}>
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default PurpleBackground
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import Button from './Button/index.js'
|
|
||||||
import Leaf from './Leaf/index.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'purple-background',
|
|
||||||
Button,
|
|
||||||
Leaf,
|
|
||||||
}
|
|
||||||
@@ -3,10 +3,10 @@ import LinkImport from 'next/link.js'
|
|||||||
import { redirect } from 'next/navigation.js'
|
import { redirect } from 'next/navigation.js'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import type { AdminViewProps } from '../../../../../packages/payload/types.js'
|
|
||||||
|
|
||||||
const Link = (LinkImport.default || LinkImport) as unknown as typeof LinkImport.default
|
const Link = (LinkImport.default || LinkImport) as unknown as typeof LinkImport.default
|
||||||
|
|
||||||
|
import type { AdminViewProps } from 'payload/types'
|
||||||
|
|
||||||
import { Button } from '@payloadcms/ui/elements/Button'
|
import { Button } from '@payloadcms/ui/elements/Button'
|
||||||
import { SetStepNav } from '@payloadcms/ui/elements/StepNav'
|
import { SetStepNav } from '@payloadcms/ui/elements/StepNav'
|
||||||
|
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ export default buildConfigWithDefaults({
|
|||||||
custom: 'Hello, world!',
|
custom: 'Hello, world!',
|
||||||
email: devUser.email,
|
email: devUser.email,
|
||||||
password: devUser.password,
|
password: devUser.password,
|
||||||
|
roles: ['admin'],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,6 @@ export interface PayloadMigration {
|
|||||||
|
|
||||||
|
|
||||||
declare module 'payload' {
|
declare module 'payload' {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export interface GeneratedTypes extends Config {}
|
export interface GeneratedTypes extends Config {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { slateEditor } from '@payloadcms/richtext-slate'
|
import { slateEditor } from '@payloadcms/richtext-slate'
|
||||||
|
|
||||||
|
import type { Post } from './payload-types.js'
|
||||||
|
|
||||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||||
import { devUser } from '../credentials.js'
|
import { devUser } from '../credentials.js'
|
||||||
|
|
||||||
@@ -79,6 +81,6 @@ export default buildConfigWithDefaults({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const postDoc = {
|
export const postDoc: Pick<Post, 'title'> = {
|
||||||
title: 'test post',
|
title: 'test post',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ describe('dataloader', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const innerMostRelationship =
|
const innerMostRelationship =
|
||||||
|
// @ts-expect-error Deep typing not worth doing
|
||||||
relationAWithDepth.relationship.relationship.richText[1].value.relationship.relationship
|
relationAWithDepth.relationship.relationship.richText[1].value.relationship.relationship
|
||||||
|
|
||||||
expect(innerMostRelationship).toStrictEqual(relationB.id)
|
expect(innerMostRelationship).toStrictEqual(relationB.id)
|
||||||
|
|||||||
@@ -154,5 +154,6 @@ export interface PayloadMigration {
|
|||||||
|
|
||||||
|
|
||||||
declare module 'payload' {
|
declare module 'payload' {
|
||||||
|
// @ts-ignore
|
||||||
export interface GeneratedTypes extends Config {}
|
export interface GeneratedTypes extends Config {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { SendMailOptions } from 'nodemailer'
|
|
||||||
import type { PaginatedDocs } from 'payload/database'
|
import type { PaginatedDocs } from 'payload/database'
|
||||||
|
import type { SendEmailOptions } from 'payload/types'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
CreateArgs,
|
CreateArgs,
|
||||||
@@ -82,7 +82,7 @@ export class PayloadTestSDK<TGeneratedTypes extends GeneratedTypes<TGeneratedTyp
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEmail = async ({ jwt, ...args }: { jwt?: string } & SendMailOptions): Promise<unknown> => {
|
sendEmail = async ({ jwt, ...args }: { jwt?: string } & SendEmailOptions): Promise<unknown> => {
|
||||||
return this.fetch({
|
return this.fetch({
|
||||||
operation: 'sendEmail',
|
operation: 'sendEmail',
|
||||||
args,
|
args,
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { LivePreviewConfig } from 'payload/config'
|
import type { LivePreviewConfig } from 'payload/config'
|
||||||
|
|
||||||
import type { Tenant } from '../payload-types.js'
|
|
||||||
|
|
||||||
export const formatLivePreviewURL: LivePreviewConfig['url'] = async ({
|
export const formatLivePreviewURL: LivePreviewConfig['url'] = async ({
|
||||||
data,
|
data,
|
||||||
collectionConfig,
|
collectionConfig,
|
||||||
@@ -13,7 +11,7 @@ export const formatLivePreviewURL: LivePreviewConfig['url'] = async ({
|
|||||||
// For example, multi-tenant apps may need to lookup additional data
|
// For example, multi-tenant apps may need to lookup additional data
|
||||||
if (data.tenant) {
|
if (data.tenant) {
|
||||||
try {
|
try {
|
||||||
const fullTenant = (await payload
|
const fullTenant = await payload
|
||||||
.find({
|
.find({
|
||||||
collection: 'tenants',
|
collection: 'tenants',
|
||||||
where: {
|
where: {
|
||||||
@@ -24,7 +22,7 @@ export const formatLivePreviewURL: LivePreviewConfig['url'] = async ({
|
|||||||
limit: 1,
|
limit: 1,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
})
|
})
|
||||||
.then((res) => res?.docs?.[0])) as Tenant
|
.then((res) => res?.docs?.[0])
|
||||||
|
|
||||||
if (fullTenant?.clientURL) {
|
if (fullTenant?.clientURL) {
|
||||||
baseURL = `${fullTenant.clientURL}/live-preview`
|
baseURL = `${fullTenant.clientURL}/live-preview`
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import * as AWS from '@aws-sdk/client-s3'
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
|
|
||||||
|
import type { Config } from './payload-types.js'
|
||||||
|
|
||||||
import { describeIfInCIOrHasLocalstack } from '../helpers.js'
|
import { describeIfInCIOrHasLocalstack } from '../helpers.js'
|
||||||
import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
||||||
import configPromise from './config.js'
|
import configPromise from './config.js'
|
||||||
@@ -103,7 +105,7 @@ describe('@payloadcms/plugin-cloud-storage', () => {
|
|||||||
uploadId,
|
uploadId,
|
||||||
prefix = '',
|
prefix = '',
|
||||||
}: {
|
}: {
|
||||||
collectionSlug: string
|
collectionSlug: keyof Config['collections']
|
||||||
prefix?: string
|
prefix?: string
|
||||||
uploadId: number | string
|
uploadId: number | string
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
// Ideally, this should be "." once we get rid of all relative package paths
|
"rootDir": ".",
|
||||||
"rootDir": "..",
|
"baseUrl": ".",
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"outDir": "./just-in-case",
|
|
||||||
"target": "esnext",
|
"target": "esnext",
|
||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"moduleResolution": "NodeNext",
|
"moduleResolution": "NodeNext",
|
||||||
@@ -17,25 +14,89 @@
|
|||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"sourceMap": true,
|
|
||||||
"strict": false,
|
|
||||||
"types": ["jest", "node", "@types/jest"],
|
"types": ["jest", "node", "@types/jest"],
|
||||||
"incremental": true,
|
// "incremental": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "next"
|
"name": "next"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {}
|
"paths": {
|
||||||
|
"@payload-config": ["./_community/config.ts"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["dist", "build", "node_modules", ".eslintrc.js", "dist/**/*.js", "**/dist/**/*.js"],
|
"exclude": ["dist", "build", "temp", "node_modules"],
|
||||||
"include": [
|
"include": [
|
||||||
// "./test/_community/**/*.ts"
|
// "./test/_community/**/*.ts"
|
||||||
"./**/*.ts"
|
// "./_community/**/*.ts"
|
||||||
// "/**/*.ts",
|
"/**/*.ts"
|
||||||
// "../packages/**/src/**/*.ts",
|
// "../packages/**/src/**/*.ts",
|
||||||
// "../packages/**/src/**/*.tsx"
|
// "../packages/**/src/**/*.tsx"
|
||||||
],
|
],
|
||||||
"references": []
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../packages/create-payload-app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/db-mongodb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/db-postgres"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/graphql"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/live-preview"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/live-preview-react"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/next"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-cloud-storage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-cloud"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-form-builder"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-nested-docs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-redirects"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-search"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-sentry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-seo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/plugin-stripe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/richtext-slate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/richtext-lexical"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/translations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../packages/ui"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -580,6 +580,7 @@ describe('versions', () => {
|
|||||||
collection: autosaveCollectionSlug,
|
collection: autosaveCollectionSlug,
|
||||||
data: {
|
data: {
|
||||||
title: 'some title',
|
title: 'some title',
|
||||||
|
description: 'some description',
|
||||||
},
|
},
|
||||||
draft: true,
|
draft: true,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import { type Payload } from 'payload'
|
import { type Payload } from 'payload'
|
||||||
|
|
||||||
|
import type { DraftPost } from './payload-types.js'
|
||||||
|
|
||||||
import { devUser } from '../credentials.js'
|
import { devUser } from '../credentials.js'
|
||||||
import { executePromises } from '../helpers/executePromises.js'
|
import { executePromises } from '../helpers/executePromises.js'
|
||||||
import { titleToDelete } from './shared.js'
|
import { titleToDelete } from './shared.js'
|
||||||
import { draftCollectionSlug } from './slugs.js'
|
import { draftCollectionSlug } from './slugs.js'
|
||||||
|
|
||||||
export async function seed(_payload: Payload, parallel: boolean = false) {
|
export async function seed(_payload: Payload, parallel: boolean = false) {
|
||||||
const blocksField = [
|
const blocksField: DraftPost['blocksField'] = [
|
||||||
{
|
{
|
||||||
blockType: 'block',
|
blockType: 'block',
|
||||||
localized: 'text',
|
localized: null,
|
||||||
text: 'text',
|
text: 'Hello World',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user