Skip to content

Commit

Permalink
Merge pull request #629 from jetstreamapp/feat/423-2
Browse files Browse the repository at this point in the history
Remember rearranged columns on re-load query
  • Loading branch information
paustint authored Nov 27, 2023
2 parents 482cde3 + b68298b commit 86352a0
Show file tree
Hide file tree
Showing 13 changed files with 458 additions and 388 deletions.
13 changes: 8 additions & 5 deletions apps/jetstream-e2e/src/pageObjectModels/QueryPage.model.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { APIRequestContext, expect, Locator, Page } from '@playwright/test';
import { QueryResults } from '@jetstream/api-interfaces';
import { formatNumber } from '@jetstream/shared/ui-utils';
import { isRecordWithId } from '@jetstream/shared/utils';
import { QueryFilterOperator } from '@jetstream/types';
import { APIRequestContext, expect, Locator, Page } from '@playwright/test';
import isNumber from 'lodash/isNumber';
import { formatNumber } from '@jetstream/shared/ui-utils';
import { QueryResults } from '@jetstream/api-interfaces';
import { ApiRequestUtils } from '../fixtures/ApiRequestUtils';
import { isRecordWithId } from '@jetstream/shared/utils';

export class QueryPage {
readonly apiRequestUtils: ApiRequestUtils;
Expand Down Expand Up @@ -200,7 +200,10 @@ export class QueryPage {

// verify correct query shows up
await this.page.getByRole('button', { name: 'SOQL Query' }).click();
await expect(this.page.getByRole('code').locator('div').filter({ hasText: query }).first()).toBeVisible();
// The full query is broken up in a weird way, we we check each token individually
for (const token of query.split(' ')) {
await expect(this.page.getByRole('code').locator('div').filter({ hasText: token }).first()).toBeVisible();
}
await this.page.getByRole('button', { name: 'Collapse SOQL Query' }).click();

await this.page.getByRole('button', { name: 'History' }).click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import React, { Fragment, FunctionComponent, useCallback, useEffect, useRef, use
import { Link, NavLink, useLocation, useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue } from 'recoil';
import { filter } from 'rxjs/operators';
import { Query } from 'soql-parser-js';
import { FieldSubquery, Query, composeQuery, isFieldSubquery, parseQuery } from 'soql-parser-js';
import { applicationCookieState, selectedOrgState } from '../../../app-state';
import ViewEditCloneRecord from '../../core/ViewEditCloneRecord';
import { useAmplitude } from '../../core/analytics';
Expand Down Expand Up @@ -94,7 +94,6 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
const [records, setRecords] = useState<Record[] | null>(null);
const [nextRecordsUrl, setNextRecordsUrl] = useState<Maybe<string>>(null);
const [fields, setFields] = useState<string[] | null>(null);
const [modifiedFields, setModifiedFields] = useState<string[] | null>(null);
const [subqueryFields, setSubqueryFields] = useState<Maybe<MapOf<string[]>>>(null);
const [filteredRows, setFilteredRows] = useState<Record[]>([]);
const [selectedRows, setSelectedRows] = useState<Record[]>([]);
Expand Down Expand Up @@ -178,15 +177,29 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
}
}, [isTooling, soqlPanelOpen, trackEvent]);

// Ensure that the query is updated in the browser history any time it changes
useNonInitialEffect(() => {
if (soql) {
window.history.replaceState({ state: { soql, isTooling } }, '');
}
}, [isTooling, soql]);

