Assign the selected label to the picker
authorAlexander Ebert <ebert@woltlab.com>
Sat, 23 Sep 2023 17:28:31 +0000 (19:28 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 5 Oct 2023 15:22:51 +0000 (17:22 +0200)
com.woltlab.wcf/templates/articleAdd.tpl
ts/WoltLabSuite/WebComponent/woltlab-core-label-picker.ts
wcfsetup/install/files/js/WoltLabSuite/WebComponent.min.js
wcfsetup/install/files/lib/acp/form/ArticleAddForm.class.php
wcfsetup/install/files/lib/acp/form/ArticleEditForm.class.php
wcfsetup/install/files/lib/system/label/LabelPicker.class.php

index 367d7a518e8a511f09064dca2d14e8126b6cb650..5450ad8a7ca1df7c7e2ee742731a90f265682ca8 100644 (file)
 
                {foreach from=$labelPickers item=labelPicker}
                        <dl>
-                               <dt>{$labelPicker->labelGroup->getTitle()}</dt>
-                               <dd>{@$labelPicker->toHtml()}</dd>
+                               <dt><label for="{$labelPicker->getId()}">{$labelPicker->labelGroup->getTitle()}</label></dt>
+                               <dd>
+                                       {@$labelPicker->toHtml()}
+                                       {if $errorField == 'label' && $errorType[$labelPicker->labelGroup->groupID]|isset}
+                                               <small class="innerError">
+                                                       {if $errorType[$labelPicker->labelGroup->groupID] == 'missing'}
+                                                               {lang}wcf.label.error.missing{/lang}
+                                                       {else}
+                                                               {lang}wcf.label.error.invalid{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                               </dd>
                        </dl>
                {/foreach}
                
-               {if $labelGroups|count}
-                       {foreach from=$labelGroups item=labelGroup}
-                               {if $labelGroup|count}
-                                       <dl{if $errorField == 'label' && $errorType[$labelGroup->groupID]|isset} class="formError"{/if}>
-                                               <dt><label>{$labelGroup->getTitle()}</label></dt>
-                                               <dd>
-                                                       <ul class="labelList jsOnly" data-object-id="{@$labelGroup->groupID}">
-                                                               <li class="dropdown labelChooser" id="labelGroup{@$labelGroup->groupID}" data-group-id="{@$labelGroup->groupID}" data-force-selection="{if $labelGroup->forceSelection}true{else}false{/if}">
-                                                                       <div class="dropdownToggle" data-toggle="labelGroup{@$labelGroup->groupID}"><span class="badge label">{lang}wcf.label.none{/lang}</span></div>
-                                                                       <div class="dropdownMenu">
-                                                                               <ul class="scrollableDropdownMenu">
-                                                                                       {foreach from=$labelGroup item=label}
-                                                                                               <li data-label-id="{@$label->labelID}"><span>{@$label->render()}</span></li>
-                                                                                       {/foreach}
-                                                                               </ul>
-                                                                       </div>
-                                                               </li>
-                                                       </ul>
-                                                       <noscript>
-                                                               <select name="labelIDs[{@$labelGroup->groupID}]">
-                                                                       {foreach from=$labelGroup item=label}
-                                                                               <option value="{$label->labelID}">{$label->getTitle()}</option>
-                                                                       {/foreach}
-                                                               </select>
-                                                       </noscript>
-                                                       {if $errorField == 'label' && $errorType[$labelGroup->groupID]|isset}
-                                                               <small class="innerError">
-                                                                       {if $errorType[$labelGroup->groupID] == 'missing'}
-                                                                               {lang}wcf.label.error.missing{/lang}
-                                                                       {else}
-                                                                               {lang}wcf.label.error.invalid{/lang}
-                                                                       {/if}
-                                                               </small>
-                                                       {/if}
-                                               </dd>
-                                       </dl>
-                               {/if}
-                       {/foreach}
-               {/if}
-               
                <dl{if $errorField == 'username'} class="formError"{/if}>
                        <dt><label for="username">{lang}wcf.acp.article.author{/lang}</label></dt>
                        <dd>
                });
                
                {if !$labelGroups|empty}
