Hi I want to ask about gridstack placeholder, my problem:
- why is the size of the placeholder that I load when loading the layout not the same size as the widget size??
below is the data for the layout that I saved { "x": 5, "y": 0, "width": 4, "height": 3, "resizable": true, "pixelWidth": 355, "pixelHeight": 266, "resizableWidthUnits": 4, "resizableHeightUnits": 3, "name": "Dashboard", "selectedDevice": "2", "widgetKey": "Dashboard-1739955813057", "selectedIcon": null, "iconColor": null, "bgColor": null, "selectedPins": {} }
and im load with this code :
const convertPixelToGrid = (pixelWidth, pixelHeight, cellWidth, cellHeight) => {
const gridDims = {
width: Math.round(pixelWidth / cellWidth), // Gunakan Math.round
height: Math.round(pixelHeight / cellHeight), // Gunakan Math.round
};
return gridDims;
};
const checkOverlap = (x, y, width, height, nodes, tolerance = 1) => {
for (const node of nodes) {
const isOverlapping =
x < node.x + node.width + tolerance &&
x + width > node.x - tolerance &&
y < node.y + node.height + tolerance &&
y + height > node.y - tolerance;
if (isOverlapping) {
return true;
}
}
return false;
};
const loadSavedLayout = async () => {
try {
// Clear the saved layout from localStorage if not in edit mode
if (!isEditMode.value) {
localStorage.removeItem("currentLayoutId");
// Reload the page to reflect the changes
window.location.reload();
}
let savedLayout;
// Cek apakah layout tersimpan di localStorage
const localStorageLayout = localStorage.getItem(
`layoutData_${currentLayoutId.value}`
);
if (localStorageLayout) {
savedLayout = JSON.parse(localStorageLayout);
} else {
const response = await axios.get(
`${appState.value.baseUrl}/api/Layout/${currentLayoutId.value}`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem("authToken")}`,
},
}
);
savedLayout = JSON.parse(response.data.layoutData);
}
if (savedLayout && savedLayout.length > 0) {
hasData.value = true;
const cellWidth = grid.cellWidth();
const cellHeight = grid.opts.cellHeight;
const allDevices = {};
const nodes = []; // Menyimpan semua node untuk validasi overlap
for (const item of savedLayout) {
const gridDims = convertPixelToGrid(
item.pixelWidth,
item.pixelHeight,
cellWidth,
cellHeight
);
const widget = widgets.find((w) => w.name === item.name);
if (widget) {
const widgetElement = addWidget(
{
...widget,
selectedDevice: item.selectedDevice,
widgetKey: item.widgetKey,
},
item.x,
item.y,
gridDims.width,
gridDims.height
);
if (widgetElement) {
applyPixelDimensions(widgetElement); // Terapkan ukuran pixel setelah widget ditambahkan
}
grid.update(widgetElement, {
x: item.x,
y: item.y,
width: gridDims.width,
height: gridDims.height,
});
// Set ukuran pixel untuk widget yang di-load
widgetElement.style.width = `${item.pixelWidth}px`;
widgetElement.style.height = `${item.pixelHeight}px`;
// Process Label & Value 2 with multiple devices
if (
item.name === "Label &Value 2" &&
Array.isArray(item.selectedDevice)
) {
item.selectedDevice.forEach((deviceIdentifier) => {
deviceStore.addSelectedDevice(item.widgetKey, deviceIdentifier);
allDevices[item.widgetKey] = allDevices[item.widgetKey] || [];
allDevices[item.widgetKey].push(deviceIdentifier);
});
} else if (item.widgetKey && item.selectedDevice) {
allDevices[item.widgetKey] = item.selectedDevice;
}
// Cek placeholder setelah widget ditambahkan
if (widgetElement) {
// Terapkan posisi dan ukuran grid
grid.update(widgetElement, {
x: item.x,
y: item.y,
width: gridDims.width,
height: gridDims.height,
});
}
// Save widget size in the store using item.widgetKey
deviceStore.setWidgetSize(item.widgetKey, {
width: item.width,
height: item.height,
pixelWidth: item.pixelWidth,
pixelHeight: item.pixelHeight,
resizableWidthUnits: item.resizableWidthUnits, // Tambahkan resizable width units
resizableHeightUnits: item.resizableHeightUnits, // Tambahkan resizable height units
});
// Periksa apakah ada selectedPins untuk widget yang dimuat
if (item.selectedPins) {
deviceStore.setCheckedPins(item.widgetKey, item.selectedPins);
}
// Periksa apakah ada selectedIcon dan iconColor untuk widget yang dimuat
if (item.selectedIcon) {
const iconData = {
icon: item.selectedIcon,
color: item.iconColor || "#000000", // Gunakan warna default jika tidak ada
bgColor: item.bgColor || "#000000", // Gunakan warna default jika tidak ada
};
deviceStore.setSelectedIcon(item.widgetKey, iconData);
}
// ✅ Jika widget adalah "Label & Value 2", muat ulang ikon ke store
if (item.name === "Label &Value 2" && Array.isArray(item.icons)) {
// Pastikan ikon dalam array dan masukkan ke store
deviceStore.setSelectedIcons(item.widgetKey, item.icons);
}
// ✅ Jika widget adalah "Rack Server", muat ulang rackDevices ke store
if (item.name === "Rack Server" && Array.isArray(item.rackDevices)) {
// Pastikan rackDevices adalah array dan muat ke store
deviceStore.addDevices(item.widgetKey, item.rackDevices);
}
// ✅ Jika widget adalah "Multiple Chart", muat ulang preferensi dari layout ke store
if (item.name === "Multiple Chart") {
deviceStore.setMultipleChartPreferences(item.widgetKey, {
chartType: item.chartType || "line",
chartColors: Array.isArray(item.chartColors)
? item.chartColors
: ["#4bc0c0"], // Default color jika kosong
chartAnimation:
typeof item.chartAnimation === "boolean"
? item.chartAnimation
: false,
chartData: item.chartData ? parseInt(item.chartData, 10) : 24, // Konversi ke angka jika ada
});
}
// Periksa apakah widget adalah "Analogue Gauges" dan atur warna ke store
if (item.name === "Analogue gauges") {
const gaugeColors = {
minColor: item.minColor || "#00ff00", // Default hijau
midColor: item.midColor || "#ffcc00", // Default kuning
maxColor: item.maxColor || "#ff0000", // Default merah
};
deviceStore.setGaugeColors(item.widgetKey, gaugeColors);
}
if (item.name === "Simple Chart") {
deviceStore.setSimpleChart(item.widgetKey, {
chartColor: item.chartColor || "#4bc0c0",
minValue: item.minValue,
maxValue: item.maxValue,
});
}
// Cek apakah widget adalah "Toggle", "Control", atau "Modular Monitoring" dan simpan customName
if (
(item.name === "Toggle" ||
item.name === "Control" ||
item.name === "Containment" ||
item.name === "Device ModularI2C" ||
item.name === "Subrack" ||
item.name === "Modular Monitoring") &&
item.customName
) {
deviceStore.setSubrackType(item.widgetKey, item.subrackType);
deviceStore.setCustomName(item.widgetKey, item.customName); // Simpan customName ke store
deviceStore.setTotalRackNumber(
item.widgetKey,
item.totalRackNumber
);
}
if (widgetElement) {
widgetElement.style.width = `${item.pixelWidth}px`;
widgetElement.style.height = `${item.pixelHeight}px`;
if (
item.name === "Chart Line" ||
item.name === "Chart Bar" ||
item.name === "Power Analyzer"
) {
deviceStore.setChartPreferences(item.widgetKey, {
chartType: item.chartType || "line",
chartColor: item.chartColor || "#4bc0c0",
chartAnimation:
typeof item.chartAnimation === "boolean"
? item.chartAnimation
: false,
chartData: item.chartData ? parseInt(item.chartData, 10) : 24,
});
}
} else {
console.warn("Widget element not created for", item.name);
}
} else {
console.warn("Widget not found for", item.name);
}
}
// **Penempatan kedua**: Setelah semua widget diproses
grid.engine.nodes.forEach((node) => {
// Validasi dimensi
if (node.width <= 0 || node.height <= 0) {
node.width = Math.max(1, node.width);
node.height = Math.max(1, node.height);
grid.update(node.el, { width: node.width, height: node.height });
}
});
deviceStore.setAllDevices(allDevices);
gridmit();
} else {
hasData.value = false;
}
} catch (error) {
console.error("Error loading layout:", error);
Swal.fire("Error", "Failed to load layout.", "error");
}
};
Can Someone Help me ??I spent days and still haven't succeeded