useEffect(() => {
logger.log({ location });
if (locationState) {
setSoql(locationState.soql || '');
if (locationState && locationState.soql) {
setSoql(locationState.soql);
setIsTooling(locationState.isTooling ? true : false);
locationState.soql &&
executeQuery(locationState.soql, locationState.fromHistory ? SOURCE_HISTORY : SOURCE_STANDARD, {
isTooling: locationState.isTooling,
});

try {
const parsedQuery = parseQuery(locationState.soql);
setParsedQuery(parsedQuery);
} catch (ex) {
logger.warn('Could not parse query from location state', locationState.soql, ex.message);
}

executeQuery(locationState.soql, locationState.fromHistory ? SOURCE_HISTORY : SOURCE_STANDARD, {
isTooling: locationState.isTooling,
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);
Expand Down Expand Up @@ -254,12 +267,12 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
}
setRecords(null);
setRecordCount(null);
// setFields(null);
setSubqueryFields(null);
const results = await query(selectedOrg, soqlQuery, tooling, !tooling && includeDeletedRecords);
if (!isMounted.current) {
return;
}
setParsedQuery(results.parsedQuery);
setQueryResults(results);
setNextRecordsUrl(results.queryResults.nextRecordsUrl);
setRecordCount(results.queryResults.totalSize);
Expand All @@ -286,7 +299,6 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
const sobjectName = results.parsedQuery?.sObject || results.columns?.entityName;
sobjectName && (await saveQueryHistory(soqlQuery, sobjectName, tooling));
setSobject(sobjectName);
setParsedQuery(results.parsedQuery);
} catch (ex) {
if (!isMounted.current) {
return;
Expand Down Expand Up @@ -417,9 +429,50 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
}
}

function handleFieldsChanged({ allFields, visibleFields }: { allFields: string[]; visibleFields: string[] }) {
setFields(allFields);
setModifiedFields(visibleFields);
function handleFieldsChanged(newFields: string[], columnOrder: number[]) {
try {
setFields(newFields);
if (newFields?.length && parsedQuery?.fields && Array.isArray(parsedQuery.fields)) {
const newParsedQuery = {
...parsedQuery,
fields: columnOrder.map((idx) => parsedQuery.fields![idx]),
};
setParsedQuery(newParsedQuery);
setSoql(composeQuery(newParsedQuery, { format: true }));
}
} catch (ex) {
logger.warn('Error setting query after fields changed', ex.message);
}
}

function handleSubqueryFieldsChanged(columnKey: string, newFields: string[], columnOrder: number[]) {
try {
const subqueryIdx = fields?.findIndex((field) => field === columnKey) || -1;
if (
subqueryIdx >= 0 &&
newFields?.length &&
parsedQuery?.fields &&
Array.isArray(parsedQuery.fields) &&
isFieldSubquery(parsedQuery.fields[subqueryIdx])
) {
const subqueryColumn = { ...(parsedQuery.fields[subqueryIdx] as FieldSubquery) };

subqueryColumn.subquery = {
...subqueryColumn.subquery,
fields: columnOrder.map((idx) => subqueryColumn.subquery.fields![idx]),
};

const newParsedQuery = {
...parsedQuery,
fields: parsedQuery.fields.map((field, idx) => (idx === subqueryIdx ? subqueryColumn : field)),
};
setParsedQuery(newParsedQuery);

setSoql(composeQuery(newParsedQuery, { format: true }));
}
} catch (ex) {
logger.warn('Error setting query after fields changed (Subquery)', ex.message);
}
}

function handleOpenHistory(type: fromQueryHistory.QueryHistoryType) {
Expand Down Expand Up @@ -496,7 +549,7 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
<QueryResultsCopyToClipboard
className="collapsible-button collapsible-button-md"
hasRecords={hasRecords()}
fields={modifiedFields || []}
fields={fields || []}
records={records || []}
filteredRows={filteredRows}
selectedRows={selectedRows}
Expand All @@ -511,7 +564,6 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
isTooling={isTooling}
nextRecordsUrl={nextRecordsUrl}
fields={fields || []}
modifiedFields={modifiedFields || []}
subqueryFields={subqueryFields}
records={records || []}
filteredRows={filteredRows}
Expand Down Expand Up @@ -618,6 +670,7 @@ export const QueryResults: FunctionComponent<QueryResultsProps> = React.memo(()
}
onSelectionChanged={setSelectedRows}
onFields={handleFieldsChanged}
onSubqueryFieldReorder={handleSubqueryFieldsChanged}
onFilteredRowsChanged={setFilteredRows}
onLoadMoreRecords={handleLoadMore}
onSavedRecords={(data) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ export const QueryResultsCopyToClipboard: FunctionComponent<QueryResultsCopyToCl

return (
<Fragment>
{/* TODO */}
<ButtonGroupContainer>
<Tooltip
delay={[1000, null]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export interface QueryResultsDownloadButtonProps {
isTooling: boolean;
nextRecordsUrl: Maybe<string>;
fields: string[];
modifiedFields: string[];
subqueryFields: Maybe<MapOf<string[]>>;
records: any[];
filteredRows: any[];
Expand All @@ -37,7 +36,6 @@ export const QueryResultsDownloadButton: FunctionComponent<QueryResultsDownloadB
isTooling,
nextRecordsUrl,
fields,
modifiedFields,
subqueryFields,
records,
filteredRows,
Expand Down Expand Up @@ -146,7 +144,6 @@ export const QueryResultsDownloadButton: FunctionComponent<QueryResultsDownloadB
downloadModalOpen={isDownloadModalOpen}
columns={columns}
fields={fields || []}
modifiedFields={modifiedFields || []}
subqueryFields={subqueryFields || {}}
records={records || []}
filteredRecords={filteredRows}
Expand Down
4 changes: 2 additions & 2 deletions libs/ui/src/lib/data-table/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ColumnWithFilter, ContextMenuActionData, RowWithKey } from './data-tabl
import { useDataTable } from './useDataTable';

export interface DataTableProps<T = RowWithKey, TContext = Record<string, any>>
extends Omit<DataGridProps<T>, 'columns' | 'rows' | 'rowKeyGetter'> {
extends Omit<DataGridProps<T>, 'columns' | 'rows' | 'rowKeyGetter' | 'onColumnsReorder'> {
data: T[];
columns: ColumnWithFilter<T>[];
serverUrl?: string;
Expand All @@ -24,7 +24,7 @@ export interface DataTableProps<T = RowWithKey, TContext = Record<string, any>>
getRowKey: (row: T) => string;
rowAlwaysVisible?: (row: T) => boolean;
ignoreRowInSetFilter?: (row: T) => boolean;
onReorderColumns?: (columns: string[]) => void;
onReorderColumns?: (columns: string[], columnOrder: number[]) => void;
onSortedAndFilteredRowsChange?: (rows: readonly T[]) => void;
}

Expand Down
Loading

0 comments on commit 86352a0

Please sign in to comment.