in src/devtools/views/StoreInspector/StoreInspector.js [154:342]
export default function StoreInspector(props: {|
+portalContainer: mixed,
currentEnvID: ?number,
|}) {
const store = useContext(StoreContext);
const bridge = useContext(BridgeContext);
const [tab, setTab] = useState(explorerTab);
const selectTab = useCallback(
tabInfo => {
logEvent({ event_name: 'selected-store-tab', extra: tabInfo.id });
setTab(tabInfo);
},
[setTab]
);
const [, forceUpdate] = useState({});
const [envSnapshotList, setEnvSnapshotList] = useState({});
const [envSnapshotListByType, setEnvSnapshotListByType] = useState({});
const [isRecording, setIsRecording] = useState(false);
const [checked, setChecked] = useState({
networkEvents: true,
storeEvents: true,
});
const stopAndClearRecording = useCallback(() => {
setIsRecording(false);
store.stopRecording();
store.clearAllEvents();
}, [store, setIsRecording]);
const stopRecording = useCallback(() => {
setIsRecording(false);
store.stopRecording();
}, [store, setIsRecording]);
const startRecording = useCallback(() => {
setIsRecording(true);
store.startRecording();
}, [store, setIsRecording]);
useEffect(() => {
const refreshEvents = () => {
forceUpdate({});
};
store.addListener('storeDataReceived', refreshEvents);
store.addListener('allEventsReceived', refreshEvents);
return () => {
store.removeListener('storeDataReceived', refreshEvents);
store.removeListener('allEventsReceived', refreshEvents);
};
}, [store]);
const [selectedRecordID, setSelectedRecordID] = useState('');
let records = {};
const recordsByType = new Map();
const refreshStore = useCallback(() => {
const currEnvID = props.currentEnvID;
if (currEnvID != null) {
const recordsArr = envSnapshotList[currEnvID] || [];
recordsArr.push(deepCopyFunction(records));
const recordsTypeArr = envSnapshotListByType[currEnvID] || [];
recordsTypeArr.push(deepCopyFunction(recordsByType));
setEnvSnapshotList({ ...envSnapshotList, [currEnvID]: recordsArr });
setEnvSnapshotListByType({
...envSnapshotListByType,
[currEnvID]: recordsTypeArr,
});
bridge.send('refreshStore', currEnvID);
}
}, [
props,
bridge,
records,
recordsByType,
envSnapshotList,
envSnapshotListByType,
]);
const copyToClipboard = useCallback(() => {
copy(serializeDataForCopy(records));
}, [records]);
const currentEnvID = props.currentEnvID;
if (currentEnvID == null) {
return null;
}
const recordingImportEnvironmentID = store.getImportEnvID();
const allEvents = recordingImportEnvironmentID
? store.getEvents(recordingImportEnvironmentID)
: store.getEvents(currentEnvID);
records = store.getRecords(currentEnvID);
const optimisticUpdates = store.getOptimisticUpdates(currentEnvID);
let selectedRecord = {};
if (records != null) {
for (const key in records) {
const rec = records[key];
if (rec != null) {
const arr = recordsByType.get(rec.__typename);
if (arr) {
arr.push(key);
} else {
recordsByType.set(rec.__typename, [key]);
}
}
}
selectedRecord = records[selectedRecordID];
}
if (records == null) {
return null;
}
return (
<div className={styles.StoreInspector}>
<div className={styles.Toolbar}>
<button
className={styles.RefreshButton}
onClick={refreshStore}
title="Take Store Snapshot"
>
Take Store Snapshot
</button>
<Button onClick={copyToClipboard} title="Copy to clipboard">
<ButtonIcon type="copy" />
</Button>
<div className={styles.Spacer} />
</div>
<div className={styles.TabBar}>
<div className={styles.Spacer} />
<TabBar
tabID={tab.id}
id="StoreTab"
selectTab={selectTab}
size="small"
tabs={tabs}
/>
</div>
<div className={styles.Content}>
{tab === explorerTab && (
<div className={styles.TabContent}>
<RecordList
records={records}
recordsByType={recordsByType}
selectedRecordID={selectedRecordID}
setSelectedRecordID={setSelectedRecordID}
/>
<RecordDetails
records={records}
setSelectedRecordID={setSelectedRecordID}
selectedRecord={selectedRecord}
/>
</div>
)}
{tab === snapshotTab && (
<div className={styles.TabContent}>
<Snapshots
envSnapshotList={envSnapshotList}
envSnapshotListByType={envSnapshotListByType}
currentEnvID={props.currentEnvID}
/>
</div>
)}
{tab === optimisticTab && (
<div className={styles.TabContent}>
<Optimistic optimisticUpdates={optimisticUpdates} />
</div>
)}
{tab === recorderTab && (
<div className={styles.RecordEvents}>
<RecordEventsMenu
isRecording={isRecording}
stopRecording={stopRecording}
startRecording={startRecording}
stopAndClearRecording={stopAndClearRecording}
store={store}
checked={checked}
setChecked={setChecked}
/>
<EventLogger
allEvents={allEvents}
isRecording={isRecording}
checked={checked}
/>
</div>
)}
</div>
</div>
);
}