show builds on deployment page

This commit is contained in:
beckerinj
2023-01-19 21:05:53 -05:00
parent 4098c6b487
commit 6f697d292a
6 changed files with 67 additions and 24 deletions

View File

@@ -27,8 +27,12 @@ pub fn router() -> Router {
.map(|v| v.as_str().unwrap_or("0").parse().unwrap_or(0))
.unwrap_or(0);
let target = serde_json::from_str::<UpdateTarget>(&value.to_string()).ok();
let show_builds = value
.get("show_builds")
.map(|b| b.as_bool().unwrap_or_default())
.unwrap_or_default();
let updates = state
.list_updates(target, offset, &user)
.list_updates(target, offset, show_builds, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(updates))
@@ -82,14 +86,42 @@ impl State {
&self,
target: Option<UpdateTarget>,
offset: u64,
show_builds: bool,
user: &RequestUser,
) -> anyhow::Result<Vec<Update>> {
let filter = match target {
Some(target) => {
self.permission_on_update_target(&target, user).await?;
Some(doc! {
"target": to_bson(&target).unwrap()
})
if let (UpdateTarget::Deployment(id), true) = (&target, show_builds) {
let deployment = self
.get_deployment_check_permissions(id, user, PermissionLevel::Read)
.await?;
if let Some(build_id) = &deployment.branch {
let build = self
.get_build_check_permissions(build_id, user, PermissionLevel::Read)
.await;
if let Ok(_) = build {
Some(doc! {
"$or": [
{"target": to_bson(&target).unwrap()},
{"target": { "type": "Build", "id": build_id }, "operation": "build_build"}
],
})
} else {
Some(doc! {
"target": to_bson(&target).unwrap()
})
}
} else {
Some(doc! {
"target": to_bson(&target).unwrap()
})
}
} else {
self.permission_on_update_target(&target, user).await?;
Some(doc! {
"target": to_bson(&target).unwrap()
})
}
}
None => {
if user.is_admin {

View File

@@ -4,16 +4,14 @@ import Grid from "../shared/layout/Grid";
import Update from "../update/Update";
import { useAppState } from "../../state/StateProvider";
import { combineClasses } from "../../util/helpers";
import { useParams } from "@solidjs/router";
import { Operation } from "../../types";
import Flex from "../shared/layout/Flex";
import Loading from "../shared/loading/Loading";
const Updates: Component<{}> = (p) => {
const { ws, deployments } = useAppState();
const params = useParams();
const updates = useUpdates({ type: "Deployment", id: params.id });
const buildID = () => deployments.get(params.id)?.deployment.build_id;
const { ws, params, deployment } = useAppState();
const updates = useUpdates({ type: "Deployment", id: params.id! }, true);
const buildID = () => deployment()?.deployment.build_id;
let unsub = () => {};
createEffect(() => {
unsub();

View File

@@ -1,4 +1,4 @@
import { useNavigate } from "@solidjs/router";
import { Params, useNavigate, useParams } from "@solidjs/router";
import { createContext, ParentComponent, useContext } from "solid-js";
import { useWindowKeyDown } from "../util/hooks";
import {
@@ -13,16 +13,19 @@ import {
} from "./hooks";
import connectToWs from "./ws";
import { useUser } from "./UserProvider";
import { PermissionLevel } from "../types";
import { Build, DeploymentWithContainerState, PermissionLevel, ServerWithStatus } from "../types";
export type State = {
usernames: ReturnType<typeof useUsernames>;
servers: ReturnType<typeof useServers>;
server: () => ServerWithStatus | undefined;
getPermissionOnServer: (id: string) => PermissionLevel;
serverStats: ReturnType<typeof useServerStats>;
ungroupedServerIds: () => string[] | undefined;
build: () => Build | undefined;
builds: ReturnType<typeof useBuilds>;
getPermissionOnBuild: (id: string) => PermissionLevel;
deployment: () => DeploymentWithContainerState | undefined;
deployments: ReturnType<typeof useDeployments>;
getPermissionOnDeployment: (id: string) => PermissionLevel;
groups: ReturnType<typeof useGroups>;
@@ -30,6 +33,7 @@ export type State = {
procedures: ReturnType<typeof useProcedures>;
getPermissionOnProcedure: (id: string) => PermissionLevel;
updates: ReturnType<typeof useUpdates>;
params: { id?: string };
};
const context = createContext<
@@ -41,6 +45,7 @@ const context = createContext<
export const AppStateProvider: ParentComponent = (p) => {
const { user, logout } = useUser();
const params = useParams<{ id?: string }>();
const navigate = useNavigate();
const userId = (user()._id as any).$oid as string;
const servers = useServers();
@@ -52,6 +57,7 @@ export const AppStateProvider: ParentComponent = (p) => {
const state: State = {
usernames,
servers,
server: () => servers.get(params.id!),
getPermissionOnServer: (id: string) => {
const server = servers.get(id)!;
const permissions = server.server.permissions![userId] as
@@ -77,6 +83,7 @@ export const AppStateProvider: ParentComponent = (p) => {
});
},
builds,
build: () => builds.get(params.id!),
getPermissionOnBuild: (id: string) => {
const build = builds.get(id)!;
const permissions = build.permissions![userId] as
@@ -88,6 +95,7 @@ export const AppStateProvider: ParentComponent = (p) => {
return PermissionLevel.None;
}
},
deployment: () => deployments.get(params.id!),
deployments,
getPermissionOnDeployment: (id: string) => {
const deployment = deployments.get(id)!;
@@ -126,6 +134,7 @@ export const AppStateProvider: ParentComponent = (p) => {
}
},
updates: useUpdates(),
params,
};
// createEffect(() => {

View File

@@ -124,9 +124,9 @@ export function useDeployments() {
};
}
export function useUpdates(target?: UpdateTarget) {
export function useUpdates(target?: UpdateTarget, show_builds?: boolean) {
const updates = useArrayWithId(
() => client.list_updates(0, target),
() => client.list_updates(0, target, show_builds),
["_id", "$oid"]
);
const [noMore, setNoMore] = createSignal(false);

View File

@@ -404,13 +404,14 @@ export class Client {
}
// updates
list_updates(offset: number, target?: UpdateTarget): Promise<Update[]> {
// show_builds is only relevant for Deployment targets, must pass show_builds = true to include build updates of attached build_id
list_updates(offset: number, target?: UpdateTarget, show_builds?: boolean): Promise<Update[]> {
return this.get(
`/api/update/list${generateQuery({
offset,
type: target && target.type,
id: target && target.id,
show_builds,
})}`
);
}

View File

@@ -87,21 +87,24 @@ impl PeripheryClient {
Ok(socket)
}
async fn get_text(&self, server: &Server, endpoint: &str, timeout_ms: impl Into<Option<u64>>) -> anyhow::Result<String> {
async fn get_text(
&self,
server: &Server,
endpoint: &str,
timeout_ms: impl Into<Option<u64>>,
) -> anyhow::Result<String> {
let mut req = self
.http_client
.get(format!("{}{endpoint}", server.address));
if let Some(timeout) = timeout_ms.into() {
req = req.timeout(Duration::from_millis(timeout))
}
let res = req.send()
.await
.context(format!(
"failed at get request to server {} | not reachable",
server.name
))?;
let res = req.send().await.context(format!(
"failed at get request to server {} | not reachable",
server.name
))?;
let status = res.status();
if status == StatusCode::OK {
let text = res.text().await.context("failed at parsing response")?;