Skip to content

Commit

Permalink
Implement basic functionality of testbed (#12)
Browse files Browse the repository at this point in the history
* Implement testbed

---------

Co-authored-by: Maximilian Pohl <[email protected]>
Co-authored-by: Marlon Baeten <[email protected]>
  • Loading branch information
3 people authored Jan 30, 2023
1 parent de6cc07 commit 747ec6e
Show file tree
Hide file tree
Showing 35 changed files with 2,291 additions and 993 deletions.
24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@
},
"dependencies": {
"buffer": "^6.0.3",
"luxon": "^3.1.0",
"luxon": "^3.2.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router5": "^8.0.1",
"router5": "^8.0.1",
"router5-plugin-browser": "^8.0.1"
},
"devDependencies": {
"@playwright/test": "^1.27.0",
"@types/luxon": "^3.1.0",
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"@vitejs/plugin-react": "^2.1.0",
"eslint": "^8.25.0",
"eslint-plugin-react": "^7.31.10",
"typescript": "^4.8.4",
"vite": "^3.1.8"
"@playwright/test": "^1.30.0",
"@types/luxon": "^3.2.0",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@typescript-eslint/eslint-plugin": "^5.49.0",
"@typescript-eslint/parser": "^5.49.0",
"@vitejs/plugin-react": "^3.0.1",
"eslint": "^8.33.0",
"eslint-plugin-react": "^7.32.2",
"typescript": "^4.9.4",
"vite": "^4.0.4"
}
}
26 changes: 25 additions & 1 deletion src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import CasParents from './CasParents';
import CasRepository from './CasRepository';
import Loader from './Loader';
import Login from './Login';
import TestBed from './TestBed';
import TestBedDelCa from './TestBedDelCa';
import TestBedAddPub from './TestBedAddPub';
import TestBedDelPub from './TestBedDelPub';
import Onboarding from './Onboarding';

export default function App() {
const { route } = useRoute();
Expand All @@ -17,6 +22,10 @@ export default function App() {
return <Login />;
}

if (route.name === 'onboarding') {
return <Onboarding />;
}

if (route.name.startsWith('cas.parents')) {
return <CasParents />;
}
Expand All @@ -29,6 +38,21 @@ export default function App() {
return <Cas />;
}

if (route.name == 'testbed.del_ca') {
return <TestBedDelCa />;
}

if (route.name == 'testbed.add_pub') {
return <TestBedAddPub />;
}

if (route.name == 'testbed.del_pub') {
return <TestBedDelPub />;
}

if (route.name.startsWith('testbed')) {
return <TestBed />;
}

return null;
}

36 changes: 36 additions & 0 deletions src/components/CopyDownloadButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import clipboard from '../img/clipboard.svg?url';
import download from '../img/download.svg?url';
import useTranslations from '../hooks/useTranslations';
import {Notification, NotificationType} from '../core/types';

export interface CopyDownloadButtonProps {
xml: string,
name: string,
setNotification: (notification: Notification) => void,
}

export default function CopyDownloadButton({xml, name, setNotification}: CopyDownloadButtonProps) {
const t = useTranslations();

const onCopy = () => {
navigator.clipboard.writeText(xml);

setNotification({
type: NotificationType.success,
message: t.common.copySuccess
});
};

return (
<>
<button className="button large icon" type="button" title={t.common.copy} onClick={onCopy}>
<img src={clipboard} alt={t.common.copy}/>
</button>
<a className="button large icon" title={t.common.download}
href={`data:application/xml;base64,${btoa(xml)}`} download={`${name}.xml`}>
<img src={download} alt={t.common.download}/>
</a>
</>
);
}
23 changes: 23 additions & 0 deletions src/components/NotificationElem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { Notification } from '../core/types';
import useNavigation from '../hooks/useNavigation';

interface NotificationProps {
notification: Notification,
}

export default function NotificationElem({ notification }: NotificationProps) {
const navigate = useNavigation();

return (
<div className={`notification ${ notification.type }`}>
<button className="close" onClick={() => navigate({ notification: 'clear' })}>
&times;
</button>
<span>
{notification.message}
</span>
</div>
);
}

43 changes: 43 additions & 0 deletions src/components/Onboarding.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { FormEvent, useState } from 'react';
import Layout from './Layout';
import welcome from '../img/welcome.svg?url';
import useTranslations from '../hooks/useTranslations';
import useNavigation from '../hooks/useNavigation';

export default function Onboarding() {
const navigate = useNavigation();
const [name, setName] = useState('');
const t = useTranslations();

const submit = (e: FormEvent) => {
e.preventDefault();
navigate({ name });
};

return (
<Layout>
<form method="POST" onSubmit={submit} className="center-form">
<div>
<img src={welcome} alt={t.common.copy} />
<h2>{t.onboarding.welcome}</h2>
<div dangerouslySetInnerHTML={{ __html: t.onboarding.welcomeHtml }} />
</div>
<div>
<label htmlFor="token required">CA {t.caDetails.handle}</label>
<input
name="name"
type="test"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div>
<button type="submit" className="button">
{t.onboarding.addCAForm.confirm}
</button>
</div>
</form>
</Layout>
);
}
15 changes: 15 additions & 0 deletions src/components/TestBed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import Layout from './Layout';
import TestBedHeader from './TestBedHeader';
import TestBedAddCaForm from './forms/TestBedAddCaForm';

export default function TestBed() {
return (
<Layout>
<div className="testbed">
<TestBedHeader />
<TestBedAddCaForm />
</div>
</Layout>
);
}
15 changes: 15 additions & 0 deletions src/components/TestBedAddPub.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import Layout from './Layout';
import TestBedHeader from './TestBedHeader';
import TestBedAddPubForm from './forms/TestBedAddPubForm';

