Make the role form a custom element

So that it can be used in the occupant modal as well.
This commit is contained in:
JC Brand 2023-02-21 22:53:42 +01:00
parent 26062df4e5
commit 85181053e6
6 changed files with 122 additions and 71 deletions

View File

@ -183,7 +183,7 @@ u.isChatRoom = function (model) {
return model && (model.get('type') === 'chatroom');
}
u.isErrorObject = function (o) {
export function isErrorObject (o) {
return o instanceof Error;
}
@ -620,6 +620,7 @@ export function saveWindowState (ev) {
export default Object.assign({
isErrorObject,
getRandomInt,
getUniqueId,
isElement,

View File

@ -5,6 +5,7 @@
*/
import '../chatboxviews/index.js';
import './affiliation-form.js';
import './role-form.js';
import MUCView from './muc.js';
import { api, converse } from '@converse/headless/core.js';
import { clearHistory, parseMessageForMUCCommands } from './utils.js';

View File

@ -1,4 +1,3 @@
import log from '@converse/headless/log.js';
import tplModeratorTools from './templates/moderator-tools.js';
import { AFFILIATIONS, ROLES } from '@converse/headless/plugins/muc/constants.js';
import { CustomElement } from 'shared/components/element.js';
@ -10,7 +9,7 @@ import { getOpenPromise } from '@converse/openpromise';
import './styles/moderator-tools.scss';
const { Strophe, sizzle, u } = converse.env;
const { u } = converse.env;
export default class ModeratorTools extends CustomElement {
static get properties () {
@ -42,6 +41,11 @@ export default class ModeratorTools extends CustomElement {
this.onSearchAffiliationChange();
this.requestUpdate()
});
this.addEventListener("roleChanged", () => {
this.alert(__('Role changed'), 'primary');
this.requestUpdate()
});
}
updated (changed) {
@ -191,36 +195,6 @@ export default class ModeratorTools extends CustomElement {
this.alert_type = undefined;
}
assignRole (ev) {
ev.stopPropagation();
ev.preventDefault();
this.clearAlert();
const data = new FormData(ev.target);
const occupant = this.muc.getOccupant(data.get('jid') || data.get('nick'));
const role = data.get('role');
const reason = data.get('reason');
const current_role = this.role;
this.muc.setRole(
occupant,
role,
reason,
() => {
this.alert(__('Role changed'), 'primary');
this.role = null;
this.role = current_role;
},
e => {
if (sizzle(`not-allowed[xmlns="${Strophe.NS.STANZAS}"]`, e).length) {
this.alert(__("You're not allowed to make that change"), 'danger');
} else {
this.alert(__('Sorry, something went wrong while trying to set the role'), 'danger');
if (u.isErrorObject(e)) {
log.error(e);
}
}
}
);
}
}
api.elements.define('converse-modtools', ModeratorTools);

View File

@ -0,0 +1,68 @@
import log from '@converse/headless/log';
import tplRoleForm from './templates/role-form.js';
import { CustomElement } from 'shared/components/element.js';
import { __ } from 'i18n';
import { api, converse } from '@converse/headless/core.js';
import { isErrorObject } from '@converse/headless/utils/core.js';
const { Strophe, sizzle } = converse.env;
class RoleForm extends CustomElement {
static get properties () {
return {
muc: { type: Object },
jid: { type: String },
role: { type: String },
alert_message: { type: String, attribute: false },
alert_type: { type: String, attribute: false },
};
}
render () {
return tplRoleForm(this);
}
alert (message, type) {
this.alert_message = message;
this.alert_type = type;
}
assignRole (ev) {
ev.stopPropagation();
ev.preventDefault();
this.alert(); // clear alert
const data = new FormData(ev.target);
const occupant = this.muc.getOccupant(data.get('jid') || data.get('nick'));
const role = data.get('role');
const reason = data.get('reason');
this.muc.setRole(
occupant,
role,
reason,
() => {
/**
* @event roleChanged
* @example
* const el = document.querySelector('converse-muc-role-form');
* el.addEventListener('roleChanged', () => { ... });
*/
const event = new CustomEvent('roleChanged', { bubbles: true });
this.dispatchEvent(event);
},
e => {
if (sizzle(`not-allowed[xmlns="${Strophe.NS.STANZAS}"]`, e).length) {
this.alert(__("You're not allowed to make that change"), 'danger');
} else {
this.alert(__('Sorry, something went wrong while trying to set the role'), 'danger');
if (isErrorObject(e)) log.error(e);
}
}
);
}
}
api.elements.define('converse-muc-role-form', RoleForm);

View File

@ -38,45 +38,13 @@ const affiliation_option = (o) => html`
`;
const tplSetRoleForm = (o) => {
const i18n_change_role = __('Change role');
const i18n_new_role = __('New Role');
const i18n_reason = __('Reason');
return html`
<form class="role-form hidden" @submit=${o.assignRole}>
<div class="form-group">
<input type="hidden" name="jid" value="${o.item.jid}"/>
<input type="hidden" name="nick" value="${o.item.nick}"/>
<div class="row">
<div class="col">
<label><strong>${i18n_new_role}:</strong></label>
<select class="custom-select select-role" name="role">
${ o.assignable_roles.map(role => html`<option value="${role}" ?selected=${role === o.item.role}>${role}</option>`) }
</select>
</div>
<div class="col">
<label><strong>${i18n_reason}:</strong></label>
<input class="form-control" type="text" name="reason"/>
</div>
</div>
</div>
<div class="form-group">
<div class="col">
<input type="submit" class="btn btn-primary" value="${i18n_change_role}"/>
</div>
</div>
</form>
`;
}
const role_form_toggle = (o) => html`
<a href="#" data-form="role-form" class="toggle-form right" color="var(--subdued-color)" @click=${o.toggleForm}>
const tplRoleFormToggle = (o) => html`
<a href="#" data-form="converse-muc-role-form" class="toggle-form right" color="var(--subdued-color)" @click=${o.toggleForm}>
<converse-icon class="fa fa-wrench" size="1em"></converse-icon>
</a>`;
const role_list_item = (o) => html`
const tplRoleListItem = (el, o) => html`
<li class="list-group-item" data-nick="${o.item.nick}">
<ul class="list-group">
<li class="list-group-item active">
@ -86,8 +54,10 @@ const role_list_item = (o) => html`
<div><strong>Nickname:</strong> ${o.item.nick}</div>
</li>
<li class="list-group-item">
<div><strong>Role:</strong> ${o.item.role} ${o.assignable_roles.length ? role_form_toggle(o) : ''}</div>
${o.assignable_roles.length ? tplSetRoleForm(o) : ''}
<div><strong>Role:</strong> ${o.item.role} ${o.assignable_roles.length ? tplRoleFormToggle(o) : ''}</div>
${o.assignable_roles.length ?
html`<converse-muc-role-form class="hidden" .muc=${el.muc} jid=${o.item.jid} role=${o.item.role}></converse-muc-role-form>` : ''
}
</li>
</ul>
</li>
@ -240,7 +210,7 @@ export default (el, o) => {
<ul class="list-group list-group--users">
${ o.loading_users_with_role ? html`<li class="list-group-item"> ${spinner()} </li>` : '' }
${ (o.users_with_role && o.users_with_role.length === 0) ? html`<li class="list-group-item">${i18n_no_users_with_role}</li>` : '' }
${ (o.users_with_role || []).map(item => (item.nick.match(o.roles_filter) ? role_list_item(Object.assign({item}, o)) : '')) }
${ (o.users_with_role || []).map(item => (item.nick.match(o.roles_filter) ? tplRoleListItem(el, Object.assign({item}, o)) : '')) }
</ul>
</div>
</div>`: '' }

View File

@ -0,0 +1,37 @@
import { __ } from 'i18n';
import { html } from "lit";
import { getAssignableRoles } from '@converse/headless/plugins/muc/utils.js';
export default (el) => {
const i18n_change_role = __('Change role');
const i18n_new_role = __('New Role');
const i18n_reason = __('Reason');
const occupant = el.muc.getOwnOccupant();
const assignable_roles = getAssignableRoles(occupant);
return html`
<form class="role-form" @submit=${el.assignRole}>
<div class="form-group">
<input type="hidden" name="jid" value="${el.jid}"/>
<input type="hidden" name="nick" value="${el.nick}"/>
<div class="row">
<div class="col">
<label><strong>${i18n_new_role}:</strong></label>
<select class="custom-select select-role" name="role">
${ assignable_roles.map(role => html`<option value="${role}" ?selected=${role === el.role}>${role}</option>`) }
</select>
</div>
<div class="col">
<label><strong>${i18n_reason}:</strong></label>
<input class="form-control" type="text" name="reason"/>
</div>
</div>
</div>
<div class="form-group">
<div class="col">
<input type="submit" class="btn btn-primary" value="${i18n_change_role}"/>
</div>
</div>
</form>
`;
}