Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 7 additions & 10 deletions src/components/forms/form-template-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ import TextEditorV3 from "openstack-uicore-foundation/lib/components/inputs/edit
import Swal from "sweetalert2";
import FormRepeater from "../form-repeater";
import FormTemplateMetaFieldForm from "./form-template-meta-field-form";
import { scrollToError, shallowEqual, hasErrors } from "../../utils/methods";
import {
scrollToError,
shallowEqual,
hasErrors,
getMediaInputValue
} from "../../utils/methods";
import {
MAX_FORM_TEMPLATE_MATERIALS_UPLOAD_SIZE,
MAX_FORM_TEMPLATE_MATERIALS_UPLOAD_QTY,
Expand Down Expand Up @@ -100,14 +105,6 @@ const FormTemplateForm = ({
}
};

const getMediaInputValue = () =>
entity.materials.length > 0
? entity.materials.map((material) => ({
...material,
filename: material.filename ?? material.file_path ?? material.file_url
}))
: [];

const handleSubmit = (ev) => {
ev.preventDefault();
entity.meta_fields = getNormalizedMetaFields();
Expand Down Expand Up @@ -247,7 +244,7 @@ const FormTemplateForm = ({
<UploadInputV2
id="material"
onUploadComplete={handleMaterialUploadComplete}
value={getMediaInputValue()}
value={getMediaInputValue(entity, "materials")}
mediaType={mediaType}
onRemove={handleRemoveMaterial}
postUrl={`${window.FILE_UPLOAD_API_BASE_URL}/api/v1/files/upload`}
Expand Down
17 changes: 7 additions & 10 deletions src/components/forms/inventory-item-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ import TextEditorV3 from "openstack-uicore-foundation/lib/components/inputs/edit
import Swal from "sweetalert2";
import FormRepeater from "../form-repeater";
import InventoryItemMetaFieldForm from "./inventory-item-meta-field-form";
import { scrollToError, shallowEqual, hasErrors } from "../../utils/methods";
import {
scrollToError,
shallowEqual,
hasErrors,
getMediaInputValue
} from "../../utils/methods";
import {
MAX_INVENTORY_IMAGE_UPLOAD_SIZE,
MAX_INVENTORY_IMAGES_UPLOAD_QTY,
Expand Down Expand Up @@ -100,14 +105,6 @@ const InventoryItemForm = ({
}
};

const getMediaInputValue = () =>
entity.images.length > 0
? entity.images.map((img) => ({
...img,
filename: img.filename ?? img.file_path ?? img.file_url
}))
: [];

const handleSubmit = (ev) => {
ev.preventDefault();
entity.meta_fields = getNormalizedMetaFields();
Expand Down Expand Up @@ -323,7 +320,7 @@ const InventoryItemForm = ({
<UploadInputV2
id="image"
onUploadComplete={handleImageUploadComplete}
value={getMediaInputValue()}
value={getMediaInputValue(entity)}
mediaType={mediaType}
onRemove={handleRemoveImage}
postUrl={`${window.FILE_UPLOAD_API_BASE_URL}/api/v1/files/upload`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
} from "../../../utils/yup";
import AdditionalInputList from "../../../components/mui/formik-inputs/additional-input/additional-input-list";
import MuiFormikQuantityField from "../../../components/mui/formik-inputs/mui-formik-quantity-field";
import { getMediaInputValue } from "../../../utils/methods";

const SponsorItemDialog = ({
open,
Expand Down Expand Up @@ -101,17 +102,6 @@ const SponsorItemDialog = ({
}
};

const getMediaInputValue = () =>
initialEntity.images?.length > 0
? initialEntity.images.map((img) => {
const filename = img.filename ?? img.file_path ?? img.file_url;
return {
...img,
filename: filename.concat("?t=", Date?.now())
};
})
: [];

const handleClose = () => {
formik.resetForm();
onClose();
Expand Down Expand Up @@ -283,7 +273,7 @@ const SponsorItemDialog = ({
id="image-upload"
name="image"
onUploadComplete={handleImageUploadComplete}
value={getMediaInputValue()}
value={getMediaInputValue(initialEntity)}
mediaType={mediaType}
onRemove={handleRemoveImage}
postUrl={`${window.FILE_UPLOAD_API_BASE_URL}/api/v1/files/upload`}
Expand Down
6 changes: 5 additions & 1 deletion src/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,13 @@ export const EVENT_TYPE_FISHBOWL = "Fishbowl";

export const EVENT_TYPE_GROUP_EVENTS = "Groups Events";

export const FILENAME_TRUNCATE_SIDE_PERCENT = 0.4;

export const TRIM_TEXT_LENGTH_20 = 20;

export const TRIM_TEXT_LENGTH_50 = 50;

export const TRIM_TEXT_LENGTH_40 = 50;
export const TRIM_TEXT_LENGTH_40 = 40;

export const LANGUAGE_CODE_LENGTH = 2;

Expand Down
42 changes: 41 additions & 1 deletion src/utils/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import {
ERROR_CODE_403,
ERROR_CODE_412,
ERROR_CODE_500,
FILENAME_TRUNCATE_SIDE_PERCENT,
HEX_RADIX,
INT_BASE,
MARKETING_SETTING_TYPE_HEX_COLOR,
MILLISECONDS_TO_SECONDS,
ONE_MINUTE,
OR_FILTER
OR_FILTER,
TRIM_TEXT_LENGTH_20
} from "./constants";

const DAY_IN_SECONDS = 86400; // 86400 seconds per day
Expand Down Expand Up @@ -530,3 +532,41 @@ export const formatBadgeQR = (code, summit) => {

return null;
};

export const getMediaInputValue = (
entity,
fieldName = "images",
maxLength = TRIM_TEXT_LENGTH_20
) => {
const mediaFiles = entity?.[fieldName];

if (!mediaFiles?.length) return [];

return mediaFiles.map((img) => {
const fileUrl = img.filename ?? img.file_path ?? img.file_url;

let filename = fileUrl.includes("/") ? fileUrl.split("/").pop() : fileUrl;

const parts = filename.split(".");
const ext = parts.pop();
let nameWithoutExtension = parts.join(".");

if (nameWithoutExtension.length > maxLength) {
const startChars = Math.floor(maxLength * FILENAME_TRUNCATE_SIDE_PERCENT);
const endChars = Math.floor(maxLength * FILENAME_TRUNCATE_SIDE_PERCENT);
const start = nameWithoutExtension.substring(0, startChars);
const end = nameWithoutExtension.substring(
nameWithoutExtension.length - endChars
);
nameWithoutExtension = `${start}...${end}`;
}

filename = `${nameWithoutExtension}.${ext}`;

return {
...img,
public_url: img?.public_url || fileUrl,
filename: filename.concat("?t=", Date.now())
};
});
Comment on lines +536 to +571
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard against missing file URLs and extension-less names.

Line 546 can yield fileUrl as undefined, which will throw on includes, split, and concat. Also, filenames without a dot become .name because the basename is treated as the extension.

🔧 Suggested fix
   return mediaFiles.map((img) => {
     const fileUrl = img.filename ?? img.file_path ?? img.file_url;
+    if (!fileUrl) {
+      return { ...img };
+    }
 
     let filename = fileUrl.includes("/") ? fileUrl.split("/").pop() : fileUrl;
 
-    const parts = filename.split(".");
-    const ext = parts.pop();
-    let nameWithoutExtension = parts.join(".");
+    const lastDot = filename.lastIndexOf(".");
+    const hasExt = lastDot > 0;
+    const ext = hasExt ? filename.slice(lastDot + 1) : "";
+    let nameWithoutExtension = hasExt ? filename.slice(0, lastDot) : filename;
 
     if (nameWithoutExtension.length > maxLength) {
       const startChars = Math.floor(maxLength * FILENAME_TRUNCATE_SIDE_PERCENT);
       const endChars = Math.floor(maxLength * FILENAME_TRUNCATE_SIDE_PERCENT);
       const start = nameWithoutExtension.substring(0, startChars);
       const end = nameWithoutExtension.substring(
         nameWithoutExtension.length - endChars
       );
       nameWithoutExtension = `${start}...${end}`;
     }
 
-    filename = `${nameWithoutExtension}.${ext}`;
+    filename = ext ? `${nameWithoutExtension}.${ext}` : nameWithoutExtension;
 
     return {
       ...img,
       public_url: img?.public_url || fileUrl,
       filename: filename.concat("?t=", Date.now())
     };
   });
🤖 Prompt for AI Agents
In `@src/utils/methods.js` around lines 536 - 571, In getMediaInputValue, guard
against undefined fileUrl and names without extensions: first derive fileUrl
safely (fallback to empty string or use
img.filename||img.file_path||img.file_url || ""), check existence before calling
includes/split, and compute basename robustly (use lastSegment =
fileUrl.includes("/") ? ... only if fileUrl; otherwise use an empty string or
img.name). When splitting the filename, detect if there is no dot and treat the
whole name as nameWithoutExtension with ext as an empty string (or a default
like "bin") so filename construction doesn't produce ".name"; ensure final
filename assembly handles empty ext (e.g., omit ".") and that the timestamp
concat is applied to a string (use String(filename) + "?t=" + Date.now()).
Update references inside getMediaInputValue (variables fileUrl, filename, parts,
ext, nameWithoutExtension) accordingly.

};