I'm creating a custom tool using Python SDK v2 and UI SDK. Per the getting started guide, I installed all the prerequisites and used ayx_plugin_cli to create a new project template.
I modified my index.tsx file to add several TextFields:
return (
<Box p={4}>
<Grid container spacing={4} direction="column" alignItems="center">
<Grid item>
<Alteryx className={classes.alteryx} />
</Grid>
<Grid item>
<TextField name='system' label="System" placeholder='System' value={"my_system"}/>
</Grid>
<Grid item>
<TextField name='username' label="Username" placeholder='Username'/>
</Grid>
<Grid item>
<TextField name='password' label="Password" placeholder='Password' type='password'/>
</Grid>
<Grid item>
<TextField name='sql' label="SQL Statement" multiline></TextField>
</Grid>
</Grid>
</Box>
)
}
system = self.provider.tool_config.get('system')
username = self.provider.tool_config.get('username')
password = self.provider.tool_config.get('password')
sql = self.provider.tool_config.get('sql')
Solved! Go to Solution.
There's no quicker way for me to figure something out myself, than to ask a question.
I figured it out. In the files that are generated by ayx_plugin_cli, there's a folder: ui/<your tool name>/src/tool-templates. In those files, it shows how the tool data can be persisted.
For others' sake, here's my whole index.tsx file:
import React, { useContext, useEffect} from 'react'; import ReactDOM from 'react-dom'; import { AyxAppWrapper, Box, Grid, Typography, makeStyles, Theme } from '@alteryx/ui'; import { Alteryx } from '@alteryx/icons'; import { Context as UiSdkContext, DesignerApi } from '@alteryx/react-comms'; import { TextField } from '@alteryx/ui'; const useStyles = makeStyles((theme: Theme) => ({ alteryx: { color: theme.palette.brand.corporateBlue, height: '125px', width: '125px' } })); const App = () => { const classes = useStyles(); const [model, handleUpdateModel] = useContext(UiSdkContext); // Dev Harness Specific Code ---------- Start // The following code is specifically a dev harness functionality. // If you're developing a tool for Designer, you'll want to remove this // and check out our docs for guidance useEffect(() => { handleUpdateModel(model) }, []); // Dev Harness Specific Code ---------- End const onHandleTextChange = event => { const newModel = { ...model }; newModel.Configuration[event.target.name] = event.target.value; handleUpdateModel(newModel); }; return ( <Box p={4}> <Grid container spacing={4} direction="column" alignItems="center"> <Grid item> <Alteryx className={classes.alteryx} /> </Grid> <Grid item> <TextField name='system' label="System" placeholder='System' onChange={onHandleTextChange} value={model.Configuration.system || "" } /> </Grid> <Grid item> <TextField name='username' label="Username" placeholder='Username' onChange={onHandleTextChange} value={model.Configuration.username || "" } /> </Grid> <Grid item> <TextField name='password' label="Password" placeholder='Password' type='password' onChange={onHandleTextChange} value={model.Configuration.password || "" } /> </Grid> <Grid item> <TextField name='sql' label="SQL Statement" onChange={onHandleTextChange} value={model.Configuration.sql || ""} multiline></TextField> </Grid> </Grid> </Box> ) } const Tool = () => { return ( <DesignerApi messages={{}}> <AyxAppWrapper> <App /> </AyxAppWrapper> </DesignerApi> ) } ReactDOM.render( <Tool />, document.getElementById('app') );
The notable parts are here:
const onHandleTextChange = event => { const newModel = { ...model }; newModel.Configuration[event.target.name] = event.target.value; handleUpdateModel(newModel); };
This code creates a copy of the model dictionary and updates its Configuration object with the new value. Then it tells Alteryx to replace the old model with the new model.
<Grid item> <TextField name='username' label="Username" placeholder='Username' onChange={onHandleTextChange} value={model.Configuration.username || "" } /> </Grid>
In the TextField, we added a name, onChange event, and value. The onChange event calls the code above when the TextField changes, and the value field fills in the value of the TextField when the model is initialized (i.e. the user configures the tool).
Note we also added an import statement at the top, so we can use the TextField tag in our UI:
import { TextField } from '@alteryx/ui';