Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added button to execute all query cells in a datadoc after the current cell #1296

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion querybook/server/datasources/datadoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def run_data_doc(id):


@register("/datadoc/<int:id>/run/", methods=["POST"])
def adhoc_run_data_doc(id, send_notification=False):
def adhoc_run_data_doc(id, start_index=0, send_notification=False):
assert_can_write(id)
verify_data_doc_permission(id)

Expand All @@ -403,6 +403,7 @@ def adhoc_run_data_doc(id, send_notification=False):
args=[],
kwargs={
"doc_id": id,
"start_index": start_index,
"user_id": current_user.id,
"execution_type": QueryExecutionType.ADHOC.value,
"notifications": notifications,
Expand Down
3 changes: 2 additions & 1 deletion querybook/server/tasks/run_datadoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def run_datadoc(self, *args, **kwargs):
def run_datadoc_with_config(
self,
doc_id,
start_index=0,
notifications=[],
user_id=None,
execution_type=QueryExecutionType.SCHEDULED.value,
Expand All @@ -56,7 +57,7 @@ def run_datadoc_with_config(
return

runner_id = user_id if user_id is not None else data_doc.owner_uid
query_cells = data_doc.get_query_cells()
query_cells = (data_doc.get_query_cells())[start_index:]

# Create db entry record only for scheduled run
if execution_type == QueryExecutionType.SCHEDULED.value:
Expand Down
8 changes: 8 additions & 0 deletions querybook/webapp/components/DataDocCell/DataDocCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import * as dataDocSelectors from 'redux/dataDoc/selector';
import { IStoreState } from 'redux/store/types';

import './DataDocCell.scss';
import { useRunAllFromIndex } from 'hooks/dataDoc/useRunAllFromIndex';

interface IDataDocCellProps {
docId: number;
Expand Down Expand Up @@ -80,6 +81,12 @@ export const DataDocCell: React.FunctionComponent<IDataDocCellProps> =
fullScreenCellIndex,
} = useContext(DataDocContext);

const onRunAllFromIndex = useRunAllFromIndex(
docId,
queryIndexInDoc
);
console.log(onRunAllFromIndex);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove console.log


const cellIdtoUid = useMakeSelector(
dataDocSelectors.makeDataDocCursorByCellIdSelector,
docId
Expand Down Expand Up @@ -186,6 +193,7 @@ export const DataDocCell: React.FunctionComponent<IDataDocCellProps> =
templatedVariables,
isFullScreen,
toggleFullScreen,
onRunAllFromIndex,
};
cellDOM = <DataDocQueryCell {...allProps} />;
} else if (cell.cell_type === 'chart') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ interface IOwnProps {
onUpKeyPressed?: () => any;
onDownKeyPressed?: () => any;
toggleFullScreen: () => any;
onRunAllFromIndex: () => any;
}
type IProps = IOwnProps & StateProps & DispatchProps;

Expand Down Expand Up @@ -555,6 +556,17 @@ class DataDocQueryCellComponent extends React.PureComponent<IProps, IState> {
tooltipPos: 'left',
});

additionalButtons.push({
name: 'Run From Current Cell',
onClick: () => {
this.props.onRunAllFromIndex();
},
icon: 'FastForward',
tooltip:
'Run all cells in the current datadoc starting from this cell',
tooltipPos: 'left',
});

additionalButtons.push({
name: queryCollapsed ? 'Show Query' : 'Hide Query',
onClick: this.toggleQueryCollapsing.bind(this, !queryCollapsed),
Expand Down Expand Up @@ -672,7 +684,6 @@ class DataDocQueryCellComponent extends React.PureComponent<IProps, IState> {

public renderCellHeaderDOM() {
const {
docId,
cellId,
queryEngines,
queryEngineById,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import React, { useCallback, useMemo, useRef } from 'react';
import toast from 'react-hot-toast';
import React from 'react';

import { ComponentType, ElementType } from 'const/analytics';
import { useQueryCells } from 'hooks/dataDoc/useQueryCells';
import { useMakeSelector } from 'hooks/redux/useMakeSelector';
import { trackClick } from 'lib/analytics';
import { sendConfirm } from 'lib/querybookUI';
import { makeLatestQueryExecutionsSelector } from 'redux/queryExecutions/selector';
import { DataDocResource } from 'resource/dataDoc';
import { IconButton } from 'ui/Button/IconButton';

import { DataDocRunAllButtonConfirm } from './DataDocRunAllButtonConfirm';
import { useRunAllFromIndex } from '../../hooks/dataDoc/useRunAllFromIndex';

interface IProps {
docId: number;
Expand All @@ -19,47 +11,7 @@ interface IProps {
export const DataDocRunAllButton: React.FunctionComponent<IProps> = ({
docId,
}) => {
const queryCells = useQueryCells(docId);
const latestQueryExecutions = useMakeSelector(
makeLatestQueryExecutionsSelector,
queryCells.map((c) => c.id) ?? []
);
const hasQueryRunning = useMemo(
() => latestQueryExecutions.some((q) => q.status < 3),
[latestQueryExecutions]
);
const notification = useRef(true);

const onRunAll = useCallback(() => {
sendConfirm({
header: 'Run All Cells',
message: (
<DataDocRunAllButtonConfirm
defaultNotification={notification.current}
onNotificationChange={(value) => {
notification.current = value;
}}
hasQueryRunning={hasQueryRunning}
queryCells={queryCells}
/>
),
onConfirm: () => {
trackClick({
component: ComponentType.DATADOC_PAGE,
element: ElementType.RUN_ALL_CELLS_BUTTON,
});
toast.promise(
DataDocResource.run(docId, notification.current),
{
loading: null,
success: 'DataDoc execution started!',
error: 'Failed to start the execution',
}
);
},
confirmText: 'Run',
});
}, [docId, hasQueryRunning, notification, queryCells]);
const onRunAll = useRunAllFromIndex(docId, null);

return (
<IconButton
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';

import { useQueryCells } from 'hooks/dataDoc/useQueryCells';
import { Message } from 'ui/Message/Message';
import { ToggleSwitch } from 'ui/ToggleSwitch/ToggleSwitch';
import { useMakeSelector } from '../../hooks/redux/useMakeSelector';
import { makeLatestQueryExecutionsSelector } from '../../redux/queryExecutions/selector';
import { QueryExecutionStatus } from '../../const/queryExecution';

interface IProps {
defaultNotification: boolean;
onNotificationChange: (notification: boolean) => void;
hasQueryRunning: boolean;
queryCells: ReturnType<typeof useQueryCells>;
docId: number;
index?: number;
}

export const DataDocRunAllButtonConfirm: React.FunctionComponent<IProps> = ({
defaultNotification,
onNotificationChange,
hasQueryRunning,
queryCells,
docId,
index,
}) => {
const [notification, setNotification] = useState(defaultNotification);

Expand All @@ -27,6 +30,20 @@ export const DataDocRunAllButtonConfirm: React.FunctionComponent<IProps> = ({
[onNotificationChange, setNotification]
);

let queryCells = useQueryCells(docId);
if (index !== undefined) {
queryCells = queryCells.slice(index);
}

Comment on lines +34 to +36
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this the index of the query cell in the datadoc, including text cells? e.g. what if there is a text cell before the starting query cell, is the slicing still correct?

same for the start_index in the above .py file, please double confirm

const latestQueryExecutions = useMakeSelector(
makeLatestQueryExecutionsSelector,
queryCells.map((c) => c.id) ?? []
);
const hasQueryRunning = useMemo(
() => latestQueryExecutions.some((q) => QueryExecutionStatus.DONE),
[latestQueryExecutions]
);

return (
<div>
{hasQueryRunning && (
Expand Down
1 change: 1 addition & 0 deletions querybook/webapp/const/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export enum ElementType {
TEMPLATE_CONFIG_BUTTON = 'TEMPLATE_CONFIG_BUTTON',
RENDER_QUERY_BUTTON = 'RENDER_QUERY_BUTTON',
CREATE_DATADOC_BUTTON = 'CREATE_DATADOC_BUTTON',
RUN_ALL_FROM_CELL_BUTTON = 'RUN_ALL_FROM_CELL_BUTTON',

// Table detail view
OVERVIEW_TABLE_TAB = 'OVERVIEW_TABLE_TAB',
Expand Down
47 changes: 47 additions & 0 deletions querybook/webapp/hooks/dataDoc/useRunAllFromIndex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useCallback, useRef } from 'react';
import { sendConfirm } from '../../lib/querybookUI';
import { DataDocRunAllButtonConfirm } from '../../components/DataDocRightSidebar/DataDocRunAllButtonConfirm';
import { trackClick } from '../../lib/analytics';
import { ComponentType, ElementType } from '../../const/analytics';
import toast from 'react-hot-toast';
import { DataDocResource } from '../../resource/dataDoc';

export function useRunAllFromIndex(docId: number, index?: number) {
const header =
index === undefined ? 'Run All Cells' : 'Run all cells below';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please keep the case consistent.


const notification = useRef(true);

const onRunAll = useCallback(() => {
sendConfirm({
header,
message: (
<DataDocRunAllButtonConfirm
defaultNotification={notification.current}
onNotificationChange={(value) => {
notification.current = value;
}}
docId={docId}
index={index}
/>
),
onConfirm: () => {
trackClick({
component: ComponentType.DATADOC_PAGE,
element: ElementType.RUN_ALL_FROM_CELL_BUTTON,
});
toast.promise(
DataDocResource.run(docId, notification.current, index),
{
loading: null,
success: 'DataDoc execution started!',
error: 'Failed to start the execution',
}
);
},
confirmText: 'Run',
});
return null;
}, [docId, notification]);
return onRunAll;
}
7 changes: 6 additions & 1 deletion querybook/webapp/resource/dataDoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,13 @@ export const DataDocResource = {
}>(`/favorite_data_doc/${docId}/`),
unfavorite: (docId: number) => ds.delete(`/favorite_data_doc/${docId}/`),

run: (docId: number, sendNotification: boolean = false) =>
run: (
docId: number,
sendNotification: boolean = false,
startIndex: number = 0
) =>
ds.save<null>(`/datadoc/${docId}/run/`, {
start_index: startIndex,
send_notification: sendNotification,
}),

Expand Down
2 changes: 2 additions & 0 deletions querybook/webapp/ui/Icon/LucideIcons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
ExternalLink,
Eye,
EyeOff,
FastForward,
File,
FileOutput,
FileText,
Expand Down Expand Up @@ -162,6 +163,7 @@ const AllLucideIcons = {
EyeOff,
Expand,
ExternalLink,
FastForward,
File,
FileOutput,
FileText,
Expand Down
Loading