Skip to content
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

Web sockets #29

Merged
merged 11 commits into from
Apr 6, 2023
Prev Previous commit
Minor CSS changes
  • Loading branch information
mjhuff committed Apr 6, 2023
commit 30c4b75215d3d3ead7f8f9359488b65bc85366f7
58 changes: 32 additions & 26 deletions client/components/BucketSelect.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,50 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { updateSelectedBucket } from '../slice';
import LoadingButton from './LoadingButton'
import LoadingButton from './LoadingButton';

const BucketSelect = (props) => {
const dispatch = useDispatch();
const { bucketLoading, bucketOptions } = useSelector((state) => state.GUI[props.remote]);
const { bucketLoading, bucketOptions } = useSelector(
(state) => state.GUI[props.remote]
);
const options = [];
options.push(<option value="">Select Bucket</option>);
options.push(
<option key={Date.now() + Math.random()} value="">
Select Bucket
</option>
);
bucketOptions.forEach((bucket) => {
options.push(
<option key={bucket} value={bucket}>
<option key={Date.now() + Math.random()} value={bucket}>
{bucket}
</option>
);
});
return (
<>
{bucketLoading ?
<LoadingButton></LoadingButton> :
<div>
<label htmlFor="buckets" for="buckets" class="text-xs scale-75">
Choose a bucket:
</label>
<select
class="inline-flex w-full justify-center gap-x-1.5 rounded-md bg-white px-3 py-2 text-sm text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
name="buckets"
onChange={(e) => {
const payload = {
bucket: e.target.value,
remote: props.remote
};
dispatch(updateSelectedBucket(payload));
}}
>
{options}
</select>
</div>
}

{bucketLoading ? (
<LoadingButton></LoadingButton>
) : (
<div>
<label htmlFor="buckets" className="text-xs scale-75">
Choose a bucket:
</label>
<select
className="inline-flex w-full justify-center gap-x-1.5 rounded-md bg-white px-3 py-2 text-sm text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
name="buckets"
onChange={(e) => {
const payload = {
bucket: e.target.value,
remote: props.remote
};
dispatch(updateSelectedBucket(payload));
}}
>
{options}
</select>
</div>
)}
</>
);
};
Expand Down
182 changes: 82 additions & 100 deletions client/components/Destination.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import {
} from '../slice';
import { useDispatch, useSelector } from 'react-redux';
import BucketSelect from './BucketSelect';
import aws_edited from '../public/aws_edited.png'
import cloudflare_edited from '../public/cloudflare_edited.png'
import aws_edited from '../public/aws_edited.png';
import cloudflare_edited from '../public/cloudflare_edited.png';
import MigrationButton from './MigrationButton';



