synapse-react-client 4.0.20 → 4.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SWC.index.d.ts +1 -0
- package/dist/SWC.index.d.ts.map +1 -1
- package/dist/SWC.index.js +2 -1
- package/dist/SWC.index.js.map +1 -1
- package/dist/components/CardContainer/CardConfiguration.d.ts +2 -0
- package/dist/components/CardContainer/CardConfiguration.d.ts.map +1 -1
- package/dist/components/CardContainer/CardContainer.d.ts.map +1 -1
- package/dist/components/CardContainer/CardContainer.js +44 -50
- package/dist/components/CardContainer/CardContainer.js.map +1 -1
- package/dist/components/CardContainerLogic/CardContainerLogic.d.ts +14 -0
- package/dist/components/CardContainerLogic/CardContainerLogic.d.ts.map +1 -1
- package/dist/components/CardContainerLogic/CardContainerLogic.js +64 -40
- package/dist/components/CardContainerLogic/CardContainerLogic.js.map +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmissionStepper.js +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmissionStepper.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.css +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.js +16 -16
- package/dist/components/DataExplorer/DataExplorer.module.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.module.scss +26 -7
- package/dist/components/DataGrid/DataGrid.d.ts +1 -0
- package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/DataGrid.js +72 -72
- package/dist/components/DataGrid/DataGrid.js.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +209 -206
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.d.ts +6 -3
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.d.ts.map +1 -1
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js +54 -46
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js.map +1 -1
- package/dist/components/DataGrid/hooks/useColumnResizeHandles.d.ts.map +1 -1
- package/dist/components/DataGrid/hooks/useColumnResizeHandles.js +1 -1
- package/dist/components/DataGrid/hooks/useColumnResizeHandles.js.map +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.d.ts.map +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.js +68 -67
- package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.d.ts +1 -0
- package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js +5 -3
- package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
- package/dist/components/DataGrid/utils/modelColsToGrid.d.ts +1 -1
- package/dist/components/DataGrid/utils/modelColsToGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/modelColsToGrid.js +15 -14
- package/dist/components/DataGrid/utils/modelColsToGrid.js.map +1 -1
- package/dist/components/DataGrid/utils/normalizeWebsocketError.d.ts +7 -0
- package/dist/components/DataGrid/utils/normalizeWebsocketError.d.ts.map +1 -0
- package/dist/components/DataGrid/utils/normalizeWebsocketError.js +8 -0
- package/dist/components/DataGrid/utils/normalizeWebsocketError.js.map +1 -0
- package/dist/components/GenericCard/GenericCard.d.ts +2 -0
- package/dist/components/GenericCard/GenericCard.d.ts.map +1 -1
- package/dist/components/GenericCard/GenericCard.js +76 -64
- package/dist/components/GenericCard/GenericCard.js.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js +33 -25
- package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
- package/dist/components/Goals/Goals.d.ts +8 -0
- package/dist/components/Goals/Goals.d.ts.map +1 -1
- package/dist/components/Goals/Goals.js +54 -40
- package/dist/components/Goals/Goals.js.map +1 -1
- package/dist/components/Plot/SynapseSankeyPlot.css +1 -0
- package/dist/components/Plot/SynapseSankeyPlot.d.ts +44 -2
- package/dist/components/Plot/SynapseSankeyPlot.d.ts.map +1 -1
- package/dist/components/Plot/SynapseSankeyPlot.js +343 -38
- package/dist/components/Plot/SynapseSankeyPlot.js.map +1 -1
- package/dist/components/Plot/SynapseSankeyPlot.module.js +15 -0
- package/dist/components/Plot/SynapseSankeyPlot.module.js.map +1 -0
- package/dist/components/Plot/SynapseSankeyPlot.module.scss +63 -0
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.d.ts +9 -0
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.d.ts.map +1 -0
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.js +69 -0
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.js.map +1 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.d.ts +13 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.d.ts.map +1 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.js +11 -0
- package/dist/components/ProjectVisibilityChip/getProjectVisibilityFromACL.js.map +1 -0
- package/dist/components/ProjectVisibilityChip/index.d.ts +5 -0
- package/dist/components/ProjectVisibilityChip/index.d.ts.map +1 -0
- package/dist/components/ProjectVisibilityChip/index.js +7 -0
- package/dist/components/ProjectVisibilityChip/index.js.map +1 -0
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.d.ts.map +1 -1
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js +1 -1
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/RowSetView.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/RowSetView.js +9 -12
- package/dist/components/QueryWrapperPlotNav/RowSetView.js.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.d.ts +7 -15
- package/dist/components/RssFeedCards/RssFeedCards.d.ts.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.js +114 -123
- package/dist/components/RssFeedCards/RssFeedCards.js.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts +13 -12
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +88 -77
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js +63 -74
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/ColumnModelForm.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js +72 -68
- package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts +27 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js +47 -36
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.d.ts +12 -12
- package/dist/components/TableColumnSchemaEditor/Validators/BooleanSchema.d.ts +4 -1
- package/dist/components/TableColumnSchemaEditor/Validators/BooleanSchema.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/ColumnModelValidator.d.ts +167 -517
- package/dist/components/TableColumnSchemaEditor/Validators/ColumnModelValidator.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/ColumnModelValidator.js +65 -65
- package/dist/components/TableColumnSchemaEditor/Validators/ColumnModelValidator.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/DatetimeSchema.d.ts +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/DatetimeSchema.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/DoubleSchema.d.ts +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/DoubleSchema.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/DoubleSchema.js +6 -13
- package/dist/components/TableColumnSchemaEditor/Validators/DoubleSchema.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/EntityIdSchema.d.ts +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/EntityIdSchema.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/IntegerSchema.d.ts +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/IntegerSchema.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/IntegerSchema.js +2 -2
- package/dist/components/TableColumnSchemaEditor/Validators/IntegerSchema.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/OptionalStringSchema.d.ts +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/OptionalStringSchema.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/getZodSchemaForColumnType.d.ts +2 -2
- package/dist/components/TableColumnSchemaEditor/Validators/getZodSchemaForColumnType.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/getZodSchemaForColumnType.js +15 -16
- package/dist/components/TableColumnSchemaEditor/Validators/getZodSchemaForColumnType.js.map +1 -1
- package/dist/components/UserCardList/UserCardList.d.ts +2 -20
- package/dist/components/UserCardList/UserCardList.d.ts.map +1 -1
- package/dist/components/UserCardList/UserCardList.js +49 -72
- package/dist/components/UserCardList/UserCardList.js.map +1 -1
- package/dist/components/UserCardList/UserCardListRotate.d.ts +13 -0
- package/dist/components/UserCardList/UserCardListRotate.d.ts.map +1 -1
- package/dist/components/UserCardList/UserCardListRotate.js +82 -57
- package/dist/components/UserCardList/UserCardListRotate.js.map +1 -1
- package/dist/mocks/mockSearchQueryData.js +2 -2
- package/dist/mocks/mockSearchQueryData.js.map +1 -1
- package/dist/mocks/msw/handlers/searchQueryHandlers.d.ts +1 -1
- package/dist/mocks/msw/handlers/searchQueryHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/searchQueryHandlers.js +6 -3
- package/dist/mocks/msw/handlers/searchQueryHandlers.js.map +1 -1
- package/dist/mocks/query/mockUserCardTableQueryResultBundle.d.ts +13 -0
- package/dist/mocks/query/mockUserCardTableQueryResultBundle.d.ts.map +1 -1
- package/dist/mocks/query/mockUserCardTableQueryResultBundle.js +27 -0
- package/dist/mocks/query/mockUserCardTableQueryResultBundle.js.map +1 -1
- package/dist/style/abstracts/_cssVariables.scss +1 -0
- package/dist/style/components/_cards.scss +10 -0
- package/dist/style/components/_data-grid-extra.css +1 -1
- package/dist/style/components/_data-grid-extra.scss +7 -1
- package/dist/style/main.css +1 -1
- package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
- package/dist/synapse-client/SynapseClient.js +497 -495
- package/dist/synapse-client/SynapseClient.js.map +1 -1
- package/dist/synapse-queries/KeyFactory.d.ts +1 -0
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +3 -0
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/index.js +46 -44
- package/dist/synapse-queries/user/index.js +3 -3
- package/dist/synapse-queries/user/useUserBundle.d.ts +12 -0
- package/dist/synapse-queries/user/useUserBundle.d.ts.map +1 -1
- package/dist/synapse-queries/user/useUserBundle.js +50 -36
- package/dist/synapse-queries/user/useUserBundle.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/AppUtils/session/SessionInitializedGuard.d.ts +10 -5
- package/dist/utils/AppUtils/session/SessionInitializedGuard.d.ts.map +1 -1
- package/dist/utils/AppUtils/session/SessionInitializedGuard.js +13 -9
- package/dist/utils/AppUtils/session/SessionInitializedGuard.js.map +1 -1
- package/dist/utils/functions/SqlFunctions.d.ts +1 -1
- package/dist/utils/functions/SqlFunctions.d.ts.map +1 -1
- package/dist/utils/functions/SqlFunctions.js +1 -1
- package/dist/utils/functions/SqlFunctions.js.map +1 -1
- package/package.json +7 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseSankeyPlot.js","names":[],"sources":["../../../src/components/Plot/SynapseSankeyPlot.tsx"],"sourcesContent":["import React from 'react'\nimport { useGetFullTableQueryResults } from '@/synapse-queries'\nimport { SynapseConstants } from '@/utils'\nimport { parseEntityIdFromSqlStatement } from '@/utils/functions/SqlFunctions'\nimport { Skeleton } from '@mui/material'\nimport { QueryBundleRequest } from '@sage-bionetworks/synapse-types'\nimport type { Data, Layout, SankeyData } from 'plotly.js'\nimport { PlotFullBundle } from './Plot'\n\nexport type SynapseSankeyPlotProps = {\n /** SQL query whose first column provides node labels and second column provides link values */\n sql: string\n /** Label for the root node that links to every row returned by the query */\n rootLabel: string\n /** Optional plot title */\n title?: string\n}\n\nexport const SynapseSankeyPlot = (\n props: SynapseSankeyPlotProps,\n): React.ReactNode => {\n const { sql, rootLabel, title } = props\n\n const queryRequest: QueryBundleRequest = {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n partMask: SynapseConstants.BUNDLE_MASK_QUERY_RESULTS,\n entityId: parseEntityIdFromSqlStatement(sql),\n query: {\n sql,\n },\n }\n\n const { data: queryData, isLoading } =\n useGetFullTableQueryResults(queryRequest)\n\n if (isLoading) {\n return <Skeleton width={'100%'} height={'500px'} />\n }\n if (!queryData) {\n return <></>\n }\n\n const rows = queryData.queryResult?.queryResults.rows ?? []\n if (rows.length === 0) {\n return <></>\n }\n\n // Build Sankey nodes and links.\n // Node 0: rootLabel (the shared source node)\n // Nodes 1..N: the label from column 0 of each query row (target nodes)\n const sources: number[] = []\n const targets: number[] = []\n const values: number[] = []\n\n rows.forEach((row, index) => {\n values.push(Number(row.values[1] ?? 0))\n sources.push(0)\n targets.push(index + 1)\n })\n\n const total = values.reduce((sum, v) => sum + v, 0)\n\n // Plotly Sankey processes <br> via convertToTspans(), rendering the count on a second line.\n const nodeLabels: string[] = [`${rootLabel}<br>n=${total}`]\n rows.forEach(row => {\n const label = row.values[0] ?? ''\n const value = Number(row.values[1] ?? 0)\n nodeLabels.push(`${label}<br>n=${value}`)\n })\n\n const sankeyData: Partial<SankeyData>[] = [\n {\n type: 'sankey',\n node: {\n label: nodeLabels,\n },\n link: {\n source: sources,\n target: targets,\n value: values,\n },\n },\n ]\n\n const layout: Partial<Layout> = {\n title,\n }\n\n return (\n <PlotFullBundle\n style={{ width: '100%', height: '450px' }}\n layout={layout}\n data={sankeyData as Data[]}\n config={{ displayModeBar: false }}\n />\n )\n}\n\nexport default SynapseSankeyPlot\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,KACX,MACoB;CACpB,IAAM,EAAE,QAAK,cAAW,aAAU,GAW5B,EAAE,MAAM,GAAW,iBACvB,EAA4B;EAT5B,cAAc;EACd,UAAU;EACV,UAAU,EAA8B,CAAG;EAC3C,OAAO,EACL,OACF;CAI4B,CAAY;CAE1C,IAAI,GACF,OAAO,kBAAC,GAAD;EAAU,OAAO;EAAQ,QAAQ;CAAU,CAAA;CAEpD,IAAI,CAAC,GACH,OAAO,kBAAA,GAAA,CAAI,CAAA;CAGb,IAAM,IAAO,EAAU,aAAa,aAAa,QAAQ,CAAC;CAC1D,IAAI,EAAK,WAAW,GAClB,OAAO,kBAAA,GAAA,CAAI,CAAA;CAMb,IAAM,IAAoB,CAAC,GACrB,IAAoB,CAAC,GACrB,IAAmB,CAAC;CAE1B,EAAK,SAAS,GAAK,MAAU;EAG3B,AAFA,EAAO,KAAK,OAAO,EAAI,OAAO,MAAM,CAAC,CAAC,GACtC,EAAQ,KAAK,CAAC,GACd,EAAQ,KAAK,IAAQ,CAAC;CACxB,CAAC;CAKD,IAAM,IAAuB,CAAC,GAAG,EAAU,QAH7B,EAAO,QAAQ,GAAK,MAAM,IAAM,GAAG,CAGE,GAAO;CAyB1D,OAxBA,EAAK,SAAQ,MAAO;EAClB,IAAM,IAAQ,EAAI,OAAO,MAAM,IACzB,IAAQ,OAAO,EAAI,OAAO,MAAM,CAAC;EACvC,EAAW,KAAK,GAAG,EAAM,QAAQ,GAAO;CAC1C,CAAC,GAqBC,kBAAC,GAAD;EACE,OAAO;GAAE,OAAO;GAAQ,QAAQ;EAAQ;EAChC,QAAA,EANV,SAMU;EACR,MAAM,CArBR;GACE,MAAM;GACN,MAAM,EACJ,OAAO,EACT;GACA,MAAM;IACJ,QAAQ;IACR,QAAQ;IACR,OAAO;GACT;EACF,CAWQ;EACN,QAAQ,EAAE,gBAAgB,GAAM;CACjC,CAAA;AAEL"}
|
|
1
|
+
{"version":3,"file":"SynapseSankeyPlot.js","names":[],"sources":["../../../src/components/Plot/SynapseSankeyPlot.tsx"],"sourcesContent":["import React, { useEffect, useId, useMemo, useRef, useState } from 'react'\nimport { useGetFullTableQueryResults } from '@/synapse-queries'\nimport { SynapseConstants } from '@/utils'\nimport { parseEntityIdFromSqlStatement } from '@/utils/functions/SqlFunctions'\nimport { Skeleton, useTheme } from '@mui/material'\nimport { QueryBundleRequest } from '@sage-bionetworks/synapse-types'\nimport {\n sankey as d3Sankey,\n sankeyLinkHorizontal,\n type SankeyNode as D3SankeyNode,\n} from 'd3-sankey'\nimport tinycolor from 'tinycolor2'\nimport classNames from 'classnames'\nimport styles from './SynapseSankeyPlot.module.scss'\n\nexport type SynapseSankeyPlotProps = {\n /** SQL query providing the node labels and link values (see labelColumn/valueColumn) */\n sql: string\n /** Label for the left end node that links to every row returned by the query */\n rootLabel: string\n /** Optional plot title */\n title?: string\n /**\n * Column supplying each category's label. Either a column name (matched\n * against the query result headers) or a zero-based index. Defaults to the\n * first column.\n */\n labelColumn?: string | number\n /**\n * Column supplying each link's value. Either a column name or a zero-based\n * index. Defaults to the second column.\n */\n valueColumn?: string | number\n /**\n * Noun for the left end total caption, e.g. \"datasets\" renders\n * \"datasets total\". Defaults to \"items\".\n */\n unitLabel?: string\n /**\n * Phrase describing the breakdown, used in the chart's accessible label,\n * e.g. \"by source\" renders \"All Datasets broken down by source\".\n */\n breakdownLabel?: string\n /**\n * Invoked with a category's label when its left flow, center node, or label\n * is clicked. When provided, those become interactive (pointer cursor).\n */\n onCategoryClick?: (categoryLabel: string) => void\n /** Invoked when the left end node (rootLabel) is clicked. */\n onRootClick?: () => void\n /**\n * Enables \"butterfly\" mode: a second value per category drawn as a mirrored\n * flow from each center node to a right end node. Either a column name or a\n * zero-based index (defaults to the third column when a right end is shown).\n */\n rightValueColumn?: string | number\n /** Label for the right end node (butterfly mode). Defaults to \"Files\". */\n rightLabel?: string\n /** Noun for the right end total caption, e.g. \"files\". Defaults to \"items\". */\n rightUnitLabel?: string\n /** Invoked with a category's label when its right flow is clicked. */\n onRightCategoryClick?: (categoryLabel: string) => void\n /** Invoked when the right end node (rightLabel) is clicked. */\n onRightEndClick?: () => void\n}\n\n// Datum shapes for the d3-sankey graph.\ntype NodeKind = 'leftEnd' | 'source' | 'rightEnd'\ntype NodeDatum = {\n name: string\n value: number\n color: string\n kind: NodeKind\n // Raw per-source counts, used by the butterfly center labels.\n leftValue?: number\n rightValue?: number\n}\ntype LinkDatum = {\n value: number\n // Zero-based index of the center (source) node this link belongs to.\n sourceIndex: number\n side: 'left' | 'right'\n}\ntype LaidOutNode = D3SankeyNode<NodeDatum, LinkDatum>\ntype InteractiveProps = { cursor?: 'pointer'; onClick?: () => void }\n\n// Coordinate space of the SVG. The rendered width is capped at VIEW_W (see the\n// wrapper's maxWidth) so one viewBox unit ≈ one CSS pixel and text renders at\n// its intended size instead of being magnified on wide containers. Generous\n// gutters leave unclipped room for the end figures and labels. The height grows\n// with the number of categories so rows stay legible.\nconst VIEW_W = 920\nconst GUTTER_LEFT = 124\nconst GUTTER_RIGHT = 286\nconst GUTTER_Y = 22\nconst NODE_WIDTH = 13\nconst NODE_PADDING = 34\nconst ROW_HEIGHT = 46\n// Horizontal gap between a node and its adjacent label/figure.\nconst LABEL_GAP = 14\n// Category row: a fixed-width column reserved for the count, so the share\n// micro-bar always starts at the same x regardless of the number's length.\nconst COUNT_COLUMN_W = 70\nconst BAR_TRACK_W = 64\nconst BAR_HEIGHT = 4.5\n// Butterfly mode needs more vertical room per row for the center labels, which\n// sit in the padding gap above each node. The left/right gutters are equal so\n// the center column lands at the SVG's horizontal center (aligning the center\n// labels with the centered title), with room for an end figure on each side.\nconst BUTTERFLY_ROW_HEIGHT = 64\nconst BUTTERFLY_NODE_PADDING = 56\nconst BUTTERFLY_GUTTER_TOP = 44\nconst BUTTERFLY_GUTTER_X = 160\n\nconst midY = (node: LaidOutNode) => ((node.y0 ?? 0) + (node.y1 ?? 0)) / 2\nconst midX = (node: LaidOutNode) => ((node.x0 ?? 0) + (node.x1 ?? 0)) / 2\n\n// The editorial figure beside an end node: an eyebrow label, the total, and a\n// caption (e.g. \"datasets total\"). Mirrored for the right end.\nfunction SankeyEndFigure(props: {\n node: LaidOutNode\n total: number\n unitLabel: string\n align: 'left' | 'right'\n onMouseEnter: () => void\n interactiveProps: InteractiveProps\n}): React.ReactNode {\n const { node, total, unitLabel, align, onMouseEnter, interactiveProps } =\n props\n const theme = useTheme()\n const cy = midY(node)\n const x =\n align === 'left' ? (node.x0 ?? 0) - LABEL_GAP : (node.x1 ?? 0) + LABEL_GAP\n const textAnchor = align === 'left' ? 'end' : 'start'\n return (\n <g onMouseEnter={onMouseEnter} {...interactiveProps}>\n <text\n x={x}\n y={cy - 22}\n textAnchor={textAnchor}\n fontSize={10}\n fontWeight={600}\n letterSpacing={1.2}\n fill={theme.palette.grey[700]}\n >\n {node.name.toUpperCase()}\n </text>\n <text\n x={x}\n y={cy + 6}\n textAnchor={textAnchor}\n fontSize={26}\n fontWeight={600}\n fill={theme.palette.primary.dark}\n className={styles.tabularNums}\n >\n {total.toLocaleString()}\n </text>\n <text\n x={x}\n y={cy + 23}\n textAnchor={textAnchor}\n fontSize={11}\n fontWeight={500}\n fill={theme.palette.text.secondary}\n >\n {`${unitLabel} total`}\n </text>\n </g>\n )\n}\n\n// Hub-and-spoke category label (single value): name, count, share bar, percent,\n// placed to the right of the center node.\nfunction SankeyCategoryLabel(props: {\n node: LaidOutNode\n total: number\n opacity: number\n onMouseEnter: () => void\n interactiveProps: InteractiveProps\n}): React.ReactNode {\n const { node, total, opacity, onMouseEnter, interactiveProps } = props\n const theme = useTheme()\n const cy = midY(node)\n const x = (node.x1 ?? 0) + LABEL_GAP\n const value = node.value ?? 0\n const pct = total > 0 ? value / total : 0\n const barX = x + COUNT_COLUMN_W\n const barY = cy + 6\n return (\n <g\n opacity={opacity}\n className={styles.categoryLabel}\n onMouseEnter={onMouseEnter}\n {...interactiveProps}\n >\n <text\n x={x}\n y={cy - 4}\n fontSize={13}\n fontWeight={600}\n fill={theme.palette.text.primary}\n >\n {node.name}\n </text>\n <text\n x={x}\n y={cy + 14}\n fontSize={13}\n fontWeight={600}\n fill={node.color}\n className={styles.tabularNums}\n >\n {value.toLocaleString()}\n </text>\n <rect\n x={barX}\n y={barY}\n width={BAR_TRACK_W}\n height={BAR_HEIGHT}\n rx={BAR_HEIGHT / 2}\n fill={theme.palette.grey[300]}\n />\n <rect\n x={barX}\n y={barY}\n width={BAR_TRACK_W * pct}\n height={BAR_HEIGHT}\n rx={BAR_HEIGHT / 2}\n fill={node.color}\n />\n <text\n x={barX + BAR_TRACK_W + 7}\n y={cy + 13}\n fontSize={11}\n fontWeight={500}\n fill={theme.palette.grey[700]}\n className={styles.tabularNums}\n >\n {(pct * 100).toFixed(1)}%\n </text>\n </g>\n )\n}\n\n// Butterfly center label: the source name and both counts, centered above the\n// node (the only clear space between the left and right flows).\nfunction SankeyCenterLabel(props: {\n node: LaidOutNode\n leftValue: number\n rightValue: number\n unitLabel: string\n rightUnitLabel: string\n opacity: number\n onMouseEnter: () => void\n interactiveProps: InteractiveProps\n}): React.ReactNode {\n const {\n node,\n leftValue,\n rightValue,\n unitLabel,\n rightUnitLabel,\n opacity,\n onMouseEnter,\n interactiveProps,\n } = props\n const theme = useTheme()\n const cx = midX(node)\n const topY = node.y0 ?? 0\n return (\n <g\n opacity={opacity}\n className={styles.categoryLabel}\n onMouseEnter={onMouseEnter}\n {...interactiveProps}\n >\n <text\n x={cx}\n y={topY - 20}\n textAnchor=\"middle\"\n fontSize={13}\n fontWeight={600}\n fill={theme.palette.text.primary}\n stroke={theme.palette.background.paper}\n className={styles.haloText}\n >\n {node.name}\n </text>\n <text\n x={cx}\n y={topY - 6}\n textAnchor=\"middle\"\n fontSize={11}\n fontWeight={600}\n fill={theme.palette.text.secondary}\n stroke={theme.palette.background.paper}\n className={classNames(styles.tabularNums, styles.haloText)}\n >\n {`${leftValue.toLocaleString()} ${unitLabel} · ${rightValue.toLocaleString()} ${rightUnitLabel}`}\n </text>\n </g>\n )\n}\n\nexport const SynapseSankeyPlot = (\n props: SynapseSankeyPlotProps,\n): React.ReactNode => {\n const {\n sql,\n rootLabel,\n title,\n labelColumn,\n valueColumn,\n unitLabel = 'items',\n breakdownLabel,\n onCategoryClick,\n onRootClick,\n rightValueColumn,\n rightLabel = 'Files',\n rightUnitLabel = 'items',\n onRightCategoryClick,\n onRightEndClick,\n } = props\n const theme = useTheme()\n const gradientPrefix = useId()\n\n const hasRightFlow = rightValueColumn !== undefined\n\n // Index of the center node currently focused (null = nothing focused). Drives\n // the focus/dim hover interaction; shared by both flows of a source.\n const [hovered, setHovered] = useState<number | null>(null)\n // Index of the center node that was clicked; briefly emphasized before the\n // handler fires.\n const [clicked, setClicked] = useState<number | null>(null)\n // One-time gentle fade-in on mount.\n const [visible, setVisible] = useState(false)\n useEffect(() => {\n const id = requestAnimationFrame(() => setVisible(true))\n return () => cancelAnimationFrame(id)\n }, [])\n // Timer that briefly emphasizes a clicked flow before invoking the handler.\n // Held in a ref so it can be cleared on unmount and replaced on rapid clicks.\n const clickTimer = useRef<number | undefined>(undefined)\n useEffect(() => {\n return () => {\n if (clickTimer.current !== undefined) {\n window.clearTimeout(clickTimer.current)\n }\n }\n }, [])\n\n const queryRequest: QueryBundleRequest = {\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n partMask: SynapseConstants.BUNDLE_MASK_QUERY_RESULTS,\n entityId: parseEntityIdFromSqlStatement(sql),\n query: {\n sql,\n },\n }\n\n const { data: queryData, isLoading } =\n useGetFullTableQueryResults(queryRequest)\n\n const rows = useMemo(\n () => queryData?.queryResult?.queryResults.rows ?? [],\n [queryData],\n )\n\n // Resolve the label/value columns (by name or index) against the result\n // headers, falling back to the first columns.\n const { labelIndex, valueIndex, rightValueIndex } = useMemo(() => {\n const headers = queryData?.queryResult?.queryResults.headers ?? []\n const resolve = (col: string | number | undefined, fallback: number) => {\n if (typeof col === 'number') {\n return col\n }\n if (typeof col === 'string') {\n const idx = headers.findIndex(h => h.name === col)\n return idx >= 0 ? idx : fallback\n }\n return fallback\n }\n return {\n labelIndex: resolve(labelColumn, 0),\n valueIndex: resolve(valueColumn, 1),\n rightValueIndex: hasRightFlow ? resolve(rightValueColumn, 2) : -1,\n }\n }, [queryData, labelColumn, valueColumn, rightValueColumn, hasRightFlow])\n\n // Theme-derived palette: end nodes use the dark primary color; category nodes\n // step through a light-to-dark sweep of the primary color so they stay\n // on-brand while remaining distinguishable (even when a portal's primary and\n // secondary colors are identical).\n const fontFamily = theme.typography.fontFamily ?? 'inherit'\n const endColor = theme.palette.primary.dark\n const textColor = theme.palette.text.primary\n\n // viewH feeds the SVG viewBox, so it lives at component scope; the remaining\n // spacing is derived inside the layout memo below.\n const gutterTop = hasRightFlow ? BUTTERFLY_GUTTER_TOP : GUTTER_Y\n const rowHeight = hasRightFlow ? BUTTERFLY_ROW_HEIGHT : ROW_HEIGHT\n const viewH = Math.max(320, gutterTop + GUTTER_Y + rows.length * rowHeight)\n\n // Build and lay out the graph. Memoized so hovering (which only changes\n // opacity) doesn't recompute the layout.\n const graphResult = useMemo(() => {\n if (rows.length === 0) {\n return null\n }\n const gradientStart = tinycolor(theme.palette.primary.main).lighten(18)\n const gradientEnd = tinycolor(theme.palette.primary.main).darken(12)\n const categoryColor = (index: number) =>\n rows.length <= 1\n ? theme.palette.primary.main\n : tinycolor\n .mix(gradientStart, gradientEnd, (index / (rows.length - 1)) * 100)\n .toHexString()\n\n const sources = rows.map((row, index) => ({\n name: String(row.values[labelIndex] ?? ''),\n leftValue: Number(row.values[valueIndex] ?? 0),\n rightValue: hasRightFlow ? Number(row.values[rightValueIndex] ?? 0) : 0,\n color: categoryColor(index),\n }))\n const totalLeft = sources.reduce((sum, s) => sum + s.leftValue, 0)\n const totalRight = sources.reduce((sum, s) => sum + s.rightValue, 0)\n const rightEndIndex = sources.length + 1\n\n // d3-sankey scales every ribbon by a single value→thickness factor. When the\n // two flows differ in magnitude (e.g. ~25 datasets vs thousands of files),\n // the smaller side collapses to hairlines. Scale the left flow so both\n // halves sum to the same total — ribbon widths then read as each side's\n // share. The real counts are preserved on the node data for the labels.\n const leftScale =\n hasRightFlow && totalLeft > 0 && totalRight > 0\n ? totalRight / totalLeft\n : 1\n const linkValue = (value: number, side: 'left' | 'right') =>\n side === 'left' ? value * leftScale : value\n\n const nodes: NodeDatum[] = [\n { name: rootLabel, value: totalLeft, color: endColor, kind: 'leftEnd' },\n ...sources.map(s => ({\n name: s.name,\n value: s.leftValue,\n color: s.color,\n kind: 'source' as const,\n leftValue: s.leftValue,\n rightValue: s.rightValue,\n })),\n ...(hasRightFlow\n ? [\n {\n name: rightLabel,\n value: totalRight,\n color: endColor,\n kind: 'rightEnd' as const,\n },\n ]\n : []),\n ]\n const links: ({ source: number; target: number } & LinkDatum)[] = [\n ...sources.map((s, index) => ({\n source: 0,\n target: index + 1,\n value: linkValue(s.leftValue, 'left'),\n sourceIndex: index,\n side: 'left' as const,\n })),\n ...(hasRightFlow\n ? sources.map((s, index) => ({\n source: index + 1,\n target: rightEndIndex,\n value: linkValue(s.rightValue, 'right'),\n sourceIndex: index,\n side: 'right' as const,\n }))\n : []),\n ]\n\n const nodePadding = hasRightFlow ? BUTTERFLY_NODE_PADDING : NODE_PADDING\n // Symmetric gutters in butterfly mode center the column layout.\n const gutterLeft = hasRightFlow ? BUTTERFLY_GUTTER_X : GUTTER_LEFT\n const gutterRight = hasRightFlow ? BUTTERFLY_GUTTER_X : GUTTER_RIGHT\n const layout = d3Sankey<NodeDatum, LinkDatum>()\n .nodeWidth(NODE_WIDTH)\n .nodePadding(nodePadding)\n .nodeSort(null) // preserve query order top-to-bottom\n .extent([\n [gutterLeft, gutterTop],\n [VIEW_W - gutterRight, viewH - GUTTER_Y],\n ])\n\n return {\n graph: layout({\n nodes: nodes.map(d => ({ ...d })),\n links: links.map(d => ({ ...d })),\n }),\n // Real (unscaled) totals for the end-node figures.\n totalLeft,\n totalRight,\n }\n }, [\n rows,\n labelIndex,\n valueIndex,\n rightValueIndex,\n hasRightFlow,\n rootLabel,\n rightLabel,\n endColor,\n theme.palette.primary.main,\n viewH,\n gutterTop,\n ])\n\n if (isLoading) {\n return <Skeleton width={'100%'} height={'500px'} />\n }\n if (!graphResult) {\n return <></>\n }\n\n const { graph, totalLeft, totalRight } = graphResult\n const linkPath = sankeyLinkHorizontal<NodeDatum, LinkDatum>()\n\n // The clicked flow takes precedence over the hovered one for emphasis.\n const focusIndex = clicked ?? hovered\n // Dim the rest harder once a selection has been committed.\n const dimLink = clicked !== null ? 0.05 : 0.07\n const dimNode = clicked !== null ? 0.1 : 0.16\n const dimLabel = clicked !== null ? 0.15 : 0.32\n\n // Opacity helpers for the focus/dim interaction. Both flows of a focused\n // source share its center-node index.\n const linkOpacity = (sourceIndex: number) =>\n focusIndex === null\n ? 0.6\n : sourceIndex === focusIndex\n ? clicked !== null\n ? 1\n : 0.95\n : dimLink\n const nodeOpacity = (node: LaidOutNode) =>\n focusIndex === null ||\n node.kind !== 'source' ||\n (node.index ?? 1) - 1 === focusIndex\n ? 1\n : dimNode\n const labelOpacity = (sourceIndex: number) =>\n focusIndex === null || focusIndex === sourceIndex ? 1 : dimLabel\n\n // Clicking a center flow briefly emphasizes it (a quick \"swell\") and then\n // fires the handler, so the navigation feels intentional. No tabIndex/role:\n // those make the browser draw a focus outline box around the SVG shape.\n const activate = (sourceIndex: number, fire: () => void) => {\n if (clickTimer.current !== undefined) {\n window.clearTimeout(clickTimer.current)\n }\n setClicked(sourceIndex)\n clickTimer.current = window.setTimeout(() => {\n clickTimer.current = undefined\n // Clear the transient emphasis before invoking the handler so the chart\n // returns to its resting state for consumers whose handler doesn't\n // navigate away (and unmount) the component.\n setClicked(null)\n fire()\n }, 320)\n }\n // Center flows swell on click; end nodes navigate immediately.\n const flowProps = (\n sourceIndex: number,\n fire: (() => void) | undefined,\n ): InteractiveProps =>\n fire\n ? { cursor: 'pointer', onClick: () => activate(sourceIndex, fire) }\n : {}\n const endProps = (fire: (() => void) | undefined): InteractiveProps =>\n fire ? { cursor: 'pointer', onClick: fire } : {}\n // The \"datasets\" (left) handler fires for a center node and its left flow.\n const categoryFire = (name: string) =>\n onCategoryClick ? () => onCategoryClick(name) : undefined\n\n return (\n <div className={classNames(styles.root, { [styles.rootVisible]: visible })}>\n {title && (\n <div className={styles.title} style={{ fontFamily, color: textColor }}>\n {title}\n </div>\n )}\n <svg\n viewBox={`0 0 ${VIEW_W} ${viewH}`}\n role=\"img\"\n aria-label={\n breakdownLabel\n ? `${rootLabel} broken down ${breakdownLabel}`\n : `${rootLabel} breakdown`\n }\n className={styles.svg}\n style={{ fontFamily, maxWidth: VIEW_W }}\n onMouseLeave={() => setHovered(null)}\n >\n <defs>\n {graph.links.map((link, i) => {\n const source = link.source as LaidOutNode\n const target = link.target as LaidOutNode\n return (\n <linearGradient\n key={i}\n id={`${gradientPrefix}-grad-${i}`}\n gradientUnits=\"userSpaceOnUse\"\n x1={source.x1}\n x2={target.x0}\n >\n <stop offset=\"0%\" stopColor={source.color} />\n <stop offset=\"100%\" stopColor={target.color} />\n </linearGradient>\n )\n })}\n </defs>\n\n {/* Ribbons */}\n <g fill=\"none\">\n {graph.links.map((link, i) => {\n const sourceNode = (\n link.side === 'left' ? link.target : link.source\n ) as LaidOutNode\n const baseWidth = Math.max(1, link.width ?? 1)\n const handler =\n link.side === 'left' ? onCategoryClick : onRightCategoryClick\n const fire = handler ? () => handler(sourceNode.name) : undefined\n return (\n <path\n key={i}\n d={linkPath(link) ?? undefined}\n stroke={`url(#${gradientPrefix}-grad-${i})`}\n strokeWidth={\n clicked === link.sourceIndex ? baseWidth * 1.25 : baseWidth\n }\n strokeOpacity={linkOpacity(link.sourceIndex)}\n className={styles.ribbon}\n onMouseEnter={() => setHovered(link.sourceIndex)}\n {...flowProps(link.sourceIndex, fire)}\n />\n )\n })}\n </g>\n\n {/* Nodes */}\n <g>\n {graph.nodes.map((node, i) => {\n const sourceIndex = (node.index ?? 1) - 1\n const clickProps =\n node.kind === 'leftEnd'\n ? endProps(onRootClick)\n : node.kind === 'rightEnd'\n ? endProps(onRightEndClick)\n : flowProps(sourceIndex, categoryFire(node.name))\n return (\n <rect\n key={i}\n x={node.x0}\n y={node.y0}\n width={(node.x1 ?? 0) - (node.x0 ?? 0)}\n height={Math.max(1, (node.y1 ?? 0) - (node.y0 ?? 0))}\n rx={4}\n fill={node.color}\n fillOpacity={nodeOpacity(node)}\n stroke={theme.palette.background.paper}\n strokeWidth={1}\n className={styles.node}\n onMouseEnter={() =>\n setHovered(node.kind === 'source' ? sourceIndex : null)\n }\n {...clickProps}\n />\n )\n })}\n </g>\n\n {/* Labels */}\n {graph.nodes.map((node, i) => {\n if (node.kind === 'leftEnd') {\n return (\n <SankeyEndFigure\n key={`lab-${i}`}\n node={node}\n total={totalLeft}\n unitLabel={unitLabel}\n align=\"left\"\n onMouseEnter={() => setHovered(null)}\n interactiveProps={endProps(onRootClick)}\n />\n )\n }\n if (node.kind === 'rightEnd') {\n return (\n <SankeyEndFigure\n key={`lab-${i}`}\n node={node}\n total={totalRight}\n unitLabel={rightUnitLabel}\n align=\"right\"\n onMouseEnter={() => setHovered(null)}\n interactiveProps={endProps(onRightEndClick)}\n />\n )\n }\n const sourceIndex = (node.index ?? 1) - 1\n const fire = categoryFire(node.name)\n if (hasRightFlow) {\n return (\n <SankeyCenterLabel\n key={`lab-${i}`}\n node={node}\n leftValue={node.leftValue ?? 0}\n rightValue={node.rightValue ?? 0}\n unitLabel={unitLabel}\n rightUnitLabel={rightUnitLabel}\n opacity={labelOpacity(sourceIndex)}\n onMouseEnter={() => setHovered(sourceIndex)}\n interactiveProps={flowProps(sourceIndex, fire)}\n />\n )\n }\n return (\n <SankeyCategoryLabel\n key={`lab-${i}`}\n node={node}\n total={totalLeft}\n opacity={labelOpacity(sourceIndex)}\n onMouseEnter={() => setHovered(sourceIndex)}\n interactiveProps={flowProps(sourceIndex, fire)}\n />\n )\n })}\n </svg>\n </div>\n )\n}\n\nexport default SynapseSankeyPlot\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import './SynapseSankeyPlot.css';var e = {
|
|
2
|
+
root: "_root_244go_1",
|
|
3
|
+
rootVisible: "_rootVisible_244go_8",
|
|
4
|
+
title: "_title_244go_12",
|
|
5
|
+
svg: "_svg_244go_19",
|
|
6
|
+
ribbon: "_ribbon_244go_28",
|
|
7
|
+
node: "_node_244go_32",
|
|
8
|
+
categoryLabel: "_categoryLabel_244go_36",
|
|
9
|
+
tabularNums: "_tabularNums_244go_40",
|
|
10
|
+
haloText: "_haloText_244go_44"
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { e as default };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=SynapseSankeyPlot.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SynapseSankeyPlot.module.js","names":[],"sources":["../../../src/components/Plot/SynapseSankeyPlot.module.scss"],"sourcesContent":["// Layout/chrome for SynapseSankeyPlot. Theme-derived values (font family,\n// colors) stay inline in the component so the chart adopts each portal's MUI\n// palette; only the static structure and transitions live here.\n\n.root {\n width: 100%;\n margin-top: 48px;\n opacity: 0;\n transition: opacity 0.6s ease;\n}\n\n.rootVisible {\n opacity: 1;\n}\n\n.title {\n font-weight: 600;\n font-size: 20px;\n text-align: center;\n margin-bottom: 12px;\n}\n\n.svg {\n display: block;\n overflow: visible;\n width: 100%;\n height: auto;\n margin: 0 auto;\n outline: none;\n}\n\n.ribbon {\n transition:\n stroke-opacity 0.25s ease,\n stroke-width 0.25s ease;\n}\n\n.node {\n transition: fill-opacity 0.25s ease;\n}\n\n.categoryLabel {\n transition: opacity 0.2s ease;\n}\n\n.tabularNums {\n font-variant-numeric: tabular-nums;\n}\n\n// White halo behind label text so it stays legible where it crosses a ribbon.\n// The stroke color is set inline from the theme background; paint-order draws\n// the stroke first (behind the fill).\n.haloText {\n paint-order: stroke;\n stroke-width: 3px;\n stroke-linejoin: round;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .root {\n transition: none;\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Layout/chrome for SynapseSankeyPlot. Theme-derived values (font family,
|
|
2
|
+
// colors) stay inline in the component so the chart adopts each portal's MUI
|
|
3
|
+
// palette; only the static structure and transitions live here.
|
|
4
|
+
|
|
5
|
+
.root {
|
|
6
|
+
width: 100%;
|
|
7
|
+
margin-top: 48px;
|
|
8
|
+
opacity: 0;
|
|
9
|
+
transition: opacity 0.6s ease;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.rootVisible {
|
|
13
|
+
opacity: 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.title {
|
|
17
|
+
font-weight: 600;
|
|
18
|
+
font-size: 20px;
|
|
19
|
+
text-align: center;
|
|
20
|
+
margin-bottom: 12px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.svg {
|
|
24
|
+
display: block;
|
|
25
|
+
overflow: visible;
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: auto;
|
|
28
|
+
margin: 0 auto;
|
|
29
|
+
outline: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.ribbon {
|
|
33
|
+
transition:
|
|
34
|
+
stroke-opacity 0.25s ease,
|
|
35
|
+
stroke-width 0.25s ease;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.node {
|
|
39
|
+
transition: fill-opacity 0.25s ease;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.categoryLabel {
|
|
43
|
+
transition: opacity 0.2s ease;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.tabularNums {
|
|
47
|
+
font-variant-numeric: tabular-nums;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// White halo behind label text so it stays legible where it crosses a ribbon.
|
|
51
|
+
// The stroke color is set inline from the theme background; paint-order draws
|
|
52
|
+
// the stroke first (behind the fill).
|
|
53
|
+
.haloText {
|
|
54
|
+
paint-order: stroke;
|
|
55
|
+
stroke-width: 3px;
|
|
56
|
+
stroke-linejoin: round;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@media (prefers-reduced-motion: reduce) {
|
|
60
|
+
.root {
|
|
61
|
+
transition: none;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ProjectVisibility } from './getProjectVisibilityFromACL';
|
|
2
|
+
export type ProjectVisibilityChipProps = {
|
|
3
|
+
visibility: ProjectVisibility;
|
|
4
|
+
};
|
|
5
|
+
export type ProjectVisibilityChipContainerProps = {
|
|
6
|
+
entityId: string;
|
|
7
|
+
};
|
|
8
|
+
export default function ProjectVisibilityChip({ entityId, }: ProjectVisibilityChipContainerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=ProjectVisibilityChip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectVisibilityChip.d.ts","sourceRoot":"","sources":["../../../src/components/ProjectVisibilityChip/ProjectVisibilityChip.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,iBAAiB,EAClB,MAAM,+BAA+B,CAAA;AAKtC,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,iBAAiB,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,mCAAmC,GAAG;IAChD,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AA+DD,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAC5C,QAAQ,GACT,EAAE,mCAAmC,kDA0BrC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useGetRealmPrincipals as e } from "../../synapse-queries/realm/useRealmPrincipals.js";
|
|
2
|
+
import t from "../../synapse-queries/entity/useEntityBundle.js";
|
|
3
|
+
import "../../synapse-queries/index.js";
|
|
4
|
+
import { getProjectVisibilityFromACL as n } from "./getProjectVisibilityFromACL.js";
|
|
5
|
+
import { Chip as r, Skeleton as i, Typography as a } from "@mui/material";
|
|
6
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
7
|
+
import s from "@mui/icons-material/VisibilityOutlined";
|
|
8
|
+
import c from "@mui/icons-material/LanguageOutlined";
|
|
9
|
+
import l from "@mui/icons-material/LockOutlined";
|
|
10
|
+
//#region src/components/ProjectVisibilityChip/ProjectVisibilityChip.tsx
|
|
11
|
+
var u = {
|
|
12
|
+
fill: "var(--synapse-gray-900)",
|
|
13
|
+
width: "16px"
|
|
14
|
+
}, d = {
|
|
15
|
+
PRIVATE: {
|
|
16
|
+
label: "Private Project",
|
|
17
|
+
color: "#FAC3C3",
|
|
18
|
+
icon: /* @__PURE__ */ o(l, { sx: u })
|
|
19
|
+
},
|
|
20
|
+
DISCOVERABLE: {
|
|
21
|
+
label: "Discoverable Project",
|
|
22
|
+
color: "#FDEFC1",
|
|
23
|
+
icon: /* @__PURE__ */ o(s, { sx: u })
|
|
24
|
+
},
|
|
25
|
+
PUBLIC: {
|
|
26
|
+
label: "Public Project",
|
|
27
|
+
color: "#D4EFD4",
|
|
28
|
+
icon: /* @__PURE__ */ o(c, { sx: u })
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function f({ visibility: e }) {
|
|
32
|
+
return /* @__PURE__ */ o(r, {
|
|
33
|
+
sx: {
|
|
34
|
+
display: "flex",
|
|
35
|
+
padding: "4px 8px",
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
gap: "6px",
|
|
38
|
+
borderRadius: "7px",
|
|
39
|
+
width: "fit-content",
|
|
40
|
+
backgroundColor: d[e].color,
|
|
41
|
+
"& .MuiChip-icon": {
|
|
42
|
+
marginLeft: "0px",
|
|
43
|
+
marginRight: "0px"
|
|
44
|
+
},
|
|
45
|
+
"& .MuiChip-label": { px: 0 }
|
|
46
|
+
},
|
|
47
|
+
icon: d[e].icon,
|
|
48
|
+
label: /* @__PURE__ */ o(a, {
|
|
49
|
+
variant: "body2",
|
|
50
|
+
sx: {
|
|
51
|
+
lineHeight: "12px",
|
|
52
|
+
letterSpacing: "-0.06px"
|
|
53
|
+
},
|
|
54
|
+
children: d[e].label
|
|
55
|
+
})
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function p({ entityId: r }) {
|
|
59
|
+
let { data: a, isLoading: s, isError: c } = t(r, void 0, { includeBenefactorACL: !0 }), { data: l, isLoading: u, isError: d } = e();
|
|
60
|
+
return c || d ? null : s || u ? /* @__PURE__ */ o(i, {
|
|
61
|
+
variant: "rounded",
|
|
62
|
+
width: 120,
|
|
63
|
+
height: 24
|
|
64
|
+
}) : /* @__PURE__ */ o(f, { visibility: n(a?.benefactorAcl?.resourceAccess ?? [], l || {}) });
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { p as default };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=ProjectVisibilityChip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectVisibilityChip.js","names":[],"sources":["../../../src/components/ProjectVisibilityChip/ProjectVisibilityChip.tsx"],"sourcesContent":["import { useGetRealmPrincipals } from '@/synapse-queries/realm/useRealmPrincipals'\nimport { Skeleton, Chip, Typography } from '@mui/material'\nimport { useGetEntityBundle } from '@/synapse-queries'\nimport {\n getProjectVisibilityFromACL,\n ProjectVisibility,\n} from './getProjectVisibilityFromACL'\nimport VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined'\nimport LanguageOutlinedIcon from '@mui/icons-material/LanguageOutlined'\nimport LockOutlinedIcon from '@mui/icons-material/LockOutlined'\n\nexport type ProjectVisibilityChipProps = {\n visibility: ProjectVisibility\n}\n\nexport type ProjectVisibilityChipContainerProps = {\n entityId: string\n}\n\nconst iconStyles = {\n fill: 'var(--synapse-gray-900)',\n width: '16px',\n}\n\nconst VISIBILITY_LABELS: Record<\n ProjectVisibility,\n { label: string; color: string; icon: React.ReactElement }\n> = {\n PRIVATE: {\n label: 'Private Project',\n color: '#FAC3C3',\n icon: <LockOutlinedIcon sx={iconStyles} />,\n },\n DISCOVERABLE: {\n label: 'Discoverable Project',\n color: '#FDEFC1',\n icon: <VisibilityOutlinedIcon sx={iconStyles} />,\n },\n PUBLIC: {\n label: 'Public Project',\n color: '#D4EFD4',\n icon: <LanguageOutlinedIcon sx={iconStyles} />,\n },\n}\n\nfunction ProjectVisibilityChipUI({ visibility }: ProjectVisibilityChipProps) {\n return (\n <Chip\n sx={{\n display: 'flex',\n padding: '4px 8px',\n alignItems: 'center',\n gap: '6px',\n borderRadius: '7px',\n width: 'fit-content',\n backgroundColor: VISIBILITY_LABELS[visibility].color,\n '& .MuiChip-icon': {\n marginLeft: '0px',\n marginRight: '0px',\n },\n '& .MuiChip-label': {\n px: 0,\n },\n }}\n icon={VISIBILITY_LABELS[visibility].icon}\n label={\n <Typography\n variant=\"body2\"\n sx={{\n lineHeight: '12px',\n letterSpacing: '-0.06px',\n }}\n >\n {VISIBILITY_LABELS[visibility].label}\n </Typography>\n }\n />\n )\n}\n\nexport default function ProjectVisibilityChip({\n entityId,\n}: ProjectVisibilityChipContainerProps) {\n const {\n data: entityBundle,\n isLoading: isLoadingEntityBundle,\n isError: isErrorEntityBundle,\n } = useGetEntityBundle(entityId, undefined, { includeBenefactorACL: true })\n const {\n data: realmPrincipals,\n isLoading: isLoadingRealmPrincipals,\n isError: isErrorRealmPrincipals,\n } = useGetRealmPrincipals()\n\n if (isErrorEntityBundle || isErrorRealmPrincipals) {\n return null\n }\n\n if (isLoadingEntityBundle || isLoadingRealmPrincipals) {\n return <Skeleton variant=\"rounded\" width={120} height={24} />\n }\n\n const visibility = getProjectVisibilityFromACL(\n entityBundle?.benefactorAcl?.resourceAccess ?? [],\n realmPrincipals || {},\n )\n\n return <ProjectVisibilityChipUI visibility={visibility} />\n}\n"],"mappings":";;;;;;;;;;AAmBA,IAAM,IAAa;CACjB,MAAM;CACN,OAAO;AACT,GAEM,IAGF;CACF,SAAS;EACP,OAAO;EACP,OAAO;EACP,MAAM,kBAAC,GAAD,EAAkB,IAAI,EAAa,CAAA;CAC3C;CACA,cAAc;EACZ,OAAO;EACP,OAAO;EACP,MAAM,kBAAC,GAAD,EAAwB,IAAI,EAAa,CAAA;CACjD;CACA,QAAQ;EACN,OAAO;EACP,OAAO;EACP,MAAM,kBAAC,GAAD,EAAsB,IAAI,EAAa,CAAA;CAC/C;AACF;AAEA,SAAS,EAAwB,EAAE,iBAA0C;CAC3E,OACE,kBAAC,GAAD;EACE,IAAI;GACF,SAAS;GACT,SAAS;GACT,YAAY;GACZ,KAAK;GACL,cAAc;GACd,OAAO;GACP,iBAAiB,EAAkB,GAAY;GAC/C,mBAAmB;IACjB,YAAY;IACZ,aAAa;GACf;GACA,oBAAoB,EAClB,IAAI,EACN;EACF;EACA,MAAM,EAAkB,GAAY;EACpC,OACE,kBAAC,GAAD;GACE,SAAQ;GACR,IAAI;IACF,YAAY;IACZ,eAAe;GACjB;aAEC,EAAkB,GAAY;EACrB,CAAA;CAEf,CAAA;AAEL;AAEA,SAAwB,EAAsB,EAC5C,eACsC;CACtC,IAAM,EACJ,MAAM,GACN,WAAW,GACX,SAAS,MACP,EAAmB,GAAU,KAAA,GAAW,EAAE,sBAAsB,GAAK,CAAC,GACpE,EACJ,MAAM,GACN,WAAW,GACX,SAAS,MACP,EAAsB;CAe1B,OAbI,KAAuB,IAClB,OAGL,KAAyB,IACpB,kBAAC,GAAD;EAAU,SAAQ;EAAU,OAAO;EAAK,QAAQ;CAAK,CAAA,IAQvD,kBAAC,GAAD,EAAqC,YALzB,EACjB,GAAc,eAAe,kBAAkB,CAAC,GAChD,KAAmB,CAAC,CAGsB,EAAa,CAAA;AAC3D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ResourceAccess } from '@sage-bionetworks/synapse-types';
|
|
2
|
+
export type ProjectVisibility = 'PRIVATE' | 'DISCOVERABLE' | 'PUBLIC';
|
|
3
|
+
/**
|
|
4
|
+
* Determines a project's visibility category based on its Access Control List (ACL).
|
|
5
|
+
* - **PUBLIC**: Public group has READ access AND authenticated users have both READ and DOWNLOAD access.
|
|
6
|
+
* - **DISCOVERABLE**: Public group has READ access AND authenticated users have READ access (but lack DOWNLOAD access).
|
|
7
|
+
* - **PRIVATE**: Default state; matches neither condition above.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getProjectVisibilityFromACL(resourceAccess: ResourceAccess[], realmPrincipals: {
|
|
10
|
+
publicGroup?: string;
|
|
11
|
+
authenticatedUsers?: string;
|
|
12
|
+
}): ProjectVisibility;
|
|
13
|
+
//# sourceMappingURL=getProjectVisibilityFromACL.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getProjectVisibilityFromACL.d.ts","sourceRoot":"","sources":["../../../src/components/ProjectVisibilityChip/getProjectVisibilityFromACL.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAG7E,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,CAAA;AAErE;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,cAAc,EAAE,EAChC,eAAe,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GACrE,iBAAiB,CAyBnB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { consolidateResourceAccessList as e } from "../../utils/functions/AccessControlListUtils.js";
|
|
2
|
+
import { ACCESS_TYPE as t } from "@sage-bionetworks/synapse-types";
|
|
3
|
+
//#region src/components/ProjectVisibilityChip/getProjectVisibilityFromACL.ts
|
|
4
|
+
function n(n, r) {
|
|
5
|
+
let i = e(n), a = i.find((e) => e.principalId === Number(r.publicGroup))?.accessType ?? [], o = i.find((e) => e.principalId === Number(r.authenticatedUsers))?.accessType ?? [], s = a.includes(t.READ), c = o.includes(t.READ), l = o.includes(t.DOWNLOAD);
|
|
6
|
+
return s && c && l ? "PUBLIC" : s && c ? "DISCOVERABLE" : "PRIVATE";
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { n as getProjectVisibilityFromACL };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=getProjectVisibilityFromACL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getProjectVisibilityFromACL.js","names":[],"sources":["../../../src/components/ProjectVisibilityChip/getProjectVisibilityFromACL.ts"],"sourcesContent":["import { ACCESS_TYPE, ResourceAccess } from '@sage-bionetworks/synapse-types'\nimport { consolidateResourceAccessList } from '@/utils/functions/AccessControlListUtils'\n\nexport type ProjectVisibility = 'PRIVATE' | 'DISCOVERABLE' | 'PUBLIC'\n\n/**\n * Determines a project's visibility category based on its Access Control List (ACL).\n * - **PUBLIC**: Public group has READ access AND authenticated users have both READ and DOWNLOAD access.\n * - **DISCOVERABLE**: Public group has READ access AND authenticated users have READ access (but lack DOWNLOAD access).\n * - **PRIVATE**: Default state; matches neither condition above.\n */\nexport function getProjectVisibilityFromACL(\n resourceAccess: ResourceAccess[],\n realmPrincipals: { publicGroup?: string; authenticatedUsers?: string },\n): ProjectVisibility {\n const consolidated = consolidateResourceAccessList(resourceAccess)\n\n // Extract access types for public and authenticated principals\n const publicAccess =\n consolidated.find(\n ra => ra.principalId === Number(realmPrincipals.publicGroup),\n )?.accessType ?? []\n\n const authAccess =\n consolidated.find(\n ra => ra.principalId === Number(realmPrincipals.authenticatedUsers),\n )?.accessType ?? []\n\n const publicCanRead = publicAccess.includes(ACCESS_TYPE.READ)\n const authCanRead = authAccess.includes(ACCESS_TYPE.READ)\n const authCanDownload = authAccess.includes(ACCESS_TYPE.DOWNLOAD)\n\n if (publicCanRead && authCanRead && authCanDownload) {\n return 'PUBLIC'\n }\n if (publicCanRead && authCanRead) {\n return 'DISCOVERABLE'\n }\n return 'PRIVATE'\n}\n"],"mappings":";;;AAWA,SAAgB,EACd,GACA,GACmB;CACnB,IAAM,IAAe,EAA8B,CAAc,GAG3D,IACJ,EAAa,MACX,MAAM,EAAG,gBAAgB,OAAO,EAAgB,WAAW,CAC7D,GAAG,cAAc,CAAC,GAEd,IACJ,EAAa,MACX,MAAM,EAAG,gBAAgB,OAAO,EAAgB,kBAAkB,CACpE,GAAG,cAAc,CAAC,GAEd,IAAgB,EAAa,SAAS,EAAY,IAAI,GACtD,IAAc,EAAW,SAAS,EAAY,IAAI,GAClD,IAAkB,EAAW,SAAS,EAAY,QAAQ;CAQhE,OANI,KAAiB,KAAe,IAC3B,WAEL,KAAiB,IACZ,iBAEF;AACT"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import ProjectVisibilityChip from './ProjectVisibilityChip';
|
|
2
|
+
import type { ProjectVisibilityChipProps, ProjectVisibilityChipContainerProps } from './ProjectVisibilityChip';
|
|
3
|
+
export { ProjectVisibilityChip, ProjectVisibilityChipProps, ProjectVisibilityChipContainerProps, };
|
|
4
|
+
export default ProjectVisibilityChip;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ProjectVisibilityChip/index.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,mCAAmC,EACpC,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,mCAAmC,GACpC,CAAA;AACD,eAAe,qBAAqB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/ProjectVisibilityChip/index.ts"],"sourcesContent":["import ProjectVisibilityChip from './ProjectVisibilityChip'\nimport type {\n ProjectVisibilityChipProps,\n ProjectVisibilityChipContainerProps,\n} from './ProjectVisibilityChip'\nexport {\n ProjectVisibilityChip,\n ProjectVisibilityChipProps,\n ProjectVisibilityChipContainerProps,\n}\nexport default ProjectVisibilityChip\n"],"mappings":";;AAUA,IAAA,IAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryVisualizationWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/QueryVisualizationWrapper/QueryVisualizationWrapper.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAA6C,MAAM,OAAO,CAAA;AAI5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAA;AACnF,OAAO,EAAE,wBAAwB,EAAE,MAAM,2DAA2D,CAAA;AAUpG,KAAK,uBAAuB,GAAG;IAC7B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG;IAC3C,QAAQ,EAAE,SAAS,GAAG,SAAS,EAAE,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uGAAuG;IACvG,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,gGAAgG;IAChG,8BAA8B,CAAC,EAAE,OAAO,CAAA;IACxC,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,6BAA6B;IAC7B,wBAAwB,CAAC,EAAE,wBAAwB,CAAA;IACnD,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAA;IACjC;mEAC+D;IAC/D,kCAAkC,CAAC,EAAE,MAAM,CAAA;IAC3C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,uBAAuB,EAAE,CAAA;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;gDAC4C;IAC5C,gCAAgC,CAAC,EAAE,wBAAwB,EAAE,CAAA;IAC7D,yBAAyB,CAAC,EAAE,OAAO,CAAA;CACpC,CAAA;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,8BAA8B,
|
|
1
|
+
{"version":3,"file":"QueryVisualizationWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/QueryVisualizationWrapper/QueryVisualizationWrapper.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAA6C,MAAM,OAAO,CAAA;AAI5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAA;AACnF,OAAO,EAAE,wBAAwB,EAAE,MAAM,2DAA2D,CAAA;AAUpG,KAAK,uBAAuB,GAAG;IAC7B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG;IAC3C,QAAQ,EAAE,SAAS,GAAG,SAAS,EAAE,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uGAAuG;IACvG,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,gGAAgG;IAChG,8BAA8B,CAAC,EAAE,OAAO,CAAA;IACxC,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,6BAA6B;IAC7B,wBAAwB,CAAC,EAAE,wBAAwB,CAAA;IACnD,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAA;IACjC;mEAC+D;IAC/D,kCAAkC,CAAC,EAAE,MAAM,CAAA;IAC3C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,uBAAuB,EAAE,CAAA;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;gDAC4C;IAC5C,gCAAgC,CAAC,EAAE,wBAAwB,EAAE,CAAA;IAC7D,yBAAyB,CAAC,EAAE,OAAO,CAAA;CACpC,CAAA;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,8BAA8B,2CAqNtC"}
|
|
@@ -32,7 +32,7 @@ function m(m) {
|
|
|
32
32
|
X
|
|
33
33
|
]);
|
|
34
34
|
let Z = s((e, t) => {
|
|
35
|
-
let n = localStorage.getItem("force-display-original-column-names") === "true";
|
|
35
|
+
let n = typeof localStorage < "u" && localStorage.getItem("force-display-original-column-names") === "true";
|
|
36
36
|
if (!e || n && !t) return e;
|
|
37
37
|
if (T[e]) return T[e];
|
|
38
38
|
if (t) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryVisualizationWrapper.js","names":[],"sources":["../../../src/components/QueryVisualizationWrapper/QueryVisualizationWrapper.tsx"],"sourcesContent":["import { getDisplayValue } from '@/utils/functions/getDataFromFromStorage'\nimport { unCamelCase } from '@/utils/functions/unCamelCase'\nimport useMutuallyExclusiveState from '@/utils/hooks/useMutuallyExclusiveState'\nimport { useQuery } from '@tanstack/react-query'\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\nimport { useQueryContext } from '../QueryContext'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { NoContentPlaceholderType } from '../SynapseTable/NoContentPlaceholderType'\nimport { ExternalAnalysisPlatform } from '../SynapseTable/export/ExternalAnalysisPlatformsConstants'\nimport NoContentPlaceholderComponent from './NoContentPlaceholder'\nimport {\n QueryVisualizationContextProvider,\n QueryVisualizationContextType,\n} from './QueryVisualizationContext'\n\n// By default, show no external analysis platforms.\nconst DEFAULT_ENABLED_ANALYSIS_PLATFORMS: ExternalAnalysisPlatform[] = []\n\ntype ColumnOrFacetHelpConfig = {\n /** Text that describes the column or facet */\n helpText: string\n /** The name of the column for which the markdown applies */\n columnName: string\n /** The JSON path matching a described JSON Column facet */\n jsonPath?: string\n}\n\nexport type QueryVisualizationWrapperProps = {\n children: ReactNode | ReactNode[]\n rgbIndex?: number\n /** The singular word to use to describe a what a row represents (e.g. \"file\"). Defaults to \"result\" */\n unitDescription?: string\n /** Mapping from column name to the name that should be shown for the column */\n columnAliases?: Record<string, string>\n visibleColumnCount?: number\n hiddenColumns?: string[]\n defaultShowPlots?: boolean\n hideCopyToClipboard?: boolean\n hideSearchBarControl?: boolean\n /** When true, the text matches filter pill is shown but cannot be removed. Defaults to true. */\n lockTextMatchesQueryFilterPill?: boolean\n defaultShowSearchBar?: boolean\n showLastUpdatedOn?: boolean\n /** Default is INTERACTIVE */\n noContentPlaceholderType?: NoContentPlaceholderType\n isRowSelectionVisible?: boolean\n /** The set of columns that defines a uniqueness constraint on the table for the purposes of filtering based on row selection.\n * Note that Synapse tables have no internal concept of a primary key.\n */\n rowSelectionPrimaryKey?: string[]\n /** Look for additional filters using the given key. If not provided, the entity ID will be used.\n * @deprecated - configure the filter before passing a query */\n additionalFiltersSessionStorageKey?: string\n /** Configuration to add a help popover to each corresponding column header */\n helpConfiguration?: ColumnOrFacetHelpConfig[]\n hasCustomPlots?: boolean\n /** The set of external analysis platform to which the UI will support exporting data.\n * @default [] (no platforms are enabled) */\n enabledExternalAnalysisPlatforms?: ExternalAnalysisPlatform[]\n hideVisualizationsControl?: boolean\n}\n\n/**\n * QueryVisualizationWrapper manages UI state for components that query tables in Synapse. That state can be accessed\n * or updated using QueryVisualizationContext. A QueryVisualizationWrapper must be used within a QueryWrapper.\n */\nexport function QueryVisualizationWrapper(\n props: QueryVisualizationWrapperProps,\n) {\n const {\n noContentPlaceholderType = NoContentPlaceholderType.INTERACTIVE,\n defaultShowSearchBar = false,\n defaultShowPlots = true,\n hideCopyToClipboard = false,\n hideSearchBarControl = false,\n lockTextMatchesQueryFilterPill = true,\n unitDescription = 'result',\n helpConfiguration,\n hasCustomPlots = false,\n visibleColumnCount = Infinity,\n enabledExternalAnalysisPlatforms = DEFAULT_ENABLED_ANALYSIS_PLATFORMS,\n } = props\n\n const columnAliases = useMemo(\n () => props.columnAliases ?? {},\n [props.columnAliases],\n )\n\n const {\n getCurrentQueryRequest,\n hasFacetedSelectColumn,\n hasResettableFilters,\n rowDataQueryOptions,\n } = useQueryContext()\n const { data: queryMetadata } = useGetQueryMetadata()\n\n // Get the selectColumns from either query so that creating the context isn't bottlenecked by one or the other\n // Use the previous result as placeholder data so we don't reset the selectColumns unless they have actually changed.\n const { data: selectColumnsFromRowData } = useQuery({\n ...rowDataQueryOptions,\n select: data => data.responseBody?.queryResult?.queryResults.headers,\n placeholderData: prevData => prevData,\n })\n const { data: selectColumnsFromMetadata } = useGetQueryMetadata({\n select: data => data.responseBody?.selectColumns,\n placeholderData: prevData => prevData,\n })\n // We deep-compare-memoize the selectColumns so we don't reset visible columns if the reference changes, but not the contents (e.g. on page change)\n const selectColumns = useDeepCompareMemoize(\n selectColumnsFromRowData ?? selectColumnsFromMetadata ?? [],\n )\n\n const [showSqlEditor, setShowSqlEditor] = useState(false)\n const [showPlots, setShowPlots] = useState(defaultShowPlots)\n const [showCopyToClipboard, setShowCopyToClipboard] =\n useState(!hideCopyToClipboard)\n const [showFacetFilter, setShowFacetFilter] = useState(true)\n\n // The search bar and download confirmation should not be shown at the same time.\n const [\n showSearchBar,\n setShowSearchBar,\n showDownloadConfirmation,\n setShowDownloadConfirmation,\n ] = useMutuallyExclusiveState(\n defaultShowSearchBar && !hideSearchBarControl,\n false,\n )\n\n const [\n isShowingExportToAnalysisPlatformModal,\n setIsShowingExportToAnalysisPlatformModal,\n ] = useState<boolean>(false)\n\n const [visibleColumns, setVisibleColumns] = useState<string[]>([])\n\n const lastQueryRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n\n // Deep-compare-memoize so callers passing a fresh array literal\n // (e.g. `hiddenColumns={['topic']}`) don't reset visible columns on every\n // parent render.\n const hiddenColumns = useDeepCompareMemoize(props.hiddenColumns ?? [])\n useEffect(() => {\n // SWC-6030: If sql changes, reset what columns are visible\n const hidden = new Set(hiddenColumns)\n setVisibleColumns(\n selectColumns\n .filter(el => !hidden.has(el.name))\n .slice(0, visibleColumnCount)\n .map(el => el.name),\n )\n }, [\n selectColumns,\n lastQueryRequest.query.sql,\n visibleColumnCount,\n hiddenColumns,\n ])\n\n const getColumnDisplayName = useCallback(\n (columnName: string, jsonPath?: string) => {\n // SWC-5982: if force-display-original-column-names is set, then just return the string\n const forceDisplayOriginalColumnName =\n localStorage.getItem('force-display-original-column-names') === 'true'\n\n if (!columnName || (forceDisplayOriginalColumnName && !jsonPath)) {\n return columnName\n }\n if (columnAliases[columnName]) {\n return columnAliases[columnName]\n }\n if (jsonPath) {\n const columnModel = queryMetadata?.columnModels?.find(\n cm => cm.name === columnName,\n )\n if (columnModel?.jsonSubColumns) {\n const jsonSubColumn = columnModel.jsonSubColumns.find(\n jsc => jsc.jsonPath === jsonPath,\n )\n if (jsonSubColumn) {\n return jsonSubColumn.name\n }\n }\n }\n return unCamelCase(columnName)\n },\n [columnAliases, queryMetadata?.columnModels],\n )\n\n const getHelpText = useCallback(\n (columnName: string, jsonPath?: string): string | undefined => {\n if (Array.isArray(helpConfiguration)) {\n const helpConfig = helpConfiguration.find(\n config =>\n config.columnName === columnName && config.jsonPath === jsonPath,\n )\n return helpConfig?.helpText\n }\n return undefined\n },\n [helpConfiguration],\n )\n\n const NoContentPlaceholder = useCallback(\n () => (\n <NoContentPlaceholderComponent\n type={noContentPlaceholderType}\n hasResettableFilters={hasResettableFilters}\n />\n ),\n [noContentPlaceholderType, hasResettableFilters],\n )\n\n const context: QueryVisualizationContextType = useMemo(\n () => ({\n columnsToShowInTable: visibleColumns,\n setColumnsToShowInTable: setVisibleColumns,\n rgbIndex: props.rgbIndex,\n unitDescription: unitDescription,\n showLastUpdatedOn: props.showLastUpdatedOn,\n getColumnDisplayName,\n getDisplayValue,\n getHelpText,\n NoContentPlaceholder,\n isShowingExportToAnalysisPlatformModal:\n isShowingExportToAnalysisPlatformModal,\n setIsShowingExportToAnalysisPlatformModal:\n setIsShowingExportToAnalysisPlatformModal,\n showFacetFilter: hasFacetedSelectColumn ? showFacetFilter : false,\n setShowFacetFilter,\n hideSearchBarControl,\n lockTextMatchesQueryFilterPill,\n showSearchBar,\n setShowSearchBar,\n showDownloadConfirmation,\n setShowDownloadConfirmation,\n showSqlEditor,\n setShowSqlEditor,\n showPlots: hasCustomPlots || hasFacetedSelectColumn ? showPlots : false,\n setShowPlots,\n showCopyToClipboard,\n setShowCopyToClipboard,\n enabledExternalAnalysisPlatforms,\n }),\n [\n NoContentPlaceholder,\n getColumnDisplayName,\n getHelpText,\n hasFacetedSelectColumn,\n isShowingExportToAnalysisPlatformModal,\n props.rgbIndex,\n props.showLastUpdatedOn,\n setShowDownloadConfirmation,\n setShowSearchBar,\n showCopyToClipboard,\n showDownloadConfirmation,\n showFacetFilter,\n showPlots,\n showSearchBar,\n showSqlEditor,\n unitDescription,\n visibleColumns,\n hasCustomPlots,\n enabledExternalAnalysisPlatforms,\n hideSearchBarControl,\n lockTextMatchesQueryFilterPill,\n ],\n )\n /**\n * Render the children without any formatting\n */\n const { children } = props\n return (\n <QueryVisualizationContextProvider queryVisualizationContext={context}>\n {children}\n </QueryVisualizationContextProvider>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"QueryVisualizationWrapper.js","names":[],"sources":["../../../src/components/QueryVisualizationWrapper/QueryVisualizationWrapper.tsx"],"sourcesContent":["import { getDisplayValue } from '@/utils/functions/getDataFromFromStorage'\nimport { unCamelCase } from '@/utils/functions/unCamelCase'\nimport useMutuallyExclusiveState from '@/utils/hooks/useMutuallyExclusiveState'\nimport { useQuery } from '@tanstack/react-query'\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\nimport { useQueryContext } from '../QueryContext'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { NoContentPlaceholderType } from '../SynapseTable/NoContentPlaceholderType'\nimport { ExternalAnalysisPlatform } from '../SynapseTable/export/ExternalAnalysisPlatformsConstants'\nimport NoContentPlaceholderComponent from './NoContentPlaceholder'\nimport {\n QueryVisualizationContextProvider,\n QueryVisualizationContextType,\n} from './QueryVisualizationContext'\n\n// By default, show no external analysis platforms.\nconst DEFAULT_ENABLED_ANALYSIS_PLATFORMS: ExternalAnalysisPlatform[] = []\n\ntype ColumnOrFacetHelpConfig = {\n /** Text that describes the column or facet */\n helpText: string\n /** The name of the column for which the markdown applies */\n columnName: string\n /** The JSON path matching a described JSON Column facet */\n jsonPath?: string\n}\n\nexport type QueryVisualizationWrapperProps = {\n children: ReactNode | ReactNode[]\n rgbIndex?: number\n /** The singular word to use to describe a what a row represents (e.g. \"file\"). Defaults to \"result\" */\n unitDescription?: string\n /** Mapping from column name to the name that should be shown for the column */\n columnAliases?: Record<string, string>\n visibleColumnCount?: number\n hiddenColumns?: string[]\n defaultShowPlots?: boolean\n hideCopyToClipboard?: boolean\n hideSearchBarControl?: boolean\n /** When true, the text matches filter pill is shown but cannot be removed. Defaults to true. */\n lockTextMatchesQueryFilterPill?: boolean\n defaultShowSearchBar?: boolean\n showLastUpdatedOn?: boolean\n /** Default is INTERACTIVE */\n noContentPlaceholderType?: NoContentPlaceholderType\n isRowSelectionVisible?: boolean\n /** The set of columns that defines a uniqueness constraint on the table for the purposes of filtering based on row selection.\n * Note that Synapse tables have no internal concept of a primary key.\n */\n rowSelectionPrimaryKey?: string[]\n /** Look for additional filters using the given key. If not provided, the entity ID will be used.\n * @deprecated - configure the filter before passing a query */\n additionalFiltersSessionStorageKey?: string\n /** Configuration to add a help popover to each corresponding column header */\n helpConfiguration?: ColumnOrFacetHelpConfig[]\n hasCustomPlots?: boolean\n /** The set of external analysis platform to which the UI will support exporting data.\n * @default [] (no platforms are enabled) */\n enabledExternalAnalysisPlatforms?: ExternalAnalysisPlatform[]\n hideVisualizationsControl?: boolean\n}\n\n/**\n * QueryVisualizationWrapper manages UI state for components that query tables in Synapse. That state can be accessed\n * or updated using QueryVisualizationContext. A QueryVisualizationWrapper must be used within a QueryWrapper.\n */\nexport function QueryVisualizationWrapper(\n props: QueryVisualizationWrapperProps,\n) {\n const {\n noContentPlaceholderType = NoContentPlaceholderType.INTERACTIVE,\n defaultShowSearchBar = false,\n defaultShowPlots = true,\n hideCopyToClipboard = false,\n hideSearchBarControl = false,\n lockTextMatchesQueryFilterPill = true,\n unitDescription = 'result',\n helpConfiguration,\n hasCustomPlots = false,\n visibleColumnCount = Infinity,\n enabledExternalAnalysisPlatforms = DEFAULT_ENABLED_ANALYSIS_PLATFORMS,\n } = props\n\n const columnAliases = useMemo(\n () => props.columnAliases ?? {},\n [props.columnAliases],\n )\n\n const {\n getCurrentQueryRequest,\n hasFacetedSelectColumn,\n hasResettableFilters,\n rowDataQueryOptions,\n } = useQueryContext()\n const { data: queryMetadata } = useGetQueryMetadata()\n\n // Get the selectColumns from either query so that creating the context isn't bottlenecked by one or the other\n // Use the previous result as placeholder data so we don't reset the selectColumns unless they have actually changed.\n const { data: selectColumnsFromRowData } = useQuery({\n ...rowDataQueryOptions,\n select: data => data.responseBody?.queryResult?.queryResults.headers,\n placeholderData: prevData => prevData,\n })\n const { data: selectColumnsFromMetadata } = useGetQueryMetadata({\n select: data => data.responseBody?.selectColumns,\n placeholderData: prevData => prevData,\n })\n // We deep-compare-memoize the selectColumns so we don't reset visible columns if the reference changes, but not the contents (e.g. on page change)\n const selectColumns = useDeepCompareMemoize(\n selectColumnsFromRowData ?? selectColumnsFromMetadata ?? [],\n )\n\n const [showSqlEditor, setShowSqlEditor] = useState(false)\n const [showPlots, setShowPlots] = useState(defaultShowPlots)\n const [showCopyToClipboard, setShowCopyToClipboard] =\n useState(!hideCopyToClipboard)\n const [showFacetFilter, setShowFacetFilter] = useState(true)\n\n // The search bar and download confirmation should not be shown at the same time.\n const [\n showSearchBar,\n setShowSearchBar,\n showDownloadConfirmation,\n setShowDownloadConfirmation,\n ] = useMutuallyExclusiveState(\n defaultShowSearchBar && !hideSearchBarControl,\n false,\n )\n\n const [\n isShowingExportToAnalysisPlatformModal,\n setIsShowingExportToAnalysisPlatformModal,\n ] = useState<boolean>(false)\n\n const [visibleColumns, setVisibleColumns] = useState<string[]>([])\n\n const lastQueryRequest = useMemo(\n () => getCurrentQueryRequest(),\n [getCurrentQueryRequest],\n )\n\n // Deep-compare-memoize so callers passing a fresh array literal\n // (e.g. `hiddenColumns={['topic']}`) don't reset visible columns on every\n // parent render.\n const hiddenColumns = useDeepCompareMemoize(props.hiddenColumns ?? [])\n useEffect(() => {\n // SWC-6030: If sql changes, reset what columns are visible\n const hidden = new Set(hiddenColumns)\n setVisibleColumns(\n selectColumns\n .filter(el => !hidden.has(el.name))\n .slice(0, visibleColumnCount)\n .map(el => el.name),\n )\n }, [\n selectColumns,\n lastQueryRequest.query.sql,\n visibleColumnCount,\n hiddenColumns,\n ])\n\n const getColumnDisplayName = useCallback(\n (columnName: string, jsonPath?: string) => {\n // SWC-5982: if force-display-original-column-names is set, then just return the string\n const forceDisplayOriginalColumnName =\n typeof localStorage !== 'undefined' &&\n localStorage.getItem('force-display-original-column-names') === 'true'\n\n if (!columnName || (forceDisplayOriginalColumnName && !jsonPath)) {\n return columnName\n }\n if (columnAliases[columnName]) {\n return columnAliases[columnName]\n }\n if (jsonPath) {\n const columnModel = queryMetadata?.columnModels?.find(\n cm => cm.name === columnName,\n )\n if (columnModel?.jsonSubColumns) {\n const jsonSubColumn = columnModel.jsonSubColumns.find(\n jsc => jsc.jsonPath === jsonPath,\n )\n if (jsonSubColumn) {\n return jsonSubColumn.name\n }\n }\n }\n return unCamelCase(columnName)\n },\n [columnAliases, queryMetadata?.columnModels],\n )\n\n const getHelpText = useCallback(\n (columnName: string, jsonPath?: string): string | undefined => {\n if (Array.isArray(helpConfiguration)) {\n const helpConfig = helpConfiguration.find(\n config =>\n config.columnName === columnName && config.jsonPath === jsonPath,\n )\n return helpConfig?.helpText\n }\n return undefined\n },\n [helpConfiguration],\n )\n\n const NoContentPlaceholder = useCallback(\n () => (\n <NoContentPlaceholderComponent\n type={noContentPlaceholderType}\n hasResettableFilters={hasResettableFilters}\n />\n ),\n [noContentPlaceholderType, hasResettableFilters],\n )\n\n const context: QueryVisualizationContextType = useMemo(\n () => ({\n columnsToShowInTable: visibleColumns,\n setColumnsToShowInTable: setVisibleColumns,\n rgbIndex: props.rgbIndex,\n unitDescription: unitDescription,\n showLastUpdatedOn: props.showLastUpdatedOn,\n getColumnDisplayName,\n getDisplayValue,\n getHelpText,\n NoContentPlaceholder,\n isShowingExportToAnalysisPlatformModal:\n isShowingExportToAnalysisPlatformModal,\n setIsShowingExportToAnalysisPlatformModal:\n setIsShowingExportToAnalysisPlatformModal,\n showFacetFilter: hasFacetedSelectColumn ? showFacetFilter : false,\n setShowFacetFilter,\n hideSearchBarControl,\n lockTextMatchesQueryFilterPill,\n showSearchBar,\n setShowSearchBar,\n showDownloadConfirmation,\n setShowDownloadConfirmation,\n showSqlEditor,\n setShowSqlEditor,\n showPlots: hasCustomPlots || hasFacetedSelectColumn ? showPlots : false,\n setShowPlots,\n showCopyToClipboard,\n setShowCopyToClipboard,\n enabledExternalAnalysisPlatforms,\n }),\n [\n NoContentPlaceholder,\n getColumnDisplayName,\n getHelpText,\n hasFacetedSelectColumn,\n isShowingExportToAnalysisPlatformModal,\n props.rgbIndex,\n props.showLastUpdatedOn,\n setShowDownloadConfirmation,\n setShowSearchBar,\n showCopyToClipboard,\n showDownloadConfirmation,\n showFacetFilter,\n showPlots,\n showSearchBar,\n showSqlEditor,\n unitDescription,\n visibleColumns,\n hasCustomPlots,\n enabledExternalAnalysisPlatforms,\n hideSearchBarControl,\n lockTextMatchesQueryFilterPill,\n ],\n )\n /**\n * Render the children without any formatting\n */\n const { children } = props\n return (\n <QueryVisualizationContextProvider queryVisualizationContext={context}>\n {children}\n </QueryVisualizationContextProvider>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RowSetView.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapperPlotNav/RowSetView.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAgB,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAWtE,MAAM,MAAM,eAAe,GAAG;IAC5B,kBAAkB,CAAC,EAAE,yBAAyB,CAAA;IAC9C,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"RowSetView.d.ts","sourceRoot":"","sources":["../../../src/components/QueryWrapperPlotNav/RowSetView.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAgB,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAWtE,MAAM,MAAM,eAAe,GAAG;IAC5B,kBAAkB,CAAC,EAAE,yBAAyB,CAAA;IAC9C,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,2CA2EhD"}
|
|
@@ -24,18 +24,15 @@ function g(g) {
|
|
|
24
24
|
className: "RowSetView",
|
|
25
25
|
children: [
|
|
26
26
|
D && /* @__PURE__ */ p(a, { progressMessage: E }),
|
|
27
|
-
!D && T && /* @__PURE__ */ m(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
multiCardList: b
|
|
37
|
-
})]
|
|
38
|
-
}),
|
|
27
|
+
!D && T && /* @__PURE__ */ m(f, { children: [w && /* @__PURE__ */ p(r, {
|
|
28
|
+
...w,
|
|
29
|
+
rowSet: T,
|
|
30
|
+
isLoadingNewPage: O
|
|
31
|
+
}), _ && /* @__PURE__ */ p(n, {
|
|
32
|
+
..._,
|
|
33
|
+
rowSet: T,
|
|
34
|
+
multiCardList: b
|
|
35
|
+
})] }),
|
|
39
36
|
/* @__PURE__ */ m(l, {
|
|
40
37
|
fallback: /* @__PURE__ */ p(f, {}),
|
|
41
38
|
children: [!C && /* @__PURE__ */ p(d, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RowSetView.js","names":[],"sources":["../../../src/components/QueryWrapperPlotNav/RowSetView.tsx"],"sourcesContent":["import { Suspense, useState } from 'react'\nimport { CardContainer } from '../CardContainer/CardContainer'\nimport { SynapseTable, SynapseTableConfiguration } from '../SynapseTable'\nimport { CardConfiguration } from '../CardContainer/CardConfiguration'\nimport LastUpdatedOn from './LastUpdatedOn'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\nimport QueryWrapperLoadingScreen from '../QueryWrapper/QueryWrapperLoadingScreen'\nimport { SynapseErrorBoundary } from '../error'\nimport { useQueryContext } from '../QueryContext'\nimport { Box } from '@mui/material'\nimport { TablePagination } from '../SynapseTable/TablePagination'\nimport { ViewMoreQueryResultsButton } from '../QueryWrapper/ViewMoreQueryResultsButton'\nimport { useRowSet } from './UseRowSet'\n\nexport type RowSetViewProps = {\n tableConfiguration?: SynapseTableConfiguration\n cardConfiguration?: CardConfiguration\n initialLimit?: number\n hideDownload?: boolean\n multiCardList?: boolean\n}\n\n/**\n * Renders a table or cards representing the RowSet. Also displays appropriate pagination controls\n * depending on the value of QueryContext.isInfinite.\n * @param props\n * @constructor\n */\nexport function RowSetView(props: RowSetViewProps) {\n const { cardConfiguration, hideDownload, initialLimit, multiCardList } = props\n\n const [initialLimitIsApplied, setInitialLimitIsApplied] = useState(\n initialLimit != null,\n )\n\n const { isInfinite } = useQueryContext()\n const tableConfiguration = useDeepCompareMemoize(\n props.tableConfiguration\n ? {\n ...props.tableConfiguration,\n hideDownload,\n }\n : undefined,\n )\n\n const {\n rowSet,\n progressMessage,\n isLoading,\n isLoadingNewPage,\n fetchNextPageOfInfiniteData,\n hasNextPageOfInfiniteData,\n } = useRowSet(initialLimitIsApplied ? initialLimit : undefined)\n\n return (\n <SynapseErrorBoundary>\n <div className={`RowSetView`}>\n {isLoading && (\n <QueryWrapperLoadingScreen progressMessage={progressMessage} />\n )}\n {!isLoading
|
|
1
|
+
{"version":3,"file":"RowSetView.js","names":[],"sources":["../../../src/components/QueryWrapperPlotNav/RowSetView.tsx"],"sourcesContent":["import { Suspense, useState } from 'react'\nimport { CardContainer } from '../CardContainer/CardContainer'\nimport { SynapseTable, SynapseTableConfiguration } from '../SynapseTable'\nimport { CardConfiguration } from '../CardContainer/CardConfiguration'\nimport LastUpdatedOn from './LastUpdatedOn'\nimport { useDeepCompareMemoize } from 'use-deep-compare-effect'\nimport QueryWrapperLoadingScreen from '../QueryWrapper/QueryWrapperLoadingScreen'\nimport { SynapseErrorBoundary } from '../error'\nimport { useQueryContext } from '../QueryContext'\nimport { Box } from '@mui/material'\nimport { TablePagination } from '../SynapseTable/TablePagination'\nimport { ViewMoreQueryResultsButton } from '../QueryWrapper/ViewMoreQueryResultsButton'\nimport { useRowSet } from './UseRowSet'\n\nexport type RowSetViewProps = {\n tableConfiguration?: SynapseTableConfiguration\n cardConfiguration?: CardConfiguration\n initialLimit?: number\n hideDownload?: boolean\n multiCardList?: boolean\n}\n\n/**\n * Renders a table or cards representing the RowSet. Also displays appropriate pagination controls\n * depending on the value of QueryContext.isInfinite.\n * @param props\n * @constructor\n */\nexport function RowSetView(props: RowSetViewProps) {\n const { cardConfiguration, hideDownload, initialLimit, multiCardList } = props\n\n const [initialLimitIsApplied, setInitialLimitIsApplied] = useState(\n initialLimit != null,\n )\n\n const { isInfinite } = useQueryContext()\n const tableConfiguration = useDeepCompareMemoize(\n props.tableConfiguration\n ? {\n ...props.tableConfiguration,\n hideDownload,\n }\n : undefined,\n )\n\n const {\n rowSet,\n progressMessage,\n isLoading,\n isLoadingNewPage,\n fetchNextPageOfInfiniteData,\n hasNextPageOfInfiniteData,\n } = useRowSet(initialLimitIsApplied ? initialLimit : undefined)\n\n return (\n <SynapseErrorBoundary>\n <div className={`RowSetView`}>\n {isLoading && (\n <QueryWrapperLoadingScreen progressMessage={progressMessage} />\n )}\n {!isLoading && rowSet && (\n <>\n {tableConfiguration && (\n <SynapseTable\n {...tableConfiguration}\n rowSet={rowSet}\n isLoadingNewPage={isLoadingNewPage}\n />\n )}\n {cardConfiguration && (\n <CardContainer\n {...cardConfiguration}\n rowSet={rowSet}\n multiCardList={multiCardList}\n />\n )}\n </>\n )}\n <Suspense fallback={<></>}>\n {!isInfinite && (\n <Box sx={{ mt: 2, textAlign: 'right' }}>\n <TablePagination />\n </Box>\n )}\n {isInfinite && (\n <ViewMoreQueryResultsButton\n initialLimit={initialLimit}\n initialLimitIsApplied={initialLimitIsApplied}\n onRemoveInitialLimit={() => {\n setInitialLimitIsApplied(false)\n }}\n fetchNextPage={() => {\n void fetchNextPageOfInfiniteData()\n }}\n hasNextPage={hasNextPageOfInfiniteData}\n isFetchingNextPage={isLoadingNewPage}\n />\n )}\n </Suspense>\n <LastUpdatedOn />\n </div>\n </SynapseErrorBoundary>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA4BA,SAAgB,EAAW,GAAwB;CACjD,IAAM,EAAE,sBAAmB,iBAAc,iBAAc,qBAAkB,GAEnE,CAAC,GAAuB,KAA4B,EACxD,KAAgB,IAClB,GAEM,EAAE,kBAAe,EAAgB,GACjC,IAAqB,EACzB,EAAM,qBACF;EACE,GAAG,EAAM;EACT;CACF,IACA,KAAA,CACN,GAEM,EACJ,WACA,oBACA,cACA,qBACA,gCACA,iCACE,EAAU,IAAwB,IAAe,KAAA,CAAS;CAE9D,OACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;EAAK,WAAW;YAAhB;GACG,KACC,kBAAC,GAAD,EAA4C,mBAAkB,CAAA;GAE/D,CAAC,KAAa,KACb,kBAAA,GAAA,EAAA,UAAA,CACG,KACC,kBAAC,GAAD;IACE,GAAI;IACI;IACU;GACnB,CAAA,GAEF,KACC,kBAAC,GAAD;IACE,GAAI;IACI;IACO;GAChB,CAAA,CAEH,EAAA,CAAA;GAEJ,kBAAC,GAAD;IAAU,UAAU,kBAAA,GAAA,CAAI,CAAA;cAAxB,CACG,CAAC,KACA,kBAAC,GAAD;KAAK,IAAI;MAAE,IAAI;MAAG,WAAW;KAAQ;eACnC,kBAAC,GAAD,CAAkB,CAAA;IACf,CAAA,GAEN,KACC,kBAAC,GAAD;KACgB;KACS;KACvB,4BAA4B;MAC1B,EAAyB,EAAK;KAChC;KACA,qBAAqB;MACnB,EAAiC;KACnC;KACA,aAAa;KACb,oBAAoB;IACrB,CAAA,CAEK;;GACV,kBAAC,GAAD,CAAgB,CAAA;EACb;IACe,CAAA;AAE1B"}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type RssState = {
|
|
3
|
-
rssFeed: any;
|
|
4
|
-
isLoadingError: boolean;
|
|
5
|
-
isShowingSubscribeUI: boolean;
|
|
6
|
-
allItemsUrl?: string;
|
|
7
|
-
};
|
|
1
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
8
2
|
export type RssFilter = {
|
|
9
3
|
type?: 'tag' | 'category';
|
|
10
4
|
value: string;
|
|
@@ -18,13 +12,11 @@ export type RssFeedCardsProps = {
|
|
|
18
12
|
mailChimpUrl?: string;
|
|
19
13
|
viewAllNewsButtonText?: string;
|
|
20
14
|
};
|
|
21
|
-
export declare
|
|
22
|
-
_isMounted: boolean;
|
|
23
|
-
constructor(props: RssFeedCardsProps);
|
|
24
|
-
componentDidMount(): void;
|
|
25
|
-
componentWillUnmount(): void;
|
|
26
|
-
onClickSubscribe: () => void;
|
|
27
|
-
render(): import("react/jsx-runtime").JSX.Element;
|
|
28
|
-
}
|
|
15
|
+
export declare function RssFeedCards(props: RssFeedCardsProps): import("react/jsx-runtime").JSX.Element;
|
|
29
16
|
export default RssFeedCards;
|
|
17
|
+
/**
|
|
18
|
+
* Prefetches the RSS feed into a QueryClient for use with HydrationBoundary.
|
|
19
|
+
* Uses the same query key as the RssFeedCards component.
|
|
20
|
+
*/
|
|
21
|
+
export declare function prefetchRssFeed(queryClient: QueryClient, url: string, filter?: RssFilter): Promise<void>;
|
|
30
22
|
//# sourceMappingURL=RssFeedCards.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RssFeedCards.d.ts","sourceRoot":"","sources":["../../../src/components/RssFeedCards/RssFeedCards.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RssFeedCards.d.ts","sourceRoot":"","sources":["../../../src/components/RssFeedCards/RssFeedCards.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAA0B,MAAM,uBAAuB,CAAA;AAK3E,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,CAAC,EAAE,KAAK,GAAG,UAAU,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B,CAAA;AAuBD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CA6IpD;AAED,eAAe,YAAY,CAAA;AAE3B;;;GAGG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,WAAW,EACxB,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,SAAS,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf"}
|