You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2025/01/29 21:12:37 UTC
(superset) branch gsheets-improvement updated (dc03fc47db -> b0581b380a)
This is an automated email from the ASF dual-hosted git repository.
beto pushed a change to branch gsheets-improvement
in repository https://gitbox.apache.org/repos/asf/superset.git
discard dc03fc47db WIP
add 827042f12f refactor: Remove CSV upload size limit and related validation (#32000)
add 09c1987de4 chore(fe): correct typing for sheetsColumnNames (#32007)
add 1b375b715c refactor: upload data unification, less permissions and less endpoints (#31959)
add aa74ba3da2 fix(sqllab): tab layout truncated (#32005)
add 7e2b7941f3 refactor: Upgrade to React 17 (#31961)
add 640d4f09bd chore: add UPDATING note for CSV_UPLOAD_MAX_SIZE removal (#32013)
add 962fd4cca3 chore: Removing DASHBOARD_CROSS_FILTERS flag and all that comes with it. (#31794)
add 6478bb7eab feat: add date format to the email subject (#31413)
add 23d9f46d30 chore(Network Errors): Update network errors on filter bars and charts (#31811)
add f4efce3475 fix: Reordering echart props to fix confidence interval in Mixed Charts (#30716)
add a21f184058 fix(issue #31927): TimeGrain.WEEK_STARTING_MONDAY (#32015)
add 19e8a7049b feat(fe): upgrade `superset-frontend` to Typescript v5 (#31979)
add a87a13c3ab fix: Filters badge disappeared (#32025)
add e4bdb28ba2 fix(ci): change ephemeral env to use github labels instead of comments (#31340)
add 732de4ac7f fix: eph env + improve docker images to run in userspace (#32017)
new b0581b380a WIP
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (dc03fc47db)
\
N -- N -- N refs/heads/gsheets-improvement (b0581b380a)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.github/workflows/dependency-review.yml | 1 +
.github/workflows/ephemeral-env.yml | 425 +-
.gitignore | 1 +
Dockerfile | 71 +-
RESOURCES/FEATURE_FLAGS.md | 2 +-
UPDATING.md | 5 +
docker/docker-bootstrap.sh | 5 +-
docker/entrypoints/docker-ci.sh | 2 +-
docs/docs/configuration/alerts-reports.mdx | 3 +
superset-frontend/babel.config.js | 16 +-
superset-frontend/jest.config.js | 10 +-
superset-frontend/package-lock.json | 91608 +++++--------------
superset-frontend/package.json | 39 +-
.../plugin-chart/templates/package-lock.erb | 2 +-
.../generators/plugin-chart/templates/package.erb | 2 +-
.../superset-ui-chart-controls/package.json | 6 +-
.../src/components/ControlHeader.tsx | 2 +-
.../src/components/Tooltip.tsx | 16 +-
.../superset-ui-chart-controls/src/index.ts | 2 +-
.../components/RadioButtonControl.tsx | 2 +-
.../superset-ui-chart-controls/src/types.ts | 7 +
.../src/utils/displayTimeRelatedControls.ts | 2 +-
.../superset-ui-chart-controls/src/utils/index.ts | 3 +-
.../superset-ui-chart-controls/test/types.test.ts | 17 +
.../packages/superset-ui-core/package.json | 6 +-
.../src/chart-composition/legend/WithLegend.tsx | 2 +-
.../src/chart/components/FallbackComponent.tsx | 17 +-
.../src/chart/components/SuperChart.tsx | 7 +-
.../src/query/getClientErrorObject.ts | 2 +-
.../superset-ui-core/src/query/types/Filter.ts | 4 +
.../superset-ui-core/src/query/types/Query.ts | 20 +-
.../src/query/types/QueryResponse.ts | 3 +
.../packages/superset-ui-core/src/style/index.tsx | 1 +
.../superset-ui-core/src/utils/featureFlags.ts | 4 +-
.../src/validator/validateNumber.ts | 2 +-
.../chart-composition/legend/WithLegend.test.tsx | 3 +-
.../chart/components/FallbackComponent.test.tsx | 20 +-
.../test/chart/components/SuperChart.test.tsx | 6 +-
.../time-comparison/customTimeRangeDecode.test.ts | 78 +
.../packages/superset-ui-demo/package.json | 6 +-
.../legacy-plugin-chart-calendar/package.json | 2 +-
.../plugins/legacy-plugin-chart-chord/package.json | 2 +-
.../legacy-plugin-chart-country-map/package.json | 2 +-
.../legacy-plugin-chart-horizon/package.json | 2 +-
.../legacy-plugin-chart-map-box/package.json | 2 +-
.../legacy-plugin-chart-paired-t-test/package.json | 2 +-
.../package.json | 2 +-
.../legacy-plugin-chart-partition/package.json | 4 +-
.../plugins/legacy-plugin-chart-rose/package.json | 2 +-
.../legacy-plugin-chart-world-map/package.json | 2 +-
.../legacy-preset-chart-deckgl/package.json | 5 +-
.../src/CategoricalDeckGLContainer.tsx | 2 +-
.../src/DeckGLContainer.tsx | 1 -
.../legacy-preset-chart-deckgl/src/Multi/Multi.tsx | 1 +
.../src/components/Legend.tsx | 4 +-
.../src/layers/Geojson/Geojson.tsx | 2 +-
.../src/layers/common.tsx | 6 +-
.../legacy-preset-chart-deckgl/src/utils.ts | 7 +-
.../src/utils/explore.ts | 2 +-
.../src/utils/sandbox.ts | 13 +-
.../plugins/legacy-preset-chart-nvd3/package.json | 3 +-
.../plugins/plugin-chart-cartodiagram/package.json | 6 +-
.../src/util/controlPanelUtil.tsx | 2 +-
.../src/util/transformPropsUtil.ts | 2 +-
.../test/util/layerUtil.test.ts | 1 +
.../plugins/plugin-chart-echarts/package.json | 2 +-
.../BigNumberPeriodOverPeriod/transformProps.ts | 3 +-
.../BigNumber/BigNumberPeriodOverPeriod/utils.ts | 2 +-
.../src/BigNumber/BigNumberTotal/controlPanel.ts | 9 +-
.../src/Bubble/transformProps.ts | 35 +-
.../src/MixedTimeseries/transformProps.ts | 7 +-
.../src/Timeseries/transformProps.ts | 3 +-
.../plugin-chart-echarts/src/utils/forecast.ts | 33 +-
.../src/utils/formDataSuffix.ts | 4 +-
.../test/Timeseries/transformProps.test.ts | 2 +-
.../test/utils/forecast.test.ts | 43 +
.../plugins/plugin-chart-handlebars/package.json | 4 +-
.../plugins/plugin-chart-pivot-table/package.json | 6 +-
.../src/plugin/controlPanel.tsx | 7 +-
.../plugins/plugin-chart-table/package.json | 6 +-
.../src/DataTable/components/Pagination.tsx | 5 +-
.../plugin-chart-table/src/controlPanel.tsx | 6 +-
.../plugins/plugin-chart-word-cloud/package.json | 2 +-
superset-frontend/spec/helpers/Cache.ts | 4 +-
superset-frontend/spec/helpers/setup.ts | 1 -
superset-frontend/spec/helpers/shim.tsx | 11 +-
.../src/SqlLab/actions/sqlLab.test.js | 30 +-
.../KeyboardShortcutButton.test.tsx | 4 +-
.../components/KeyboardShortcutButton/index.tsx | 19 +-
.../components/QueryHistory/QueryHistory.test.tsx | 18 +-
.../src/SqlLab/components/QueryTable/index.tsx | 15 +-
.../components/ScheduleQueryButton/index.tsx | 4 +-
.../ShareSqlLabQuery/ShareSqlLabQuery.test.tsx | 21 +-
.../SqlLab/components/SqlEditor/SqlEditor.test.tsx | 42 +-
.../src/SqlLab/components/SqlEditor/index.tsx | 16 +-
.../components/TableElement/TableElement.test.tsx | 20 +-
superset-frontend/src/SqlLab/constants.ts | 2 +-
.../middlewares/persistSqlLabStateEnhancer.js | 3 +-
.../src/SqlLab/reducers/getInitialState.ts | 2 +-
.../src/SqlLab/utils/emptyQueryResults.test.ts | 2 +-
.../SqlLab/utils/reduxStateToLocalStorageHelper.ts | 39 +-
.../src/components/AlteredSliceTag/index.tsx | 2 +-
.../Chart/ChartContextMenu/ChartContextMenu.tsx | 4 +-
.../Chart/ChartContextMenu/useContextMenu.test.tsx | 1 -
.../src/components/Chart/ChartRenderer.jsx | 7 +-
.../src/components/Chart/DrillBy/DrillByModal.tsx | 9 +-
.../Chart/DrillDetail/DrillDetailPane.tsx | 9 +-
.../src/components/Chart/chartActions.test.js | 40 +-
.../src/components/Checkbox/Checkbox.stories.tsx | 4 +-
...tionTable.test.jsx => CollectionTable.test.tsx} | 1 +
.../src/components/Datasource/CollectionTable.tsx | 25 +-
.../Datasource/DatasourceEditor.test.jsx | 15 +-
.../components/Datasource/DatasourceModal.test.jsx | 7 -
.../components/DatePicker/DatePicker.stories.tsx | 4 +-
.../src/components/DatePicker/index.tsx | 6 +-
.../src/components/EmptyState/index.tsx | 5 +-
.../src/components/ErrorBoundary/index.tsx | 5 +-
.../src/components/ErrorMessage/ErrorAlert.tsx | 6 +-
.../ErrorMessage/ErrorMessageWithStackTrace.tsx | 4 +
...st.tsx => FrontendNetworkErrorMessage.test.tsx} | 34 +-
.../ErrorMessage/FrontendNetworkErrorMessage.tsx | 8 +-
.../src/components/ErrorMessage/IssueCode.tsx | 1 +
.../ErrorMessage/MarshmallowErrorMessage.tsx | 10 +-
.../src/components/ErrorMessage/types.ts | 1 +
.../src/components/FilterableTable/index.tsx | 4 +-
.../src/components/FilterableTable/utils.test.tsx | 2 +-
.../src/components/FilterableTable/utils.tsx | 2 +-
.../src/components/FlashProvider/index.tsx | 2 +-
.../Form/LabeledErrorBoundInput.test.jsx | 2 +-
.../src/components/Icons/AntdEnhanced.tsx | 2 +
.../src/components/Icons/Icons.stories.tsx | 2 +-
.../src/components/IndeterminateCheckbox/index.tsx | 2 +
.../src/components/JsonModal/JsonModal.test.tsx | 2 +-
.../src/components/JsonModal/index.tsx | 4 +-
superset-frontend/src/components/Label/index.tsx | 7 +-
.../src/components/ListView/ListView.test.jsx | 3 +-
.../src/components/ListView/ListView.tsx | 1 +
superset-frontend/src/components/ListView/types.ts | 20 +-
superset-frontend/src/components/ListView/utils.ts | 5 +-
.../src/components/Select/AsyncSelect.test.tsx | 6 +-
superset-frontend/src/components/Select/utils.tsx | 15 +-
.../src/components/Steps/Steps.stories.tsx | 3 +-
.../src/components/Table/Table.stories.tsx | 52 +-
.../Table/cell-renderers/ActionCell/index.tsx | 2 +-
.../Table/cell-renderers/NullCell/index.tsx | 16 +-
superset-frontend/src/components/Table/index.tsx | 14 +-
.../src/components/Table/sorters.test.ts | 8 +
superset-frontend/src/components/Table/sorters.ts | 14 +-
.../src/components/TimezoneSelector/index.tsx | 4 +-
superset-frontend/src/components/Tooltip/index.tsx | 8 +-
.../src/dashboard/actions/dashboardState.js | 26 +-
.../src/dashboard/actions/dashboardState.test.js | 18 +-
superset-frontend/src/dashboard/actions/hydrate.js | 18 +-
.../BuilderComponentPane.test.tsx | 4 +-
.../components/ColorSchemeControlWrapper.jsx | 76 -
.../components/ColorSchemeControlWrapper.tsx | 64 +
.../src/dashboard/components/Dashboard.jsx | 7 +-
.../src/dashboard/components/Dashboard.test.jsx | 1 +
.../DashboardBuilder/DashboardBuilder.tsx | 6 +-
.../DashboardBuilder/DashboardContainer.tsx | 2 +-
.../OverwriteConfirmModal.test.tsx | 4 +-
.../PropertiesModal/PropertiesModal.test.tsx | 48 +-
.../dashboard/components/PropertiesModal/index.tsx | 2 -
.../src/dashboard/components/SliceAdder.tsx | 2 +-
.../components/SliceHeaderControls/index.tsx | 1 -
.../components/SyncDashboardState/index.tsx | 5 +-
.../components/URLShortLinkButton/index.tsx | 3 +-
.../src/dashboard/components/dnd/DragDroppable.jsx | 2 +-
.../dashboard/components/gridComponents/Tab.jsx | 3 +-
.../components/gridComponents/Tab.test.jsx | 3 +-
.../components/gridComponents/Tabs.test.tsx | 3 -
.../gridComponents/new/DraggableNewComponent.jsx | 2 +-
.../new/DraggableNewComponent.test.jsx | 5 +-
.../FilterBar/ActionButtons/index.tsx | 18 +-
.../CrossFilters/ScopingModal/ScopingModal.tsx | 5 +-
.../nativeFilters/FilterBar/FilterBar.test.tsx | 15 +-
.../FilterBarSettings/FilterBarSettings.test.tsx | 70 +-
.../FilterBar/FilterBarSettings/index.tsx | 11 +-
.../FilterBar/FilterControls/FilterControls.tsx | 22 +-
.../FilterBar/FilterControls/FilterValue.tsx | 13 +-
.../nativeFilters/FilterBar/Horizontal.tsx | 29 +-
.../FilterBar/HorizontalFilterBar.test.tsx | 3 +
.../nativeFilters/FilterBar/Vertical.tsx | 12 +-
.../components/nativeFilters/FilterBar/index.tsx | 6 +-
.../FiltersConfigForm/ColumnSelect.test.tsx | 15 +-
.../FiltersConfigModal/FiltersConfigForm/utils.ts | 4 +-
.../FiltersConfigModal/FiltersConfigModal.test.tsx | 3 +-
.../components/nativeFilters/selectors.ts | 126 +-
.../dashboard/components/nativeFilters/state.ts | 4 +-
.../components/nativeFilters/utils.test.ts | 73 +-
.../dashboard/components/nativeFilters/utils.ts | 27 +-
.../src/dashboard/reducers/nativeFilters.ts | 3 +-
superset-frontend/src/dashboard/types.ts | 27 +-
.../dashboard/util/activeAllDashboardFilters.ts | 15 +-
.../util/charts/getFormDataWithExtraFilters.ts | 34 +-
.../src/dashboard/util/crossFilters.test.ts | 67 +-
.../src/dashboard/util/crossFilters.ts | 17 +-
.../src/dashboard/util/findParentId.ts | 8 +-
...d.test.js => findTabIndexByComponentId.test.ts} | 9 +-
...ComponentId.js => findTabIndexByComponentId.ts} | 13 +-
.../util/getFormDataWithExtraFilters.test.ts | 4 +-
.../src/dashboard/util/isValidChild.test.ts | 2 +-
.../src/dashboard/util/isValidChild.ts | 2 +-
.../src/dashboard/util/permissionUtils.test.ts | 34 +-
.../src/dashboard/util/replaceUndefinedByNull.ts | 36 -
superset-frontend/src/dataMask/reducer.ts | 38 +-
.../src/explore/actions/datasourcesActions.test.ts | 16 +-
.../src/explore/components/Control.tsx | 5 +-
.../explore/components/ControlPanelsContainer.tsx | 4 +-
.../explore/components/DataTableControl/index.tsx | 2 +-
.../explore/components/DatasourcePanel/index.tsx | 3 +-
.../src/explore/components/ExploreAlert.tsx | 6 +-
.../ExportToCSVDropdown.test.tsx | 27 +-
.../ColorSchemeControl/ColorSchemeControl.test.tsx | 1 -
.../controls/ColorSchemeControl/index.tsx | 6 +-
.../components/controls/ComparisonRangeLabel.tsx | 3 +-
.../ContourControl/ContourPopoverControl.tsx | 4 +-
.../components/controls/CustomListItem/index.tsx | 2 +-
...AdhocFilterEditPopoverSimpleTabContent.test.tsx | 25 +-
.../index.tsx | 6 +-
.../controls/FilterControl/utils/translateToSQL.ts | 8 +-
.../utils/useGetTimeRangeLabel.test.ts | 18 +-
.../components/controls/SliderControl.stories.tsx | 19 +-
.../components/controls/TimeOffsetControl.tsx | 2 +-
.../controls/VizTypeControl/VizTypeGallery.tsx | 2 +-
.../DashboardsSubMenu.test.tsx | 4 +-
.../src/explore/controlUtils/getControlState.ts | 2 +-
.../controlUtils/getFormDataFromControls.ts | 4 +-
.../getFormDataWithDashboardContext.ts | 7 +-
.../explore/controlUtils/getSectionsToRender.ts | 10 +-
.../controlUtils/standardizedFormData.test.ts | 4 +-
.../explore/controlUtils/standardizedFormData.ts | 2 +-
.../exploreUtils/getParsedExploreURLParams.ts | 64 +-
.../exploreUtils/shouldUseLegacyApi.test.ts | 18 +-
superset-frontend/src/explore/types.ts | 2 +-
.../src/features/alerts/AlertReportModal.tsx | 10 +-
.../src/features/allEntities/AllEntitiesTable.tsx | 20 +-
.../annotationLayers/AnnotationLayerModal.tsx | 8 +-
.../src/features/annotations/AnnotationModal.tsx | 3 +-
.../src/features/cssTemplates/CssTemplateModal.tsx | 8 +-
.../src/features/dashboards/DashboardCard.test.tsx | 21 +-
.../DatabaseConnectionForm/EncryptedField.tsx | 15 +-
.../DatabaseConnectionForm/ValidatedInputField.tsx | 14 +-
.../DatabaseModal/DatabaseConnectionForm/index.tsx | 1 +
.../databases/DatabaseModal/ModalHeader.tsx | 10 +-
.../databases/DatabaseModal/index.test.tsx | 11 +-
.../src/features/databases/DatabaseModal/index.tsx | 61 +-
.../UploadDataModel/UploadDataModal.test.tsx | 133 +-
.../features/databases/UploadDataModel/index.tsx | 36 +-
superset-frontend/src/features/databases/types.ts | 48 +-
.../AddDataset/DatasetPanel/DatasetPanel.tsx | 9 +-
.../features/datasets/AddDataset/Footer/index.tsx | 2 +-
.../src/features/home/ActivityTable.tsx | 14 +-
.../src/features/home/RightMenu.test.tsx | 3 +-
superset-frontend/src/features/home/RightMenu.tsx | 6 +-
.../HeaderReportDropdown/index.test.tsx | 22 +-
.../reports/ReportModal/ReportModal.test.tsx | 36 +-
superset-frontend/src/features/tags/TagModal.tsx | 2 +-
superset-frontend/src/features/tags/tags.ts | 7 +-
.../src/hooks/apiResources/datasets.ts | 2 +-
.../src/hooks/apiResources/schemas.test.ts | 6 +-
.../src/hooks/apiResources/tables.test.ts | 16 +-
superset-frontend/src/hooks/useLocale.ts | 7 +-
.../src/middleware/asyncEvent.test.ts | 22 +-
superset-frontend/src/pages/AllEntities/index.tsx | 24 +-
.../src/pages/ChartList/ChartList.test.jsx | 24 +-
.../src/pages/DashboardList/DashboardList.test.jsx | 22 +-
.../src/pages/DatasetList/DatasetList.test.tsx | 17 +-
superset-frontend/src/pages/Home/Home.test.tsx | 15 +-
.../pages/SavedQueryList/SavedQueryList.test.jsx | 58 +-
superset-frontend/src/reduxUtils.ts | 14 +-
superset-frontend/src/types/TaggedObject.ts | 23 +-
.../src/utils/{textUtils.ts => types.ts} | 16 +-
superset-frontend/src/views/App.tsx | 20 +-
superset-frontend/src/views/CRUD/hooks.ts | 11 +-
superset-frontend/src/views/CRUD/utils.tsx | 6 +-
.../src/visualizations/TimeTable/transformProps.ts | 4 +-
superset-frontend/tsconfig.json | 3 -
superset/commands/database/uploaders/base.py | 7 +
superset/config.py | 6 +-
superset/constants.py | 4 +-
superset/databases/api.py | 300 +-
superset/databases/schemas.py | 220 +-
superset/db_engine_specs/sqlite.py | 10 +-
...34_74ad1125881c_converge_upload_permissions.py} | 21 +-
superset/reports/notifications/email.py | 27 +-
superset/security/manager.py | 3 +-
tests/integration_tests/databases/api_tests.py | 4 +-
tests/integration_tests/security_tests.py | 4 +-
tests/unit_tests/databases/api_test.py | 146 +-
.../reports/notifications/email_tests.py | 42 +
291 files changed, 27058 insertions(+), 69243 deletions(-)
rename superset-frontend/src/components/Datasource/{CollectionTable.test.jsx => CollectionTable.test.tsx} (98%)
copy superset-frontend/src/components/ErrorMessage/{DatasetNotFoundErrorMessage.test.tsx => FrontendNetworkErrorMessage.test.tsx} (58%)
delete mode 100644 superset-frontend/src/dashboard/components/ColorSchemeControlWrapper.jsx
create mode 100644 superset-frontend/src/dashboard/components/ColorSchemeControlWrapper.tsx
rename superset-frontend/src/dashboard/util/{findTabIndexByComponentId.test.js => findTabIndexByComponentId.test.ts} (91%)
rename superset-frontend/src/dashboard/util/{findTabIndexByComponentId.js => findTabIndexByComponentId.ts} (86%)
delete mode 100644 superset-frontend/src/dashboard/util/replaceUndefinedByNull.ts
copy superset-frontend/src/utils/{textUtils.ts => types.ts} (73%)
copy superset/migrations/versions/{2024-02-07_17-13_87d38ad83218_migrate_can_view_and_drill_permission.py => 2025-01-22_14-34_74ad1125881c_converge_upload_permissions.py} (81%)
(superset) 01/01: WIP
Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
beto pushed a commit to branch gsheets-improvement
in repository https://gitbox.apache.org/repos/asf/superset.git
commit b0581b380ab498bb3f7dfe51688ed8977a2c3348
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Wed Jan 29 14:08:00 2025 -0500
WIP
---
.../DatabaseConnectionForm/EncryptedField.tsx | 35 +++-----------------
.../DatabaseConnectionForm/OAuth2ClientField.tsx | 17 +++++++---
.../DatabaseConnectionForm/TableCatalog.tsx | 9 ++++-
.../DatabaseConnectionForm/constants.ts | 6 ++--
superset/commands/database/validate.py | 2 +-
superset/db_engine_specs/gsheets.py | 38 +++++++++++++++-------
superset/models/core.py | 11 +++++--
7 files changed, 63 insertions(+), 55 deletions(-)
diff --git a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx
index 147b983c45..7f4f11917d 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx
+++ b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx
@@ -52,10 +52,7 @@ export const EncryptedField = ({
const [fileToUpload, setFileToUpload] = useState<string | null | undefined>(
null,
);
- const [isPublic, setIsPublic] = useState<boolean>(true);
- const showCredentialsInfo =
- db?.engine === 'gsheets' ? !isEditMode && !isPublic : !isEditMode;
- const isEncrypted = isEditMode && db?.masked_encrypted_extra !== '{}';
+ const showCredentialsInfo = !isEditMode;
const encryptedField =
db?.engine &&
encryptedCredentialsMap[db.engine as keyof typeof encryptedCredentialsMap];
@@ -67,33 +64,9 @@ export const EncryptedField = ({
: paramValue;
return (
<CredentialInfoForm>
- {db?.engine === 'gsheets' && (
- <div className="catalog-type-select">
- <FormLabel
- css={(theme: SupersetTheme) => labelMarginBottom(theme)}
- required
- >
- {t('Type of Google Sheets allowed')}
- </FormLabel>
- <AntdSelect
- style={{ width: '100%' }}
- defaultValue={isEncrypted ? 'false' : 'true'}
- onChange={(value: string) =>
- setIsPublic(castStringToBoolean(value))
- }
- >
- <AntdSelect.Option value="true" key={1}>
- {t('Publicly shared sheets only')}
- </AntdSelect.Option>
- <AntdSelect.Option value="false" key={2}>
- {t('Public and privately shared sheets')}
- </AntdSelect.Option>
- </AntdSelect>
- </div>
- )}
{showCredentialsInfo && (
<>
- <FormLabel required>
+ <FormLabel>
{t('How do you want to enter service account credentials?')}
</FormLabel>
<AntdSelect
@@ -115,7 +88,7 @@ export const EncryptedField = ({
isEditMode ||
editNewDb ? (
<div className="input-container">
- <FormLabel required>{t('Service Account')}</FormLabel>
+ <FormLabel>{t('Service Account')}</FormLabel>
<textarea
className="input-form"
name={encryptedField}
@@ -140,7 +113,7 @@ export const EncryptedField = ({
css={(theme: SupersetTheme) => infoTooltip(theme)}
>
<div css={{ display: 'flex', alignItems: 'center' }}>
- <FormLabel required>{t('Upload Credentials')}</FormLabel>
+ <FormLabel>{t('Upload Credentials')}</FormLabel>
<InfoTooltip
tooltip={t(
'Use the JSON file you automatically downloaded when creating your service account.',
diff --git a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.tsx b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.tsx
index fac3c33318..d8ffefd06d 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.tsx
+++ b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.tsx
@@ -40,16 +40,25 @@ interface OAuth2ClientInfo {
scope: string;
}
-export const OAuth2ClientField = ({ changeMethods, db }: FieldPropTypes) => {
+export const OAuth2ClientField = ({
+ changeMethods,
+ db,
+ default_value: defaultValue,
+}: FieldPropTypes) => {
const encryptedExtra = JSON.parse(db?.masked_encrypted_extra || '{}');
const [oauth2ClientInfo, setOauth2ClientInfo] = useState<OAuth2ClientInfo>({
id: encryptedExtra.oauth2_client_info?.id || '',
secret: encryptedExtra.oauth2_client_info?.secret || '',
authorization_request_uri:
- encryptedExtra.oauth2_client_info?.authorization_request_uri || '',
+ encryptedExtra.oauth2_client_info?.authorization_request_uri ||
+ defaultValue?.authorization_request_uri ||
+ '',
token_request_uri:
- encryptedExtra.oauth2_client_info?.token_request_uri || '',
- scope: encryptedExtra.oauth2_client_info?.scope || '',
+ encryptedExtra.oauth2_client_info?.token_request_uri ||
+ defaultValue?.token_request_uri ||
+ '',
+ scope:
+ encryptedExtra.oauth2_client_info?.scope || defaultValue?.scope || '',
});
const handleChange = (key: any) => (e: any) => {
diff --git a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/TableCatalog.tsx b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/TableCatalog.tsx
index 4fe71d0906..91b6a63c0b 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/TableCatalog.tsx
+++ b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/TableCatalog.tsx
@@ -40,7 +40,7 @@ export const TableCatalog = ({
<div>
{tableCatalog?.map((sheet: CatalogObject, idx: number) => (
<>
- <FormLabel className="catalog-label" required>
+ <FormLabel className="catalog-label">
{t('Google Sheet Name and URL')}
</FormLabel>
<div className="catalog-name">
@@ -105,6 +105,13 @@ export const TableCatalog = ({
+ {t('Add sheet')}
</StyledFooterButton>
</div>
+ <div className="helper">
+ <div>
+ {t(
+ 'In order to connect to non-public sheets you need to either provide a service account or configure an OAuth2 client.',
+ )}
+ </div>
+ </div>
</StyledCatalogTable>
);
};
diff --git a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/constants.ts b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/constants.ts
index a0bf7a5dd7..4512d1f707 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/constants.ts
+++ b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/constants.ts
@@ -52,16 +52,16 @@ export const FormFieldOrder = [
'http_path_field',
'database_name',
'project_id',
+ 'catalog',
'credentials_info',
'service_account_info',
- 'catalog',
'query',
'encryption',
'account',
'warehouse',
'role',
'ssh',
- 'oauth2_client',
+ 'oauth2_client_info',
];
const extensionsRegistry = getExtensionsRegistry();
@@ -79,7 +79,7 @@ export const FORM_FIELD_MAP = {
default_schema: defaultSchemaField,
username: usernameField,
password: passwordField,
- oauth2_client: OAuth2ClientField,
+ oauth2_client_info: OAuth2ClientField,
access_token: accessTokenField,
database_name: displayField,
query: queryField,
diff --git a/superset/commands/database/validate.py b/superset/commands/database/validate.py
index e1584d59c0..eda5d75bed 100644
--- a/superset/commands/database/validate.py
+++ b/superset/commands/database/validate.py
@@ -96,7 +96,7 @@ class ValidateDatabaseParametersCommand(BaseCommand):
server_cert=self._properties.get("server_cert", ""),
extra=self._properties.get("extra", "{}"),
impersonate_user=self._properties.get("impersonate_user", False),
- encrypted_extra=serialized_encrypted_extra,
+ encrypted_extra=json.dumps(encrypted_extra),
)
database.set_sqlalchemy_uri(sqlalchemy_uri)
database.db_engine_spec.mutate_db_for_connection_test(database)
diff --git a/superset/db_engine_specs/gsheets.py b/superset/db_engine_specs/gsheets.py
index 65afd9aee9..6fd5baaaa8 100644
--- a/superset/db_engine_specs/gsheets.py
+++ b/superset/db_engine_specs/gsheets.py
@@ -67,6 +67,18 @@ class GSheetsParametersSchema(Schema):
"field_name": "service_account_info",
},
)
+ oauth2_client_info = EncryptedString(
+ required=False,
+ metadata={
+ "description": "OAuth2 client information",
+ "default": {
+ "scope": " ".join(SCOPES),
+ "authorization_request_uri": "https://accounts.google.com/o/oauth2/v2/auth",
+ "token_request_uri": "https://oauth2.googleapis.com/token",
+ },
+ },
+ allow_none=True,
+ )
class GSheetsParametersType(TypedDict):
@@ -165,8 +177,22 @@ class GSheetsEngineSpec(ShillelaghEngineSpec):
_: GSheetsParametersType,
encrypted_extra: None | (dict[str, Any]) = None,
) -> str:
+ if encrypted_extra and "oauth2_client_info" in encrypted_extra:
+ del encrypted_extra["oauth2_client_info"]
+
return "gsheets://"
+ @staticmethod
+ def update_params_from_encrypted_extra(
+ database: Database,
+ params: dict[str, Any],
+ ) -> None:
+ """
+ Remove `oauth2_client_info` from `encrypted_extra`.
+ """
+ if "oauth2_client_info" in params.get("encrypted_extra", {}):
+ del params["encrypted_extra"]["oauth2_client_info"]
+
@classmethod
def get_parameters_from_uri(
cls,
@@ -221,18 +247,6 @@ class GSheetsEngineSpec(ShillelaghEngineSpec):
if isinstance(encrypted_credentials, str):
encrypted_credentials = json.loads(encrypted_credentials)
- if not table_catalog:
- # Allowing users to submit empty catalogs
- errors.append(
- SupersetError(
- message="Sheet name is required",
- error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR,
- level=ErrorLevel.WARNING,
- extra={"catalog": {"idx": 0, "name": True}},
- ),
- )
- return errors
-
# We need a subject in case domain wide delegation is set, otherwise the
# check will fail. This means that the admin will be able to add sheets
# that only they have access, even if later users are not able to access
diff --git a/superset/models/core.py b/superset/models/core.py
index 6f32383ab8..ddfe32c280 100755
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -38,6 +38,7 @@ import sqlalchemy as sqla
import sshtunnel
from flask import g, request
from flask_appbuilder import Model
+from marshmallow.exceptions import ValidationError
from sqlalchemy import (
Boolean,
Column,
@@ -1133,9 +1134,13 @@ class Database(Model, AuditMixinNullable, ImportExportMixin): # pylint: disable
admins to create custom OAuth2 clients from the Superset UI, and assign them to
specific databases.
"""
- encrypted_extra = json.loads(self.encrypted_extra or "{}")
- oauth2_client_info = encrypted_extra.get("oauth2_client_info", {})
- return bool(oauth2_client_info) or self.db_engine_spec.is_oauth2_enabled()
+ try:
+ client_config = self.db_engine_spec.get_oauth2_config()
+ except ValidationError:
+ logger.warning("Invalid OAuth2 client configuration for database %s", self)
+ client_config = None
+
+ return client_config or self.db_engine_spec.is_oauth2_enabled()
def get_oauth2_config(self) -> OAuth2ClientConfig | None:
"""