This is an automated email from the ASF dual-hosted git repository.

dixitdeepak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 30fd902549 Add common user profile page (OFBIZ-13419) (#1275)
30fd902549 is described below

commit 30fd902549fa02f4d6d9aef429c62d843af9be10
Author: Deepak Dixit <[email protected]>
AuthorDate: Tue May 26 16:33:25 2026 +0530

    Add common user profile page (OFBIZ-13419) (#1275)
    
    -Added a userprofile request/view in common-controller so it is
    available across applications.
    - Added common-theme rendering with screenlets for user login details,
    locale update, and timezone update, reusing existing setSessionLocale
    and setSessionTimeZone handlers
---
 applications/commonext/widget/CommonScreens.xml    |   6 +-
 .../common/webcommon/WEB-INF/common-controller.xml |  19 ++++
 framework/common/widget/CommonScreens.xml          |  13 ++-
 .../config/freemarker-whitelist.properties         |   2 +-
 themes/bluelight/template/Header.ftl               |   2 +-
 themes/common-theme/template/UserProfile.ftl       | 126 +++++++++++++++++++++
 themes/common-theme/widget/CommonScreens.xml       |  23 ++++
 themes/common-theme/widget/Theme.xml               |   1 +
 themes/flatgrey/template/Header.ftl                |   4 +-
 themes/helveticus/template/includes/Avatar.ftl     |   2 +-
 themes/rainbowstone/template/includes/Avatar.ftl   |   2 +-
 themes/tomahawk/template/AppBarClose.ftl           |   2 +-
 12 files changed, 191 insertions(+), 11 deletions(-)

diff --git a/applications/commonext/widget/CommonScreens.xml 
b/applications/commonext/widget/CommonScreens.xml
index 58483c7292..80898eceae 100644
--- a/applications/commonext/widget/CommonScreens.xml
+++ b/applications/commonext/widget/CommonScreens.xml
@@ -27,9 +27,9 @@ under the License.
                 <entity-one entity-name="PartyNameView" 
value-field="partyNameView">
                     <field-map field-name="partyId" 
from-field="userLogin.partyId"/>
                 </entity-one>
-                <set field="line.text" value="${uiLabelMap.CommonWelcome} 
${person.firstName} ${person.middleName} ${person.lastName}"/>
-                <set field="line.urlText" value="[${userLogin.userLoginId}]"/>
-                <set field="line.url" 
value="/partymgr/control/viewprofile?partyId=${userLogin.partyId}"/>
+                <set field="line.text" value="${uiLabelMap.CommonWelcome}"/>
+                <set field="line.urlText" value="${groovy: 
userLogin.userFullName?:userLogin.userLoginId}"/>
+                <set field="line.url" value="userprofile"/>
                 <set field="layoutSettings.topLines[]" from-field="line" 
global="true"/>
                 <script 
location="component://commonext/src/main/groovy/org/apache/ofbiz/commonext/ofbizsetup/ChangeOrgPartyId.groovy"/><!--
 to see ofbizsetup needs to be displayed -->
                 <!-- system info notes -->
diff --git a/framework/common/webcommon/WEB-INF/common-controller.xml 
b/framework/common/webcommon/WEB-INF/common-controller.xml
index 0f6741b14a..d8cc8d6279 100644
--- a/framework/common/webcommon/WEB-INF/common-controller.xml
+++ b/framework/common/webcommon/WEB-INF/common-controller.xml
@@ -130,6 +130,24 @@ under the License.
         <response name="error" type="request" value="main"/>
     </request-map>
 
+    <!-- userprofile requset -->
+    <request-map uri="userprofile">
+        <security https="true" auth="true"/>
+        <response name="success" type="view" value="userprofile"/>
+    </request-map>
+    <request-map uri="setUserLocale">
+        <security https="true" auth="false"/>
+        <event type="java" path="org.apache.ofbiz.common.CommonEvents" 
invoke="setSessionLocale"/>
+        <response name="success" type="request-redirect" value="userprofile"/>
+        <response name="error" type="request" value="userprofile"/>
+    </request-map>
+    <request-map uri="setUserTimeZone">
+        <security https="true" auth="false"/>
+        <event type="java" path="org.apache.ofbiz.common.CommonEvents" 
invoke="setSessionTimeZone"/>
+        <response name="success" type="request-redirect" value="userprofile"/>
+        <response name="error" type="request" value="userprofile"/>
+    </request-map>
+
     <!-- Common Mappings used for Set user organization -->
     <request-map uri="ListSetCompanies"><security https="true" 
auth="false"/><response name="success" type="view" value="ListSetCompanies" 
save-last-view="true"/></request-map>
 
@@ -360,6 +378,7 @@ under the License.
     <view-map name="LookupTimeDuration" type="screen" 
page="component://common/widget/LookupScreens.xml#TimeDuration" auth="false"/>
     <view-map name="ListTimezones" type="screen" 
page="component://common/widget/LookupScreens.xml#ListTimezones"/>
     <view-map name="ListVisualThemes" type="screen" 
page="component://common/widget/LookupScreens.xml#ListVisualThemes"/>
+    <view-map name="userprofile" type="screen" 
page="component://common/widget/CommonScreens.xml#userprofile"/>
 
     <view-map name="ajaxAutocompleteOptions" type="screen" 
page="component://common/widget/CommonScreens.xml#ajaxAutocompleteOptions"/>
 
diff --git a/framework/common/widget/CommonScreens.xml 
b/framework/common/widget/CommonScreens.xml
index c451fa29d2..2bf1d677fe 100644
--- a/framework/common/widget/CommonScreens.xml
+++ b/framework/common/widget/CommonScreens.xml
@@ -282,6 +282,17 @@ under the License.
             </widgets>
         </section>
     </screen>
+    <screen name="userprofile">
+        <section>
+            <actions>
+                <set field="titleProperty" value="CommonProfile" />
+            </actions>
+            <widgets>
+                <include-screen name="MinimalActions" />
+                <include-screen name="userprofile" 
location="${groovy:commonScreenLocations.userprofile?commonScreenLocations.userprofile:commonDecoratorLocation}"/>
+            </widgets>
+        </section>
+    </screen>
     <screen name="GetUiLabels">
         <section>
             <widgets>
@@ -379,4 +390,4 @@ under the License.
             </widgets>
         </section>
     </screen>
-</screens>
\ No newline at end of file
+</screens>
diff --git a/framework/security/config/freemarker-whitelist.properties 
b/framework/security/config/freemarker-whitelist.properties
index 3d078bc253..e306c1995f 100644
--- a/framework/security/config/freemarker-whitelist.properties
+++ b/framework/security/config/freemarker-whitelist.properties
@@ -58,7 +58,7 @@ java.text.DateFormat = LONG,getDateInstance
 # formatting via java.time.
 java.time.format.TextStyle = FULL_STANDALONE
 # TimeZone.LONG is a static int constant used in TimeZone.getDisplayName().
-java.util.TimeZone = LONG,getDefault
+java.util.TimeZone = LONG,getDefault,getTimeZone
 
 # ===========================================================================
 # OFBiz — Framework
diff --git a/themes/bluelight/template/Header.ftl 
b/themes/bluelight/template/Header.ftl
index 1d8a3f8bb7..762576cde1 100644
--- a/themes/bluelight/template/Header.ftl
+++ b/themes/bluelight/template/Header.ftl
@@ -164,7 +164,7 @@ under the License.
         <li class="control-area">
           <ul id="preferences-menu">
             <#if userLogin??>
-              <li class="user">${userName}</li>
+              <li class="user"><a 
href="<@ofbizUrl>userprofile</@ofbizUrl>">${userName}</a></li>
               <#if orgName?has_content>
                 <li class="org">${orgName}</li>
               </#if>
diff --git a/themes/common-theme/template/UserProfile.ftl 
b/themes/common-theme/template/UserProfile.ftl
new file mode 100644
index 0000000000..21e63b7fbb
--- /dev/null
+++ b/themes/common-theme/template/UserProfile.ftl
@@ -0,0 +1,126 @@
+<#--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<#assign lastLocaleId = (userLogin.lastLocale)!>
+<#assign selectedLocaleId = lastLocaleId>
+<#if !(selectedLocaleId?has_content)>
+  <#assign selectedLocaleId = locale.toString()>
+</#if>
+<#assign lastTimeZoneId = (userLogin.lastTimeZone)!>
+<#assign selectedTimeZoneId = lastTimeZoneId>
+<#if !(selectedTimeZoneId?has_content) && timeZone??>
+  <#assign selectedTimeZoneId = timeZone.getID()>
+</#if>
+<#assign displayStyle = Static["java.util.TimeZone"].LONG>
+<#assign availableLocales = 
Static["org.apache.ofbiz.base.util.UtilMisc"].availableLocales()>
+<#assign availableTimeZones = 
Static["org.apache.ofbiz.base.util.UtilDateTime"].availableTimeZones()>
+
+<#assign lastLocaleDisplay = uiLabelMap.CommonNA>
+<#if lastLocaleId?has_content>
+  <#assign lastLocaleObject = 
Static["org.apache.ofbiz.base.util.UtilMisc"].parseLocale(lastLocaleId)>
+  <#assign lastLocaleDisplay = lastLocaleObject.getDisplayName(locale) + " [" 
+ lastLocaleId?replace("_", "-") + "]">
+</#if>
+
+<#assign lastTimeZoneDisplay = uiLabelMap.CommonNA>
+<#if lastTimeZoneId?has_content>
+  <#assign lastTimeZone = 
Static["java.util.TimeZone"].getTimeZone(lastTimeZoneId)>
+  <#assign lastTimeZoneDisplay = 
lastTimeZone.getDisplayName(lastTimeZone.useDaylightTime(), displayStyle, 
locale) + " (" + lastTimeZone.getID() + ")">
+</#if>
+
+<div class="screenlet">
+  <div class="screenlet-title-bar">
+    <ul>
+      <li class="h3">${uiLabelMap.CommonProfile}</li>
+    </ul>
+    <br class="clear"/>
+  </div>
+  <div class="screenlet-body">
+    <table cellspacing="0" class="basic-table">
+      <tr>
+        <td class="label">${uiLabelMap.CommonUserLoginId}</td>
+        <td>${((userLogin.userLoginId)!uiLabelMap.CommonNA)}</td>
+      </tr>
+      <tr>
+        <td class="label">${uiLabelMap.CommonUsername}</td>
+        <td>${((userLogin.userFullName)!uiLabelMap.CommonNA)}</td>
+      </tr>
+      <tr>
+        <td class="label">${uiLabelMap.CommonLanguageTitle}</td>
+        <td>${lastLocaleDisplay!}</td>
+      </tr>
+      <tr>
+        <td class="label">${uiLabelMap.CommonTimeZone}</td>
+        <td>${lastTimeZoneDisplay!}</td>
+      </tr>
+    </table>
+  </div>
+</div>
+
+<div class="screenlet">
+  <div class="screenlet-title-bar">
+    <ul>
+      <li class="h3">${uiLabelMap.CommonLanguageTitle}</li>
+    </ul>
+    <br class="clear"/>
+  </div>
+  <div class="screenlet-body">
+    <form method="post" action="<@ofbizUrl>setUserLocale</@ofbizUrl>">
+      <div>
+        <select name="newLocale">
+          <#list availableLocales as availableLocale>
+            <#assign availableLocaleId = availableLocale.toString()>
+            <#assign langAttr = availableLocaleId?replace("_", "-")>
+            <option value="${availableLocaleId}"<#if availableLocaleId == 
selectedLocaleId!> selected="selected"</#if>>
+              ${availableLocale.getDisplayName(availableLocale)!} 
[${langAttr!}]
+            </option>
+          </#list>
+        </select>
+      </div>
+      <div>
+        <input type="submit" value="${uiLabelMap.CommonUpdate}"/>
+      </div>
+    </form>
+  </div>
+</div>
+
+<div class="screenlet">
+  <div class="screenlet-title-bar">
+    <ul>
+      <li class="h3">${uiLabelMap.CommonTimeZone}</li>
+    </ul>
+    <br class="clear"/>
+  </div>
+  <div class="screenlet-body">
+    <form method="get" action="<@ofbizUrl>setUserTimeZone</@ofbizUrl>">
+      <div>
+        <select name="tzId">
+          <#list availableTimeZones as availableTz>
+            <#assign availableTzId = availableTz.getID()>
+            <option value="${availableTzId}"<#if availableTzId == 
selectedTimeZoneId!> selected="selected"</#if>>
+              ${availableTz.getDisplayName(availableTz.useDaylightTime(), 
displayStyle, locale)} (${availableTzId})
+            </option>
+          </#list>
+        </select>
+      </div>
+      <div>
+        <input name="submitButton" type="submit" 
value="${uiLabelMap.CommonUpdate}"/>
+      </div>
+    </form>
+  </div>
+</div>
diff --git a/themes/common-theme/widget/CommonScreens.xml 
b/themes/common-theme/widget/CommonScreens.xml
index 71c995cb93..80f0abb89b 100644
--- a/themes/common-theme/widget/CommonScreens.xml
+++ b/themes/common-theme/widget/CommonScreens.xml
@@ -658,6 +658,29 @@ under the License.
             </widgets>
         </section>
     </screen>
+    <screen name="userprofile">
+        <section>
+            <actions>
+                <property-map resource="CommonUiLabels" map-name="uiLabelMap" 
global="true"/>
+                <set field="titleProperty" value="CommonProfile"/>
+            </actions>
+            <widgets>
+                <decorator-screen name="main-decorator" 
location="${parameters.mainDecoratorLocation}">
+                    <decorator-section name="body">
+                        <section>
+                            <actions>
+                                <set field="userProfileTemplateLocation" 
from-field="layoutSettings.VT_USER_PROFILE_TMPLT_LOC" 
default-value="component://common-theme/template/UserProfile.ftl"/>
+                            </actions>
+                            <widgets />
+                        </section>
+                        <platform-specific>
+                            <html><html-template 
location="${userProfileTemplateLocation}"/></html>
+                        </platform-specific>
+                    </decorator-section>
+                </decorator-screen>
+            </widgets>
+        </section>
+    </screen>
     <screen name="GetUiLabels">
         <section>
             <actions>
diff --git a/themes/common-theme/widget/Theme.xml 
b/themes/common-theme/widget/Theme.xml
index e10663e2fd..df4b0aa880 100644
--- a/themes/common-theme/widget/Theme.xml
+++ b/themes/common-theme/widget/Theme.xml
@@ -153,6 +153,7 @@ under the License.
             <screen name="ajaxNotLoggedIn"/>
             <screen name="requirePasswordChange"/>
             <screen name="forgotPassword"/>
+            <screen name="userprofile"/>
             <screen name="GetUiLabels"/>
             <screen name="help"/>
             <screen name="viewBlocked"/>
diff --git a/themes/flatgrey/template/Header.ftl 
b/themes/flatgrey/template/Header.ftl
index 9eee7fad28..0d213fe935 100644
--- a/themes/flatgrey/template/Header.ftl
+++ b/themes/flatgrey/template/Header.ftl
@@ -143,7 +143,7 @@ under the License.
             <#if layoutSettings.topLines?has_content>
               <#list layoutSettings.topLines as topLine>
                 <#if topLine.text??>
-                  <li>${topLine.text}<a 
href="${StringUtil.wrapString(topLine.url!)}${StringUtil.wrapString(externalKeyParam)}">${topLine.urlText!}</a></li>
+                  <li>${topLine.text} <a 
href="${StringUtil.wrapString(topLine.url!)}">${topLine.urlText!}</a></li>
                 <#elseif topLine.dropDownList??>
                   <li><#include 
"component://common-theme/template/includes/InsertDropDown.ftl"/></li>
                 <#else>
@@ -151,7 +151,7 @@ under the License.
                 </#if>
               </#list>
             <#else>
-              <li>${userLogin.userFullName!userLogin.userLoginId}</li>
+              <li><a 
href="<@ofbizUrl>userprofile</@ofbizUrl>">${userLogin.userFullName!userLogin.userLoginId}</a></li>
             </#if>
             <li><a 
href="<@ofbizUrl>logout</@ofbizUrl>">${uiLabelMap.CommonLogout}</a></li>
           <#else>
diff --git a/themes/helveticus/template/includes/Avatar.ftl 
b/themes/helveticus/template/includes/Avatar.ftl
index 67606367a4..e078617809 100644
--- a/themes/helveticus/template/includes/Avatar.ftl
+++ b/themes/helveticus/template/includes/Avatar.ftl
@@ -26,7 +26,7 @@ under the License.
     </svg>
 <#--</#if>-->
     <div id="user-details" style="display:none;">
-        <p id="user-name">
+        <p id="user-name" onclick="javascript:location.href='userprofile'">
             <strong>${userLogin.userFullName!userLogin.userLoginId}</strong>
         </p>
 
diff --git a/themes/rainbowstone/template/includes/Avatar.ftl 
b/themes/rainbowstone/template/includes/Avatar.ftl
index 3f6ecce19f..8065998220 100644
--- a/themes/rainbowstone/template/includes/Avatar.ftl
+++ b/themes/rainbowstone/template/includes/Avatar.ftl
@@ -30,7 +30,7 @@ under the License.
         <#else>-->
             <img src="/rainbowstone/images/avatar.svg" alt="user">
 <#--        </#if>-->
-            <div id="user-name">
+            <div id="user-name" 
onclick="javascript:location.href='userprofile'">
                 <span>${userLogin.userFullName!userLogin.userLoginId}</span>
             </div>
             <a id="user-lang" href="<@ofbizUrl>ListLocales</@ofbizUrl>">
diff --git a/themes/tomahawk/template/AppBarClose.ftl 
b/themes/tomahawk/template/AppBarClose.ftl
index 0bdb853ef8..40e48c5980 100644
--- a/themes/tomahawk/template/AppBarClose.ftl
+++ b/themes/tomahawk/template/AppBarClose.ftl
@@ -76,7 +76,7 @@ under the License.
     </#if>
     <li <#if companyListSize?default(0) &lt;= 1>class="language"</#if>><a 
href="<@ofbizUrl>ListLocales</@ofbizUrl>">${uiLabelMap.CommonLanguageTitle}</a></li>
     <#if userLogin?exists>
-      <li class="user">${userName}</li>
+      <li class="user"><a 
href="<@ofbizUrl>userprofile</@ofbizUrl>">${userName}</a></li>
     </#if>
   </ul>
 </div>

Reply via email to