mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-14 13:33:00 +00:00
Admin server buttons depending on the status (pending, running or stopped)
Fixes #4466
This commit is contained in:
@@ -21,14 +21,6 @@ import "./server-dashboard.css";
|
|||||||
import { timeSince } from "../../util/timeSince";
|
import { timeSince } from "../../util/timeSince";
|
||||||
import PaginationFooter from "../PaginationFooter/PaginationFooter";
|
import PaginationFooter from "../PaginationFooter/PaginationFooter";
|
||||||
|
|
||||||
const AccessServerButton = ({ url }) => (
|
|
||||||
<a href={url || ""}>
|
|
||||||
<button className="btn btn-primary btn-xs" style={{ marginRight: 20 }}>
|
|
||||||
Access Server
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
|
|
||||||
const RowListItem = ({ text }) => (
|
const RowListItem = ({ text }) => (
|
||||||
<span className="server-dashboard-row-list-item">{text}</span>
|
<span className="server-dashboard-row-list-item">{text}</span>
|
||||||
);
|
);
|
||||||
@@ -56,7 +48,6 @@ const ServerDashboard = (props) => {
|
|||||||
|
|
||||||
var [errorAlert, setErrorAlert] = useState(null);
|
var [errorAlert, setErrorAlert] = useState(null);
|
||||||
var [sortMethod, setSortMethod] = useState(null);
|
var [sortMethod, setSortMethod] = useState(null);
|
||||||
var [disabledButtons, setDisabledButtons] = useState({});
|
|
||||||
var [collapseStates, setCollapseStates] = useState({});
|
var [collapseStates, setCollapseStates] = useState({});
|
||||||
|
|
||||||
var user_data = useSelector((state) => state.user_data),
|
var user_data = useSelector((state) => state.user_data),
|
||||||
@@ -128,15 +119,15 @@ const ServerDashboard = (props) => {
|
|||||||
user_data = sortMethod(user_data);
|
user_data = sortMethod(user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const StopServerButton = ({ serverName, userName }) => {
|
const ServerButton = ({ server, user, action, name, extraClass }) => {
|
||||||
var [isDisabled, setIsDisabled] = useState(false);
|
var [isDisabled, setIsDisabled] = useState(false);
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className="btn btn-danger btn-xs stop-button"
|
className={`btn btn-xs ${extraClass}`}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled || server.pending}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsDisabled(true);
|
setIsDisabled(true);
|
||||||
stopServer(userName, serverName)
|
action(user.name, server.name)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status < 300) {
|
if (res.status < 300) {
|
||||||
updateUsers(...slice)
|
updateUsers(...slice)
|
||||||
@@ -152,103 +143,87 @@ const ServerDashboard = (props) => {
|
|||||||
setErrorAlert(`Failed to update users list.`);
|
setErrorAlert(`Failed to update users list.`);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setErrorAlert(`Failed to stop server.`);
|
setErrorAlert(`Failed to ${name.toLowerCase()}.`);
|
||||||
setIsDisabled(false);
|
setIsDisabled(false);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setErrorAlert(`Failed to stop server.`);
|
setErrorAlert(`Failed to ${name.toLowerCase()}.`);
|
||||||
setIsDisabled(false);
|
setIsDisabled(false);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Stop Server
|
{name}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const DeleteServerButton = ({ serverName, userName }) => {
|
const StopServerButton = ({ server, user }) => {
|
||||||
if (serverName === "") {
|
if (!server.ready) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var [isDisabled, setIsDisabled] = useState(false);
|
return ServerButton({
|
||||||
return (
|
server,
|
||||||
<button
|
user,
|
||||||
className="btn btn-danger btn-xs stop-button"
|
action: stopServer,
|
||||||
|
name: "Stop Server",
|
||||||
|
extraClass: "btn-danger stop-button",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const DeleteServerButton = ({ server, user }) => {
|
||||||
|
if (server.name === "") {
|
||||||
// It's not possible to delete unnamed servers
|
// It's not possible to delete unnamed servers
|
||||||
disabled={isDisabled}
|
return null;
|
||||||
onClick={() => {
|
|
||||||
setIsDisabled(true);
|
|
||||||
deleteServer(userName, serverName)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.status < 300) {
|
|
||||||
updateUsers(...slice)
|
|
||||||
.then((data) => {
|
|
||||||
dispatchPageUpdate(
|
|
||||||
data.items,
|
|
||||||
data._pagination,
|
|
||||||
name_filter,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setIsDisabled(false);
|
|
||||||
setErrorAlert(`Failed to update users list.`);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setErrorAlert(`Failed to delete server.`);
|
|
||||||
setIsDisabled(false);
|
|
||||||
}
|
}
|
||||||
return res;
|
if (server.ready || server.pending) {
|
||||||
})
|
return null;
|
||||||
.catch(() => {
|
}
|
||||||
setErrorAlert(`Failed to delete server.`);
|
return ServerButton({
|
||||||
setIsDisabled(false);
|
server,
|
||||||
|
user,
|
||||||
|
action: deleteServer,
|
||||||
|
name: "Delete Server",
|
||||||
|
extraClass: "btn-danger stop-button",
|
||||||
});
|
});
|
||||||
}}
|
};
|
||||||
|
|
||||||
|
const StartServerButton = ({ server, user }) => {
|
||||||
|
if (server.ready) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ServerButton({
|
||||||
|
server,
|
||||||
|
user,
|
||||||
|
action: startServer,
|
||||||
|
name: server.pending ? "Server is pending" : "Start Server",
|
||||||
|
extraClass: "btn-success start-button",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const SpawnPageButton = ({ server, user }) => {
|
||||||
|
if (server.ready) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={`${base_url}spawn/${user.name}${
|
||||||
|
server.name ? "/" + server.name : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
Delete Server
|
<button className="btn btn-light btn-xs">Spawn Page</button>
|
||||||
</button>
|
</a>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const StartServerButton = ({ serverName, userName }) => {
|
const AccessServerButton = ({ server }) => {
|
||||||
var [isDisabled, setIsDisabled] = useState(false);
|
if (!server.ready) {
|
||||||
return (
|
return null;
|
||||||
<button
|
|
||||||
className="btn btn-success btn-xs start-button"
|
|
||||||
disabled={isDisabled}
|
|
||||||
onClick={() => {
|
|
||||||
setIsDisabled(true);
|
|
||||||
startServer(userName, serverName)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.status < 300) {
|
|
||||||
updateUsers(...slice)
|
|
||||||
.then((data) => {
|
|
||||||
dispatchPageUpdate(
|
|
||||||
data.items,
|
|
||||||
data._pagination,
|
|
||||||
name_filter,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setErrorAlert(`Failed to update users list.`);
|
|
||||||
setIsDisabled(false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setErrorAlert(`Failed to start server.`);
|
|
||||||
setIsDisabled(false);
|
|
||||||
}
|
}
|
||||||
return res;
|
return (
|
||||||
})
|
<a href={server.url || ""}>
|
||||||
.catch(() => {
|
<button className="btn btn-primary btn-xs">Access Server</button>
|
||||||
setErrorAlert(`Failed to start server.`);
|
</a>
|
||||||
setIsDisabled(false);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Start Server
|
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -358,39 +333,12 @@ const ServerDashboard = (props) => {
|
|||||||
<td data-testid="user-row-last-activity">
|
<td data-testid="user-row-last-activity">
|
||||||
{server.last_activity ? timeSince(server.last_activity) : "Never"}
|
{server.last_activity ? timeSince(server.last_activity) : "Never"}
|
||||||
</td>
|
</td>
|
||||||
<td data-testid="user-row-server-activity">
|
<td data-testid="user-row-server-activity" className="actions">
|
||||||
{server.ready ? (
|
<StartServerButton server={server} user={user} />
|
||||||
// Stop Single-user server
|
<StopServerButton server={server} user={user} />
|
||||||
<>
|
<DeleteServerButton server={server} user={user} />
|
||||||
<StopServerButton serverName={server.name} userName={user.name} />
|
<AccessServerButton server={server} />
|
||||||
<AccessServerButton url={server.url} />
|
<SpawnPageButton server={server} user={user} />
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
// Start Single-user server
|
|
||||||
<>
|
|
||||||
<StartServerButton
|
|
||||||
serverName={server.name}
|
|
||||||
userName={user.name}
|
|
||||||
style={{ marginRight: 20 }}
|
|
||||||
/>
|
|
||||||
<DeleteServerButton
|
|
||||||
serverName={server.name}
|
|
||||||
userName={user.name}
|
|
||||||
/>
|
|
||||||
<a
|
|
||||||
href={`${base_url}spawn/${user.name}${
|
|
||||||
server.name ? "/" + server.name : ""
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="btn btn-secondary btn-xs"
|
|
||||||
style={{ marginRight: 20 }}
|
|
||||||
>
|
|
||||||
Spawn Page
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</td>
|
</td>
|
||||||
<EditUserCell user={user} />
|
<EditUserCell user={user} />
|
||||||
</tr>,
|
</tr>,
|
||||||
|
16077
jsx/yarn.lock
16077
jsx/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user