Skip to content

Commit

Permalink
Update for Flarum beta 15
Browse files Browse the repository at this point in the history
Fix visual glitch hiding a field after edit
Fix dropdown not refreshing in edit modal
  • Loading branch information
clarkwinkelmann committed Feb 15, 2021
1 parent 286e964 commit 709928b
Show file tree
Hide file tree
Showing 24 changed files with 976 additions and 1,024 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2020 FriendsOfFlarum
Copyright (c) 2020-2021 FriendsOfFlarum
Copyright (c) 2017-2019 Flagrow

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@
],
"support": {
"issues": "https://github.com/FriendsOfFlarum/mason/issues",
"source": "https://github.com/FriendsOfFlarum/mason"
"source": "https://github.com/FriendsOfFlarum/mason",
"forum": "https://discuss.flarum.org/d/7028"
},
"require": {
"flarum/core": ">=0.1.0-beta.14 <0.1.0-beta.15"
"flarum/core": ">=0.1.0-beta.15 <0.1.0-beta.16"
},
"replace": {
"flagrow/mason": "*"
},
"extra": {
"flarum-extension": {
"title": "FoF Mason",
"category": "discussion",
"icon": {
"name": "fas fa-dungeon",
"backgroundColor": "#e74c3c",
Expand Down
55 changes: 51 additions & 4 deletions extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@

namespace FoF\Mason;

use Flarum\Api\Controller\CreateDiscussionController;
use Flarum\Api\Controller\ListDiscussionsController;
use Flarum\Api\Controller\ShowDiscussionController;
use Flarum\Api\Controller\ShowForumController;
use Flarum\Api\Controller\UpdateDiscussionController;
use Flarum\Api\Serializer\DiscussionSerializer;
use Flarum\Api\Serializer\ForumSerializer;
use Flarum\Discussion\Discussion;
use Flarum\Discussion\Event\Saving;
use Flarum\Extend;
use FoF\Mason\Api\Serializers\AnswerSerializer;
use FoF\Mason\Api\Serializers\FieldSerializer;
use FoF\Mason\Listeners\DiscussionSaving;

return [
(new Extend\Frontend('forum'))
Expand All @@ -26,6 +37,37 @@
->patch('/fof/mason/answers/{id:[0-9]+}', 'fof-mason.api.answers.update', Api\Controllers\AnswerUpdateController::class)
->delete('/fof/mason/answers/{id:[0-9]+}', 'fof-mason.api.answers.delete', Api\Controllers\AnswerDeleteController::class),
(new Extend\Locales(__DIR__ . '/resources/locale')),

(new Extend\ApiController(ShowForumController::class))
->addInclude('masonFields.suggested_answers')
->prepareDataForSerialization(LoadForumFieldsRelationship::class),
(new Extend\ApiSerializer(ForumSerializer::class))
->hasMany('masonFields', FieldSerializer::class)
->mutate(ForumAttributes::class),

(new Extend\ApiController(ListDiscussionsController::class))
->addInclude('masonAnswers.field'),
(new Extend\ApiController(ShowDiscussionController::class))
->addInclude('masonAnswers.field'),
(new Extend\ApiController(CreateDiscussionController::class))
->addInclude('masonAnswers.field'),
(new Extend\ApiController(UpdateDiscussionController::class))
->addInclude('masonAnswers.field'),
(new Extend\ApiSerializer(DiscussionSerializer::class))
->hasMany('masonAnswers', AnswerSerializer::class)
->mutate(function (DiscussionSerializer $serializer, Discussion $discussion): array {
$canSee = $serializer->getActor()->can('seeMasonAnswers', $discussion);

if (!$canSee) {
// Will cause a skip of the relationship retrieval
$discussion->setRelation('masonAnswers', null);
}

return [
'canSeeMasonAnswers' => $canSee,
'canUpdateMasonAnswers' => $serializer->getActor()->can('updateMasonAnswers', $discussion),
];
}),
(new Extend\Model(Discussion::class))
->relationship('masonAnswers', function (Discussion $discussion) {
return $discussion->belongsToMany(Answer::class, 'fof_mason_discussion_answer', 'discussion_id', 'answer_id')
Expand All @@ -34,8 +76,13 @@
// Only load answers to fields that have not been deleted
$query->whereNull('deleted_at');
});
}),
new Extenders\ForumAttributes,
new Extenders\DiscussionAttributes,
new Extenders\Policies,
}),

