FEATURE: new field type Composer Preview (#130)
* WIP * composer preview field working * remove redundant variable * fix linting issues * fix rubocop * remove unnecessary entry * consolidate preview generation code * add styles for onebox * add css for @ mentions * fixed eslint issues * FIX: ensure oneboxes load every time * remove unused import * fix prettier issues * removed unused code * remove unused imports * fixed prettier issue * improve css structure * add csrf header in all cases
Dieser Commit ist enthalten in:
Ursprung
d88d2b7d97
Commit
ca10ae797a
12 geänderte Dateien mit 127 neuen und 26 gelöschten Zeilen
|
@ -25,6 +25,7 @@ export default Component.extend(UndoChanges, {
|
||||||
showContent: or("isCategory", "isTag", "isGroup", "isDropdown"),
|
showContent: or("isCategory", "isTag", "isGroup", "isDropdown"),
|
||||||
showLimit: or("isCategory", "isTag"),
|
showLimit: or("isCategory", "isTag"),
|
||||||
isTextType: or("isText", "isTextarea", "isComposer"),
|
isTextType: or("isText", "isTextarea", "isComposer"),
|
||||||
|
isComposerPreview: equal("field.type", "composer_preview"),
|
||||||
categoryPropertyTypes: selectKitContent(["id", "slug"]),
|
categoryPropertyTypes: selectKitContent(["id", "slug"]),
|
||||||
showAdvanced: alias("field.type"),
|
showAdvanced: alias("field.type"),
|
||||||
messageUrl: "https://thepavilion.io/t/2809",
|
messageUrl: "https://thepavilion.io/t/2809",
|
||||||
|
|
|
@ -125,6 +125,18 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isComposerPreview}}
|
||||||
|
<div class="setting">
|
||||||
|
<div class="setting-label">
|
||||||
|
<label>{{i18n "admin.wizard.field.preview_template"}}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="setting-value">
|
||||||
|
{{textarea name="preview-template" value=field.preview_template}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if isUpload}}
|
{{#if isUpload}}
|
||||||
<div class="setting">
|
<div class="setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
import { loadOneboxes } from "discourse/lib/load-oneboxes";
|
||||||
|
import { schedule } from "@ember/runloop";
|
||||||
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
|
import { resolveAllShortUrls } from "pretty-text/upload-short-url";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import { on } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
@on("init")
|
||||||
|
updatePreview() {
|
||||||
|
if (this.isDestroyed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
schedule("afterRender", () => {
|
||||||
|
if (this._state !== "inDOM" || !this.element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const $preview = $(this.element);
|
||||||
|
|
||||||
|
if ($preview.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.previewUpdated($preview);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
previewUpdated($preview) {
|
||||||
|
// Paint oneboxes
|
||||||
|
const paintFunc = () => {
|
||||||
|
loadOneboxes(
|
||||||
|
$preview[0],
|
||||||
|
ajax,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
this.siteSettings.max_oneboxes_per_post,
|
||||||
|
true // refresh on every load
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
discourseDebounce(this, paintFunc, 450);
|
||||||
|
|
||||||
|
// Short upload urls need resolution
|
||||||
|
resolveAllShortUrls(ajax, this.siteSettings, $preview[0]);
|
||||||
|
},
|
||||||
|
});
|
|
@ -29,8 +29,6 @@ export default {
|
||||||
const getToken = requirejs("wizard/lib/ajax").getToken;
|
const getToken = requirejs("wizard/lib/ajax").getToken;
|
||||||
const setEnvironment = requirejs("discourse-common/config/environment")
|
const setEnvironment = requirejs("discourse-common/config/environment")
|
||||||
.setEnvironment;
|
.setEnvironment;
|
||||||
const isDevelopment = requirejs("discourse-common/config/environment")
|
|
||||||
.isDevelopment;
|
|
||||||
const container = app.__container__;
|
const container = app.__container__;
|
||||||
Discourse.Model = EmberObject.extend();
|
Discourse.Model = EmberObject.extend();
|
||||||
Discourse.__container__ = container;
|
Discourse.__container__ = container;
|
||||||
|
@ -114,9 +112,7 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
$.ajaxPrefilter(function (_, __, jqXHR) {
|
$.ajaxPrefilter(function (_, __, jqXHR) {
|
||||||
if (isDevelopment()) {
|
|
||||||
jqXHR.setRequestHeader("X-CSRF-Token", getToken());
|
jqXHR.setRequestHeader("X-CSRF-Token", getToken());
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="wizard-composer-preview d-editor-preview-wrapper">
|
||||||
|
<div class="d-editor-preview">
|
||||||
|
{{html-safe field.preview_template}}
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -239,8 +239,19 @@
|
||||||
|
|
||||||
// Markdown table styles for wizard composer preview
|
// Markdown table styles for wizard composer preview
|
||||||
|
|
||||||
.cooked table,
|
.cooked,
|
||||||
.d-editor-preview table {
|
.d-editor-preview {
|
||||||
|
a.mention {
|
||||||
|
display: inline-block; // https://bugzilla.mozilla.org/show_bug.cgi?id=1656119
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.93em;
|
||||||
|
color: var(--primary-high-or-secondary-low);
|
||||||
|
padding: 0 4px 1px;
|
||||||
|
background: var(--primary-low);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
|
@ -267,3 +278,4 @@
|
||||||
padding: 3px 3px 3px 0.5em;
|
padding: 3px 3px 3px 0.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
@import "common/foundation/variables";
|
@import "common/foundation/variables";
|
||||||
@import "common/base/code_highlighting";
|
@import "common/base/code_highlighting";
|
||||||
@import "common/base/modal";
|
@import "common/base/modal";
|
||||||
|
@import "common/base/onebox";
|
||||||
@import "common/components/buttons";
|
@import "common/components/buttons";
|
||||||
@import "common/d-editor";
|
@import "common/d-editor";
|
||||||
@import "desktop/modal";
|
@import "desktop/modal";
|
||||||
|
|
|
@ -175,6 +175,7 @@ en:
|
||||||
char_counter_placeholder: "Display Character Counter"
|
char_counter_placeholder: "Display Character Counter"
|
||||||
field_placeholder: "Field Placeholder"
|
field_placeholder: "Field Placeholder"
|
||||||
file_types: "File Types"
|
file_types: "File Types"
|
||||||
|
preview_template: "Preview Template"
|
||||||
limit: "Limit"
|
limit: "Limit"
|
||||||
property: "Property"
|
property: "Property"
|
||||||
prefill: "Prefill"
|
prefill: "Prefill"
|
||||||
|
@ -201,6 +202,7 @@ en:
|
||||||
text: "Text"
|
text: "Text"
|
||||||
textarea: Textarea
|
textarea: Textarea
|
||||||
composer: Composer
|
composer: Composer
|
||||||
|
composer_preview: Composer Preview
|
||||||
text_only: Text Only
|
text_only: Text Only
|
||||||
number: Number
|
number: Number
|
||||||
checkbox: Checkbox
|
checkbox: Checkbox
|
||||||
|
|
|
@ -109,6 +109,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
||||||
:format,
|
:format,
|
||||||
:limit,
|
:limit,
|
||||||
:property,
|
:property,
|
||||||
|
:preview_template,
|
||||||
:placeholder,
|
:placeholder,
|
||||||
prefill: mapped_params,
|
prefill: mapped_params,
|
||||||
content: mapped_params,
|
content: mapped_params,
|
||||||
|
|
|
@ -187,6 +187,18 @@ class CustomWizard::Builder
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if field_template['preview_template'].present?
|
||||||
|
preview_template = mapper.interpolate(
|
||||||
|
field_template['preview_template'],
|
||||||
|
user: true,
|
||||||
|
value: true,
|
||||||
|
wizard: true,
|
||||||
|
template: true
|
||||||
|
)
|
||||||
|
|
||||||
|
params[:preview_template] = PrettyText.cook(preview_template)
|
||||||
|
end
|
||||||
|
|
||||||
if field_template['placeholder'].present?
|
if field_template['placeholder'].present?
|
||||||
params[:placeholder] = mapper.interpolate(
|
params[:placeholder] = mapper.interpolate(
|
||||||
field_template['placeholder'],
|
field_template['placeholder'],
|
||||||
|
|
|
@ -21,6 +21,7 @@ class CustomWizard::Field
|
||||||
:limit,
|
:limit,
|
||||||
:property,
|
:property,
|
||||||
:content,
|
:content,
|
||||||
|
:preview_template,
|
||||||
:placeholder
|
:placeholder
|
||||||
|
|
||||||
attr_accessor :index,
|
attr_accessor :index,
|
||||||
|
@ -45,6 +46,7 @@ class CustomWizard::Field
|
||||||
@limit = attrs[:limit]
|
@limit = attrs[:limit]
|
||||||
@property = attrs[:property]
|
@property = attrs[:property]
|
||||||
@content = attrs[:content]
|
@content = attrs[:content]
|
||||||
|
@preview_template = attrs[:preview_template]
|
||||||
@placeholder = attrs[:placeholder]
|
@placeholder = attrs[:placeholder]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -82,6 +84,9 @@ class CustomWizard::Field
|
||||||
placeholder: nil
|
placeholder: nil
|
||||||
},
|
},
|
||||||
text_only: {},
|
text_only: {},
|
||||||
|
composer_preview: {
|
||||||
|
preview_template: nil,
|
||||||
|
},
|
||||||
date: {
|
date: {
|
||||||
format: "YYYY-MM-DD"
|
format: "YYYY-MM-DD"
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,8 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
:content,
|
:content,
|
||||||
:validations,
|
:validations,
|
||||||
:max_length,
|
:max_length,
|
||||||
:char_counter
|
:char_counter,
|
||||||
|
:preview_template
|
||||||
|
|
||||||
def id
|
def id
|
||||||
object.id
|
object.id
|
||||||
|
@ -117,4 +118,8 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
def char_counter
|
def char_counter
|
||||||
object.char_counter
|
object.char_counter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def preview_template
|
||||||
|
object.preview_template
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Laden …
In neuem Issue referenzieren