diff --git a/frontend/src/modules/Dashboards/views/DashboardImportForm.js b/frontend/src/modules/Dashboards/views/DashboardImportForm.js index 50fbc3ac4..83afbc2c9 100644 --- a/frontend/src/modules/Dashboards/views/DashboardImportForm.js +++ b/frontend/src/modules/Dashboards/views/DashboardImportForm.js @@ -8,12 +8,10 @@ import { CardContent, CardHeader, Chip, - CircularProgress, Container, FormHelperText, Grid, Link, - MenuItem, TextField, Typography } from '@mui/material'; @@ -31,13 +29,9 @@ import { useSettings } from 'design'; import { SET_ERROR, useDispatch } from 'globalErrors'; -import { - listEnvironmentGroups, - listValidEnvironments, - searchGlossary, - useClient -} from 'services'; +import { searchGlossary, useClient } from 'services'; import { importDashboard } from '../services'; +import { EnvironmentTeamDropdown } from 'modules/Shared'; const DashboardImportForm = (props) => { const navigate = useNavigate(); @@ -45,31 +39,8 @@ const DashboardImportForm = (props) => { const dispatch = useDispatch(); const client = useClient(); const { settings } = useSettings(); - const [loading, setLoading] = useState(true); - const [groupOptions, setGroupOptions] = useState([]); - const [environmentOptions, setEnvironmentOptions] = useState([]); const [selectableTerms, setSelectableTerms] = useState([]); - const fetchEnvironments = useCallback(async () => { - setLoading(true); - const response = await client.query( - listValidEnvironments({ - filter: Defaults.selectListFilter - }) - ); - if (!response.errors) { - setEnvironmentOptions( - response.data.listValidEnvironments.nodes.map((e) => ({ - ...e, - value: e.environmentUri, - label: e.label - })) - ); - } else { - dispatch({ type: SET_ERROR, error: response.errors[0].message }); - } - setLoading(false); - }, [client, dispatch]); const fetchTerms = useCallback(async () => { const response = await client.query( searchGlossary(Defaults.selectListFilter) @@ -95,37 +66,11 @@ const DashboardImportForm = (props) => { }, [client, dispatch]); useEffect(() => { if (client) { - fetchEnvironments().catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); fetchTerms().catch((e) => dispatch({ type: SET_ERROR, error: e.message }) ); } - }, [client, fetchTerms, fetchEnvironments, dispatch]); - - const fetchGroups = async (environmentUri) => { - try { - const response = await client.query( - listEnvironmentGroups({ - filter: Defaults.selectListFilter, - environmentUri - }) - ); - if (!response.errors) { - setGroupOptions( - response.data.listEnvironmentGroups.nodes.map((g) => ({ - value: g.groupUri, - label: g.groupUri - })) - ); - } else { - dispatch({ type: SET_ERROR, error: response.errors[0].message }); - } - } catch (e) { - dispatch({ type: SET_ERROR, error: e.message }); - } - }; + }, [client, fetchTerms, dispatch]); async function submit(values, setStatus, setSubmitting, setErrors) { try { @@ -136,7 +81,7 @@ const DashboardImportForm = (props) => { dashboardId: values.dashboardId, environmentUri: values.environment.environmentUri, description: values.description, - SamlGroupName: values.SamlGroupName, + SamlGroupName: values.SamlAdminGroupName, tags: values.tags, terms: values.terms.nodes ? values.terms.nodes.map((t) => t.nodeUri) @@ -168,9 +113,6 @@ const DashboardImportForm = (props) => { dispatch({ type: SET_ERROR, error: err.message }); } } - if (loading) { - return ; - } return ( <> @@ -239,7 +181,7 @@ const DashboardImportForm = (props) => { label: '', dashboardId: '', description: '', - SamlGroupName: '', + SamlAdminGroupName: '', environment: '', tags: [], terms: [] @@ -252,7 +194,7 @@ const DashboardImportForm = (props) => { .max(255) .required('*QuickSight dashboard identifier is required'), description: Yup.string().max(5000), - SamlGroupName: Yup.string() + SamlAdminGroupName: Yup.string() .max(255) .required('*Team is required'), environment: Yup.object().required('*Environment is required'), @@ -392,94 +334,13 @@ const DashboardImportForm = (props) => { - - - - { - setFieldValue('SamlGroupName', ''); - fetchGroups( - event.target.value.environmentUri - ).catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - setFieldValue('environment', event.target.value); - }} - select - value={values.environment} - variant="outlined" - > - {environmentOptions.map((environment) => ( - - {environment.label} - - ))} - - - - - - - - - - - {groupOptions.map((group) => ( - - {group.label} - - ))} - - - + {errors.submit && ( {errors.submit} diff --git a/frontend/src/modules/MLStudio/views/MLStudioCreateForm.js b/frontend/src/modules/MLStudio/views/MLStudioCreateForm.js index 0f4c13e34..74206dc88 100644 --- a/frontend/src/modules/MLStudio/views/MLStudioCreateForm.js +++ b/frontend/src/modules/MLStudio/views/MLStudioCreateForm.js @@ -6,18 +6,15 @@ import { Card, CardContent, CardHeader, - CircularProgress, Container, FormHelperText, Grid, Link, - MenuItem, TextField, Typography } from '@mui/material'; import { Formik } from 'formik'; import { useSnackbar } from 'notistack'; -import { useCallback, useEffect, useState } from 'react'; import { Helmet } from 'react-helmet-async'; import { Link as RouterLink, useNavigate } from 'react-router-dom'; import * as Yup from 'yup'; @@ -25,17 +22,13 @@ import { ArrowLeftIcon, ChevronRightIcon, ChipInput, - Defaults, useSettings } from 'design'; import { SET_ERROR, useDispatch } from 'globalErrors'; -import { - listEnvironmentGroups, - listValidEnvironments, - useClient -} from 'services'; +import { useClient } from 'services'; import { createSagemakerStudioUser } from '../services'; +import { EnvironmentTeamDropdown } from 'modules/Shared'; const MLStudioCreateForm = (props) => { const navigate = useNavigate(); @@ -43,57 +36,6 @@ const MLStudioCreateForm = (props) => { const dispatch = useDispatch(); const client = useClient(); const { settings } = useSettings(); - const [loading, setLoading] = useState(true); - const [groupOptions, setGroupOptions] = useState([]); - const [environmentOptions, setEnvironmentOptions] = useState([]); - const fetchEnvironments = useCallback(async () => { - setLoading(true); - const response = await client.query( - listValidEnvironments({ filter: Defaults.selectListFilter }) - ); - if (!response.errors) { - setEnvironmentOptions( - response.data.listValidEnvironments.nodes.map((e) => ({ - ...e, - value: e.environmentUri, - label: e.label - })) - ); - } else { - dispatch({ type: SET_ERROR, error: response.errors[0].message }); - } - setLoading(false); - }, [client, dispatch]); - const fetchGroups = async (environmentUri) => { - try { - const response = await client.query( - listEnvironmentGroups({ - filter: Defaults.selectListFilter, - environmentUri - }) - ); - if (!response.errors) { - setGroupOptions( - response.data.listEnvironmentGroups.nodes.map((g) => ({ - value: g.groupUri, - label: g.groupUri - })) - ); - } else { - dispatch({ type: SET_ERROR, error: response.errors[0].message }); - } - } catch (e) { - dispatch({ type: SET_ERROR, error: e.message }); - } - }; - useEffect(() => { - if (client) { - fetchEnvironments().catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - } - }, [client, dispatch, fetchEnvironments]); - async function submit(values, setStatus, setSubmitting, setErrors) { try { const response = await client.mutate( @@ -130,10 +72,6 @@ const MLStudioCreateForm = (props) => { setSubmitting(false); } } - if (loading) { - return ; - } - return ( <> @@ -282,31 +220,6 @@ const MLStudioCreateForm = (props) => { - - - {groupOptions.map((group) => ( - - {group.label} - - ))} - - { - - - - { - setFieldValue('SamlGroupName', ''); - fetchGroups( - event.target.value.environmentUri - ).catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - setFieldValue('environment', event.target.value); - }} - select - value={values.environment} - variant="outlined" - > - {environmentOptions.map((environment) => ( - - {environment.label} - - ))} - - - - - - - - - + {errors.submit && ( {errors.submit} diff --git a/frontend/src/modules/Notebooks/views/NotebookCreateForm.js b/frontend/src/modules/Notebooks/views/NotebookCreateForm.js index 2d256fc2d..b433b5fe2 100644 --- a/frontend/src/modules/Notebooks/views/NotebookCreateForm.js +++ b/frontend/src/modules/Notebooks/views/NotebookCreateForm.js @@ -394,45 +394,52 @@ const NotebookCreateForm = (props) => { - { + option)} + onChange={(event, value) => { setFieldValue('SamlAdminGroupName', ''); - fetchGroups( - event.target.value.environmentUri - ).catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - setFieldValue('environment', event.target.value); - setVpcOptions( - event.target.value.networks.map((v) => ({ - ...v, - value: v, - label: v.VpcId - })) - ); + if (value && value.environmentUri) { + setFieldValue('environment', value); + fetchGroups(value.environmentUri).catch((e) => + dispatch({ + type: SET_ERROR, + error: e.message + }) + ); + setVpcOptions( + value.networks.map((v) => ({ + ...v, + value: v, + label: v.VpcId + })) + ); + } else { + setFieldValue('environment', ''); + setVpcOptions([]); + setGroupOptions([]); + } }} - select - value={values.environment} - variant="outlined" - > - {environmentOptions.map((environment) => ( - - {environment.label} - - ))} - + renderInput={(params) => ( + + )} + /> { label="Region" name="region" value={ - values.environment + values.environment && values.environment.region ? values.environment.region : '' } @@ -455,7 +462,8 @@ const NotebookCreateForm = (props) => { label="Organization" name="organization" value={ - values.environment + values.environment && + values.environment.organization ? values.environment.organization.label : '' } @@ -463,29 +471,59 @@ const NotebookCreateForm = (props) => { /> - option)} + onChange={(event, value) => { + if (value && value.value) { + setFieldValue( + 'SamlAdminGroupName', + value.value + ); + } else { + setFieldValue('SamlAdminGroupName', ''); + } + }} + inputValue={values.SamlAdminGroupName} + renderInput={(params) => ( + + {groupOptions.length > 0 ? ( + + ) : ( + + )} + )} - helperText={ - touched.SamlAdminGroupName && - errors.SamlAdminGroupName - } - label="Team" - name="SamlAdminGroupName" - onChange={handleChange} - select - value={values.SamlAdminGroupName} - variant="outlined" - > - {groupOptions.map((group) => ( - - {group.label} - - ))} - + /> @@ -558,7 +596,6 @@ const NotebookCreateForm = (props) => { - {errors.submit && ( {errors.submit} diff --git a/frontend/src/modules/Omics/views/OmicsRunCreateForm.js b/frontend/src/modules/Omics/views/OmicsRunCreateForm.js index cdf5dc4e3..fbf62acad 100644 --- a/frontend/src/modules/Omics/views/OmicsRunCreateForm.js +++ b/frontend/src/modules/Omics/views/OmicsRunCreateForm.js @@ -14,22 +14,17 @@ import { FormHelperText, Grid, Link, - MenuItem, TextField, Typography } from '@mui/material'; import { Helmet } from 'react-helmet-async'; import { LoadingButton } from '@mui/lab'; import React, { useCallback, useEffect, useState } from 'react'; -import { - useClient, - listEnvironmentGroups, - listValidEnvironments, - listS3DatasetsOwnedByEnvGroup -} from 'services'; +import { useClient } from 'services'; import { getOmicsWorkflow, createOmicsRun } from '../services'; -import { ArrowLeftIcon, ChevronRightIcon, Defaults, useSettings } from 'design'; +import { ArrowLeftIcon, ChevronRightIcon, useSettings } from 'design'; import { SET_ERROR, useDispatch } from 'globalErrors'; +import { EnvironmentTeamDatasetsDropdown } from 'modules/Shared'; const OmicsRunCreateForm = (props) => { const params = useParams(); @@ -54,88 +49,6 @@ const OmicsRunCreateForm = (props) => { setLoading(false); }, [client, dispatch, params.uri]); - const [groupOptions, setGroupOptions] = useState([]); - const [environmentOptions, setEnvironmentOptions] = useState([]); - const [currentEnv, setCurrentEnv] = useState(''); - const [datasetOptions, setDatasetOptions] = useState([]); - const fetchEnvironments = useCallback(async () => { - setLoading(true); - const response = await client.query( - listValidEnvironments({ filter: Defaults.SelectListFilter }) - ); - if (!response.errors) { - setEnvironmentOptions( - response.data.listValidEnvironments.nodes.map((e) => ({ - ...e, - value: e.environmentUri, - label: e.label - })) - ); - } else { - dispatch({ type: SET_ERROR, error: response.errors[0].message }); - } - setLoading(false); - }, [client, dispatch]); - - const fetchGroups = async (environmentUri) => { - setCurrentEnv(environmentUri); - try { - const response = await client.query( - listEnvironmentGroups({ - filter: Defaults.SelectListFilter, - environmentUri - }) - ); - if (!response.errors) { - setGroupOptions( - response.data.listEnvironmentGroups.nodes.map((g) => ({ - value: g.groupUri, - label: g.groupUri - })) - ); - } else { - dispatch({ type: SET_ERROR, error: response.errors[0].message }); - } - } catch (e) { - dispatch({ type: SET_ERROR, error: e.message }); - } - }; - - const fetchDatasets = async (groupUri) => { - let ownedDatasets = []; - try { - const response = await client.query( - listS3DatasetsOwnedByEnvGroup({ - filter: Defaults.SelectListFilter, - environmentUri: currentEnv, - groupUri: groupUri - }) - ); - if (!response.errors) { - ownedDatasets = response.data.listS3DatasetsOwnedByEnvGroup.nodes?.map( - (dataset) => ({ - value: dataset.datasetUri, - label: dataset.label - }) - ); - } else { - dispatch({ type: SET_ERROR, error: response.errors[0].message }); - } - } catch (e) { - dispatch({ type: SET_ERROR, error: e.message }); - } - setDatasetOptions(ownedDatasets); - }; - - useEffect(() => { - if (client) { - fetchEnvironments().catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - fetchItem().catch((e) => dispatch({ type: SET_ERROR, error: e.message })); - } - }, [client, dispatch, fetchEnvironments, fetchItem]); - useEffect(() => { if (client) { fetchItem().catch((e) => dispatch({ type: SET_ERROR, error: e.message })); @@ -151,7 +64,7 @@ const OmicsRunCreateForm = (props) => { workflowUri: omicsWorkflow.workflowUri, parameterTemplate: values.parameterTemplate, SamlAdminGroupName: values.SamlAdminGroupName, - destination: values.destination + destination: values.dataset }) ); setStatus({ success: true }); @@ -252,7 +165,7 @@ const OmicsRunCreateForm = (props) => { label: '', SamlAdminGroupName: '', environment: '', - destination: '', + dataset: '', parameterTemplate: omicsWorkflow.parameterTemplate }} validationSchema={Yup.object().shape({ @@ -267,9 +180,7 @@ const OmicsRunCreateForm = (props) => { .max(255) .required('*Team is required'), environment: Yup.object().required('*Environment is required'), - destination: Yup.string() - .max(255) - .required('*Destination is required') + dataset: Yup.string().max(255).required('*Dataset is required') })} onSubmit={async ( values, @@ -316,114 +227,13 @@ const OmicsRunCreateForm = (props) => { variant="outlined" /> - - { - setFieldValue('SamlAdminGroupName', ''); - fetchGroups( - event.target.value.environmentUri - ).catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - setFieldValue('environment', event.target.value); - }} - select - value={values.environment} - variant="outlined" - > - {environmentOptions.map((environment) => ( - - {environment.label} - - ))} - - - - - - - { - setFieldValue('destination', ''); - fetchDatasets(event.target.value).catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - setFieldValue( - 'SamlAdminGroupName', - event.target.value - ); - }} - select - value={values.SamlAdminGroupName} - variant="outlined" - > - {groupOptions.map((group) => ( - - {group.label} - - ))} - - - - - {datasetOptions.map((dataset) => ( - - {dataset.label} - - ))} - - + diff --git a/frontend/src/modules/S3_Datasets/views/DatasetCreateForm.js b/frontend/src/modules/S3_Datasets/views/DatasetCreateForm.js index cc88bf175..565afe50c 100644 --- a/frontend/src/modules/S3_Datasets/views/DatasetCreateForm.js +++ b/frontend/src/modules/S3_Datasets/views/DatasetCreateForm.js @@ -120,7 +120,7 @@ const DatasetCreateForm = (props) => { owner: '', stewards: values.stewards, label: values.label, - SamlAdminGroupName: values.SamlGroupName, + SamlAdminGroupName: values.SamlAdminGroupName, tags: values.tags, description: values.description, topics: values.topics ? values.topics.map((t) => t.value) : [], @@ -220,7 +220,7 @@ const DatasetCreateForm = (props) => { environment: '', stewards: '', confidentiality: '', - SamlGroupName: '', + SamlAdminGroupName: '', tags: [], topics: [], autoApprovalEnabled: false @@ -230,7 +230,7 @@ const DatasetCreateForm = (props) => { .max(255) .required('*Dataset name is required'), description: Yup.string().max(5000), - SamlGroupName: Yup.string() + SamlAdminGroupName: Yup.string() .max(255) .required('*Owners team is required'), topics: isFeatureEnabled('datasets_base', 'topics_dropdown') @@ -429,38 +429,45 @@ const DatasetCreateForm = (props) => { - { - setFieldValue('SamlGroupName', ''); - fetchGroups( - event.target.value.environmentUri - ).catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - setFieldValue('environment', event.target.value); + option)} + onChange={(event, value) => { + setFieldValue('SamlAdminGroupName', ''); + setFieldValue('stewards', ''); + if (value && value.environmentUri) { + setFieldValue('environment', value); + fetchGroups(value.environmentUri).catch((e) => + dispatch({ + type: SET_ERROR, + error: e.message + }) + ); + } else { + setFieldValue('environment', ''); + setGroupOptions([]); + } }} - select - value={values.environment} - variant="outlined" - > - {environmentOptions.map((environment) => ( - - {environment.label} - - ))} - + renderInput={(params) => ( + + )} + /> { label="Region" name="region" value={ - values.environment + values.environment && values.environment.region ? values.environment.region : '' } @@ -483,7 +490,8 @@ const DatasetCreateForm = (props) => { label="Organization" name="organization" value={ - values.environment + values.environment && + values.environment.organization ? values.environment.organization.label : '' } @@ -494,45 +502,105 @@ const DatasetCreateForm = (props) => { - option)} + onChange={(event, value) => { + if (value && value.value) { + setFieldValue( + 'SamlAdminGroupName', + value.value + ); + } else { + setFieldValue('SamlAdminGroupName', ''); + } + }} + inputValue={values.SamlAdminGroupName} + renderInput={(params) => ( + + {groupOptions.length > 0 ? ( + + ) : ( + + )} + )} - helperText={ - touched.SamlGroupName && errors.SamlGroupName - } - label="Owners" - name="SamlGroupName" - onChange={handleChange} - select - value={values.SamlGroupName} - variant="outlined" - > - {groupOptions.map((group) => ( - - {group.label} - - ))} - + /> option.value)} + disablePortal + options={groupOptions.map((option) => option)} onChange={(event, value) => { - setFieldValue('stewards', value); + if (value && value.value) { + setFieldValue('stewards', value.value); + } else { + setFieldValue('stewards', ''); + } }} - renderInput={(renderParams) => ( - + inputValue={values.stewards} + renderInput={(params) => ( + + {groupOptions.length > 0 ? ( + + ) : ( + + )} + )} /> diff --git a/frontend/src/modules/S3_Datasets/views/DatasetImportForm.js b/frontend/src/modules/S3_Datasets/views/DatasetImportForm.js index c73a7cfbc..21454003f 100644 --- a/frontend/src/modules/S3_Datasets/views/DatasetImportForm.js +++ b/frontend/src/modules/S3_Datasets/views/DatasetImportForm.js @@ -119,7 +119,7 @@ const DatasetImportForm = (props) => { environmentUri: values.environment.environmentUri, owner: '', label: values.label, - SamlAdminGroupName: values.SamlGroupName, + SamlAdminGroupName: values.SamlAdminGroupName, tags: values.tags, description: values.description, topics: values.topics ? values.topics.map((t) => t.value) : [], @@ -223,7 +223,7 @@ const DatasetImportForm = (props) => { environment: '', businessOwnerEmail: '', businessOwnerDelegationEmails: [], - SamlGroupName: '', + SamlAdminGroupName: '', stewards: '', tags: [], topics: [], @@ -238,7 +238,7 @@ const DatasetImportForm = (props) => { .max(255) .required('*Dataset name is required'), description: Yup.string().max(5000), - SamlGroupName: Yup.string() + SamlAdminGroupName: Yup.string() .max(255) .required('*Team is required'), topics: isFeatureEnabled('datasets_base', 'topics_dropdown') @@ -442,38 +442,45 @@ const DatasetImportForm = (props) => { - { - setFieldValue('SamlGroupName', ''); - fetchGroups( - event.target.value.environmentUri - ).catch((e) => - dispatch({ type: SET_ERROR, error: e.message }) - ); - setFieldValue('environment', event.target.value); + option)} + onChange={(event, value) => { + setFieldValue('SamlAdminGroupName', ''); + setFieldValue('stewards', ''); + if (value && value.environmentUri) { + setFieldValue('environment', value); + fetchGroups(value.environmentUri).catch((e) => + dispatch({ + type: SET_ERROR, + error: e.message + }) + ); + } else { + setFieldValue('environment', ''); + setGroupOptions([]); + } }} - select - value={values.environment} - variant="outlined" - > - {environmentOptions.map((environment) => ( - - {environment.label} - - ))} - + renderInput={(params) => ( + + )} + /> { label="Region" name="region" value={ - values.environment + values.environment && values.environment.region ? values.environment.region : '' } @@ -496,7 +503,8 @@ const DatasetImportForm = (props) => { label="Organization" name="organization" value={ - values.environment + values.environment && + values.environment.organization ? values.environment.organization.label : '' } @@ -558,45 +566,105 @@ const DatasetImportForm = (props) => { - option)} + onChange={(event, value) => { + if (value && value.value) { + setFieldValue( + 'SamlAdminGroupName', + value.value + ); + } else { + setFieldValue('SamlAdminGroupName', ''); + } + }} + inputValue={values.SamlAdminGroupName} + renderInput={(params) => ( + + {groupOptions.length > 0 ? ( + + ) : ( + + )} + )} - helperText={ - touched.SamlGroupName && errors.SamlGroupName - } - label="Team" - name="SamlGroupName" - onChange={handleChange} - select - value={values.SamlGroupName} - variant="outlined" - > - {groupOptions.map((group) => ( - - {group.label} - - ))} - + /> option.value)} + disablePortal + options={groupOptions.map((option) => option)} onChange={(event, value) => { - setFieldValue('stewards', value); + if (value && value.value) { + setFieldValue('stewards', value.value); + } else { + setFieldValue('stewards', ''); + } }} - renderInput={(renderParams) => ( - + inputValue={values.stewards} + renderInput={(params) => ( + + {groupOptions.length > 0 ? ( + + ) : ( + + )} + )} /> diff --git a/frontend/src/modules/Shared/EnvironmentGroupSelect/EnvironmentTeamDatasetsDropdown.js b/frontend/src/modules/Shared/EnvironmentGroupSelect/EnvironmentTeamDatasetsDropdown.js new file mode 100644 index 000000000..515182243 --- /dev/null +++ b/frontend/src/modules/Shared/EnvironmentGroupSelect/EnvironmentTeamDatasetsDropdown.js @@ -0,0 +1,282 @@ +import { + Autocomplete, + Box, + Card, + CardContent, + CardHeader, + CircularProgress, + TextField +} from '@mui/material'; +import React, { useCallback, useEffect, useState } from 'react'; +import { Defaults } from 'design'; +import { SET_ERROR, useDispatch } from 'globalErrors'; +import { + listEnvironmentGroups, + listValidEnvironments, + listS3DatasetsOwnedByEnvGroup, + useClient +} from 'services'; + +import PropTypes from 'prop-types'; + +export const EnvironmentTeamDatasetsDropdown = (props) => { + const { setFieldValue, handleChange, values, touched, errors } = props; + const dispatch = useDispatch(); + const client = useClient(); + const [loading, setLoading] = useState(true); + const [groupOptions, setGroupOptions] = useState([]); + const [environmentOptions, setEnvironmentOptions] = useState([]); + const [currentEnv, setCurrentEnv] = useState(''); + const [datasetOptions, setDatasetOptions] = useState([]); + const fetchEnvironments = useCallback(async () => { + setLoading(true); + const response = await client.query( + listValidEnvironments({ filter: Defaults.SelectListFilter }) + ); + if (!response.errors) { + setEnvironmentOptions( + response.data.listValidEnvironments.nodes.map((e) => ({ + ...e, + value: e.environmentUri, + label: e.label + })) + ); + } else { + dispatch({ type: SET_ERROR, error: response.errors[0].message }); + } + setLoading(false); + }, [client, dispatch]); + const fetchGroups = async (environmentUri) => { + setCurrentEnv(environmentUri); + try { + const response = await client.query( + listEnvironmentGroups({ + filter: Defaults.SelectListFilter, + environmentUri + }) + ); + if (!response.errors) { + setGroupOptions( + response.data.listEnvironmentGroups.nodes.map((g) => ({ + value: g.groupUri, + label: g.groupUri + })) + ); + } else { + dispatch({ type: SET_ERROR, error: response.errors[0].message }); + } + } catch (e) { + dispatch({ type: SET_ERROR, error: e.message }); + } + }; + const fetchDatasets = async (groupUri) => { + let ownedDatasets = []; + try { + const response = await client.query( + listS3DatasetsOwnedByEnvGroup({ + filter: Defaults.SelectListFilter, + environmentUri: currentEnv, + groupUri: groupUri + }) + ); + if (!response.errors) { + ownedDatasets = response.data.listS3DatasetsOwnedByEnvGroup.nodes?.map( + (dataset) => ({ + value: dataset.datasetUri, + label: dataset.label + }) + ); + } else { + dispatch({ type: SET_ERROR, error: response.errors[0].message }); + } + } catch (e) { + dispatch({ type: SET_ERROR, error: e.message }); + } + setDatasetOptions(ownedDatasets); + }; + + useEffect(() => { + if (client) { + fetchEnvironments().catch((e) => + dispatch({ type: SET_ERROR, error: e.message }) + ); + } + }, [client, dispatch, fetchEnvironments]); + + if (loading) { + return ; + } + + return ( + + + + + option)} + onChange={(event, value) => { + setFieldValue('SamlAdminGroupName', ''); + setFieldValue('dataset', ''); + if (value && value.environmentUri) { + setFieldValue('environment', value); + fetchGroups(value.environmentUri).catch((e) => + dispatch({ + type: SET_ERROR, + error: e.message + }) + ); + } else { + setFieldValue('environment', ''); + setGroupOptions([]); + setDatasetOptions([]); + } + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + option)} + onChange={(event, value) => { + setFieldValue('dataset', ''); + if (value && value.value) { + setFieldValue('SamlAdminGroupName', value.value); + fetchDatasets(value).catch((e) => + dispatch({ type: SET_ERROR, error: e.message }) + ); + } else { + setFieldValue('SamlAdminGroupName', ''); + setDatasetOptions([]); + } + }} + inputValue={values.SamlAdminGroupName} + renderInput={(params) => ( + + {groupOptions.length > 0 ? ( + + ) : ( + + )} + + )} + /> + + + option)} + onChange={(event, value) => { + if (value && value.value) { + setFieldValue('dataset', value.value); + } else { + setFieldValue('dataset', ''); + } + }} + inputValue={values.dataset} + renderInput={(params) => ( + + {datasetOptions.length > 0 ? ( + + ) : ( + + )} + + )} + /> + + + + ); +}; + +EnvironmentTeamDatasetsDropdown.propTypes = { + setFieldValue: PropTypes.func.isRequired, + handleChange: PropTypes.func.isRequired, + values: PropTypes.object.isRequired, + touched: PropTypes.object.isRequired, + errors: PropTypes.object.isRequired +}; diff --git a/frontend/src/modules/Shared/EnvironmentGroupSelect/EnvironmentTeamDropdown.js b/frontend/src/modules/Shared/EnvironmentGroupSelect/EnvironmentTeamDropdown.js new file mode 100644 index 000000000..6862c8baf --- /dev/null +++ b/frontend/src/modules/Shared/EnvironmentGroupSelect/EnvironmentTeamDropdown.js @@ -0,0 +1,205 @@ +import { + Autocomplete, + Box, + Card, + CardContent, + CardHeader, + CircularProgress, + TextField +} from '@mui/material'; +import React, { useCallback, useEffect, useState } from 'react'; +import { Defaults } from 'design'; +import { SET_ERROR, useDispatch } from 'globalErrors'; +import { + listEnvironmentGroups, + listValidEnvironments, + useClient +} from 'services'; + +import PropTypes from 'prop-types'; + +export const EnvironmentTeamDropdown = (props) => { + const { setFieldValue, handleChange, values, touched, errors } = props; + const dispatch = useDispatch(); + const client = useClient(); + const [loading, setLoading] = useState(true); + const [groupOptions, setGroupOptions] = useState([]); + const [environmentOptions, setEnvironmentOptions] = useState([]); + const fetchEnvironments = useCallback(async () => { + setLoading(true); + const response = await client.query( + listValidEnvironments({ filter: Defaults.selectListFilter }) + ); + if (!response.errors) { + setEnvironmentOptions( + response.data.listValidEnvironments.nodes.map((e) => ({ + ...e, + value: e.environmentUri, + label: e.label + })) + ); + } else { + dispatch({ type: SET_ERROR, error: response.errors[0].message }); + } + setLoading(false); + }, [client, dispatch]); + const fetchGroups = async (environmentUri) => { + try { + const response = await client.query( + listEnvironmentGroups({ + filter: Defaults.selectListFilter, + environmentUri + }) + ); + if (!response.errors) { + setGroupOptions( + response.data.listEnvironmentGroups.nodes.map((g) => ({ + value: g.groupUri, + label: g.groupUri + })) + ); + } else { + dispatch({ type: SET_ERROR, error: response.errors[0].message }); + } + } catch (e) { + dispatch({ type: SET_ERROR, error: e.message }); + } + }; + useEffect(() => { + if (client) { + fetchEnvironments().catch((e) => + dispatch({ type: SET_ERROR, error: e.message }) + ); + } + }, [client, dispatch, fetchEnvironments]); + + if (loading) { + return ; + } + + return ( + + + + + option)} + onChange={(event, value) => { + setFieldValue('SamlAdminGroupName', ''); + if (value && value.environmentUri) { + setFieldValue('environment', value); + fetchGroups(value.environmentUri).catch((e) => + dispatch({ + type: SET_ERROR, + error: e.message + }) + ); + } else { + setFieldValue('environment', ''); + setGroupOptions([]); + } + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + option)} + onChange={(event, value) => { + if (value && value.value) { + setFieldValue('SamlAdminGroupName', value.value); + } else { + setFieldValue('SamlAdminGroupName', ''); + } + }} + inputValue={values.SamlAdminGroupName} + renderInput={(params) => ( + + {groupOptions.length > 0 ? ( + + ) : ( + + )} + + )} + /> + + + + ); +}; + +EnvironmentTeamDropdown.propTypes = { + setFieldValue: PropTypes.func.isRequired, + handleChange: PropTypes.func.isRequired, + values: PropTypes.object.isRequired, + touched: PropTypes.object.isRequired, + errors: PropTypes.object.isRequired +}; diff --git a/frontend/src/modules/Shared/EnvironmentGroupSelect/index.js b/frontend/src/modules/Shared/EnvironmentGroupSelect/index.js new file mode 100644 index 000000000..c89c2caf3 --- /dev/null +++ b/frontend/src/modules/Shared/EnvironmentGroupSelect/index.js @@ -0,0 +1,2 @@ +export * from './EnvironmentTeamDatasetsDropdown'; +export * from './EnvironmentTeamDropdown'; diff --git a/frontend/src/modules/Shared/index.js b/frontend/src/modules/Shared/index.js index ccffdd8d7..04647f029 100644 --- a/frontend/src/modules/Shared/index.js +++ b/frontend/src/modules/Shared/index.js @@ -1,3 +1,4 @@ export * from './Comments'; +export * from './EnvironmentGroupSelect'; export * from './KeyValueTags'; export * from './Stack';