fix(cli): better support for external modules and toolGroups in templates (#3364)
* choe(modes, components): improved readability This commit includes changes to improve performance in the basic-dev-mode and Thumbnail components. Additionally, a change in the webpack configuration file was made to ignore ".min.js.map" files. The defaultDataSourceName was also added to several configuration files, and whiteLabeling code was removed from the local_orthanc configuration file. * fix(cli): better path management and add dependencies * better docs * add default tool group to the templates * add review comments * apply review comments * try to fix test * fix thumbnail in tests
This commit is contained in:
1 parent
187e6b5f30
commit
2f355fa158
26 files changed
+193
-142
No files matched your search
@@ -41,9 +41,37 @@ async function linkPackage(packageDir, options, addToConfig, keyword) {
|
||||
results = await execa(`yarn`, ['link', packageName]);
|
||||
console.log(results.stdout);
|
||||
|
||||
// Add the node_modules of the linked package so that webpack
|
||||
// can find the linked package externals if there are
|
||||
const webpackPwaPath = path.join(
|
||||
viewerDirectory,
|
||||
'.webpack',
|
||||
'webpack.pwa.js'
|
||||
);
|
||||
|
||||
async function updateWebpackConfig(webpackConfigPath, packageDir) {
|
||||
const packageNodeModules = path.join(packageDir, 'node_modules');
|
||||
const fileContent = await fs.promises.readFile(webpackConfigPath, 'utf8');
|
||||
|
||||
const newLine = `path.resolve(__dirname, '${packageNodeModules}'),`;
|
||||
const modifiedFileContent = fileContent.replace(
|
||||
/(modules:\s*\[)([\s\S]*?)(\])/,
|
||||
`$1$2 ${newLine}$3`
|
||||
);
|
||||
|
||||
await fs.promises.writeFile(webpackConfigPath, modifiedFileContent);
|
||||
}
|
||||
|
||||
await updateWebpackConfig(webpackPwaPath, packageDir);
|
||||
|
||||
// change directory to viewer packages and add the config item
|
||||
process.chdir(viewerDirectory);
|
||||
addToConfig(packageName, { version });
|
||||
addToConfig(packageName, {
|
||||
version,
|
||||
});
|
||||
|
||||
// run prettier on the webpack config
|
||||
results = await execa(`yarn`, ['prettier', '--write', webpackPwaPath]);
|
||||
}
|
||||
|
||||
function linkExtension(packageDir, options) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { execa } from 'execa';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {
|
||||
validateYarn,
|
||||
removeExtensionFromConfig,
|
||||
@@ -17,10 +19,51 @@ const linkPackage = async (packageName, options, removeFromConfig) => {
|
||||
const results = await execa(`yarn`, ['unlink', packageName]);
|
||||
console.log(results.stdout);
|
||||
|
||||
const webpackPwaPath = path.join(
|
||||
viewerDirectory,
|
||||
'.webpack',
|
||||
'webpack.pwa.js'
|
||||
);
|
||||
|
||||
await removePathFromWebpackConfig(webpackPwaPath, packageName);
|
||||
|
||||
//update the plugin.json file
|
||||
removeFromConfig(packageName);
|
||||
|
||||
// run prettier on the webpack config
|
||||
await execa(`yarn`, ['prettier', '--write', webpackPwaPath]);
|
||||
};
|
||||
|
||||
async function removePathFromWebpackConfig(webpackConfigPath, packageName) {
|
||||
const fileContent = await fs.promises.readFile(webpackConfigPath, 'utf8');
|
||||
|
||||
const packageNameSubstring = `${packageName}/node_modules`;
|
||||
const pathResolveStart = 'path.resolve(';
|
||||
const closingParenthesis = ')';
|
||||
|
||||
let startIndex = fileContent.indexOf(packageNameSubstring);
|
||||
|
||||
if (startIndex === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the start of the "path.resolve" line.
|
||||
startIndex = fileContent.lastIndexOf(pathResolveStart, startIndex);
|
||||
|
||||
// Find the end of the line with the closing parenthesis.
|
||||
let endIndex = fileContent.indexOf(closingParenthesis, startIndex) + 1;
|
||||
|
||||
// Check if there's a comma after the closing parenthesis and remove it as well.
|
||||
if (fileContent[endIndex] === ',') {
|
||||
endIndex++;
|
||||
}
|
||||
|
||||
const modifiedFileContent =
|
||||
fileContent.slice(0, startIndex) + fileContent.slice(endIndex);
|
||||
|
||||
await fs.promises.writeFile(webpackConfigPath, modifiedFileContent);
|
||||
}
|
||||
|
||||
function unlinkExtension(extensionName, options) {
|
||||
linkPackage(extensionName, options, removeExtensionFromConfig);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ export default function writePluginConfigFile(pluginConfig) {
|
||||
|
||||
fs.writeFileSync(
|
||||
`./pluginConfig.json`,
|
||||
jsonStringOfFileContents,
|
||||
jsonStringOfFileContents + '\n', // Add a newline character at the end
|
||||
{ flag: 'w+' },
|
||||
(err) => {
|
||||
err => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import path from 'path';
|
||||
import os from 'os';
|
||||
|
||||
function getPathQuestions(packageType) {
|
||||
return [
|
||||
@@ -6,7 +7,7 @@ function getPathQuestions(packageType) {
|
||||
type: 'input',
|
||||
name: 'name',
|
||||
message: `What is the name of your ${packageType}?`,
|
||||
validate: (input) => {
|
||||
validate: input => {
|
||||
if (!input) {
|
||||
return 'Please enter a name';
|
||||
}
|
||||
@@ -17,8 +18,8 @@ function getPathQuestions(packageType) {
|
||||
{
|
||||
type: 'input',
|
||||
name: 'baseDir',
|
||||
message: `What is the target absolute path to create your ${packageType} (we recommend you do not use the OHIF ${packageType} folder (./${packageType}s) unless you are developing a core ${packageType}):`,
|
||||
validate: (input) => {
|
||||
message: `What is the target path to create your ${packageType} (we recommend you do not use the OHIF ${packageType} folder (./${packageType}s) unless you are developing a core ${packageType}):`,
|
||||
validate: input => {
|
||||
if (!input) {
|
||||
console.log('Please provide a valid target directory path');
|
||||
return;
|
||||
@@ -26,7 +27,13 @@ function getPathQuestions(packageType) {
|
||||
return true;
|
||||
},
|
||||
filter: (input, answers) => {
|
||||
return path.resolve(input, answers.name);
|
||||
// Replace ~ with the user's home directory
|
||||
const expandedPath = input.replace(/^~(?=$|\/|\\)/, os.homedir());
|
||||
|
||||
// Resolve the path to an absolute path
|
||||
const resolvedPath = path.resolve(expandedPath, answers.name);
|
||||
|
||||
return resolvedPath;
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -43,6 +50,7 @@ function getRepoQuestions(packageType) {
|
||||
type: 'confirm',
|
||||
name: 'gitRepository',
|
||||
message: 'Should it be a git repository?',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { hotkeys } from '@ohif/core';
|
||||
import { id } from './id';
|
||||
import { initToolGroups, toolbarButtons } from '@ohif/mode-longitudinal';
|
||||
|
||||
const ohif = {
|
||||
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
|
||||
@@ -38,12 +40,76 @@ function modeFactory({ modeConfiguration }) {
|
||||
* Runs when the Mode Route is mounted to the DOM. Usually used to initialize
|
||||
* Services and other resources.
|
||||
*/
|
||||
onModeEnter: ({ servicesManager, extensionManager }) => {},
|
||||
/**
|
||||
* Runs when the Mode Route is unmounted from the DOM. Usually used to clean
|
||||
* up resources and states
|
||||
*/
|
||||
onModeExit: () => {},
|
||||
onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
|
||||
const {
|
||||
measurementService,
|
||||
toolbarService,
|
||||
toolGroupService,
|
||||
} = servicesManager.services;
|
||||
|
||||
measurementService.clearMeasurements();
|
||||
|
||||
// Init Default and SR ToolGroups
|
||||
initToolGroups(extensionManager, toolGroupService, commandsManager);
|
||||
|
||||
let unsubscribe;
|
||||
|
||||
const activateTool = () => {
|
||||
toolbarService.recordInteraction({
|
||||
groupId: 'WindowLevel',
|
||||
itemId: 'WindowLevel',
|
||||
interactionType: 'tool',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setToolActive',
|
||||
commandOptions: {
|
||||
toolName: 'WindowLevel',
|
||||
},
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// We don't need to reset the active tool whenever a viewport is getting
|
||||
// added to the toolGroup.
|
||||
unsubscribe();
|
||||
};
|
||||
|
||||
// Since we only have one viewport for the basic cs3d mode and it has
|
||||
// only one hanging protocol, we can just use the first viewport
|
||||
({ unsubscribe } = toolGroupService.subscribe(
|
||||
toolGroupService.EVENTS.VIEWPORT_ADDED,
|
||||
activateTool
|
||||
));
|
||||
|
||||
toolbarService.init(extensionManager);
|
||||
toolbarService.addButtons(toolbarButtons);
|
||||
toolbarService.createButtonSection('primary', [
|
||||
'MeasurementTools',
|
||||
'Zoom',
|
||||
'WindowLevel',
|
||||
'Pan',
|
||||
'Capture',
|
||||
'Layout',
|
||||
'MPR',
|
||||
'Crosshairs',
|
||||
'MoreTools',
|
||||
]);
|
||||
},
|
||||
onModeExit: ({ servicesManager }) => {
|
||||
const {
|
||||
toolGroupService,
|
||||
syncGroupService,
|
||||
toolbarService,
|
||||
segmentationService,
|
||||
cornerstoneViewportService,
|
||||
} = servicesManager.services;
|
||||
|
||||
toolGroupService.destroy();
|
||||
syncGroupService.destroy();
|
||||
segmentationService.destroy();
|
||||
cornerstoneViewportService.destroy();
|
||||
},
|
||||
/** */
|
||||
validationTags: {
|
||||
study: [],
|
||||
@@ -93,7 +159,7 @@ function modeFactory({ modeConfiguration }) {
|
||||
/** SopClassHandlers used by the mode */
|
||||
sopClassHandlers: [ohif.sopClassHandler],
|
||||
/** hotkeys for mode */
|
||||
hotkeys: [''],
|
||||
hotkeys: [...hotkeys.defaults.hotkeyBindings],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user