Skip to content

Commit

Permalink
export/import variables enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
ktrinh authored and anmavrid committed Aug 28, 2023
1 parent 05a0755 commit 3beb329
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 111 deletions.
74 changes: 53 additions & 21 deletions fret-electron/app/components/ExportRequirementsDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,17 @@ const styles = theme => ({
menu: {
width: 200,
},
dataTypeMenu: {
width: 250,
},
});

class ExportRequirementsDialog extends React.Component {
state = {
open: false,
projects:[]
projects:[],
project: 'All Projects',
dataType: 'requirements',
};

export_to_md = (R, P) => {
Expand All @@ -78,13 +83,13 @@ class ExportRequirementsDialog extends React.Component {
// ({reqid, parent_reqid, project, rationale, comments, fulltext, semantics, input}))(r.doc)

R.forEach((r) => {
s=s + "| " + r.reqid +
" | " + r.parent_reqid +
s=s + "| " + r.reqid +
" | " + r.parent_reqid +
" | " + r.fulltext.replace(/\|/g,",").replace(/\n/g," ").replace(/\r/g,"") +
" | " + r.rationale.replace(/\|/g,",").replace(/\n/g," ").replace(/\r/g,"");
s=s + "\n";
})

return s;
}
// REPLACE/Quote UTF-8 chars by \u BLA
Expand All @@ -109,29 +114,30 @@ class ExportRequirementsDialog extends React.Component {

// context isolation
var argList = [project, output_format ]
ipcRenderer.invoke('exportRequirements',argList).then((result) => {
// export requirements doesn't change any Redux state
// console.log('Exported requirements in project ',project)
}).catch((err) => {
const channel = this.state.dataType === 'requirements' ? 'exportRequirements' : this.state.dataType === 'variables' ? 'exportVariables' : 'exportRequirementsAndVariables'
ipcRenderer.invoke(channel, argList).catch((err) => {
console.log(err);
})

this.setState({ projectName: '' });

}

componentWillReceiveProps = (props) => {
this.setState({
open: props.open,
projects: props.fretProjects,
dialogCloseListener : props.handleDialogClose,
project: '',
output_format: 'json'
project: 'All Projects',
output_format: 'json',
dataType: 'requirements',
})
}

handleChange = name => event => {
this.setState({ [name]: event.target.value });
const { value } = event.target
if(name === 'dataType' && value && value.includes('variables')) {
this.setState({ output_format: 'json'});
}
this.setState({ [name]: value});
};

render() {
Expand All @@ -142,6 +148,7 @@ class ExportRequirementsDialog extends React.Component {
<Dialog
open={this.state.open}
onClose={this.handleClose}
maxWidth="md"
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
Expand All @@ -151,7 +158,7 @@ class ExportRequirementsDialog extends React.Component {
Select specific project or export all requirements by selecting All Projects.
</DialogContentText>
<TextField
id="standard-select-project"
id="qa_export_select_project"
select
label="Select"
className={classes.textField}
Expand All @@ -165,17 +172,42 @@ class ExportRequirementsDialog extends React.Component {
helperText="Please select a project"
margin="normal"
>
<MenuItem key={"All Projects"} value={"All Projects"}>
<MenuItem key={"All Projects"} value={"All Projects"} id="qa_export_mi_AllProjects">
{<b>All Projects</b>}
</MenuItem>
{this.state.projects.map(name => (
<MenuItem key={name} value={name}>
<MenuItem key={name} value={name} id={"qa_export_mi_"+name}>
{name}
</MenuItem>
))}
</TextField>
<TextField
id="standard-select-format"
id="qa_export_select_dataType"
select
label="Select data type"
className={classes.textField}
value={this.state.dataType}
onChange={this.handleChange('dataType')}
SelectProps={{
MenuProps: {
className: classes.dataTypeMenu,
},
}}
// helperText="Please select a project"
margin="normal"
>
<MenuItem key={"requirements"} value={"requirements"} id="qa_export_mi_requirements">
Requirements
</MenuItem>
<MenuItem key={"variables"} value={"variables"} id="qa_export_mi_variables">
Variables
</MenuItem>
<MenuItem key={"requirements-variables"} value={"requirements-variables"} id="qa_export_mi_reqsAndVars">
Requirements & Variables
</MenuItem>
</TextField>
<TextField
id="qa_export_select_dataFormat"
select
label="Select output format"
className={classes.textField}
Expand All @@ -189,19 +221,19 @@ class ExportRequirementsDialog extends React.Component {
// helperText="Please select a project"
margin="normal"
>
<MenuItem key={"JSON"} value={"json"}>
<MenuItem key={"JSON"} value={"json"} id="qa_export_mi_json">
JSON
</MenuItem>
<MenuItem key={"MD"} value={"md"}>
<MenuItem key={"MD"} value={"md"} disabled={this.state.dataType && this.state.dataType.includes('variables')} id="qa_export_mi_md">
Markdown (MD)
</MenuItem>
</TextField>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
<Button onClick={this.handleClose} color="primary" id="qa_export_btn_cancel">
Cancel
</Button>
<Button onClick={this.handleCloseOKtoExport} color="primary" autoFocus>
<Button onClick={this.handleCloseOKtoExport} color="primary" id="qa_export_btn_ok" autoFocus>
OK
</Button>
</DialogActions>
Expand Down
11 changes: 7 additions & 4 deletions fret-electron/app/components/Glossary.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Glossary extends React.Component {

componentDidMount = () => {
this.getProjectRequirements();
this.getVariables();
if (process.env.EXTERNAL_TOOL == '1') {
this.setVariablesToComponents();
}
Expand All @@ -117,6 +118,7 @@ class Glossary extends React.Component {
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.projectName !== this.props.projectName) {
this.getProjectRequirements();
this.getVariables();
this.setState({selectedComponent: ''})
}
if(prevState.selectedComponent !== this.state.selectedComponent || prevState.checked !== this.state.checked){
Expand All @@ -128,9 +130,6 @@ class Glossary extends React.Component {
if(this.props.projectRequirements !== prevProps.projectRequirements) {
this.setComponentsNames();
}
if(this.state.components !== prevState.components) {
this.getVariables();
}
if(this.props.variables !== prevProps.variables || process.env.EXTERNAL_TOOL == '1' && this.props.editVariables !== prevProps.editVariables) {
this.setVariablesToComponents();
}
Expand All @@ -151,7 +150,8 @@ class Glossary extends React.Component {

getVariables = async () => {
if (process.env.EXTERNAL_TOOL !== '1') {
ipcRenderer.invoke('selectGlossaryVariables', [this.props.projectName, Object.keys(this.state.components)]).then((result) => {
ipcRenderer.invoke('selectGlossaryVariables', [this.props.projectName]).then((result) => {
console.log('result', result.docs)
this.props.setGlossaryVariables({
glossaryVariables: result.docs
})
Expand Down Expand Up @@ -218,6 +218,9 @@ class Glossary extends React.Component {
})
variable['reqs'] = variableRequirements.sort().join(', ');
}
if(!componentsWithVariables[v.component_name]) {
componentsWithVariables[v.component_name] = [];
}
componentsWithVariables[v.component_name].push(variable);
})
this.setState({ componentsWithVariables })
Expand Down
33 changes: 33 additions & 0 deletions fret-electron/app/components/ImportedVariablesWarningDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import {Button, Dialog, DialogActions, DialogContent, DialogContentText} from "@material-ui/core";
import PropTypes from "prop-types";

class ImportedVariablesWarningDialog extends React.Component {

render() {
const {open, handleClose} = this.props;
return (<Dialog
id="qa_warning_dialog"
open={open}
onClose={handleClose}
>
<DialogContent>
<DialogContentText id="qa_warning_dialog_description">
Certain variables were not imported because of missing information about project and component.
Please see FRET manual for more information.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button id="qa_close_warning_dialog" onClick={handleClose}>Close</Button>
</DialogActions>
</Dialog>)
}

}

ImportedVariablesWarningDialog.propTypes = {
open: PropTypes.bool.isRequired,
handleClose: PropTypes.func.isRequired,
}

export default ImportedVariablesWarningDialog;
13 changes: 12 additions & 1 deletion fret-electron/app/components/MainView.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
importRequirements,
mapVariables,
} from '../reducers/allActionsSlice';
import ImportedVariablesWarningDialog from "./ImportedVariablesWarningDialog";

const app = require('electron').remote.app
const dialog = require('electron').remote.dialog
Expand Down Expand Up @@ -224,6 +225,7 @@ class MainView extends React.Component {
externalVariables: {},
missingExternalImportDialogOpen: false,
missingExternalImportDialogReason: 'unknown',
warningDialogOpen: false,
};

constructor(props) {
Expand Down Expand Up @@ -300,6 +302,7 @@ class MainView extends React.Component {

})
}
this.setState({warningDialogOpen: result.areThereIgnoredVariables})
if (result.fileExtension){
this.handleCSVImport(result.csvFields, result.importedReqs)
}
Expand Down Expand Up @@ -388,6 +391,13 @@ class MainView extends React.Component {
});
}

handleWarningDialogClose = () => {
this.setState(
{
warningDialogOpen: false,
});
}

// Handling project management END

handleDrawerOpen = () => {
Expand Down Expand Up @@ -589,7 +599,7 @@ class MainView extends React.Component {

render() {
const { classes, theme, listOfProjects, requirements } = this.props;
const { anchorEl } = this.state;
const { anchorEl, warningDialogOpen } = this.state;

return (
<div className={classes.root}>
Expand Down Expand Up @@ -778,6 +788,7 @@ class MainView extends React.Component {
selection='BROWSE'
reason={this.state.missingExternalImportDialogReason}
/>
<ImportedVariablesWarningDialog open={warningDialogOpen} handleClose={this.handleWarningDialogClose}/>
</div>
<Snackbar
anchorOrigin={{
Expand Down
10 changes: 10 additions & 0 deletions fret-electron/app/main.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,16 @@ ipcMain.handle('exportRequirements', async (evt, arg) => {
return result
})

ipcMain.handle('exportVariables', async (evt, arg) => {
const result = await fretModel.exportVariables(evt, arg);
return result
})

ipcMain.handle('exportRequirementsAndVariables', async (evt, arg) => {
const result = await fretModel.exportRequirementsAndVariables(evt, arg);
return result
})

ipcMain.handle('selectVariable', async(evt, arg) => {
const result = await fretModel.selectVariable(evt, arg);
return result
Expand Down
27 changes: 14 additions & 13 deletions fret-electron/app/reducers/allActionsSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,9 @@ const allActionsSlice = createSlice({
// * requirements *
requirements: [], // requirements from all proljects
projectRequirements: [], // requirements for selectedProject
glossaryProjectRequirements: [],

// * analysis *
components: [], // for a specific project: this is an array of all the components
completedComponents: [], // for a specific project: this is an array of all components
// that we have completed the variable mappings
cocospecData: {}, // for a specific project: this is an object where each
// key is a component of this project, and the value of each key is an array of variables
cocospecModes: {}, // for a specific project: this is an object where each
// key is a component of this project, and the value of each key is an array of modes

// variables
// * variables *
variable_data: {}, // for a specific project: this is an object where each
// key is a component of this project, and the value is
// an array[rowid: counter, variable_name, modeldoc_id, idType, dataType, description]
Expand All @@ -32,15 +24,24 @@ const allActionsSlice = createSlice({
importedComponents: [], // array of imported simulink model components
glossaryVariables: [], // variables for Glossary component

// * analysis *
components: [], // for a specific project: this is an array of all the components
completedComponents: [], // for a specific project: this is an array of all components
// that we have completed the variable mappings
cocospecData: {}, // for a specific project: this is an object where each
// key is a component of this project, and the value of each key is an array of variables
cocospecModes: {}, // for a specific project: this is an object where each
// key is a component of this project, and the value of each key is an array of modes

// realizability
rlz_data: [], // array of requirements given a specific project and system component
monolithic: undefined,
compositional: undefined,
ccSelected: undefined,
projectReport: undefined,
diagnosisRequirements: undefined,
prevState: undefined,
glossaryProjectRequirements: []
//prevState: undefined,


},

Expand Down Expand Up @@ -72,7 +73,7 @@ const allActionsSlice = createSlice({
state.compositional = action.payload.compositional;
state.ccSelected = action.payload.ccSelected;
state.diagnosisRequirements = action.payload.diagnosisRequirements;
state.prevState = action.payload.prevState;
//state.prevState = action.payload.prevState;
},

// project slice
Expand Down
Loading

0 comments on commit 3beb329

Please sign in to comment.