const Destination = (props) => {
const dispatch = useDispatch();
const { origin, destination } = useSelector((state) => state.GUI);
Expand All @@ -36,7 +34,7 @@ const Destination = (props) => {

useEffect(() => {
if (destination.accessId && destination.secretKey) {
dispatch(updateDestinationBucketLoading(true))
dispatch(updateDestinationBucketLoading(true));
if (destination.name === 'Cloudflare' && !destination.accountId) return;
(async () => {
const res = await fetch('/listBuckets', {
Expand All @@ -52,8 +50,7 @@ const Destination = (props) => {
})
});
const data = await res.json();
console.log(data)
dispatch(updateDestinationBuckets(data))
dispatch(updateDestinationBuckets(data));
dispatch(updateDestinationBucketLoading(false));
})();
}
Expand All @@ -65,114 +62,99 @@ const Destination = (props) => {
]);

return (
<>
<div>
<div class="relative z-0 w-4/5 mb-6 group text-center text-lg">
{!destination.name ?
null :
<img src={destination.name === 'AWS' ?
aws_edited :
cloudflare_edited} >
</img>
}
Destination
{props.name && (
<>
: {props.name} {props.service}
</>
)}
</div>
<div>
<div className="flex flex-col justify-items-center items-center relative z-0 w-4/5 mb-6 group text-center text-lg">
{!props.name ? null : (
<img
src={props.name === 'AWS' ? aws_edited : cloudflare_edited}
></img>
)}
Destination
{props.name && (
<>
: {props.name} {props.service}
</>
)}
</div>

<div class="relative z-0 w-4/5 mb-6 group">
<input
type="key"
class="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-800 appearance-none focus:outline-none focus:ring-0 focus:border-blue-600 peer"
placeholder=" "
required
name="destAccessId"
id="destinationAccessId"
onChange={(e) => {
const newState = props.accessIdHandler(e, origin, destination);
dispatch(updateDestinationAccessId(newState));
}}
></input>
<label
htmlFor="destAccessId"
for="destinationAccessId"
class="peer-focus:font-medium absolute text-base duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] peer-focus:left-0 peer-focus:text-blue-600 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6"
>
Access ID{destination.accessId ? <>{' \u2705'}</> : <></>}
</label>
</div>
<div className="relative z-0 w-4/5 mb-6 group">
<input
type="key"
className="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-800 appearance-none focus:outline-none focus:ring-0 focus:border-blue-600 peer"
placeholder=" "
required
name="destAccessId"
id="destinationAccessId"
onChange={(e) => {
const newState = props.accessIdHandler(e, origin, destination);
dispatch(updateDestinationAccessId(newState));
}}
></input>
<label
htmlFor="destAccessId"
className="peer-focus:font-medium absolute text-base duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] peer-focus:left-0 peer-focus:text-blue-600 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6"
>
Access ID{destination.accessId ? <>{' \u2705'}</> : <></>}
</label>
</div>

<div className="block relative z-0 w-4/5 mb-6 group">
<input
className="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-800 appearance-none focus:outline-none focus:ring-0 focus:border-blue-600 peer"
placeholder=" "
required
type="key"
name="destSecretKey"
id="destSecretKey"
onChange={(e) => {
const newState = props.secretKeyHandler(e, origin, destination);
dispatch(updateDestinationSecretKey(newState));
}}
></input>

<label
htmlFor="destSecretKey"
className="peer-focus:font-medium absolute text-base duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] peer-focus:left-0 peer-focus:text-blue-600 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6"
>
Secret Key{destination.secretKey ? <>{' \u2705'}</> : <></>}
</label>
</div>

<div class="block relative z-0 w-4/5 mb-6 group">
{props.name === 'Cloudflare' && (
<div className="relative z-0 w-4/5 mb-6 group">
<input
class="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-800 appearance-none focus:outline-none focus:ring-0 focus:border-blue-600 peer"
className="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-800 appearance-none focus:outline-none focus:ring-0 focus:border-blue-600 peer"
placeholder=" "
required
type="key"
name="destSecretKey"
id="destSecretKey"
type="id"
id="destAccountId"
name="destAccountId"
onChange={(e) => {
const newState = props.secretKeyHandler(e, origin, destination);
dispatch(updateDestinationSecretKey(newState));
const newState = props.accountIdHandler(
e,
origin,
destination,
props.remoteType
);
dispatch(updateAccountId(newState));
}}
></input>

<label
htmlFor="destSecretKey"
for="destSecretKey"
class="peer-focus:font-medium absolute text-base duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] peer-focus:left-0 peer-focus:text-blue-600 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6"
htmlFor="destAccountId"
className="peer-focus:font-medium absolute text-base duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] peer-focus:left-0 peer-focus:text-blue-600 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6"
>
Secret Key{destination.secretKey ? <>{' \u2705'}</> : <></>}
Account ID {destination.accountId.length > 1 && <>{'\u2705'}</>}
</label>
</div>

{props.name === 'Cloudflare' && (
<div class="relative z-0 w-4/5 mb-6 group">
<input
class="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-800 appearance-none focus:outline-none focus:ring-0 focus:border-blue-600 peer"
placeholder=" "
required
type="id"
id="destAccountId"
name="destAccountId"
onChange={(e) => {
const newState = props.accountIdHandler(
e,
origin,
destination,
props.remoteType
);
dispatch(updateAccountId(newState));
}}
></input>
<label
for="destAccountId"
class="peer-focus:font-medium absolute text-base duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] peer-focus:left-0 peer-focus:text-blue-600 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6"
>
Account ID {destination.accountId.length > 1 && <>{'\u2705'}</>}
</label>
</div>
)}
<div className="relative z-0 w-4/5 mb-6 group">{bucketSelect}</div>
<div className="relative z-0 w-4/5 mb-6 group">
{origin.selectedBucket && destination.selectedBucket && (
<MigrationButton></MigrationButton>
)}
<div class="relative z-0 w-4/5 mb-6 group">{bucketSelect}</div>
<div class="relative z-0 w-4/5 mb-6 group">

{origin.selectedBucket && destination.selectedBucket && (
<MigrationButton></MigrationButton>
)}
</div>
</div>
</>
</div>
);
};

export default Destination;


{/* <div class="relative z-0 w-4/5 mb-6 group">

{origin.selectedBucket && destination.selectedBucket && (
<MigrationButton></MigrationButton>
)}
</div> */}
41 changes: 27 additions & 14 deletions client/components/LoadingButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,31 @@ import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

const LoadingButton = () => {
return (
<button type="button" disabled>
<svg
className="animate-spin -ml-1 mr-3 h-5 w-5 text-black"
xmlns="https://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
...Loading Buckets
</button>
);
};

return (

<button type="button" className="bg-gradient-to-br from-cyan-100 to-stone-50" disabled>
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-black" xmlns="https://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
...Loading Buckets
</button>

)
}

export default LoadingButton
export default LoadingButton;
4 changes: 2 additions & 2 deletions client/components/MigrationButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ const StartMigrationButton = () => {

return (
<>
<div className="flex justify-center items-center">
<div className="flex justify-center items-center mt-10">
<button
class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
onClick={() => dispatch(migrationStatusChange(true))}
>
Start Migration
Expand Down
Loading