export default function TestBedAddPub() {
return (
<Layout>
<div className="testbed">
<TestBedHeader />
<TestBedAddPubForm />
</div>
</Layout>
);
}
15 changes: 15 additions & 0 deletions src/components/TestBedDelCa.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import Layout from './Layout';
import TestBedHeader from './TestBedHeader';
import TestBedDelCaForm from './forms/TestBedDelCaForm';

export default function TestBedDelCa() {
return (
<Layout>
<div className="testbed">
<TestBedHeader />
<TestBedDelCaForm />
</div>
</Layout>
);
}
15 changes: 15 additions & 0 deletions src/components/TestBedDelPub.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import Layout from './Layout';
import TestBedHeader from './TestBedHeader';
import TestBedDelPubForm from './forms/TestBedDelPubForm';

export default function TestBedDelPub() {
return (
<Layout>
<div className="testbed">
<TestBedHeader />
<TestBedDelPubForm />
</div>
</Layout>
);
}
56 changes: 56 additions & 0 deletions src/components/TestBedHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import welcome from '../img/welcome.svg?url';
import useTranslations from '../hooks/useTranslations';
import { Link } from 'react-router5';

export default function TestBedHeader() {
const t = useTranslations();

return (
<>
<div>
<img src={welcome} alt={t.common.copy} />
<h2>{t.testbed.welcome}</h2>
</div>
<div>
<h3>{t.testbed.disclaimer.heading}</h3>
<p dangerouslySetInnerHTML={{ __html: t.testbed.disclaimer.body }}></p>
<h3>{t.testbed.rpconfighelp.heading}</h3>
<p
dangerouslySetInnerHTML={{
__html: t.testbed.rpconfighelp.body.replace(
'{tallink}',
'/ta/ta.tal'
),
}}
></p>
<h3>{t.testbed.regunreg.heading}</h3>
<p dangerouslySetInnerHTML={{ __html: t.testbed.regunreg.body }}></p>
</div>
<div>
<ul className="tabs">
<li>
<Link routeName="testbed" activeStrict>
{t.testbed.addChild.heading}
</Link>
</li>
<li>
<Link routeName="testbed.del_ca">
{t.testbed.removeChild.heading}
</Link>
</li>
<li>
<Link routeName="testbed.add_pub">
{t.testbed.addPublisher.heading}
</Link>
</li>
<li>
<Link routeName="testbed.del_pub">
{t.testbed.removePublisher.heading}
</Link>
</li>
</ul>
</div>
</>
);
}
16 changes: 4 additions & 12 deletions src/components/forms/ParentModal.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react';
import useTranslations from '../../hooks/useTranslations';
import Modal from './Modal';
import clipboard from '../../img/clipboard.svg?url';
import download from '../../img/download.svg?url';
import upload from '../../img/upload.svg?url';
import useParantActions from '../../hooks/useParentActions';
import useParentActions from '../../hooks/useParentActions';
import NotificationPopup from '../NotificationPopup';
import CopyDownloadButton from '../CopyDownloadButton';

export default function ParentModal() {
const t = useTranslations();
Expand All @@ -15,15 +14,13 @@ export default function ParentModal() {
name,
setName,
request,
dataUrl,
setRequest,
response,
setResponse,
onSubmit,
onClose,
onCopy,
handleUpload,
} = useParantActions();
} = useParentActions();

return (
<Modal onClose={onClose}>
Expand All @@ -39,12 +36,7 @@ export default function ParentModal() {
<label>{t.caDetails.parentsTab.request}</label>
<textarea name="request" readOnly value={request} id="request" onChange={(e) => setRequest(e.target.value)} />
<div>
<button className="button large icon" type="button" title={t.common.copy} onClick={onCopy}>
<img src={clipboard} alt={t.common.copy} />
</button>
<a className="button large icon" title={t.common.download} href={dataUrl} download="child_request.xml">
<img src={download} alt={t.common.download} />
</a>
<CopyDownloadButton xml={request} name='child_request' setNotification={setNotification}/>
</div>
</div>
<div>
Expand Down
12 changes: 2 additions & 10 deletions src/components/forms/RepoModal.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import React from 'react';
import useTranslations from '../../hooks/useTranslations';
import Modal from './Modal';
import clipboard from '../../img/clipboard.svg?url';
import download from '../../img/download.svg?url';
import upload from '../../img/upload.svg?url';
import NotificationPopup from '../NotificationPopup';
import useRepositoryActions from '../../hooks/useRepositoryActions';
import CopyDownloadButton from '../CopyDownloadButton';

export default function RepoModal() {
const t = useTranslations();
const {
notification,
setNotification,
request,
dataUrl,
setRequest,
response,
setResponse,
onSubmit,
onClose,
onCopy,
handleUpload,
} = useRepositoryActions();

Expand All @@ -37,12 +34,7 @@ export default function RepoModal() {
<label>{t.caDetails.repoTab.request}</label>
<textarea name="request" readOnly value={request} id="request" onChange={(e) => setRequest(e.target.value)} />
<div>
<button className="button large icon" type="button" title={t.common.copy} onClick={onCopy}>
<img src={clipboard} alt={t.common.copy} />
</button>
<a className="button large icon" title={t.common.download} href={dataUrl} download="publisher_request.xml">
<img src={download} alt={t.common.download} />
</a>
<CopyDownloadButton xml={request} name='publisher_request' setNotification={setNotification}/>
</div>
</div>
<div>
Expand Down
Loading

0 comments on commit 747ec6e

Please sign in to comment.