Skip to content

Commit 8ce85f1

Browse files
committed
feat: Download configurator for current feature model
1 parent 1639583 commit 8ce85f1

File tree

5 files changed

+133
-9
lines changed

5 files changed

+133
-9
lines changed

package-lock.json

Lines changed: 79 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"@monaco-editor/react": "^4.6.0",
1414
"dom-to-svg": "^0.12.2",
1515
"file-saver": "^2.0.5",
16+
"jszip": "^3.10.1",
1617
"react": "^18.3.1",
1718
"react-d3-tree": "^3.6.2",
1819
"react-dom": "^18.3.1",

public/assets/flamapy.conf.zip

7.58 MB
Binary file not shown.

src/components/FeatureTree.jsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,21 @@ const TreeNode = ({ node, statusMap, setStatusMap }) => {
9595
// TreeView component
9696
const TreeView = ({ treeData, executeAction }) => {
9797
const SATOperations = [
98-
{ label: "Valid Configuration", value: "PySATSatisfiableConfiguration" , isOperationWithConf: true},
99-
{ label: "Interactive Configuration", value: "configurator", isOperationWithConf: false},
100-
98+
{
99+
label: "Valid Configuration",
100+
value: "PySATSatisfiableConfiguration",
101+
isOperationWithConf: true,
102+
},
103+
{
104+
label: "Interactive Configuration",
105+
value: "configurator",
106+
isOperationWithConf: false,
107+
},
108+
{
109+
label: "Download Configurator",
110+
value: "downloadConfigurator",
111+
isOperationWithConf: false,
112+
},
101113
];
102114

103115
const [statusMap, setStatusMap] = useState({});

src/pages/editor/EditorPage.jsx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { saveAs } from "file-saver";
1010
import TreeView from "../../components/FeatureTree";
1111
import FeatureModelVisualization from "../../components/FeatureModelVisualization";
1212
import Wizzard from "../../components/Wizzard";
13+
import JSZip from "jszip";
1314

1415
function EditorPage({ selectedFile }) {
1516
const [worker, setWorker] = useState(null);
@@ -265,9 +266,44 @@ function EditorPage({ selectedFile }) {
265266
}
266267
setIsRunning(false);
267268
};
268-
269269
} else {
270-
toggleView(action)
270+
if (action.value === "configurator") {
271+
toggleView(action);
272+
} else if (action.value === "downloadConfigurator") {
273+
const zip = new JSZip();
274+
275+
try {
276+
// Fetch base ZIP
277+
const response = await fetch("/assets/flamapy.conf.zip");
278+
if (!response.ok) throw new Error("Failed to load base.zip");
279+
280+
const baseZipBlob = await response.blob();
281+
const baseZipArrayBuffer = await baseZipBlob.arrayBuffer();
282+
283+
// Load the ZIP content
284+
const baseZip = await JSZip.loadAsync(baseZipArrayBuffer);
285+
286+
// Copy contents from base ZIP into our new ZIP
287+
baseZip.forEach((relativePath, file) => {
288+
zip.file(relativePath, file.async("arraybuffer"));
289+
});
290+
291+
// Add the feature model file
292+
const featureModel = new File(
293+
[editorRef.current.getValue()],
294+
"FeatureModel.uvl",
295+
{ type: "text/plain" }
296+
);
297+
zip.file(`models/${featureModel.name}`, featureModel);
298+
299+
// Generate and trigger download
300+
const newZipBlob = await zip.generateAsync({ type: "blob" });
301+
saveAs(newZipBlob, "configurator.zip");
302+
} catch (err) {
303+
console.error("Error processing ZIP:", err);
304+
alert("Failed to generate ZIP.");
305+
}
306+
}
271307
}
272308
} else {
273309
setOutput({

0 commit comments

Comments
 (0)