Merge Development (#53)
* Use responsive iframe control for charts (#49) * Use responsive iframe control to charts * Move external Grafana link to Dashboard page * Remove unused embedded style class * Add button label * added delete button to deploy packages * Fix unit test warning Remove unused route from test * Fix styling of button * minor fixes per pr review Co-authored-by: jcw-fisker <jwatson@fiskerinc.com> Co-authored-by: John Cotten Watson <83605808+jcw-fisker@users.noreply.github.com>
This commit is contained in:
@@ -30,10 +30,10 @@ describe("App", () => {
|
||||
beforeAll(() => {
|
||||
// Stablize Table Pagination control ids
|
||||
expect.addSnapshotSerializer({
|
||||
test: function(val) {
|
||||
test: function (val) {
|
||||
return val && typeof val === "string" && val.indexOf("mui-") >= 0;
|
||||
},
|
||||
print: function(val) {
|
||||
print: function (val) {
|
||||
let str = val;
|
||||
str = str.replace(/mui-[0-9]*/g, "mui-00000");
|
||||
|
||||
@@ -67,10 +67,6 @@ describe("App", () => {
|
||||
await check("/updates", "span.MuiButton-label", "Sign In");
|
||||
});
|
||||
|
||||
it("Route /update unauthenticated", async () => {
|
||||
await check("/update/1", "span.MuiButton-label", "Sign In");
|
||||
});
|
||||
|
||||
it("Route /carupdate-deploy unauthenticated", async () => {
|
||||
await check("/carupdate-deploy/1", "span.MuiButton-label", "Sign In");
|
||||
});
|
||||
@@ -120,14 +116,9 @@ describe("App", () => {
|
||||
await check("/updates", "h6", "Deploy Packages");
|
||||
});
|
||||
|
||||
it("Route /update authenticated", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
await check("/update/1", "h6", "Edit Update Package 1");
|
||||
});
|
||||
|
||||
it("Route /carupdate-status authenticated", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
await check("/carupdate-status/1", "h6", "");
|
||||
await check("/carupdate-status/1", "h6", "Package Package 1.0");
|
||||
});
|
||||
|
||||
it("Route /vehicles authenticated", async () => {
|
||||
@@ -156,7 +147,7 @@ describe("App", () => {
|
||||
|
||||
it("Route /carupdate-deploy authenticated", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
await check("/carupdate-deploy/1", "h6", "Deploy ");
|
||||
await check("/carupdate-deploy/1", "h6", "Deploy Package 1.0");
|
||||
});
|
||||
|
||||
it("Route /dashboard authenticated", async () => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ import { StatusProvider } from "../Contexts/StatusContext";
|
||||
import { CssBaseline } from "@material-ui/core";
|
||||
import MenuDrawer from "../Layouts/MenuDrawer";
|
||||
import SiteRoutes from "../Routes/SiteRoutes";
|
||||
import {} from "../../services/monitoring";
|
||||
import { } from "../../services/monitoring";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
||||
@@ -48,6 +48,26 @@ export const UpdatesProvider = ({ children }) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
const deletePackage = async (package_id, token) => {
|
||||
let result;
|
||||
|
||||
const index = packages.findIndex((element) => {
|
||||
return element.id === package_id;
|
||||
});
|
||||
packages.splice(index, 1);
|
||||
|
||||
try {
|
||||
setBusy(true);
|
||||
result = await api.deletePackage(package_id, token);
|
||||
if (result.error)
|
||||
throw new Error(`Delete package error. ${result.message}`);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const createCarUpdates = async (data, token) => {
|
||||
let result;
|
||||
|
||||
@@ -188,6 +208,7 @@ export const UpdatesProvider = ({ children }) => {
|
||||
totalCarUpdates,
|
||||
getPackages,
|
||||
updatePackage,
|
||||
deletePackage,
|
||||
createCarUpdates,
|
||||
getCarUpdates,
|
||||
getVINUpdates,
|
||||
|
||||
@@ -4,6 +4,15 @@ const UpdatesContext = React.createContext();
|
||||
|
||||
let busy = false;
|
||||
let packages = [];
|
||||
const examplePackage = {
|
||||
id: 0,
|
||||
package_name: "Package",
|
||||
version: "1.0",
|
||||
desc: "Description",
|
||||
release_notes: "https://www.google.com/",
|
||||
created: Date.now().toString(),
|
||||
};
|
||||
packages.push(examplePackage)
|
||||
let totalPackages = 0;
|
||||
let carUpdates = [];
|
||||
let totalCarUpdates = 0;
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from "@material-ui/core";
|
||||
import SendIcon from "@material-ui/icons/Send";
|
||||
import VisibilityIcon from "@material-ui/icons/Visibility";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import useStyles from "../../useStyles";
|
||||
import {
|
||||
UpdatesProvider,
|
||||
@@ -54,14 +55,15 @@ const UpdatePackagesList = () => {
|
||||
const [orderBy, setOrderBy] = useState("id");
|
||||
const [order, setOrder] = useState("desc");
|
||||
const [search, setSearch] = useState("");
|
||||
const { getPackages, packages, totalPackages } = useUpdatesContext();
|
||||
const { getPackages, deletePackage, packages, totalPackages } =
|
||||
useUpdatesContext();
|
||||
const {
|
||||
token: {
|
||||
idToken: { jwtToken: token },
|
||||
},
|
||||
groups,
|
||||
} = useUserContext();
|
||||
const { setTitle } = useStatusContext();
|
||||
const { setMessage, setTitle } = useStatusContext();
|
||||
|
||||
useEffect(() => {
|
||||
setTitle("Deploy Packages");
|
||||
@@ -107,6 +109,14 @@ const UpdatePackagesList = () => {
|
||||
setSearch(search);
|
||||
};
|
||||
|
||||
const onDelete = async (package_id) => {
|
||||
try {
|
||||
await deletePackage(parseInt(package_id), token);
|
||||
} catch (e) {
|
||||
setMessage(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
const Actions = (row) => {
|
||||
let actions = [];
|
||||
if (hasRole([Roles.CREATE, Roles.READ], groups)) {
|
||||
@@ -131,18 +141,39 @@ const UpdatePackagesList = () => {
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
tip: `Delete "${row.package_name} ${row.version}"`,
|
||||
id: row.id,
|
||||
icon: (
|
||||
<DeleteIcon
|
||||
aria-label={`Delete ${row.package_name} ${row.version}`}
|
||||
/>
|
||||
),
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
if (actions.length === 0) return "No actions";
|
||||
|
||||
return actions.map((action) => (
|
||||
return actions.map((action) => {
|
||||
if (action.link != null) {
|
||||
return (
|
||||
<Tooltip key={action.link} title={action.tip}>
|
||||
<Link to={action.link} style={{ margin: 5 }}>
|
||||
{action.icon}
|
||||
</Link>
|
||||
</Tooltip>
|
||||
));
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Tooltip key={`delete-${action.id}`} title={action.tip}>
|
||||
<Link to="#" onClick={() => onDelete(action.id)}>
|
||||
{action.icon}
|
||||
</Link>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -10,6 +10,12 @@ const updatesAPI = {
|
||||
})
|
||||
.then(fetchRespHandler),
|
||||
|
||||
deletePackage: async (package_id, token) => fetch(`${API_ENDPOINT}/update?id=${package_id}`, {
|
||||
method: "DELETE",
|
||||
headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
|
||||
})
|
||||
.then(fetchRespHandler),
|
||||
|
||||
getPackages: async (search, token) => {
|
||||
var u = addQueryParams(`${API_ENDPOINT}/updates`, search);
|
||||
return fetch(u, {
|
||||
|
||||
Reference in New Issue
Block a user