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,14 +30,14 @@ describe("App", () => {
|
|||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
// Stablize Table Pagination control ids
|
// Stablize Table Pagination control ids
|
||||||
expect.addSnapshotSerializer({
|
expect.addSnapshotSerializer({
|
||||||
test: function(val) {
|
test: function (val) {
|
||||||
return val && typeof val === "string" && val.indexOf("mui-") >= 0;
|
return val && typeof val === "string" && val.indexOf("mui-") >= 0;
|
||||||
},
|
},
|
||||||
print: function(val) {
|
print: function (val) {
|
||||||
let str = val;
|
let str = val;
|
||||||
str = str.replace(/mui-[0-9]*/g, "mui-00000");
|
str = str.replace(/mui-[0-9]*/g, "mui-00000");
|
||||||
|
|
||||||
return `"${str}"`;
|
return `"${str}"`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -67,10 +67,6 @@ describe("App", () => {
|
|||||||
await check("/updates", "span.MuiButton-label", "Sign In");
|
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 () => {
|
it("Route /carupdate-deploy unauthenticated", async () => {
|
||||||
await check("/carupdate-deploy/1", "span.MuiButton-label", "Sign In");
|
await check("/carupdate-deploy/1", "span.MuiButton-label", "Sign In");
|
||||||
});
|
});
|
||||||
@@ -120,17 +116,12 @@ describe("App", () => {
|
|||||||
await check("/updates", "h6", "Deploy Packages");
|
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 () => {
|
it("Route /carupdate-status authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
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 () => {
|
it("Route /vehicles authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT);
|
||||||
await check("/vehicles", "h6", "Vehicles");
|
await check("/vehicles", "h6", "Vehicles");
|
||||||
});
|
});
|
||||||
@@ -156,7 +147,7 @@ describe("App", () => {
|
|||||||
|
|
||||||
it("Route /carupdate-deploy authenticated", async () => {
|
it("Route /carupdate-deploy authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
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 () => {
|
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 { CssBaseline } from "@material-ui/core";
|
||||||
import MenuDrawer from "../Layouts/MenuDrawer";
|
import MenuDrawer from "../Layouts/MenuDrawer";
|
||||||
import SiteRoutes from "../Routes/SiteRoutes";
|
import SiteRoutes from "../Routes/SiteRoutes";
|
||||||
import {} from "../../services/monitoring";
|
import { } from "../../services/monitoring";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -48,6 +48,26 @@ export const UpdatesProvider = ({ children }) => {
|
|||||||
return result;
|
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) => {
|
const createCarUpdates = async (data, token) => {
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
@@ -188,6 +208,7 @@ export const UpdatesProvider = ({ children }) => {
|
|||||||
totalCarUpdates,
|
totalCarUpdates,
|
||||||
getPackages,
|
getPackages,
|
||||||
updatePackage,
|
updatePackage,
|
||||||
|
deletePackage,
|
||||||
createCarUpdates,
|
createCarUpdates,
|
||||||
getCarUpdates,
|
getCarUpdates,
|
||||||
getVINUpdates,
|
getVINUpdates,
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ const UpdatesContext = React.createContext();
|
|||||||
|
|
||||||
let busy = false;
|
let busy = false;
|
||||||
let packages = [];
|
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 totalPackages = 0;
|
||||||
let carUpdates = [];
|
let carUpdates = [];
|
||||||
let totalCarUpdates = 0;
|
let totalCarUpdates = 0;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import SendIcon from "@material-ui/icons/Send";
|
import SendIcon from "@material-ui/icons/Send";
|
||||||
import VisibilityIcon from "@material-ui/icons/Visibility";
|
import VisibilityIcon from "@material-ui/icons/Visibility";
|
||||||
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import useStyles from "../../useStyles";
|
import useStyles from "../../useStyles";
|
||||||
import {
|
import {
|
||||||
UpdatesProvider,
|
UpdatesProvider,
|
||||||
@@ -54,14 +55,15 @@ const UpdatePackagesList = () => {
|
|||||||
const [orderBy, setOrderBy] = useState("id");
|
const [orderBy, setOrderBy] = useState("id");
|
||||||
const [order, setOrder] = useState("desc");
|
const [order, setOrder] = useState("desc");
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const { getPackages, packages, totalPackages } = useUpdatesContext();
|
const { getPackages, deletePackage, packages, totalPackages } =
|
||||||
|
useUpdatesContext();
|
||||||
const {
|
const {
|
||||||
token: {
|
token: {
|
||||||
idToken: { jwtToken: token },
|
idToken: { jwtToken: token },
|
||||||
},
|
},
|
||||||
groups,
|
groups,
|
||||||
} = useUserContext();
|
} = useUserContext();
|
||||||
const { setTitle } = useStatusContext();
|
const { setMessage, setTitle } = useStatusContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTitle("Deploy Packages");
|
setTitle("Deploy Packages");
|
||||||
@@ -107,6 +109,14 @@ const UpdatePackagesList = () => {
|
|||||||
setSearch(search);
|
setSearch(search);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onDelete = async (package_id) => {
|
||||||
|
try {
|
||||||
|
await deletePackage(parseInt(package_id), token);
|
||||||
|
} catch (e) {
|
||||||
|
setMessage(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const Actions = (row) => {
|
const Actions = (row) => {
|
||||||
let actions = [];
|
let actions = [];
|
||||||
if (hasRole([Roles.CREATE, Roles.READ], groups)) {
|
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";
|
if (actions.length === 0) return "No actions";
|
||||||
|
|
||||||
return actions.map((action) => (
|
return actions.map((action) => {
|
||||||
<Tooltip key={action.link} title={action.tip}>
|
if (action.link != null) {
|
||||||
<Link to={action.link} style={{ margin: 5 }}>
|
return (
|
||||||
{action.icon}
|
<Tooltip key={action.link} title={action.tip}>
|
||||||
</Link>
|
<Link to={action.link} style={{ margin: 5 }}>
|
||||||
</Tooltip>
|
{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 (
|
return (
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ const updatesAPI = {
|
|||||||
})
|
})
|
||||||
.then(fetchRespHandler),
|
.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) => {
|
getPackages: async (search, token) => {
|
||||||
var u = addQueryParams(`${API_ENDPOINT}/updates`, search);
|
var u = addQueryParams(`${API_ENDPOINT}/updates`, search);
|
||||||
return fetch(u, {
|
return fetch(u, {
|
||||||
|
|||||||
Reference in New Issue
Block a user