diff --git a/superset-frontend/packages/superset-ui-core/src/components/EmptyState/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/EmptyState/index.tsx index b8f655c2760..05e39eed9b7 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/EmptyState/index.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/EmptyState/index.tsx @@ -128,7 +128,7 @@ const ImageContainer = ({ ); diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx index fc4e7b9000c..7804a02f743 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTable/index.tsx @@ -40,7 +40,7 @@ import { } from 'ag-grid-community'; import { AgGridReact } from 'ag-grid-react'; import { type FunctionComponent } from 'react'; -import { JsonObject, DataRecordValue, DataRecord } from '@superset-ui/core'; +import { JsonObject, DataRecordValue, DataRecord, t } from '@superset-ui/core'; import { SearchOutlined } from '@ant-design/icons'; import { debounce, isEqual } from 'lodash'; import Pagination from './components/Pagination'; @@ -326,6 +326,79 @@ const AgGridDataTable: FunctionComponent = memo( paginationPageSizeSelector={PAGE_SIZE_OPTIONS} suppressDragLeaveHidesColumns pinnedBottomRowData={showTotals ? [cleanedTotals] : undefined} + localeText={{ + // Pagination controls + next: t('Next'), + previous: t('Previous'), + page: t('Page'), + more: t('More'), + to: t('to'), + of: t('of'), + first: t('First'), + last: t('Last'), + loadingOoo: t('Loading...'), + // Set Filter + selectAll: t('Select All'), + searchOoo: t('Search...'), + blanks: t('Blanks'), + // Filter operations + filterOoo: t('Filter'), + applyFilter: t('Apply Filter'), + equals: t('Equals'), + notEqual: t('Not Equal'), + lessThan: t('Less Than'), + greaterThan: t('Greater Than'), + lessThanOrEqual: t('Less Than or Equal'), + greaterThanOrEqual: t('Greater Than or Equal'), + inRange: t('In Range'), + contains: t('Contains'), + notContains: t('Not Contains'), + startsWith: t('Starts With'), + endsWith: t('Ends With'), + // Logical conditions + andCondition: t('AND'), + orCondition: t('OR'), + // Panel and group labels + group: t('Group'), + columns: t('Columns'), + filters: t('Filters'), + valueColumns: t('Value Columns'), + pivotMode: t('Pivot Mode'), + groups: t('Groups'), + values: t('Values'), + pivots: t('Pivots'), + toolPanelButton: t('Tool Panel'), + // Enterprise menu items + pinColumn: t('Pin Column'), + valueAggregation: t('Value Aggregation'), + autosizeThiscolumn: t('Autosize This Column'), + autosizeAllColumns: t('Autosize All Columns'), + groupBy: t('Group By'), + ungroupBy: t('Ungroup By'), + resetColumns: t('Reset Columns'), + expandAll: t('Expand All'), + collapseAll: t('Collapse All'), + toolPanel: t('Tool Panel'), + export: t('Export'), + csvExport: t('CSV Export'), + excelExport: t('Excel Export'), + excelXmlExport: t('Excel XML Export'), + // Aggregation functions + sum: t('Sum'), + min: t('Min'), + max: t('Max'), + none: t('None'), + count: t('Count'), + average: t('Average'), + // Standard menu items + copy: t('Copy'), + copyWithHeaders: t('Copy with Headers'), + paste: t('Paste'), + // Column menu and sorting + sortAscending: t('Sort Ascending'), + sortDescending: t('Sort Descending'), + sortUnSort: t('Clear Sort'), + }} context={{ onColumnHeaderClicked: handleColumnHeaderClick, initialSortState: getInitialSortState( diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/consts.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/consts.ts index d4db087c304..995e43ea672 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/consts.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/consts.ts @@ -17,10 +17,6 @@ * under the License. */ import { formatSelectOptions } from '@superset-ui/chart-controls'; -import { addLocaleData } from '@superset-ui/core'; -import i18n from './i18n'; - -addLocaleData(i18n); export const SERVER_PAGE_SIZE_OPTIONS = formatSelectOptions([ 10, 20, 50, 100, 200, diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/i18n.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/i18n.ts deleted file mode 100644 index 3ea82b00e07..00000000000 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/i18n.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Locale } from '@superset-ui/core'; - -const en = { - 'Query Mode': [''], - Aggregate: [''], - 'Raw Records': [''], - 'Emit Filter Events': [''], - 'Show Cell Bars': [''], - 'page_size.show': ['Show'], - 'page_size.all': ['All'], - 'page_size.entries': ['entries'], - 'table.previous_page': ['Previous'], - 'table.next_page': ['Next'], - 'search.num_records': ['%s record', '%s records...'], -}; - -const translations: Partial> = { - en, - fr: { - 'Query Mode': [''], - Aggregate: [''], - 'Raw Records': [''], - 'Emit Filter Events': [''], - 'Show Cell Bars': [''], - 'page_size.show': ['Afficher'], - 'page_size.all': ['tous'], - 'page_size.entries': ['entrées'], - 'table.previous_page': ['Précédent'], - 'table.next_page': ['Suivante'], - 'search.num_records': ['%s enregistrement', '%s enregistrements...'], - }, - zh: { - 'Query Mode': ['查询模式'], - Aggregate: ['分组聚合'], - 'Raw Records': ['原始数据'], - 'Emit Filter Events': ['关联看板过滤器'], - 'Show Cell Bars': ['为指标添加条状图背景'], - 'page_size.show': ['每页显示'], - 'page_size.all': ['全部'], - 'page_size.entries': ['条'], - 'table.previous_page': ['上一页'], - 'table.next_page': ['下一页'], - 'search.num_records': ['%s条记录...'], - }, -}; - -export default translations; diff --git a/superset-frontend/plugins/plugin-chart-table/src/consts.ts b/superset-frontend/plugins/plugin-chart-table/src/consts.ts index c2cd9dfa66f..58f60d049f5 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/consts.ts +++ b/superset-frontend/plugins/plugin-chart-table/src/consts.ts @@ -17,10 +17,7 @@ * under the License. */ import { formatSelectOptions } from '@superset-ui/chart-controls'; -import { addLocaleData, t } from '@superset-ui/core'; -import i18n from './i18n'; - -addLocaleData(i18n); +import { t } from '@superset-ui/core'; export const PAGE_SIZE_OPTIONS = formatSelectOptions([ [0, t('page_size.all')], diff --git a/superset-frontend/plugins/plugin-chart-table/src/i18n.ts b/superset-frontend/plugins/plugin-chart-table/src/i18n.ts deleted file mode 100644 index 3ea82b00e07..00000000000 --- a/superset-frontend/plugins/plugin-chart-table/src/i18n.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Locale } from '@superset-ui/core'; - -const en = { - 'Query Mode': [''], - Aggregate: [''], - 'Raw Records': [''], - 'Emit Filter Events': [''], - 'Show Cell Bars': [''], - 'page_size.show': ['Show'], - 'page_size.all': ['All'], - 'page_size.entries': ['entries'], - 'table.previous_page': ['Previous'], - 'table.next_page': ['Next'], - 'search.num_records': ['%s record', '%s records...'], -}; - -const translations: Partial> = { - en, - fr: { - 'Query Mode': [''], - Aggregate: [''], - 'Raw Records': [''], - 'Emit Filter Events': [''], - 'Show Cell Bars': [''], - 'page_size.show': ['Afficher'], - 'page_size.all': ['tous'], - 'page_size.entries': ['entrées'], - 'table.previous_page': ['Précédent'], - 'table.next_page': ['Suivante'], - 'search.num_records': ['%s enregistrement', '%s enregistrements...'], - }, - zh: { - 'Query Mode': ['查询模式'], - Aggregate: ['分组聚合'], - 'Raw Records': ['原始数据'], - 'Emit Filter Events': ['关联看板过滤器'], - 'Show Cell Bars': ['为指标添加条状图背景'], - 'page_size.show': ['每页显示'], - 'page_size.all': ['全部'], - 'page_size.entries': ['条'], - 'table.previous_page': ['上一页'], - 'table.next_page': ['下一页'], - 'search.num_records': ['%s条记录...'], - }, -}; - -export default translations; diff --git a/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx b/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx index 0b0b87e89a0..00311c38ad0 100644 --- a/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx +++ b/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx @@ -109,7 +109,7 @@ export const MenuItemWithTruncation = ({ display: flex; line-height: 1.5em; `} - eventKey={menuKey} + key={menuKey} onClick={onClick} style={style} > diff --git a/superset/app.py b/superset/app.py index 22d3a6ba7d6..0a8f73d53e7 100644 --- a/superset/app.py +++ b/superset/app.py @@ -30,7 +30,7 @@ else: from _typeshed.wsgi import StartResponse, WSGIApplication, WSGIEnvironment -from flask import Flask +from flask import Flask, Response from werkzeug.exceptions import NotFound from superset.initialization import SupersetAppInitializer @@ -77,7 +77,24 @@ def create_app( class SupersetApp(Flask): - pass + def send_static_file(self, filename: str) -> Response: + """Override to prevent webpack hot-update 404s from spamming logs. + + Webpack HMR can create race conditions where the browser requests + hot-update files that no longer exist. Return 204 instead of 404 + for these files to keep logs clean. + """ + if ".hot-update." in filename: + # First try to serve it normally - it might exist + try: + return super().send_static_file(filename) + except NotFound: + logger.debug( + "Webpack hot-update file not found (likely HMR " + f"race condition): {filename}" + ) + return Response("", status=204) # No Content + return super().send_static_file(filename) class AppRootMiddleware: diff --git a/superset/db_engine_specs/__init__.py b/superset/db_engine_specs/__init__.py index 8fddccbb724..a68e8847bec 100644 --- a/superset/db_engine_specs/__init__.py +++ b/superset/db_engine_specs/__init__.py @@ -154,7 +154,7 @@ def get_available_engine_specs() -> dict[type[BaseEngineSpec], set[str]]: # noq try: dialect = ep.load() except Exception as ex: # pylint: disable=broad-except - logger.warning("Unable to load SQLAlchemy dialect %s: %s", ep.name, ex) + logger.debug("Unable to load SQLAlchemy dialect %s: %s", ep.name, ex) else: backend = dialect.name if isinstance(backend, bytes):