Merge commit 'a087961fab0d73cc54f9cae658e9eb50ab060f96'
This commit is contained in:
commit
3803b835c2
|
@ -43,6 +43,7 @@
|
||||||
"react-bootstrap-typeahead": "^6.0.0",
|
"react-bootstrap-typeahead": "^6.0.0",
|
||||||
"react-datepicker": "^4.8.0",
|
"react-datepicker": "^4.8.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-icons": "^4.4.0",
|
||||||
"react-jsonschema-form": "^1.8.1",
|
"react-jsonschema-form": "^1.8.1",
|
||||||
"react-markdown": "^8.0.3",
|
"react-markdown": "^8.0.3",
|
||||||
"react-router-dom": "^6.3.0",
|
"react-router-dom": "^6.3.0",
|
||||||
|
@ -22404,6 +22405,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
||||||
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-icons": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.9.0",
|
"version": "16.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
|
||||||
|
@ -44975,7 +44984,7 @@
|
||||||
"@csstools/postcss-text-decoration-shorthand": "^1.0.0",
|
"@csstools/postcss-text-decoration-shorthand": "^1.0.0",
|
||||||
"@csstools/postcss-trigonometric-functions": "^1.0.2",
|
"@csstools/postcss-trigonometric-functions": "^1.0.2",
|
||||||
"@csstools/postcss-unset-value": "^1.0.2",
|
"@csstools/postcss-unset-value": "^1.0.2",
|
||||||
"autoprefixer": "10.4.8",
|
"autoprefixer": "10.4.5",
|
||||||
"browserslist": "^4.21.3",
|
"browserslist": "^4.21.3",
|
||||||
"css-blank-pseudo": "^3.0.3",
|
"css-blank-pseudo": "^3.0.3",
|
||||||
"css-has-pseudo": "^3.0.4",
|
"css-has-pseudo": "^3.0.4",
|
||||||
|
@ -45013,7 +45022,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"autoprefixer": {
|
"autoprefixer": {
|
||||||
"version": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.5.tgz",
|
"version": "10.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.5.tgz",
|
||||||
"integrity": "sha512-Fvd8yCoA7lNX/OUllvS+aS1I7WRBclGXsepbvT8ZaPgrH24rgXpZzF0/6Hh3ZEkwg+0AES/Osd196VZmYoEFtw==",
|
"integrity": "sha512-Fvd8yCoA7lNX/OUllvS+aS1I7WRBclGXsepbvT8ZaPgrH24rgXpZzF0/6Hh3ZEkwg+0AES/Osd196VZmYoEFtw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"browserslist": "^4.20.2",
|
"browserslist": "^4.20.2",
|
||||||
|
@ -45721,6 +45731,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
|
||||||
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
|
||||||
},
|
},
|
||||||
|
"react-icons": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "16.9.0",
|
"version": "16.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
"react-bootstrap-typeahead": "^6.0.0",
|
"react-bootstrap-typeahead": "^6.0.0",
|
||||||
"react-datepicker": "^4.8.0",
|
"react-datepicker": "^4.8.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-icons": "^4.4.0",
|
||||||
"react-jsonschema-form": "^1.8.1",
|
"react-jsonschema-form": "^1.8.1",
|
||||||
"react-markdown": "^8.0.3",
|
"react-markdown": "^8.0.3",
|
||||||
"react-router-dom": "^6.3.0",
|
"react-router-dom": "^6.3.0",
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
export interface Secret {
|
export interface Secret {
|
||||||
|
id: number;
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
username: string;
|
creator_user_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RecentProcessModel {
|
export interface RecentProcessModel {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Link, useSearchParams } from 'react-router-dom';
|
import { Link, useSearchParams } from 'react-router-dom';
|
||||||
import { Button, Table } from 'react-bootstrap';
|
import { Button, Table } from 'react-bootstrap';
|
||||||
|
import { MdDelete } from 'react-icons/md';
|
||||||
import PaginationForTable from '../components/PaginationForTable';
|
import PaginationForTable from '../components/PaginationForTable';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
import { getPageInfoFromSearchParams } from '../helpers';
|
import { getPageInfoFromSearchParams } from '../helpers';
|
||||||
|
@ -23,17 +24,36 @@ export default function SecretList() {
|
||||||
});
|
});
|
||||||
}, [searchParams]);
|
}, [searchParams]);
|
||||||
|
|
||||||
|
const reloadSecrets = (_result: any) => {
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteSecret = (key: any) => {
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/secrets/${key}`,
|
||||||
|
successCallback: reloadSecrets,
|
||||||
|
httpMethod: 'DELETE',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const buildTable = () => {
|
const buildTable = () => {
|
||||||
const rows = secrets.map((row) => {
|
const rows = secrets.map((row) => {
|
||||||
return (
|
return (
|
||||||
<tr key={(row as any).key}>
|
<tr key={(row as any).key}>
|
||||||
|
<td>
|
||||||
|
<Link to={`/admin/secrets/${(row as any).key}`}>
|
||||||
|
{(row as any).id}
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Link to={`/admin/secrets/${(row as any).key}`}>
|
<Link to={`/admin/secrets/${(row as any).key}`}>
|
||||||
{(row as any).key}
|
{(row as any).key}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td>{(row as any).value}</td>
|
|
||||||
<td>{(row as any).username}</td>
|
<td>{(row as any).username}</td>
|
||||||
|
<td>
|
||||||
|
<MdDelete onClick={() => handleDeleteSecret((row as any).key)} />
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -41,9 +61,10 @@ export default function SecretList() {
|
||||||
<Table striped bordered>
|
<Table striped bordered>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
<th>Secret Key</th>
|
<th>Secret Key</th>
|
||||||
<th>Secret Value</th>
|
|
||||||
<th>Creator</th>
|
<th>Creator</th>
|
||||||
|
<th>Delete</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>{rows}</tbody>
|
<tbody>{rows}</tbody>
|
||||||
|
@ -72,12 +93,11 @@ export default function SecretList() {
|
||||||
|
|
||||||
if (pagination) {
|
if (pagination) {
|
||||||
return (
|
return (
|
||||||
<>
|
<div>
|
||||||
<Button href="/admin/secrets/new">Add a secret</Button>
|
<h2>Secrets</h2>
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{SecretsDisplayArea()}
|
{SecretsDisplayArea()}
|
||||||
</>
|
<Button href="/admin/secrets/new">Add a secret</Button>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Stack } from 'react-bootstrap';
|
||||||
import Button from 'react-bootstrap/Button';
|
import Button from 'react-bootstrap/Button';
|
||||||
import Form from 'react-bootstrap/Form';
|
import Form from 'react-bootstrap/Form';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
|
@ -13,6 +14,18 @@ export default function SecretNew() {
|
||||||
navigate(`/admin/secrets/${key}`);
|
navigate(`/admin/secrets/${key}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const navigateToSecrets = () => {
|
||||||
|
navigate(`/admin/secrets`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeSpacesToDash = (someString: string) => {
|
||||||
|
// change spaces to `-`
|
||||||
|
let s1 = someString.replace(' ', '-');
|
||||||
|
// remove any trailing `-`
|
||||||
|
s1 = s1.replace(/-$/, '');
|
||||||
|
return s1;
|
||||||
|
};
|
||||||
|
|
||||||
const addSecret = (event: any) => {
|
const addSecret = (event: any) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
|
@ -26,16 +39,22 @@ export default function SecretNew() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const warningStyle = {
|
||||||
|
color: 'red',
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main style={{ padding: '1rem 0' }}>
|
<main style={{ padding: '1rem 0' }}>
|
||||||
<h2>Add Secret</h2>
|
<h2>Add Secret</h2>
|
||||||
<Form onSubmit={addSecret}>
|
<Form onSubmit={addSecret}>
|
||||||
<Form.Group className="mb-3" controlId="formDisplayName">
|
<Form.Group className="mb-3" controlId="formDisplayName">
|
||||||
<Form.Label>Key:</Form.Label>
|
<Form.Label>
|
||||||
|
Key: <span style={warningStyle}>No Spaces</span>
|
||||||
|
</Form.Label>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
type="text"
|
type="text"
|
||||||
value={key}
|
value={key}
|
||||||
onChange={(e) => setKey(e.target.value)}
|
onChange={(e) => setKey(changeSpacesToDash(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group className="mb-3" controlId="formIdentifier">
|
<Form.Group className="mb-3" controlId="formIdentifier">
|
||||||
|
@ -48,9 +67,14 @@ export default function SecretNew() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Button variant="primary" type="submit">
|
<Stack direction="horizontal" gap={3}>
|
||||||
Submit
|
<Button variant="primary" type="submit">
|
||||||
</Button>
|
Submit
|
||||||
|
</Button>
|
||||||
|
<Button variant="danger" type="button" onClick={navigateToSecrets}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
</Form>
|
</Form>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams, useNavigate } from 'react-router-dom';
|
||||||
import { Stack, Table } from 'react-bootstrap';
|
import { Stack, Table, Button } from 'react-bootstrap';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
import { Secret } from '../interfaces';
|
import { Secret } from '../interfaces';
|
||||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||||
|
@ -10,10 +10,7 @@ export default function SecretShow() {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
|
||||||
const [secret, setSecret] = useState<Secret | null>(null);
|
const [secret, setSecret] = useState<Secret | null>(null);
|
||||||
|
const [secretValue, setSecretValue] = useState(secret?.value);
|
||||||
const navigateToSecrets = (_result: any) => {
|
|
||||||
navigate(`/admin/secrets`);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
|
@ -22,6 +19,37 @@ export default function SecretShow() {
|
||||||
});
|
});
|
||||||
}, [params]);
|
}, [params]);
|
||||||
|
|
||||||
|
const handleSecretValueChange = (event: any) => {
|
||||||
|
if (secret) {
|
||||||
|
setSecretValue(event.target.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// const reloadSecret = (_result: any) => {
|
||||||
|
// window.location.reload();
|
||||||
|
// };
|
||||||
|
|
||||||
|
const updateSecretValue = () => {
|
||||||
|
if (secret && secretValue) {
|
||||||
|
secret.value = secretValue;
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/secrets/${secret.key}`,
|
||||||
|
successCallback: () => {
|
||||||
|
setSecret(secret);
|
||||||
|
},
|
||||||
|
httpMethod: 'PUT',
|
||||||
|
postBody: {
|
||||||
|
value: secretValue,
|
||||||
|
creator_user_id: secret.creator_user_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigateToSecrets = (_result: any) => {
|
||||||
|
navigate(`/admin/secrets`);
|
||||||
|
};
|
||||||
|
|
||||||
const deleteSecret = () => {
|
const deleteSecret = () => {
|
||||||
if (secret === null) {
|
if (secret === null) {
|
||||||
return;
|
return;
|
||||||
|
@ -34,17 +62,18 @@ export default function SecretShow() {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (secret) {
|
if (secret) {
|
||||||
const secretToUse = secret as any;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Stack direction="horizontal" gap={3}>
|
<Stack direction="horizontal" gap={3}>
|
||||||
<h2>Secret Key: {secretToUse.key}</h2>
|
<h2>Secret Key: {secret.key}</h2>
|
||||||
<ButtonWithConfirmation
|
<ButtonWithConfirmation
|
||||||
description="Delete Secret?"
|
description="Delete Secret?"
|
||||||
onConfirmation={deleteSecret}
|
onConfirmation={deleteSecret}
|
||||||
buttonLabel="Delete"
|
buttonLabel="Delete"
|
||||||
/>
|
/>
|
||||||
|
<Button variant="warning" onClick={updateSecretValue}>
|
||||||
|
Update Value
|
||||||
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
<div>
|
<div>
|
||||||
<Table striped bordered>
|
<Table striped bordered>
|
||||||
|
@ -57,7 +86,15 @@ export default function SecretShow() {
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{params.key}</td>
|
<td>{params.key}</td>
|
||||||
<td>{secretToUse.value}</td>
|
<td>
|
||||||
|
<input
|
||||||
|
id="secret_value"
|
||||||
|
name="secret_value"
|
||||||
|
type="text"
|
||||||
|
value={secretValue || secret.value}
|
||||||
|
onChange={handleSecretValueChange}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
|
@ -17,7 +17,6 @@ export default function TaskShow() {
|
||||||
const setErrorMessage = (useContext as any)(ErrorContext)[1];
|
const setErrorMessage = (useContext as any)(ErrorContext)[1];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setErrorMessage('');
|
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
path: `/tasks/${params.process_instance_id}/${params.task_id}`,
|
path: `/tasks/${params.process_instance_id}/${params.task_id}`,
|
||||||
successCallback: setTask,
|
successCallback: setTask,
|
||||||
|
|
|
@ -67,11 +67,15 @@ backendCallProps) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
let isSuccessful = true;
|
let isSuccessful = true;
|
||||||
|
let is403 = false;
|
||||||
fetch(`${BACKEND_BASE_URL}${path}`, httpArgs)
|
fetch(`${BACKEND_BASE_URL}${path}`, httpArgs)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
UserService.doLogin();
|
UserService.doLogin();
|
||||||
throw new UnauthenticatedError('You must be authenticated to do this.');
|
throw new UnauthenticatedError('You must be authenticated to do this.');
|
||||||
|
} else if (response.status === 403) {
|
||||||
|
is403 = true;
|
||||||
|
isSuccessful = false;
|
||||||
} else if (!response.ok) {
|
} else if (!response.ok) {
|
||||||
isSuccessful = false;
|
isSuccessful = false;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +84,10 @@ backendCallProps) => {
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
if (isSuccessful) {
|
if (isSuccessful) {
|
||||||
successCallback(result);
|
successCallback(result);
|
||||||
|
} else if (is403) {
|
||||||
|
// Hopefully we can make this service a hook and use the error message context directly
|
||||||
|
// eslint-disable-next-line no-alert
|
||||||
|
alert(result.message);
|
||||||
} else {
|
} else {
|
||||||
let message = 'A server error occurred.';
|
let message = 'A server error occurred.';
|
||||||
if (result.message) {
|
if (result.message) {
|
||||||
|
@ -89,6 +97,8 @@ backendCallProps) => {
|
||||||
failureCallback(message);
|
failureCallback(message);
|
||||||
} else {
|
} else {
|
||||||
console.error(message);
|
console.error(message);
|
||||||
|
// eslint-disable-next-line no-alert
|
||||||
|
alert(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue