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) <= 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>