-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
4,963 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import React, { useState, useRef } from "react"; | ||
import PropTypes from "prop-types"; | ||
import { IconButton, InputAdornment, TextField } from "@material-ui/core"; | ||
import { SCOPES } from "../Utils/Constants"; | ||
import SelectScopeModal from "./Modal/SelectScopeModal"; | ||
import CodeIcon from "@material-ui/icons/Code"; | ||
|
||
function formatValue(value) { | ||
return value.split("/").pop(); | ||
} | ||
|
||
const ConfigurationSelector = (props) => { | ||
// Props | ||
const { rowProps = {} } = props; | ||
// State Hooks | ||
const [openModal, setOpenModal] = useState(false); | ||
const [selected, setSelected] = useState(rowProps.rowData?.value); | ||
// Refs | ||
const inputTextRef = useRef(); | ||
|
||
/** | ||
* On Configuration selected | ||
* @param {string} selectedConfiguration | ||
*/ | ||
const onSubmit = (selectedConfiguration) => { | ||
const formatted = formatValue(selectedConfiguration); | ||
rowProps.onChange(formatted); | ||
setSelected(formatted); | ||
setOpenModal(false); | ||
// Set cursor position | ||
globalThis.setImmediate(() => { | ||
if (!inputTextRef.current) return; | ||
const inputText = inputTextRef.current.querySelector("input"); | ||
inputText.focus(); | ||
const endPosition = inputText.value.length; | ||
inputText.setSelectionRange(endPosition, endPosition); | ||
}); | ||
}; | ||
|
||
//======================================================================================== | ||
/* * | ||
* Render * | ||
* */ | ||
//======================================================================================== | ||
|
||
return ( | ||
<TextField | ||
style={{ width: "100%" }} | ||
value={selected || ""} | ||
data-testid="selector-text-input" | ||
onChange={(evt) => { | ||
setSelected(evt.target.value); | ||
rowProps.onChange(evt.target.value); | ||
}} | ||
InputProps={{ | ||
ref: inputTextRef, | ||
endAdornment: ( | ||
<InputAdornment position="end"> | ||
<IconButton | ||
data-testid="open-selector-btn" | ||
aria-label="Select configuration" | ||
onClick={() => setOpenModal(true)} | ||
disabled={props.rowProps.disabled} | ||
onMouseDown={(evt) => evt.preventDefault()} | ||
> | ||
<CodeIcon></CodeIcon> | ||
</IconButton> | ||
<SelectScopeModal | ||
open={openModal} | ||
onCancel={() => setOpenModal(false)} | ||
onSubmit={onSubmit} | ||
scopeList={[SCOPES.CONFIGURATION]} | ||
selected={selected} | ||
allowArchive={false} | ||
></SelectScopeModal> | ||
</InputAdornment> | ||
), | ||
}} | ||
/> | ||
); | ||
}; | ||
|
||
ConfigurationSelector.propTypes = { | ||
rowProps: { | ||
disabled: PropTypes.bool, | ||
onChange: PropTypes.func, | ||
rowData: PropTypes.shape({ | ||
value: PropTypes.string, | ||
}), | ||
}, | ||
}; | ||
|
||
export default ConfigurationSelector; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import React, { useRef } from "react"; | ||
import { IconButton, InputAdornment, TextField } from "@material-ui/core"; | ||
import { SelectScopeModal } from "@mov-ai/mov-fe-lib-react"; | ||
import { Document } from "@mov-ai/mov-fe-lib-core"; | ||
import CodeIcon from "@material-ui/icons/Code"; | ||
import PropTypes from "prop-types"; | ||
|
||
const ConfigurationSelector = (props) => { | ||
const [openModal, setOpenModal] = React.useState(false); | ||
const [selected, setSelected] = React.useState(null); | ||
const inputTextRef = useRef(); | ||
const rowProps = props.rowProps; | ||
const rowData = props.rowProps?.rowData; | ||
|
||
const formatConfigurationValue = (configuration) => { | ||
const document = Document.parsePath(configuration, SCOPES.Configuration); | ||
// Temporary validation if document is from archive | ||
// TO BE REMOVED AFTER STANDARDIZATION OF PARSING PROCESS | ||
if (document.workspace !== "global") { | ||
props.interface.alert( | ||
"Please note that only configurations from 'global' workspace are accepted at the moment.", | ||
props.interface.ALERTS.warning, | ||
); | ||
} | ||
// Return formatted config name | ||
return document.name; | ||
}; | ||
|
||
return ( | ||
<TextField | ||
style={{ width: "100%" }} | ||
value={rowData?.value || ""} | ||
data-testid="selector-text-input" | ||
onChange={(evt) => rowProps?.onChange(evt.target.value)} | ||
InputProps={{ | ||
ref: inputTextRef, | ||
endAdornment: ( | ||
<InputAdornment position="end"> | ||
<IconButton | ||
data-testid="open-selector-btn" | ||
aria-label="Select configuration" | ||
onClick={() => setOpenModal(true)} | ||
disabled={props.rowProps.disabled} | ||
onMouseDown={(evt) => evt.preventDefault()} | ||
> | ||
<CodeIcon></CodeIcon> | ||
</IconButton> | ||
<SelectScopeModal | ||
open={openModal} | ||
onCancel={() => setOpenModal(false)} | ||
onSubmit={(selectedConfiguration) => { | ||
const formatted = formatConfigurationValue( | ||
selectedConfiguration, | ||
); | ||
rowProps.onChange(formatted); | ||
setSelected(selectedConfiguration); | ||
setOpenModal(false); | ||
// Set cursor position | ||
setImmediate(() => { | ||
if (!inputTextRef.current) return; | ||
const inputText = inputTextRef.current.querySelector("input"); | ||
inputText.focus(); | ||
const endPosition = inputText.value.length; | ||
inputText.setSelectionRange(endPosition, endPosition); | ||
}); | ||
}} | ||
scopeList={[SCOPES.Configuration]} | ||
selected={selected} | ||
allowArchive={false} | ||
></SelectScopeModal> | ||
</InputAdornment> | ||
), | ||
}} | ||
/> | ||
); | ||
}; | ||
|
||
const SCOPES = { | ||
Configuration: "Configuration", | ||
}; | ||
|
||
ConfigurationSelector.defaultProps = {}; | ||
|
||
ConfigurationSelector.propTypes = { | ||
interface: PropTypes.object.isRequired, | ||
}; | ||
|
||
export default ConfigurationSelector; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// import React from "react"; | ||
// import { render, screen } from "@testing-library/react"; | ||
import "@testing-library/jest-dom"; | ||
// import ConfigurationSelector from "../ConfigurationSelector"; | ||
// import { DATA_TYPES } from "../../Utils/DataTypes"; | ||
|
||
const mockedRowData = { key: "key", type: "string", value: "value" }; | ||
const mockedProps = { | ||
rowData: mockedRowData, | ||
onChange: (val) => { | ||
mockedRowData.value = val; | ||
}, | ||
}; | ||
|
||
describe("Test the component ConfigurationSelector", () => { | ||
it("renders the component (smoke test)", () => { | ||
// const { container } = render( | ||
// <ConfigurationSelector rowProps={mockedProps}></ConfigurationSelector> | ||
// ); | ||
// const input = screen.getByTestId("selector-text-input"); | ||
// const iconButton = screen.getByTestId("open-selector-btn"); | ||
// // Validate if main elements are present in component (container, input and iconButton) | ||
// expect(container).toBeInTheDocument(); | ||
// expect(input).toBeInTheDocument(); | ||
// expect(iconButton).toBeInTheDocument(); | ||
}); | ||
|
||
it("Open SelectScopeModal and validate rowData.value format", () => { | ||
// render( | ||
// <ConfigurationSelector rowProps={mockedProps}></ConfigurationSelector> | ||
// ); | ||
// // simulate click to open modal | ||
// // The mocked SelectScopeModal triggers the onSubmit prop when is opened | ||
// const iconButton = screen.getByTestId("open-selector-btn"); | ||
// iconButton.click(); | ||
// // Check input value | ||
// setImmediate(() => { | ||
// const value = mockedProps.rowData.value; | ||
// const isValidFormat = DATA_TYPES["config"].validation(value); | ||
// expect(isValidFormat).toBeTruthy(); | ||
// }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React, { useEffect, useRef } from "react"; | ||
import MaterialTable from "@material-table/core"; | ||
|
||
export default function CustomMaterialTable(props) { | ||
const tableRef = useRef(); | ||
const openedPanels = useRef({}); | ||
const oldFunction = useRef(); | ||
|
||
useEffect(() => { | ||
if (!oldFunction.current) { | ||
oldFunction.current = tableRef.current?.onToggleDetailPanel; | ||
} | ||
|
||
if (oldFunction.current === tableRef.current?.onToggleDetailPanel) { | ||
tableRef.current.onToggleDetailPanel = (path, render) => { | ||
if (tableRef.current.props.data[path[0]]?.tableData?.showDetailPanel) { | ||
delete openedPanels.current[path[0]]; | ||
} else { | ||
openedPanels.current = { | ||
...openedPanels.current, | ||
[path[0]]: true, | ||
}; | ||
} | ||
|
||
oldFunction.current(path, render); | ||
}; | ||
} | ||
}, [tableRef]); | ||
|
||
return ( | ||
<MaterialTable | ||
tableRef={tableRef} | ||
{...props} | ||
data={ | ||
props.data?.map((d, i) => { | ||
const detailPanelFunction = | ||
typeof props.detailPanel === "function" | ||
? props.detailPanel | ||
: (rowData) => props.detailPanel[0](rowData).render(); | ||
return { | ||
...d, | ||
tableData: { | ||
showDetailPanel: openedPanels.current[i] | ||
? detailPanelFunction | ||
: null, | ||
}, | ||
}; | ||
}) || [] | ||
} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# JsonToReact | ||
|
||
## Introduction | ||
|
||
The main motivation for JsonToReact component is to build forms in a easy way. The easy way is to create a function:Json -> Form. | ||
This was implemented through a react component called JsonToReact. The whole concept and json semantics is based on [this project](https://github.com/rjsf-team/react-jsonschema-form). | ||
|
||
## Json Semantics | ||
|
||
In order to define the form you need 3 Json files: | ||
|
||
- schema | ||
- uiSchema | ||
- formData | ||
|
||
### Schema | ||
|
||
Defines the main structure of the form. It has the following structure | ||
|
||
```javascript | ||
Root = { | ||
title: "A Title", | ||
description: "A description", | ||
type: "object", | ||
properties: { | ||
ObjectA: Root || Atom, | ||
... | ||
} | ||
}; | ||
|
||
Atom = { | ||
AtomName: { | ||
type: "a type", | ||
title: "a title" | ||
}, | ||
} | ||
``` | ||
|
||
### UiSchema | ||
|
||
Defines the types of objects. | ||
|
||
```javascript | ||
R = { | ||
ObjectName: { | ||
UiAtom || R | ||
} | ||
... | ||
} | ||
|
||
UiAtom = { | ||
"ui:<type>": value | ||
} | ||
|
||
<type> := disable || widget || options | ||
``` | ||
|
||
### Data | ||
|
||
```javascript | ||
R = { | ||
ObjectA: R || value, | ||
... | ||
} | ||
``` |
Oops, something went wrong.