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: a bunch of small ui fixes and improvements #1114

Merged
merged 2 commits into from
Dec 24, 2022
Merged
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
7 changes: 6 additions & 1 deletion querybook/webapp/components/DataDoc/DataDoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,12 @@ class DataDocComponent extends React.PureComponent<IProps, IState> {
// during this time we will focus the new inserted cell
const cellLengthChanged = cells.length !== previousCells.length;
if (cellLengthChanged && this.focusCellIndexAfterInsert != null) {
this.focusCellAt(this.focusCellIndexAfterInsert);
const cellIndexToFocus = this.focusCellIndexAfterInsert;
setImmediate(() => {
// setting focus cell during componentDidUpdate would not
// actually focus the cell, we need to do it in another event loop
this.focusCellAt(cellIndexToFocus);
});
this.focusCellIndexAfterInsert = null;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.DataDocGridItem {
.delete-grid-item-button {
.IconButton.delete-grid-item-button {
display: none;
padding: 0px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const DataTableColumnCard: React.FunctionComponent<IProps> = ({
<EditableTextField
value={column.description as ContentState}
onSave={updateDataColumnDescription.bind(null, column.id)}
placeholder="No user comments yet for column."
/>
);
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export const DataTableViewOverview: React.FC<
<EditableTextField
value={table.description as DraftJs.ContentState}
onSave={onDescriptionSave}
placeholder="No description for this table yet."
/>
) : null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
position: relative;
margin-top: 24px;

.DataTableViewQueryExamples-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
}
.DataTableViewQueryExamples-query {
height: auto;
max-height: 360px;
Expand All @@ -28,12 +34,6 @@
font-weight: var(--bold-font);
}
}

.Button {
position: absolute;
top: 0px;
right: 20px;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useDispatch, useSelector } from 'react-redux';

import { UserName } from 'components/UserBadge/UserName';
import { IPaginatedQuerySampleFilters } from 'const/metastore';
import { IQueryExecution } from 'const/queryExecution';
import { useImmer } from 'hooks/useImmer';
import { useLoader } from 'hooks/useLoader';
import { format } from 'lib/sql-helper/sql-formatter';
Expand All @@ -21,6 +22,7 @@ import { Button, TextButton } from 'ui/Button/Button';
import { ThemedCodeHighlight } from 'ui/CodeHighlight/ThemedCodeHighlight';
import { Loading } from 'ui/Loading/Loading';
import { AccentText } from 'ui/StyledText/StyledText';
import { Title } from 'ui/Title/Title';

import { DataTableViewQueryConcurrences } from './DataTableViewQueryConcurrences';
import { DataTableViewQueryEngines } from './DataTableViewQueryEngines';
Expand All @@ -32,13 +34,22 @@ interface IProps {
tableId: number;
}

interface IQueryExample {
queryExecution: IQueryExecution;
cellTitle?: string;
}

function useQueryExampleState(tableId: number) {
const queryExecutionById = useSelector(
(state: IStoreState) => state.queryExecutions.queryExecutionById
);
const queryExampleIdsState = useSelector(
(state: IStoreState) => state.dataSources.queryExampleIdsById[tableId]
);
const queryExecutionIdToCellInfo = useSelector(
(state: IStoreState) => state.queryExecutions.queryExecutionIdToCellInfo
);

return React.useMemo(
() => ({
queryExampleIds: queryExampleIdsState?.queryIds,
Expand All @@ -48,10 +59,17 @@ function useQueryExampleState(tableId: number) {
queryExampleIdsState?.queryIds ?? []
).filter((id) => !(id in queryExecutionById)),
queryExamples: (queryExampleIdsState?.queryIds ?? [])
.map((id) => queryExecutionById[id])
.filter((query) => query),
.map(
(id) =>
({
queryExecution: queryExecutionById[id],
cellTitle:
queryExecutionIdToCellInfo[id]?.cellTitle ?? '',
} as IQueryExample)
)
.filter((query) => query.queryExecution),
}),
[queryExampleIdsState, queryExecutionById]
[queryExampleIdsState, queryExecutionById, queryExecutionIdToCellInfo]
);
}

Expand Down Expand Up @@ -223,11 +241,18 @@ const QueryExamplesList: React.FC<{

const loadQueryExecution = React.useCallback(
(queryExecutionId) =>
dispatch(
queryExecutionsActions.fetchQueryExecutionIfNeeded(
queryExecutionId
)
),
Promise.all([
dispatch(
queryExecutionsActions.fetchQueryExecutionIfNeeded(
queryExecutionId
)
),
dispatch(
queryExecutionsActions.fetchDataDocInfoByQueryExecutionIdIfNeeded(
queryExecutionId
)
),
]),
[]
);

Expand Down Expand Up @@ -272,31 +297,39 @@ const QueryExamplesList: React.FC<{
}

const queryExamplesDOM = queryExamples
.map((query) => {
.map(({ queryExecution, cellTitle }) => {
const language =
queryEngineById[query.engine_id]?.language ?? 'presto';
const formattedQuery = format(query.query, language, {
queryEngineById[queryExecution.engine_id]?.language ??
'presto';
const formattedQuery = format(queryExecution.query, language, {
case: 'upper',
});
return (
<div
className="DataTableViewQueryExamples-item"
key={query.id}
key={queryExecution.id}
>
<div className="DataTableViewQueryExamples-header mb4">
<Title size="med" untitled={!cellTitle}>
{cellTitle || 'Untitled Execution'}
</Title>
<TextButton
icon="ArrowRight"
title="Open Execution"
onClick={() =>
openDisplayModal(queryExecution.id)
}
/>
</div>

<ThemedCodeHighlight
className="DataTableViewQueryExamples-query"
value={formattedQuery}
/>
<div className="DataTableViewQueryExamples-info">
<span>by </span>
<UserName uid={query.uid} />
<UserName uid={queryExecution.uid} />
</div>
<TextButton
icon="ArrowRight"
title="Open Execution"
className="mt8"
onClick={() => openDisplayModal(query.id)}
/>
</div>
);
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { DataDocSchemaNavigator } from 'components/DataDocSchemaNavigator/DataDo
import { QuerySnippetNavigator } from 'components/QuerySnippetNavigator/QuerySnippetNavigator';
import { QueryViewNavigator } from 'components/QueryViewNavigator/QueryViewNavigator';
import { useEvent } from 'hooks/useEvent';
import { useLocalStoreState } from 'hooks/useLocalStoreState';
import { SIDEBAR_ENTITY } from 'lib/local-store/const';
import { KeyMap, matchKeyMap } from 'lib/utils/keyboard';
import { navigateWithinEnv } from 'lib/utils/query-string';
import { currentEnvironmentSelector } from 'redux/environment/selector';
Expand All @@ -30,7 +32,10 @@ export const EnvironmentAppSidebar: React.FunctionComponent = () => {
(state: IStoreState) => state.querybookUI.isEnvCollapsed
);
const dispatch: Dispatch = useDispatch();
const [entity, setEntity] = React.useState<Entity>('datadoc');
const [entity, setEntity] = useLocalStoreState<Entity>({
storeKey: SIDEBAR_ENTITY,
defaultValue: 'datadoc',
});

const currentEnvironment = useSelector(currentEnvironmentSelector);

Expand All @@ -47,7 +52,7 @@ export const EnvironmentAppSidebar: React.FunctionComponent = () => {
return newEntity;
});
},
[dispatch, collapsed]
[dispatch, collapsed, setEntity]
);

const scrollToCollapseSidebar = React.useCallback(
Expand Down
6 changes: 5 additions & 1 deletion querybook/webapp/const/chartColors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export const ColorPalette: IColorPalette[] = [
{ name: 'pink', color: '#ff3975', fillColor: 'rgba(255, 57, 117, 0.25)' },
{ name: 'grey', color: '#bfbfbf', fillColor: 'rgba(191, 191, 191, 0.25)' },
{ name: 'gold', color: '#ffca00', fillColor: 'rgba(255, 202, 0, 0.25)' },
{ name: 'blue', color: '#529dce', fillColor: 'rgba(82, 157, 206, 0.25)' },
{
name: 'picton blue',
color: '#529dce',
fillColor: 'rgba(82, 157, 206, 0.25)',
},
{ name: 'orange', color: '#ff9f42', fillColor: 'rgba(255, 159, 66, 0.25)' },
{
name: 'creamy forest green',
Expand Down
2 changes: 1 addition & 1 deletion querybook/webapp/hooks/chart/useChartSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export function useChartSource(
getCellQueryExecutions(cellId);
} else if (cellId == null && executionId) {
dispatch(
queryExecutionsActions.fetchDataDocInfoByQueryExecutionId(
queryExecutionsActions.fetchDataDocInfoByQueryExecutionIdIfNeeded(
executionId
)
).then(({ cell_id: newCellId }) => {
Expand Down
38 changes: 38 additions & 0 deletions querybook/webapp/hooks/useLocalStoreState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import localStore from 'lib/local-store';
import { Nullable } from 'lib/typescript';
import { isFunction } from 'lodash';
import { useCallback, useEffect, useState } from 'react';

export function useLocalStoreState<T>({
storeKey,
defaultValue,
}: {
storeKey: string;
defaultValue: Nullable<T | (() => T)>;
}) {
const [state, setState] = useState<T>(defaultValue);

useEffect(() => {
localStore.get<T>(storeKey).then((storedVal) => {
if (storedVal != null) {
// if the val is retrieved
setState(storedVal);
}
});
}, [storeKey]);

const syncedSetState = useCallback(
(newValOrFunc: T | ((old: T) => T)) => {
setState((oldVal) => {
const newVal = isFunction(newValOrFunc)
? newValOrFunc(oldVal)
: newValOrFunc;
localStore.set(storeKey, newVal);
return newVal;
});
},
[storeKey]
);

return [state, syncedSetState] as const;
}
6 changes: 5 additions & 1 deletion querybook/webapp/lib/local-store/const.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IAdhocQuery } from 'const/adhocQuery';
import type { Entity } from 'components/EnvironmentAppSidebar/types';
import type { IAdhocQuery } from 'const/adhocQuery';

export const DISMISSED_ANNOUNCEMENT_KEY = 'dismissed_announcement_ids';
export type DismissedAnnouncementValue = number[];
Expand All @@ -14,3 +15,6 @@ export type DataDocNavSectionValue = Record<string, boolean>;

export const ADHOC_QUERY_KEY = 'adhoc_query_editor';
export type AdhocQueryValue = IAdhocQuery;

export const SIDEBAR_ENTITY = 'sidebar_entity';
export type TSidebarEntity = Entity;
15 changes: 13 additions & 2 deletions querybook/webapp/redux/queryExecutions/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export function fetchQueryExecutionsByCell(
};
}

export function fetchDataDocInfoByQueryExecutionId(
export function fetchDataDocInfoByQueryExecutionIdIfNeeded(
executionId: number
): ThunkResult<
Promise<{
Expand All @@ -249,7 +249,16 @@ export function fetchDataDocInfoByQueryExecutionId(
cell_title: string;
}>
> {
return async (dispatch) => {
return async (dispatch, getState) => {
const state = getState().queryExecutions.queryExecutionIdToCellInfo;
if (executionId in state) {
return {
cell_id: state[executionId].cellId,
doc_id: state[executionId].docId,
cell_title: state[executionId].cellTitle,
};
}

const { data: result } = await QueryExecutionResource.getDataDoc(
executionId
);
Expand All @@ -259,6 +268,8 @@ export function fetchDataDocInfoByQueryExecutionId(
payload: {
executionId,
cellId: result.cell_id,
cellTitle: result.cell_title,
docId: result.doc_id,
},
});
return result;
Expand Down
24 changes: 24 additions & 0 deletions querybook/webapp/redux/queryExecutions/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import { IQueryExecutionState, QueryExecutionAction } from './types';
const initialState: IQueryExecutionState = {
queryExecutionById: {},
statementExecutionById: {},

dataCellIdQueryExecution: {},
queryExecutionIdToCellInfo: {},

statementResultById: {},
statementResultLoadingById: {},
Expand All @@ -23,6 +25,26 @@ const initialState: IQueryExecutionState = {
accessRequestsByExecutionIdUserId: {},
};

function queryExecutionIdToCellInfoReducer(
state = initialState.queryExecutionIdToCellInfo,
action: QueryExecutionAction
) {
return produce(state, (draft) => {
switch (action.type) {
case '@@queryExecutions/RECEIVE_QUERY_CELL_ID_FROM_EXECUTION': {
const { executionId, cellId, cellTitle, docId } =
action.payload;
draft[executionId] = {
cellId,
cellTitle,
docId,
};
return;
}
}
});
}

function dataCellIdQueryExecutionReducer(
state = initialState.dataCellIdQueryExecution,
action: QueryExecutionAction
Expand Down Expand Up @@ -414,6 +436,8 @@ function statementExportersReducer(

export default combineReducers({
dataCellIdQueryExecution: dataCellIdQueryExecutionReducer,
queryExecutionIdToCellInfo: queryExecutionIdToCellInfoReducer,

statementExecutionById: statementExecutionByIdReducer,
queryExecutionById: queryExecutionByIdReducer,

Expand Down
Loading