-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Create tab into Digital Twins page preview #1005
base: feature/distributed-demo
Are you sure you want to change the base?
Changes from 6 commits
8d1d846
2db9646
fb72ff4
54985e5
b9a0c62
15654df
b6dff7d
0d06bdb
8289011
e4d9dc6
70e1565
ae4a9a8
28c38a7
86159b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,55 @@ | ||
import * as React from 'react'; | ||
import { useState, useEffect } from 'react'; | ||
import { useEffect } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
import { Typography } from '@mui/material'; | ||
import Layout from 'page/Layout'; | ||
import TabComponent from 'components/tab/TabComponent'; | ||
import { TabData } from 'components/tab/subcomponents/TabRender'; | ||
import AssetBoard from 'preview/components/asset/AssetBoard'; | ||
import GitlabInstance from 'preview/util/gitlab'; | ||
import { getAuthority } from 'util/envUtil'; | ||
import { setAssets } from 'preview/store/assets.slice'; | ||
import { Asset } from 'preview/components/asset/Asset'; | ||
import DigitalTwin from 'preview/util/gitlabDigitalTwin'; | ||
import { setDigitalTwin } from 'preview/store/digitalTwin.slice'; | ||
import { addNewFile } from 'preview/store/file.slice'; | ||
import tabs from './DigitalTwinTabDataPreview'; | ||
import Editor from './editor/Editor'; | ||
import CustomSnackbar from './Snackbar'; | ||
|
||
export const createDTTab = (error: string | null): TabData[] => | ||
export const createDTTab = (): TabData[] => | ||
tabs | ||
.filter((tab) => tab.label === 'Manage' || tab.label === 'Execute') | ||
.filter( | ||
(tab) => | ||
tab.label === 'Manage' || | ||
tab.label === 'Execute' || | ||
tab.label === 'Create', | ||
) | ||
.map((tab) => ({ | ||
label: tab.label, | ||
body: ( | ||
<> | ||
<Typography variant="body1">{tab.body}</Typography> | ||
<AssetBoard tab={tab.label} error={error} /> | ||
{tab.label === 'Create' ? ( | ||
<> | ||
<Typography variant="body1">{tab.body}</Typography> | ||
<Editor tab={'create'} /> | ||
<CustomSnackbar /> | ||
</> | ||
) : ( | ||
<> | ||
<Typography variant="body1">{tab.body}</Typography> | ||
<AssetBoard tab={tab.label} /> | ||
</> | ||
)} | ||
</> | ||
), | ||
})); | ||
|
||
export const fetchSubfolders = async ( | ||
gitlabInstance: GitlabInstance, | ||
dispatch: ReturnType<typeof useDispatch>, | ||
setError: React.Dispatch<React.SetStateAction<string | null>>, | ||
) => { | ||
try { | ||
await gitlabInstance.init(); | ||
if (gitlabInstance.projectId) { | ||
const subfolders = await gitlabInstance.getDTSubfolders( | ||
gitlabInstance.projectId, | ||
); | ||
dispatch(setAssets(subfolders)); | ||
return subfolders; | ||
} | ||
dispatch(setAssets([])); | ||
return []; | ||
} catch (error) { | ||
setError('An error occurred'); | ||
return []; | ||
} | ||
}; | ||
|
||
export const createDigitalTwinsForAssets = async ( | ||
assets: Asset[], | ||
dispatch: ReturnType<typeof useDispatch>, | ||
) => { | ||
assets.forEach(async (asset) => { | ||
const gitlabInstance = new GitlabInstance( | ||
sessionStorage.getItem('username') || '', | ||
getAuthority(), | ||
sessionStorage.getItem('access_token') || '', | ||
); | ||
await gitlabInstance.init(); | ||
const digitalTwin = new DigitalTwin(asset.name, gitlabInstance); | ||
await digitalTwin.getDescription(); | ||
dispatch(setDigitalTwin({ assetName: asset.name, digitalTwin })); | ||
}); | ||
}; | ||
|
||
export const DTContent = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is only creating new DT. Can this intent be made more clear with a restructuring of code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The purpose of this file has remained unchanged, I have only added the necessary logic for the Create page (the useState There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
const [error, setError] = useState<string | null>(null); | ||
const dispatch = useDispatch(); | ||
const gitlabInstance = new GitlabInstance( | ||
sessionStorage.getItem('username') || '', | ||
getAuthority(), | ||
sessionStorage.getItem('access_token') || '', | ||
); | ||
|
||
useEffect(() => { | ||
fetchSubfolders(gitlabInstance, dispatch, setError).then((assets) => { | ||
if (assets) { | ||
createDigitalTwinsForAssets(assets, dispatch); | ||
} | ||
const defaultFiles = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This array and the method to iterate upon this can moved to either to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has been moved to |
||
{ name: 'description.md', type: 'description' }, | ||
{ name: 'README.md', type: 'description' }, | ||
{ name: '.gitlab-ci.yml', type: 'config' }, | ||
]; | ||
defaultFiles.forEach((file) => { | ||
dispatch(addNewFile(file)); | ||
}); | ||
}, [dispatch]); | ||
|
||
|
@@ -90,7 +60,7 @@ export const DTContent = () => { | |
The feature is experimental and requires certain gitlab setup in order | ||
for it to work. | ||
</Typography> | ||
<TabComponent assetType={createDTTab(error)} scope={[]} /> | ||
<TabComponent assetType={createDTTab()} scope={[]} /> | ||
</Layout> | ||
); | ||
}; | ||
|
VanessaScherma marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import * as React from 'react'; | ||
import { | ||
Dialog, | ||
DialogActions, | ||
DialogContent, | ||
DialogTitle, | ||
TextField, | ||
Button, | ||
} from '@mui/material'; | ||
import { useDispatch } from 'react-redux'; | ||
import { deleteFile, renameFile } from 'preview/store/file.slice'; | ||
|
||
interface CreateDialogsProps { | ||
openChangeFileNameDialog: boolean; | ||
onCloseChangeFileNameDialog: () => void; | ||
fileName: string; | ||
setFileName: (name: string) => void; | ||
setFileContent: (content: string) => void; | ||
setFileType: (type: string) => void; | ||
|
||
openDeleteFileDialog: boolean; | ||
onCloseDeleteFileDialog: () => void; | ||
} | ||
|
||
const CreateDialogs: React.FC<CreateDialogsProps> = ({ | ||
VanessaScherma marked this conversation as resolved.
Show resolved
Hide resolved
|
||
openChangeFileNameDialog, | ||
onCloseChangeFileNameDialog, | ||
fileName, | ||
setFileName, | ||
setFileContent, | ||
setFileType, | ||
|
||
openDeleteFileDialog, | ||
onCloseDeleteFileDialog, | ||
}) => { | ||
const [modifiedFileName, setModifiedFileName] = React.useState(fileName); | ||
const dispatch = useDispatch(); | ||
|
||
React.useEffect(() => { | ||
setModifiedFileName(fileName); | ||
}, [fileName]); | ||
|
||
const handleChangeFileName = () => { | ||
dispatch(renameFile({ oldName: fileName, newName: modifiedFileName })); | ||
|
||
setFileName(modifiedFileName); | ||
|
||
const extension = modifiedFileName.split('.').pop(); | ||
setFileType(extension || ''); | ||
|
||
onCloseChangeFileNameDialog(); | ||
}; | ||
|
||
const handleDeleteFile = () => { | ||
dispatch(deleteFile(fileName)); | ||
setFileName(''); | ||
setFileContent(''); | ||
onCloseDeleteFileDialog(); | ||
}; | ||
|
||
return ( | ||
<> | ||
<Dialog open={openChangeFileNameDialog}> | ||
<DialogTitle>Change the file name</DialogTitle> | ||
<DialogContent> | ||
<TextField | ||
autoFocus | ||
margin="dense" | ||
label="New File Name" | ||
fullWidth | ||
variant="outlined" | ||
value={modifiedFileName} | ||
onChange={(e) => setModifiedFileName(e.target.value)} | ||
/> | ||
</DialogContent> | ||
<DialogActions> | ||
<Button onClick={onCloseChangeFileNameDialog} color="primary"> | ||
Cancel | ||
</Button> | ||
<Button onClick={handleChangeFileName} color="secondary"> | ||
Change | ||
</Button> | ||
</DialogActions> | ||
</Dialog> | ||
|
||
<Dialog open={openDeleteFileDialog}> | ||
<DialogContent> | ||
Are you sure you want to delete the <strong>{fileName}</strong> file | ||
and its content? | ||
</DialogContent> | ||
<DialogActions> | ||
<Button onClick={onCloseDeleteFileDialog} color="primary"> | ||
No | ||
</Button> | ||
<Button onClick={handleDeleteFile} color="secondary"> | ||
Yes | ||
</Button> | ||
</DialogActions> | ||
</Dialog> | ||
</> | ||
); | ||
}; | ||
|
||
export default CreateDialogs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code has been moved from
DigitalTwinsPreview.tsx
to here. The non-react part of code belongs to some file inpreview/util
module.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been moved to
init.ts
inpreview/util.