Skip to content

Commit 0064499

Browse files
authored
Download code view content (#188)
* Allow saving install script from WLS Operator page * Allow saving scripts and resource files for VZ install, component, and application pages * Allow saving scripts and resource files for operator domain, image, and ingress pages
1 parent f7de948 commit 0064499

19 files changed

+285
-9
lines changed

electron/app/js/ipcRendererPreload.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ contextBridge.exposeInMainWorld(
3131
send: (channel, ...args) => {
3232
const validChannels = [
3333
'close-window',
34+
'download-file',
3435
'new-project',
3536
'open-project',
3637
'window-app-quit',

electron/app/js/project.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {getCredentialPassphrase} = require('./promptUtils');
88
const {copyFile, mkdir, readFile, writeFile} = require('fs/promises');
99
const path = require('path');
1010
const uuid = require('uuid');
11+
const { EOL } = require('os');
1112

1213
const model = require('./model');
1314
const modelProperties = require('./modelProperties');
@@ -972,6 +973,32 @@ function getProjectFileName(dialogReturnedFileName) {
972973
return result;
973974
}
974975

976+
function downloadFile(targetWindow, lines, fileType, format, formatName) {
977+
const title = i18n.t('dialog-saveTitle', {type: fileType});
978+
const filterName = i18n.t('dialog-saveFilterLabel', {type: formatName});
979+
980+
dialog.showSaveDialog(targetWindow, {
981+
title: title,
982+
message: title,
983+
filters: [
984+
{name: filterName, extensions: [format]}
985+
],
986+
properties: [
987+
'createDirectory',
988+
'showOverwriteConfirmation'
989+
]
990+
}).then(saveResponse => {
991+
if (saveResponse.filePath) {
992+
const contents = lines.join(EOL);
993+
writeFile(saveResponse.filePath, contents, { encoding: 'utf8' })
994+
.catch(err => {
995+
dialog.showErrorBox(title,
996+
i18n.t('dialog-saveFileErrorMessage', { file: saveResponse.filePath, error: err }));
997+
});
998+
}
999+
});
1000+
}
1001+
9751002
module.exports = {
9761003
chooseArchiveFile,
9771004
chooseModelFile,
@@ -980,6 +1007,7 @@ module.exports = {
9801007
closeProject,
9811008
confirmProjectFile,
9821009
createNewProject,
1010+
downloadFile,
9831011
getModelFileContent,
9841012
getWindowForProject,
9851013
exportArchiveFile,

electron/app/locales/en/electron.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@
159159
"dialog-createNewProjectTitle": "Create WebLogic Kubernetes Toolkit Project",
160160
"dialog-projectSaveFileLocationNotWritableTitle": "Project Directory Not Writable",
161161
"dialog-projectSaveFileLocationNotWritableError": "The {{projectFileDirectory}} directory chosen to write the new project file is not writable by the current process.",
162+
"dialog-saveTitle": "Save {{type}}",
163+
"dialog-saveFilterLabel": "{{type}} Files",
164+
"dialog-saveFileErrorMessage": "Unable to save {{file}}: {{error}}",
162165

163166
"dialog-openProjectWindowPrompt": "Choose the window where the project should be opened.",
164167
"dialog-chooseDomainHome": "Select the Domain Home directory to use",

electron/app/locales/en/webui.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
"script-sh-label": "sh Script",
3434
"script-ps1-label": "Powershell Script",
3535
"script-cmd-label": "Windows CMD Script",
36+
"script-button-download": "Download",
37+
"script-file-type-label": "{{type}} {{subType}}",
38+
"script-resource-file-format": "Resource",
3639

3740
"kubectl-form-name": "Kubernetes Client Configuration",
3841
"kubectl-title": "Configure the Kubernetes Client",
@@ -229,6 +232,7 @@
229232
"image-code-primary-image-script-no-content": "Create New Primary Image is turned off so no content to show.",
230233
"image-code-auxiliary-image-script-no-content": "Create New Auxiliary Image is turned off so no content to show.",
231234
"image-code-not-creating-images-no-content": "This project is not configured to create any images so no content to show.",
235+
"image-code-script-title": "{{type}} Script",
232236

233237
"image-design-form-name": "Image",
234238
"image-design-form-primary-tab-name": "Primary Image",

electron/app/main.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ class Main {
287287
await currentWindow.close();
288288
});
289289

290+
ipcMain.on('download-file', (event, lines, fileType, fileFormat, fileFormatName) => {
291+
const window = event.sender.getOwnerBrowserWindow();
292+
return project.downloadFile(window, lines, fileType, fileFormat, fileFormatName);
293+
});
294+
290295
// eslint-disable-next-line no-unused-vars
291296
ipcMain.on('skip-quickstart-at-startup', async (event) => {
292297
userSettings.setSkipQuickstartAtStartup(true);

webui/src/js/viewModels/domain-code-view.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,37 @@ function (accUtils, ko, project, K8sDomainScriptGenerator, K8sDomainConfigMapGen
115115
};
116116

117117
this.renderScript(this.selectedSubview());
118+
119+
this.downloadInstaller = () => {
120+
const format = this.shellScriptType();
121+
const generator = new K8sDomainScriptGenerator(format);
122+
const lines = generator.generate();
123+
const fileType = i18n.t('script-file-type-label', {
124+
type: i18n.t('nav-domain'),
125+
subType: i18n.t('domain-code-script-title')
126+
});
127+
const formatLabel = this.shellLabelMapper(format + '-label');
128+
129+
window.api.ipc.send('download-file', lines, fileType, format, formatLabel);
130+
};
131+
132+
this.downloadComponentResource = () => {
133+
const generator = this.getDomainResourceGenerator();
134+
const lines = generator.generate();
135+
const fileType = i18n.t('domain-code-domain-resource-title');
136+
const formatLabel = this.shellLabelMapper('resource-file-format');
137+
138+
window.api.ipc.send('download-file', lines, fileType, 'yaml', formatLabel);
139+
};
140+
141+
this.downloadConfigMap = () => {
142+
const generator = this.k8sConfigMapGenerator;
143+
const lines = generator.generate();
144+
const fileType = i18n.t('domain-code-configmap-resource-title');
145+
const formatLabel = this.shellLabelMapper('resource-file-format');
146+
147+
window.api.ipc.send('download-file', lines, fileType, 'yaml', formatLabel);
148+
};
118149
}
119150

120151
return DomainCodeViewModel;

webui/src/js/viewModels/image-code-view.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@ function(accUtils, ko, i18n, project, ImageScriptGenerator, ArrayDataProvider) {
116116
};
117117

118118
this.codeText = ko.observable();
119+
120+
this.downloadScript = () => {
121+
const format = this.codeViewScriptLanguage();
122+
const generator = new ImageScriptGenerator(format);
123+
const auxiliary = this.selectedSubview() === 'auxiliaryImageScript';
124+
const lines = auxiliary ? generator.generateAuxiliary() : generator.generatePrimary();
125+
const typeName = this.labelMapper(auxiliary ? 'auxiliary-image-script-tab' : 'primary-image-script-tab');
126+
const fileType = i18n.t('image-code-script-title', {type: typeName});
127+
const formatLabel = this.shellLabelMapper(format + '-label');
128+
129+
window.api.ipc.send('download-file', lines, fileType, format, formatLabel);
130+
};
119131
}
120132

121133
/*

webui/src/js/viewModels/ingress-code-view.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,38 @@ function(accUtils, ko, i18n, project, IngressInstallScriptGenerator, IngressRout
111111
const lines = generator.generate();
112112
this.ingressRoutesYamlText(lines.join('\n'));
113113
};
114+
115+
this.downloadInstaller = () => {
116+
const format = this.shellScriptType();
117+
const generator = new IngressInstallScriptGenerator(format);
118+
const lines = generator.generate();
119+
const fileType = i18n.t('script-file-type-label', {
120+
type: i18n.t('nav-ingress'),
121+
subType: i18n.t('ingress-code-install-script-title')
122+
});
123+
const formatLabel = this.shellLabelMapper(format + '-label');
124+
125+
window.api.ipc.send('download-file', lines, fileType, format, formatLabel);
126+
};
127+
128+
this.downloadAddRoutesScript = () => {
129+
const format = this.shellScriptType();
130+
const generator = new IngressRoutesScriptGenerator(format);
131+
const lines = generator.generate();
132+
const fileType = i18n.t('ingress-code-add-routes-script-title');
133+
const formatLabel = this.shellLabelMapper(format + '-label');
134+
135+
window.api.ipc.send('download-file', lines, fileType, format, formatLabel);
136+
};
137+
138+
this.downloadRoutesResource = () => {
139+
const generator = new IngressResourceGenerator();
140+
const lines = generator.generate();
141+
const fileType = i18n.t('ingress-code-ingress-yaml-title');
142+
const formatLabel = this.shellLabelMapper('resource-file-format');
143+
144+
window.api.ipc.send('download-file', lines, fileType, 'yaml', formatLabel);
145+
};
114146
}
115147

116148
/*

webui/src/js/viewModels/operator-code-view.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ function(i18n, accUtils, ko, project, OperatorScriptGenerator, ArrayDataProvider
5050
this.shellScriptType(event.detail.value);
5151
this.updateCodeText(event.detail.value);
5252
};
53+
54+
this.download = () => {
55+
const format = this.shellScriptType();
56+
const generator = new OperatorScriptGenerator(format);
57+
const lines = generator.generate();
58+
const fileType = i18n.t('script-file-type-label', {
59+
type: i18n.t('nav-operator'),
60+
subType: i18n.t('domain-code-script-title')
61+
});
62+
const formatLabel = this.shellLabelMapper(format + '-label');
63+
64+
window.api.ipc.send('download-file', lines, fileType, format, formatLabel);
65+
};
5366
}
5467

5568
/*

webui/src/js/viewModels/vz-application-code-view.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,37 @@ function (accUtils, ko, project, VerrazzanoApplicationScriptGenerator, Verrazzan
107107
};
108108

109109
this.renderScript(this.selectedSubview());
110+
111+
this.downloadDeployer = () => {
112+
const format = this.shellScriptType();
113+
const generator = new VerrazzanoApplicationScriptGenerator(format);
114+
const lines = generator.generate();
115+
const fileType = i18n.t('script-file-type-label', {
116+
type: i18n.t('nav-vz-component'),
117+
subType: i18n.t('vz-install-code-script-title')
118+
});
119+
const formatLabel = this.shellLabelMapper(format + '-label');
120+
121+
window.api.ipc.send('download-file', lines, fileType, format, formatLabel);
122+
};
123+
124+
this.downloadApplicationResource = () => {
125+
const generator = this.vzApplicationResourceGenerator;
126+
const lines = generator.generate();
127+
const fileType = i18n.t('vz-application-code-application-resource-title');
128+
const formatLabel = this.shellLabelMapper('resource-file-format');
129+
130+
window.api.ipc.send('download-file', lines, fileType, 'yaml', formatLabel);
131+
};
132+
133+
this.downloadProjectResource = () => {
134+
const generator = this.vzProjectResourceGenerator;
135+
const lines = generator.generate();
136+
const fileType = i18n.t('vz-application-code-project-resource-title');
137+
const formatLabel = this.shellLabelMapper('resource-file-format');
138+
139+
window.api.ipc.send('download-file', lines, fileType, 'yaml', formatLabel);
140+
};
110141
}
111142

112143
return VerrazzanoApplicationCodeViewModel;

0 commit comments

Comments
 (0)