import { dialog, getCurrentWindow } from "@electron/remote"; import React from "react"; import { observable, computed, action, runInAction, values, toJS, autorun, makeObservable } from "mobx"; import { observer } from "mobx-react"; import { stringCompare } from "eez-studio-shared/string"; import { beginTransaction, commitTransaction } from "eez-studio-shared/store"; import { sendSimpleMessage } from "eez-studio-shared/util-renderer"; import { Splitter } from "eez-studio-ui/splitter"; import { VerticalHeaderWithBody, ToolbarHeader, Body } from "eez-studio-ui/header-with-body"; import { IconAction, DropdownIconAction, DropdownItem } from "eez-studio-ui/action"; import { List as ListComponent } from "eez-studio-ui/list"; import { confirm } from "eez-studio-ui/dialog-electron"; import { showGenericDialog } from "eez-studio-ui/generic-dialog"; import { validators } from "eez-studio-shared/validation"; import { IAppStore, SelectHistoryItemsSpecification, History, DeletedItemsHistory, IInstrumentObject } from "instrument/window/history/history"; import { Filters } from "instrument/window/history/filters"; import { HistoryTools, HistoryView } from "instrument/window/history/history-view"; import { DeletedHistoryItemsTools, DeletedHistoryItemsView } from "instrument/window/history/deleted-history-items-view"; import { INotebook, notebooks, addNotebook, deleteNotebook, updateNotebook, deletedNotebooks, itemsStore } from "notebook/store"; import { importNotebook } from "notebook/import"; import { showDeletedNotebooksDialog } from "notebook/deleted-notebooks-dialog"; import type { IUnit } from "eez-studio-shared/units"; //////////////////////////////////////////////////////////////////////////////// class NotebooksHomeSectionStore { private _selectedNotebook: INotebook | undefined; showDeletedHistoryItems = false; constructor() { makeObservable(this, { _selectedNotebook: observable, showDeletedHistoryItems: observable, appStore: computed }); autorun(() => { if ( this.selectedNotebook && !notebooks.get(this.selectedNotebook.id) ) { runInAction(() => { this._selectedNotebook = undefined; }); } if ( this.appStore && this.appStore.deletedItemsHistory.deletedCount === 0 ) { runInAction(() => { this.showDeletedHistoryItems = false; }); } }); } get selectedNotebook() { return this._selectedNotebook; } set selectedNotebook(value: INotebook | undefined) { runInAction(() => { this._selectedNotebook = value; this.showDeletedHistoryItems = false; }); } get appStore() { if (this._selectedNotebook) { return new AppStore(this._selectedNotebook.id); } return null; } } const notebooksHomeSectionStore = new NotebooksHomeSectionStore(); //////////////////////////////////////////////////////////////////////////////// const MasterView = observer( class MasterView extends React.Component { constructor(props: any) { super(props); makeObservable(this, { sortedNotebooks: computed }); } get sortedNotebooks() { return Array.from(notebooks.values()) .sort((a, b) => stringCompare(a.name, b.name)) .map(notebook => ({ id: notebook.id, data: notebook, selected: notebooksHomeSectionStore.selectedNotebook !== undefined && notebook.id === notebooksHomeSectionStore.selectedNotebook.id })); } addNotebook = () => { showGenericDialog({ dialogDefinition: { fields: [ { name: "name", displayName: "Notebook name", type: "string", validators: [ validators.required, validators.unique( {}, values(notebooks), "Notebook with the same name already exists" ) ] } ] }, values: { name: "" } }) .then(result => { beginTransaction("Add notebook"); const notebookId = addNotebook(result.values); commitTransaction(); setTimeout(() => { notebooksHomeSectionStore.selectedNotebook = notebooks.get(notebookId); setTimeout(() => { let element = document.querySelector( `.EezStudio_Notebook_${notebookId}` ); if (element) { element.scrollIntoView(); } }, 10); }, 10); }) .catch(() => {}); }; importNotebook = async () => { const result = await dialog.showOpenDialog(getCurrentWindow(), { properties: ["openFile"], filters: [ { name: "EEZ Notebook files", extensions: ["eez-notebook"] }, { name: "All Files", extensions: ["*"] } ] }); const filePaths = result.filePaths; if (filePaths && filePaths[0]) { importNotebook(filePaths[0], { showNotebook: true }); } }; removeNotebook = () => { confirm("Are you sure?", undefined, () => { beginTransaction("Remove notebook"); deleteNotebook( toJS(notebooksHomeSectionStore.selectedNotebook!) ); commitTransaction(); }); }; showDeletedNotebooks = () => { showDeletedNotebooksDialog(); }; changeNotebookName = () => { showGenericDialog({ dialogDefinition: { fields: [ { name: "name", displayName: "Name", type: "string", validators: [ validators.required, validators.unique( notebooksHomeSectionStore.selectedNotebook, values(notebooks), "Notebook with the same name already exists" ) ] } ] }, values: notebooksHomeSectionStore.selectedNotebook }) .then(result => { beginTransaction("Rename notebook"); updateNotebook( Object.assign( {}, notebooksHomeSectionStore.selectedNotebook, result.values ) ); commitTransaction(); }) .catch(() => {}); }; render() { return ( 0} onClick={this.showDeletedNotebooks} /> (
{node.data.name}
)} selectNode={node => (notebooksHomeSectionStore.selectedNotebook = node.data) } />
); } } ); //////////////////////////////////////////////////////////////////////////////// class AppStore implements IAppStore { constructor(public notebookId: string) { makeObservable(this, { selectHistoryItemsSpecification: observable, selectedHistoryItems: observable, selectHistoryItem: action, selectHistoryItems: action }); this.history = new History(this, { store: itemsStore, isSessionsSupported: false, oid: this.notebookId }); this.deletedItemsHistory = new DeletedItemsHistory(this, { store: itemsStore, oid: this.notebookId }); } selectHistoryItemsSpecification: | SelectHistoryItemsSpecification | undefined; selectedHistoryItems = new Map(); instrument: IInstrumentObject = { id: "0", connection: { abortLongOperation() { // @todo }, isConnected: false, isPlotterEnabled: false }, listsMinDwellProperty: 0, listsMaxDwellProperty: 0, firstChannel: undefined, getDigits: (unit: IUnit) => 3, listsMaxPointsProperty: 0, listsCurrentDigitsProperty: 0, listsDwellDigitsProperty: 0, listsVoltageDigitsProperty: 0, commandsProtocol: "SCPI" }; instrumentLists = []; filters: Filters = new Filters(); history: History; deletedItemsHistory: DeletedItemsHistory; isHistoryItemSelected(id: string): boolean { return this.selectedHistoryItems.has(id); } selectHistoryItem(id: string, selected: boolean): void { if (selected) { this.selectedHistoryItems.set(id, true); } else { this.selectedHistoryItems.delete(id); } } selectHistoryItems( specification: SelectHistoryItemsSpecification | undefined ) { this.selectHistoryItemsSpecification = specification; this.selectedHistoryItems.clear(); } navigationStore = { navigateToHistory() { runInAction( () => (notebooksHomeSectionStore.showDeletedHistoryItems = false) ); }, navigateToDeletedHistoryItems() { runInAction( () => (notebooksHomeSectionStore.showDeletedHistoryItems = true) ); }, navigateToSessionsList() {}, mainHistoryView: undefined, selectedListId: undefined, async changeSelectedListId() {} }; searchViewSection: "calendar" | "sessions" = "calendar"; setSearchViewSection(value: "calendar" | "sessions"): void { // @todo } findListIdByName(listName: string): string | undefined { // @todo return undefined; } } //////////////////////////////////////////////////////////////////////////////// export const DetailsView = observer( class DetailsView extends React.Component { render() { if (notebooksHomeSectionStore.showDeletedHistoryItems) { return ( ); } else { return ( ); } } } ); //////////////////////////////////////////////////////////////////////////////// const NotebooksHomeSection = observer( class NotebooksHomeSection extends React.Component { render() { return ( {notebooksHomeSectionStore.selectedNotebook ? ( ) : (
)} ); } } ); //////////////////////////////////////////////////////////////////////////////// export function showNotebook(notebookId: string) { sendSimpleMessage("home/show-section", { sectionId: "notebooks", itemId: notebookId }); } //////////////////////////////////////////////////////////////////////////////// export function renderContent() { return ; } export function selectItem(itemId: string) { runInAction(() => { notebooksHomeSectionStore.selectedNotebook = notebooks.get(itemId); }); }