Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • andersharrisson/ce-deploy-ui
  • ccce/dev/ce-deploy-ui
2 results
Show changes
Commits on Source (8)
import React, { useMemo, useEffect, useState, useContext } from "react"; import React, { useMemo, useEffect, useState, useContext } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useTypingTimer } from "../../common/SearchBoxFilter/TypingTimer"; import { useTypingTimer } from "../../common/SearchBoxFilter/TypingTimer";
import { useCustomSnackbar } from "../../common/snackbar";
import { RepositoryOptions, WITHOUT_REPO } from "./RepositoryOptions";
import { RepositoryName } from "./RepositoryName";
import { RootPaper } from "@ess-ics/ce-ui-common/dist/components/common/container/RootPaper"; import { RootPaper } from "@ess-ics/ce-ui-common/dist/components/common/container/RootPaper";
import { import {
Alert, Alert,
...@@ -24,10 +27,13 @@ const createRequestParams = (query) => { ...@@ -24,10 +27,13 @@ const createRequestParams = (query) => {
export function CreateIOC() { export function CreateIOC() {
const navigate = useNavigate(); const navigate = useNavigate();
const [name, setName] = useState(); const showSnackBar = useCustomSnackbar();
const [gitId, setGitId] = useState(null); const [namingEntity, setNamingEntity] = useState({});
const [gitProject, setGitProject] = useState({});
const [nameQuery, onNameKeyUp] = useTypingTimer({ interval: 500 }); const [nameQuery, onNameKeyUp] = useTypingTimer({ interval: 500 });
const [repoQuery, onRepoKeyUp] = useTypingTimer({ interval: 500 }); const [repoQuery, onRepoKeyUp] = useTypingTimer({ interval: 500 });
const [selectedRepoOption, setSelectedRepoOption] = useState(WITHOUT_REPO);
const [repoName, setRepoName] = useState("");
const client = useContext(apiContext); const client = useContext(apiContext);
...@@ -65,11 +71,6 @@ export function CreateIOC() { ...@@ -65,11 +71,6 @@ export function CreateIOC() {
call: false call: false
}); });
// Return home on cancel
const handleCancel = () => {
navigate("/");
};
// create the ioc on form submit // create the ioc on form submit
const onSubmit = (event) => { const onSubmit = (event) => {
event.preventDefault(); event.preventDefault();
...@@ -77,13 +78,20 @@ export function CreateIOC() { ...@@ -77,13 +78,20 @@ export function CreateIOC() {
{}, {},
{ {
requestBody: { requestBody: {
gitProjectId: gitId, gitProjectId: gitProject.id,
namingUuid: name ? name.uuid : undefined namingUuid: namingEntity ? namingEntity.uuid : undefined,
repository_name: repoName ? repoName : undefined
} }
} }
); );
}; };
const handleSelectRepoOption = (option) => {
setSelectedRepoOption(option);
setNamingEntity({});
setGitProject({});
};
// fetch new names when name query changes // fetch new names when name query changes
useEffect(() => { useEffect(() => {
if (nameQuery) { if (nameQuery) {
...@@ -100,9 +108,15 @@ export function CreateIOC() { ...@@ -100,9 +108,15 @@ export function CreateIOC() {
// navigate home once ioc created // navigate home once ioc created
useEffect(() => { useEffect(() => {
if (ioc) { if (ioc) {
navigate(`/iocs/${ioc.id}`); showSnackBar(
selectedRepoOption === WITHOUT_REPO
? "IOC created"
: "IOC created with a repository",
"success"
);
navigate(`/iocs/${ioc.id}?&tab=Management`);
} }
}, [ioc, navigate]); }, [ioc, showSnackBar, selectedRepoOption, navigate]);
return ( return (
<RootPaper <RootPaper
...@@ -116,15 +130,18 @@ export function CreateIOC() { ...@@ -116,15 +130,18 @@ export function CreateIOC() {
width="600px" width="600px"
> >
<Typography variant="h2">Create new IOC</Typography> <Typography variant="h2">Create new IOC</Typography>
<RepositoryOptions
selectedRepoOption={selectedRepoOption}
onSelectRepoOption={handleSelectRepoOption}
/>
<Autocomplete <Autocomplete
autoHighlight autoHighlight
id="nameAutocomplete" id="nameAutocomplete"
value={namingEntity}
options={nameQuery ? names ?? [] : []} options={nameQuery ? names ?? [] : []}
loading={loadingNames} loading={loadingNames}
clearOnBlur={false} clearOnBlur={false}
getOptionLabel={(option) => { getOptionLabel={(option) => option?.name ?? ""}
return option?.name ?? "";
}}
renderInput={(params) => ( renderInput={(params) => (
<TextField <TextField
{...params} {...params}
...@@ -146,70 +163,74 @@ export function CreateIOC() { ...@@ -146,70 +163,74 @@ export function CreateIOC() {
) )
}} }}
disabled={loading} disabled={loading}
helperText={name ? name.description : ""} helperText={namingEntity ? namingEntity.description : ""}
/> />
)} )}
onChange={(event, value, reason) => { onChange={(_, value) => setNamingEntity(value)}
setName(value); onInputChange={(event) => event && onNameKeyUp(event.nativeEvent)}
}}
onInputChange={(event) => {
event && onNameKeyUp(event.nativeEvent);
}}
autoSelect autoSelect
/> />
{selectedRepoOption === WITHOUT_REPO ? (
<Autocomplete
autoHighlight
id="gitId"
value={gitProject}
options={repoQuery || gitProject ? allowedGitProjects ?? [] : []}
loading={loadingAllowedGitProjects}
clearOnBlur={false}
getOptionLabel={(option) => {
return option?.url ?? "";
}}
onChange={(_, value) => setGitProject(value)}
onInputChange={(event) => event && onRepoKeyUp(event.nativeEvent)}
renderInput={(params) => (
<TextField
{...params}
label="Git repository"
variant="outlined"
fullWidth
required
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loadingAllowedGitProjects ? (
<CircularProgress
color="inherit"
size={20}
/>
) : null}
{params.InputProps.endAdornment}
</React.Fragment>
)
}}
disabled={loading}
/>
)}
autoSelect
/>
) : (
<RepositoryName
repoName={repoName}
onRepoNameChange={(name) => setRepoName(name)}
/>
)}
<Autocomplete
autoHighlight
id="gitId"
options={repoQuery || gitId ? allowedGitProjects ?? [] : []}
loading={loadingAllowedGitProjects}
clearOnBlur={false}
getOptionLabel={(option) => {
return option?.url ?? "";
}}
onChange={(event, value, reason) => {
setGitId(value?.id);
}}
onInputChange={(event) => {
event && onRepoKeyUp(event.nativeEvent);
}}
renderInput={(params) => (
<TextField
{...params}
label="Git repository"
variant="outlined"
fullWidth
required
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loadingAllowedGitProjects ? (
<CircularProgress
color="inherit"
size={20}
/>
) : null}
{params.InputProps.endAdornment}
</React.Fragment>
)
}}
disabled={loading}
/>
)}
autoSelect
/>
{error ? ( {error ? (
<Alert severity="error">{getErrorMessage(error)}</Alert> <Alert severity="error">{getErrorMessage(error)}</Alert>
) : ( ) : null}
<></> {loading ? (
)} <LinearProgress
aria-busy="true"
aria-label="Creating IOC, please wait"
/>
) : null}
<Stack <Stack
direction="row" direction="row"
justifyContent="flex-end" justifyContent="flex-end"
> >
<Button <Button
onClick={handleCancel} onClick={() => navigate("/")}
color="primary" color="primary"
disabled={loading} disabled={loading}
> >
...@@ -219,17 +240,15 @@ export function CreateIOC() { ...@@ -219,17 +240,15 @@ export function CreateIOC() {
color="primary" color="primary"
variant="contained" variant="contained"
type="submit" type="submit"
disabled={!name || !gitId || loading} disabled={
loading || !namingEntity || selectedRepoOption === WITHOUT_REPO
? !gitProject
: !repoName
}
> >
Create Create
</Button> </Button>
</Stack> </Stack>
{loading ? (
<LinearProgress
aria-busy="true"
aria-label="Creating IOC, please wait"
/>
) : null}
</Stack> </Stack>
</RootPaper> </RootPaper>
); );
......
import React, { useState, useCallback } from "react";
import { Box, Stack, TextField, Typography } from "@mui/material";
import { string, func } from "prop-types";
const propTypes = {
repoName: string,
onRepoNameChange: func
};
// match from beginning to end
// starts with an alpha numeric character (a-Z 0-9)
// followed by 0 or more combinations of alphanumeric characters or - or _
// ends with an alpha numeric character (a-Z 0-9)
const REPO_NAME_REGEX = "^[a-z0-9]+([a-z0-9_-]+)*[a-z0-9]$";
export const RepositoryName = ({ repoName, onRepoNameChange }) => {
const [valid, setValid] = useState(repoName || repoName.length === 0);
const handleNameChange = useCallback(
(e) => {
const reg = new RegExp(REPO_NAME_REGEX);
const hasValidCharacters = reg.test(e.target.value);
const hasValidLength =
e.target.value.length >= 4 && e.target.value.length <= 20;
const valid = hasValidCharacters && hasValidLength;
setValid(valid);
if (valid) {
onRepoNameChange(e.target.value);
} else {
onRepoNameChange("");
}
},
[onRepoNameChange]
);
return (
<Stack
width="100%"
gap={1}
>
<Box>
<TextField
autoComplete="off"
id="repositoryName"
label="Git repository name"
variant="outlined"
fullWidth
onChange={handleNameChange}
error={!valid}
helperText={
!valid
? "Only lowercase alphanumeric chars, hyphens and underscores are allowed in Git repository name (min 4 and max 20 chars)"
: null
}
/>
<Typography
variant="body2"
fontStyle="italic"
id="iocTypeName-name-preview"
>
The Git repository name will follow the pattern: &nbsp;
<Box
sx={{ fontFamily: "Monospace" }}
component="span"
>
e3-ioc-
<Box
sx={{ fontWeight: "bold", display: "inline" }}
component="span"
>
{repoName ? repoName : "{git repository name}"}
</Box>
</Box>
</Typography>
</Box>
</Stack>
);
};
RepositoryName.propTypes = propTypes;
import React from "react";
import { string, func } from "prop-types";
import {
FormControl,
FormControlLabel,
RadioGroup,
Radio
} from "@mui/material";
const propTypes = {
selectedRepoOption: string,
onSelectRepoOption: func
};
export const WITH_REPO = "with";
export const WITHOUT_REPO = "without";
export const RepositoryOptions = ({
selectedRepoOption,
onSelectRepoOption
}) => (
<FormControl>
<RadioGroup
row
aria-label="Choose option to create IOC with or without existing repository"
name="repositoryOptions"
value={selectedRepoOption}
onChange={(event) => onSelectRepoOption(event.target.value)}
>
<FormControlLabel
value={WITHOUT_REPO}
control={<Radio />}
label="Create IOC with existing repository"
/>
<FormControlLabel
value={WITH_REPO}
control={<Radio />}
label="Create IOC and a repository"
/>
</RadioGroup>
</FormControl>
);
RepositoryOptions.propTypes = propTypes;