mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-10 04:56:56 +00:00
Fix bug publish screenshot (#762)
[Preview this branch](https://cosmos-explorer-preview.azurewebsites.net/pull/762?feature.someFeatureFlagYouMightNeed=true) The main change in this PR fixes the snapshot functionality in the Publish pane-related components. Because the code cell outputs are now rendered in their own iframes for security reasons, a single snapshot of the notebook is no longer possible: each cell output takes its own snapshot and the snapshots are collated on the main notebook snapshot. - Move the snapshot functionality to notebook components: this removes the reference of the notebook DOM node that we must pass to the Publish pane via explorer. - Add slice in the state and actions in notebook redux for notebook snapshot requests and result - Add post robot message to take snapshots and receive results - Add logic in `NotebookRenderer` to wait for all output snapshots done before taking the main one collating. - Use `zustand` to share snapshot between Redux world and React world. This solves the issue of keeping the `PanelContainer` component generic, while being able to update its children (`PublishPanel` component) with the new snapshot. Additional changes: - Add `local()` in `@font-face` to check if font is already installed before downloading the font (must be done for Safari, but not Edge/Chrome) - Add "Export output to image" menu item in notebook cell, since each cell output can take its own snapshot (which can be downloaded) 
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { ContextualMenuItemType, DirectionalHint, IconButton, IContextualMenuItem } from "@fluentui/react";
|
||||
import { CellId, CellType } from "@nteract/commutable";
|
||||
import { CellId, CellType, ImmutableCodeCell } from "@nteract/commutable";
|
||||
import { actions, AppState, DocumentRecordProps } from "@nteract/core";
|
||||
import * as selectors from "@nteract/selectors";
|
||||
import { CellToolbarContext } from "@nteract/stateful-components";
|
||||
@@ -10,6 +10,8 @@ import { connect } from "react-redux";
|
||||
import { Dispatch } from "redux";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as cdbActions from "../NotebookComponent/actions";
|
||||
import { SnapshotRequest } from "../NotebookComponent/types";
|
||||
import { NotebookUtil } from "../NotebookUtil";
|
||||
|
||||
export interface ComponentProps {
|
||||
contentRef: ContentRef;
|
||||
@@ -26,12 +28,14 @@ interface DispatchProps {
|
||||
clearOutputs: () => void;
|
||||
deleteCell: () => void;
|
||||
traceNotebookTelemetry: (action: Action, actionModifier?: string, data?: any) => void;
|
||||
takeNotebookSnapshot: (payload: SnapshotRequest) => void;
|
||||
}
|
||||
|
||||
interface StateProps {
|
||||
cellType: CellType;
|
||||
cellIdAbove: CellId;
|
||||
cellIdBelow: CellId;
|
||||
hasCodeOutput: boolean;
|
||||
}
|
||||
|
||||
class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & StateProps> {
|
||||
@@ -58,11 +62,29 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksClearOutputsFromMenu, ActionModifiers.Mark);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Divider",
|
||||
itemType: ContextualMenuItemType.Divider,
|
||||
},
|
||||
]);
|
||||
|
||||
if (this.props.hasCodeOutput) {
|
||||
items.push({
|
||||
key: "Export output to image",
|
||||
text: "Export output to image",
|
||||
onClick: () => {
|
||||
this.props.takeNotebookSnapshot({
|
||||
requestId: new Date().getTime().toString(),
|
||||
aspectRatio: undefined,
|
||||
type: "celloutput",
|
||||
cellId: this.props.id,
|
||||
notebookContentRef: this.props.contentRef,
|
||||
downloadFilename: `celloutput-${this.props.contentRef}_${this.props.id}.png`,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
items.push({
|
||||
key: "Divider",
|
||||
itemType: ContextualMenuItemType.Divider,
|
||||
});
|
||||
}
|
||||
|
||||
items = items.concat([
|
||||
@@ -183,12 +205,13 @@ const mapDispatchToProps = (
|
||||
deleteCell: () => dispatch(actions.deleteCell({ id, contentRef })),
|
||||
traceNotebookTelemetry: (action: Action, actionModifier?: string, data?: any) =>
|
||||
dispatch(cdbActions.traceNotebookTelemetry({ action, actionModifier, data })),
|
||||
takeNotebookSnapshot: (request: SnapshotRequest) => dispatch(cdbActions.takeNotebookSnapshot(request)),
|
||||
});
|
||||
|
||||
const makeMapStateToProps = (state: AppState, ownProps: ComponentProps): ((state: AppState) => StateProps) => {
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
const cellType = selectors.cell.cellFromState(state, { id: ownProps.id, contentRef: ownProps.contentRef })
|
||||
.cell_type;
|
||||
const cell = selectors.cell.cellFromState(state, { id: ownProps.id, contentRef: ownProps.contentRef });
|
||||
const cellType = cell.cell_type;
|
||||
const model = selectors.model(state, { contentRef: ownProps.contentRef });
|
||||
const cellOrder = selectors.notebook.cellOrder(model as RecordOf<DocumentRecordProps>);
|
||||
const cellIndex = cellOrder.indexOf(ownProps.id);
|
||||
@@ -199,6 +222,7 @@ const makeMapStateToProps = (state: AppState, ownProps: ComponentProps): ((state
|
||||
cellType,
|
||||
cellIdAbove,
|
||||
cellIdBelow,
|
||||
hasCodeOutput: cellType === "code" && NotebookUtil.hasCodeCellOutput(cell as ImmutableCodeCell),
|
||||
};
|
||||
};
|
||||
return mapStateToProps;
|
||||
|
||||
Reference in New Issue
Block a user