浏览代码

Modal improvements

- Add typing
- Markup improvement to the MUC occupant modal
- Markup improvements to the prompt modal
JC Brand 3 月之前
父节点
当前提交
336df63363

+ 3 - 6
src/headless/shared/api/send.js

@@ -12,12 +12,9 @@ export default {
      * @param {Element|Builder} stanza
      * @returns {void}
      * @example
-     * const msg = converse.env.$msg({
-     *     'from': 'juliet@example.com/balcony',
-     *     'to': 'romeo@example.net',
-     *     'type':'chat'
-     * });
-     * _converse.api.send(msg);
+     *     const { stx } = _converse.env;
+     *     const msg = stx`<message from="juliet@example.com/balcony" to="romeo@example.net" type="chat"/>`;
+     *     _converse.api.send(msg);
      */
     send(stanza) {
         const { api } = _converse;

+ 0 - 4
src/plugins/modal/styles/_modal.scss

@@ -107,10 +107,6 @@ $prefix: 'converse-';
             overflow-y: auto;
         }
 
-        .role-form, .affiliation-form {
-            padding: 2em 0 1em 0;
-        }
-
         .set-xmpp-status {
             margin: 1em;
             .custom-control-label {

+ 14 - 12
src/plugins/modal/templates/prompt.js

@@ -10,17 +10,19 @@ function tplField(f) {
               <input name="${f.name}" class="form-check-input" type="checkbox" value="" id="${f.name}" />
               <label class="form-check-label" for="${f.name}">${f.label}</label>
           </div>`
-        : html`<div>
-              <label class="form-label">
+        : html`<div class="mb-3">
+              <label class="form-label" for="${f.name}">
                   ${f.label || ''}
-                  <input
-                      type="text"
-                      name="${f.name}"
-                      class="${f.challenge_failed ? 'error' : ''} form-control form-control--labeled"
-                      ?required="${f.required}"
-                      placeholder="${f.placeholder}"
-                  />
               </label>
+              <input
+                  type="text"
+                  name="${f.name}"
+                  class="${f.challenge_failed ? 'is-invalid' : ''} form-control"
+                  ?required="${f.required}"
+                  placeholder="${f.placeholder}"
+                  id="${f.name}"
+              />
+              ${f.challenge_failed ? html`<div class="invalid-feedback">Please provide a valid input.</div>` : ''}
           </div>`;
 }
 
@@ -33,10 +35,10 @@ export default (el) => {
         action="#"
         @submit=${(ev) => el.onConfimation(ev)}
     >
-        <div>${el.model.get('messages')?.map(/** @param {string} msg */ (msg) => html`<p>${msg}</p>`)}</div>
+        <div class="mb-3">${el.model.get('messages')?.map(/** @param {string} msg */ (msg) => html`<p>${msg}</p>`)}</div>
         ${el.model.get('fields')?.map(/** @param {import('../types').Field} f */ (f) => tplField(f))}
-        <div>
-            <button type="submit" class="btn btn-primary">${__('Confirm')}</button>
+        <div class="d-flex justify-content-end">
+            <button type="submit" class="btn btn-primary me-2">${__('Confirm')}</button>
             <input type="button" class="btn btn-secondary" data-bs-dismiss="modal" value="${__('Cancel')}" />
         </div>
     </form>`;

+ 8 - 3
src/plugins/muc-views/affiliation-form.js

@@ -1,7 +1,9 @@
-import tplAffiliationForm from './templates/affiliation-form.js';
-import { CustomElement } from 'shared/components/element';
-import { __ } from 'i18n';
 import { api, converse, log, u } from '@converse/headless';
+import { __ } from 'i18n';
+import { CustomElement } from 'shared/components/element';
+import tplAffiliationForm from './templates/affiliation-form.js';
+
+import './styles/affiliation-form.scss';
 
 const { Strophe, sizzle } = converse.env;
 
@@ -20,6 +22,7 @@ class AffiliationForm extends CustomElement {
         super();
         this.jid = null;
         this.muc = null;
+        this.affiliation = null;
     }
 
     render () {
@@ -71,3 +74,5 @@ class AffiliationForm extends CustomElement {
 }
 
 api.elements.define('converse-muc-affiliation-form', AffiliationForm);
+
+export default AffiliationForm;

+ 0 - 1
src/plugins/muc-views/modals/occupant.js

@@ -64,7 +64,6 @@ export default class OccupantModal extends BaseModal {
     toggleForm (ev) {
         const toggle = u.ancestor(ev.target, '.toggle-form');
         const form = toggle.getAttribute('data-form');
-
         if (form === 'row-form') {
             this.show_role_form = !this.show_role_form;
         } else {

+ 2 - 2
src/plugins/muc-views/modals/templates/occupant.js

@@ -69,7 +69,7 @@ export default (el) => {
                             }
                         </div>
                         ${el.show_affiliation_form ?
-                            html`<div class="row"><converse-muc-affiliation-form jid=${jid} .muc=${muc} affiliation=${affiliation}></converse-muc-affiliation-form></div>` : ''}
+                            html`<div class="row mt-2"><converse-muc-affiliation-form jid=${jid} .muc=${muc} affiliation=${affiliation}></converse-muc-affiliation-form></div>` : ''}
                     </li>
                     <li class="row mb-2">
                         <div class="col text-start"><strong>${__('Role')}:</strong></div>
@@ -82,7 +82,7 @@ export default (el) => {
                                 </a>` : ''
                             }
                         </div>
-                        ${el.show_role_form ? html`<div class="row"><converse-muc-role-form jid=${jid} .muc=${muc} role=${role}></converse-muc-role-form></div>` : ''}
+                        ${el.show_role_form ? html`<div class="row mt-2"><converse-muc-role-form jid=${jid} .muc=${muc} role=${role}></converse-muc-role-form></div>` : ''}
                     </li>
                     <li class="row mb-2">
                         <div class="col text-start"><strong>${__('Hats')}:</strong></div>

+ 9 - 3
src/plugins/muc-views/role-form.js

@@ -1,7 +1,9 @@
-import tplRoleForm from './templates/role-form.js';
-import { CustomElement } from 'shared/components/element.js';
-import { __ } from 'i18n';
 import { api, converse, log, u } from '@converse/headless';
+import { __ } from 'i18n';
+import { CustomElement } from 'shared/components/element.js';
+import tplRoleForm from './templates/role-form.js';
+
+import './styles/role-form.scss';
 
 const { Strophe, sizzle } = converse.env;
 
@@ -20,6 +22,8 @@ class RoleForm extends CustomElement {
     constructor () {
         super();
         this.muc = null;
+        this.nick = null;
+        this.jid = null;
     }
 
     render () {
@@ -70,3 +74,5 @@ class RoleForm extends CustomElement {
 }
 
 api.elements.define('converse-muc-role-form', RoleForm);
+
+export default RoleForm;

+ 6 - 0
src/plugins/muc-views/styles/affiliation-form.scss

@@ -0,0 +1,6 @@
+converse-muc-affiliation-form {
+    background-color: var(--highlight-color);
+    padding: 1em 0 1em 0;
+    border-radius: 0.25em;
+}
+

+ 5 - 0
src/plugins/muc-views/styles/role-form.scss

@@ -0,0 +1,5 @@
+converse-muc-role-form {
+    background-color: var(--highlight-color);
+    padding: 1em 0 1em 0;
+    border-radius: 0.25em;
+}

+ 12 - 11
src/plugins/muc-views/templates/affiliation-form.js

@@ -1,6 +1,9 @@
-import { __ } from 'i18n';
 import { html } from "lit";
+import { __ } from 'i18n';
 
+/**
+ * @param {import('../affiliation-form').default} el
+ */
 export default (el) => {
     const i18n_change_affiliation = __('Change affiliation');
     const i18n_new_affiliation = __('New affiliation');
@@ -9,26 +12,24 @@ export default (el) => {
     const assignable_affiliations = occupant.getAssignableAffiliations();
 
     return html`
-        <form class="affiliation-form" @submit=${ev => el.assignAffiliation(ev)}>
+        <form class="affiliation-form" @submit=${(ev) => el.assignAffiliation(ev)}>
             ${el.alert_message ? html`<div class="alert alert-${el.alert_type}" role="alert">${el.alert_message}</div>` : '' }
-            <div>
+            <div class="mb-3">
                 <div class="row">
-                    <div class="col">
+                    <div class="col-md-6">
                         <label class="form-label"><strong>${i18n_new_affiliation}:</strong></label>
                         <select class="form-select select-affiliation" name="affiliation">
-                            ${ assignable_affiliations.map(aff => html`<option value="${aff}" ?selected=${aff === el.affiliation}>${aff}</option>`) }
+                            ${assignable_affiliations.map((aff) => html`<option value="${aff}" ?selected=${aff === el.affiliation}>${aff}</option>`)}
                         </select>
                     </div>
-                    <div class="col">
+                    <div class="col-md-6">
                         <label class="form-label"><strong>${i18n_reason}:</strong></label>
-                        <input class="form-control" type="text" name="reason"/>
+                        <input class="form-control" type="text" name="reason" placeholder="${i18n_reason}"/>
                     </div>
                 </div>
             </div>
-            <div>
-                <div class="col">
-                    <input type="submit" class="btn btn-primary" name="change" value="${i18n_change_affiliation}"/>
-                </div>
+            <div class="text-end">
+                <button type="submit" class="btn btn-primary" name="change">${i18n_change_affiliation}</button>
             </div>
         </form>
     `;

+ 13 - 12
src/plugins/muc-views/templates/role-form.js

@@ -1,6 +1,9 @@
-import { __ } from 'i18n';
 import { html } from "lit";
+import { __ } from 'i18n';
 
+/**
+ * @param {import('../role-form').default} el
+ */
 export default (el) => {
     const i18n_change_role = __('Change role');
     const i18n_new_role = __('New Role');
@@ -10,26 +13,24 @@ export default (el) => {
 
     return html`
         <form class="role-form" @submit=${el.assignRole}>
-            <div>
-                <input type="hidden" name="jid" value="${el.jid}"/>
-                <input type="hidden" name="nick" value="${el.nick}"/>
+            <input type="hidden" name="jid" value="${el.jid}"/>
+            <input type="hidden" name="nick" value="${el.nick}"/>
+            <div class="mb-3">
                 <div class="row">
-                    <div class="col">
+                    <div class="col-md-6">
                         <label class="form-label"><strong>${i18n_new_role}:</strong></label>
                         <select class="form-select select-role" name="role">
-                        ${ assignable_roles.map(role => html`<option value="${role}" ?selected=${role === el.role}>${role}</option>`) }
+                            ${assignable_roles.map(role => html`<option value="${role}" ?selected=${role === el.role}>${role}</option>`)}
                         </select>
                     </div>
-                    <div class="col">
+                    <div class="col-md-6">
                         <label class="form-label"><strong>${i18n_reason}:</strong></label>
-                        <input class="form-control" type="text" name="reason"/>
+                        <input class="form-control" type="text" name="reason" placeholder="${i18n_reason}"/>
                     </div>
                 </div>
             </div>
-            <div>
-                <div class="col">
-                    <input type="submit" class="btn btn-primary" value="${i18n_change_role}"/>
-                </div>
+            <div class="text-end">
+                <button type="submit" class="btn btn-primary">${i18n_change_role}</button>
             </div>
         </form>
     `;

+ 1 - 1
src/plugins/muc-views/tests/commands.js

@@ -859,7 +859,7 @@ describe("Groupchats", function () {
             submit.click();
 
             expect(u.isVisible(modal)).toBeTruthy();
-            await u.waitUntil(() => u.hasClass('error', challenge_el));
+            await u.waitUntil(() => u.hasClass('is-invalid', challenge_el));
             challenge_el.value = muc_jid;
             submit.click();
 

+ 5 - 0
src/shared/styles/forms.scss

@@ -5,6 +5,11 @@
     }
 
     form {
+        .form-check {
+            .form-check-input {
+                margin-top: 0.05em;
+            }
+        }
 
         .invalid-feedback {
             display: block;

+ 0 - 2
src/types/plugins/controlbox/loginform.d.ts

@@ -4,7 +4,6 @@ declare class LoginForm extends CustomElement {
     handler: () => void;
     connectedCallback(): void;
     render(): import("lit-html").TemplateResult<1>;
-    firstUpdated(): void;
     /**
      * @param {SubmitEvent} ev
      */
@@ -13,7 +12,6 @@ declare class LoginForm extends CustomElement {
      * @param {HTMLFormElement} form
      */
     discoverConnectionMethods(form: HTMLFormElement): any;
-    initPopovers(): void;
     /**
      * @param {string} [jid]
      */

+ 31 - 1
src/types/plugins/muc-views/affiliation-form.d.ts

@@ -1,2 +1,32 @@
-export {};
+export default AffiliationForm;
+declare class AffiliationForm extends CustomElement {
+    static get properties(): {
+        muc: {
+            type: ObjectConstructor;
+        };
+        jid: {
+            type: StringConstructor;
+        };
+        affiliation: {
+            type: StringConstructor;
+        };
+        alert_message: {
+            type: StringConstructor;
+            attribute: boolean;
+        };
+        alert_type: {
+            type: StringConstructor;
+            attribute: boolean;
+        };
+    };
+    jid: any;
+    muc: any;
+    affiliation: any;
+    render(): import("lit-html").TemplateResult<1>;
+    alert(message: any, type: any): void;
+    alert_message: any;
+    alert_type: any;
+    assignAffiliation(ev: any): Promise<void>;
+}
+import { CustomElement } from 'shared/components/element';
 //# sourceMappingURL=affiliation-form.d.ts.map

+ 5 - 1
src/types/plugins/muc-views/modals/occupant.d.ts

@@ -1,8 +1,12 @@
 export default class OccupantModal extends BaseModal {
     constructor(options: any);
     message: any;
-    getVcard(): any;
     renderModal(): import("lit-html").TemplateResult<1>;
+    /**
+     * @param {MouseEvent} ev
+     */
+    openChat(ev: MouseEvent): void;
+    getVcard(): any;
     getModalTitle(): any;
     addToContacts(): void;
     toggleForm(ev: any): void;

+ 31 - 1
src/types/plugins/muc-views/role-form.d.ts

@@ -1,2 +1,32 @@
-export {};
+export default RoleForm;
+declare class RoleForm extends CustomElement {
+    static get properties(): {
+        muc: {
+            type: ObjectConstructor;
+        };
+        jid: {
+            type: StringConstructor;
+        };
+        role: {
+            type: StringConstructor;
+        };
+        alert_message: {
+            type: StringConstructor;
+            attribute: boolean;
+        };
+        alert_type: {
+            type: StringConstructor;
+            attribute: boolean;
+        };
+    };
+    muc: any;
+    nick: any;
+    jid: any;
+    render(): import("lit-html").TemplateResult<1>;
+    alert(message: any, type: any): void;
+    alert_message: any;
+    alert_type: any;
+    assignRole(ev: any): void;
+}
+import { CustomElement } from 'shared/components/element.js';
 //# sourceMappingURL=role-form.d.ts.map

+ 1 - 1
src/types/plugins/muc-views/templates/affiliation-form.d.ts

@@ -1,3 +1,3 @@
-declare function _default(el: any): import("lit-html").TemplateResult<1>;
+declare function _default(el: import("../affiliation-form").default): import("lit-html").TemplateResult<1>;
 export default _default;
 //# sourceMappingURL=affiliation-form.d.ts.map

+ 1 - 1
src/types/plugins/muc-views/templates/role-form.d.ts

@@ -1,3 +1,3 @@
-declare function _default(el: any): import("lit-html").TemplateResult<1>;
+declare function _default(el: import("../role-form").default): import("lit-html").TemplateResult<1>;
 export default _default;
 //# sourceMappingURL=role-form.d.ts.map