Skip to content

Commit

Permalink
Merge pull request #429 from nickgros/SWC-6484c
Browse files Browse the repository at this point in the history
  • Loading branch information
nickgros authored Aug 28, 2023
2 parents c6f3aef + 1eef739 commit 05dbb62
Show file tree
Hide file tree
Showing 35 changed files with 1,234 additions and 472 deletions.
2 changes: 2 additions & 0 deletions packages/synapse-react-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"downshift": "^6.1.12",
"history": "^5.3.0",
"immutable": "4.1.0",
"jotai": "^2.3.1",
"json-rules-engine": "^4.1.0",
"katex": "0.11.1",
"lodash-es": "^4.17.21",
Expand Down Expand Up @@ -206,6 +207,7 @@
"jest-mock-promise": "^1.1.12",
"jest-serial-runner": "^1.2.1",
"jest-when": "^3.5.2",
"jotai-devtools": "^0.6.2",
"jsdom": "^21.1.2",
"memfs": "^3.5.3",
"msw": "^1.2.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import TotalQueryResults from '../TotalQueryResults'
import UserCardList from '../UserCardList/UserCardList'
import WideButton from '../styled/WideButton'
import { Box } from '@mui/material'
import { useAtomValue } from 'jotai'
import { tableQueryDataAtom } from '../QueryWrapper/QueryWrapper'