-                       new WCF.Label.ArticleLabelChooser({ {implode from=$labelGroupsToCategories key=__labelCategoryID item=labelGroupIDs}{@$__labelCategoryID}: [ {implode from=$labelGroupIDs item=labelGroupID}{@$labelGroupID}{/implode} ] {/implode} }, { {implode from=$labelIDs key=groupID item=labelID}{@$groupID}: {@$labelID}{/implode} }, '.articleAddForm');
+                       //new WCF.Label.ArticleLabelChooser({ {implode from=$labelGroupsToCategories key=__labelCategoryID item=labelGroupIDs}{@$__labelCategoryID}: [ {implode from=$labelGroupIDs item=labelGroupID}{@$labelGroupID}{/implode} ] {/implode} }, { {implode from=$labelIDs key=groupID item=labelID}{@$groupID}: {@$labelID}{/implode} }, '.articleAddForm');
                {/if}
                
                new WCF.Message.I18nPreview({
index 7cdd6147fb1b0c492292006afbfcc42ab19f179a..d1edfabbf8d42553b85b79d4eea67b43a5f895d2 100644 (file)
@@ -20,6 +20,7 @@
         throw new Error("Expected a non empty list of labels.");
       }
 
+      // TODO: This HTML is duplicated in `set selected()`
       const emptyLabel = `<span class="badge label">${window.WoltLabLanguage.getPhrase("wcf.label.none")}</span>`;
 
       this.#button.type = "button";
         this.dispatchEvent(evt);
       });
 