(new Extend\Event())
->listen(Saving::class, DiscussionSaving::class),

(new Extend\Policy())
->modelPolicy(Answer::class, Access\AnswerPolicy::class)
->modelPolicy(Discussion::class, Access\DiscussionPolicy::class)
->modelPolicy(Field::class, Access\FieldPolicy::class),
];
2 changes: 1 addition & 1 deletion js/dist/admin.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/dist/admin.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/dist/forum.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/dist/forum.js.map

Large diffs are not rendered by default.

1,438 changes: 744 additions & 694 deletions js/package-lock.json

Large diffs are not rendered by default.

24 changes: 0 additions & 24 deletions js/src/admin/addMasonFieldsPage.js

This file was deleted.

48 changes: 0 additions & 48 deletions js/src/admin/addPermissions.js

This file was deleted.

42 changes: 37 additions & 5 deletions js/src/admin/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,45 @@
import app from 'flarum/app';
import Answer from './../lib/models/Answer';
import Field from './../lib/models/Field';
import addMasonFieldsPage from './addMasonFieldsPage';
import addPermissions from './addPermissions';
import MasonFieldsPage from './pages/MasonFieldsPage';

app.initializers.add('fof-mason', app => {
app.initializers.add('fof-mason', () => {
app.store.models['mason-fields'] = Field;
app.store.models['mason-answers'] = Answer;

addMasonFieldsPage();
addPermissions();
app.extensionData
.for('fof-mason')
.registerPage(MasonFieldsPage)
.registerPermission({
icon: 'fas fa-eye',
label: app.translator.trans('fof-mason.admin.permissions.see-own-fields'),
permission: 'fof-mason.see-own-fields',
}, 'view')
.registerPermission({
icon: 'fas fa-eye',
label: app.translator.trans('fof-mason.admin.permissions.see-other-fields'),
permission: 'fof-mason.see-other-fields',
allowGuest: true,
}, 'view')
.registerPermission({
icon: 'fas fa-tasks',
label: app.translator.trans('fof-mason.admin.permissions.fill-fields'),
permission: 'fof-mason.fill-fields',
}, 'reply')
.registerPermission({
icon: 'fas fa-edit',
label: app.translator.trans('fof-mason.admin.permissions.update-own-fields'),
permission: 'fof-mason.update-own-fields',
}, 'reply')
.registerPermission({
icon: 'fas fa-edit',
label: app.translator.trans('fof-mason.admin.permissions.update-other-fields'),
permission: 'fof-mason.update-other-fields',
allowGuest: true,
}, 'moderate')
.registerPermission({
icon: 'fas fa-forward',
label: app.translator.trans('fof-mason.admin.permissions.skip-required-fields'),
permission: 'fof-mason.skip-required-fields',
}, 'moderate');
});
10 changes: 5 additions & 5 deletions js/src/admin/pages/MasonFieldsPage.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import sortable from 'html5sortable/dist/html5sortable.es.js';

import app from 'flarum/app';
import Page from 'flarum/components/Page';
import ExtensionPage from 'flarum/components/ExtensionPage';
import FieldEdit from './../components/FieldEdit';
import sortByAttribute from './../../lib/helpers/sortByAttribute';
import MasonSettings from './../components/MasonSettings';

/* global m, $ */

export default class MasonFieldsPage extends Page {
export default class MasonFieldsPage extends ExtensionPage {
oninit(vnode) {
super.oninit(vnode);

Expand Down Expand Up @@ -45,7 +45,7 @@ export default class MasonFieldsPage extends Page {
this.configSortable();
}

view() {
content() {
const fields = app.store.all('mason-fields');

let fieldsList = [];
Expand All @@ -61,7 +61,7 @@ export default class MasonFieldsPage extends Page {
})));
});

return m('.container', [
return m('.ExtensionPage-settings', m('.container', [
m('h2', app.translator.trans('fof-mason.admin.titles.fields')),
m('.Mason-Container', [
m('.js-fields-container', fieldsList),
Expand All @@ -71,7 +71,7 @@ export default class MasonFieldsPage extends Page {
]),
m('h2', app.translator.trans('fof-mason.admin.titles.settings')),
MasonSettings.component(),
]);
]));
}

updateSort(sorting) {
Expand Down
12 changes: 11 additions & 1 deletion js/src/forum/addFieldsOnDiscussionPost.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@ export default function () {
this.subtree.check(() => {
// Create a string with all answer ids
// If answers change this string will be different
return this.attrs.post.discussion().masonAnswers().map(answer => answer.id()).join(',');
return this.attrs.post.discussion().masonAnswers().map(answer => {
// Sometimes answer will be undefined while the data is being saved in FieldsEditorModal
if (!answer) {
return '';
}

// There is a time after discussion.save() is called but before the data included in response is parsed
// where Flarum will already have updated the relationship, but answer.field will be missing and this causes
// the field to be skipped in FieldsViewer. So we also need to check the load status of that relationship
return JSON.stringify([answer.id(), !!answer.field()]);
}).join(',');
});
});

Expand Down
43 changes: 19 additions & 24 deletions js/src/forum/components/FieldEditDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@ import sortByAttribute from './../../lib/helpers/sortByAttribute';
/* global m */

export default class FieldEditDropdown extends Component {
oninit(vnode) {
super.oninit(vnode);
view(vnode) {
// To be certain to not work on object copies, we always read the current one from vnode.attrs
const {field, answers, onchange} = vnode.attrs;

this.field = this.attrs.field;
this.answers = this.attrs.answers;
this.onchange = this.attrs.onchange;
}

view() {
let selectedAnswerIdsForThisField = [];

this.field.suggested_answers().forEach(answer => {
const answerIndex = this.answers.findIndex(a => {
field.suggested_answers().forEach(answer => {
const answerIndex = answers.findIndex(a => {
// Temporary store entries seem to turn into undefined after saving
if (typeof a === 'undefined') {
return false;
Expand All @@ -34,7 +29,7 @@ export default class FieldEditDropdown extends Component {

return m('span.Select', [
m('select.Select-input.FormControl', {
multiple: this.field.multiple(),
multiple: field.multiple(),
onchange: event => {
let answers = [];

Expand All @@ -48,16 +43,16 @@ export default class FieldEditDropdown extends Component {
}
}

this.onchange(answers);
onchange(answers);
},
}, [
(this.field.multiple() ? null : m('option', {
(field.multiple() ? null : m('option', {
value: 'none',
selected: selectedAnswerIdsForThisField.length === 0,
disabled: this.field.required(),
hidden: this.placeholderHidden(),
}, this.selectPlaceholder())),
sortByAttribute(this.field.suggested_answers()).map(
disabled: field.required(),
hidden: this.placeholderHidden(field),
}, this.selectPlaceholder(field))),
sortByAttribute(field.suggested_answers()).map(
answer => m('option', {
value: answer.id(),
selected: selectedAnswerIdsForThisField.indexOf(answer.id()) !== -1,
Expand All @@ -68,30 +63,30 @@ export default class FieldEditDropdown extends Component {
]);
}

placeholderHidden() {
placeholderHidden(field) {
// If labels are hidden, we need to always show the default value (even if it can't be selected)
// Otherwise when the field is "required" you can't find the name of the field anymore once something is selected
if (app.forum.attribute('fof-mason.labels-as-placeholders')) {
return false;
}

return this.field.required();
return field.required();
}

selectPlaceholder() {
selectPlaceholder(field) {
let text = '';

if (app.forum.attribute('fof-mason.labels-as-placeholders')) {
text += this.field.name();
text += field.name();

if (this.field.required()) {
text+= ' *';
if (field.required()) {
text += ' *';
}

text += ' - ';
}

if (this.field.required()) {
if (field.required()) {
text += app.translator.trans('fof-mason.forum.answers.choose-option');
} else {
text += app.translator.trans('fof-mason.forum.answers.no-option-selected');
Expand Down
Loading

0 comments on commit 709928b

Please sign in to comment.