Move to individual custom field saving
Dieser Commit ist enthalten in:
Ursprung
155eabd377
Commit
b383538a6b
14 geänderte Dateien mit 268 neuen und 116 gelöschten Zeilen
|
@ -1,6 +1,6 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import discourseComputed, { discourseObserve } from "discourse-common/utils/decorators";
|
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||||
import { or } from "@ember/object/computed";
|
import { or, alias } from "@ember/object/computed";
|
||||||
|
|
||||||
const generateContent = function(array, type) {
|
const generateContent = function(array, type) {
|
||||||
return array.map(key => ({
|
return array.map(key => ({
|
||||||
|
@ -18,9 +18,17 @@ export default Component.extend({
|
||||||
klassContent: generateContent(['topic', 'post', 'group', 'category'], 'klass'),
|
klassContent: generateContent(['topic', 'post', 'group', 'category'], 'klass'),
|
||||||
typeContent: generateContent(['string', 'boolean', 'integer', 'json'], 'type'),
|
typeContent: generateContent(['string', 'boolean', 'integer', 'json'], 'type'),
|
||||||
showInputs: or('field.new', 'field.edit'),
|
showInputs: or('field.new', 'field.edit'),
|
||||||
|
classNames: ['custom-field-input'],
|
||||||
|
loading: or('saving', 'destroying'),
|
||||||
|
destroyDisabled: alias('loading'),
|
||||||
|
closeDisabled: alias('loading'),
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this.set('originalField', JSON.parse(JSON.stringify(this.field)));
|
||||||
|
},
|
||||||
|
|
||||||
@discourseComputed('field.klass')
|
@discourseComputed('field.klass')
|
||||||
serializerContent(klass) {
|
serializerContent(klass, p2) {
|
||||||
const serializers = this.get(`${klass}Serializers`);
|
const serializers = this.get(`${klass}Serializers`);
|
||||||
|
|
||||||
if (serializers) {
|
if (serializers) {
|
||||||
|
@ -30,6 +38,44 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@observes('field.klass')
|
||||||
|
clearSerializersWhenClassChanges() {
|
||||||
|
this.set('field.serializers', null);
|
||||||
|
},
|
||||||
|
|
||||||
|
compareArrays(array1, array2) {
|
||||||
|
return array1.length === array2.length && array1.every((value, index) => {
|
||||||
|
return value === array2[index];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed(
|
||||||
|
'saving',
|
||||||
|
'field.name',
|
||||||
|
'field.klass',
|
||||||
|
'field.type',
|
||||||
|
'field.serializers'
|
||||||
|
)
|
||||||
|
saveDisabled(saving) {
|
||||||
|
if (saving) return true;
|
||||||
|
|
||||||
|
const originalField = this.originalField;
|
||||||
|
if (!originalField) return false;
|
||||||
|
|
||||||
|
return ['name', 'klass', 'type', 'serializers'].every(attr => {
|
||||||
|
let current = this.get(attr);
|
||||||
|
let original = originalField[attr];
|
||||||
|
|
||||||
|
if (!current) return false;
|
||||||
|
|
||||||
|
if (attr == 'serializers') {
|
||||||
|
return this.compareArrays(current, original);
|
||||||
|
} else {
|
||||||
|
return current == original;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
edit() {
|
edit() {
|
||||||
this.set('field.edit', true);
|
this.set('field.edit', true);
|
||||||
|
@ -42,8 +88,32 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.set('removing', true);
|
this.set('destroying', true);
|
||||||
this.removeField(this.field);
|
this.removeField(this.field);
|
||||||
|
},
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.set('saving', true);
|
||||||
|
|
||||||
|
const field = this.field;
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
id: field.id,
|
||||||
|
klass: field.klass,
|
||||||
|
type: field.type,
|
||||||
|
serializers: field.serializers,
|
||||||
|
name: field.name
|
||||||
|
}
|
||||||
|
|
||||||
|
this.saveField(data).then((result) => {
|
||||||
|
if (result.success) {
|
||||||
|
this.set('saveIcon', 'check');
|
||||||
|
} else {
|
||||||
|
this.set('saveIcon', 'times');
|
||||||
|
}
|
||||||
|
setTimeout(() => this.set('saveIcon', null), 10000);
|
||||||
|
this.set('saving', false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -3,8 +3,10 @@ import EmberObject from '@ember/object';
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
import CustomWizardCustomField from "../models/custom-wizard-custom-field";
|
import CustomWizardCustomField from "../models/custom-wizard-custom-field";
|
||||||
|
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
|
messageKey: 'create',
|
||||||
fieldKeys: ['klass', 'type', 'serializers', 'name'],
|
fieldKeys: ['klass', 'type', 'serializers', 'name'],
|
||||||
documentationUrl: "https://thepavilion.io/t/3572",
|
documentationUrl: "https://thepavilion.io/t/3572",
|
||||||
|
|
||||||
|
@ -15,24 +17,36 @@ export default Controller.extend({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
saveFields() {
|
saveField(field) {
|
||||||
this.set('saving', true);
|
return CustomWizardCustomField.saveField(field)
|
||||||
CustomWizardCustomField.saveFields(this.customFields)
|
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.set('saveIcon', 'check');
|
this.setProperties({
|
||||||
|
messageKey: 'saved',
|
||||||
|
messageType: 'success'
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.set('saveIcon', 'times');
|
if (result.messages) {
|
||||||
|
this.setProperties({
|
||||||
|
messageKey: 'error',
|
||||||
|
messageType: 'error',
|
||||||
|
messageOpts: { messages: result.messages }
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setTimeout(() => this.set('saveIcon', ''), 5000);
|
|
||||||
this.get('customFields').setEach('edit', false);
|
setTimeout(() => this.setProperties({
|
||||||
}).finally(() => {
|
messageKey: 'create',
|
||||||
this.set('saving', false);
|
messageType: null,
|
||||||
|
messageOpts: null
|
||||||
|
}), 10000);
|
||||||
|
|
||||||
|
return result;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
removeField(field) {
|
removeField(field) {
|
||||||
CustomWizardCustomField.removeField(field)
|
return CustomWizardCustomField.destroyField(field)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
this.get('customFields').removeObject(field);
|
this.get('customFields').removeObject(field);
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,18 +14,16 @@ CustomWizardCustomField.reopenClass({
|
||||||
return ajax(basePath).catch(popupAjaxError);
|
return ajax(basePath).catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
saveFields(customFields) {
|
saveField(customField) {
|
||||||
return ajax(basePath, {
|
return ajax(basePath, {
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
dataType: 'json',
|
data: {
|
||||||
contentType: 'application/json',
|
custom_field: customField
|
||||||
data: JSON.stringify({
|
}
|
||||||
custom_fields: customFields
|
|
||||||
})
|
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
removeField(field) {
|
destroyField(field) {
|
||||||
return ajax(`${basePath}/${field.name}`, {
|
return ajax(`${basePath}/${field.name}`, {
|
||||||
type: 'DELETE'
|
type: 'DELETE'
|
||||||
}).catch(popupAjaxError);
|
}).catch(popupAjaxError);
|
||||||
|
|
|
@ -2,16 +2,6 @@
|
||||||
<h3>{{i18n 'admin.wizard.custom_field.nav_label'}}</h3>
|
<h3>{{i18n 'admin.wizard.custom_field.nav_label'}}</h3>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
{{#if saving}}
|
|
||||||
{{loading-spinner size="small"}}
|
|
||||||
{{else}}
|
|
||||||
{{#if saveIcon}}
|
|
||||||
{{d-icon saveIcon}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{d-button
|
|
||||||
label="admin.wizard.custom_field.save"
|
|
||||||
action="saveFields"}}
|
|
||||||
{{d-button
|
{{d-button
|
||||||
label="admin.wizard.custom_field.add"
|
label="admin.wizard.custom_field.add"
|
||||||
icon="plus"
|
icon="plus"
|
||||||
|
@ -20,7 +10,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{wizard-message
|
{{wizard-message
|
||||||
key='create'
|
key=messageKey
|
||||||
|
opts=messageOpts
|
||||||
|
type=messageType
|
||||||
url=documentationUrl
|
url=documentationUrl
|
||||||
component='custom_fields'}}
|
component='custom_fields'}}
|
||||||
|
|
||||||
|
@ -36,7 +28,8 @@
|
||||||
{{#each customFields as |field|}}
|
{{#each customFields as |field|}}
|
||||||
{{custom-field-input
|
{{custom-field-input
|
||||||
field=field
|
field=field
|
||||||
removeField=(action 'removeField')}}
|
removeField=(action 'removeField')
|
||||||
|
saveField=(action 'saveField')}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</table>
|
</table>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -13,40 +13,51 @@
|
||||||
none="admin.wizard.custom_field.type.select"
|
none="admin.wizard.custom_field.type.select"
|
||||||
onChange=(action (mut field.type))}}
|
onChange=(action (mut field.type))}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="multi-select">
|
||||||
{{multi-select
|
{{multi-select
|
||||||
value=field.serializers
|
value=field.serializers
|
||||||
content=serializerContent
|
content=serializerContent
|
||||||
none="admin.wizard.custom_field.serializers.select"
|
none="admin.wizard.custom_field.serializers.select"
|
||||||
onChange=(action (mut field.serializers))}}
|
onChange=(action (mut field.serializers))}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="input">
|
||||||
{{input
|
{{input
|
||||||
value=field.name
|
value=field.name
|
||||||
placeholder=(i18n "admin.wizard.custom_field.klass.select")}}
|
placeholder=(i18n "admin.wizard.custom_field.name.select")}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="actions">
|
||||||
{{d-button action="close" icon="times"}}
|
{{#if loading}}
|
||||||
|
{{loading-spinner size="small"}}
|
||||||
|
{{else}}
|
||||||
|
{{#if saveIcon}}
|
||||||
|
{{d-icon saveIcon}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{d-button
|
||||||
|
action="destroy"
|
||||||
|
icon="trash-alt"
|
||||||
|
class="destroy"
|
||||||
|
disabled=destroyDisabled}}
|
||||||
|
{{d-button
|
||||||
|
icon="save"
|
||||||
|
action="save"
|
||||||
|
disabled=saveDisabled
|
||||||
|
class="save"}}
|
||||||
|
{{d-button
|
||||||
|
action="close"
|
||||||
|
icon="times"
|
||||||
|
disabled=closeDisabled}}
|
||||||
</td>
|
</td>
|
||||||
{{else}}
|
{{else}}
|
||||||
<td><label>{{field.klass}}</label></td>
|
<td><label>{{field.klass}}</label></td>
|
||||||
<td><label>{{field.type}}</label></td>
|
<td><label>{{field.type}}</label></td>
|
||||||
<td>
|
<td class="multi-select">
|
||||||
{{#each field.serializers as |serializer|}}
|
{{#each field.serializers as |serializer|}}
|
||||||
<label>{{serializer}}</label>
|
<label>{{serializer}}</label>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</td>
|
</td>
|
||||||
<td><label>{{field.name}}</label></td>
|
<td class="input"><label>{{field.name}}</label></td>
|
||||||
<td>
|
<td class="actions">
|
||||||
{{d-button action="edit" icon="pencil-alt"}}
|
{{d-button action="edit" icon="pencil-alt"}}
|
||||||
{{#if field.edit}}
|
|
||||||
{{d-button action="close" icon="times"}}
|
|
||||||
{{else}}
|
|
||||||
{{#if destroying}}
|
|
||||||
{{loading-spinner size="small"}}
|
|
||||||
{{else}}
|
|
||||||
{{d-button action="destroy" icon="trash-alt"}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
</td>
|
||||||
{{/if}}
|
{{/if}}
|
|
@ -1,6 +1,7 @@
|
||||||
@import 'wizard-mapper';
|
@import 'wizard-mapper';
|
||||||
@import 'wizard-manager';
|
@import 'wizard-manager';
|
||||||
@import 'wizard-api';
|
@import 'wizard-api';
|
||||||
|
@import 'common/components/buttons';
|
||||||
|
|
||||||
.admin-wizard-controls {
|
.admin-wizard-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -565,16 +566,35 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-wizards-custom-fields {
|
.admin-wizards-custom-fields {
|
||||||
|
.admin-wizard-controls {
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button.btn {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.save:enabled {
|
||||||
|
@extend .btn-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.destroy {
|
||||||
|
@extend .btn-danger;
|
||||||
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-kit {
|
.select-kit {
|
||||||
width: 200px;
|
width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-kit.multi-select {
|
.select-kit.multi-select {
|
||||||
width: 200px;
|
width: 300px;
|
||||||
|
|
||||||
.choices .choice,
|
.choices .choice,
|
||||||
.select-kit-filter .filter-input {
|
.select-kit-filter .filter-input {
|
||||||
|
@ -587,20 +607,39 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
table {
|
||||||
vertical-align: top;
|
td {
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
min-width: 170px;
|
||||||
|
width: 170px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.multi-select {
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.input {
|
||||||
|
min-width: 210px;
|
||||||
|
width: 210px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.actions {
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
button.btn {
|
||||||
|
margin-left: 5px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
td:not(:last-of-type) {
|
|
||||||
min-width: 230px;
|
|
||||||
}
|
|
||||||
|
|
||||||
td:last-of-type {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -73,7 +73,9 @@ en:
|
||||||
edit: "You're editing an action"
|
edit: "You're editing an action"
|
||||||
documentation: "Check out the action documentation"
|
documentation: "Check out the action documentation"
|
||||||
custom_fields:
|
custom_fields:
|
||||||
create: "Create or edit a custom field record"
|
create: "Create, edit or destroy a custom field record"
|
||||||
|
saved: "Saved custom field"
|
||||||
|
error: "Failed to save: {{messages}}"
|
||||||
documentation: Check out the custom field documentation
|
documentation: Check out the custom field documentation
|
||||||
manager:
|
manager:
|
||||||
info: "Export, import or destroy wizards"
|
info: "Export, import or destroy wizards"
|
||||||
|
@ -296,11 +298,10 @@ en:
|
||||||
|
|
||||||
custom_field:
|
custom_field:
|
||||||
nav_label: "Custom Fields"
|
nav_label: "Custom Fields"
|
||||||
add: "Add Custom Field"
|
add: "Add"
|
||||||
save: "Save Custom Fields"
|
|
||||||
name:
|
name:
|
||||||
label: "Name"
|
label: "Name"
|
||||||
select: "Enter a name"
|
select: "underscored_name"
|
||||||
type:
|
type:
|
||||||
label: "Type"
|
label: "Type"
|
||||||
select: "Select a type"
|
select: "Select a type"
|
||||||
|
@ -322,6 +323,7 @@ en:
|
||||||
topic_view: "Topic View"
|
topic_view: "Topic View"
|
||||||
topic_list_item: "Topic List Item"
|
topic_list_item: "Topic List Item"
|
||||||
basic_category: "Category"
|
basic_category: "Category"
|
||||||
|
basic_group: "Group"
|
||||||
post: "Post"
|
post: "Post"
|
||||||
|
|
||||||
submissions:
|
submissions:
|
||||||
|
|
|
@ -4,39 +4,38 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
fields_to_save = []
|
errors = []
|
||||||
|
field_id = nil
|
||||||
custom_field_params[:custom_fields].each do |field_param|
|
field_data = {}
|
||||||
field_id = nil
|
|
||||||
field_data = {}
|
|
||||||
|
|
||||||
if saved_field = CustomWizard::CustomField.find(field_param[:name])
|
|
||||||
CustomWizard::CustomField::ATTRS.each do |attr|
|
|
||||||
field_data[attr] = saved_field.send(attr)
|
|
||||||
end
|
|
||||||
field_id = saved_field.id
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if saved_field = CustomWizard::CustomField.find(field_params[:id].to_i)
|
||||||
CustomWizard::CustomField::ATTRS.each do |attr|
|
CustomWizard::CustomField::ATTRS.each do |attr|
|
||||||
field_data[attr] = field_param[attr]
|
field_data[attr] = saved_field.send(attr)
|
||||||
end
|
end
|
||||||
|
field_id = saved_field.id
|
||||||
field = CustomWizard::CustomField.new(field_id, field_data)
|
|
||||||
fields_to_save.push(field)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
CustomWizard::CustomField::ATTRS.each do |attr|
|
||||||
|
field_data[attr] = field_params[attr]
|
||||||
|
end
|
||||||
|
|
||||||
|
field = CustomWizard::CustomField.new(field_id, field_data)
|
||||||
|
|
||||||
PluginStoreRow.transaction do
|
PluginStoreRow.transaction do
|
||||||
fields_to_save.each do |field|
|
unless field.save
|
||||||
unless field.save
|
field_errors = field.errors.any? ?
|
||||||
raise ActiveRecord::Rollback.new,
|
field.errors.full_messages.join("\n\n") :
|
||||||
field.errors.any? ?
|
I18n.t("wizard.custom_field.error.save_default", name: field.name)
|
||||||
field.errors.full_messages.join("\n\n") :
|
errors << field_errors
|
||||||
I18n.t("wizard.custom_field.error.save_default", name: field.name)
|
raise ActiveRecord::Rollback.new
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: success_json
|
if errors.any?
|
||||||
|
render json: failed_json.merge(messages: errors)
|
||||||
|
else
|
||||||
|
render json: success_json
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
@ -51,14 +50,14 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def custom_field_params
|
def field_params
|
||||||
params.permit(
|
params.required(:custom_field)
|
||||||
custom_fields: [
|
.permit(
|
||||||
|
:id,
|
||||||
:name,
|
:name,
|
||||||
:klass,
|
:klass,
|
||||||
:type,
|
:type,
|
||||||
serializers: []
|
serializers: []
|
||||||
]
|
)
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"result": {
|
"result": {
|
||||||
"covered_percent": 89.04
|
"covered_percent": 89.03
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ class ::CustomWizard::CustomField
|
||||||
attr_reader :id
|
attr_reader :id
|
||||||
|
|
||||||
ATTRS ||= ["name", "klass", "type", "serializers"]
|
ATTRS ||= ["name", "klass", "type", "serializers"]
|
||||||
REQUIRED ||= ["name", "klass"]
|
REQUIRED ||= ["name", "klass", "type"]
|
||||||
NAMESPACE ||= "custom_wizard_custom_fields"
|
NAMESPACE ||= "custom_wizard_custom_fields"
|
||||||
NAME_MIN_LENGTH ||= 3
|
NAME_MIN_LENGTH ||= 3
|
||||||
|
|
||||||
|
@ -143,11 +143,21 @@ class ::CustomWizard::CustomField
|
||||||
PluginStoreRow.where(plugin_name: NAMESPACE, key: name).exists?
|
PluginStoreRow.where(plugin_name: NAMESPACE, key: name).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find(name)
|
def self.find(field_id)
|
||||||
records = PluginStoreRow.where(plugin_name: NAMESPACE, key: name)
|
record = PluginStoreRow.find_by(id: field_id, plugin_name: NAMESPACE)
|
||||||
|
|
||||||
if records.exists?
|
if record
|
||||||
create_from_store(records.first)
|
create_from_store(record)
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.find_by_name(name)
|
||||||
|
record = PluginStoreRow.find_by(key: name, plugin_name: NAMESPACE)
|
||||||
|
|
||||||
|
if record
|
||||||
|
create_from_store(record)
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -161,8 +171,9 @@ class ::CustomWizard::CustomField
|
||||||
|
|
||||||
def self.save_to_store(id = nil, key, data)
|
def self.save_to_store(id = nil, key, data)
|
||||||
if id
|
if id
|
||||||
record = PluginStoreRow.find_by(id: id, plugin_name: NAMESPACE, key: key)
|
record = PluginStoreRow.find_by(id: id, plugin_name: NAMESPACE)
|
||||||
return false if !record
|
return false if !record
|
||||||
|
record.key = key
|
||||||
record.value = data.to_json
|
record.value = data.to_json
|
||||||
record.save
|
record.save
|
||||||
else
|
else
|
||||||
|
|
|
@ -31,6 +31,7 @@ if respond_to?(:register_svg_icon)
|
||||||
register_svg_icon "far-calendar"
|
register_svg_icon "far-calendar"
|
||||||
register_svg_icon "chevron-right"
|
register_svg_icon "chevron-right"
|
||||||
register_svg_icon "chevron-left"
|
register_svg_icon "chevron-left"
|
||||||
|
register_svg_icon "save"
|
||||||
end
|
end
|
||||||
|
|
||||||
after_initialize do
|
after_initialize do
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe CustomWizard::CustomField do
|
||||||
|
|
||||||
updated_field_json = custom_field_json['custom_fields'][0]
|
updated_field_json = custom_field_json['custom_fields'][0]
|
||||||
updated_field_json['serializers'] = ["topic_view"]
|
updated_field_json['serializers'] = ["topic_view"]
|
||||||
existing_field = CustomWizard::CustomField.find(updated_field_json["name"])
|
existing_field = CustomWizard::CustomField.find_by_name(updated_field_json["name"])
|
||||||
updated_field = CustomWizard::CustomField.new(existing_field.id, updated_field_json)
|
updated_field = CustomWizard::CustomField.new(existing_field.id, updated_field_json)
|
||||||
|
|
||||||
expect(updated_field.save).to eq(true)
|
expect(updated_field.save).to eq(true)
|
||||||
|
|
|
@ -21,12 +21,26 @@ describe CustomWizard::AdminCustomFieldsController do
|
||||||
expect(response.parsed_body.length).to eq(4)
|
expect(response.parsed_body.length).to eq(4)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates the list of custom fields" do
|
it "saves custom fields" do
|
||||||
custom_field_json['custom_fields'][0]['type'] = 'string'
|
topic_field = CustomWizard::CustomField.find_by_name('topic_field_1')
|
||||||
put "/admin/wizards/custom-fields.json", params: custom_field_json
|
topic_field_json = topic_field.as_json
|
||||||
|
topic_field_json['type'] = 'string'
|
||||||
|
|
||||||
|
put "/admin/wizards/custom-fields.json", params: {
|
||||||
|
custom_field: topic_field_json
|
||||||
|
}
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
expect(
|
expect(
|
||||||
CustomWizard::CustomField.find('topic_field_1').type
|
CustomWizard::CustomField.find_by_name('topic_field_1').type
|
||||||
).to eq('string')
|
).to eq('string')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "destroys custom fields" do
|
||||||
|
topic_field = custom_field_json['custom_fields'][0]
|
||||||
|
delete "/admin/wizards/custom-fields/#{topic_field["name"]}.json"
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(
|
||||||
|
CustomWizard::CustomField.exists?('topic_field_1')
|
||||||
|
).to eq(false)
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -17,7 +17,7 @@ describe CustomWizard::CustomFieldSerializer do
|
||||||
end
|
end
|
||||||
|
|
||||||
json = CustomWizard::CustomFieldSerializer.new(
|
json = CustomWizard::CustomFieldSerializer.new(
|
||||||
CustomWizard::CustomField.find("topic_field_1"),
|
CustomWizard::CustomField.find_by_name("topic_field_1"),
|
||||||
scope: Guardian.new(user),
|
scope: Guardian.new(user),
|
||||||
root: false
|
root: false
|
||||||
).as_json
|
).as_json
|
||||||
|
|
Laden …
In neuem Issue referenzieren