Skip to content

Commit

Permalink
Do not sync non-react widgets to scrolled state in editor
Browse files Browse the repository at this point in the history
Align with seed of published entries. Otherwise this causes problems
when a template based widgets uses a role that is also used by
Pageflow Scrolled since there is then no component to render it.

REDMINE-20765
  • Loading branch information
tf committed Jun 28, 2024
1 parent 2258013 commit 4c3520e
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 6 deletions.
3 changes: 2 additions & 1 deletion app/helpers/pageflow/widgets_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def widget_types_json_seeds(config)
result[role] ||= []
result[role] << {
name: widget_type.name,
translationKey: widget_type.translation_key
translationKey: widget_type.translation_key,
insertPoint: widget_type.insert_point
}
end
end.to_json.html_safe
Expand Down
25 changes: 25 additions & 0 deletions entry_types/scrolled/package/spec/entryState/widgets-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ describe('useWidget', () => {
setup: dispatch =>
watchCollections(
factories.entry(ScrolledEntry, {}, {
widgetTypes: factories.widgetTypes([{
role: 'navigation', name: 'customNavigation', insertPoint: 'react'
}]),
widgetsAttributes: [{
type_name: 'customNavigation',
role: 'navigation',
Expand All @@ -33,6 +36,28 @@ describe('useWidget', () => {
});
});

it('filters out non react widgets in editor', () => {
const {result} = renderHookInEntry(() => useWidget({role: 'consent'}), {
setup: dispatch =>
watchCollections(
factories.entry(ScrolledEntry, {}, {
widgetTypes: factories.widgetTypes([{
role: 'consent', name: 'some_consent_provider', insertPoint: 'bottom_of_entry'
}]),
widgetsAttributes: [{
type_name: 'some_consent_provider',
role: 'consent'
}],
entryTypeSeed: normalizeSeed()
}),
{dispatch}
)
});
const widget = result.current;

expect(widget).toBeUndefined();
});

it('reads data from seed', () => {
const {result} = renderHookInEntry(
() => useWidget({role: 'navigation'}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function watchCollections(entry, {dispatch}) {
dispatch
}));

teardownFns.push(watchCollection(widgets, {
teardownFns.push(watchCollection(widgets.withInsertPoint('react'), {
name: 'widgets',
attributes: [{typeName: 'type_name'}, 'role', {permaId: 'role'}],
keyAttribute: 'permaId',
Expand Down
4 changes: 3 additions & 1 deletion package/spec/editor/api/WidgetTypes-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@ describe('WidgetTypes', () => {
navigation: [
{
name: 'fancy_bar',
translationKey: 'pageflow.fancy_bar.widget_type_name'
translationKey: 'pageflow.fancy_bar.widget_type_name',
insertPoint: 'bottom_of_entry'
}
]
});

var widgetType = widgetTypes.findByName('fancy_bar');

expect(widgetType.name).toBe('fancy_bar');
expect(widgetType.insertPoint).toBe('bottom_of_entry');
});
});

Expand Down
35 changes: 35 additions & 0 deletions package/spec/editor/collections/widgetsCollection-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {WidgetsCollection} from 'editor/collections/WidgetsCollection';
import {factories} from '$support';

describe('WidgetsCollection', () => {
it('supports gettting subset collection for insert point', () => {
const widgetTypes = factories.widgetTypes([
{role: 'navigation', name: 'some_navigation_bar', insertPoint: 'react'},
{role: 'consent', name: 'some_consent_provider', insertPoint: 'bottom_of_entry'}
]);
const widgets = new WidgetsCollection([
{type_name: 'some_navigation_bar'},
{type_name: 'some_consent_provider'},
], {widgetTypes});

expect(
widgets.withInsertPoint('react').pluck('type_name')
).toEqual(['some_navigation_bar']);
});

it('keeps insert point subset collection up to date when type name changes', () => {
const widgetTypes = factories.widgetTypes([
{role: 'consent', name: 'consent_bar', insertPoint: 'react'},
{role: 'consent', name: 'some_consent_provider', insertPoint: 'bottom_of_entry'}
]);
const widgets = new WidgetsCollection([
{type_name: 'some_consent_provider'},
], {widgetTypes});
widgets.subject = factories.entry();

const subsetCollection = widgets.withInsertPoint('react');
widgets.first().set('type_name', 'consent_bar');

expect(subsetCollection.pluck('type_name')).toEqual(['consent_bar']);
});
});
1 change: 1 addition & 0 deletions package/src/editor/api/WidgetType.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const WidgetType = Object.extend({
initialize: function(serverSideConfig, clientSideConfig) {
this.name = serverSideConfig.name;
this.translationKey = serverSideConfig.translationKey;
this.insertPoint = serverSideConfig.insertPoint;
this.configurationEditorView = clientSideConfig.configurationEditorView;
this.isOptional = clientSideConfig.isOptional;
},
Expand Down
9 changes: 9 additions & 0 deletions package/src/editor/collections/WidgetsCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Backbone from 'backbone';
import _ from 'underscore';

import {Widget} from '../models/Widget';
import {SubsetCollection} from './SubsetCollection';

export const WidgetsCollection = Backbone.Collection.extend({
model: Widget,
Expand Down Expand Up @@ -32,5 +33,13 @@ export const WidgetsCollection = Backbone.Collection.extend({
subject.trigger('sync:widgets', subject, response, {});
}
}));
},

withInsertPoint(insertPoint) {
return new SubsetCollection({
parent: this,
watchAttribute: 'type_name',
filter: widget => widget.widgetType().insertPoint === insertPoint
});
}
});
3 changes: 2 additions & 1 deletion package/src/testHelpers/factories.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ function ensureFilesCollections(options) {

function ensureWidgetsCollections(options) {
if (!options.widgets) {
options.widgets = new WidgetsCollection(options.widgetsAttributes);
options.widgets = new WidgetsCollection(options.widgetsAttributes,
{widgetTypes: options.widgetTypes});
}
}
23 changes: 21 additions & 2 deletions spec/helpers/pageflow/widgets_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,29 @@ module Pageflow
end
end

describe '#widget_types_json_seeds' do
it 'renders name, translationKey and insertPoint by role' do
widget_type = TestWidgetType.new(name: 'fancy_bar',
roles: ['navigation'],
insert_point: :react)
pageflow_configure do |config|
config.widget_types.clear
config.widget_types.register(widget_type)
end

result = JSON.parse(helper.widget_types_json_seeds(Pageflow.config))

expect(result['navigation'][0]['name']).to eq('fancy_bar')
expect(result['navigation'][0]['translationKey'])
.to eq('pageflow.fancy_bar.widget_type_name')
expect(result['navigation'][0]['insertPoint']).to eq('react')
end
end

describe '#widgets_json_seeds' do
it 'includes role as id, type_name, configuration' do
entry = DraftEntry.new(create(:entry))
widget_type = TestWidgetType.new(name: 'fancy_bar', roles: 'navigation')
widget_type = TestWidgetType.new(name: 'fancy_bar', roles: ['navigation'])
create(:widget,
subject: entry.draft,
type_name: 'fancy_bar',
Expand All @@ -237,7 +256,7 @@ module Pageflow

it 'includes placeholders for roles without width' do
entry = DraftEntry.new(create(:entry))
widget_type = TestWidgetType.new(name: 'test', roles: 'foo')
widget_type = TestWidgetType.new(name: 'test', roles: ['foo'])

pageflow_configure do |config|
config.widget_types.clear
Expand Down

0 comments on commit 4c3520e

Please sign in to comment.