feat: persist selected environment inside collection

This commit is contained in:
Anoop M D 2022-10-16 18:51:02 +05:30
parent ecc2252e84
commit 42a60a3372
5 changed files with 82 additions and 13 deletions

View File

@ -1,17 +1,24 @@
import React, { useRef, forwardRef, useState } from 'react';
import find from 'lodash/find';
import Dropdown from 'components/Dropdown';
import { IconAdjustmentsHorizontal, IconCaretDown } from '@tabler/icons';
import { selectEnvironment } from 'providers/ReduxStore/slices/collections/actions';
import { IconSettings, IconCaretDown, IconDatabase } from '@tabler/icons';
import EnvironmentSettings from "../EnvironmentSettings";
import toast from 'react-hot-toast';
import { useDispatch } from 'react-redux';
import StyledWrapper from './StyledWrapper';
const EnvironmentSelector = ({collection}) => {
const dispatch = useDispatch();
const dropdownTippyRef = useRef();
const [openSettingsModal, setOpenSettingsModal] = useState(false);
const { environments, activeEnvironmentUid } = collection;
const activeEnvironment = activeEnvironmentUid ? find(environments, e => e.uid === activeEnvironmentUid) : null;
const Icon = forwardRef((props, ref) => {
return (
<div ref={ref} className="current-enviroment flex items-center justify-center pl-3 pr-2 py-1 select-none">
No Environment
{activeEnvironment ? activeEnvironment.name : 'No Environment'}
<IconCaretDown className="caret" size={14} strokeWidth={2}/>
</div>
);
@ -19,28 +26,39 @@ const EnvironmentSelector = ({collection}) => {
const onDropdownCreate = (ref) => dropdownTippyRef.current = ref;
const onSelect = (environment) => {
dispatch(selectEnvironment(environment ? environment.uid : null, collection.uid))
.then(() => {
if(environment) {
toast.success(`Environment changed to ${environment.name}`);
} else {
toast.success(`No Environments are active now`);
}
})
.catch((err) => console.log(err) && toast.error("An error occured while selecting the environment"));
};
return (
<StyledWrapper>
<div className="flex items-center cursor-pointer environment-selector">
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement='bottom-end'>
{(environments && environments.length) ? environments.map((e) => (
<div className="dropdown-item" key={e.uid} onClick={() => {
onSelect(e);
dropdownTippyRef.current.hide();
}}>
<IconDatabase size={18} strokeWidth={1.5}/> <span className="ml-2">{e.name}</span>
</div>
)) : null}
<div className="dropdown-item" onClick={() => {
dropdownTippyRef.current.hide();
}}>
<span>QA1</span>
</div>
<div className="dropdown-item" onClick={() => {
dropdownTippyRef.current.hide();
}}>
<span>STG</span>
</div>
<div className="dropdown-item" onClick={() => {
dropdownTippyRef.current.hide();
onSelect(null);
}}>
<span>No Environment</span>
</div>
<div className="dropdown-item" style={{borderTop: 'solid 1px #e7e7e7'}} onClick={() => setOpenSettingsModal(true)}>
<div className="pr-2 text-gray-600">
<IconAdjustmentsHorizontal size={18} strokeWidth={1.5}/>
<IconSettings size={18} strokeWidth={1.5}/>
</div>
<span>Settings</span>
</div>

View File

@ -36,6 +36,7 @@ import {
renameEnvironment as _renameEnvironment,
deleteEnvironment as _deleteEnvironment,
saveEnvironment as _saveEnvironment,
selectEnvironment as _selectEnvironment,
createCollection as _createCollection,
renameCollection as _renameCollection,
deleteCollection as _deleteCollection,
@ -719,6 +720,34 @@ export const saveEnvironment = (variables, environmentUid, collectionUid) => (di
});
};
export const selectEnvironment = (environmentUid, collectionUid) => (dispatch, getState) => {
return new Promise((resolve, reject) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if(!collection) {
return reject(new Error('Collection not found'));
}
const collectionCopy = cloneDeep(collection);
if(environmentUid) {
const environment = findEnvironmentInCollection(collectionCopy, environmentUid);
if(!environment) {
return reject(new Error('Environment not found'));
}
}
collectionCopy.activeEnvironmentUid = environmentUid;
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
collectionSchema
.validate(collectionToSave)
.then(() => saveCollectionToIdb(window.__idb, collectionToSave))
.then(() => dispatch(_selectEnvironment({environmentUid, collectionUid})))
.then(resolve)
.catch(reject);
});
};
export const removeLocalCollection = (collectionUid) => (dispatch, getState) => {
return new Promise((resolve, reject) => {
const state = getState();

View File

@ -115,6 +115,22 @@ export const collectionsSlice = createSlice({
}
}
},
selectEnvironment: (state, action) => {
const { environmentUid, collectionUid } = action.payload;
const collection = findCollectionByUid(state.collections, collectionUid);
if(collection) {
if(environmentUid) {
const environment = findEnvironmentInCollection(collection, environmentUid);
if(environment) {
collection.activeEnvironmentUid = environmentUid;
}
} else {
collection.activeEnvironmentUid = null;
}
}
},
newItem: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
@ -740,6 +756,7 @@ export const {
renameEnvironment,
deleteEnvironment,
saveEnvironment,
selectEnvironment,
newItem,
deleteItem,
renameItem,

View File

@ -237,6 +237,7 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => {
collectionToSave.name = collection.name;
collectionToSave.uid = collection.uid;
collectionToSave.items = [];
collectionToSave.activeEnvironmentUid = collection.activeEnvironmentUid;
collectionToSave.environments = collection.environments || [];
copyItems(collection.items, collectionToSave.items);

View File

@ -70,6 +70,10 @@ const collectionSchema = Yup.object({
.max(50, 'name must be 100 characters or less')
.required('name is required'),
items: Yup.array().of(itemSchema),
activeEnvironmentUid: Yup.string()
.length(21, 'activeEnvironmentUid must be 21 characters in length')
.matches(/^[a-zA-Z0-9]*$/, 'uid must be alphanumeric')
.nullable(),
environments: Yup.array().of(environmentSchema),
pathname: Yup.string().max(1024, 'pathname cannot be more than 1024 characters').nullable()
}).noUnknown(true).strict();