+      // Moving the ID to the button allows clicks on the label to be forwarded.
+      this.#button.id = this.id;
+      this.removeAttribute("id");
+
       this.append(this.#button);
 
-      const dropdownMenu = document.createElement("ul");
-      dropdownMenu.classList.add("dropdownMenu");
+      const scrollableDropdownMenu = document.createElement("ul");
+      scrollableDropdownMenu.classList.add("scrollableDropdownMenu");
       for (const [labelId, html] of this.#labels) {
-        dropdownMenu.append(this.#createLabelItem(labelId, html));
+        scrollableDropdownMenu.append(this.#createLabelItem(labelId, html));
       }
 
       if (!this.required) {
         const divider = document.createElement("li");
         divider.classList.add("dropdownDivider");
 
-        dropdownMenu.append(divider, this.#createLabelItem(0, emptyLabel));
+        scrollableDropdownMenu.append(divider, this.#createLabelItem(0, emptyLabel));
       }
 
+      const dropdownMenu = document.createElement("ul");
+      dropdownMenu.classList.add("dropdownMenu");
+      dropdownMenu.append(scrollableDropdownMenu);
+
       this.append(dropdownMenu);
 
       this.classList.add("dropdown");
@@ -55,7 +64,7 @@
         if (this.#formValue === undefined) {
           this.#formValue = document.createElement("input");
           this.#formValue.type = "hidden";
-          this.#formValue.name = "labelIDs[]";
+          this.#formValue.name = `labelIDs[${this.dataset.groupId}]`;
           this.append(this.#formValue);
         }
 
       } else {
         this.#formValue?.remove();
       }
+
+      if (this.selected) {
+        // TODO: This is _slightly_ awkward.
+        this.selected = this.selected!;
+      }
     }
 
     #createLabelItem(labelId: number, html: string): HTMLLIElement {
index 35e2fe2c04af5b0483e286d255440ea052fd7614..cef37066b10d99b2477512df9e340a31bc7844c6 100644 (file)
@@ -60,7 +60,7 @@ Expecting `+Z.join(", ")+", got '"+(this.terminals_[E]||E)+"'":ae="Parse error o
             time::after {
               content: " (" attr(title) ")";
             }
-          }`,L.append(C)}g&&(this.#e.dateTime=p.toISOString(),this.#e.title=b.DateAndTime.format(p));let y;if(this.static)y=this.#e.title;else if(x<k.OneMinute)y=window.WoltLabLanguage.getPhrase("wcf.date.relative.now");else if(x<k.OneHour){let L=Math.trunc(x/k.OneMinute);y=b.Minutes.format(L*-1,"minute")}else if(x<k.OneWeek){let L=b.DayOfWeekAndTime.formatToParts(p);L[0].type==="weekday"?p.getTime()>t?y=this.#t(L,0):p.getTime()>a?y=this.#t(L,-1):y=L.map(W=>W.value).join(""):y=b.DateAndTime.format(p)}else y=b.Date.format(p);y=y.charAt(0).toUpperCase()+y.slice(1),this.#e.textContent=y}#t(g,p){return g.map(y=>y.type==="weekday"?b.TodayOrYesterday.format(p,"day"):y.value).join("")}}window.customElements.define("woltlab-core-date-time",q);let S=()=>{document.querySelectorAll("woltlab-core-date-time").forEach(h=>h.refresh(!1))},z,P=()=>{z=window.setInterval(()=>{i(),S()},6e4)};document.addEventListener("DOMContentLoaded",()=>P(),{once:!0}),document.addEventListener("visibilitychange",()=>{document.hidden?window.clearInterval(z):(S(),P())})}{class e extends HTMLElement{#a;#e;#t=new Map;constructor(){super(),this.#a=document.createElement("button")}connectedCallback(){if(this.hasAttribute("labels")&&(this.#t=new Map(JSON.parse(this.getAttribute("labels"))),this.removeAttribute("labels")),this.#t.size===0)throw new Error("Expected a non empty list of labels.");let l=`<span class="badge label">${window.WoltLabLanguage.getPhrase("wcf.label.none")}</span>`;this.#a.type="button",this.#a.classList.add("dropdownToggle"),this.#a.innerHTML=l,this.#a.addEventListener("click",t=>{t.preventDefault();let a=new CustomEvent("showPicker");this.dispatchEvent(a)}),this.append(this.#a);let c=document.createElement("ul");c.classList.add("dropdownMenu");for(let[t,a]of this.#t)c.append(this.#s(t,a));if(!this.required){let t=document.createElement("li");t.classList.add("dropdownDivider"),c.append(t,this.#s(0,l))}this.append(c),this.classList.add("dropdown"),this.closest("form")!==null?(this.#e===void 0&&(this.#e=document.createElement("input"),this.#e.type="hidden",this.#e.name="labelIDs[]",this.append(this.#e)),this.#e.value=(this.selected||0).toString()):this.#e?.remove()}#s(l,c){let t=document.createElement("button");t.type="button",t.dataset.labelId=l.toString(),t.innerHTML=c,t.addEventListener("click",()=>{this.selected=l});let a=document.createElement("li");return a.append(t),a}set selected(l){this.setAttribute("selected",l.toString()),this.#a.innerHTML=this.#t.get(l)||`<span class="badge label">${window.WoltLabLanguage.getPhrase("wcf.label.none")}</span>`,this.#e!==void 0&&(this.#e.value=l.toString())}get selected(){let l=parseInt(this.getAttribute("selected"));if(!Number.isNaN(l))return l}set disabled(l){l?this.setAttribute("disabled",""):this.removeAttribute("disabled"),this.#a.disabled=l,this.#e&&(this.#e.disabled=l)}get disabled(){return this.hasAttribute("disabled")}set required(l){l?this.setAttribute("required",""):this.removeAttribute("required")}get required(){return this.hasAttribute("required")}get labels(){return new Map(this.#t)}}window.customElements.define("woltlab-core-label-picker",e)}{let r=[24,48,96];class l extends HTMLElement{#a;#e;connectedCallback(){this.#a===void 0&&this.#t()}attributeChangedCallback(t,a,i){if(t==="size"){let d=parseInt(i||"");if(!r.includes(d)){let b=parseInt(a||"");r.includes(b)||(b=24),this.setAttribute(t,b.toString())}}}#t(){this.classList.add("loading-indicator"),this.hasAttribute("size")||this.setAttribute("size",24 .toString()),this.#a=document.createElement("fa-icon"),this.#a.size=this.size,this.#a.setIcon("spinner"),this.#e=document.createElement("span"),this.#e.classList.add("loading-indicator__text"),this.#e.textContent=window.WoltLabLanguage.getPhrase("wcf.global.loading"),this.#e.hidden=this.hideText;let t=document.createElement("div");t.classList.add("loading-indicator__wrapper"),t.append(this.#a,this.#e),this.append(t)}get size(){return parseInt(this.getAttribute("size"))}set size(t){if(!r.includes(t))throw new TypeError(`The size ${t} is unrecognized, permitted values are ${r.join(", ")}.`);this.setAttribute("size",t.toString()),this.#a&&(this.#a.size=t)}get hideText(){return this.hasAttribute("hide-text")}set hideText(t){t?this.setAttribute("hide-text",""):this.removeAttribute("hide-text"),this.#e&&(this.#e.hidden=t)}static get observedAttributes(){return["size"]}}window.customElements.define("woltlab-core-loading-indicator",l)}{let e,r=()=>(e===void 0&&(e=window.matchMedia("(max-width: 544px)")),e);class l extends HTMLElement{#a="pagination";connectedCallback(){this.#e(),r().addEventListener("change",()=>this.#e())}#e(){if(this.innerHTML="",this.count<2)return;this.classList.add(`${this.#a}__wrapper`);let t=this.#t();this.append(t);let a=this.#s();a&&t.append(a);let i=document.createElement("ul");i.classList.add(`${this.#a}__list`),t.append(i),i.append(this.#l(1)),this.page>this.thresholdForEllipsis+1&&i.append(this.#i()),this.#f().forEach(b=>{i.append(b)}),this.count-this.page>this.thresholdForEllipsis&&i.append(this.#i()),i.append(this.#l(this.count));let d=this.#o();d&&t.append(d)}#t(){let t=document.createElement("nav");return t.setAttribute("role","navigation"),t.setAttribute("aria-label",window.WoltLabLanguage.getPhrase("wcf.page.pagination")),t.classList.add(this.#a),t}#s(){if(this.page===1)return;let t=document.createElement("div");t.classList.add(`${this.#a}__prev`);let a=this.#r(this.page-1);a instanceof HTMLAnchorElement&&(a.rel="prev"),a.title=window.WoltLabLanguage.getPhrase("wcf.global.page.previous"),a.classList.add("jsTooltip"),t.append(a);let i=document.createElement("fa-icon");return i.setIcon("arrow-left"),a.append(i),t}#o(){if(this.page===this.count)return;let t=document.createElement("div");t.classList.add(`${this.#a}__next`);let a=this.#r(this.page+1);a instanceof HTMLAnchorElement&&(a.rel="next"),a.title=window.WoltLabLanguage.getPhrase("wcf.global.page.next"),a.classList.add("jsTooltip"),t.append(a);let i=document.createElement("fa-icon");return i.setIcon("arrow-right"),a.append(i),t}#r(t){let a,i=this.getLinkUrl(t);return i?(a=document.createElement("a"),a.href=i):(a=document.createElement("button"),a.type="button",this.page===t?a.disabled=!0:a.addEventListener("click",()=>{this.#n(t)})),a.classList.add(`${this.#a}__link`),a}#l(t){let a=document.createElement("li");a.classList.add(`${this.#a}__item`);let i=this.#r(t);return i.setAttribute("aria-label",window.WoltLabLanguage.getPhrase("wcf.page.pageNo",{pageNo:t})),t===this.page&&(i.setAttribute("aria-current","page"),i.classList.add(`${this.#a}__link--current`)),i.textContent=t.toLocaleString(document.documentElement.lang),a.append(i),a}#f(){let t=[],a,i;r().matches?(a=this.page,i=this.page):(a=this.page-1,a===3&&a--,i=this.page+1,i===this.count-2&&i++);for(let d=a;d<=i;d++)d<=1||d>=this.count||t.push(this.#l(d));return t}#i(){let t=document.createElement("li");t.classList.add(`${this.#a}__item`,`${this.#a}__item--ellipsis`);let a=document.createElement("button");return a.type="button",a.title=window.WoltLabLanguage.getPhrase("wcf.page.jumpTo"),a.classList.add("pagination__link","jsTooltip"),a.innerHTML="&ctdot;",a.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("jumpToPage"))}),t.append(a),t}get thresholdForEllipsis(){return r().matches?1:3}getLinkUrl(t){if(!this.url)return"";let a=new URL(this.url);return a.search+=a.search!==""?"&":"?",a.search+=new URLSearchParams([["pageNo",t.toString()]]).toString(),a.toString()}jumpToPage(t){let a=this.getLinkUrl(t);a?window.location.href=a:this.#n(t)}#n(t){let a=new CustomEvent("switchPage",{cancelable:!0,detail:t});this.dispatchEvent(a),a.defaultPrevented||(this.page=t)}get count(){return this.hasAttribute("count")?parseInt(this.getAttribute("count")):0}set count(t){this.setAttribute("count",t.toString()),this.#e()}get page(){return this.hasAttribute("page")?parseInt(this.getAttribute("page")):1}set page(t){this.setAttribute("page",t.toString()),this.#e()}get url(){return this.getAttribute("url")}set url(t){this.setAttribute("url",t),this.#e()}}window.customElements.define("woltlab-core-pagination",l)}{class e extends HTMLElement{connectedCallback(){this.setData(this.#e(),this.#t())}setData(l,c){this.#a(l,c)}get objectId(){return parseInt(this.getAttribute("object-id"))}get objectType(){return this.getAttribute("object-type")}#a(l,c){if(this.innerHTML="",!l.size)return;let t=document.createElement("button");t.classList.add("reactionSummary","jsTooltip"),t.title=window.WoltLabLanguage.getPhrase("wcf.reactions.summary.listReactions"),t.addEventListener("click",()=>{this.dispatchEvent(new Event("showDetails"))}),this.append(t),l.forEach((a,i)=>{let d=document.createElement("span");d.classList.add("reactionCountButton"),i===c&&d.classList.add("selected");let b=document.createElement("span");b.innerHTML=window.REACTION_TYPES[i].renderedIcon,d.append(b);let k=document.createElement("span");k.classList.add("reactionCount"),k.textContent=a.toString(),d.append(k),t.append(d)})}#e(){let l=JSON.parse(this.getAttribute("data"));return this.removeAttribute("data"),new Map(l)}#t(){return parseInt(this.getAttribute("selected-reaction"))}}window.customElements.define("woltlab-core-reaction-summary",e)}window.WoltLabLanguage=ne;window.WoltLabTemplate=V;window.HTMLParsedElement=pe;})();
+          }`,L.append(C)}g&&(this.#e.dateTime=p.toISOString(),this.#e.title=b.DateAndTime.format(p));let y;if(this.static)y=this.#e.title;else if(x<k.OneMinute)y=window.WoltLabLanguage.getPhrase("wcf.date.relative.now");else if(x<k.OneHour){let L=Math.trunc(x/k.OneMinute);y=b.Minutes.format(L*-1,"minute")}else if(x<k.OneWeek){let L=b.DayOfWeekAndTime.formatToParts(p);L[0].type==="weekday"?p.getTime()>t?y=this.#t(L,0):p.getTime()>a?y=this.#t(L,-1):y=L.map(W=>W.value).join(""):y=b.DateAndTime.format(p)}else y=b.Date.format(p);y=y.charAt(0).toUpperCase()+y.slice(1),this.#e.textContent=y}#t(g,p){return g.map(y=>y.type==="weekday"?b.TodayOrYesterday.format(p,"day"):y.value).join("")}}window.customElements.define("woltlab-core-date-time",q);let S=()=>{document.querySelectorAll("woltlab-core-date-time").forEach(h=>h.refresh(!1))},z,P=()=>{z=window.setInterval(()=>{i(),S()},6e4)};document.addEventListener("DOMContentLoaded",()=>P(),{once:!0}),document.addEventListener("visibilitychange",()=>{document.hidden?window.clearInterval(z):(S(),P())})}{class e extends HTMLElement{#a;#e;#t=new Map;constructor(){super(),this.#a=document.createElement("button")}connectedCallback(){if(this.hasAttribute("labels")&&(this.#t=new Map(JSON.parse(this.getAttribute("labels"))),this.removeAttribute("labels")),this.#t.size===0)throw new Error("Expected a non empty list of labels.");let l=`<span class="badge label">${window.WoltLabLanguage.getPhrase("wcf.label.none")}</span>`;this.#a.type="button",this.#a.classList.add("dropdownToggle"),this.#a.innerHTML=l,this.#a.addEventListener("click",a=>{a.preventDefault();let i=new CustomEvent("showPicker");this.dispatchEvent(i)}),this.#a.id=this.id,this.removeAttribute("id"),this.append(this.#a);let c=document.createElement("ul");c.classList.add("scrollableDropdownMenu");for(let[a,i]of this.#t)c.append(this.#s(a,i));if(!this.required){let a=document.createElement("li");a.classList.add("dropdownDivider"),c.append(a,this.#s(0,l))}let t=document.createElement("ul");t.classList.add("dropdownMenu"),t.append(c),this.append(t),this.classList.add("dropdown"),this.closest("form")!==null?(this.#e===void 0&&(this.#e=document.createElement("input"),this.#e.type="hidden",this.#e.name=`labelIDs[${this.dataset.groupId}]`,this.append(this.#e)),this.#e.value=(this.selected||0).toString()):this.#e?.remove(),this.selected&&(this.selected=this.selected)}#s(l,c){let t=document.createElement("button");t.type="button",t.dataset.labelId=l.toString(),t.innerHTML=c,t.addEventListener("click",()=>{this.selected=l});let a=document.createElement("li");return a.append(t),a}set selected(l){this.setAttribute("selected",l.toString()),this.#a.innerHTML=this.#t.get(l)||`<span class="badge label">${window.WoltLabLanguage.getPhrase("wcf.label.none")}</span>`,this.#e!==void 0&&(this.#e.value=l.toString())}get selected(){let l=parseInt(this.getAttribute("selected"));if(!Number.isNaN(l))return l}set disabled(l){l?this.setAttribute("disabled",""):this.removeAttribute("disabled"),this.#a.disabled=l,this.#e&&(this.#e.disabled=l)}get disabled(){return this.hasAttribute("disabled")}set required(l){l?this.setAttribute("required",""):this.removeAttribute("required")}get required(){return this.hasAttribute("required")}get labels(){return new Map(this.#t)}}window.customElements.define("woltlab-core-label-picker",e)}{let r=[24,48,96];class l extends HTMLElement{#a;#e;connectedCallback(){this.#a===void 0&&this.#t()}attributeChangedCallback(t,a,i){if(t==="size"){let d=parseInt(i||"");if(!r.includes(d)){let b=parseInt(a||"");r.includes(b)||(b=24),this.setAttribute(t,b.toString())}}}#t(){this.classList.add("loading-indicator"),this.hasAttribute("size")||this.setAttribute("size",24 .toString()),this.#a=document.createElement("fa-icon"),this.#a.size=this.size,this.#a.setIcon("spinner"),this.#e=document.createElement("span"),this.#e.classList.add("loading-indicator__text"),this.#e.textContent=window.WoltLabLanguage.getPhrase("wcf.global.loading"),this.#e.hidden=this.hideText;let t=document.createElement("div");t.classList.add("loading-indicator__wrapper"),t.append(this.#a,this.#e),this.append(t)}get size(){return parseInt(this.getAttribute("size"))}set size(t){if(!r.includes(t))throw new TypeError(`The size ${t} is unrecognized, permitted values are ${r.join(", ")}.`);this.setAttribute("size",t.toString()),this.#a&&(this.#a.size=t)}get hideText(){return this.hasAttribute("hide-text")}set hideText(t){t?this.setAttribute("hide-text",""):this.removeAttribute("hide-text"),this.#e&&(this.#e.hidden=t)}static get observedAttributes(){return["size"]}}window.customElements.define("woltlab-core-loading-indicator",l)}{let e,r=()=>(e===void 0&&(e=window.matchMedia("(max-width: 544px)")),e);class l extends HTMLElement{#a="pagination";connectedCallback(){this.#e(),r().addEventListener("change",()=>this.#e())}#e(){if(this.innerHTML="",this.count<2)return;this.classList.add(`${this.#a}__wrapper`);let t=this.#t();this.append(t);let a=this.#s();a&&t.append(a);let i=document.createElement("ul");i.classList.add(`${this.#a}__list`),t.append(i),i.append(this.#l(1)),this.page>this.thresholdForEllipsis+1&&i.append(this.#i()),this.#f().forEach(b=>{i.append(b)}),this.count-this.page>this.thresholdForEllipsis&&i.append(this.#i()),i.append(this.#l(this.count));let d=this.#o();d&&t.append(d)}#t(){let t=document.createElement("nav");return t.setAttribute("role","navigation"),t.setAttribute("aria-label",window.WoltLabLanguage.getPhrase("wcf.page.pagination")),t.classList.add(this.#a),t}#s(){if(this.page===1)return;let t=document.createElement("div");t.classList.add(`${this.#a}__prev`);let a=this.#r(this.page-1);a instanceof HTMLAnchorElement&&(a.rel="prev"),a.title=window.WoltLabLanguage.getPhrase("wcf.global.page.previous"),a.classList.add("jsTooltip"),t.append(a);let i=document.createElement("fa-icon");return i.setIcon("arrow-left"),a.append(i),t}#o(){if(this.page===this.count)return;let t=document.createElement("div");t.classList.add(`${this.#a}__next`);let a=this.#r(this.page+1);a instanceof HTMLAnchorElement&&(a.rel="next"),a.title=window.WoltLabLanguage.getPhrase("wcf.global.page.next"),a.classList.add("jsTooltip"),t.append(a);let i=document.createElement("fa-icon");return i.setIcon("arrow-right"),a.append(i),t}#r(t){let a,i=this.getLinkUrl(t);return i?(a=document.createElement("a"),a.href=i):(a=document.createElement("button"),a.type="button",this.page===t?a.disabled=!0:a.addEventListener("click",()=>{this.#n(t)})),a.classList.add(`${this.#a}__link`),a}#l(t){let a=document.createElement("li");a.classList.add(`${this.#a}__item`);let i=this.#r(t);return i.setAttribute("aria-label",window.WoltLabLanguage.getPhrase("wcf.page.pageNo",{pageNo:t})),t===this.page&&(i.setAttribute("aria-current","page"),i.classList.add(`${this.#a}__link--current`)),i.textContent=t.toLocaleString(document.documentElement.lang),a.append(i),a}#f(){let t=[],a,i;r().matches?(a=this.page,i=this.page):(a=this.page-1,a===3&&a--,i=this.page+1,i===this.count-2&&i++);for(let d=a;d<=i;d++)d<=1||d>=this.count||t.push(this.#l(d));return t}#i(){let t=document.createElement("li");t.classList.add(`${this.#a}__item`,`${this.#a}__item--ellipsis`);let a=document.createElement("button");return a.type="button",a.title=window.WoltLabLanguage.getPhrase("wcf.page.jumpTo"),a.classList.add("pagination__link","jsTooltip"),a.innerHTML="&ctdot;",a.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("jumpToPage"))}),t.append(a),t}get thresholdForEllipsis(){return r().matches?1:3}getLinkUrl(t){if(!this.url)return"";let a=new URL(this.url);return a.search+=a.search!==""?"&":"?",a.search+=new URLSearchParams([["pageNo",t.toString()]]).toString(),a.toString()}jumpToPage(t){let a=this.getLinkUrl(t);a?window.location.href=a:this.#n(t)}#n(t){let a=new CustomEvent("switchPage",{cancelable:!0,detail:t});this.dispatchEvent(a),a.defaultPrevented||(this.page=t)}get count(){return this.hasAttribute("count")?parseInt(this.getAttribute("count")):0}set count(t){this.setAttribute("count",t.toString()),this.#e()}get page(){return this.hasAttribute("page")?parseInt(this.getAttribute("page")):1}set page(t){this.setAttribute("page",t.toString()),this.#e()}get url(){return this.getAttribute("url")}set url(t){this.setAttribute("url",t),this.#e()}}window.customElements.define("woltlab-core-pagination",l)}{class e extends HTMLElement{connectedCallback(){this.setData(this.#e(),this.#t())}setData(l,c){this.#a(l,c)}get objectId(){return parseInt(this.getAttribute("object-id"))}get objectType(){return this.getAttribute("object-type")}#a(l,c){if(this.innerHTML="",!l.size)return;let t=document.createElement("button");t.classList.add("reactionSummary","jsTooltip"),t.title=window.WoltLabLanguage.getPhrase("wcf.reactions.summary.listReactions"),t.addEventListener("click",()=>{this.dispatchEvent(new Event("showDetails"))}),this.append(t),l.forEach((a,i)=>{let d=document.createElement("span");d.classList.add("reactionCountButton"),i===c&&d.classList.add("selected");let b=document.createElement("span");b.innerHTML=window.REACTION_TYPES[i].renderedIcon,d.append(b);let k=document.createElement("span");k.classList.add("reactionCount"),k.textContent=a.toString(),d.append(k),t.append(d)})}#e(){let l=JSON.parse(this.getAttribute("data"));return this.removeAttribute("data"),new Map(l)}#t(){return parseInt(this.getAttribute("selected-reaction"))}}window.customElements.define("woltlab-core-reaction-summary",e)}window.WoltLabLanguage=ne;window.WoltLabTemplate=V;window.HTMLParsedElement=pe;})();
 /**
  * Handles the low level management of language items.
  *
index 6b385e6d001eef7a3971d9fac25de4cb022b6c98..787d375892817f57c87cd62005778ac3366a57f7 100644 (file)
@@ -249,6 +249,7 @@ class ArticleAddForm extends AbstractForm
 
         // labels
         ArticleLabelObjectHandler::getInstance()->setCategoryIDs(ArticleCategory::getAccessibleCategoryIDs());
+        $this->labelPickers = ArticleCategory::getLabelPickers();
 
         if (isset($_REQUEST['tmpHash'])) {
             $this->tmpHash = $_REQUEST['tmpHash'];
@@ -490,6 +491,14 @@ class ArticleAddForm extends AbstractForm
         if (!empty($validationResult)) {
             throw new UserInputException('label', $validationResult);
         }
+
+        foreach ($this->labelIDs as $groupID => $labelID) {
+            foreach ($this->labelPickers as $labelPicker) {
+                if ($labelPicker->labelGroup->groupID == $groupID) {
+                    $labelPicker->selected = $labelID;
+                }
+            }
+        }
     }
 
     /**
@@ -599,7 +608,6 @@ class ArticleAddForm extends AbstractForm
 
         $this->labelGroupsToCategories = ArticleCategoryLabelCacheBuilder::getInstance()->getData();
         $this->labelGroups = ArticleCategory::getAccessibleLabelGroups();
-        $this->labelPickers = ArticleCategory::getLabelPickers();
 
         if (empty($_POST)) {
             $this->setDefaultValues();
index 417e0f07e325f8305add4cf4a9636d7d98ff0a2d..901b60eaac96e9e6095e6a16806c62a370699828 100644 (file)
@@ -206,7 +206,12 @@ class ArticleEditForm extends ArticleAddForm
             );
             if (isset($assignedLabels[$this->article->articleID])) {
                 foreach ($assignedLabels[$this->article->articleID] as $label) {
-                    $this->labelIDs[$label->groupID] = $label->labelID;
+                    foreach ($this->labelPickers as $labelPicker) {
+                        if ($labelPicker->labelGroup->groupID === $label->groupID) {
+                            $labelPicker->selected = $label->labelID;
+                            break;
+                        }
+                    }
                 }
             }
         }
index f063233470cc53808b055b6be787f9987b7cc837..75ebcfc19756ff62bc8c59cce160b5215ee3076b 100644 (file)
@@ -9,6 +9,8 @@ use wcf\util\StringUtil;
 
 final class LabelPicker
 {
+    public int $selected = 0;
+
     public function __construct(public readonly ViewableLabelGroup $labelGroup)
     {
     }
@@ -23,10 +25,25 @@ final class LabelPicker
         }
 
         return \sprintf(
-            '<woltlab-core-label-picker group-id="%d" title="%s" labels="%s"></woltlab-core-label-picker>',
-            $this->labelGroup->groupID,
+            <<<'EOT'
+                <woltlab-core-label-picker
+                    selected="%d"
+                    id="%s"
+                    title="%s"
+                    labels="%s"
+                    data-group-id="%d"
+                ></woltlab-core-label-picker>
+            EOT,
+            $this->selected,
+            $this->getId(),
             $this->labelGroup->getTitle(),
             StringUtil::encodeHTML(JSON::encode($labels)),
+            $this->labelGroup->groupID,
         );
     }
+
+    public function getId(): string
+    {
+        return "labelGroup{$this->labelGroup->groupID}";
+    }
 }