export type CardContainerProps = {
isHeader?: boolean
Expand Down Expand Up @@ -63,8 +65,8 @@ export function CardContainer(props: CardContainerProps) {
} = props
const infiniteQueryContext = useInfiniteQueryContext()
const { NoContentPlaceholder } = useQueryVisualizationContext()
const { data, appendNextPageToResults, hasNextPage } = infiniteQueryContext

const { appendNextPageToResults, hasNextPage } = infiniteQueryContext
const data = useAtomValue(tableQueryDataAtom)
const queryVisualizationContext = useQueryVisualizationContext()

const ids = data?.queryResult!.queryResults.tableId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
} from '../widgets/facet-nav/FacetNavPanel'
import { getFacets } from '../widgets/facet-nav/FacetNav'
import { useSynapseContext } from '../../utils/context/SynapseContext'
import { useQueryContext } from '../QueryContext'
import { useQueryVisualizationContext } from '../QueryVisualizationWrapper'
import { ShowMore } from '../row_renderers/utils'
import {
Expand All @@ -36,6 +35,11 @@ import {
} from './FacetPlotsCardGrid'
import { SkeletonParagraph, SkeletonTable } from '../Skeleton'
import { times } from 'lodash-es'
import { useAtomValue } from 'jotai'
import {
isLoadingNewBundleAtom,
tableQueryDataAtom,
} from '../QueryWrapper/QueryWrapper'

const Plot = createPlotlyComponent(Plotly)

Expand Down Expand Up @@ -98,10 +102,9 @@ const FacetPlotsCard: React.FunctionComponent<FacetPlotsCardProps> = ({
detailsPagePath,
}: FacetPlotsCardProps): JSX.Element => {
const { accessToken } = useSynapseContext()
const { data, isLoadingNewBundle } = useQueryContext<
'columnModels' | 'facets',
true
>()
const isLoadingNewBundle = useAtomValue(isLoadingNewBundleAtom)
const data = useAtomValue(tableQueryDataAtom)

const { getColumnDisplayName } = useQueryVisualizationContext()
const [facetPlotDataArray, setFacetPlotDataArray] = useState<GraphData[]>([])
const [facetDataArray, setFacetDataArray] = useState<FacetColumnResult[]>([])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ import {
import { IconOptions } from '../Icon'
import { calculateFriendlyFileSize } from '../../utils/functions/calculateFriendlyFileSize'
import { SynapseCardLabel } from './SynapseCardLabel'
import { useQueryContext } from '../QueryContext'
import { useAtomValue } from 'jotai'
import { tableQueryEntityAtom } from '../QueryWrapper/QueryWrapper'

export type KeyToAlias = {
key: string
Expand Down Expand Up @@ -725,7 +726,7 @@ class _GenericCard extends React.Component<
}

export default function GenericCard(props: GenericCardProps) {
const { entity: table } = useQueryContext()
const table = useAtomValue(tableQueryEntityAtom)
const queryVisualizationContext = useQueryVisualizationContext()
return (
<_GenericCard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import {
ColumnModel,
QueryBundleRequest,
QueryResultBundle,
Row,
Table,
} from '@sage-bionetworks/synapse-types'
import { ImmutableTableQueryResult } from '../../utils/hooks/useImmutableTableQuery/useImmutableTableQuery'
import { ReadonlyDeep, SetRequired } from 'type-fest'
import { ReadonlyDeep } from 'type-fest'

/*
For details page: to lock a column (e.g. study, grant) so that the facet values and active filters
Expand Down Expand Up @@ -37,17 +35,6 @@ export type QueryContextType<
TIncludedFields extends OptionalQueryBundleRequestFields = never,
ExcludeOtherFields extends true | false = false,
> = {
/** The entity being queried. Will be undefined while initially fetching */
entity: Table | undefined
/** The query results, which will be undefined while initially fetching a new bundle, but will not be unloaded when fetching new pages */
data:
| Omit<
SetRequired<QueryResultBundle, TIncludedFields>,
ExcludeOtherFields extends true
? Exclude<OptionalQueryBundleRequestFields, TIncludedFields>
: never
>
| undefined
currentQueryRequest: ReadonlyDeep<QueryBundleRequest>
nextQueryRequest: ReadonlyDeep<QueryBundleRequest>
/** Returns a deep clone of the current query bundle request */
Expand All @@ -65,39 +52,17 @@ export type QueryContextType<
removeQueryFilter: ImmutableTableQueryResult['removeQueryFilter']
/** Removes a value from a QueryFilter. If no more values remain in the filter, the filter is also removed */
removeValueFromQueryFilter: ImmutableTableQueryResult['removeValueFromQueryFilter']
/** Returns true when loading a brand-new query result bundle. Will not be true when just loading the next page of query results. */
isLoadingNewBundle: boolean
/** The error returned by the query request, if one is encountered */
error: SynapseClientError | null
/** The status of the asynchronous job. */
asyncJobStatus?: AsynchronousJobStatus<QueryBundleRequest, QueryResultBundle>
/** Whether facets are available to be filtered upon based on the current data */
isFacetsAvailable: boolean
/**
* A column name may be "locked" so that it is both (1) not shown to the user that the filter is active, and (2) not modifiable by the user.
* For example, we may show only the data matching a particular facet value on a Details Page without implying that the shown data is part of a larger table.
* The presence of a locked filter will result in a client-side modification of the active query and result bundle data.
*/
lockedColumn?: LockedColumn
/** Returns true iff the current request has resettable filters applied via facet filters or additionalFilters. Excludes filters applied to a locked column */
hasResettableFilters: boolean
getColumnModel: (columnName: string) => ColumnModel | null
// Either open benefactor entity page in a new window or open the sharing settings dialog (in Synapse.org)
onViewSharingSettingsClicked?: (benefactorId: string) => void
/** Whether the user can select individual rows on which to perform an action */
isRowSelectionVisible: boolean
/** The collection of selected rows */
selectedRows: Row[]
/** State updater for `selectedRows` */
setSelectedRows: React.Dispatch<React.SetStateAction<Row[]>>
/** The set of columns that defines a uniqueness constraint on the table for the purposes of filtering based on row selection.
* Note that Synapse tables have no internal concept of a primary key.
*/
rowSelectionPrimaryKey?: string[]
/** Whether the user has selected any rows */
hasSelectedRows: boolean
/** Method used to determine if an individual row is selected */
getIsRowSelected: (row: Row) => boolean
/** Combines two faceted columns into a single inclusive range selector */
combineRangeFacetConfig?: ReadonlyDeep<CombineRangeFacetConfig>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react'
import { useDeepCompareMemoize } from 'use-deep-compare-effect'
Expand All @@ -15,6 +16,8 @@ import { unCamelCase } from '../../utils/functions/unCamelCase'
import { ColumnType } from '@sage-bionetworks/synapse-types'
import { getDisplayValue } from '../../utils/functions/getDataFromFromStorage'
import useMutuallyExclusiveState from '../../utils/hooks/useMutuallyExclusiveState'
import { useAtomValue } from 'jotai'
import { tableQueryDataAtom } from '../QueryWrapper/QueryWrapper'

export type QueryVisualizationContextType = {
columnsToShowInTable: string[]
Expand Down Expand Up @@ -117,18 +120,19 @@ export function QueryVisualizationWrapper(
) {
const {
noContentPlaceholderType = NoContentPlaceholderType.INTERACTIVE,
columnAliases = {},
defaultShowSearchBar = false,
defaultShowFacetVisualization = true,
unitDescription = 'result',
} = props

const {
data,
getCurrentQueryRequest,
isFacetsAvailable,
hasResettableFilters,
} = useQueryContext()
const columnAliases = useMemo(
() => props.columnAliases ?? {},
[props.columnAliases],
)

const { getCurrentQueryRequest, isFacetsAvailable, hasResettableFilters } =
useQueryContext()
const data = useAtomValue(tableQueryDataAtom)

const [showSqlEditor, setShowSqlEditor] = useState(false)
const [showFacetVisualization, setShowFacetVisualization] = useState(
Expand Down Expand Up @@ -195,30 +199,52 @@ export function QueryVisualizationWrapper(
}
}, [noContentPlaceholderType, hasResettableFilters])

const context: QueryVisualizationContextType = {
columnsToShowInTable: visibleColumns,
setColumnsToShowInTable: setVisibleColumns,
rgbIndex: props.rgbIndex,
unitDescription: unitDescription,
showLastUpdatedOn: props.showLastUpdatedOn,
getColumnDisplayName,
getDisplayValue,
NoContentPlaceholder,
isShowingExportToCavaticaModal,
setIsShowingExportToCavaticaModal,
showFacetFilter: isFacetsAvailable ? showFacetFilter : false,
setShowFacetFilter,
showSearchBar,
setShowSearchBar,
showDownloadConfirmation,
setShowDownloadConfirmation,
showSqlEditor,
setShowSqlEditor,
showFacetVisualization: isFacetsAvailable ? showFacetVisualization : false,
setShowFacetVisualization,
showCopyToClipboard,
setShowCopyToClipboard,
}
const context: QueryVisualizationContextType = useMemo(
() => ({
columnsToShowInTable: visibleColumns,
setColumnsToShowInTable: setVisibleColumns,
rgbIndex: props.rgbIndex,
unitDescription: unitDescription,
showLastUpdatedOn: props.showLastUpdatedOn,
getColumnDisplayName,
getDisplayValue,
NoContentPlaceholder,
isShowingExportToCavaticaModal,
setIsShowingExportToCavaticaModal,
showFacetFilter: isFacetsAvailable ? showFacetFilter : false,
setShowFacetFilter,
showSearchBar,
setShowSearchBar,
showDownloadConfirmation,
setShowDownloadConfirmation,
showSqlEditor,
setShowSqlEditor,
showFacetVisualization: isFacetsAvailable
? showFacetVisualization
: false,
setShowFacetVisualization,
showCopyToClipboard,
setShowCopyToClipboard,
}),
[
NoContentPlaceholder,
getColumnDisplayName,
isFacetsAvailable,
isShowingExportToCavaticaModal,
props.rgbIndex,
props.showLastUpdatedOn,
setShowDownloadConfirmation,
setShowSearchBar,
showCopyToClipboard,
showDownloadConfirmation,
showFacetFilter,
showFacetVisualization,
showSearchBar,
showSqlEditor,
unitDescription,
visibleColumns,
],
)
/**
* Render the children without any formatting
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import {
QueryContextType,
useQueryContext,
} from '../QueryContext'
import { QueryWrapper, QueryWrapperProps } from './QueryWrapper'
import {
isLoadingNewBundleAtom,
QueryWrapper,
QueryWrapperProps,
tableQueryDataAtom,
} from './QueryWrapper'
import { SynapseConstants } from '../../utils'
import {
QueryBundleRequest,
Expand All @@ -19,6 +24,9 @@ import SynapseClient from '../../synapse-client'
import { mockCompleteAsyncJob } from '../../mocks/mockFileViewQuery'
import userEvent from '@testing-library/user-event'
import { createWrapper } from '../../testutils/TestingLibraryUtils'
import { useAtomValue } from 'jotai'
import { useSetAtom } from 'jotai'
import { selectedRowsAtom } from './TableRowSelectionState'

jest.mock('../../synapse-client', () => ({
getQueryTableAsyncJobResults: jest.fn(),
Expand All @@ -34,15 +42,15 @@ const renderedTextConfirmation = 'QueryWrapper rendered!'
let isLoadingNewBundleValue: boolean | undefined
let currentQueryDataValue: QueryResultBundle | undefined
let selectedRows: Row[] | undefined
let setSelectedRows: QueryContextType['setSelectedRows'] | undefined
let setSelectedRows: ReturnType<typeof useSetAtom> | undefined

const QueryContextReceiver = () => {
// An error would be thrown if context was not provided by QueryWrapper
const context = useQueryContext()
isLoadingNewBundleValue = context.isLoadingNewBundle
currentQueryDataValue = context.data
selectedRows = context.selectedRows
setSelectedRows = context.setSelectedRows
isLoadingNewBundleValue = useAtomValue(isLoadingNewBundleAtom)
currentQueryDataValue = useAtomValue(tableQueryDataAtom)
selectedRows = useAtomValue(selectedRowsAtom)
setSelectedRows = useSetAtom(selectedRowsAtom)
providedContext = context
return <>{renderedTextConfirmation}</>
}
Expand Down Expand Up @@ -102,7 +110,7 @@ describe('QueryWrapper', () => {
await screen.findByText(renderedTextConfirmation)
})

it('Data is set', async () => {
it('Data atom is set', async () => {
renderComponent({ initQueryRequest: initialQueryRequest })
await waitFor(() => {
expect(isLoadingNewBundleValue).toBe(false)
Expand Down
Loading

0 comments on commit 05dbb62

Please sign in to comment.