Skip to content

Commit aa372d4

Browse files
committed
Enhance bulk edit functionality in modular-list-bulk.js
- Introduced a new utility function, normalizeShareComponentItems, to standardize the handling of share component values, improving robustness against various input types. - Refactored existing logic to utilize the new utility function, streamlining the process of extracting user IDs from share components. - Updated documentation to clarify the purpose of the module and the organization of bulk-related features.
1 parent 57f8614 commit aa372d4

1 file changed

Lines changed: 72 additions & 116 deletions

File tree

dt-assets/js/modular-list-bulk.js

Lines changed: 72 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
'use strict';
22
/**
33
* Bulk Edit Operations for Modular List
4-
* Handles bulk edit, bulk delete, bulk messaging functionality
4+
* Handles bulk edit, bulk delete, bulk messaging functionality.
5+
*
6+
* This module is the primary home for bulk behavior on modular lists.
7+
* New bulk-related features (edit, delete, share/follow, messaging, app actions)
8+
* should be implemented here rather than in modular-list.js.
59
*
610
* Organized into three main sections:
711
* 1. Bulk Operations & List Controls - Checkbox handling, record counting, shared queue processing
@@ -878,6 +882,41 @@
878882
* Field Value Collection
879883
*/
880884

885+
function normalizeShareComponentItems(rawValue) {
886+
if (rawValue === null || rawValue === undefined) {
887+
return [];
888+
}
889+
890+
let value = rawValue;
891+
892+
if (typeof rawValue === 'string') {
893+
const trimmed = rawValue.trim();
894+
if (!trimmed || trimmed === 'null' || trimmed === '[]') {
895+
return [];
896+
}
897+
try {
898+
value = JSON.parse(trimmed);
899+
} catch (e) {
900+
console.error(
901+
'Error parsing share component string value as JSON:',
902+
e,
903+
'Value was:',
904+
rawValue,
905+
);
906+
return [];
907+
}
908+
} else if (Array.isArray(rawValue)) {
909+
value = rawValue;
910+
} else if (typeof rawValue === 'object') {
911+
value = Array.isArray(rawValue.value) ? rawValue.value : [rawValue];
912+
} else {
913+
// Unexpected primitive type (number, boolean, etc.)
914+
return [];
915+
}
916+
917+
return Array.isArray(value) ? value : [];
918+
}
919+
881920
function collectFieldValue(fieldKey, fieldType, fieldWrapper) {
882921
// Special case: comment field (not a real post field type)
883922
if (fieldType === 'comment') {
@@ -922,54 +961,37 @@
922961
}
923962

924963
// Fallback: check component value directly
925-
// dt-users-connection provides user IDs directly, so extract them
964+
// dt-users-connection should expose an array (or JSON string) of items
926965
if (shareComponent && shareComponent.value) {
927-
try {
928-
let value;
929-
if (typeof shareComponent.value === 'string') {
930-
const trimmed = shareComponent.value.trim();
931-
if (trimmed === '' || trimmed === '[]' || trimmed === 'null') {
932-
return null;
933-
}
934-
value = JSON.parse(shareComponent.value);
935-
} else if (Array.isArray(shareComponent.value)) {
936-
value = shareComponent.value;
937-
} else {
938-
return null;
939-
}
966+
const items = normalizeShareComponentItems(shareComponent.value);
967+
if (items.length === 0) {
968+
return null;
969+
}
940970

941-
if (Array.isArray(value) && value.length > 0) {
942-
// Extract user IDs directly from dt-users-connection format
943-
const userIds = value
944-
.map((item) => {
945-
const userId = item.id || item.user_id || null;
946-
return userId ? parseInt(userId, 10) : null;
947-
})
948-
.filter((id) => id !== null);
949-
950-
if (userIds.length > 0) {
951-
// Cache in fieldData for future use
952-
if (fieldData) {
953-
fieldData.shareUserIds = userIds;
954-
fieldData.shareUserId = userIds[0];
955-
// Store labels if available
956-
fieldData.shareUserLabels = {};
957-
value.forEach((item) => {
958-
const userId = item.id || item.user_id;
959-
if (userId) {
960-
fieldData.shareUserLabels[userId] = item.label || '';
961-
}
962-
});
963-
}
964-
return userIds;
971+
const userIds = items
972+
.map((item) => {
973+
const userId = item.id || item.user_id || null;
974+
return userId ? parseInt(userId, 10) : null;
975+
})
976+
.filter((id) => id !== null);
977+
978+
if (userIds.length === 0) {
979+
return null;
980+
}
981+
982+
if (fieldData) {
983+
fieldData.shareUserIds = userIds;
984+
fieldData.shareUserId = userIds[0];
985+
fieldData.shareUserLabels = {};
986+
items.forEach((item) => {
987+
const userId = item.id || item.user_id;
988+
if (userId) {
989+
fieldData.shareUserLabels[userId] = item.label || '';
965990
}
966-
}
967-
} catch (e) {
968-
console.error(
969-
'Error parsing share component value in collectFieldValue:',
970-
e,
971-
);
991+
});
972992
}
993+
994+
return userIds;
973995
}
974996

975997
return null;
@@ -1960,7 +1982,7 @@
19601982
}
19611983

19621984
// Function to process component value and update fieldData
1963-
// dt-users-connection provides user IDs directly, so no conversion needed
1985+
// dt-users-connection provides user IDs directly
19641986
const processShareComponentValue = async function (componentValue) {
19651987
const currentFieldData = bulkEditSelectedFields.find(
19661988
(f) => f.fieldKey === fieldKey,
@@ -1969,79 +1991,13 @@
19691991
return;
19701992
}
19711993

1972-
// Handle empty or invalid values
1973-
// componentValue might be a string, array, or object
1974-
if (
1975-
!componentValue ||
1976-
componentValue === null ||
1977-
componentValue === undefined
1978-
) {
1979-
// Value is null/undefined
1980-
currentFieldData.shareUserIds = [];
1981-
currentFieldData.shareUserLabels = {};
1982-
currentFieldData.shareUserId = null;
1983-
currentFieldData.shareUserLabel = null;
1984-
return;
1985-
}
1986-
1987-
// Handle if componentValue is already an array or object
1988-
let value;
1989-
if (Array.isArray(componentValue)) {
1990-
value = componentValue;
1991-
} else if (typeof componentValue === 'object') {
1992-
// If it's an object, try to convert to array format
1993-
value = Array.isArray(componentValue.value)
1994-
? componentValue.value
1995-
: [componentValue];
1996-
} else if (typeof componentValue === 'string') {
1997-
// Handle string values
1998-
const trimmed = componentValue.trim();
1999-
if (
2000-
trimmed === '' ||
2001-
trimmed === 'null' ||
2002-
trimmed === '[]' ||
2003-
trimmed === 'undefined'
2004-
) {
2005-
// Value is empty/null/empty array string
2006-
currentFieldData.shareUserIds = [];
2007-
currentFieldData.shareUserLabels = {};
2008-
currentFieldData.shareUserId = null;
2009-
currentFieldData.shareUserLabel = null;
2010-
return;
2011-
}
2012-
// Try to parse as JSON
2013-
try {
2014-
value = JSON.parse(componentValue);
2015-
} catch (e) {
2016-
console.error(
2017-
'Error parsing share component value as JSON:',
2018-
e,
2019-
'Value was:',
2020-
componentValue,
2021-
);
2022-
// Clear field data on parse error
2023-
currentFieldData.shareUserIds = [];
2024-
currentFieldData.shareUserLabels = {};
2025-
currentFieldData.shareUserId = null;
2026-
currentFieldData.shareUserLabel = null;
2027-
return;
2028-
}
2029-
} else {
2030-
// Unknown type
2031-
console.error(
2032-
'Share component value has unexpected type:',
2033-
typeof componentValue,
2034-
componentValue,
2035-
);
2036-
return;
2037-
}
1994+
const items = normalizeShareComponentItems(componentValue);
20381995

2039-
// Now process the value (should be an array at this point)
20401996
try {
2041-
if (Array.isArray(value) && value.length > 0) {
1997+
if (items.length > 0) {
20421998
// dt-users-connection format: [{id: <userId>, type: 'user', label: <displayName>}]
20431999
// Extract user IDs directly - no conversion needed!
2044-
const userIds = value
2000+
const userIds = items
20452001
.map((item) => {
20462002
// item.id is the user ID directly
20472003
const userId = item.id || item.user_id || null;
@@ -2052,7 +2008,7 @@
20522008
// Store user IDs and labels
20532009
currentFieldData.shareUserIds = userIds;
20542010
currentFieldData.shareUserLabels = {};
2055-
value.forEach((item) => {
2011+
items.forEach((item) => {
20562012
const userId = item.id || item.user_id;
20572013
if (userId) {
20582014
currentFieldData.shareUserLabels[userId] = item.label || '';

0 commit comments

Comments
 (0)