Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
65764f9
LPD-9465 - Refactor. Property check to prevent app crash
juanjofgliferay Oct 23, 2025
353d6a7
LPD-9465 - Refactor. Move component to TS
juanjofgliferay Oct 23, 2025
1151644
LPD-9465 - Feat. Update model to store FDS Custom Views
juanjofgliferay Oct 31, 2025
4c3258b
LPD-9465 - Feat. Serialize custom views
juanjofgliferay Oct 31, 2025
a287867
LPD-9465 - Feat. Retrieve and handle custom views in FDS
juanjofgliferay Oct 31, 2025
6b9233e
LPD-9465 - Refactor. Return empty array as default customViews for th…
juanjofgliferay Oct 31, 2025
095147d
LPD-9465 - Refactor. Validate customViewsEnabled
juanjofgliferay Oct 31, 2025
f19107b
LPD-9465 - Refactor. Remove customViews from sample as endpoint is no…
juanjofgliferay Oct 31, 2025
3acfdce
LPD-9465 - Refactor. Remove Portalpreferences requests
juanjofgliferay Oct 31, 2025
4ed39c7
LPD-9465 - SF
juanjofgliferay Oct 31, 2025
6ae166f
LPD-9465 - Feat. Include label to reflect custom view changes (not on…
juanjofgliferay Nov 4, 2025
2c45ccd
LPD-9465 - Include custom views feature tests
juanjofgliferay Nov 4, 2025
c0e0462
LPD-9465 - Refactor - Remove dataSetERC as it is returned as fdsName
juanjofgliferay Nov 6, 2025
419b29a
LPD-9465 - Redefine and rename object definition
juanjofgliferay Nov 6, 2025
79de794
LPD-9465 - Feat. Serialize user views filter by data set ERC and creator
juanjofgliferay Nov 6, 2025
65f7abe
LPD-9465 - Refactor. Update endpoint and remove utility
juanjofgliferay Nov 6, 2025
e4711fa
LPD-9465 - Refactor. Update fields type
juanjofgliferay Nov 7, 2025
f6b0751
LPD-9465 - Feat. Serialize custom views for system data sets
juanjofgliferay Nov 7, 2025
ccb4872
LPD-9465 - Feat. Prevent custom views serialization if they are not e…
juanjofgliferay Nov 7, 2025
d0d1fa6
LPD-9465 - Feat. Enable custom views in FDS Sample
juanjofgliferay Nov 7, 2025
7f10825
LPD-9465 - Refactor. Update visibleFieldNames when reset
juanjofgliferay Nov 7, 2025
cf739e7
LPD-9465 - SF
juanjofgliferay Nov 7, 2025
f5f1521
LPD-9465 - Refactor. Extract filter expression
juanjofgliferay Nov 11, 2025
65e1b68
LPD-9465 - Feat. Allow custom views for signed in users
juanjofgliferay Nov 11, 2025
1759463
LPD-9465 - Feat. Add UI to enable custom views
juanjofgliferay Nov 11, 2025
03d55ab
LPD-9465 - Refactor. Clean up
juanjofgliferay Nov 11, 2025
4452f51
LPD-9465 - Refactor. Update ObjectEntryManager configuration
juanjofgliferay Nov 13, 2025
f8f9ea2
LPD-9465 - Refactor. Set modifiedFields in the defaultView so we can …
juanjofgliferay Nov 13, 2025
2c4ebf2
LPD-9465 - Refactor. Update custom view with response data
juanjofgliferay Nov 13, 2025
86888d6
LPD-9465 - Refactor. Prevent fields not in schema to be added as visi…
juanjofgliferay Nov 18, 2025
2c173c1
LPD-9465 - Feat. Block View settings while working with Custom Views …
juanjofgliferay Nov 18, 2025
69947f6
LPD-9465 - Refactor. Apply same column configuration for all User Fea…
juanjofgliferay Nov 19, 2025
584882d
LPD-9465 - Refactor. Fix Default View update
juanjofgliferay Nov 19, 2025
ec71b49
LPD-9465 - Feat. Sync state and config in URL
juanjofgliferay Nov 19, 2025
e12d121
LPD-9465 - Move test back to routine
juanjofgliferay Nov 19, 2025
259ff21
LPD-9465 - Rename
juanjofgliferay Nov 20, 2025
dd76118
LPD-9465 - Refactor. Remove all snapshots before finishing test
juanjofgliferay Nov 20, 2025
80d8692
LPD-9465 - Refactor. Prevent rename action to mark view as modified
juanjofgliferay Nov 20, 2025
a3739e0
LPD-9465 - Refactor. Clarify usage
juanjofgliferay Nov 20, 2025
68bca19
LPD-9465 - Refactor. Move snapshot handling to FrontendDataSet to pro…
juanjofgliferay Nov 21, 2025
67acf5a
LPD-9465 - Adjust locator as filters can vary
juanjofgliferay Nov 21, 2025
78020b8
LPD-9465 - Refactor. Move shared serializeSnapshots to base class
juanjofgliferay Nov 21, 2025
ef6f836
LPD-9465 - Refactor. Update reducer, passing initial state object and…
juanjofgliferay Nov 25, 2025
9aa5d82
LPD-9465 - Refactor. Prevent filter activation/deactivation mutate or…
juanjofgliferay Nov 25, 2025
36bbd12
LPD-9465 - Refactor. Prevent non signedIn users to manage User views
juanjofgliferay Nov 25, 2025
b49f236
LPD-9465 - Refactor. Revert changes that prevented initial filter loa…
juanjofgliferay Nov 26, 2025
7e1a7d4
LPD-9465 - Feat. Add new action to update filters after loading CX wi…
juanjofgliferay Nov 26, 2025
56d7839
LPD-9465 - Refactor. Adjust tests
juanjofgliferay Nov 26, 2025
48b57e8
LPD-9465 - Refactor. Rename and simplify
juanjofgliferay Nov 26, 2025
69cf555
LPD-9465 - Refactor. Remove default empty array of snapshots
juanjofgliferay Nov 26, 2025
6d7d784
LPD-9465 - Refactor. Safe check
juanjofgliferay Nov 26, 2025
3145d71
LPD-9465 - Refactor. Rename
juanjofgliferay Nov 26, 2025
a496cd4
LPD-9465 - Refactor. Ensure we are working with a fresh set of filter…
juanjofgliferay Nov 26, 2025
d689425
LPD-9465 - Enable user views feature flag
juanjofgliferay Nov 27, 2025
da272a2
LPD-9465 Polish the way we get snapshots from the backend: do not use…
dsanz Nov 27, 2025
1f636e0
LPD-9465 Do not read active view settings if we have snapshots in place
dsanz Nov 27, 2025
bf6c277
LPD-9465 Make advanced sample work when system dataset is created fro…
dsanz Nov 27, 2025
481d883
LPD-9465 - Refactor. Rename object definition
juanjofgliferay Nov 27, 2025
236db00
LPD-9465 - Feat. Add deepClone utility to create a copy of snapshots …
juanjofgliferay Nov 27, 2025
790b954
LPD-9465 - Refactor. Set correct data on updateFilterActivation and a…
juanjofgliferay Nov 27, 2025
ac1c2f6
LPD-9465 - Refactor. Simplify, pass filtered snapshot to the state
juanjofgliferay Nov 27, 2025
6d9f286
LPD-9465 - Refactor. Rename
juanjofgliferay Dec 1, 2025
b086d92
LPD-9465 - Refactor. Revert initial value of reducer as it needs to r…
juanjofgliferay Dec 1, 2025
0e6c951
LPD-9465 - Feat. Handle Default view and prevent object mutation (mai…
juanjofgliferay Dec 1, 2025
618c2d1
LPD-9465 - Refactor. Move deepClone utility to frontend-js-web
juanjofgliferay Dec 3, 2025
41f60bc
LPD-9465 - Refactor. Simplify null value handling
juanjofgliferay Dec 3, 2025
4759992
LPD-9465 - Refactor. Memoize intial active filters.
juanjofgliferay Dec 3, 2025
7dfd557
LPD-9465 - Refactor. Throw exception if no valid response
juanjofgliferay Dec 3, 2025
36fd3ec
LPD-9465 - Refactor. Control CX loading and prevent infinite loop whe…
juanjofgliferay Dec 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -183,13 +184,17 @@ public void render(
return;
}

Map<String, Object> properties = dataSetObjectEntry.getProperties();

if (!FeatureFlagManagerUtil.isEnabled(
_portal.getCompanyId(httpServletRequest), "LPD-38564")) {

_fdsRenderer.render(
HashMapBuilder.<String, Object>put(
"namespace",
fragmentRendererContext.getFragmentElementId()
).put(
"snapshotsEnabled", properties.get("snapshotsEnabled")
Copy link
Collaborator

@dsanz dsanz Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine for now, nevertheless, we will improve this to include:

  • Serialization from custom/system datasets. Custom datasets get it from the object entry, system datasets get it from the Java SystemFDSEntry interface, which requires us to add the corresponding method there
  • Ability to bring initial value via tag lib attribute
  • Check current permissions to disable this for guests. This check is primitive, in the future we can make it more complicated but we can include the guest check for the moment

).put(
"style", "fluid"
).build(),
Expand Down Expand Up @@ -230,6 +235,8 @@ public void render(
HashMapBuilder.<String, Object>put(
"namespace",
fragmentRendererContext.getFragmentElementId()
).put(
"snapshotsEnabled", properties.get("snapshotsEnabled")
).put(
"style", "fluid"
).put(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const Settings = ({
onDataSetUpdate,
spritemap,
}: IDataSetSectionProps) => {
const [snapshotsEnabled, setSnapshotsEnabled] = useState<boolean>(
dataSet.snapshotsEnabled
);
const [defaultVisualizationMode, setDefaultVisualizationMode] = useState<
string | undefined
>(NOT_CONFIGURED_VISUALIZATION_MODE.type);
Expand All @@ -57,6 +60,7 @@ const Settings = ({
const body = {
defaultVisualizationMode,
hideManagementBarInEmptyState,
snapshotsEnabled,
};

const url = getDataSetResourceURL({
Expand Down Expand Up @@ -350,8 +354,8 @@ const Settings = ({
{Liferay.Language.get('user-customization')}
</h3>

<ClayLayout.Row className="align-items-center justify-content-between">
<ClayLayout.Col size={8}>
<ClayLayout.Row className="align-items-center justify-content-between mb-4">
<ClayLayout.Col size={11}>
<div>
<label
htmlFor="hide-management-bar-in-empty-state"
Expand All @@ -370,7 +374,7 @@ const Settings = ({
</div>
</ClayLayout.Col>

<ClayLayout.Col size={4}>
<ClayLayout.Col size={1}>
<div className="d-flex form-group justify-content-end mr-2">
<ClayToggle
disabled={loading}
Expand All @@ -380,6 +384,35 @@ const Settings = ({
</div>
</ClayLayout.Col>
</ClayLayout.Row>

{Liferay.FeatureFlags['LPD-10683'] && (
<ClayLayout.Row className="align-items-center justify-content-between mb-4">
<ClayLayout.Col size={11}>
<div>
<label htmlFor="user-views-toggle">
{Liferay.Language.get(
'enable-user-views'
)}
</label>
</div>

<div>
{Liferay.Language.get('user-views-help')}
</div>
</ClayLayout.Col>

<ClayLayout.Col
className="align-self-start"
size={1}
>
<ClayToggle
id="user-views-toggle"
onToggle={setSnapshotsEnabled}
toggled={snapshotsEnabled}
/>
</ClayLayout.Col>
</ClayLayout.Row>
)}
</ClayLayout.SheetSection>

<ClayLayout.SheetFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export interface IDataSet {
restApplication: string;
restEndpoint: string;
restSchema: string;
snapshotsEnabled: boolean;
sortsOrder?: string;
tableSectionsOrder?: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public JSONObject serializePagination(
public String serializePropsTransformer(
String fdsName, HttpServletRequest httpServletRequest);

public JSONArray serializeSnapshots(
String fdsName, HttpServletRequest httpServletRequest);

public List<FDSSortItem> serializeSorts(
String fdsName, HttpServletRequest httpServletRequest);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
import com.liferay.portal.kernel.json.JSONUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.HashMapBuilder;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.template.react.renderer.ComponentDescriptor;
import com.liferay.portal.template.react.renderer.ReactRenderer;

Expand Down Expand Up @@ -110,6 +112,21 @@ public void render(
}
}
else {
Boolean snapshotsEnabled;

ThemeDisplay themeDisplay =
(ThemeDisplay)httpServletRequest.getAttribute(
WebKeys.THEME_DISPLAY);

if (Validator.isNull(props.get("snapshotsEnabled")) ||
!themeDisplay.isSignedIn()) {

snapshotsEnabled = false;
}
else {
snapshotsEnabled = (boolean)props.get("snapshotsEnabled");
}

props.putAll(
HashMapBuilder.<String, Object>put(
"additionalAPIURLParameters",
Expand Down Expand Up @@ -211,6 +228,25 @@ public void render(

return paginationJSONObject;
}
).put(
"snapshots",
() -> {
if (!snapshotsEnabled) {
return null;
}

JSONArray snapshotsJSONArray =
fdsSerializer.serializeSnapshots(
fdsName, httpServletRequest);

if (JSONUtil.isEmpty(snapshotsJSONArray)) {
return null;
}

return snapshotsJSONArray;
}
).put(
"snapshotsEnabled", snapshotsEnabled
).put(
"sorts",
() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,30 @@

import com.liferay.frontend.data.set.internal.url.FDSAPIURLBuilder;
import com.liferay.frontend.data.set.url.FDSAPIURLResolverRegistry;
import com.liferay.object.entry.util.ObjectEntryThreadLocal;
import com.liferay.object.model.ObjectDefinition;
import com.liferay.object.rest.dto.v1_0.ObjectEntry;
import com.liferay.object.rest.manager.v1_0.DefaultObjectEntryManagerProvider;
import com.liferay.object.rest.manager.v1_0.ObjectEntryManager;
import com.liferay.object.rest.manager.v1_0.ObjectEntryManagerRegistry;
import com.liferay.object.service.ObjectDefinitionLocalService;
import com.liferay.petra.string.StringBundler;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.vulcan.dto.converter.DefaultDTOConverterContext;
import com.liferay.portal.vulcan.pagination.Page;

import jakarta.servlet.http.HttpServletRequest;

import java.util.Collection;
import java.util.Map;

import org.osgi.service.component.annotations.Reference;

/**
Expand All @@ -26,7 +47,79 @@ public FDSAPIURLBuilder createFDSAPIURLBuilder(
restEndpoint, restSchema);
}

protected JSONArray serializeSnapshots(
String fdsName, HttpServletRequest httpServletRequest,
ObjectDefinitionLocalService objectDefinitionLocalService,
ObjectEntryManagerRegistry objectEntryManagerRegistry)
throws Exception {

ThemeDisplay themeDisplay =
(ThemeDisplay)httpServletRequest.getAttribute(
WebKeys.THEME_DISPLAY);

String filterExpression = StringBundler.concat(
"(fdsName eq '", fdsName, "' and creatorId eq ",
themeDisplay.getUserId(), ")");

ObjectEntryThreadLocal.setSkipObjectEntryResourcePermission(true);

JSONArray jsonArray = JSONUtil.putAll();

try {
ObjectDefinition objectDefinition =
objectDefinitionLocalService.fetchObjectDefinition(
PortalUtil.getCompanyId(httpServletRequest),
"DataSetSnapshot");

ObjectEntryManager objectEntryManager =
DefaultObjectEntryManagerProvider.provide(
objectEntryManagerRegistry.getObjectEntryManager(
objectDefinition.getCompanyId(),
objectDefinition.getStorageType()));

Page<ObjectEntry> page = objectEntryManager.getObjectEntries(
PortalUtil.getCompanyId(httpServletRequest), objectDefinition,
null, null,
new DefaultDTOConverterContext(
false, null, null, null, null,
LocaleUtil.getMostRelevantLocale(), null, null),
filterExpression, null, null, null);

Collection<ObjectEntry> objectEntries = page.getItems();

jsonArray = JSONUtil.toJSONArray(
objectEntries,
(ObjectEntry objectEntry) -> {
Map<String, Object> properties =
objectEntry.getProperties();

return JSONUtil.put(
"configuration", properties.get("viewConfig")
).put(
"erc", objectEntry.getExternalReferenceCode()
).put(
"label", String.valueOf(properties.get("label"))
);
});
}
catch (Exception exception) {
if (_log.isWarnEnabled()) {
_log.warn(
"Unable to get snapshot FDS config object entries",
exception);
}
}
finally {
ObjectEntryThreadLocal.setSkipObjectEntryResourcePermission(false);
}

return jsonArray;
}

@Reference
protected FDSAPIURLResolverRegistry fdsAPIURLResolverRegistry;

private static final Log _log = LogFactoryUtil.getLog(
BaseFDSSerializer.class);

}
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,22 @@ public String serializePropsTransformer(
return String.valueOf(properties.get("propsTransformer"));
}

@Override
public JSONArray serializeSnapshots(
String fdsName, HttpServletRequest httpServletRequest) {

try {
return serializeSnapshots(
fdsName, httpServletRequest, _objectDefinitionLocalService,
_objectEntryManagerRegistry);
}
catch (Exception exception) {
_log.error("Unable to serialize snapshots", exception);

return _jsonFactory.createJSONArray();
}
}

@Override
public List<FDSSortItem> serializeSorts(
String fdsName, HttpServletRequest httpServletRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@
import com.liferay.frontend.data.set.view.FDSViewContextContributorRegistry;
import com.liferay.frontend.data.set.view.FDSViewRegistry;
import com.liferay.frontend.taglib.clay.servlet.taglib.util.CreationMenu;
import com.liferay.object.rest.manager.v1_0.ObjectEntryManagerRegistry;
import com.liferay.object.service.ObjectDefinitionLocalService;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.json.JSONUtil;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.PortalUtil;
Expand Down Expand Up @@ -254,6 +258,22 @@ public String serializePropsTransformer(
return systemFDSEntry.getPropsTransformer();
}

@Override
public JSONArray serializeSnapshots(
String fdsName, HttpServletRequest httpServletRequest) {

try {
return serializeSnapshots(
fdsName, httpServletRequest, _objectDefinitionLocalService,
_objectEntryManagerRegistry);
}
catch (Exception exception) {
_log.error("Unable to serialize snapshots", exception);

return JSONUtil.putAll();
}
}

@Override
public List<FDSSortItem> serializeSorts(
String fdsName, HttpServletRequest httpServletRequest) {
Expand Down Expand Up @@ -400,6 +420,9 @@ private void _serializeFilters(
}
}

private static final Log _log = LogFactoryUtil.getLog(
SystemFDSSerializer.class);

private static final SystemFDSEntry _systemFDSEntry = new SystemFDSEntry() {

public int getDefaultItemsPerPage() {
Expand Down Expand Up @@ -442,4 +465,10 @@ public String getTitle() {

};

@Reference
private ObjectDefinitionLocalService _objectDefinitionLocalService;

@Reference
private ObjectEntryManagerRegistry _objectEntryManagerRegistry;

}
Loading