mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
chore(n8n Form Node): Incorporate design feedback for Custom HTML (#12817)
This commit is contained in:
parent
b60011a180
commit
ddc40ef7de
|
@ -6,13 +6,9 @@
|
||||||
<meta property="og:title" content="{{formTitle}}" />
|
<meta property="og:title" content="{{formTitle}}" />
|
||||||
<meta property="og:description" content="{{formDescriptionMetadata}}" />
|
<meta property="og:description" content="{{formDescriptionMetadata}}" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:image" content="https://raw.githubusercontent.com/n8n-io/n8n/80be10551eb081cb11bd8cab6c6ff89e44493d2c/assets/og_image.png?raw=true" />
|
<meta property="og:image" content="/static/og_image.png" />
|
||||||
<link rel='icon' type='image/png' href='https://n8n.io/favicon.ico' />
|
<link rel='icon' type='image/png' href='https://n8n.io/favicon.ico' />
|
||||||
<link
|
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap" rel="stylesheet">
|
||||||
href='https://fonts.googleapis.com/css?family=Open+Sans'
|
|
||||||
rel='stylesheet'
|
|
||||||
type='text/css'
|
|
||||||
/>
|
|
||||||
<title>{{formTitle}}</title>
|
<title>{{formTitle}}</title>
|
||||||
<style>
|
<style>
|
||||||
*,
|
*,
|
||||||
|
@ -25,7 +21,7 @@
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family:
|
font-family:
|
||||||
Open Sans,
|
"Open Sans",
|
||||||
sans-serif;
|
sans-serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -288,6 +284,60 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.html {
|
||||||
|
text-align: left;
|
||||||
|
color: #555;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
div.html h1, div.html h2, div.html h3, div.html h4, div.html h5, div.html h6, div.html p, div.html ul, div.html ol, div.html a {
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
div.html li {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
div.html ul, div.html ol {
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-self: stretch;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
div.html b {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
div.html h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
line-height: 35px;
|
||||||
|
}
|
||||||
|
div.html h2 {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 26px;
|
||||||
|
}
|
||||||
|
div.html h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
div.html h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
div.html h5 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
div.html h6 {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
div.html p {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
div.html a {
|
||||||
|
color: #FF6D5A;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 500px) {
|
@media only screen and (max-width: 500px) {
|
||||||
body {
|
body {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -372,8 +422,9 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isHtml}}
|
{{#if isHtml}}
|
||||||
<div class="form-group">
|
<div class="form-group html">
|
||||||
{{{html}}}
|
{{{html}}}
|
||||||
|
<input type="hidden" id="{{id}}" name="{{id}}" value="{{html}}" />
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
BIN
packages/editor-ui/public/static/og_image.png
Normal file
BIN
packages/editor-ui/public/static/og_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
|
@ -57,7 +57,7 @@ export const formFields: INodeProperties = {
|
||||||
name: 'values',
|
name: 'values',
|
||||||
values: [
|
values: [
|
||||||
{
|
{
|
||||||
displayName: 'Field Label',
|
displayName: 'Field Name',
|
||||||
name: 'fieldLabel',
|
name: 'fieldLabel',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
|
@ -66,7 +66,7 @@ export const formFields: INodeProperties = {
|
||||||
required: true,
|
required: true,
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
hide: {
|
hide: {
|
||||||
fieldType: ['hiddenField'],
|
fieldType: ['hiddenField', 'html'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -120,6 +120,19 @@ export const formFields: INodeProperties = {
|
||||||
],
|
],
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Element Name',
|
||||||
|
name: 'elementName',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'e.g. content-section',
|
||||||
|
description: 'Optional field. It can be used to include the html in the output.',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
fieldType: ['html'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Placeholder',
|
displayName: 'Placeholder',
|
||||||
name: 'placeholder',
|
name: 'placeholder',
|
||||||
|
@ -204,14 +217,16 @@ export const formFields: INodeProperties = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'HTML Template',
|
displayName: 'HTML',
|
||||||
name: 'html',
|
name: 'html',
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
editor: 'htmlEditor',
|
editor: 'htmlEditor',
|
||||||
},
|
},
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
noDataExpression: true,
|
||||||
default: placeholder,
|
default: placeholder,
|
||||||
description: 'HTML template to render',
|
description: 'HTML elements to display on the form page',
|
||||||
|
hint: 'Does not accept <code><script></code>, <code><style></code> or <code><input></code> tags',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
fieldType: ['html'],
|
fieldType: ['html'],
|
||||||
|
@ -256,18 +271,6 @@ export const formFields: INodeProperties = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
displayName:
|
|
||||||
'Does not accept <code><style></code> <code><script></code> or <code><input></code> tags.',
|
|
||||||
name: 'htmlTips',
|
|
||||||
type: 'notice',
|
|
||||||
default: '',
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
fieldType: ['html'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
displayName: 'Required Field',
|
displayName: 'Required Field',
|
||||||
name: 'requiredField',
|
name: 'requiredField',
|
||||||
|
|
|
@ -743,6 +743,22 @@ describe('prepareFormReturnItem', () => {
|
||||||
|
|
||||||
expect(result.json.formQueryParameters).toEqual(staticData);
|
expect(result.json.formQueryParameters).toEqual(staticData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return html if field name is set', async () => {
|
||||||
|
mockContext.getBodyData.mockReturnValue({
|
||||||
|
data: { 'field-0': '<div>hi</div>', 'field-1': '<h1><haha/hi>' },
|
||||||
|
files: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formFields = [
|
||||||
|
{ fieldLabel: '', elementName: 'greeting', fieldType: 'html' },
|
||||||
|
{ fieldLabel: '', elementName: '', fieldType: 'html' },
|
||||||
|
];
|
||||||
|
const result = await prepareFormReturnItem(mockContext, formFields, 'production');
|
||||||
|
|
||||||
|
expect(result.json.greeting).toBe('<div>hi</div>');
|
||||||
|
expect(result.json.formMode).toBe('production');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resolveRawData', () => {
|
describe('resolveRawData', () => {
|
||||||
|
|
|
@ -50,6 +50,10 @@ export function sanitizeHtml(text: string) {
|
||||||
'pre',
|
'pre',
|
||||||
'span',
|
'span',
|
||||||
'br',
|
'br',
|
||||||
|
'ul',
|
||||||
|
'ol',
|
||||||
|
'li',
|
||||||
|
'p',
|
||||||
],
|
],
|
||||||
allowedAttributes: {
|
allowedAttributes: {
|
||||||
a: ['href', 'target', 'rel'],
|
a: ['href', 'target', 'rel'],
|
||||||
|
@ -280,6 +284,13 @@ export async function prepareFormReturnItem(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (field.fieldType === 'html') {
|
||||||
|
if (field.elementName) {
|
||||||
|
returnItem.json[field.elementName as string] = value;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (field.fieldType === 'number') {
|
if (field.fieldType === 'number') {
|
||||||
value = Number(value);
|
value = Number(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2677,6 +2677,7 @@ export interface ResourceMapperField {
|
||||||
|
|
||||||
export type FormFieldsParameter = Array<{
|
export type FormFieldsParameter = Array<{
|
||||||
fieldLabel: string;
|
fieldLabel: string;
|
||||||
|
elementName?: string;
|
||||||
fieldType?: string;
|
fieldType?: string;
|
||||||
requiredField?: boolean;
|
requiredField?: boolean;
|
||||||
fieldOptions?: { values: Array<{ option: string }> };
|
fieldOptions?: { values: Array<{ option: string }> };
|
||||||
|
|
Loading…
Reference in a new issue