Merge branch 'develop' into release/0.0.3
This commit is contained in:
40
.github/workflows/blackduck.yml
vendored
Normal file
40
.github/workflows/blackduck.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: Blackduck
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# run scans twice a month
|
||||
- cron: "0 2 1,15 * *"
|
||||
|
||||
jobs:
|
||||
blackduck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "16"
|
||||
cache: "npm"
|
||||
- run: npm install
|
||||
- run: npm run build
|
||||
|
||||
# ota-admin-portal
|
||||
- name: Run Synopsys Detect - ota-admin-portal
|
||||
uses: synopsys-sig/detect-action@v0.3.2
|
||||
env:
|
||||
DETECT_PROJECT_NAME: ota-admin-portal
|
||||
DETECT_EXCLUDED_DIRECTORIES: node_modules
|
||||
DETECT_PROJECT_VERSION_NAME: default
|
||||
DETECT_NPM_INCLUDE_DEV_DEPENDENCIES: "FALSE"
|
||||
# DETECT_DETECTOR_SEARCH_EXCLUSION_DEFAULTS: "true"
|
||||
DETECT_DETECTOR_SEARCH_DEPTH: 0
|
||||
DETECT_DETECTOR_SEARCH_CONTINUE: "true"
|
||||
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
detect-version: 7.9.0
|
||||
blackduck-url: ${{ secrets.BLACKDUCK_URL }}
|
||||
blackduck-api-token: ${{ secrets.BLACKDUCK_API_KEY }}
|
||||
scan-mode: INTELLIGENT
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import api from "../../services/suppliersAPI";
|
||||
import { LocalDateTimeString } from "../../utils/dates";
|
||||
|
||||
import {
|
||||
validateSupplier,
|
||||
@@ -12,26 +13,26 @@ const SupplierDetailsContext = React.createContext();
|
||||
export const SupplierDetailsProvider = ({ children }) => {
|
||||
const { getSuppliers, suppliers } = useSupplierContext();
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [id, setID] = useState("");
|
||||
const [contact, setContact] = useState("");
|
||||
const [company, setCompany] = useState("");
|
||||
const [address, setAddress] = useState("");
|
||||
const [phone, setPhone] = useState("");
|
||||
const [program, setProgram] = useState("");
|
||||
const [ecus, setECUs] = useState("");
|
||||
const [activated, setActivated] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!suppliers || suppliers.length === 0) return;
|
||||
|
||||
const supplier = suppliers[0];
|
||||
|
||||
setID(supplier?.id || "");
|
||||
setContact(supplier?.contact || "");
|
||||
setCompany(supplier?.company || "");
|
||||
setAddress(supplier?.address || "");
|
||||
setPhone(supplier?.telephone || "");
|
||||
setProgram(supplier?.program || "");
|
||||
setECUs(supplier?.ecus.join(",") || "");
|
||||
setActivated(LocalDateTimeString(supplier?.activated));
|
||||
}, [suppliers]);
|
||||
|
||||
const getSupplier = async (email, token) => {
|
||||
@@ -55,7 +56,6 @@ export const SupplierDetailsProvider = ({ children }) => {
|
||||
};
|
||||
|
||||
const formData = (email) => ({
|
||||
id,
|
||||
contact,
|
||||
company,
|
||||
address,
|
||||
@@ -65,6 +65,25 @@ export const SupplierDetailsProvider = ({ children }) => {
|
||||
ecus: getECUs(),
|
||||
});
|
||||
|
||||
const activateSupplier = async (email, token) => {
|
||||
try {
|
||||
setBusy(true);
|
||||
validateEmail(email);
|
||||
|
||||
const result = await api.activateSupplier(email, token);
|
||||
if (result.error)
|
||||
throw new Error(`Activate supplier error. ${result.message}`);
|
||||
|
||||
setActivated(
|
||||
LocalDateTimeString(result.activate) || new Date().toDateString()
|
||||
);
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
const updateSupplier = async (email, token) => {
|
||||
try {
|
||||
const supplier = formData(email);
|
||||
@@ -80,14 +99,15 @@ export const SupplierDetailsProvider = ({ children }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const deleteSupplier = async (vin, token) => {
|
||||
const deleteSupplier = async (email, token) => {
|
||||
try {
|
||||
setBusy(true);
|
||||
validateEmail(vin);
|
||||
validateEmail(email);
|
||||
|
||||
const result = await api.deleteSupplier(vin, token);
|
||||
const result = await api.deleteSupplier(email, token);
|
||||
if (result.error)
|
||||
throw new Error(`Delete supplier error. ${result.message}`);
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
setBusy(false);
|
||||
@@ -97,18 +117,18 @@ export const SupplierDetailsProvider = ({ children }) => {
|
||||
return (
|
||||
<SupplierDetailsContext.Provider
|
||||
value={{
|
||||
activated,
|
||||
busy,
|
||||
id,
|
||||
contact,
|
||||
company,
|
||||
address,
|
||||
phone,
|
||||
program,
|
||||
ecus,
|
||||
activateSupplier,
|
||||
deleteSupplier,
|
||||
getSupplier,
|
||||
updateSupplier,
|
||||
setID,
|
||||
setContact,
|
||||
setCompany,
|
||||
setAddress,
|
||||
|
||||
@@ -19,52 +19,6 @@ exports[`Supplier page Render 1`] = `
|
||||
class="makeStyles-form-5"
|
||||
novalidate=""
|
||||
>
|
||||
<div
|
||||
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal MuiFormControl-fullWidth"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required"
|
||||
data-shrink="false"
|
||||
for="id"
|
||||
id="id-label"
|
||||
>
|
||||
Active Directory ID
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="MuiFormLabel-asterisk MuiInputLabel-asterisk"
|
||||
>
|
||||
|
||||
*
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-fullWidth MuiInputBase-formControl"
|
||||
>
|
||||
<input
|
||||
aria-invalid="false"
|
||||
class="MuiInputBase-input MuiOutlinedInput-input"
|
||||
id="id"
|
||||
maxlength="255"
|
||||
name="id"
|
||||
required=""
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<fieldset
|
||||
aria-hidden="true"
|
||||
class="PrivateNotchedOutline-root-62 MuiOutlinedInput-notchedOutline"
|
||||
>
|
||||
<legend
|
||||
class="PrivateNotchedOutline-legendLabelled-64"
|
||||
>
|
||||
<span>
|
||||
Active Directory ID
|
||||
*
|
||||
</span>
|
||||
</legend>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal MuiFormControl-fullWidth"
|
||||
>
|
||||
@@ -341,6 +295,20 @@ exports[`Supplier page Render 1`] = `
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-6 MuiButton-containedSecondary MuiButton-fullWidth"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label"
|
||||
>
|
||||
Activate
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-6 MuiButton-containedPrimary MuiButton-fullWidth"
|
||||
tabindex="0"
|
||||
|
||||
@@ -15,7 +15,7 @@ const Main = () => {
|
||||
const classes = useStyles();
|
||||
const {
|
||||
busy,
|
||||
id,
|
||||
activated,
|
||||
contact,
|
||||
company,
|
||||
address,
|
||||
@@ -23,13 +23,13 @@ const Main = () => {
|
||||
program,
|
||||
ecus,
|
||||
getSupplier,
|
||||
setID,
|
||||
setContact,
|
||||
setCompany,
|
||||
setAddress,
|
||||
setPhone,
|
||||
setProgram,
|
||||
setECUs,
|
||||
activateSupplier,
|
||||
updateSupplier,
|
||||
} = useSupplierDetailsContext();
|
||||
const { setTitle, setSitePath, setMessage } = useStatusContext();
|
||||
@@ -49,6 +49,16 @@ const Main = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const activate = async (event) => {
|
||||
event.preventDefault();
|
||||
try {
|
||||
await activateSupplier(email, token);
|
||||
setMessage(`Activated ${email}`);
|
||||
} catch (e) {
|
||||
setMessage(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setTitle(`Supplier ${email}`);
|
||||
setSitePath([
|
||||
@@ -74,20 +84,6 @@ const Main = () => {
|
||||
return (
|
||||
<div className={classes.paper}>
|
||||
<form className={classes.form} noValidate action="#">
|
||||
<TextField
|
||||
id="id"
|
||||
name="id"
|
||||
label="Active Directory ID"
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
inputProps={{
|
||||
maxLength: "255",
|
||||
}}
|
||||
required
|
||||
fullWidth
|
||||
value={id}
|
||||
onChange={(e) => setID(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
id="contact"
|
||||
name="contact"
|
||||
@@ -172,6 +168,33 @@ const Main = () => {
|
||||
value={ecus}
|
||||
onChange={(e) => setECUs(e.target.value)}
|
||||
/>
|
||||
{activated ? (
|
||||
<TextField
|
||||
id="activated"
|
||||
name="activated"
|
||||
label="Activated"
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
inputProps={{
|
||||
maxLength: "255",
|
||||
readOnly: true,
|
||||
}}
|
||||
required
|
||||
fullWidth
|
||||
value={activated}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
disabled={busy}
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
className={classes.submit}
|
||||
onClick={activate}
|
||||
>
|
||||
Activate
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={busy}
|
||||
|
||||
@@ -23,29 +23,6 @@ exports[`Suppliers page Render 1`] = `
|
||||
<tr
|
||||
class="MuiTableRow-root MuiTableRow-head"
|
||||
>
|
||||
<th
|
||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||
scope="col"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
ID
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||
scope="col"
|
||||
@@ -190,6 +167,29 @@ exports[`Suppliers page Render 1`] = `
|
||||
</svg>
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||
scope="col"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Activated
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody
|
||||
@@ -198,9 +198,6 @@ exports[`Suppliers page Render 1`] = `
|
||||
<tr
|
||||
class="MuiTableRow-root"
|
||||
>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
/>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
>
|
||||
@@ -239,13 +236,13 @@ exports[`Suppliers page Render 1`] = `
|
||||
>
|
||||
7/14/2021 8:09:40 PM
|
||||
</td>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
/>
|
||||
</tr>
|
||||
<tr
|
||||
class="MuiTableRow-root"
|
||||
>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
/>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
>
|
||||
@@ -284,13 +281,13 @@ exports[`Suppliers page Render 1`] = `
|
||||
>
|
||||
7/16/2021 10:09:40 PM
|
||||
</td>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
/>
|
||||
</tr>
|
||||
<tr
|
||||
class="MuiTableRow-root"
|
||||
>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
/>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
>
|
||||
@@ -329,6 +326,9 @@ exports[`Suppliers page Render 1`] = `
|
||||
>
|
||||
7/16/2021 10:09:40 PM
|
||||
</td>
|
||||
<td
|
||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||
/>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot
|
||||
|
||||
@@ -18,10 +18,6 @@ import TableHeaderSortable from "../../Table/HeaderSortable";
|
||||
import { logger } from "../../../services/monitoring";
|
||||
|
||||
const tableColumns = [
|
||||
{
|
||||
id: "id",
|
||||
label: "ID",
|
||||
},
|
||||
{
|
||||
id: "contact",
|
||||
label: "Contact",
|
||||
@@ -46,6 +42,10 @@ const tableColumns = [
|
||||
id: "created_at",
|
||||
label: "Registered",
|
||||
},
|
||||
{
|
||||
id: "activated_at",
|
||||
label: "Activated",
|
||||
},
|
||||
];
|
||||
|
||||
const SupplierTable = (props) => {
|
||||
@@ -119,7 +119,6 @@ const SupplierTable = (props) => {
|
||||
{suppliers.map((row, index) => {
|
||||
return (
|
||||
<TableRow key={index}>
|
||||
<TableCell align="center">{row?.id}</TableCell>
|
||||
<TableCell align="center">
|
||||
<Link to={`/supplier/${row.email}`}>{row.contact}</Link>
|
||||
</TableCell>
|
||||
@@ -132,6 +131,9 @@ const SupplierTable = (props) => {
|
||||
<TableCell align="center">
|
||||
{LocalDateTimeString(row.created)}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
{LocalDateTimeString(row.activated)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -39,6 +39,9 @@ const suppliersAPI = {
|
||||
data.push(supplier);
|
||||
return supplier;
|
||||
},
|
||||
activateSupplier: async (_email, _token) => {
|
||||
return { message: "2022-07-14T21:02:58.998182Z" };
|
||||
},
|
||||
deleteSupplier: async (email) => {
|
||||
const index = data.findIndex((element) => element.email === email);
|
||||
if (index >= 0) data.splice(index, 1);
|
||||
|
||||
@@ -20,6 +20,17 @@ const suppliersAPI = {
|
||||
.then(fetchRespHandler)
|
||||
.catch(errorHandler),
|
||||
|
||||
activateSupplier: async (email, token) =>
|
||||
fetch(`${API_ENDPOINT}/supplier/activate/${email}`, {
|
||||
method: "POST",
|
||||
headers: Object.assign(
|
||||
{ "Content-Type": "application/json" },
|
||||
getAuthHeaderOptions(token)
|
||||
),
|
||||
})
|
||||
.then(fetchRespHandler)
|
||||
.catch(errorHandler),
|
||||
|
||||
deleteSupplier: async (email, token) =>
|
||||
fetch(`${API_ENDPOINT}/supplier/${email}`, {
|
||||
method: "DELETE",
|
||||
|
||||
@@ -7,10 +7,6 @@ export const validateSupplier = (supplier) => {
|
||||
|
||||
validateEmail(supplier.email);
|
||||
|
||||
if (!supplier?.id) {
|
||||
throw new Error("id required");
|
||||
}
|
||||
|
||||
if (!supplier?.contact) {
|
||||
throw new Error("contact required");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user