import React from "react";
import { action, autorun, makeObservable, observable } from "mobx";
import { observer } from "mobx-react";
import classNames from "classnames";
import { validators } from "eez-studio-shared/validation";
import { ButtonAction, IconAction } from "eez-studio-ui/action";
import { showGenericDialog } from "eez-studio-ui/generic-dialog";
import {
Body,
ToolbarHeader,
VerticalHeaderWithBody
} from "eez-studio-ui/header-with-body";
import { confirm } from "eez-studio-ui/dialog-electron";
import type { IAppStore } from "instrument/window/history/history";
import {
historySessions,
IHistorySession,
SESSION_FREE_ID
} from "instrument/window/history/session/store";
export function showEditSessionNameDialog(
session: IHistorySession | undefined,
callback: (name: string) => void
) {
showGenericDialog({
dialogDefinition: {
title: session ? "Edit Session Name" : "New Session",
fields: [
{
name: "name",
type: "string",
validators: [
validators.required,
validators.unique(
session,
historySessions.sessions,
"A session with this name already exists."
)
]
}
]
},
values: {
name: session?.name ?? ""
}
})
.then(result => callback(result.values.name))
.catch(() => {});
}
export const SessionListItem = observer(
class SessionListItem extends React.Component<{
appStore: IAppStore;
session: IHistorySession;
isSelected: boolean;
onSelect: () => void;
}> {
get lastActivity() {
const lastActivity = historySessions.getLastActivity(
this.props.session
);
return lastActivity ? lastActivity.toLocaleString() : "";
}
render() {
let className = classNames({
selected: this.props.isSelected,
session_free_mode: this.props.session.id == SESSION_FREE_ID
});
return (
| {this.props.session.name} |
{this.lastActivity} |
);
}
}
);
export const SessionList = observer(
class SessionList extends React.Component<{
appStore: IAppStore;
}> {
ref = React.createRef();
sortBy: string = "name-asc";
constructor(props: any) {
super(props);
this.sortBy =
window.localStorage.getItem("session-list-sort") ?? "name-asc";
makeObservable(this, {
sortBy: observable
});
autorun(() => {
window.localStorage.setItem("session-list-sort", this.sortBy);
});
}
get sessions() {
const sessions = (
historySessions.showDeleted
? historySessions.deletedSessions
: historySessions.sessions
).slice();
const sortedSessions = sessions.slice(1);
sortedSessions.sort((a, b) => {
let result;
if (this.sortBy.startsWith("name")) {
result = b.name
.toLowerCase()
.localeCompare(a.name.toLowerCase());
} else {
const aLastActivity = historySessions.getLastActivity(a);
const bLastActivity = historySessions.getLastActivity(b);
if (!aLastActivity && !bLastActivity) {
result = 0;
} else if (!aLastActivity) {
result = this.sortBy.endsWith("asc") ? -1 : 1;
} else if (!bLastActivity) {
result = this.sortBy.endsWith("asc") ? 1 : -1;
} else {
result =
aLastActivity < bLastActivity
? 1
: aLastActivity > bLastActivity
? -1
: 0;
}
}
if (this.sortBy.endsWith("asc")) {
result = -result;
}
return result;
});
return [sessions[0], ...sortedSessions];
}
componentDidMount() {
this.ensureSelectedVisible();
}
componentDidUpdate() {
this.ensureSelectedVisible();
}
ensureSelectedVisible() {
const container = this.ref.current;
if (container) {
const selected = container.querySelector(".selected");
if (selected) {
const rectSelected = selected.getBoundingClientRect();
const rectContainer = container.getBoundingClientRect();
const margin = 2 * rectSelected.height;
let y = rectSelected.y - rectContainer.y;
const scrollTop = container.parentElement!.scrollTop;
const height = container.parentElement!.clientHeight;
if (scrollTop > y - margin) {
container.parentElement!.scrollTop = y - margin;
} else if (
scrollTop + height <
y + rectSelected.height + margin
) {
container.parentElement!.scrollTop =
y + rectSelected.height + margin - height;
}
}
}
}
newSession = () => {
showEditSessionNameDialog(undefined, name => {
historySessions.createNewSession(name);
});
};
handleEditSessionName = () => {
const selectedSession = historySessions.selectedSession;
if (selectedSession) {
showEditSessionNameDialog(selectedSession, name => {
historySessions.updateSessionName(selectedSession, name);
});
}
};
handleDeleteSession = () => {
const selectedSession = historySessions.selectedSession;
if (selectedSession) {
confirm("Are you sure?", undefined, () => {
historySessions.deleteSession(selectedSession);
});
}
};
handleDeleteForeverSession = () => {
const session = historySessions.selectedSession;
if (session) {
confirm(
"Are you sure?",
"This will irrevocably delete the selected session and all history items belonging to the session.",
() => {
historySessions.deleteForeverSession(session);
}
);
}
};
render() {
return (
{historySessions.showDeleted ? (
<>
historySessions.restoreSession(
historySessions.selectedSession
)
}
enabled={
historySessions.selectedSession !=
undefined
}
/>
historySessions.setShowDeleted(false)
}
className="btn-secondary btn-sm"
/>
>
) : (
<>
{historySessions.deletedSessions.length > 0 && (
historySessions.setShowDeleted(true)
}
className="btn-secondary btn-sm"
style={{ marginLeft: 20 }}
/>
)}
>
)}
| {
if (this.sortBy == "name-asc") {
this.sortBy = "name-desc";
} else {
this.sortBy = "name-asc";
}
})}
>
Name
|
{
if (
this.sortBy ==
"last-activity-asc"
) {
this.sortBy =
"last-activity-desc";
} else {
this.sortBy =
"last-activity-asc";
}
})}
>
Last Activity
|
{this.sessions.map(session => (
{
if (
historySessions.showDeleted
) {
historySessions.selectSession(
session
);
} else {
historySessions.activateSession(
session.id
);
}
})}
/>
))}
);
}
}
);